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 ****************************************************************************
24 /* RX: Globals for internal use, basically */
37 /* The array of installed services. Null terminated. */
38 EXT
struct rx_service
*rx_services
[RX_MAX_SERVICES
+ 1];
40 /* Incoming calls wait on this queue when there are no available server processes */
41 EXT
struct rx_queue rx_incomingCallQueue
;
43 /* Server processes wait on this queue when there are no appropriate calls to process */
44 EXT
struct rx_queue rx_idleServerQueue
;
47 * Constant delay time before sending an acknowledge of the last
48 * packet received. This is to avoid sending an extra acknowledge
49 * when the client is about to make another call, anyway, or the
50 * server is about to respond.
52 EXT
struct clock rx_lastAckDelay
;
56 * Constant delay time before sending a hard ack if the receiver
57 * consumes a packet while no delayed ack event is scheduled. Ensures
58 * that the sender is able to advance its window when the receiver
59 * consumes a packet after the sender has exhausted its transmit
62 EXT
struct clock rx_hardAckDelay
;
65 * Constant delay time before sending a soft ack when none was
66 * requested. This is to make sure we send soft acks before the
67 * sender times out, Normally we wait and send a hard ack when the
68 * receiver consumes the packet
70 EXT
struct clock rx_softAckDelay
;
74 /* Variable to allow introduction of network unreliability */
76 EXT
int rx_intentionallyDroppedPacketsPer100
INIT(0); /* Dropped on Send */
80 EXT
int rx_extraQuota
INIT(0); /* extra packets to add to the quota */
81 EXT
int rx_extraPackets
INIT(32); /* extra packets to alloc (2 windows
84 EXT
int rx_stackSize
INIT(RX_DEFAULT_STACK_SIZE
);
86 EXT
int rx_connDeadTime
INIT(12); /* Time until an unresponsive
87 * connection is declared dead */
88 EXT
int rx_idleConnectionTime
INIT(700); /* Time until we toss an idle
90 EXT
int rx_idlePeerTime
INIT(60); /* Time until we toss a peer
91 * structure, after all connections
92 * using it have disappeared */
94 /* These definitions should be in one place */
96 #define RX_CBUF_TIME 180 /* Check for cbuf deficit */
97 #define RX_REAP_TIME 90 /* Check for tossable connections
100 #define RX_CBUF_TIME 120 /* Check for cbuf deficit */
101 #define RX_REAP_TIME 60 /* Check for tossable connections
102 * every 60 seconds */
106 #define RX_FAST_ACK_RATE 1
108 EXT
int rxi_SoftAckRate
INIT(RX_FAST_ACK_RATE
);
109 EXT
int rxi_HardAckRate
INIT(RX_FAST_ACK_RATE
+ 1);
111 #endif /* SOFT_ACK */
113 EXT
int rx_Window
INIT(15); /* Temporary HACK: transmit/receive
115 EXT
int rx_initialWindow
INIT(2); /* "Slow start" with 2 packets */
117 EXT
int rx_nPackets
INIT(100); /* obsolete; use rx_extraPackets now */
119 /* List of free packets */
120 EXT
struct rx_queue rx_freePacketQueue
;
121 EXT
struct rx_queue rx_freeCbufQueue
;
123 #ifdef RX_ENABLE_LOCKS
124 EXT afs_lock_t rx_freePktQ_lock
;
128 /* Number of free packets */
129 EXT
int rx_nFreePackets
INIT(0);
130 EXT
int rx_nFreeCbufs
INIT(0);
131 EXT
int rx_nCbufs
INIT(0);
132 EXT
int rxi_NeedMoreCbufs
INIT(0);
133 EXT
int rx_nWaiting
INIT(0);
135 /* largest packet which we can safely receive, initialized to AFS 3.2 value
136 * This is provided for backward compatibility with peers which may be unable
137 * to swallow anything larger. THIS MUST NEVER DECREASE WHILE AN APPLICATION
139 EXT u_long rx_maxReceiveSize
INIT(OLD_MAX_PACKET_SIZE
);
141 EXT u_long rx_MyMaxSendSize
INIT(OLD_MAX_PACKET_SIZE
- RX_HEADER_SIZE
);
144 /* List of free queue entries */
145 EXT
struct rx_serverQueueEntry
*rx_FreeSQEList
INIT(0);
147 #ifdef RX_ENABLE_LOCKS
148 EXT kmutex_t freeSQEList_lock
;
152 /* List of free call structures */
153 EXT
struct rx_queue rx_freeCallQueue
;
155 #ifdef RX_ENABLE_LOCKS
156 EXT kmutex_t rx_freeCallQueue_lock
;
159 EXT
long rxi_nCalls
INIT(0);
161 /* Basic socket for client requests; other sockets (for receiving
162 * server requests) are in the service structures */
164 EXT osi_socket rx_socket
;
166 /* socket for icmp messages */
167 EXT osi_socket rx_socket_icmp
;
169 /* Port requested at rx_Init. If this is zero, the actual port used will be different--but it will only be used for client operations. If non-zero, server provided services may use the same port. */
170 EXT
uint16_t rx_port
;
172 /* This is actually the minimum number of packets that must remain free,
173 overall, immediately after a packet of the requested class has been
174 allocated. *WARNING* These must be assigned with a great deal of care.
175 In order, these are receive quota, send quota and special quota */
176 #define RX_PACKET_QUOTAS {1, 10, 0}
177 /* value large enough to guarantee that no allocation fails due to RX_PACKET_QUOTAS.
178 Make it a little bigger, just for fun */
179 #define RX_MAX_QUOTA 15 /* part of min packet computation */
180 EXT
int rx_packetQuota
[RX_N_PACKET_CLASSES
] INIT(RX_PACKET_QUOTAS
);
182 EXT
int rx_nextCid
; /* Next connection call id */
183 EXT
uint32_t rx_epoch
; /* Initialization time of rx */
185 #ifdef RX_ENABLE_LOCKS
186 EXT kmutex_t rx_waitingForPackets_lock
;
187 EXT kcondvar_t rx_waitingForPackets_cv
;
190 EXT
char rx_waitingForPackets
; /* Processes set and wait on this
191 * variable when waiting for packet
194 EXT
struct rx_stats rx_stats
;
196 EXT
struct rx_peer
**rx_peerHashTable
;
197 EXT
struct rx_connection
**rx_connHashTable
;
198 EXT u_long rx_hashTableSize
INIT(256); /* Power of 2 */
199 EXT u_long rx_hashTableMask
INIT(255); /* One less than rx_hashTableSize */
201 #define CONN_HASH(host, port, cid, epoch, type) ((((cid)>>RX_CIDSHIFT)&rx_hashTableMask))
203 #define PEER_HASH(host, port) ((host ^ port) & rx_hashTableMask)
205 #ifdef notdef /* Use a func for now to measure
206 * allocated structs */
207 #define rxi_Free(addr, size) osi_Free(addr, size)
210 #define rxi_AllocSecurityObject() (struct rx_securityClass *) rxi_Alloc(sizeof(struct rx_securityClass))
211 #define rxi_FreeSecurityObject(obj) rxi_Free(obj, sizeof(struct rx_securityClass))
212 #define rxi_AllocService() (struct rx_service *) rxi_Alloc(sizeof(struct rx_service))
213 #define rxi_FreeService(obj) rxi_Free(obj, sizeof(struct rx_service))
214 #define rxi_AllocPeer() (struct rx_peer *) rxi_Alloc(sizeof(struct rx_peer))
215 #define rxi_FreePeer(peer) rxi_Free(peer, sizeof(struct rx_peer))
216 #define rxi_AllocConnection() (struct rx_connection *) rxi_Alloc(sizeof(struct rx_connection))
217 #define rxi_FreeConnection(conn) (rxi_Free(conn, sizeof(struct rx_connection)))
219 /* Forward definitions of internal procedures */
220 struct rx_packet
* rxi_AllocPacket(int);
221 struct rx_packet
* rxi_AllocSendPacket(struct rx_call
*, int);
222 void * rxi_Alloc(int);
223 struct rx_peer
* rxi_FindPeer(uint32_t, uint16_t);
224 struct rx_call
* rxi_NewCall(struct rx_connection
*, int);
225 void rxi_FreeCall(struct rx_call
*);
226 void rxi_Listener(void);
227 void rxi_ReadIcmp(osi_socket
);
228 int rxi_ReadPacket(int, struct rx_packet
*,
229 uint32_t *, uint16_t *);
230 struct rx_packet
* rxi_ReceivePacket(struct rx_packet
*, osi_socket
,
232 struct rx_packet
* rxi_ReceiveDataPacket(struct rx_call
*,
234 struct rx_packet
* rxi_ReceiveAckPacket(struct rx_call
*,
236 struct rx_packet
* rxi_ReceiveResponsePacket(struct rx_connection
*,
238 struct rx_packet
* rxi_ReceiveChallengePacket(struct rx_connection
*,
240 void rx_ServerProc(void);
241 void rxi_AttachServerProc(struct rx_call
*);
242 void rxi_ChallengeOn(struct rx_connection
*);
243 void rxi_InitPeerParams(struct rx_peer
*);
246 #define rxi_ChallengeOff(conn) rxevent_Cancel((conn)->challengeEvent);
247 void rxi_ChallengeEvent(struct rxevent
*, struct rx_connection
*,
249 struct rx_packet
*rxi_SendAck(struct rx_call
*,
250 struct rx_packet
*, int, int, int, int);
251 void rxi_ClearTransmitQueue(struct rx_call
*);
252 void rxi_ClearReceiveQueue(struct rx_call
*);
253 void rxi_ResetConnection(struct rx_connection
*);
254 void rxi_InitCall(void); /* obsolete ? */
255 void rxi_ResetCall(struct rx_call
*);
256 void rxi_CallError(struct rx_call
*, int32_t);
257 void rxi_ConnectionError(struct rx_connection
*, int32_t);
258 void rxi_QueuePackets(void); /* obsolete ? */
259 void rxi_Start(struct rxevent
*, struct rx_call
*);
260 void rxi_CallIsIdle(void); /* obsolete ? */
261 void rxi_CallTimedOut(void); /* obsolete ? */
262 void rxi_ComputeRoundTripTime(struct rx_packet
*,
265 void rxi_ScheduleKeepAliveEvent(struct rx_call
*);
266 void rxi_KeepAliveEvent(struct rxevent
*, struct rx_call
*, char *);
267 void rxi_KeepAliveOn(struct rx_call
*);
269 #define rxi_KeepAliveOff(call) rxevent_Cancel((call)->keepAliveEvent)
270 void rxi_AckAll(struct rxevent
*, struct rx_call
*, char *);
271 void rxi_SendDelayedAck(struct rxevent
*, struct rx_call
*, char *);
272 struct rx_packet
*rxi_SendSpecial(struct rx_call
*,
273 struct rx_connection
*,
274 struct rx_packet
*, int, char *, int);
275 struct rx_packet
*rxi_SendCallAbort(struct rx_call
*,
277 struct rx_packet
*rxi_SendConnectionAbort(struct rx_connection
*,
279 void rxi_ScheduleDecongestionEvent(struct rx_call
*, int);
280 void rxi_CongestionWait(struct rx_call
*);
281 void rxi_ReapConnections(void);
282 void rxi_EncodePacketHeader(struct rx_packet
*);
283 void rxi_DecodePacketHeader(struct rx_packet
*);
284 void rxi_DebugPrint(const char *, ...);
285 void rxi_PrepareSendPacket(struct rx_call
*,
286 struct rx_packet
*, int);
287 void rxi_MoreCbufs(int);
288 uint32_t rx_SlowGetLong(struct rx_packet
*, int);
290 void rxi_Send(struct rx_call
*, struct rx_packet
*);
291 void rxi_FreeAllPackets(void);
292 void rxi_SendPacket(struct rx_connection
*,
294 int rxi_IsConnInteresting(struct rx_connection
*);
295 struct rx_packet
*rxi_ReceiveDebugPacket(struct rx_packet
*, osi_socket
,
297 struct rx_packet
*rxi_ReceiveVersionPacket(struct rx_packet
*, osi_socket
,
299 void rxi_SendDebugPacket(struct rx_packet
*, osi_socket
, uint32_t, uint16_t);
303 /* Some debugging stuff */
304 EXT
FILE *rx_debugFile
; /* Set by the user to a stdio file for
305 * debugging output */
307 #define Log rx_debugFile
308 #define dpf(args) do { if (rx_debugFile) rxi_DebugPrint args; } while(0)
310 EXT
char *rx_packetTypes
[RX_N_PACKET_TYPES
] INIT(RX_PACKET_TYPES
); /* Strings defined in