4 ****************************************************************************
5 * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
7 * Permission to use, copy, modify, and distribute this software and its *
8 * documentation for any purpose and without fee is hereby granted, *
9 * provided that the above copyright notice appear in all copies and *
10 * that both that copyright notice and this permission notice appear in *
11 * supporting documentation, and that the name of IBM not be used in *
12 * advertising or publicity pertaining to distribution of the software *
13 * without specific, written prior permission. *
15 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
18 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
19 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
20 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
21 ****************************************************************************
28 #include "../rx/rx_machdep.h"
29 #include "../rx/rx_kernel.h"
30 #include "../rx/rx_clock.h"
31 #include "../rx/rx_event.h"
32 #include "../rx/rx_queue.h"
33 #include "../rx/rx_packet.h"
34 #include "../rx/rxgencon.h"
41 #include <sys/param.h>
51 /* Configurable parameters */
52 #define RX_IDLE_DEAD_TIME 60 /* default idle dead time */
53 #define RX_MAX_SERVICES 20 /* Maximum number of services that may
55 #define RX_DEFAULT_STACK_SIZE 16000 /* Default process stack size;
56 * overriden by rx_SetStackSize */
58 /* This parameter should not normally be changed */
59 #define RX_PROCESS_PRIORITY LWP_NORMAL_PRIORITY
61 /* backoff is fixed point binary. Ie, units of 1/4 seconds */
62 #define MAXBACKOFF 0x1F
64 struct rx_securityClass
;
67 /* Exported interfaces XXXX clean this up: not all of these are exported */
69 struct rx_service
*rx_NewService(u_short
, u_short
, char *,
70 struct rx_securityClass
**, int, int32_t (*)());
71 struct rx_connection
*rx_NewConnection(uint32_t, u_short
, u_short
,
72 struct rx_securityClass
*, int);
73 void rxi_KillConnection(uint32_t host
, u_short
);
75 rx_NewCall(struct rx_connection
*);
77 rx_GetCall(void); /* Not normally used, but not obsolete */
78 int32_t rx_EndCall(struct rx_call
*, int32_t);
79 int rx_AllocPackets(void);
80 void rx_FreePackets(void);
81 ssize_t
rx_Write(struct rx_call
*, const void *, size_t);
82 ssize_t
rx_Read(struct rx_call
*, void *, size_t);
83 void rx_FlushWrite(struct rx_call
*);
85 void rx_PrintPeerStats(FILE *file
, struct rx_peer
*peer
);
86 void rx_SetArrivalProc(struct rx_call
* call
, void (*proc
) (),
87 void *handle
, void *arg
);
88 void rx_Finalize(void);
89 void rx_StartServer(int);
90 void rx_DestroyConnection(struct rx_connection
*);
91 void rxi_Free(void *, int);
92 int rxi_GetCallNumberVector(const struct rx_connection
*, int32_t *);
93 int rxi_SetCallNumberVector(struct rx_connection
*, int32_t *);
94 void rx_SetEpoch(uint32_t);
96 void shutdown_rx(void);
101 #define RX_DONTWAIT 0
103 #define rx_ConnectionOf(call) ((call)->conn)
104 #define rx_PeerOf(conn) ((conn)->peer)
105 #define rx_HostOf(peer) ((peer)->host)
106 #define rx_PortOf(peer) ((peer)->port)
107 #define rx_SetLocalStatus(call, status) ((call)->localStatus = (status))
108 #define rx_GetLocalStatus(call, status) ((call)->localStatus)
109 #define rx_GetRemoteStatus(call) ((call)->remoteStatus)
110 #define rx_SetCallError(call,status) ((call)->error = (status))
111 #define rx_GetCallError(call) ((call)->error)
112 #define rx_Error(call) ((call)->error)
113 #define rx_ConnError(conn) ((conn)->error)
114 #define rx_IsServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION)
115 #define rx_IsClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION)
116 /* Don't use these; use the IsServerConn style */
117 #define rx_ServerConn(conn) ((conn)->type == RX_SERVER_CONNECTION)
118 #define rx_ClientConn(conn) ((conn)->type == RX_CLIENT_CONNECTION)
119 #define rx_IsUsingPktCksum(conn) ((conn)->flags & \
120 RX_CONN_USING_PACKET_CKSUM)
123 * Set and get rock is applicable to both connections and calls.
124 * It's used by multi rx macros for calls.
126 #define rx_SetRock(obj, newrock) ((obj)->rock = (void *)(newrock))
127 #define rx_GetRock(obj, type) ((type)(obj)->rock)
128 #define rx_ServiceIdOf(conn) ((conn)->serviceId)
129 #define rx_SecurityClassOf(conn) ((conn)->securityIndex)
130 #define rx_SecurityObjectOf(conn) ((conn)->securityObject)
133 * Macros callable by the user to further define attributes of a
134 * service. Must be called before rx_StartServer
138 * Set the service stack size. This currently just sets the stack
139 * size for all processes to be the maximum seen, so far
141 #define rx_SetStackSize(service, stackSize) \
142 rx_stackSize = (((stackSize) > rx_stackSize)? stackSize: rx_stackSize)
145 * Set minimum number of processes guaranteed to be available for this
146 * service at all times
148 #define rx_SetMinProcs(service, min) ((service)->minProcs = (min))
151 * Set maximum number of processes that will be made available to this
152 * service (also a guarantee that this number will be made available
153 * if there is no competition)
155 #define rx_SetMaxProcs(service, max) ((service)->maxProcs = (max))
158 * Define a procedure to be called just before a server connection is
161 #define rx_SetDestroyConnProc(service,proc) ((service)->destroyConnProc = (proc))
163 /* Define procedure to set service dead time */
164 #define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time))
167 * Define procedures for getting and setting before and after execute-request
170 #define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc))
171 #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
172 #define rx_GetAfterProc(service) ((service)->afterProc)
173 #define rx_GetBeforeProc(service) ((service)->beforeProc)
175 /* Define a procedure to be called when a server connection is created */
176 #define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc))
179 * NOTE: We'll probably redefine the following three routines, again,
184 * Set the connection dead time for any connections created for this service
187 #define rx_SetServiceDeadTime(service, seconds) ((service)->secondsUntilDead = (seconds))
189 /* Set connection dead time, for a specific client or server connection */
190 #define rx_SetConnDeadTime(conn, seconds) (rxi_SetConnDeadTime(conn, seconds))
191 extern void rxi_SetConnDeadTime(struct rx_connection
* conn
, int seconds
);
193 /* Set connection hard timeout for a connection */
194 #define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime = (seconds))
197 * Set rx default connection dead time; set on both services and
198 * connections at creation time
200 extern int rx_connDeadTime
;
202 #define rx_SetRxDeadTime(seconds) (rx_connDeadTime = (seconds))
204 extern int rx_nPackets
;
206 #define cpspace(call) \
207 ((call)->currentPacket->wirevec[(call)->curvec].iov_len - (call)->curpos)
208 #define cppos(call) \
209 ((call)->currentPacket->wirevec[(call)->curvec].iov_base + (call)->curpos)
212 * This is the maximum size data packet that can be sent on this connection,
213 * accounting for security module-specific overheads.
215 #define rx_MaxUserDataSize(conn) ((conn)->maxPacketSize - \
217 (conn)->securityHeaderSize - \
218 (conn)->securityMaxTrailerSize)
220 struct rx_securityObjectStats
{
221 char type
; /* 0:unk 1:null,2:vab 3:kad */
223 char sparec
[10]; /* force correct alignment */
224 uint32_t flags
; /* 1=>unalloc, 2=>auth, 4=>expired */
226 uint32_t packetsReceived
;
227 uint32_t packetsSent
;
228 uint32_t bytesReceived
;
235 * XXXX (rewrite this description) A security class object contains a set of
236 * procedures and some private data to implement a security model for rx
237 * connections. These routines are called by rx as appropriate. Rx knows
238 * nothing about the internal details of any particular security model, or
239 * about security state. Rx does maintain state per connection on behalf of
240 * the security class. Each security class implementation is also expected to
241 * provide routines to create these objects. Rx provides a basic routine to
242 * allocate one of these objects; this routine must be called by the class.
244 struct rx_securityClass
{
245 struct rx_securityOps
{
246 int (*op_Close
) ( /* obj */ );
247 int (*op_NewConnection
) ( /* obj, conn */ );
248 int (*op_PreparePacket
) ( /* obj, call, packet */ );
249 int (*op_SendPacket
) ( /* obj, call, packet */ );
250 int (*op_CheckAuthentication
) ( /* obj,conn */ );
251 int (*op_CreateChallenge
) ( /* obj,conn */ );
252 int (*op_GetChallenge
) ( /* obj,conn,packet */ );
253 int (*op_GetResponse
) ( /* obj,conn,packet */ );
254 int (*op_CheckResponse
) ( /* obj,conn,packet */ );
255 int (*op_CheckPacket
) ( /* obj,call,packet */ );
256 int (*op_DestroyConnection
) ( /* obj, conn */ );
257 int (*op_GetStats
) ( /* obj, conn, stats */ );
258 int (*op_NewService
) ( /* obj, service */ );
266 #if defined(__STDC__) && !defined(__HIGHC__)
267 #define RXS_OP(obj,op,args) ((obj->ops->op_ ## op) ? \
268 (*(obj)->ops->op_ ## op)args : 0)
270 #define RXS_OP(obj,op,args) ((obj->ops->op_/**/op) ? \
271 (*(obj)->ops->op_/**/op)args : 0)
274 #define RXS_Close(obj) RXS_OP(obj,Close,(obj))
275 #define RXS_NewConnection(obj,conn) RXS_OP(obj,NewConnection,(obj,conn))
276 #define RXS_PreparePacket(obj,call,packet) RXS_OP(obj,PreparePacket,\
278 #define RXS_SendPacket(obj,call,packet) RXS_OP(obj,SendPacket,\
280 #define RXS_CheckAuthentication(obj,conn) RXS_OP(obj,CheckAuthentication,\
282 #define RXS_CreateChallenge(obj,conn) RXS_OP(obj,CreateChallenge,\
284 #define RXS_GetChallenge(obj,conn,packet) RXS_OP(obj,GetChallenge,\
286 #define RXS_GetResponse(obj,conn,packet) RXS_OP(obj,GetResponse,\
288 #define RXS_CheckResponse(obj,conn,packet) RXS_OP(obj,CheckResponse,\
290 #define RXS_CheckPacket(obj,call,packet) RXS_OP(obj,CheckPacket,\
292 #define RXS_DestroyConnection(obj,conn) RXS_OP(obj,DestroyConnection,\
294 #define RXS_GetStats(obj,conn,stats) RXS_OP(obj,GetStats,\
296 #define RXS_NewService(obj,service,reuse) RXS_OP(obj,NewService,\
300 rxs_Release(struct rx_securityClass
*aobj
);
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 security objects (instances of
310 * security classes) which implement various types of end-to-end security
311 * protocols for connections made to this service. Finally, there are two
312 * parameters controlling the number of requests which may be executed in
313 * parallel by this service: minProcs is the number of requests to this
314 * service which are guaranteed to be able to run in parallel at any time;
315 * maxProcs has two meanings: it limits the total number of requests which may
316 * execute in parallel and it also guarantees that that many requests
317 * may be handled in parallel if no other service is handling any
322 uint16_t serviceId
; /* Service number */
323 uint16_t servicePort
; /* UDP port for this service */
324 char *serviceName
; /* Name of the service */
325 osi_socket socket
; /* socket struct or file descriptor */
326 u_short nRequestsRunning
; /*
327 * Number of requests currently in
330 u_short nSecurityObjects
; /* Number of entries in security
332 struct rx_securityClass
**securityObjects
; /*
333 * Array of security class
336 int32_t (*executeRequestProc
) (struct rx_call
*);
337 /* Routine to call when an rpc request
339 void (*destroyConnProc
)(struct rx_connection
* conn
);
340 /* Routine to call when a server
341 * connection is destroyed */
342 void (*newConnProc
) (); /*
343 * Routine to call when a server
344 * connection is created
346 void (*beforeProc
) (); /* routine to call before a call is
348 void (*afterProc
) (); /* routine to call after a call is
350 u_short maxProcs
; /* Maximum procs to be used for this
352 u_short minProcs
; /* Minimum # of requests guaranteed
353 * executable simultaneously */
354 u_short connDeadTime
; /*
355 * Secs until a client of this service
356 * will be declared dead, if it is not
359 u_short idleDeadTime
; /*
360 * Time a server will wait for I/O to
363 void *serviceRock
; /* Rock for service */
366 void * rx_getServiceRock(struct rx_service
*);
367 void rx_setServiceRock(struct rx_service
*, void *);
368 void * rx_getConnRock(struct rx_connection
*);
369 void rx_setConnRock(struct rx_connection
*, void *);
373 * A server puts itself on an idle queue for a service using an
374 * instance of the following structure. When a call arrives, the call
375 * structure pointer is placed in "newcall", the routine to execute to
376 * service the request is placed in executeRequestProc, and the
377 * process is woken up. The queue entry's address is used for the
380 struct rx_serverQueueEntry
{
381 struct rx_queue queueItemHeader
;
382 struct rx_call
*newcall
;
383 #ifdef RX_ENABLE_LOCKS
389 /* Bottom n-bits of the Call Identifier give the call number */
390 #define RX_MAXCALLS 4 /* Power of 2; max async calls per
392 #define RX_CIDSHIFT 2 /* Log2(RX_MAXCALLS) */
393 #define RX_CHANNELMASK (RX_MAXCALLS-1)
394 #define RX_CIDMASK (~RX_CHANNELMASK)
397 * A peer refers to a peer process, specified by a (host,port) pair.
398 * There may be more than one peer on a given host.
401 struct rx_peer
*next
; /* Next in hash conflict or free list */
402 struct rx_queue connQueue
; /* a list of all conn use this peer */
403 uint32_t host
; /* Remote IP address, in net byte
405 uint16_t port
; /* Remote UDP port, in net byte order */
406 u_short packetSize
; /*
407 * Max packet size, if known, for this
411 /* For garbage collection */
412 u_long idleWhen
; /* When the refcountwent to zero */
413 short refCount
; /* Reference count for this structure */
415 /* Congestion control parameters */
417 * Reinitialization size for the burst
420 u_char burst
; /* Number of packets that can be
421 * transmitted right now, without
423 struct clock burstWait
; /* Delay until new burst is allowed */
424 struct rx_queue congestionQueue
; /*
425 * Calls that are waiting for non-zero
428 u_long srtt
; /* Smoothed RTT in us. */
429 u_long mdev
; /* Smoothed mean deviation of RTT (us)*/
431 struct clock timeout
; /* Current retransmission delay */
433 * Total number of distinct data packets
434 * sent, not including retransmissions
437 * Total number of retransmissions for
438 * this peer, since this structure was
443 * Skew: if a packet is received N packets later than expected (based
444 * on packet serial numbers), then we define it to have a skew of N.
445 * The maximum skew values allow us to decide when a packet hasn't
446 * been received yet because it is out-of-order, as opposed to when it
447 * is likely to have been dropped.
449 u_long inPacketSkew
; /* Maximum skew on incoming packets */
450 u_long outPacketSkew
; /* Peer-reported max skew on our sent
452 int rateFlag
; /* Flag for rate testing (-no 0yes
454 u_short maxWindow
; /* Maximum window size (number of
457 * we have to manually align things
463 * A connection is an authenticated communication path, allowing
464 * limited multiple asynchronous conversations.
466 struct rx_connection
{
467 struct rx_queue queue_item
; /* conns on same peer */
468 struct rx_connection
*next
; /* on hash chain _or_ free list */
469 struct rx_peer
*peer
;
470 #ifdef RX_ENABLE_LOCKS
474 uint32_t epoch
; /* Process start time of client side
476 uint32_t cid
; /* Connection id (call channel is
478 uint32_t error
; /* If this connection is in error,
480 void *rock
; /* User definable */
481 struct rx_call
*call
[RX_MAXCALLS
];
482 uint32_t callNumber
[RX_MAXCALLS
]; /* Current call numbers */
483 uint32_t serial
; /* Next outgoing packet serial number */
484 uint32_t lastSerial
; /* # of last packet received, for
486 uint32_t maxSerial
; /* largest serial number seen on
487 * incoming packets */
488 uint32_t maxPacketSize
; /*
489 * max packet size should be
490 * per-connection since peer process
491 * could be restarted on us.
493 struct rxevent
*challengeEvent
; /* Scheduled when the server is
494 * challenging a client-- to
495 * retransmit the challenge */
496 struct rx_service
*service
; /* used by servers only */
497 u_short serviceId
; /* To stamp on requests, clients only */
498 short refCount
; /* Reference count */
499 u_char flags
; /* Defined below */
500 u_char type
; /* Type of connection, defined below */
501 u_char secondsUntilPing
; /* how often to ping for each active
503 u_char securityIndex
; /* corresponds to the security class
505 /* securityObject for this conn */
506 struct rx_securityClass
*securityObject
; /*
507 * Security object for this
510 void *securityData
; /* Private data for this conn's
512 u_short securityHeaderSize
; /*
513 * Length of security module's packet
516 u_short securityMaxTrailerSize
; /*
517 * Length of security module's packet
521 * Overall timeout per call (seconds)
524 int lastSendTime
; /* Last send time for this connection */
525 u_short secondsUntilDead
; /*
526 * Maximum silence from peer before
529 u_short hardDeadTime
; /* hard max for call execution */
532 /* Flag bits for connection structure */
533 #define RX_CONN_MAKECALL_WAITING 1 /* rx_NewCall is waiting for a
535 #define RX_CONN_DESTROY_ME 2 /*
536 * Destroy *client* connection after
539 #define RX_CONN_USING_PACKET_CKSUM 4 /* non-zero header.spare field seen */
540 #define RX_CONN_BIG_ONES 8 /*
541 * may use packets > 1500 bytes
546 /* Type of connection, client or server */
547 #define RX_CLIENT_CONNECTION 0
548 #define RX_SERVER_CONNECTION 1
551 * Call structure: only instantiated for active calls and dallying server
552 * calls. The permanent call state (i.e. the call number as well as state
553 * shared with other calls associated with this connection) is maintained
554 * in the connection structure.
557 struct rx_queue queue_item_header
; /*
558 * Call can be on various queues
561 struct rx_queue tq
; /* Transmit packet queue */
562 struct rx_queue rq
; /* Receive packet queue */
563 #ifdef RX_ENABLE_LOCKS
570 struct rx_connection
*conn
; /* Parent connection for this call */
571 uint32_t *callNumber
; /*
572 * Pointer to call number field
577 * Next byte to fill or read in current
582 * Number of bytes left in first receive
585 struct rx_packet
*currentPacket
; /*
586 * Current packet being assembled or
589 u_short curvec
; /* current iovec in currentPacket */
590 u_short curpos
; /* current position within curvec */
591 u_short nFree
; /* Number of bytes free in last send
593 u_char channel
; /* Index of call, within connection */
594 u_char state
; /* Current call state as defined below */
595 u_char mode
; /* Current mode of a call in ACTIVE
597 u_char flags
; /* Some random flags */
598 u_char localStatus
; /* Local user status sent out of band */
599 u_char remoteStatus
; /* Remote user status received out of
601 int32_t error
; /* Error condition for this call */
602 u_long timeout
; /* High level timeout for this call */
604 * Next sequence number expected to be
605 * read by rx_ReadData
608 * Previous packet received; used for
609 * deciding what the next packet to be
610 * received should be in order to decide
611 * whether a negative acknowledge should
615 * The receive window: the peer must
616 * not send packets with sequence
617 * numbers >= rnext+rwind
620 * First unacknowledged transmit packet
623 uint32_t tnext
; /* Next transmit sequence number to
626 * The transmit window: we cannot
627 * assign a sequence number to a
628 * packet >= tfirst + twind
631 u_short nSoftAcks
; /* The number of delayed soft acks */
632 u_short nHardAcks
; /* The number of delayed hard acks */
635 u_short cwind
; /* The congestion window */
636 u_short nextCwind
; /* The congestion window after recovery */
637 u_short nCwindAcks
; /* Number acks received at current cwind */
638 u_short ssthresh
; /* The slow start threshold */
639 u_short nAcks
; /* The number of consecttive acks */
640 u_short nNacks
; /* Number packets acked that follow the
641 * first negatively acked packet */
642 u_short congestSeq
; /* Peer's congestion sequence counter */
644 struct rxevent
*resendEvent
; /*
645 * If this is non-Null, there is a
646 * retransmission event pending
648 struct rxevent
*timeoutEvent
; /*
649 * If this is non-Null, then there is an
650 * overall timeout for this call
652 struct rxevent
*keepAliveEvent
; /*
653 * Scheduled periodically in active
654 * calls to keep call alive
656 struct rxevent
*delayedAckEvent
; /*
657 * Scheduled after all packets are
658 * received to send an ack if a reply
659 * or new call is not generated soon
661 int lastSendTime
; /* Last time a packet was sent on this
663 int lastReceiveTime
; /* Last time a packet was received for
665 void (*arrivalProc
) (); /* Procedure to call when reply is
667 void *arrivalProcHandle
; /* Handle to pass to replyFunc */
668 void *arrivalProcArg
; /* Additional arg to pass to reply
670 u_long lastAcked
; /* last packet "hard" acked by
672 u_long startTime
; /* time the call started running */
674 * time server began waiting for
675 * input data/send quota
677 struct clock traceWait
; /*
678 * time server began waiting for input
681 struct clock traceStart
; /* time the call started running */
684 /* Major call states */
685 #define RX_STATE_NOTINIT 0 /* Call structure has never been
687 #define RX_STATE_PRECALL 1 /*
688 * Server-only: call is not in
689 * progress, but packets have arrived
691 #define RX_STATE_ACTIVE 2 /*
692 * An active call; a process is dealing
695 #define RX_STATE_DALLY 3 /* Dallying after process is done with
699 * Call modes: the modes of a call in RX_STATE_ACTIVE state (process attached)
701 #define RX_MODE_SENDING 1 /* Sending or ready to send */
702 #define RX_MODE_RECEIVING 2 /* Receiving or ready to receive */
703 #define RX_MODE_ERROR 3 /* Something in error for current
705 #define RX_MODE_EOF 4 /*
706 * Server has flushed (or client has
707 * read) last reply packet
711 #define RX_CALL_READER_WAIT 1 /* Reader is waiting for next packet */
712 #define RX_CALL_WAIT_WINDOW_ALLOC 2 /*
713 * Sender is waiting for window to
716 #define RX_CALL_WAIT_WINDOW_SEND 4 /*
717 * Sender is waiting for window to
720 #define RX_CALL_WAIT_PACKETS 8 /*
721 * Sender is waiting for packet buffers
723 #define RX_CALL_WAIT_PROC 16 /*
724 * Waiting for a process to be assigned
726 #define RX_CALL_RECEIVE_DONE 32 /* All packets received on this call */
727 #define RX_CALL_CLEARED 64 /*
728 * Receive queue cleared in precall
731 #define RX_CALL_TQ_BUSY 128 /*
732 * Call's Xmit Queue is busy;
736 #define RX_CALL_SLOW_START_OK 0x2000 /* receiver support slow start */
738 /* Maximum number of acknowledgements in an acknowledge packet */
739 #define RX_MAXACKS 255
742 * The structure of the data portion of an acknowledge packet: An acknowledge
743 * packet is in network byte order at all times. An acknowledgement is always
744 * prompted for a specific reason by a specific incoming packet. This reason
745 * is reported in "reason" and the packet's sequence number in the packet
746 * header.seq. In addition to this information, all of the current
747 * acknowledgement information about this call is placed in the packet.
748 * "FirstPacket" is the sequence number of the first packet represented in an
749 * array of bytes, "acks", containing acknowledgement information for a number
750 * of consecutive packets. All packets prior to FirstPacket are implicitly
751 * acknowledged: the sender need no longer be concerned about them. Packets
752 * from firstPacket+nAcks and on are not acknowledged. Packets in the range
753 * [firstPacket,firstPacket+nAcks) are each acknowledged explicitly. The
754 * acknowledgement may be RX_NACK if the packet is not (currently) at the
755 * receiver (it may have never been received, or received and then later
756 * dropped), or it may be RX_ACK if the packet is queued up waiting to be read
757 * by the upper level software. RX_ACK does not imply that the packet may not
758 * be dropped before it is read; it does imply that the sender should stop
759 * retransmitting the packet until notified otherwise. The field
760 * previousPacket identifies the previous packet received by the peer. This
761 * was used in a previous version of this software, and could be used in the
762 * future. The serial number in the data part of the ack packet corresponds to
763 * the serial number oof the packet which prompted the acknowledge. Any
764 * packets which are explicitly not acknowledged, and which were last
765 * transmitted with a serial number less than the provided serial number,
766 * should be retransmitted immediately. Actually, this is slightly inaccurate:
767 * packets are not necessarily received in order. When packets are habitually
768 * transmitted out of order, this is allowed for in the retransmission
769 * algorithm by introducing the notion of maximum packet skew: the degree of
770 * out-of-orderness of the packets received on the wire. This number is
771 * communicated from the receiver to the sender in ack packets.
774 struct rx_ackPacket
{
775 uint16_t bufferSpace
; /*
776 * Number of packet buffers available.
777 * That is: the number of buffers that
778 * the sender of the ack packet is
779 * willing to provide for data,
780 * on this or subsequent calls. Lying is
784 * Maximum difference between serial# of
785 * packet acknowledged and highest
786 * packet yet received
788 uint32_t firstPacket
; /*
789 * The first packet in the list of
790 * acknowledged packets
792 uint32_t previousPacket
; /*
793 * The previous packet number received
797 * Serial number of the packet which
798 * prompted the acknowledge
801 * Reason for the acknowledge of
802 * ackPacket, defined below
804 u_char nAcks
; /* Number of acknowledgements */
805 u_char acks
[RX_MAXACKS
]; /*
806 * Up to RX_MAXACKS packet ack's,
810 * Packets <firstPacket are implicitly acknowledged and may be discarded
811 * by the sender. Packets >= firstPacket+nAcks are implicitly NOT
812 * acknowledged. No packets with sequence numbers >= firstPacket should
813 * be discarded by the sender (they may thrown out at any time by the
818 #define FIRSTACKOFFSET 4
820 /* Reason for acknowledge message */
821 #define RX_ACK_REQUESTED 1 /* Peer requested an ack on this
823 #define RX_ACK_DUPLICATE 2 /* Duplicate packet */
824 #define RX_ACK_OUT_OF_SEQUENCE 3 /* Packet out of sequence */
825 #define RX_ACK_EXCEEDS_WINDOW 4 /*
826 * Packet sequence number higher than
829 #define RX_ACK_NOSPACE 5 /* No buffer space at all */
830 #define RX_ACK_PING 6 /* This is a keep-alive ack */
831 #define RX_ACK_PING_RESPONSE 7 /* Ack'ing because we were pinged */
832 #define RX_ACK_DELAY 8 /*
833 * Ack generated since nothing has
834 * happened since receiving packet
836 #define RX_ACK_IDLE 9 /* */
838 /* Packet acknowledgement type */
839 #define RX_ACK_TYPE_NACK 0 /* I Don't have this packet */
840 #define RX_ACK_TYPE_ACK 1 /*
841 * I have this packet, although I may
846 * The packet size transmitted for an acknowledge is adjusted to reflect the
847 * actual size of the acks array. This macro defines the size
849 #define rx_AckDataSize(nAcks) (18 + (nAcks))
851 #define RX_CHALLENGE_TIMEOUT 2 /*
852 * Number of seconds before another
853 * authentication request packet is
858 * RX error codes. RX uses error codes from -1 to -64. Rxgen may use other
859 * error codes < -64; user programs are expected to return positive error
864 #define RX_MIN_ERROR (-1)
866 /* Something bad happened to the connection; temporary loss of communication */
867 #define RX_CALL_DEAD (-1)
870 * An invalid operation, such as a client attempting to send data after
871 * having received the beginning of a reply from the server
873 #define RX_INVALID_OPERATION (-2)
875 /* An optional timeout per call may be specified */
876 #define RX_CALL_TIMEOUT (-3)
878 /* End of data on a read */
881 /* Some sort of low-level protocol error */
882 #define RX_PROTOCOL_ERROR (-5)
885 * Generic user abort code; used when no more specific error code needs to
886 * be communicated. For example, multi rx clients use this code to abort a
889 #define RX_USER_ABORT (-6)
891 /* Port already in use (from rx_Init) */
892 #define RX_ADDRINUSE (-7)
894 /* EMSGSIZE returned from network. Packet too big, must fragment */
895 #define RX_MSGSIZE (-8)
898 *Not on wire, when CheckResponse/GetResponse return this,
899 * packet should be sent.
901 #define RX_AUTH_REPLY (-63)
904 #define RX_MAX_ERROR (-64)
907 * Structure for keeping rx statistics. Note that this structure is returned
908 * by rxdebug, so, for compatibility reasons, new fields should be appended (or
909 * spares used), the rxdebug protocol checked, if necessary, and the PrintStats
910 * code should be updated as well.
912 * Clearly we assume that ntohl will work on these structures so sizeof(int)
913 * must equal sizeof(long).
916 struct rx_stats
{ /* General rx statistics */
917 uint32_t packetRequests
; /* Number of packet allocation
919 uint32_t noPackets
[RX_N_PACKET_CLASSES
];/*
920 * Number of failed packet requests,
921 * per allocation class
923 uint32_t socketGreedy
; /* Whether SO_GREEDY succeeded */
924 uint32_t bogusPacketOnRead
; /*
925 * Number of inappropriately short
928 uint32_t bogusHost
; /* Host address from bogus packets */
929 uint32_t noPacketOnRead
; /*
930 * Number of read packets attempted
931 * when there was actually no packet
932 * to read off the wire
934 uint32_t noPacketBuffersOnRead
; /*
935 * Number of dropped data packets due
936 * to lack of packet buffers
939 * Number of selects waiting for packet
942 uint32_t sendSelects
; /*
943 * Number of selects forced when
946 uint32_t packetsRead
[RX_N_PACKET_TYPES
];/*
947 * Total number of packets read, per
950 uint32_t dataPacketsRead
; /*
951 * Number of unique data packets read
954 uint32_t ackPacketsRead
; /* Number of ack packets read */
955 uint32_t dupPacketsRead
; /* Number of duplicate data packets
957 uint32_t spuriousPacketsRead
; /* Number of inappropriate data
959 uint32_t packetsSent
[RX_N_PACKET_TYPES
];/*
960 * Number of rxi_Sends: packets sent
961 * over the wire, per type
963 uint32_t ackPacketsSent
; /* Number of acks sent */
964 uint32_t pingPacketsSent
; /* Total number of ping packets sent */
965 uint32_t abortPacketsSent
; /* Total number of aborts */
966 uint32_t busyPacketsSent
; /* Total number of busies sent
968 uint32_t dataPacketsSent
; /* Number of unique data packets sent */
969 uint32_t dataPacketsReSent
; /* Number of retransmissions */
970 uint32_t dataPacketsPushed
; /*
971 * Number of retransmissions pushed early by
974 uint32_t ignoreAckedPacket
; /*
975 * Number of packets with acked flag,
978 struct clock totalRtt
; /*
979 * Total round trip time measured
980 * (use to compute average)
982 struct clock minRtt
; /* Minimum round trip time measured */
983 struct clock maxRtt
; /* Maximum round trip time measured */
984 uint32_t nRttSamples
; /* Total number of round trip samples */
985 uint32_t nServerConns
; /* Total number of server connections */
986 uint32_t nClientConns
; /* Total number of client connections */
987 uint32_t nPeerStructs
; /* Total number of peer structures */
988 uint32_t nCallStructs
; /* Total number of call structures
990 uint32_t nFreeCallStructs
; /*
991 * Total number of previously allocated
992 * free call structures
994 uint32_t netSendFailures
;
995 uint32_t fatalErrors
;
999 /* structures for debug input and output packets */
1001 /* debug input types */
1007 /* Invalid rx debug package type */
1008 #define RX_DEBUGI_BADTYPE (-8)
1010 #define RX_DEBUGI_VERSION_MINIMUM ('L')/* earliest real version */
1011 #define RX_DEBUGI_VERSION ('N') /* Latest version */
1012 /* first version w/ secStats */
1013 #define RX_DEBUGI_VERSION_W_SECSTATS ('L')
1014 /* version M is first supporting GETALLCONN and RXSTATS type */
1015 #define RX_DEBUGI_VERSION_W_GETALLCONN ('M')
1016 #define RX_DEBUGI_VERSION_W_RXSTATS ('M')
1017 /* last version with unaligned debugConn */
1018 #define RX_DEBUGI_VERSION_W_UNALIGNED_CONN ('L')
1019 #define RX_DEBUGI_VERSION_W_WAITERS ('N')
1021 #define RX_DEBUGI_GETSTATS 1 /* get basic rx stats */
1022 #define RX_DEBUGI_GETCONN 2 /* get connection info */
1023 #define RX_DEBUGI_GETALLCONN 3 /* get even uninteresting conns */
1024 #define RX_DEBUGI_RXSTATS 4 /* get all rx stats */
1026 struct rx_debugStats
{
1027 uint32_t nFreePackets
;
1028 uint32_t packetReclaims
;
1029 uint32_t callsExecuted
;
1030 uint8_t waitingForPackets
;
1038 struct rx_debugConn_vL
{
1042 uint32_t callNumber
[RX_MAXCALLS
];
1048 char callState
[RX_MAXCALLS
];
1049 char callMode
[RX_MAXCALLS
];
1050 char callFlags
[RX_MAXCALLS
];
1051 char callOther
[RX_MAXCALLS
];
1052 /* old style getconn stops here */
1053 struct rx_securityObjectStats secStats
;
1054 uint32_t sparel
[10];
1057 struct rx_debugConn
{
1061 uint32_t callNumber
[RX_MAXCALLS
];
1067 char sparec
[3]; /* force correct alignment */
1068 char callState
[RX_MAXCALLS
];
1069 char callMode
[RX_MAXCALLS
];
1070 char callFlags
[RX_MAXCALLS
];
1071 char callOther
[RX_MAXCALLS
];
1072 /* old style getconn stops here */
1073 struct rx_securityObjectStats secStats
;
1075 uint32_t maxPacketSize
;
1079 #define RX_OTHER_IN 1 /* packets avail in in queue */
1080 #define RX_OTHER_OUT 2 /* packets avail in out queue */
1082 void rx_PrintStats(FILE *);
1083 void rx_PrintTheseStats(FILE *file
, struct rx_stats
*s
, int size
);
1085 #endif /* _RX_ End of rx.h */