OpenAFS
OpenAFS distributed network file system
|
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 */