OpenAFS
OpenAFS distributed network file system
/cygdrive/c/src/openafs/openafs.git/repo/src/rx/rx.h
00001 /*
00002  * Copyright 2000, International Business Machines Corporation and others.
00003  * All Rights Reserved.
00004  *
00005  * This software has been released under the terms of the IBM Public
00006  * License.  For details, see the LICENSE file in the top-level source
00007  * directory or online at http://www.openafs.org/dl/license10.html
00008  */
00009 
00010 #ifdef KDUMP_RX_LOCK
00011 /* kdump for SGI needs MP and SP versions of rx_serverQueueEntry,
00012  * rx_peer, rx_connection and rx_call structs. rx.h gets included a
00013  * second time to pick up mp_ versions of those structs. Currently
00014  * the affected struct's have #ifdef's in them for the second pass.
00015  * This should change once we start using only ANSI compilers.
00016  * Actually, kdump does not use rx_serverQueueEntry, but I'm including
00017  * it for completeness.
00018  */
00019 #undef _RX_
00020 #endif
00021 
00022 #ifndef _RX_
00023 #define _RX_
00024 
00025 #ifndef KDUMP_RX_LOCK
00026 #ifdef  KERNEL
00027 #include "rx_kmutex.h"
00028 #include "rx_kernel.h"
00029 #if defined (AFS_OBSD_ENV) && !defined (MLEN)
00030 #include "sys/mbuf.h"
00031 #endif
00032 #include "netinet/in.h"
00033 #include "sys/socket.h"
00034 #else /* KERNEL */
00035 # include <sys/types.h>
00036 # include <stdio.h>
00037 # include <string.h>
00038 #ifdef AFS_PTHREAD_ENV
00039 # include "rx_pthread.h"
00040 #else
00041 # include "rx_lwp.h"
00042 #endif
00043 #ifdef AFS_NT40_ENV
00044 #include <malloc.h>
00045 #include <winsock2.h>
00046 #include <ws2tcpip.h>
00047 #endif
00048 # include "rx_user.h"
00049 #ifndef AFS_NT40_ENV
00050 # include <netinet/in.h>
00051 # include <sys/socket.h>
00052 #endif
00053 #endif /* KERNEL */
00054 
00055 #include "rx_queue.h"
00056 #include "rx_clock.h"
00057 #include "rx_event.h"
00058 #include "rx_misc.h"
00059 #include "rx_null.h"
00060 #include "rx_multi.h"
00061 
00062 /* These items are part of the new RX API. They're living in this section
00063  * for now, to keep them separate from everything else... */
00064 
00065 struct rx_connection;
00066 struct rx_call;
00067 struct rx_packet;
00068 
00069 /* Connection management */
00070 
00071 extern void rx_SetConnectionEpoch(struct rx_connection *conn, int epoch);
00072 extern int  rx_GetConnectionEpoch(struct rx_connection *conn);
00073 extern void rx_SetConnectionId(struct rx_connection *conn, int id);
00074 extern int  rx_GetConnectionId(struct rx_connection *conn);
00075 extern void *rx_GetSecurityData(struct rx_connection *conn);
00076 extern void  rx_SetSecurityData(struct rx_connection *conn, void *data);
00077 extern int  rx_IsUsingPktCksum(struct rx_connection *conn);
00078 extern void rx_SetSecurityHeaderSize(struct rx_connection *conn, int size);
00079 extern int  rx_GetSecurityHeaderSize(struct rx_connection *conn);
00080 extern void rx_SetSecurityMaxTrailerSize(struct rx_connection *conn, int size);
00081 extern int  rx_GetSecurityMaxTrailerSize(struct rx_connection *conn);
00082 extern void rx_SetMsgsizeRetryErr(struct rx_connection *conn, int err);
00083 extern int  rx_IsServerConn(struct rx_connection *conn);
00084 extern int  rx_IsClientConn(struct rx_connection *conn);
00085 extern struct rx_securityClass *rx_SecurityObjectOf(const struct rx_connection *);
00086 extern struct rx_peer *rx_PeerOf(struct rx_connection *);
00087 extern u_short rx_ServiceIdOf(struct rx_connection *);
00088 extern int rx_SecurityClassOf(struct rx_connection *);
00089 extern struct rx_service *rx_ServiceOf(struct rx_connection *);
00090 extern int rx_ConnError(struct rx_connection *);
00091 
00092 /* Call management */
00093 extern struct rx_connection *rx_ConnectionOf(struct rx_call *call);
00094 extern int rx_Error(struct rx_call *call);
00095 extern int rx_GetRemoteStatus(struct rx_call *call);
00096 extern void rx_SetLocalStatus(struct rx_call *call, int status);
00097 extern int rx_GetCallAbortCode(struct rx_call *call);
00098 extern void rx_SetCallAbortCode(struct rx_call *call, int code);
00099 
00100 extern void rx_RecordCallStatistics(struct rx_call *call,
00101                                     unsigned int rxInterface,
00102                                     unsigned int currentFunc,
00103                                     unsigned int totalFunc,
00104                                     int isServer);
00105 
00106 /* Peer management */
00107 extern afs_uint32 rx_HostOf(struct rx_peer *peer);
00108 extern u_short rx_PortOf(struct rx_peer *peer);
00109 
00110 /* Packets */
00111 
00112 /* Packet classes, for rx_AllocPacket and rx_packetQuota */
00113 #define RX_PACKET_CLASS_RECEIVE     0
00114 #define RX_PACKET_CLASS_SEND        1
00115 #define RX_PACKET_CLASS_SPECIAL     2
00116 #define RX_PACKET_CLASS_RECV_CBUF   3
00117 #define RX_PACKET_CLASS_SEND_CBUF   4
00118 
00119 #define RX_N_PACKET_CLASSES         5   /* Must agree with above list */
00120 
00121 #define RX_PACKET_TYPES     {"data", "ack", "busy", "abort", "ackall", "challenge", "response", "debug", "params", "unused", "unused", "unused", "version"}
00122 #define RX_N_PACKET_TYPES           13  /* Must agree with above list;
00123                                          * counts 0
00124                                          * WARNING: if this number ever
00125                                          * grows past 13, rxdebug packets
00126                                          * will need to be modified */
00127 
00128 
00129 /* For most Unixes, maximum elements in an iovec is 16 */
00130 #define RX_MAXIOVECS 16                 /* limit for ReadvProc/WritevProc */
00131 #define RX_MAXWVECS (RX_MAXIOVECS-1)    /* need one iovec for packet header */
00132 
00133 /* Debugging */
00134 
00135 /* Call flags, states and modes are exposed by the debug interface */
00136 #ifndef KDUMP_RX_LOCK
00137 /* Major call states */
00138 #define RX_STATE_NOTINIT  0     /* Call structure has never been initialized */
00139 #define RX_STATE_PRECALL  1     /* Server-only:  call is not in progress, but packets have arrived */
00140 #define RX_STATE_ACTIVE   2     /* An active call; a process is dealing with this call */
00141 #define RX_STATE_DALLY    3     /* Dallying after process is done with call */
00142 #define RX_STATE_HOLD     4     /* Waiting for acks on reply data packets */
00143 #define RX_STATE_RESET    5     /* Call is being reset */
00144 
00145 /* Call modes:  the modes of a call in RX_STATE_ACTIVE state (process attached) */
00146 #define RX_MODE_SENDING   1     /* Sending or ready to send */
00147 #define RX_MODE_RECEIVING 2     /* Receiving or ready to receive */
00148 #define RX_MODE_ERROR     3     /* Something in error for current conversation */
00149 #define RX_MODE_EOF       4     /* Server has flushed (or client has read) last reply packet */
00150 
00151 /* Flags */
00152 #define RX_CALL_READER_WAIT        1    /* Reader is waiting for next packet */
00153 #define RX_CALL_WAIT_WINDOW_ALLOC  2    /* Sender is waiting for window to allocate buffers */
00154 #define RX_CALL_WAIT_WINDOW_SEND   4    /* Sender is waiting for window to send buffers */
00155 #define RX_CALL_WAIT_PACKETS       8    /* Sender is waiting for packet buffers */
00156 #define RX_CALL_WAIT_PROC         16    /* Waiting for a process to be assigned */
00157 #define RX_CALL_RECEIVE_DONE      32    /* All packets received on this call */
00158 #define RX_CALL_CLEARED           64    /* Receive queue cleared in precall state */
00159 #define RX_CALL_TQ_BUSY          128    /* Call's Xmit Queue is busy; don't modify */
00160 #define RX_CALL_TQ_CLEARME       256    /* Need to clear this call's TQ later */
00161 #define RX_CALL_TQ_SOME_ACKED    512    /* rxi_Start needs to discard ack'd packets. */
00162 #define RX_CALL_TQ_WAIT         1024    /* Reader is waiting for TQ_BUSY to be reset */
00163 #define RX_CALL_FAST_RECOVER    2048    /* call is doing congestion recovery */
00164 /* 4096 was RX_CALL_FAST_RECOVER_WAIT */
00165 #define RX_CALL_SLOW_START_OK   8192    /* receiver acks every other packet */
00166 #define RX_CALL_IOVEC_WAIT      16384   /* waiting thread is using an iovec */
00167 #define RX_CALL_HAVE_LAST       32768   /* Last packet has been received */
00168 #define RX_CALL_NEED_START      0x10000 /* tells rxi_Start to start again */
00169 #define RX_CALL_PEER_BUSY       0x20000 /* the last packet we received on this call was a
00170                                          * BUSY packet; i.e. the channel for this call is busy */
00171 #define RX_CALL_ACKALL_SENT     0x40000 /* ACKALL has been sent on the call */
00172 
00173 #endif
00174 
00175 
00176 /* Configurable parameters */
00177 #define RX_IDLE_DEAD_TIME       60      /* default idle dead time */
00178 #define RX_MAX_SERVICES         20      /* Maximum number of services that may be installed */
00179 #if defined(KERNEL) && defined(AFS_AIX51_ENV) && defined(__64__)
00180 #define RX_DEFAULT_STACK_SIZE   24000
00181 #else
00182 #define RX_DEFAULT_STACK_SIZE   16000   /* Default process stack size; overriden by rx_SetStackSize */
00183 #endif
00184 
00185 /* This parameter should not normally be changed */
00186 #define RX_PROCESS_PRIORITY     LWP_NORMAL_PRIORITY
00187 
00188 #define ADDRSPERSITE 16
00189 
00190 #ifndef KDUMP_RX_LOCK
00191 /* Bottom n-bits of the Call Identifier give the call number */
00192 #define RX_MAXCALLS 4           /* Power of 2; max async calls per connection */
00193 #define RX_CIDSHIFT 2           /* Log2(RX_MAXCALLS) */
00194 #define RX_CHANNELMASK (RX_MAXCALLS-1)
00195 #define RX_CIDMASK  (~RX_CHANNELMASK)
00196 #endif /* !KDUMP_RX_LOCK */
00197 
00198 #ifndef KERNEL
00199 typedef void (*rx_destructor_t) (void *);
00200 int rx_KeyCreate(rx_destructor_t);
00201 osi_socket rxi_GetHostUDPSocket(u_int host, u_short port);
00202 osi_socket rxi_GetUDPSocket(u_short port);
00203 #endif /* KERNEL */
00204 
00205 
00206 int ntoh_syserr_conv(int error);
00207 
00208 #define RX_WAIT     1
00209 #define RX_DONTWAIT 0
00210 
00211 #define rx_GetLocalStatus(call, status) ((call)->localStatus)
00212 
00213 
00214 static_inline int
00215 rx_IsLoopbackAddr(afs_uint32 addr)
00216 {
00217     return ((addr & 0xffff0000) == 0x7f000000);
00218 }
00219 
00220 /*******************
00221  * Macros callable by the user to further define attributes of a
00222  * service.  Must be called before rx_StartServer
00223  */
00224 
00225 /* Set the service stack size.  This currently just sets the stack
00226  * size for all processes to be the maximum seen, so far */
00227 #define rx_SetStackSize(service, stackSize) \
00228   rx_stackSize = (((stackSize) > rx_stackSize)? stackSize: rx_stackSize)
00229 
00230 /* Set minimum number of processes guaranteed to be available for this
00231  * service at all times */
00232 #define rx_SetMinProcs(service, min) ((service)->minProcs = (min))
00233 
00234 /* Set maximum number of processes that will be made available to this
00235  * service (also a guarantee that this number will be made available
00236  * if there is no competition) */
00237 #define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max))
00238 
00239 /* Define a procedure to be called just before a server connection is destroyed */
00240 #define rx_SetDestroyConnProc(service,proc) ((service)->destroyConnProc = (proc))
00241 
00242 /* Define procedure to set service dead time */
00243 #define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time))
00244 
00245 /*
00246  * Define error to return in server connections when failing to answer.
00247  * (server only) For example, AFS viced sends VNOSERVICE.
00248  */
00249 #define rx_SetServerIdleDeadErr(service,err) ((service)->idleDeadErr = (err))
00250 
00251 /* Define procedures for getting and setting before and after execute-request procs */
00252 #define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc))
00253 #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
00254 #define rx_GetAfterProc(service) ((service)->afterProc)
00255 #define rx_GetBeforeProc(service) ((service)->beforeProc)
00256 #define rx_SetPostProc(service,proc) ((service)->postProc = (proc))
00257 #define rx_GetPostProc(service) ((service)->postProc)
00258 
00259 /* Define a procedure to be called when a server connection is created */
00260 #define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc))
00261 
00262 /* NOTE:  We'll probably redefine the following three routines, again, sometime. */
00263 
00264 /* Set the connection dead time for any connections created for this service (server only) */
00265 #define rx_SetServiceDeadTime(service, seconds) ((service)->secondsUntilDead = (seconds))
00266 
00267 /* Enable or disable asymmetric client checking for a service */
00268 #define rx_SetCheckReach(service, x) ((service)->checkReach = (x))
00269 
00270 /* Set the overload threshold and the overload error */
00271 #define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code))
00272 
00273 /* If this flag is set,no new requests are processed by rx, all new requests are
00274 returned with an error code of RX_CALL_DEAD ( transient error ) */
00275 #define rx_SetRxTranquil()              (rx_tranquil = 1)
00276 #define rx_ClearRxTranquil()            (rx_tranquil = 0)
00277 
00278 /* Set the threshold and time to delay aborts for consecutive errors */
00279 #define rx_SetCallAbortThreshold(A) (rxi_callAbortThreshhold = (A))
00280 #define rx_SetCallAbortDelay(A) (rxi_callAbortDelay = (A))
00281 #define rx_SetConnAbortThreshold(A) (rxi_connAbortThreshhold = (A))
00282 #define rx_SetConnAbortDelay(A) (rxi_connAbortDelay = (A))
00283 
00284 
00285 
00286 #define cpspace(call) ((call)->curlen)
00287 #define cppos(call) ((call)->curpos)
00288 
00289 #define rx_Read(call, buf, nbytes)   rx_ReadProc(call, buf, nbytes)
00290 #define rx_Read32(call, value)   rx_ReadProc32(call, value)
00291 #define rx_Readv(call, iov, nio, maxio, nbytes) \
00292    rx_ReadvProc(call, iov, nio, maxio, nbytes)
00293 #define rx_Write(call, buf, nbytes) rx_WriteProc(call, buf, nbytes)
00294 #define rx_Write32(call, value) rx_WriteProc32(call, value)
00295 #define rx_Writev(call, iov, nio, nbytes) \
00296    rx_WritevProc(call, iov, nio, nbytes)
00297 
00298 /* This is the maximum size data packet that can be sent on this connection, accounting for security module-specific overheads. */
00299 #define rx_MaxUserDataSize(call)                ((call)->MTU - RX_HEADER_SIZE - (call)->conn->securityHeaderSize - (call)->conn->securityMaxTrailerSize)
00300 
00301 /* Macros to turn the hot thread feature on and off. Enabling hot threads
00302  * allows the listener thread to trade places with an idle worker thread,
00303  * which moves the context switch from listener to worker out of the
00304  * critical path.
00305  */
00306 #define rx_EnableHotThread()            (rx_enable_hot_thread = 1)
00307 #define rx_DisableHotThread()           (rx_enable_hot_thread = 0)
00308 
00309 #define rx_PutConnection(conn) rx_DestroyConnection(conn)
00310 
00311 /* A service is installed by rx_NewService, and specifies a service type that
00312  * is exported by this process.  Incoming calls are stamped with the service
00313  * type, and must match an installed service for the call to be accepted.
00314  * Each service exported has a (port,serviceId) pair to uniquely identify it.
00315  * It is also named:  this is intended to allow a remote statistics gathering
00316  * program to retrieve per service statistics without having to know the local
00317  * service id's.  Each service has a number of
00318  */
00319 
00320 /* security objects (instances of security classes) which implement
00321  * various types of end-to-end security protocols for connections made
00322  * to this service.  Finally, there are two parameters controlling the
00323  * number of requests which may be executed in parallel by this
00324  * service: minProcs is the number of requests to this service which
00325  * are guaranteed to be able to run in parallel at any time; maxProcs
00326  * has two meanings: it limits the total number of requests which may
00327  * execute in parallel and it also guarantees that that many requests
00328  * may be handled in parallel if no other service is handling any
00329  * requests. */
00330 
00331 struct rx_service {
00332     u_short serviceId;          /* Service number */
00333     afs_uint32 serviceHost;     /* IP address for this service */
00334     u_short servicePort;        /* UDP port for this service */
00335     char *serviceName;          /* Name of the service */
00336     osi_socket socket;          /* socket structure or file descriptor */
00337     u_short nRequestsRunning;   /* Number of requests currently in progress */
00338     u_short nSecurityObjects;   /* Number of entries in security objects array */
00339     struct rx_securityClass **securityObjects;  /* Array of security class objects */
00340       afs_int32(*executeRequestProc) (struct rx_call * acall);  /* Routine to call when an rpc request is received */
00341     void (*destroyConnProc) (struct rx_connection * tcon);      /* Routine to call when a server connection is destroyed */
00342     void (*newConnProc) (struct rx_connection * tcon);  /* Routine to call when a server connection is created */
00343     void (*beforeProc) (struct rx_call * acall);        /* routine to call before a call is executed */
00344     void (*afterProc) (struct rx_call * acall, afs_int32 code); /* routine to call after a call is executed */
00345     void (*postProc) (afs_int32 code);  /* routine to call after the call has ended */
00346     u_short maxProcs;           /* Maximum procs to be used for this service */
00347     u_short minProcs;           /* Minimum # of requests guaranteed executable simultaneously */
00348     u_short connDeadTime;       /* Seconds until a client of this service will be declared dead, if it is not responding */
00349     u_short idleDeadTime;       /* Time a server will wait for I/O to start up again */
00350     u_char checkReach;          /* Check for asymmetric clients? */
00351     afs_int32 idleDeadErr;
00352     int nSpecific;              /* number entries in specific data */
00353     void **specific;            /* pointer to connection specific data */
00354 #ifdef  RX_ENABLE_LOCKS
00355     afs_kmutex_t svc_data_lock; /* protect specific data */
00356 #endif
00357 
00358 };
00359 
00360 #endif /* KDUMP_RX_LOCK */
00361 
00362 /* A server puts itself on an idle queue for a service using an
00363  * instance of the following structure.  When a call arrives, the call
00364  * structure pointer is placed in "newcall", the routine to execute to
00365  * service the request is placed in executeRequestProc, and the
00366  * process is woken up.  The queue entry's address is used for the
00367  * sleep/wakeup. If socketp is non-null, then this thread is willing
00368  * to become a listener thread. A thread sets *socketp to -1 before
00369  * sleeping. If *socketp is not -1 when the thread awakes, it is now
00370  * the listener thread for *socketp. When socketp is non-null, tno
00371  * contains the server's threadID, which is used to make decitions in GetCall.
00372  */
00373 #ifdef KDUMP_RX_LOCK
00374 struct rx_serverQueueEntry_rx_lock {
00375 #else
00376 struct rx_serverQueueEntry {
00377 #endif
00378     struct rx_queue queueItemHeader;
00379 #ifdef KDUMP_RX_LOCK
00380     struct rx_call_rx_lock *newcall;
00381 #else
00382     struct rx_call *newcall;
00383 #endif
00384 #ifdef  RX_ENABLE_LOCKS
00385     afs_kmutex_t lock;
00386     afs_kcondvar_t cv;
00387 #endif
00388     int tno;
00389     osi_socket *socketp;
00390 };
00391 
00392 #ifndef KDUMP_RX_LOCK
00393 /* Flag bits for connection structure */
00394 #define RX_CONN_MAKECALL_WAITING    1   /* rx_NewCall is waiting for a channel */
00395 #define RX_CONN_DESTROY_ME          2   /* Destroy *client* connection after last call */
00396 #define RX_CONN_USING_PACKET_CKSUM  4   /* non-zero header.spare field seen */
00397 #define RX_CONN_KNOW_WINDOW         8   /* window size negotiation works */
00398 #define RX_CONN_RESET              16   /* connection is reset, remove */
00399 #define RX_CONN_BUSY               32   /* connection is busy; don't delete */
00400 #define RX_CONN_ATTACHWAIT         64   /* attach waiting for peer->lastReach */
00401 #define RX_CONN_MAKECALL_ACTIVE   128   /* a thread is actively in rx_NewCall */
00402 #define RX_CONN_NAT_PING          256   /* nat ping requested */
00403 
00404 /* Type of connection, client or server */
00405 #define RX_CLIENT_CONNECTION    0
00406 #define RX_SERVER_CONNECTION    1
00407 #endif /* !KDUMP_RX_LOCK */
00408 
00409 /* Maximum number of acknowledgements in an acknowledge packet */
00410 #define RX_MAXACKS          255
00411 
00412 #ifndef KDUMP_RX_LOCK
00413 
00414 /* The structure of the data portion of an acknowledge packet: An acknowledge
00415  * packet is in network byte order at all times.  An acknowledgement is always
00416  * prompted for a specific reason by a specific incoming packet.  This reason
00417  * is reported in "reason" and the packet's sequence number in the packet
00418  * header.seq.  In addition to this information, all of the current
00419  * acknowledgement information about this call is placed in the packet.
00420  * "FirstPacket" is the sequence number of the first packet represented in an
00421  * array of bytes, "acks", containing acknowledgement information for a number
00422  * of consecutive packets.  All packets prior to FirstPacket are implicitly
00423  * acknowledged: the sender need no longer be concerned about them.  Packets
00424  * from firstPacket+nAcks and on are not acknowledged.  Packets in the range
00425  * [firstPacket,firstPacket+nAcks) are each acknowledged explicitly.  The
00426  * acknowledgement may be RX_NACK if the packet is not (currently) at the
00427  * receiver (it may have never been received, or received and then later
00428  * dropped), or it may be RX_ACK if the packet is queued up waiting to be read
00429  * by the upper level software.  RX_ACK does not imply that the packet may not
00430  * be dropped before it is read; it does imply that the sender should stop
00431  * retransmitting the packet until notified otherwise.  The field
00432  * previousPacket identifies the previous packet received by the peer.  This
00433  * was used in a previous version of this software, and could be used in the
00434  * future.  The serial number in the data part of the ack packet corresponds to
00435  * the serial number oof the packet which prompted the acknowledge.  Any
00436  * packets which are explicitly not acknowledged, and which were last
00437  * transmitted with a serial number less than the provided serial number,
00438  * should be retransmitted immediately.  Actually, this is slightly inaccurate:
00439  * packets are not necessarily received in order.  When packets are habitually
00440  * transmitted out of order, this is allowed for in the retransmission
00441  * algorithm by introducing the notion of maximum packet skew: the degree of
00442  * out-of-orderness of the packets received on the wire.  This number is
00443  * communicated from the receiver to the sender in ack packets. */
00444 
00445 struct rx_ackPacket {
00446     u_short bufferSpace;        /* Number of packet buffers available.  That is:  the number of buffers that the sender of the ack packet is willing to provide for data, on this or subsequent calls.  Lying is permissable. */
00447     u_short maxSkew;            /* Maximum difference between serial# of packet acknowledged and highest packet yet received */
00448     afs_uint32 firstPacket;     /* The first packet in the list of acknowledged packets */
00449     afs_uint32 previousPacket;  /* The previous packet number received (obsolete?) */
00450     afs_uint32 serial;          /* Serial number of the packet which prompted the acknowledge */
00451     u_char reason;              /* Reason for the acknowledge of ackPacket, defined below */
00452     u_char nAcks;               /* Number of acknowledgements */
00453     u_char acks[RX_MAXACKS];    /* Up to RX_MAXACKS packet acknowledgements, defined below */
00454     /* Packets <firstPacket are implicitly acknowledged and may be discarded by the sender.  Packets >= firstPacket+nAcks are implicitly NOT acknowledged.  No packets with sequence numbers >= firstPacket should be discarded by the sender (they may thrown out at any time by the receiver) */
00455 };
00456 
00457 #define FIRSTACKOFFSET 4
00458 
00459 /* Reason for acknowledge message */
00460 #define RX_ACK_REQUESTED        1       /* Peer requested an ack on this packet */
00461 #define RX_ACK_DUPLICATE        2       /* Duplicate packet */
00462 #define RX_ACK_OUT_OF_SEQUENCE  3       /* Packet out of sequence */
00463 #define RX_ACK_EXCEEDS_WINDOW   4       /* Packet sequence number higher than window; discarded */
00464 #define RX_ACK_NOSPACE          5       /* No buffer space at all */
00465 #define RX_ACK_PING             6       /* This is a keep-alive ack */
00466 #define RX_ACK_PING_RESPONSE    7       /* Ack'ing because we were pinged */
00467 #define RX_ACK_DELAY            8       /* Ack generated since nothing has happened since receiving packet */
00468 #define RX_ACK_IDLE             9       /* Similar to RX_ACK_DELAY, but can
00469                                          * be used to compute RTT */
00470 #define RX_ACK_MTU             -1       /* will be rewritten to ACK_PING */
00471 
00472 /* Packet acknowledgement type */
00473 #define RX_ACK_TYPE_NACK        0       /* I Don't have this packet */
00474 #define RX_ACK_TYPE_ACK         1       /* I have this packet, although I may discard it later */
00475 
00476 /* The packet size transmitted for an acknowledge is adjusted to reflect the actual size of the acks array.  This macro defines the size */
00477 #define rx_AckDataSize(nAcks) (3 + nAcks + offsetof(struct rx_ackPacket, acks[0]))
00478 
00479 #define RX_CHALLENGE_TIMEOUT    2       /* Number of seconds before another authentication request packet is generated */
00480 #define RX_CHALLENGE_MAXTRIES   50      /* Max # of times we resend challenge */
00481 #define RX_CHECKREACH_TIMEOUT   2       /* Number of seconds before another ping is generated */
00482 #define RX_CHECKREACH_TTL       60      /* Re-check reachability this often */
00483 
00484 /*
00485  * RX error codes.  RX uses error codes from -1 to -64 and -100.
00486  * Rxgen uses other error codes < -64 (see src/rxgen/rpc_errors.h);
00487  * user programs are expected to return positive error codes
00488  */
00489 
00490 /* Something bad happened to the connection; temporary loss of communication */
00491 #define RX_CALL_DEAD                (-1)
00492 
00493 /*
00494  * An invalid operation, such as a client attempting to send data
00495  * after having received the beginning of a reply from the server.
00496  */
00497 #define RX_INVALID_OPERATION        (-2)
00498 
00499 /* An optional timeout per call may be specified */
00500 #define RX_CALL_TIMEOUT             (-3)
00501 
00502 /* End of data on a read.  Not currently in use. */
00503 #define RX_EOF                      (-4)
00504 
00505 /* Some sort of low-level protocol error. */
00506 #define RX_PROTOCOL_ERROR           (-5)
00507 
00508 /*
00509  * Generic user abort code; used when no more specific error code needs to be
00510  * communicated.  For example, multi rx clients use this code to abort a multi-
00511  * rx call.
00512  */
00513 #define RX_USER_ABORT               (-6)
00514 
00515 /* Port already in use (from rx_Init).  This error is never sent on the wire. */
00516 #define RX_ADDRINUSE                (-7)
00517 
00518 /* EMSGSIZE returned from network.  Packet too big, must fragment */
00519 #define RX_MSGSIZE                  (-8)
00520 
00521 /*
00522  * Idle dead timeout error.  This error is never sent on the wire.
00523  * rxi_SendCallAbort() translates RX_CALL_IDLE to RX_CALL_TIMEOUT.
00524  */
00525 #define RX_CALL_IDLE                (-9)
00526 
00527 /*
00528  * Busy call channel error.  This error is never sent on the wire.
00529  * rxi_SendCallAbort() translates RX_CALL_BUSY to RX_CALL_TIMEOUT.
00530  */
00531 #define RX_CALL_BUSY                (-10)
00532 
00533 /* transient failure detected ( possibly the server is restarting ) */
00534 /* this should be equal to VRESTARTING ( util/errors.h ) for old clients to work */
00535 #define RX_RESTARTING               (-100)
00536 
00537 typedef enum {
00538     RX_SECIDX_NULL = 0,
00539     RX_SECIDX_KAD  = 2,
00540     RX_SECIDX_GK   = 4,
00541     RX_SECIDX_K5   = 5,
00542 } rx_securityIndex;
00543 
00544 struct rx_securityObjectStats {
00545     char type;                  /* 0:unk 1:null,2:vab 3:kad */
00546     char level;
00547     char sparec[10];            /* force correct alignment */
00548     afs_int32 flags;            /* 1=>unalloc, 2=>auth, 4=>expired */
00549     afs_uint32 expires;
00550     afs_uint32 packetsReceived;
00551     afs_uint32 packetsSent;
00552     afs_uint32 bytesReceived;
00553     afs_uint32 bytesSent;
00554     short spares[4];
00555     afs_int32 sparel[8];
00556 };
00557 
00558 /* Configuration settings */
00559 
00560 /* Enum for storing configuration variables which can be set via the
00561  * SetConfiguration method in the rx_securityClass, below
00562  */
00563 
00564 typedef enum {
00565      RXS_CONFIG_FLAGS /* afs_uint32 set of bitwise flags */
00566 } rx_securityConfigVariables;
00567 
00568 /* For the RXS_CONFIG_FLAGS, the following bit values are defined */
00569 
00570 /* Disable the principal name contains dot check in rxkad */
00571 #define RXS_CONFIG_FLAGS_DISABLE_DOTCHECK       0x01
00572 
00573 /* XXXX (rewrite this description) A security class object contains a set of
00574  * procedures and some private data to implement a security model for rx
00575  * connections.  These routines are called by rx as appropriate.  Rx knows
00576  * nothing about the internal details of any particular security model, or
00577  * about security state.  Rx does maintain state per connection on behalf of
00578  * the security class.  Each security class implementation is also expected to
00579  * provide routines to create these objects.  Rx provides a basic routine to
00580  * allocate one of these objects; this routine must be called by the class. */
00581 struct rx_securityClass {
00582     struct rx_securityOps {
00583         int (*op_Close) (struct rx_securityClass * aobj);
00584         int (*op_NewConnection) (struct rx_securityClass * aobj,
00585                                  struct rx_connection * aconn);
00586         int (*op_PreparePacket) (struct rx_securityClass * aobj,
00587                                  struct rx_call * acall,
00588                                  struct rx_packet * apacket);
00589         int (*op_SendPacket) (struct rx_securityClass * aobj,
00590                               struct rx_call * acall,
00591                               struct rx_packet * apacket);
00592         int (*op_CheckAuthentication) (struct rx_securityClass * aobj,
00593                                        struct rx_connection * aconn);
00594         int (*op_CreateChallenge) (struct rx_securityClass * aobj,
00595                                    struct rx_connection * aconn);
00596         int (*op_GetChallenge) (struct rx_securityClass * aobj,
00597                                 struct rx_connection * aconn,
00598                                 struct rx_packet * apacket);
00599         int (*op_GetResponse) (struct rx_securityClass * aobj,
00600                                struct rx_connection * aconn,
00601                                struct rx_packet * apacket);
00602         int (*op_CheckResponse) (struct rx_securityClass * aobj,
00603                                  struct rx_connection * aconn,
00604                                  struct rx_packet * apacket);
00605         int (*op_CheckPacket) (struct rx_securityClass * aobj,
00606                                struct rx_call * acall,
00607                                struct rx_packet * apacket);
00608         int (*op_DestroyConnection) (struct rx_securityClass * aobj,
00609                                      struct rx_connection * aconn);
00610         int (*op_GetStats) (struct rx_securityClass * aobj,
00611                             struct rx_connection * aconn,
00612                             struct rx_securityObjectStats * astats);
00613         int (*op_SetConfiguration) (struct rx_securityClass * aobj,
00614                                     struct rx_connection * aconn,
00615                                     rx_securityConfigVariables atype,
00616                                     void * avalue,
00617                                     void ** acurrentValue);
00618         int (*op_Spare2) (void);
00619         int (*op_Spare3) (void);
00620     } *ops;
00621     void *privateData;
00622     int refCount;
00623 };
00624 
00625 #define RXS_OP(obj,op,args) ((obj && (obj->ops->op_ ## op)) ? (*(obj)->ops->op_ ## op)args : 0)
00626 
00627 #define RXS_Close(obj) RXS_OP(obj,Close,(obj))
00628 #define RXS_NewConnection(obj,conn) RXS_OP(obj,NewConnection,(obj,conn))
00629 #define RXS_PreparePacket(obj,call,packet) RXS_OP(obj,PreparePacket,(obj,call,packet))
00630 #define RXS_SendPacket(obj,call,packet) RXS_OP(obj,SendPacket,(obj,call,packet))
00631 #define RXS_CheckAuthentication(obj,conn) RXS_OP(obj,CheckAuthentication,(obj,conn))
00632 #define RXS_CreateChallenge(obj,conn) RXS_OP(obj,CreateChallenge,(obj,conn))
00633 #define RXS_GetChallenge(obj,conn,packet) RXS_OP(obj,GetChallenge,(obj,conn,packet))
00634 #define RXS_GetResponse(obj,conn,packet) RXS_OP(obj,GetResponse,(obj,conn,packet))
00635 #define RXS_CheckResponse(obj,conn,packet) RXS_OP(obj,CheckResponse,(obj,conn,packet))
00636 #define RXS_CheckPacket(obj,call,packet) RXS_OP(obj,CheckPacket,(obj,call,packet))
00637 #define RXS_DestroyConnection(obj,conn) RXS_OP(obj,DestroyConnection,(obj,conn))
00638 #define RXS_GetStats(obj,conn,stats) RXS_OP(obj,GetStats,(obj,conn,stats))
00639 #define RXS_SetConfiguration(obj, conn, type, value, currentValue) RXS_OP(obj, SetConfiguration,(obj,conn,type,value,currentValue))
00640 
00641 
00642 
00643 /* Structure for keeping rx statistics.  Note that this structure is returned
00644  * by rxdebug, so, for compatibility reasons, new fields should be appended (or
00645  * spares used), the rxdebug protocol checked, if necessary, and the PrintStats
00646  * code should be updated as well.
00647  *
00648  * Clearly we assume that ntohl will work on these structures so sizeof(int)
00649  * must equal sizeof(afs_int32). */
00650 
00651 struct rx_statistics {          /* General rx statistics */
00652     int packetRequests;         /* Number of packet allocation requests */
00653     int receivePktAllocFailures;
00654     int sendPktAllocFailures;
00655     int specialPktAllocFailures;
00656     int socketGreedy;           /* Whether SO_GREEDY succeeded */
00657     int bogusPacketOnRead;      /* Number of inappropriately short packets received */
00658     int bogusHost;              /* Host address from bogus packets */
00659     int noPacketOnRead;         /* Number of read packets attempted when there was actually no packet to read off the wire */
00660     int noPacketBuffersOnRead;  /* Number of dropped data packets due to lack of packet buffers */
00661     int selects;                /* Number of selects waiting for packet or timeout */
00662     int sendSelects;            /* Number of selects forced when sending packet */
00663     int packetsRead[RX_N_PACKET_TYPES]; /* Total number of packets read, per type */
00664     int dataPacketsRead;        /* Number of unique data packets read off the wire */
00665     int ackPacketsRead;         /* Number of ack packets read */
00666     int dupPacketsRead;         /* Number of duplicate data packets read */
00667     int spuriousPacketsRead;    /* Number of inappropriate data packets */
00668     int packetsSent[RX_N_PACKET_TYPES]; /* Number of rxi_Sends: packets sent over the wire, per type */
00669     int ackPacketsSent;         /* Number of acks sent */
00670     int pingPacketsSent;        /* Total number of ping packets sent */
00671     int abortPacketsSent;       /* Total number of aborts */
00672     int busyPacketsSent;        /* Total number of busies sent received */
00673     int dataPacketsSent;        /* Number of unique data packets sent */
00674     int dataPacketsReSent;      /* Number of retransmissions */
00675     int dataPacketsPushed;      /* Number of retransmissions pushed early by a NACK */
00676     int ignoreAckedPacket;      /* Number of packets with acked flag, on rxi_Start */
00677     struct clock totalRtt;      /* Total round trip time measured (use to compute average) */
00678     struct clock minRtt;        /* Minimum round trip time measured */
00679     struct clock maxRtt;        /* Maximum round trip time measured */
00680     int nRttSamples;            /* Total number of round trip samples */
00681     int nServerConns;           /* Total number of server connections */
00682     int nClientConns;           /* Total number of client connections */
00683     int nPeerStructs;           /* Total number of peer structures */
00684     int nCallStructs;           /* Total number of call structures allocated */
00685     int nFreeCallStructs;       /* Total number of previously allocated free call structures */
00686     int netSendFailures;
00687     afs_int32 fatalErrors;
00688     int ignorePacketDally;      /* packets dropped because call is in dally state */
00689     int receiveCbufPktAllocFailures;
00690     int sendCbufPktAllocFailures;
00691     int nBusies;
00692     int spares[4];
00693 };
00694 
00695 /* structures for debug input and output packets */
00696 
00697 /* debug input types */
00698 struct rx_debugIn {
00699     afs_int32 type;
00700     afs_int32 index;
00701 };
00702 
00703 /* Invalid rx debug package type */
00704 #define RX_DEBUGI_BADTYPE     (-8)
00705 
00706 #define RX_DEBUGI_VERSION_MINIMUM ('L') /* earliest real version */
00707 #define RX_DEBUGI_VERSION     ('S')    /* Latest version */
00708     /* first version w/ secStats */
00709 #define RX_DEBUGI_VERSION_W_SECSTATS ('L')
00710     /* version M is first supporting GETALLCONN and RXSTATS type */
00711 #define RX_DEBUGI_VERSION_W_GETALLCONN ('M')
00712 #define RX_DEBUGI_VERSION_W_RXSTATS ('M')
00713     /* last version with unaligned debugConn */
00714 #define RX_DEBUGI_VERSION_W_UNALIGNED_CONN ('L')
00715 #define RX_DEBUGI_VERSION_W_WAITERS ('N')
00716 #define RX_DEBUGI_VERSION_W_IDLETHREADS ('O')
00717 #define RX_DEBUGI_VERSION_W_NEWPACKETTYPES ('P')
00718 #define RX_DEBUGI_VERSION_W_GETPEER ('Q')
00719 #define RX_DEBUGI_VERSION_W_WAITED ('R')
00720 #define RX_DEBUGI_VERSION_W_PACKETS ('S')
00721 
00722 #define RX_DEBUGI_GETSTATS      1       /* get basic rx stats */
00723 #define RX_DEBUGI_GETCONN       2       /* get connection info */
00724 #define RX_DEBUGI_GETALLCONN    3       /* get even uninteresting conns */
00725 #define RX_DEBUGI_RXSTATS       4       /* get all rx stats */
00726 #define RX_DEBUGI_GETPEER       5       /* get all peer structs */
00727 
00728 struct rx_debugStats {
00729     afs_int32 nFreePackets;
00730     afs_int32 packetReclaims;
00731     afs_int32 callsExecuted;
00732     char waitingForPackets;
00733     char usedFDs;
00734     char version;
00735     char spare1;
00736     afs_int32 nWaiting;
00737     afs_int32 idleThreads;      /* Number of server threads that are idle */
00738     afs_int32 nWaited;
00739     afs_int32 nPackets;
00740     afs_int32 spare2[6];
00741 };
00742 
00743 struct rx_debugConn_vL {
00744     afs_uint32 host;
00745     afs_int32 cid;
00746     afs_int32 serial;
00747     afs_int32 callNumber[RX_MAXCALLS];
00748     afs_int32 error;
00749     short port;
00750     char flags;
00751     char type;
00752     char securityIndex;
00753     char callState[RX_MAXCALLS];
00754     char callMode[RX_MAXCALLS];
00755     char callFlags[RX_MAXCALLS];
00756     char callOther[RX_MAXCALLS];
00757     /* old style getconn stops here */
00758     struct rx_securityObjectStats secStats;
00759     afs_int32 sparel[10];
00760 };
00761 
00762 struct rx_debugConn {
00763     afs_uint32 host;
00764     afs_int32 cid;
00765     afs_int32 serial;
00766     afs_int32 callNumber[RX_MAXCALLS];
00767     afs_int32 error;
00768     short port;
00769     char flags;
00770     char type;
00771     char securityIndex;
00772     char sparec[3];             /* force correct alignment */
00773     char callState[RX_MAXCALLS];
00774     char callMode[RX_MAXCALLS];
00775     char callFlags[RX_MAXCALLS];
00776     char callOther[RX_MAXCALLS];
00777     /* old style getconn stops here */
00778     struct rx_securityObjectStats secStats;
00779     afs_int32 epoch;
00780     afs_int32 natMTU;
00781     afs_int32 sparel[9];
00782 };
00783 
00784 struct rx_debugPeer {
00785     afs_uint32 host;
00786     u_short port;
00787     u_short ifMTU;
00788     afs_uint32 idleWhen;
00789     short refCount;
00790     u_char burstSize;
00791     u_char burst;
00792     struct clock burstWait;
00793     afs_int32 rtt;
00794     afs_int32 rtt_dev;
00795     struct clock timeout;
00796     afs_int32 nSent;
00797     afs_int32 reSends;
00798     afs_int32 inPacketSkew;
00799     afs_int32 outPacketSkew;
00800     afs_int32 rateFlag;
00801     u_short natMTU;
00802     u_short maxMTU;
00803     u_short maxDgramPackets;
00804     u_short ifDgramPackets;
00805     u_short MTU;
00806     u_short cwind;
00807     u_short nDgramPackets;
00808     u_short congestSeq;
00809     afs_hyper_t bytesSent;
00810     afs_hyper_t bytesReceived;
00811     afs_int32 sparel[10];
00812 };
00813 
00814 #define RX_OTHER_IN     1       /* packets avail in in queue */
00815 #define RX_OTHER_OUT    2       /* packets avail in out queue */
00816 
00817 #define RX_SERVER_DEBUG_SEC_STATS               0x1
00818 #define RX_SERVER_DEBUG_ALL_CONN                0x2
00819 #define RX_SERVER_DEBUG_RX_STATS                0x4
00820 #define RX_SERVER_DEBUG_WAITER_CNT              0x8
00821 #define RX_SERVER_DEBUG_IDLE_THREADS            0x10
00822 #define RX_SERVER_DEBUG_OLD_CONN                0x20
00823 #define RX_SERVER_DEBUG_NEW_PACKETS             0x40
00824 #define RX_SERVER_DEBUG_ALL_PEER                0x80
00825 #define RX_SERVER_DEBUG_WAITED_CNT              0x100
00826 #define RX_SERVER_DEBUG_PACKETS_CNT              0x200
00827 
00828 #define AFS_RX_STATS_CLEAR_ALL                  0xffffffff
00829 #define AFS_RX_STATS_CLEAR_INVOCATIONS          0x1
00830 #define AFS_RX_STATS_CLEAR_BYTES_SENT           0x2
00831 #define AFS_RX_STATS_CLEAR_BYTES_RCVD           0x4
00832 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_SUM       0x8
00833 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_SQUARE    0x10
00834 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_MIN       0x20
00835 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_MAX       0x40
00836 #define AFS_RX_STATS_CLEAR_EXEC_TIME_SUM        0x80
00837 #define AFS_RX_STATS_CLEAR_EXEC_TIME_SQUARE     0x100
00838 #define AFS_RX_STATS_CLEAR_EXEC_TIME_MIN        0x200
00839 #define AFS_RX_STATS_CLEAR_EXEC_TIME_MAX        0x400
00840 
00841 typedef struct rx_function_entry_v1 {
00842     afs_uint32 remote_peer;
00843     afs_uint32 remote_port;
00844     afs_uint32 remote_is_server;
00845     afs_uint32 interfaceId;
00846     afs_uint32 func_total;
00847     afs_uint32 func_index;
00848     afs_uint64 invocations;
00849     afs_uint64 bytes_sent;
00850     afs_uint64 bytes_rcvd;
00851     struct clock queue_time_sum;
00852     struct clock queue_time_sum_sqr;
00853     struct clock queue_time_min;
00854     struct clock queue_time_max;
00855     struct clock execution_time_sum;
00856     struct clock execution_time_sum_sqr;
00857     struct clock execution_time_min;
00858     struct clock execution_time_max;
00859 } rx_function_entry_v1_t, *rx_function_entry_v1_p;
00860 
00861 /*
00862  * If you need to change rx_function_entry, you should probably create a brand
00863  * new structure.  Keeping the old structure will allow backwards compatibility
00864  * with old clients (even if it is only used to calculate allocation size).
00865  * If you do change the size or the format, you'll need to bump
00866  * RX_STATS_RETRIEVAL_VERSION.  This allows some primitive form
00867  * of versioning a la rxdebug.
00868  */
00869 
00870 #define RX_STATS_RETRIEVAL_VERSION 1    /* latest version */
00871 #define RX_STATS_RETRIEVAL_FIRST_EDITION 1      /* first implementation */
00872 
00873 typedef struct rx_interface_stat {
00874     struct rx_queue queue_header;
00875     struct rx_queue all_peers;
00876     rx_function_entry_v1_t stats[1];    /* make sure this is aligned correctly */
00877 } rx_interface_stat_t, *rx_interface_stat_p;
00878 
00879 #define RX_STATS_SERVICE_ID 409
00880 
00881 #ifdef AFS_NT40_ENV
00882 extern int rx_DumpCalls(FILE *outputFile, char *cookie);
00883 #endif
00884 
00885 #endif /* _RX_   End of rx.h */
00886 
00887 #ifdef  KERNEL
00888 #include "rx/rx_prototypes.h"
00889 #else
00890 #include "rx_prototypes.h"
00891 #endif
00892 
00893 static_inline afs_uint32
00894 RPCOpStat_Peer(void *blob) {
00895     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00896     return rpcop_stat->remote_peer;
00897 }
00898 
00899 static_inline afs_uint32
00900 RPCOpStat_Port(void *blob) {
00901     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00902     return rpcop_stat->remote_port;
00903 }
00904 
00905 static_inline afs_uint32
00906 RPCOpStat_IsServer(void *blob) {
00907     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00908     return rpcop_stat->remote_is_server;
00909 }
00910 
00911 static_inline afs_uint32
00912 RPCOpStat_InterfaceId(void *blob) {
00913     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00914     return rpcop_stat->interfaceId;
00915 }
00916 
00917 static_inline afs_uint32
00918 RPCOpStat_NumFuncs(void *blob) {
00919     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00920     return rpcop_stat->func_total;
00921 }
00922 
00923 static_inline afs_uint32
00924 RPCOpStat_CurFunc(void *blob) {
00925     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00926     return rpcop_stat->func_index;
00927 }
00928 
00929 static_inline struct clock *
00930 RPCOpStat_QTimeSum(void *blob) {
00931     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00932     return &(rpcop_stat->queue_time_sum);
00933 }
00934 
00935 static_inline struct clock *
00936 RPCOpStat_QTimeSumSqr(void *blob) {
00937     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00938     return &(rpcop_stat->queue_time_sum_sqr);
00939 }
00940 
00941 static_inline struct clock *
00942 RPCOpStat_QTimeSumMin(void *blob) {
00943     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00944     return &(rpcop_stat->queue_time_min);
00945 }
00946 
00947 static_inline struct clock *
00948 RPCOpStat_QTimeSumMax(void *blob) {
00949     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00950     return &(rpcop_stat->queue_time_max);
00951 }
00952 
00953 static_inline struct clock *
00954 RPCOpStat_ExecTimeSum(void *blob) {
00955     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00956     return &(rpcop_stat->execution_time_sum);
00957 }
00958 
00959 static_inline struct clock *
00960 RPCOpStat_ExecTimeSumSqr(void *blob) {
00961     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00962     return &(rpcop_stat->execution_time_sum_sqr);
00963 }
00964 
00965 static_inline struct clock *
00966 RPCOpStat_ExecTimeSumMin(void *blob) {
00967     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00968     return &(rpcop_stat->execution_time_min);
00969 }
00970 
00971 static_inline struct clock *
00972 RPCOpStat_ExecTimeSumMax(void *blob) {
00973     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00974     return &(rpcop_stat->execution_time_max);
00975 }
00976 
00977 static_inline afs_uint64
00978 RPCOpStat_NumCalls(void *blob) {
00979     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00980     return rpcop_stat->invocations;
00981 }
00982 
00983 static_inline afs_uint64
00984 RPCOpStat_BytesSent(void *blob) {
00985     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00986     return rpcop_stat->bytes_sent;
00987 }
00988 
00989 static_inline afs_uint64
00990 RPCOpStat_BytesRcvd(void *blob) {
00991     rx_function_entry_v1_p rpcop_stat = (rx_function_entry_v1_p)blob;
00992     return rpcop_stat->bytes_rcvd;
00993 }
00994 #endif /* !KDUMP_RX_LOCK */
 All Data Structures Files Functions Variables