2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 /* kdump for SGI needs MP and SP versions of rx_serverQueueEntry,
12 * rx_peer, rx_connection and rx_call structs. rx.h gets included a
13 * second time to pick up mp_ versions of those structs. Currently
14 * the affected struct's have #ifdef's in them for the second pass.
15 * This should change once we start using only ANSI compilers.
16 * Actually, kdump does not use rx_serverQueueEntry, but I'm including
17 * it for completeness.
27 #include "rx_kmutex.h"
28 #include "rx_kernel.h"
29 #if defined (AFS_OBSD_ENV) && !defined (MLEN)
32 #include "netinet/in.h"
33 #include "sys/socket.h"
35 # include <sys/types.h>
38 #ifdef AFS_PTHREAD_ENV
39 # include "rx_pthread.h"
50 # include <netinet/in.h>
51 # include <sys/socket.h>
55 #include <opr/queue.h>
63 /* These items are part of the new RX API. They're living in this section
64 * for now, to keep them separate from everything else... */
70 /* Connection management */
72 extern afs_uint32
rx_GetConnectionEpoch(struct rx_connection
*conn
);
73 extern afs_uint32
rx_GetConnectionId(struct rx_connection
*conn
);
74 extern void *rx_GetSecurityData(struct rx_connection
*conn
);
75 extern void rx_SetSecurityData(struct rx_connection
*conn
, void *data
);
76 extern int rx_IsUsingPktCksum(struct rx_connection
*conn
);
77 extern void rx_SetSecurityHeaderSize(struct rx_connection
*conn
, afs_uint32 size
);
78 extern afs_uint32
rx_GetSecurityHeaderSize(struct rx_connection
*conn
);
79 extern void rx_SetSecurityMaxTrailerSize(struct rx_connection
*conn
, afs_uint32 size
);
80 extern afs_uint32
rx_GetSecurityMaxTrailerSize(struct rx_connection
*conn
);
81 extern void rx_SetMsgsizeRetryErr(struct rx_connection
*conn
, int err
);
82 extern int rx_IsServerConn(struct rx_connection
*conn
);
83 extern int rx_IsClientConn(struct rx_connection
*conn
);
84 extern struct rx_securityClass
*rx_SecurityObjectOf(const struct rx_connection
*);
85 extern struct rx_peer
*rx_PeerOf(struct rx_connection
*);
86 extern u_short
rx_ServiceIdOf(struct rx_connection
*);
87 extern int rx_SecurityClassOf(struct rx_connection
*);
88 extern struct rx_service
*rx_ServiceOf(struct rx_connection
*);
89 extern int rx_ConnError(struct rx_connection
*);
92 extern struct rx_connection
*rx_ConnectionOf(struct rx_call
*call
);
93 extern int rx_Error(struct rx_call
*call
);
94 extern int rx_GetRemoteStatus(struct rx_call
*call
);
95 extern void rx_SetLocalStatus(struct rx_call
*call
, int status
);
96 extern int rx_GetCallAbortCode(struct rx_call
*call
);
97 extern void rx_SetCallAbortCode(struct rx_call
*call
, int code
);
99 extern void rx_RecordCallStatistics(struct rx_call
*call
,
100 unsigned int rxInterface
,
101 unsigned int currentFunc
,
102 unsigned int totalFunc
,
105 /* Peer management */
106 extern afs_uint32
rx_HostOf(struct rx_peer
*peer
);
107 extern u_short
rx_PortOf(struct rx_peer
*peer
);
111 /* Packet classes, for rx_AllocPacket and rx_packetQuota */
112 #define RX_PACKET_CLASS_RECEIVE 0
113 #define RX_PACKET_CLASS_SEND 1
114 #define RX_PACKET_CLASS_SPECIAL 2
115 #define RX_PACKET_CLASS_RECV_CBUF 3
116 #define RX_PACKET_CLASS_SEND_CBUF 4
118 #define RX_N_PACKET_CLASSES 5 /* Must agree with above list */
120 #define RX_PACKET_TYPES {"data", "ack", "busy", "abort", "ackall", "challenge", "response", "debug", "params", "unused", "unused", "unused", "version"}
121 #define RX_N_PACKET_TYPES 13 /* Must agree with above list;
123 * WARNING: if this number ever
124 * grows past 13, rxdebug packets
125 * will need to be modified */
128 /* For most Unixes, maximum elements in an iovec is 16 */
129 #define RX_MAXIOVECS 16 /* limit for ReadvProc/WritevProc */
130 #define RX_MAXWVECS (RX_MAXIOVECS-1) /* need one iovec for packet header */
134 /* Call flags, states and modes are exposed by the debug interface */
135 #ifndef KDUMP_RX_LOCK
136 /* Major call states */
137 #define RX_STATE_NOTINIT 0 /* Call structure has never been initialized */
138 #define RX_STATE_PRECALL 1 /* Server-only: call is not in progress, but packets have arrived */
139 #define RX_STATE_ACTIVE 2 /* An active call; a process is dealing with this call */
140 #define RX_STATE_DALLY 3 /* Dallying after process is done with call */
141 #define RX_STATE_HOLD 4 /* Waiting for acks on reply data packets */
142 #define RX_STATE_RESET 5 /* Call is being reset */
144 /* Call modes: the modes of a call in RX_STATE_ACTIVE state (process attached) */
145 #define RX_MODE_SENDING 1 /* Sending or ready to send */
146 #define RX_MODE_RECEIVING 2 /* Receiving or ready to receive */
147 #define RX_MODE_ERROR 3 /* Something in error for current conversation */
148 #define RX_MODE_EOF 4 /* Server has flushed (or client has read) last reply packet */
151 #define RX_CALL_READER_WAIT 1 /* Reader is waiting for next packet */
152 #define RX_CALL_WAIT_WINDOW_ALLOC 2 /* Sender is waiting for window to allocate buffers */
153 #define RX_CALL_WAIT_WINDOW_SEND 4 /* Sender is waiting for window to send buffers */
154 #define RX_CALL_WAIT_PACKETS 8 /* Sender is waiting for packet buffers */
155 #define RX_CALL_WAIT_PROC 16 /* Waiting for a process to be assigned */
156 #define RX_CALL_RECEIVE_DONE 32 /* All packets received on this call */
157 #define RX_CALL_CLEARED 64 /* Receive queue cleared in precall state */
158 #define RX_CALL_TQ_BUSY 128 /* Call's Xmit Queue is busy; don't modify */
159 #define RX_CALL_TQ_CLEARME 256 /* Need to clear this call's TQ later */
160 #define RX_CALL_TQ_SOME_ACKED 512 /* rxi_Start needs to discard ack'd packets. */
161 #define RX_CALL_TQ_WAIT 1024 /* Reader is waiting for TQ_BUSY to be reset */
162 #define RX_CALL_FAST_RECOVER 2048 /* call is doing congestion recovery */
163 /* 4096 was RX_CALL_FAST_RECOVER_WAIT */
164 #define RX_CALL_SLOW_START_OK 8192 /* receiver acks every other packet */
165 #define RX_CALL_IOVEC_WAIT 16384 /* waiting thread is using an iovec */
166 #define RX_CALL_HAVE_LAST 32768 /* Last packet has been received */
167 #define RX_CALL_NEED_START 0x10000 /* tells rxi_Start to start again */
168 /* 0x20000 was RX_CALL_PEER_BUSY */
169 #define RX_CALL_ACKALL_SENT 0x40000 /* ACKALL has been sent on the call */
170 #define RX_CALL_FLUSH 0x80000 /* Transmit queue should be flushed to peer */
174 /* Configurable parameters */
175 #define RX_IDLE_DEAD_TIME 60 /* default idle dead time */
176 #define RX_MAX_SERVICES 20 /* Maximum number of services that may be installed */
177 #if defined(KERNEL) && defined(AFS_AIX51_ENV) && defined(__64__)
178 #define RX_DEFAULT_STACK_SIZE 24000
180 #define RX_DEFAULT_STACK_SIZE 16000 /* Default process stack size; overriden by rx_SetStackSize */
183 /* This parameter should not normally be changed */
184 #define RX_PROCESS_PRIORITY LWP_NORMAL_PRIORITY
186 #define ADDRSPERSITE 16
188 #ifndef KDUMP_RX_LOCK
189 /* Bottom n-bits of the Call Identifier give the call number */
190 #define RX_MAXCALLS 4 /* Power of 2; max async calls per connection */
191 #define RX_CIDSHIFT 2 /* Log2(RX_MAXCALLS) */
192 #define RX_CHANNELMASK (RX_MAXCALLS-1)
193 #define RX_CIDMASK (~RX_CHANNELMASK)
194 #endif /* !KDUMP_RX_LOCK */
197 typedef void (*rx_destructor_t
) (void *);
198 int rx_KeyCreate(rx_destructor_t
);
199 osi_socket
rxi_GetHostUDPSocket(u_int host
, u_short port
);
200 osi_socket
rxi_GetUDPSocket(u_short port
);
204 int ntoh_syserr_conv(int error
);
207 #define RX_DONTWAIT 0
209 #define rx_GetLocalStatus(call, status) ((call)->localStatus)
213 rx_IsLoopbackAddr(afs_uint32 addr
)
215 return ((addr
& 0xffff0000) == 0x7f000000);
219 * Macros callable by the user to further define attributes of a
220 * service. Must be called before rx_StartServer
223 /* Set the service stack size. This currently just sets the stack
224 * size for all processes to be the maximum seen, so far */
225 #define rx_SetStackSize(service, stackSize) \
226 rx_stackSize = (((stackSize) > rx_stackSize)? stackSize: rx_stackSize)
228 /* Set minimum number of processes guaranteed to be available for this
229 * service at all times */
230 #define rx_SetMinProcs(service, min) ((service)->minProcs = (min))
232 /* Set maximum number of processes that will be made available to this
233 * service (also a guarantee that this number will be made available
234 * if there is no competition) */
235 #define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max))
237 /* Define a procedure to be called just before a server connection is destroyed */
238 #define rx_SetDestroyConnProc(service,proc) ((service)->destroyConnProc = (proc))
240 /* Define procedure to set service dead time */
241 #define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time))
243 /* Define procedures for getting and setting before and after execute-request procs */
244 #define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc))
245 #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
246 #define rx_GetAfterProc(service) ((service)->afterProc)
247 #define rx_GetBeforeProc(service) ((service)->beforeProc)
248 #define rx_SetPostProc(service,proc) ((service)->postProc = (proc))
249 #define rx_GetPostProc(service) ((service)->postProc)
251 /* Define a procedure to be called when a server connection is created */
252 #define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc))
254 /* NOTE: We'll probably redefine the following three routines, again, sometime. */
256 /* Set the connection dead time for any connections created for this service (server only) */
257 #define rx_SetServiceDeadTime(service, seconds) ((service)->secondsUntilDead = (seconds))
259 /* Enable or disable asymmetric client checking for a service */
260 #define rx_SetCheckReach(service, x) ((service)->checkReach = (x))
262 /* Set the overload threshold and the overload error */
263 #define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code))
265 /* If this flag is set,no new requests are processed by rx, all new requests are
266 returned with an error code of RX_CALL_DEAD ( transient error ) */
267 #define rx_SetRxTranquil() (rx_tranquil = 1)
268 #define rx_ClearRxTranquil() (rx_tranquil = 0)
270 /* Set the threshold and time to delay aborts for consecutive errors */
271 #define rx_SetCallAbortThreshold(A) (rxi_callAbortThreshhold = (A))
272 #define rx_SetCallAbortDelay(A) (rxi_callAbortDelay = (A))
273 #define rx_SetConnAbortThreshold(A) (rxi_connAbortThreshhold = (A))
274 #define rx_SetConnAbortDelay(A) (rxi_connAbortDelay = (A))
278 #define cpspace(call) ((call)->curlen)
279 #define cppos(call) ((call)->curpos)
281 #define rx_Read(call, buf, nbytes) rx_ReadProc(call, buf, nbytes)
282 #define rx_Read32(call, value) rx_ReadProc32(call, value)
283 #define rx_Readv(call, iov, nio, maxio, nbytes) \
284 rx_ReadvProc(call, iov, nio, maxio, nbytes)
285 #define rx_Write(call, buf, nbytes) rx_WriteProc(call, buf, nbytes)
286 #define rx_Write32(call, value) rx_WriteProc32(call, value)
287 #define rx_Writev(call, iov, nio, nbytes) \
288 rx_WritevProc(call, iov, nio, nbytes)
290 /* This is the maximum size data packet that can be sent on this connection, accounting for security module-specific overheads. */
291 #define rx_MaxUserDataSize(call) ((call)->MTU - RX_HEADER_SIZE - (call)->conn->securityHeaderSize - (call)->conn->securityMaxTrailerSize)
293 /* Macros to turn the hot thread feature on and off. Enabling hot threads
294 * allows the listener thread to trade places with an idle worker thread,
295 * which moves the context switch from listener to worker out of the
298 #define rx_EnableHotThread() (rx_enable_hot_thread = 1)
299 #define rx_DisableHotThread() (rx_enable_hot_thread = 0)
301 #define rx_PutConnection(conn) rx_DestroyConnection(conn)
303 /* A service is installed by rx_NewService, and specifies a service type that
304 * is exported by this process. Incoming calls are stamped with the service
305 * type, and must match an installed service for the call to be accepted.
306 * Each service exported has a (port,serviceId) pair to uniquely identify it.
307 * It is also named: this is intended to allow a remote statistics gathering
308 * program to retrieve per service statistics without having to know the local
309 * service id's. Each service has a number of
312 /* security objects (instances of security classes) which implement
313 * various types of end-to-end security protocols for connections made
314 * to this service. Finally, there are two parameters controlling the
315 * number of requests which may be executed in parallel by this
316 * service: minProcs is the number of requests to this service which
317 * are guaranteed to be able to run in parallel at any time; maxProcs
318 * has two meanings: it limits the total number of requests which may
319 * execute in parallel and it also guarantees that that many requests
320 * may be handled in parallel if no other service is handling any
324 u_short serviceId
; /* Service number */
325 afs_uint32 serviceHost
; /* IP address for this service */
326 u_short servicePort
; /* UDP port for this service */
327 char *serviceName
; /* Name of the service */
328 osi_socket socket
; /* socket structure or file descriptor */
329 u_short nRequestsRunning
; /* Number of requests currently in progress */
330 u_short nSecurityObjects
; /* Number of entries in security objects array */
331 struct rx_securityClass
**securityObjects
; /* Array of security class objects */
332 afs_int32(*executeRequestProc
) (struct rx_call
* acall
); /* Routine to call when an rpc request is received */
333 void (*destroyConnProc
) (struct rx_connection
* tcon
); /* Routine to call when a server connection is destroyed */
334 void (*newConnProc
) (struct rx_connection
* tcon
); /* Routine to call when a server connection is created */
335 void (*beforeProc
) (struct rx_call
* acall
); /* routine to call before a call is executed */
336 void (*afterProc
) (struct rx_call
* acall
, afs_int32 code
); /* routine to call after a call is executed */
337 void (*postProc
) (afs_int32 code
); /* routine to call after the call has ended */
338 u_short maxProcs
; /* Maximum procs to be used for this service */
339 u_short minProcs
; /* Minimum # of requests guaranteed executable simultaneously */
340 u_short connDeadTime
; /* Seconds until a client of this service will be declared dead, if it is not responding */
341 u_short idleDeadTime
; /* Time a server will wait for I/O to start up again */
342 u_char checkReach
; /* Check for asymmetric clients? */
343 int nSpecific
; /* number entries in specific data */
344 void **specific
; /* pointer to connection specific data */
345 #ifdef RX_ENABLE_LOCKS
346 afs_kmutex_t svc_data_lock
; /* protect specific data */
351 #endif /* KDUMP_RX_LOCK */
353 #ifndef KDUMP_RX_LOCK
354 /* Flag bits for connection structure */
355 #define RX_CONN_MAKECALL_WAITING 1 /* rx_NewCall is waiting for a channel */
356 #define RX_CONN_DESTROY_ME 2 /* Destroy *client* connection after last call */
357 #define RX_CONN_USING_PACKET_CKSUM 4 /* non-zero header.spare field seen */
358 #define RX_CONN_KNOW_WINDOW 8 /* window size negotiation works */
359 #define RX_CONN_RESET 16 /* connection is reset, remove */
360 #define RX_CONN_BUSY 32 /* connection is busy; don't delete */
361 #define RX_CONN_ATTACHWAIT 64 /* attach waiting for peer->lastReach */
362 #define RX_CONN_MAKECALL_ACTIVE 128 /* a thread is actively in rx_NewCall */
363 #define RX_CONN_NAT_PING 256 /* nat ping requested */
365 /* Type of connection, client or server */
366 #define RX_CLIENT_CONNECTION 0
367 #define RX_SERVER_CONNECTION 1
368 #endif /* !KDUMP_RX_LOCK */
370 /* Maximum number of acknowledgements in an acknowledge packet */
371 #define RX_MAXACKS 255
373 #ifndef KDUMP_RX_LOCK
375 /* The structure of the data portion of an acknowledge packet: An acknowledge
376 * packet is in network byte order at all times. An acknowledgement is always
377 * prompted for a specific reason by a specific incoming packet. This reason
378 * is reported in "reason" and the packet's sequence number in the packet
379 * header.seq. In addition to this information, all of the current
380 * acknowledgement information about this call is placed in the packet.
381 * "FirstPacket" is the sequence number of the first packet represented in an
382 * array of bytes, "acks", containing acknowledgement information for a number
383 * of consecutive packets. All packets prior to FirstPacket are implicitly
384 * acknowledged: the sender need no longer be concerned about them. Packets
385 * from firstPacket+nAcks and on are not acknowledged. Packets in the range
386 * [firstPacket,firstPacket+nAcks) are each acknowledged explicitly. The
387 * acknowledgement may be RX_NACK if the packet is not (currently) at the
388 * receiver (it may have never been received, or received and then later
389 * dropped), or it may be RX_ACK if the packet is queued up waiting to be read
390 * by the upper level software. RX_ACK does not imply that the packet may not
391 * be dropped before it is read; it does imply that the sender should stop
392 * retransmitting the packet until notified otherwise. The field
393 * previousPacket identifies the previous packet received by the peer. This
394 * was used in a previous version of this software, and could be used in the
395 * future. The serial number in the data part of the ack packet corresponds to
396 * the serial number oof the packet which prompted the acknowledge. Any
397 * packets which are explicitly not acknowledged, and which were last
398 * transmitted with a serial number less than the provided serial number,
399 * should be retransmitted immediately. Actually, this is slightly inaccurate:
400 * packets are not necessarily received in order. When packets are habitually
401 * transmitted out of order, this is allowed for in the retransmission
402 * algorithm by introducing the notion of maximum packet skew: the degree of
403 * out-of-orderness of the packets received on the wire. This number is
404 * communicated from the receiver to the sender in ack packets. */
406 struct rx_ackPacket
{
407 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. */
408 u_short maxSkew
; /* Maximum difference between serial# of packet acknowledged and highest packet yet received */
409 afs_uint32 firstPacket
; /* The first packet in the list of acknowledged packets */
410 afs_uint32 previousPacket
; /* The previous packet number received (obsolete?) */
411 afs_uint32 serial
; /* Serial number of the packet which prompted the acknowledge */
412 u_char reason
; /* Reason for the acknowledge of ackPacket, defined below */
413 u_char nAcks
; /* Number of acknowledgements */
414 u_char acks
[RX_MAXACKS
]; /* Up to RX_MAXACKS packet acknowledgements, defined below */
415 /* 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) */
418 #define FIRSTACKOFFSET 4
420 /* Reason for acknowledge message */
421 #define RX_ACK_REQUESTED 1 /* Peer requested an ack on this packet */
422 #define RX_ACK_DUPLICATE 2 /* Duplicate packet */
423 #define RX_ACK_OUT_OF_SEQUENCE 3 /* Packet out of sequence */
424 #define RX_ACK_EXCEEDS_WINDOW 4 /* Packet sequence number higher than window; discarded */
425 #define RX_ACK_NOSPACE 5 /* No buffer space at all */
426 #define RX_ACK_PING 6 /* This is a keep-alive ack */
427 #define RX_ACK_PING_RESPONSE 7 /* Ack'ing because we were pinged */
428 #define RX_ACK_DELAY 8 /* Ack generated since nothing has happened since receiving packet */
429 #define RX_ACK_IDLE 9 /* Similar to RX_ACK_DELAY, but can
430 * be used to compute RTT */
431 #define RX_ACK_MTU -1 /* will be rewritten to ACK_PING */
433 /* Packet acknowledgement type */
434 #define RX_ACK_TYPE_NACK 0 /* I Don't have this packet */
435 #define RX_ACK_TYPE_ACK 1 /* I have this packet, although I may discard it later */
437 /* The packet size transmitted for an acknowledge is adjusted to reflect the actual size of the acks array. This macro defines the size */
438 #define rx_AckDataSize(nAcks) (3 + nAcks + offsetof(struct rx_ackPacket, acks[0]))
440 #define RX_CHALLENGE_TIMEOUT 2 /* Number of seconds before another authentication request packet is generated */
441 #define RX_CHALLENGE_MAXTRIES 50 /* Max # of times we resend challenge */
442 #define RX_CHECKREACH_TIMEOUT 2 /* Number of seconds before another ping is generated */
443 #define RX_CHECKREACH_TTL 60 /* Re-check reachability this often */
446 * rx_GetNetworkError 'origin' constants. These define the meaning of the
447 * 'type' and 'code' values returned by rx_GetNetworkError.
450 /* Used for ICMP errors; the type and code are the ICMP type and code,
452 #define RX_NETWORK_ERROR_ORIGIN_ICMP (0)
455 * RX error codes. RX uses error codes from -1 to -64 and -100.
456 * Rxgen uses other error codes < -64 (see src/rxgen/rpc_errors.h);
457 * user programs are expected to return positive error codes
460 /* Something bad happened to the connection; temporary loss of communication */
461 #define RX_CALL_DEAD (-1)
464 * An invalid operation, such as a client attempting to send data
465 * after having received the beginning of a reply from the server.
467 #define RX_INVALID_OPERATION (-2)
469 /* An optional timeout per call may be specified */
470 #define RX_CALL_TIMEOUT (-3)
472 /* End of data on a read. Not currently in use. */
475 /* Some sort of low-level protocol error. */
476 #define RX_PROTOCOL_ERROR (-5)
479 * Generic user abort code; used when no more specific error code needs to be
480 * communicated. For example, multi rx clients use this code to abort a multi-
483 #define RX_USER_ABORT (-6)
485 /* Port already in use (from rx_Init). This error is never sent on the wire. */
486 #define RX_ADDRINUSE (-7)
488 /* EMSGSIZE returned from network. Packet too big, must fragment */
489 #define RX_MSGSIZE (-8)
491 /* The value -9 was previously used for RX_CALL_IDLE but is now free for
494 /* The value -10 was previously used for RX_CALL_BUSY but is now free for
497 /* transient failure detected ( possibly the server is restarting ) */
498 /* this should be equal to VRESTARTING ( util/errors.h ) for old clients to work */
499 #define RX_RESTARTING (-100)
502 RX_SECIDX_NULL
= 0, /** rxnull, no security. */
503 RX_SECIDX_VAB
= 1, /** vice tokens with bcrypt. Unused. */
504 RX_SECIDX_KAD
= 2, /** kerberos/DES. */
505 RX_SECIDX_KAE
= 3, /** rxkad, but always encrypt. */
506 RX_SECIDX_GK
= 4, /** rxgk, RFC 3961 crypto. */
507 RX_SECIDX_K5
= 5, /** kerberos 5 tickets as tokens. */
511 * We use an enum for the symbol definitions but have no need for a typedef
512 * because the enum is at least as wide as 'int' and these have to fit into
513 * a field of type 'char'. Direct assigment will do the right thing if the
514 * enum value fits into that type.
522 struct rx_securityObjectStats
{
523 char type
; /* An RX_SECTYPE_* value */
525 char sparec
[10]; /* force correct alignment */
526 afs_int32 flags
; /* 1=>unalloc, 2=>auth, 4=>expired */
528 afs_uint32 packetsReceived
;
529 afs_uint32 packetsSent
;
530 afs_uint32 bytesReceived
;
531 afs_uint32 bytesSent
;
536 /* Configuration settings */
538 /* Enum for storing configuration variables which can be set via the
539 * SetConfiguration method in the rx_securityClass, below
543 RXS_CONFIG_FLAGS
/* afs_uint32 set of bitwise flags */
544 } rx_securityConfigVariables
;
546 /* For the RXS_CONFIG_FLAGS, the following bit values are defined */
548 /* Disable the principal name contains dot check in rxkad */
549 #define RXS_CONFIG_FLAGS_DISABLE_DOTCHECK 0x01
551 /* XXXX (rewrite this description) A security class object contains a set of
552 * procedures and some private data to implement a security model for rx
553 * connections. These routines are called by rx as appropriate. Rx knows
554 * nothing about the internal details of any particular security model, or
555 * about security state. Rx does maintain state per connection on behalf of
556 * the security class. Each security class implementation is also expected to
557 * provide routines to create these objects. Rx provides a basic routine to
558 * allocate one of these objects; this routine must be called by the class. */
559 struct rx_securityClass
{
560 struct rx_securityOps
{
561 int (*op_Close
) (struct rx_securityClass
* aobj
);
562 int (*op_NewConnection
) (struct rx_securityClass
* aobj
,
563 struct rx_connection
* aconn
);
564 int (*op_PreparePacket
) (struct rx_securityClass
* aobj
,
565 struct rx_call
* acall
,
566 struct rx_packet
* apacket
);
567 int (*op_SendPacket
) (struct rx_securityClass
* aobj
,
568 struct rx_call
* acall
,
569 struct rx_packet
* apacket
);
570 int (*op_CheckAuthentication
) (struct rx_securityClass
* aobj
,
571 struct rx_connection
* aconn
);
572 int (*op_CreateChallenge
) (struct rx_securityClass
* aobj
,
573 struct rx_connection
* aconn
);
574 int (*op_GetChallenge
) (struct rx_securityClass
* aobj
,
575 struct rx_connection
* aconn
,
576 struct rx_packet
* apacket
);
577 int (*op_GetResponse
) (struct rx_securityClass
* aobj
,
578 struct rx_connection
* aconn
,
579 struct rx_packet
* apacket
);
580 int (*op_CheckResponse
) (struct rx_securityClass
* aobj
,
581 struct rx_connection
* aconn
,
582 struct rx_packet
* apacket
);
583 int (*op_CheckPacket
) (struct rx_securityClass
* aobj
,
584 struct rx_call
* acall
,
585 struct rx_packet
* apacket
);
586 int (*op_DestroyConnection
) (struct rx_securityClass
* aobj
,
587 struct rx_connection
* aconn
);
588 int (*op_GetStats
) (struct rx_securityClass
* aobj
,
589 struct rx_connection
* aconn
,
590 struct rx_securityObjectStats
* astats
);
591 int (*op_SetConfiguration
) (struct rx_securityClass
* aobj
,
592 struct rx_connection
* aconn
,
593 rx_securityConfigVariables atype
,
595 void ** acurrentValue
);
596 int (*op_Spare2
) (void);
597 int (*op_Spare3
) (void);
603 #define RXS_OP(obj,op,args) ((obj && (obj->ops->op_ ## op)) ? (*(obj)->ops->op_ ## op)args : 0)
605 #define RXS_Close(obj) RXS_OP(obj,Close,(obj))
606 #define RXS_NewConnection(obj,conn) RXS_OP(obj,NewConnection,(obj,conn))
607 #define RXS_PreparePacket(obj,call,packet) RXS_OP(obj,PreparePacket,(obj,call,packet))
608 #define RXS_SendPacket(obj,call,packet) RXS_OP(obj,SendPacket,(obj,call,packet))
609 #define RXS_CheckAuthentication(obj,conn) RXS_OP(obj,CheckAuthentication,(obj,conn))
610 #define RXS_CreateChallenge(obj,conn) RXS_OP(obj,CreateChallenge,(obj,conn))
611 #define RXS_GetChallenge(obj,conn,packet) RXS_OP(obj,GetChallenge,(obj,conn,packet))
612 #define RXS_GetResponse(obj,conn,packet) RXS_OP(obj,GetResponse,(obj,conn,packet))
613 #define RXS_CheckResponse(obj,conn,packet) RXS_OP(obj,CheckResponse,(obj,conn,packet))
614 #define RXS_CheckPacket(obj,call,packet) RXS_OP(obj,CheckPacket,(obj,call,packet))
615 #define RXS_DestroyConnection(obj,conn) RXS_OP(obj,DestroyConnection,(obj,conn))
616 #define RXS_GetStats(obj,conn,stats) RXS_OP(obj,GetStats,(obj,conn,stats))
617 #define RXS_SetConfiguration(obj, conn, type, value, currentValue) RXS_OP(obj, SetConfiguration,(obj,conn,type,value,currentValue))
621 /* Structure for keeping rx statistics. Note that this structure is returned
622 * by rxdebug, so, for compatibility reasons, new fields should be appended (or
623 * spares used), the rxdebug protocol checked, if necessary, and the PrintStats
624 * code should be updated as well.
626 * Clearly we assume that ntohl will work on these structures so sizeof(int)
627 * must equal sizeof(afs_int32). */
629 struct rx_statistics
{ /* General rx statistics */
630 int packetRequests
; /* Number of packet allocation requests */
631 int receivePktAllocFailures
;
632 int sendPktAllocFailures
;
633 int specialPktAllocFailures
;
634 int socketGreedy
; /* Whether SO_GREEDY succeeded */
635 int bogusPacketOnRead
; /* Number of inappropriately short packets received */
636 int bogusHost
; /* Host address from bogus packets */
637 int noPacketOnRead
; /* Number of read packets attempted when there was actually no packet to read off the wire */
638 int noPacketBuffersOnRead
; /* Number of dropped data packets due to lack of packet buffers */
639 int selects
; /* Number of selects waiting for packet or timeout */
640 int sendSelects
; /* Number of selects forced when sending packet */
641 int packetsRead
[RX_N_PACKET_TYPES
]; /* Total number of packets read, per type */
642 int dataPacketsRead
; /* Number of unique data packets read off the wire */
643 int ackPacketsRead
; /* Number of ack packets read */
644 int dupPacketsRead
; /* Number of duplicate data packets read */
645 int spuriousPacketsRead
; /* Number of inappropriate data packets */
646 int packetsSent
[RX_N_PACKET_TYPES
]; /* Number of rxi_Sends: packets sent over the wire, per type */
647 int ackPacketsSent
; /* Number of acks sent */
648 int pingPacketsSent
; /* Total number of ping packets sent */
649 int abortPacketsSent
; /* Total number of aborts */
650 int busyPacketsSent
; /* Total number of busies sent received */
651 int dataPacketsSent
; /* Number of unique data packets sent */
652 int dataPacketsReSent
; /* Number of retransmissions */
653 int dataPacketsPushed
; /* Number of retransmissions pushed early by a NACK */
654 int ignoreAckedPacket
; /* Number of packets with acked flag, on rxi_Start */
655 struct clock totalRtt
; /* Total round trip time measured (use to compute average) */
656 struct clock minRtt
; /* Minimum round trip time measured */
657 struct clock maxRtt
; /* Maximum round trip time measured */
658 int nRttSamples
; /* Total number of round trip samples */
659 int nServerConns
; /* Total number of server connections */
660 int nClientConns
; /* Total number of client connections */
661 int nPeerStructs
; /* Total number of peer structures */
662 int nCallStructs
; /* Total number of call structures allocated */
663 int nFreeCallStructs
; /* Total number of previously allocated free call structures */
665 afs_int32 fatalErrors
;
666 int ignorePacketDally
; /* packets dropped because call is in dally state */
667 int receiveCbufPktAllocFailures
;
668 int sendCbufPktAllocFailures
;
673 /* structures for debug input and output packets */
675 /* debug input types */
681 /* Invalid rx debug package type */
682 #define RX_DEBUGI_BADTYPE (-8)
684 #define RX_DEBUGI_VERSION_MINIMUM ('L') /* earliest real version */
685 #define RX_DEBUGI_VERSION ('S') /* Latest version */
686 /* first version w/ secStats */
687 #define RX_DEBUGI_VERSION_W_SECSTATS ('L')
688 /* version M is first supporting GETALLCONN and RXSTATS type */
689 #define RX_DEBUGI_VERSION_W_GETALLCONN ('M')
690 #define RX_DEBUGI_VERSION_W_RXSTATS ('M')
691 /* last version with unaligned debugConn */
692 #define RX_DEBUGI_VERSION_W_UNALIGNED_CONN ('L')
693 #define RX_DEBUGI_VERSION_W_WAITERS ('N')
694 #define RX_DEBUGI_VERSION_W_IDLETHREADS ('O')
695 #define RX_DEBUGI_VERSION_W_NEWPACKETTYPES ('P')
696 #define RX_DEBUGI_VERSION_W_GETPEER ('Q')
697 #define RX_DEBUGI_VERSION_W_WAITED ('R')
698 #define RX_DEBUGI_VERSION_W_PACKETS ('S')
700 #define RX_DEBUGI_GETSTATS 1 /* get basic rx stats */
701 #define RX_DEBUGI_GETCONN 2 /* get connection info */
702 #define RX_DEBUGI_GETALLCONN 3 /* get even uninteresting conns */
703 #define RX_DEBUGI_RXSTATS 4 /* get all rx stats */
704 #define RX_DEBUGI_GETPEER 5 /* get all peer structs */
706 struct rx_debugStats
{
707 afs_int32 nFreePackets
;
708 afs_int32 packetReclaims
;
709 afs_int32 callsExecuted
;
710 char waitingForPackets
;
715 afs_int32 idleThreads
; /* Number of server threads that are idle */
721 struct rx_debugConn_vL
{
725 afs_int32 callNumber
[RX_MAXCALLS
];
731 char callState
[RX_MAXCALLS
];
732 char callMode
[RX_MAXCALLS
];
733 char callFlags
[RX_MAXCALLS
];
734 char callOther
[RX_MAXCALLS
];
735 /* old style getconn stops here */
736 struct rx_securityObjectStats secStats
;
737 afs_int32 sparel
[10];
740 struct rx_debugConn
{
744 afs_int32 callNumber
[RX_MAXCALLS
];
750 char sparec
[3]; /* force correct alignment */
751 char callState
[RX_MAXCALLS
];
752 char callMode
[RX_MAXCALLS
];
753 char callFlags
[RX_MAXCALLS
];
754 char callOther
[RX_MAXCALLS
];
755 /* old style getconn stops here */
756 struct rx_securityObjectStats secStats
;
762 struct rx_debugPeer
{
770 struct clock burstWait
;
773 struct clock timeout
;
776 afs_int32 inPacketSkew
;
777 afs_int32 outPacketSkew
;
781 u_short maxDgramPackets
;
782 u_short ifDgramPackets
;
785 u_short nDgramPackets
;
787 afs_hyper_t bytesSent
;
788 afs_hyper_t bytesReceived
;
789 afs_int32 sparel
[10];
792 #define RX_OTHER_IN 1 /* packets avail in in queue */
793 #define RX_OTHER_OUT 2 /* packets avail in out queue */
795 #define RX_SERVER_DEBUG_SEC_STATS 0x1
796 #define RX_SERVER_DEBUG_ALL_CONN 0x2
797 #define RX_SERVER_DEBUG_RX_STATS 0x4
798 #define RX_SERVER_DEBUG_WAITER_CNT 0x8
799 #define RX_SERVER_DEBUG_IDLE_THREADS 0x10
800 #define RX_SERVER_DEBUG_OLD_CONN 0x20
801 #define RX_SERVER_DEBUG_NEW_PACKETS 0x40
802 #define RX_SERVER_DEBUG_ALL_PEER 0x80
803 #define RX_SERVER_DEBUG_WAITED_CNT 0x100
804 #define RX_SERVER_DEBUG_PACKETS_CNT 0x200
806 #define AFS_RX_STATS_CLEAR_ALL 0xffffffff
807 #define AFS_RX_STATS_CLEAR_INVOCATIONS 0x1
808 #define AFS_RX_STATS_CLEAR_BYTES_SENT 0x2
809 #define AFS_RX_STATS_CLEAR_BYTES_RCVD 0x4
810 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_SUM 0x8
811 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_SQUARE 0x10
812 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_MIN 0x20
813 #define AFS_RX_STATS_CLEAR_QUEUE_TIME_MAX 0x40
814 #define AFS_RX_STATS_CLEAR_EXEC_TIME_SUM 0x80
815 #define AFS_RX_STATS_CLEAR_EXEC_TIME_SQUARE 0x100
816 #define AFS_RX_STATS_CLEAR_EXEC_TIME_MIN 0x200
817 #define AFS_RX_STATS_CLEAR_EXEC_TIME_MAX 0x400
819 typedef struct rx_function_entry_v1
{
820 afs_uint32 remote_peer
;
821 afs_uint32 remote_port
;
822 afs_uint32 remote_is_server
;
823 afs_uint32 interfaceId
;
824 afs_uint32 func_total
;
825 afs_uint32 func_index
;
826 afs_uint64 invocations
;
827 afs_uint64 bytes_sent
;
828 afs_uint64 bytes_rcvd
;
829 struct clock queue_time_sum
;
830 struct clock queue_time_sum_sqr
;
831 struct clock queue_time_min
;
832 struct clock queue_time_max
;
833 struct clock execution_time_sum
;
834 struct clock execution_time_sum_sqr
;
835 struct clock execution_time_min
;
836 struct clock execution_time_max
;
837 } rx_function_entry_v1_t
, *rx_function_entry_v1_p
;
840 * If you need to change rx_function_entry, you should probably create a brand
841 * new structure. Keeping the old structure will allow backwards compatibility
842 * with old clients (even if it is only used to calculate allocation size).
843 * If you do change the size or the format, you'll need to bump
844 * RX_STATS_RETRIEVAL_VERSION. This allows some primitive form
845 * of versioning a la rxdebug.
848 #define RX_STATS_RETRIEVAL_VERSION 1 /* latest version */
849 #define RX_STATS_RETRIEVAL_FIRST_EDITION 1 /* first implementation */
851 typedef struct rx_interface_stat
{
852 struct opr_queue entry
;
853 struct opr_queue entryPeers
;
854 rx_function_entry_v1_t stats
[1]; /* make sure this is aligned correctly */
855 } rx_interface_stat_t
, *rx_interface_stat_p
;
857 #define RX_STATS_SERVICE_ID 409
860 extern int rx_DumpCalls(FILE *outputFile
, char *cookie
);
863 #endif /* _RX_ End of rx.h */
866 #include "rx/rx_prototypes.h"
868 #include "rx_prototypes.h"
871 static_inline afs_uint32
872 RPCOpStat_Peer(void *blob
) {
873 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
874 return rpcop_stat
->remote_peer
;
877 static_inline afs_uint32
878 RPCOpStat_Port(void *blob
) {
879 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
880 return rpcop_stat
->remote_port
;
883 static_inline afs_uint32
884 RPCOpStat_IsServer(void *blob
) {
885 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
886 return rpcop_stat
->remote_is_server
;
889 static_inline afs_uint32
890 RPCOpStat_InterfaceId(void *blob
) {
891 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
892 return rpcop_stat
->interfaceId
;
895 static_inline afs_uint32
896 RPCOpStat_NumFuncs(void *blob
) {
897 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
898 return rpcop_stat
->func_total
;
901 static_inline afs_uint32
902 RPCOpStat_CurFunc(void *blob
) {
903 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
904 return rpcop_stat
->func_index
;
907 static_inline
struct clock
*
908 RPCOpStat_QTimeSum(void *blob
) {
909 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
910 return &(rpcop_stat
->queue_time_sum
);
913 static_inline
struct clock
*
914 RPCOpStat_QTimeSumSqr(void *blob
) {
915 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
916 return &(rpcop_stat
->queue_time_sum_sqr
);
919 static_inline
struct clock
*
920 RPCOpStat_QTimeSumMin(void *blob
) {
921 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
922 return &(rpcop_stat
->queue_time_min
);
925 static_inline
struct clock
*
926 RPCOpStat_QTimeSumMax(void *blob
) {
927 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
928 return &(rpcop_stat
->queue_time_max
);
931 static_inline
struct clock
*
932 RPCOpStat_ExecTimeSum(void *blob
) {
933 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
934 return &(rpcop_stat
->execution_time_sum
);
937 static_inline
struct clock
*
938 RPCOpStat_ExecTimeSumSqr(void *blob
) {
939 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
940 return &(rpcop_stat
->execution_time_sum_sqr
);
943 static_inline
struct clock
*
944 RPCOpStat_ExecTimeSumMin(void *blob
) {
945 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
946 return &(rpcop_stat
->execution_time_min
);
949 static_inline
struct clock
*
950 RPCOpStat_ExecTimeSumMax(void *blob
) {
951 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
952 return &(rpcop_stat
->execution_time_max
);
955 static_inline afs_uint64
956 RPCOpStat_NumCalls(void *blob
) {
957 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
958 return rpcop_stat
->invocations
;
961 static_inline afs_uint64
962 RPCOpStat_BytesSent(void *blob
) {
963 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
964 return rpcop_stat
->bytes_sent
;
967 static_inline afs_uint64
968 RPCOpStat_BytesRcvd(void *blob
) {
969 rx_function_entry_v1_p rpcop_stat
= (rx_function_entry_v1_p
)blob
;
970 return rpcop_stat
->bytes_rcvd
;
972 #endif /* !KDUMP_RX_LOCK */