DEVEL15-rx-prototypes-20080925
[openafs.git] / src / rx / rx.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /* RX:  Extended Remote Procedure Call */
11
12 #include <afsconfig.h>
13 #ifdef  KERNEL
14 #include "afs/param.h"
15 #else
16 #include <afs/param.h>
17 #endif
18
19 RCSID
20     ("$Header$");
21
22 #ifdef KERNEL
23 #include "afs/sysincludes.h"
24 #include "afsincludes.h"
25 #ifndef UKERNEL
26 #include "h/types.h"
27 #include "h/time.h"
28 #include "h/stat.h"
29 #ifdef  AFS_OSF_ENV
30 #include <net/net_globals.h>
31 #endif /* AFS_OSF_ENV */
32 #ifdef AFS_LINUX20_ENV
33 #include "h/socket.h"
34 #endif
35 #include "netinet/in.h"
36 #ifdef AFS_SUN57_ENV
37 #include "inet/common.h"
38 #include "inet/ip.h"
39 #include "inet/ip_ire.h"
40 #endif
41 #include "afs/afs_args.h"
42 #include "afs/afs_osi.h"
43 #ifdef RX_KERNEL_TRACE
44 #include "rx_kcommon.h"
45 #endif
46 #if     (defined(AFS_AUX_ENV) || defined(AFS_AIX_ENV))
47 #include "h/systm.h"
48 #endif
49 #ifdef RXDEBUG
50 #undef RXDEBUG                  /* turn off debugging */
51 #endif /* RXDEBUG */
52 #if defined(AFS_SGI_ENV)
53 #include "sys/debug.h"
54 #endif
55 #include "afsint.h"
56 #ifdef  AFS_OSF_ENV
57 #undef kmem_alloc
58 #undef kmem_free
59 #undef mem_alloc
60 #undef mem_free
61 #undef register
62 #endif /* AFS_OSF_ENV */
63 #else /* !UKERNEL */
64 #include "afs/sysincludes.h"
65 #include "afsincludes.h"
66 #endif /* !UKERNEL */
67 #include "afs/lock.h"
68 #include "rx_kmutex.h"
69 #include "rx_kernel.h"
70 #include "rx_clock.h"
71 #include "rx_queue.h"
72 #include "rx.h"
73 #include "rx_globals.h"
74 #include "rx_trace.h"
75 #define AFSOP_STOP_RXCALLBACK   210     /* Stop CALLBACK process */
76 #define AFSOP_STOP_AFS          211     /* Stop AFS process */
77 #define AFSOP_STOP_BKG          212     /* Stop BKG process */
78 #include "afsint.h"
79 extern afs_int32 afs_termState;
80 #ifdef AFS_AIX41_ENV
81 #include "sys/lockl.h"
82 #include "sys/lock_def.h"
83 #endif /* AFS_AIX41_ENV */
84 # include "rxgen_consts.h"
85 #else /* KERNEL */
86 # include <sys/types.h>
87 # include <string.h>
88 # include <stdarg.h>
89 # include <errno.h>
90 #ifdef AFS_NT40_ENV
91 # include <stdlib.h>
92 # include <fcntl.h>
93 # include <afs/afsutil.h>
94 # include <WINNT\afsreg.h>
95 #else
96 # include <sys/socket.h>
97 # include <sys/file.h>
98 # include <netdb.h>
99 # include <sys/stat.h>
100 # include <netinet/in.h>
101 # include <sys/time.h>
102 #endif
103 # include "rx.h"
104 # include "rx_user.h"
105 # include "rx_clock.h"
106 # include "rx_queue.h"
107 # include "rx_globals.h"
108 # include "rx_trace.h"
109 # include <afs/rxgen_consts.h>
110 #endif /* KERNEL */
111
112 #ifndef KERNEL
113 #ifdef AFS_PTHREAD_ENV
114 #ifndef AFS_NT40_ENV
115 int (*registerProgram) (pid_t, char *) = 0;
116 int (*swapNameProgram) (pid_t, const char *, char *) = 0;
117 #endif
118 #else
119 int (*registerProgram) (PROCESS, char *) = 0;
120 int (*swapNameProgram) (PROCESS, const char *, char *) = 0;
121 #endif
122 #endif
123
124 /* Local static routines */
125 static void rxi_DestroyConnectionNoLock(register struct rx_connection *conn);
126 #ifdef RX_ENABLE_LOCKS
127 static void rxi_SetAcksInTransmitQueue(register struct rx_call *call);
128 #endif
129
130 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
131 struct rx_tq_debug {
132     afs_int32 rxi_start_aborted;        /* rxi_start awoke after rxi_Send in error. */
133     afs_int32 rxi_start_in_error;
134 } rx_tq_debug;
135 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
136
137 /*
138  * rxi_rpc_peer_stat_cnt counts the total number of peer stat structures
139  * currently allocated within rx.  This number is used to allocate the
140  * memory required to return the statistics when queried.
141  */
142
143 static unsigned int rxi_rpc_peer_stat_cnt;
144
145 /*
146  * rxi_rpc_process_stat_cnt counts the total number of local process stat
147  * structures currently allocated within rx.  The number is used to allocate
148  * the memory required to return the statistics when queried.
149  */
150
151 static unsigned int rxi_rpc_process_stat_cnt;
152
153 #if !defined(offsetof)
154 #include <stddef.h>             /* for definition of offsetof() */
155 #endif
156
157 #ifdef AFS_PTHREAD_ENV
158 #include <assert.h>
159
160 /*
161  * Use procedural initialization of mutexes/condition variables
162  * to ease NT porting
163  */
164
165 extern pthread_mutex_t rx_stats_mutex;
166 extern pthread_mutex_t des_init_mutex;
167 extern pthread_mutex_t des_random_mutex;
168 extern pthread_mutex_t rx_clock_mutex;
169 extern pthread_mutex_t rxi_connCacheMutex;
170 extern pthread_mutex_t rx_event_mutex;
171 extern pthread_mutex_t osi_malloc_mutex;
172 extern pthread_mutex_t event_handler_mutex;
173 extern pthread_mutex_t listener_mutex;
174 extern pthread_mutex_t rx_if_init_mutex;
175 extern pthread_mutex_t rx_if_mutex;
176 extern pthread_mutex_t rxkad_client_uid_mutex;
177 extern pthread_mutex_t rxkad_random_mutex;
178
179 extern pthread_cond_t rx_event_handler_cond;
180 extern pthread_cond_t rx_listener_cond;
181
182 static pthread_mutex_t epoch_mutex;
183 static pthread_mutex_t rx_init_mutex;
184 static pthread_mutex_t rx_debug_mutex;
185 static pthread_mutex_t rx_rpc_stats;
186
187 static void
188 rxi_InitPthread(void)
189 {
190     assert(pthread_mutex_init(&rx_clock_mutex, (const pthread_mutexattr_t *)0)
191            == 0);
192     assert(pthread_mutex_init(&rx_stats_mutex, (const pthread_mutexattr_t *)0)
193            == 0);
194     assert(pthread_mutex_init
195            (&rxi_connCacheMutex, (const pthread_mutexattr_t *)0) == 0);
196     assert(pthread_mutex_init(&rx_init_mutex, (const pthread_mutexattr_t *)0)
197            == 0);
198     assert(pthread_mutex_init(&epoch_mutex, (const pthread_mutexattr_t *)0) ==
199            0);
200     assert(pthread_mutex_init(&rx_event_mutex, (const pthread_mutexattr_t *)0)
201            == 0);
202     assert(pthread_mutex_init(&des_init_mutex, (const pthread_mutexattr_t *)0)
203            == 0);
204     assert(pthread_mutex_init
205            (&des_random_mutex, (const pthread_mutexattr_t *)0) == 0);
206     assert(pthread_mutex_init
207            (&osi_malloc_mutex, (const pthread_mutexattr_t *)0) == 0);
208     assert(pthread_mutex_init
209            (&event_handler_mutex, (const pthread_mutexattr_t *)0) == 0);
210     assert(pthread_mutex_init(&listener_mutex, (const pthread_mutexattr_t *)0)
211            == 0);
212     assert(pthread_mutex_init
213            (&rx_if_init_mutex, (const pthread_mutexattr_t *)0) == 0);
214     assert(pthread_mutex_init(&rx_if_mutex, (const pthread_mutexattr_t *)0) ==
215            0);
216     assert(pthread_mutex_init
217            (&rxkad_client_uid_mutex, (const pthread_mutexattr_t *)0) == 0);
218     assert(pthread_mutex_init
219            (&rxkad_random_mutex, (const pthread_mutexattr_t *)0) == 0);
220     assert(pthread_mutex_init(&rx_debug_mutex, (const pthread_mutexattr_t *)0)
221            == 0);
222
223     assert(pthread_cond_init
224            (&rx_event_handler_cond, (const pthread_condattr_t *)0) == 0);
225     assert(pthread_cond_init(&rx_listener_cond, (const pthread_condattr_t *)0)
226            == 0);
227     assert(pthread_key_create(&rx_thread_id_key, NULL) == 0);
228     assert(pthread_key_create(&rx_ts_info_key, NULL) == 0);
229  
230     rxkad_global_stats_init();
231
232     MUTEX_INIT(&rx_rpc_stats, "rx_rpc_stats", MUTEX_DEFAULT, 0);
233     MUTEX_INIT(&rx_freePktQ_lock, "rx_freePktQ_lock", MUTEX_DEFAULT, 0);
234 #ifdef  RX_ENABLE_LOCKS
235 #ifdef RX_LOCKS_DB
236     rxdb_init();
237 #endif /* RX_LOCKS_DB */
238     MUTEX_INIT(&freeSQEList_lock, "freeSQEList lock", MUTEX_DEFAULT, 0);
239     MUTEX_INIT(&rx_freeCallQueue_lock, "rx_freeCallQueue_lock", MUTEX_DEFAULT,
240                0);
241     CV_INIT(&rx_waitingForPackets_cv, "rx_waitingForPackets_cv", CV_DEFAULT,
242             0);
243     MUTEX_INIT(&rx_peerHashTable_lock, "rx_peerHashTable_lock", MUTEX_DEFAULT,
244                0);
245     MUTEX_INIT(&rx_connHashTable_lock, "rx_connHashTable_lock", MUTEX_DEFAULT,
246                0);
247     MUTEX_INIT(&rx_serverPool_lock, "rx_serverPool_lock", MUTEX_DEFAULT, 0);
248     MUTEX_INIT(&rxi_keyCreate_lock, "rxi_keyCreate_lock", MUTEX_DEFAULT, 0);
249 #endif /* RX_ENABLE_LOCKS */
250 }
251
252 pthread_once_t rx_once_init = PTHREAD_ONCE_INIT;
253 #define INIT_PTHREAD_LOCKS \
254 assert(pthread_once(&rx_once_init, rxi_InitPthread)==0)
255 /*
256  * The rx_stats_mutex mutex protects the following global variables:
257  * rxi_dataQuota
258  * rxi_minDeficit
259  * rxi_availProcs
260  * rxi_totalMin
261  * rxi_lowConnRefCount
262  * rxi_lowPeerRefCount
263  * rxi_nCalls
264  * rxi_Alloccnt
265  * rxi_Allocsize
266  * rx_nFreePackets
267  * rx_tq_debug
268  * rx_stats
269  */
270 #else
271 #define INIT_PTHREAD_LOCKS
272 #endif
273
274
275 /* Variables for handling the minProcs implementation.  availProcs gives the
276  * number of threads available in the pool at this moment (not counting dudes
277  * executing right now).  totalMin gives the total number of procs required
278  * for handling all minProcs requests.  minDeficit is a dynamic variable
279  * tracking the # of procs required to satisfy all of the remaining minProcs
280  * demands.
281  * For fine grain locking to work, the quota check and the reservation of
282  * a server thread has to come while rxi_availProcs and rxi_minDeficit
283  * are locked. To this end, the code has been modified under #ifdef
284  * RX_ENABLE_LOCKS so that quota checks and reservation occur at the
285  * same time. A new function, ReturnToServerPool() returns the allocation.
286  * 
287  * A call can be on several queue's (but only one at a time). When
288  * rxi_ResetCall wants to remove the call from a queue, it has to ensure
289  * that no one else is touching the queue. To this end, we store the address
290  * of the queue lock in the call structure (under the call lock) when we
291  * put the call on a queue, and we clear the call_queue_lock when the
292  * call is removed from a queue (once the call lock has been obtained).
293  * This allows rxi_ResetCall to safely synchronize with others wishing
294  * to manipulate the queue.
295  */
296
297 #if defined(RX_ENABLE_LOCKS) && defined(KERNEL)
298 static afs_kmutex_t rx_rpc_stats;
299 void rxi_StartUnlocked(struct rxevent *event, void *call,
300                        void *arg1, int istack);
301 #endif
302
303 /* We keep a "last conn pointer" in rxi_FindConnection. The odds are 
304 ** pretty good that the next packet coming in is from the same connection 
305 ** as the last packet, since we're send multiple packets in a transmit window.
306 */
307 struct rx_connection *rxLastConn = 0;
308
309 #ifdef RX_ENABLE_LOCKS
310 /* The locking hierarchy for rx fine grain locking is composed of these
311  * tiers:
312  *
313  * rx_connHashTable_lock - synchronizes conn creation, rx_connHashTable access
314  * conn_call_lock - used to synchonize rx_EndCall and rx_NewCall
315  * call->lock - locks call data fields.
316  * These are independent of each other:
317  *      rx_freeCallQueue_lock
318  *      rxi_keyCreate_lock
319  * rx_serverPool_lock
320  * freeSQEList_lock
321  *
322  * serverQueueEntry->lock
323  * rx_rpc_stats
324  * rx_peerHashTable_lock - locked under rx_connHashTable_lock
325  * peer->lock - locks peer data fields.
326  * conn_data_lock - that more than one thread is not updating a conn data
327  *                  field at the same time.
328  * rx_freePktQ_lock
329  *
330  * lowest level:
331  *      multi_handle->lock
332  *      rxevent_lock
333  *      rx_stats_mutex
334  *
335  * Do we need a lock to protect the peer field in the conn structure?
336  *      conn->peer was previously a constant for all intents and so has no
337  *      lock protecting this field. The multihomed client delta introduced
338  *      a RX code change : change the peer field in the connection structure
339  *      to that remote inetrface from which the last packet for this
340  *      connection was sent out. This may become an issue if further changes
341  *      are made.
342  */
343 #define SET_CALL_QUEUE_LOCK(C, L) (C)->call_queue_lock = (L)
344 #define CLEAR_CALL_QUEUE_LOCK(C) (C)->call_queue_lock = NULL
345 #ifdef RX_LOCKS_DB
346 /* rxdb_fileID is used to identify the lock location, along with line#. */
347 static int rxdb_fileID = RXDB_FILE_RX;
348 #endif /* RX_LOCKS_DB */
349 #else /* RX_ENABLE_LOCKS */
350 #define SET_CALL_QUEUE_LOCK(C, L)
351 #define CLEAR_CALL_QUEUE_LOCK(C)
352 #endif /* RX_ENABLE_LOCKS */
353 struct rx_serverQueueEntry *rx_waitForPacket = 0;
354 struct rx_serverQueueEntry *rx_waitingForPacket = 0;
355
356 /* ------------Exported Interfaces------------- */
357
358 /* This function allows rxkad to set the epoch to a suitably random number
359  * which rx_NewConnection will use in the future.  The principle purpose is to
360  * get rxnull connections to use the same epoch as the rxkad connections do, at
361  * least once the first rxkad connection is established.  This is important now
362  * that the host/port addresses aren't used in FindConnection: the uniqueness
363  * of epoch/cid matters and the start time won't do. */
364
365 #ifdef AFS_PTHREAD_ENV
366 /*
367  * This mutex protects the following global variables:
368  * rx_epoch
369  */
370
371 #define LOCK_EPOCH assert(pthread_mutex_lock(&epoch_mutex)==0)
372 #define UNLOCK_EPOCH assert(pthread_mutex_unlock(&epoch_mutex)==0)
373 #else
374 #define LOCK_EPOCH
375 #define UNLOCK_EPOCH
376 #endif /* AFS_PTHREAD_ENV */
377
378 void
379 rx_SetEpoch(afs_uint32 epoch)
380 {
381     LOCK_EPOCH;
382     rx_epoch = epoch;
383     UNLOCK_EPOCH;
384 }
385
386 /* Initialize rx.  A port number may be mentioned, in which case this
387  * becomes the default port number for any service installed later.
388  * If 0 is provided for the port number, a random port will be chosen
389  * by the kernel.  Whether this will ever overlap anything in
390  * /etc/services is anybody's guess...  Returns 0 on success, -1 on
391  * error. */
392 #ifndef AFS_NT40_ENV
393 static
394 #endif
395 int rxinit_status = 1;
396 #ifdef AFS_PTHREAD_ENV
397 /*
398  * This mutex protects the following global variables:
399  * rxinit_status
400  */
401
402 #define LOCK_RX_INIT assert(pthread_mutex_lock(&rx_init_mutex)==0)
403 #define UNLOCK_RX_INIT assert(pthread_mutex_unlock(&rx_init_mutex)==0)
404 #else
405 #define LOCK_RX_INIT
406 #define UNLOCK_RX_INIT
407 #endif
408
409 int
410 rx_InitHost(u_int host, u_int port)
411 {
412 #ifdef KERNEL
413     osi_timeval_t tv;
414 #else /* KERNEL */
415     struct timeval tv;
416 #endif /* KERNEL */
417     char *htable, *ptable;
418     int tmp_status;
419
420 #if defined(AFS_DJGPP_ENV) && !defined(DEBUG)
421     __djgpp_set_quiet_socket(1);
422 #endif
423
424     SPLVAR;
425
426     INIT_PTHREAD_LOCKS;
427     LOCK_RX_INIT;
428     if (rxinit_status == 0) {
429         tmp_status = rxinit_status;
430         UNLOCK_RX_INIT;
431         return tmp_status;      /* Already started; return previous error code. */
432     }
433 #ifdef RXDEBUG
434     rxi_DebugInit();
435 #endif
436 #ifdef AFS_NT40_ENV
437     if (afs_winsockInit() < 0)
438         return -1;
439 #endif
440
441 #ifndef KERNEL
442     /*
443      * Initialize anything necessary to provide a non-premptive threading
444      * environment.
445      */
446     rxi_InitializeThreadSupport();
447 #endif
448
449     /* Allocate and initialize a socket for client and perhaps server
450      * connections. */
451
452     rx_socket = rxi_GetHostUDPSocket(host, (u_short) port);
453     if (rx_socket == OSI_NULLSOCKET) {
454         UNLOCK_RX_INIT;
455         return RX_ADDRINUSE;
456     }
457 #if defined(RX_ENABLE_LOCKS) && defined(KERNEL)
458 #ifdef RX_LOCKS_DB
459     rxdb_init();
460 #endif /* RX_LOCKS_DB */
461     MUTEX_INIT(&rx_stats_mutex, "rx_stats_mutex", MUTEX_DEFAULT, 0);
462     MUTEX_INIT(&rx_rpc_stats, "rx_rpc_stats", MUTEX_DEFAULT, 0);
463     MUTEX_INIT(&rx_freePktQ_lock, "rx_freePktQ_lock", MUTEX_DEFAULT, 0);
464     MUTEX_INIT(&freeSQEList_lock, "freeSQEList lock", MUTEX_DEFAULT, 0);
465     MUTEX_INIT(&rx_freeCallQueue_lock, "rx_freeCallQueue_lock", MUTEX_DEFAULT,
466                0);
467     CV_INIT(&rx_waitingForPackets_cv, "rx_waitingForPackets_cv", CV_DEFAULT,
468             0);
469     MUTEX_INIT(&rx_peerHashTable_lock, "rx_peerHashTable_lock", MUTEX_DEFAULT,
470                0);
471     MUTEX_INIT(&rx_connHashTable_lock, "rx_connHashTable_lock", MUTEX_DEFAULT,
472                0);
473     MUTEX_INIT(&rx_serverPool_lock, "rx_serverPool_lock", MUTEX_DEFAULT, 0);
474 #if defined(AFS_HPUX110_ENV)
475     if (!uniprocessor)
476         rx_sleepLock = alloc_spinlock(LAST_HELD_ORDER - 10, "rx_sleepLock");
477 #endif /* AFS_HPUX110_ENV */
478 #endif /* RX_ENABLE_LOCKS && KERNEL */
479
480     rxi_nCalls = 0;
481     rx_connDeadTime = 12;
482     rx_tranquil = 0;            /* reset flag */
483     memset((char *)&rx_stats, 0, sizeof(struct rx_stats));
484     htable = (char *)
485         osi_Alloc(rx_hashTableSize * sizeof(struct rx_connection *));
486     PIN(htable, rx_hashTableSize * sizeof(struct rx_connection *));     /* XXXXX */
487     memset(htable, 0, rx_hashTableSize * sizeof(struct rx_connection *));
488     ptable = (char *)osi_Alloc(rx_hashTableSize * sizeof(struct rx_peer *));
489     PIN(ptable, rx_hashTableSize * sizeof(struct rx_peer *));   /* XXXXX */
490     memset(ptable, 0, rx_hashTableSize * sizeof(struct rx_peer *));
491
492     /* Malloc up a bunch of packets & buffers */
493     rx_nFreePackets = 0;
494     queue_Init(&rx_freePacketQueue);
495     rxi_NeedMorePackets = FALSE;
496 #ifdef RX_ENABLE_TSFPQ
497     rx_nPackets = 0;    /* in TSFPQ version, rx_nPackets is managed by rxi_MorePackets* */
498     rxi_MorePacketsTSFPQ(rx_extraPackets + RX_MAX_QUOTA + 2, RX_TS_FPQ_FLUSH_GLOBAL, 0);
499 #else /* RX_ENABLE_TSFPQ */
500     rx_nPackets = rx_extraPackets + RX_MAX_QUOTA + 2;   /* fudge */
501     rxi_MorePackets(rx_nPackets);
502 #endif /* RX_ENABLE_TSFPQ */
503     rx_CheckPackets();
504
505     NETPRI;
506
507     clock_Init();
508
509 #if defined(AFS_NT40_ENV) && !defined(AFS_PTHREAD_ENV)
510     tv.tv_sec = clock_now.sec;
511     tv.tv_usec = clock_now.usec;
512     srand((unsigned int)tv.tv_usec);
513 #else
514     osi_GetTime(&tv);
515 #endif
516     if (port) {
517         rx_port = port;
518     } else {
519 #if defined(KERNEL) && !defined(UKERNEL)
520         /* Really, this should never happen in a real kernel */
521         rx_port = 0;
522 #else
523         struct sockaddr_in addr;
524 #ifdef AFS_NT40_ENV
525         int addrlen = sizeof(addr);
526 #else
527         socklen_t addrlen = sizeof(addr);
528 #endif
529         if (getsockname((int)rx_socket, (struct sockaddr *)&addr, &addrlen)) {
530             rx_Finalize();
531             return -1;
532         }
533         rx_port = addr.sin_port;
534 #endif
535     }
536     rx_stats.minRtt.sec = 9999999;
537 #ifdef  KERNEL
538     rx_SetEpoch(tv.tv_sec | 0x80000000);
539 #else
540     rx_SetEpoch(tv.tv_sec);     /* Start time of this package, rxkad
541                                  * will provide a randomer value. */
542 #endif
543     MUTEX_ENTER(&rx_stats_mutex);
544     rxi_dataQuota += rx_extraQuota;     /* + extra pkts caller asked to rsrv */
545     MUTEX_EXIT(&rx_stats_mutex);
546     /* *Slightly* random start time for the cid.  This is just to help
547      * out with the hashing function at the peer */
548     rx_nextCid = ((tv.tv_sec ^ tv.tv_usec) << RX_CIDSHIFT);
549     rx_connHashTable = (struct rx_connection **)htable;
550     rx_peerHashTable = (struct rx_peer **)ptable;
551
552     rx_lastAckDelay.sec = 0;
553     rx_lastAckDelay.usec = 400000;      /* 400 milliseconds */
554     rx_hardAckDelay.sec = 0;
555     rx_hardAckDelay.usec = 100000;      /* 100 milliseconds */
556     rx_softAckDelay.sec = 0;
557     rx_softAckDelay.usec = 100000;      /* 100 milliseconds */
558
559     rxevent_Init(20, rxi_ReScheduleEvents);
560
561     /* Initialize various global queues */
562     queue_Init(&rx_idleServerQueue);
563     queue_Init(&rx_incomingCallQueue);
564     queue_Init(&rx_freeCallQueue);
565
566 #if defined(AFS_NT40_ENV) && !defined(KERNEL)
567     /* Initialize our list of usable IP addresses. */
568     rx_GetIFInfo();
569 #endif
570
571     /* Start listener process (exact function is dependent on the
572      * implementation environment--kernel or user space) */
573     rxi_StartListener();
574
575     USERPRI;
576     tmp_status = rxinit_status = 0;
577     UNLOCK_RX_INIT;
578     return tmp_status;
579 }
580
581 int
582 rx_Init(u_int port)
583 {
584     return rx_InitHost(htonl(INADDR_ANY), port);
585 }
586
587 /* called with unincremented nRequestsRunning to see if it is OK to start
588  * a new thread in this service.  Could be "no" for two reasons: over the
589  * max quota, or would prevent others from reaching their min quota.
590  */
591 #ifdef RX_ENABLE_LOCKS
592 /* This verion of QuotaOK reserves quota if it's ok while the
593  * rx_serverPool_lock is held.  Return quota using ReturnToServerPool().
594  */
595 static int
596 QuotaOK(register struct rx_service *aservice)
597 {
598     /* check if over max quota */
599     if (aservice->nRequestsRunning >= aservice->maxProcs) {
600         return 0;
601     }
602
603     /* under min quota, we're OK */
604     /* otherwise, can use only if there are enough to allow everyone
605      * to go to their min quota after this guy starts.
606      */
607     MUTEX_ENTER(&rx_stats_mutex);
608     if ((aservice->nRequestsRunning < aservice->minProcs)
609         || (rxi_availProcs > rxi_minDeficit)) {
610         aservice->nRequestsRunning++;
611         /* just started call in minProcs pool, need fewer to maintain
612          * guarantee */
613         if (aservice->nRequestsRunning <= aservice->minProcs)
614             rxi_minDeficit--;
615         rxi_availProcs--;
616         MUTEX_EXIT(&rx_stats_mutex);
617         return 1;
618     }
619     MUTEX_EXIT(&rx_stats_mutex);
620
621     return 0;
622 }
623
624 static void
625 ReturnToServerPool(register struct rx_service *aservice)
626 {
627     aservice->nRequestsRunning--;
628     MUTEX_ENTER(&rx_stats_mutex);
629     if (aservice->nRequestsRunning < aservice->minProcs)
630         rxi_minDeficit++;
631     rxi_availProcs++;
632     MUTEX_EXIT(&rx_stats_mutex);
633 }
634
635 #else /* RX_ENABLE_LOCKS */
636 static int
637 QuotaOK(register struct rx_service *aservice)
638 {
639     int rc = 0;
640     /* under min quota, we're OK */
641     if (aservice->nRequestsRunning < aservice->minProcs)
642         return 1;
643
644     /* check if over max quota */
645     if (aservice->nRequestsRunning >= aservice->maxProcs)
646         return 0;
647
648     /* otherwise, can use only if there are enough to allow everyone
649      * to go to their min quota after this guy starts.
650      */
651     if (rxi_availProcs > rxi_minDeficit)
652         rc = 1;
653     return rc;
654 }
655 #endif /* RX_ENABLE_LOCKS */
656
657 #ifndef KERNEL
658 /* Called by rx_StartServer to start up lwp's to service calls.
659    NExistingProcs gives the number of procs already existing, and which
660    therefore needn't be created. */
661 void
662 rxi_StartServerProcs(int nExistingProcs)
663 {
664     register struct rx_service *service;
665     register int i;
666     int maxdiff = 0;
667     int nProcs = 0;
668
669     /* For each service, reserve N processes, where N is the "minimum"
670      * number of processes that MUST be able to execute a request in parallel,
671      * at any time, for that process.  Also compute the maximum difference
672      * between any service's maximum number of processes that can run
673      * (i.e. the maximum number that ever will be run, and a guarantee
674      * that this number will run if other services aren't running), and its
675      * minimum number.  The result is the extra number of processes that
676      * we need in order to provide the latter guarantee */
677     for (i = 0; i < RX_MAX_SERVICES; i++) {
678         int diff;
679         service = rx_services[i];
680         if (service == (struct rx_service *)0)
681             break;
682         nProcs += service->minProcs;
683         diff = service->maxProcs - service->minProcs;
684         if (diff > maxdiff)
685             maxdiff = diff;
686     }
687     nProcs += maxdiff;          /* Extra processes needed to allow max number requested to run in any given service, under good conditions */
688     nProcs -= nExistingProcs;   /* Subtract the number of procs that were previously created for use as server procs */
689     for (i = 0; i < nProcs; i++) {
690         rxi_StartServerProc(rx_ServerProc, rx_stackSize);
691     }
692 }
693 #endif /* KERNEL */
694
695 #ifdef AFS_NT40_ENV
696 /* This routine is only required on Windows */
697 void
698 rx_StartClientThread(void)
699 {
700 #ifdef AFS_PTHREAD_ENV
701     pthread_t pid;
702     pid = pthread_self();
703 #endif /* AFS_PTHREAD_ENV */
704 }
705 #endif /* AFS_NT40_ENV */
706
707 /* This routine must be called if any services are exported.  If the
708  * donateMe flag is set, the calling process is donated to the server
709  * process pool */
710 void
711 rx_StartServer(int donateMe)
712 {
713     register struct rx_service *service;
714     register int i;
715     SPLVAR;
716     clock_NewTime();
717
718     NETPRI;
719     /* Start server processes, if necessary (exact function is dependent
720      * on the implementation environment--kernel or user space).  DonateMe
721      * will be 1 if there is 1 pre-existing proc, i.e. this one.  In this
722      * case, one less new proc will be created rx_StartServerProcs.
723      */
724     rxi_StartServerProcs(donateMe);
725
726     /* count up the # of threads in minProcs, and add set the min deficit to
727      * be that value, too.
728      */
729     for (i = 0; i < RX_MAX_SERVICES; i++) {
730         service = rx_services[i];
731         if (service == (struct rx_service *)0)
732             break;
733         MUTEX_ENTER(&rx_stats_mutex);
734         rxi_totalMin += service->minProcs;
735         /* below works even if a thread is running, since minDeficit would
736          * still have been decremented and later re-incremented.
737          */
738         rxi_minDeficit += service->minProcs;
739         MUTEX_EXIT(&rx_stats_mutex);
740     }
741
742     /* Turn on reaping of idle server connections */
743     rxi_ReapConnections(NULL, NULL, NULL);
744
745     USERPRI;
746
747     if (donateMe) {
748 #ifndef AFS_NT40_ENV
749 #ifndef KERNEL
750         char name[32];
751         static int nProcs;
752 #ifdef AFS_PTHREAD_ENV
753         pid_t pid;
754         pid = (pid_t) pthread_self();
755 #else /* AFS_PTHREAD_ENV */
756         PROCESS pid;
757         LWP_CurrentProcess(&pid);
758 #endif /* AFS_PTHREAD_ENV */
759
760         sprintf(name, "srv_%d", ++nProcs);
761         if (registerProgram)
762             (*registerProgram) (pid, name);
763 #endif /* KERNEL */
764 #endif /* AFS_NT40_ENV */
765         rx_ServerProc(NULL);    /* Never returns */
766     }
767 #ifdef RX_ENABLE_TSFPQ
768     /* no use leaving packets around in this thread's local queue if
769      * it isn't getting donated to the server thread pool. 
770      */
771     rxi_FlushLocalPacketsTSFPQ();
772 #endif /* RX_ENABLE_TSFPQ */
773     return;
774 }
775
776 /* Create a new client connection to the specified service, using the
777  * specified security object to implement the security model for this
778  * connection. */
779 struct rx_connection *
780 rx_NewConnection(register afs_uint32 shost, u_short sport, u_short sservice,
781                  register struct rx_securityClass *securityObject,
782                  int serviceSecurityIndex)
783 {
784     int hashindex, i;
785     afs_int32 cid;
786     register struct rx_connection *conn;
787
788     SPLVAR;
789
790     clock_NewTime();
791     dpf(("rx_NewConnection(host %x, port %u, service %u, securityObject %x, serviceSecurityIndex %d)\n", ntohl(shost), ntohs(sport), sservice, securityObject, serviceSecurityIndex));
792
793     /* Vasilsi said: "NETPRI protects Cid and Alloc", but can this be true in
794      * the case of kmem_alloc? */
795     conn = rxi_AllocConnection();
796 #ifdef  RX_ENABLE_LOCKS
797     MUTEX_INIT(&conn->conn_call_lock, "conn call lock", MUTEX_DEFAULT, 0);
798     MUTEX_INIT(&conn->conn_data_lock, "conn data lock", MUTEX_DEFAULT, 0);
799     CV_INIT(&conn->conn_call_cv, "conn call cv", CV_DEFAULT, 0);
800 #endif
801     NETPRI;
802     MUTEX_ENTER(&rx_connHashTable_lock);
803     cid = (rx_nextCid += RX_MAXCALLS);
804     conn->type = RX_CLIENT_CONNECTION;
805     conn->cid = cid;
806     conn->epoch = rx_epoch;
807     conn->peer = rxi_FindPeer(shost, sport, 0, 1);
808     conn->serviceId = sservice;
809     conn->securityObject = securityObject;
810     conn->securityData = (void *) 0;
811     conn->securityIndex = serviceSecurityIndex;
812     rx_SetConnDeadTime(conn, rx_connDeadTime);
813     conn->ackRate = RX_FAST_ACK_RATE;
814     conn->nSpecific = 0;
815     conn->specific = NULL;
816     conn->challengeEvent = NULL;
817     conn->delayedAbortEvent = NULL;
818     conn->abortCount = 0;
819     conn->error = 0;
820     for (i = 0; i < RX_MAXCALLS; i++) {
821         conn->twind[i] = rx_initSendWindow;
822         conn->rwind[i] = rx_initReceiveWindow;
823     }
824
825     RXS_NewConnection(securityObject, conn);
826     hashindex =
827         CONN_HASH(shost, sport, conn->cid, conn->epoch, RX_CLIENT_CONNECTION);
828
829     conn->refCount++;           /* no lock required since only this thread knows... */
830     conn->next = rx_connHashTable[hashindex];
831     rx_connHashTable[hashindex] = conn;
832     rx_MutexIncrement(rx_stats.nClientConns, rx_stats_mutex);
833     MUTEX_EXIT(&rx_connHashTable_lock);
834     USERPRI;
835     return conn;
836 }
837
838 void
839 rx_SetConnDeadTime(register struct rx_connection *conn, register int seconds)
840 {
841     /* The idea is to set the dead time to a value that allows several
842      * keepalives to be dropped without timing out the connection. */
843     conn->secondsUntilDead = MAX(seconds, 6);
844     conn->secondsUntilPing = conn->secondsUntilDead / 6;
845 }
846
847 int rxi_lowPeerRefCount = 0;
848 int rxi_lowConnRefCount = 0;
849
850 /*
851  * Cleanup a connection that was destroyed in rxi_DestroyConnectioNoLock.
852  * NOTE: must not be called with rx_connHashTable_lock held.
853  */
854 void
855 rxi_CleanupConnection(struct rx_connection *conn)
856 {
857     /* Notify the service exporter, if requested, that this connection
858      * is being destroyed */
859     if (conn->type == RX_SERVER_CONNECTION && conn->service->destroyConnProc)
860         (*conn->service->destroyConnProc) (conn);
861
862     /* Notify the security module that this connection is being destroyed */
863     RXS_DestroyConnection(conn->securityObject, conn);
864
865     /* If this is the last connection using the rx_peer struct, set its
866      * idle time to now. rxi_ReapConnections will reap it if it's still
867      * idle (refCount == 0) after rx_idlePeerTime (60 seconds) have passed.
868      */
869     MUTEX_ENTER(&rx_peerHashTable_lock);
870     if (conn->peer->refCount < 2) {
871         conn->peer->idleWhen = clock_Sec();
872         if (conn->peer->refCount < 1) {
873             conn->peer->refCount = 1;
874             MUTEX_ENTER(&rx_stats_mutex);
875             rxi_lowPeerRefCount++;
876             MUTEX_EXIT(&rx_stats_mutex);
877         }
878     }
879     conn->peer->refCount--;
880     MUTEX_EXIT(&rx_peerHashTable_lock);
881
882     if (conn->type == RX_SERVER_CONNECTION)
883         rx_MutexDecrement(rx_stats.nServerConns, rx_stats_mutex);
884     else
885         rx_MutexDecrement(rx_stats.nClientConns, rx_stats_mutex);
886 #ifndef KERNEL
887     if (conn->specific) {
888         int i;
889         for (i = 0; i < conn->nSpecific; i++) {
890             if (conn->specific[i] && rxi_keyCreate_destructor[i])
891                 (*rxi_keyCreate_destructor[i]) (conn->specific[i]);
892             conn->specific[i] = NULL;
893         }
894         free(conn->specific);
895     }
896     conn->specific = NULL;
897     conn->nSpecific = 0;
898 #endif /* !KERNEL */
899
900     MUTEX_DESTROY(&conn->conn_call_lock);
901     MUTEX_DESTROY(&conn->conn_data_lock);
902     CV_DESTROY(&conn->conn_call_cv);
903
904     rxi_FreeConnection(conn);
905 }
906
907 /* Destroy the specified connection */
908 void
909 rxi_DestroyConnection(register struct rx_connection *conn)
910 {
911     MUTEX_ENTER(&rx_connHashTable_lock);
912     rxi_DestroyConnectionNoLock(conn);
913     /* conn should be at the head of the cleanup list */
914     if (conn == rx_connCleanup_list) {
915         rx_connCleanup_list = rx_connCleanup_list->next;
916         MUTEX_EXIT(&rx_connHashTable_lock);
917         rxi_CleanupConnection(conn);
918     }
919 #ifdef RX_ENABLE_LOCKS
920     else {
921         MUTEX_EXIT(&rx_connHashTable_lock);
922     }
923 #endif /* RX_ENABLE_LOCKS */
924 }
925
926 static void
927 rxi_DestroyConnectionNoLock(register struct rx_connection *conn)
928 {
929     register struct rx_connection **conn_ptr;
930     register int havecalls = 0;
931     struct rx_packet *packet;
932     int i;
933     SPLVAR;
934
935     clock_NewTime();
936
937     NETPRI;
938     MUTEX_ENTER(&conn->conn_data_lock);
939     if (conn->refCount > 0)
940         conn->refCount--;
941     else {
942         MUTEX_ENTER(&rx_stats_mutex);
943         rxi_lowConnRefCount++;
944         MUTEX_EXIT(&rx_stats_mutex);
945     }
946
947     if ((conn->refCount > 0) || (conn->flags & RX_CONN_BUSY)) {
948         /* Busy; wait till the last guy before proceeding */
949         MUTEX_EXIT(&conn->conn_data_lock);
950         USERPRI;
951         return;
952     }
953
954     /* If the client previously called rx_NewCall, but it is still
955      * waiting, treat this as a running call, and wait to destroy the
956      * connection later when the call completes. */
957     if ((conn->type == RX_CLIENT_CONNECTION)
958         && (conn->flags & RX_CONN_MAKECALL_WAITING)) {
959         conn->flags |= RX_CONN_DESTROY_ME;
960         MUTEX_EXIT(&conn->conn_data_lock);
961         USERPRI;
962         return;
963     }
964     MUTEX_EXIT(&conn->conn_data_lock);
965
966     /* Check for extant references to this connection */
967     for (i = 0; i < RX_MAXCALLS; i++) {
968         register struct rx_call *call = conn->call[i];
969         if (call) {
970             havecalls = 1;
971             if (conn->type == RX_CLIENT_CONNECTION) {
972                 MUTEX_ENTER(&call->lock);
973                 if (call->delayedAckEvent) {
974                     /* Push the final acknowledgment out now--there
975                      * won't be a subsequent call to acknowledge the
976                      * last reply packets */
977                     rxevent_Cancel(call->delayedAckEvent, call,
978                                    RX_CALL_REFCOUNT_DELAY);
979                     if (call->state == RX_STATE_PRECALL
980                         || call->state == RX_STATE_ACTIVE) {
981                         rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
982                     } else {
983                         rxi_AckAll(NULL, call, 0);
984                     }
985                 }
986                 MUTEX_EXIT(&call->lock);
987             }
988         }
989     }
990 #ifdef RX_ENABLE_LOCKS
991     if (!havecalls) {
992         if (MUTEX_TRYENTER(&conn->conn_data_lock)) {
993             MUTEX_EXIT(&conn->conn_data_lock);
994         } else {
995             /* Someone is accessing a packet right now. */
996             havecalls = 1;
997         }
998     }
999 #endif /* RX_ENABLE_LOCKS */
1000
1001     if (havecalls) {
1002         /* Don't destroy the connection if there are any call
1003          * structures still in use */
1004         MUTEX_ENTER(&conn->conn_data_lock);
1005         conn->flags |= RX_CONN_DESTROY_ME;
1006         MUTEX_EXIT(&conn->conn_data_lock);
1007         USERPRI;
1008         return;
1009     }
1010
1011     if (conn->delayedAbortEvent) {
1012         rxevent_Cancel(conn->delayedAbortEvent, (struct rx_call *)0, 0);
1013         packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
1014         if (packet) {
1015             MUTEX_ENTER(&conn->conn_data_lock);
1016             rxi_SendConnectionAbort(conn, packet, 0, 1);
1017             MUTEX_EXIT(&conn->conn_data_lock);
1018             rxi_FreePacket(packet);
1019         }
1020     }
1021
1022     /* Remove from connection hash table before proceeding */
1023     conn_ptr =
1024         &rx_connHashTable[CONN_HASH
1025                           (peer->host, peer->port, conn->cid, conn->epoch,
1026                            conn->type)];
1027     for (; *conn_ptr; conn_ptr = &(*conn_ptr)->next) {
1028         if (*conn_ptr == conn) {
1029             *conn_ptr = conn->next;
1030             break;
1031         }
1032     }
1033     /* if the conn that we are destroying was the last connection, then we
1034      * clear rxLastConn as well */
1035     if (rxLastConn == conn)
1036         rxLastConn = 0;
1037
1038     /* Make sure the connection is completely reset before deleting it. */
1039     /* get rid of pending events that could zap us later */
1040     if (conn->challengeEvent)
1041         rxevent_Cancel(conn->challengeEvent, (struct rx_call *)0, 0);
1042     if (conn->checkReachEvent)
1043         rxevent_Cancel(conn->checkReachEvent, (struct rx_call *)0, 0);
1044
1045     /* Add the connection to the list of destroyed connections that
1046      * need to be cleaned up. This is necessary to avoid deadlocks
1047      * in the routines we call to inform others that this connection is
1048      * being destroyed. */
1049     conn->next = rx_connCleanup_list;
1050     rx_connCleanup_list = conn;
1051 }
1052
1053 /* Externally available version */
1054 void
1055 rx_DestroyConnection(register struct rx_connection *conn)
1056 {
1057     SPLVAR;
1058
1059     NETPRI;
1060     rxi_DestroyConnection(conn);
1061     USERPRI;
1062 }
1063
1064 void
1065 rx_GetConnection(register struct rx_connection *conn)
1066 {
1067     SPLVAR;
1068
1069     NETPRI;
1070     MUTEX_ENTER(&conn->conn_data_lock);
1071     conn->refCount++;
1072     MUTEX_EXIT(&conn->conn_data_lock);
1073     USERPRI;
1074 }
1075
1076 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
1077 /* Wait for the transmit queue to no longer be busy. 
1078  * requires the call->lock to be held */
1079 static void rxi_WaitforTQBusy(struct rx_call *call) {
1080     while (call->flags & RX_CALL_TQ_BUSY) {
1081         call->flags |= RX_CALL_TQ_WAIT;
1082         call->tqWaiters++;
1083 #ifdef RX_ENABLE_LOCKS
1084         osirx_AssertMine(&call->lock, "rxi_WaitforTQ lock");
1085         CV_WAIT(&call->cv_tq, &call->lock);
1086 #else /* RX_ENABLE_LOCKS */
1087         osi_rxSleep(&call->tq);
1088 #endif /* RX_ENABLE_LOCKS */
1089         call->tqWaiters--;
1090         if (call->tqWaiters == 0) {
1091             call->flags &= ~RX_CALL_TQ_WAIT;
1092         }
1093     }
1094 }
1095 #endif
1096
1097 /* Start a new rx remote procedure call, on the specified connection.
1098  * If wait is set to 1, wait for a free call channel; otherwise return
1099  * 0.  Maxtime gives the maximum number of seconds this call may take,
1100  * after rx_NewCall returns.  After this time interval, a call to any
1101  * of rx_SendData, rx_ReadData, etc. will fail with RX_CALL_TIMEOUT.
1102  * For fine grain locking, we hold the conn_call_lock in order to 
1103  * to ensure that we don't get signalle after we found a call in an active
1104  * state and before we go to sleep.
1105  */
1106 struct rx_call *
1107 rx_NewCall(register struct rx_connection *conn)
1108 {
1109     register int i;
1110     register struct rx_call *call;
1111     struct clock queueTime;
1112     SPLVAR;
1113
1114     clock_NewTime();
1115     dpf(("rx_NewCall(conn %x)\n", conn));
1116
1117     NETPRI;
1118     clock_GetTime(&queueTime);
1119     MUTEX_ENTER(&conn->conn_call_lock);
1120
1121     /*
1122      * Check if there are others waiting for a new call.
1123      * If so, let them go first to avoid starving them.
1124      * This is a fairly simple scheme, and might not be
1125      * a complete solution for large numbers of waiters.
1126      * 
1127      * makeCallWaiters keeps track of the number of 
1128      * threads waiting to make calls and the 
1129      * RX_CONN_MAKECALL_WAITING flag bit is used to 
1130      * indicate that there are indeed calls waiting.
1131      * The flag is set when the waiter is incremented.
1132      * It is only cleared in rx_EndCall when 
1133      * makeCallWaiters is 0.  This prevents us from 
1134      * accidently destroying the connection while it
1135      * is potentially about to be used.
1136      */
1137     MUTEX_ENTER(&conn->conn_data_lock);
1138     if (conn->makeCallWaiters) {
1139         conn->flags |= RX_CONN_MAKECALL_WAITING;
1140         conn->makeCallWaiters++;
1141         MUTEX_EXIT(&conn->conn_data_lock);
1142
1143 #ifdef  RX_ENABLE_LOCKS
1144         CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
1145 #else
1146         osi_rxSleep(conn);
1147 #endif
1148         MUTEX_ENTER(&conn->conn_data_lock);
1149         conn->makeCallWaiters--;
1150     } 
1151     MUTEX_EXIT(&conn->conn_data_lock);
1152
1153     for (;;) {
1154         for (i = 0; i < RX_MAXCALLS; i++) {
1155             call = conn->call[i];
1156             if (call) {
1157                 MUTEX_ENTER(&call->lock);
1158                 if (call->state == RX_STATE_DALLY) {
1159                     rxi_ResetCall(call, 0);
1160                     (*call->callNumber)++;
1161                     break;
1162                 }
1163                 MUTEX_EXIT(&call->lock);
1164             } else {
1165                 call = rxi_NewCall(conn, i);
1166                 break;
1167             }
1168         }
1169         if (i < RX_MAXCALLS) {
1170             break;
1171         }
1172         MUTEX_ENTER(&conn->conn_data_lock);
1173         conn->flags |= RX_CONN_MAKECALL_WAITING;
1174         conn->makeCallWaiters++;
1175         MUTEX_EXIT(&conn->conn_data_lock);
1176
1177 #ifdef  RX_ENABLE_LOCKS
1178         CV_WAIT(&conn->conn_call_cv, &conn->conn_call_lock);
1179 #else
1180         osi_rxSleep(conn);
1181 #endif
1182         MUTEX_ENTER(&conn->conn_data_lock);
1183         conn->makeCallWaiters--;
1184         MUTEX_EXIT(&conn->conn_data_lock);
1185     }
1186     /*
1187      * Wake up anyone else who might be giving us a chance to
1188      * run (see code above that avoids resource starvation).
1189      */
1190 #ifdef  RX_ENABLE_LOCKS
1191     CV_BROADCAST(&conn->conn_call_cv);
1192 #else
1193     osi_rxWakeup(conn);
1194 #endif
1195
1196     CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN);
1197
1198     /* Client is initially in send mode */
1199     call->state = RX_STATE_ACTIVE;
1200     call->error = conn->error;
1201     if (call->error)
1202         call->mode = RX_MODE_ERROR;
1203     else
1204         call->mode = RX_MODE_SENDING;
1205     
1206     /* remember start time for call in case we have hard dead time limit */
1207     call->queueTime = queueTime;
1208     clock_GetTime(&call->startTime);
1209     hzero(call->bytesSent);
1210     hzero(call->bytesRcvd);
1211
1212     /* Turn on busy protocol. */
1213     rxi_KeepAliveOn(call);
1214
1215     MUTEX_EXIT(&call->lock);
1216     MUTEX_EXIT(&conn->conn_call_lock);
1217     USERPRI;
1218
1219 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
1220     /* Now, if TQ wasn't cleared earlier, do it now. */
1221     MUTEX_ENTER(&call->lock);
1222     rxi_WaitforTQBusy(call);
1223     if (call->flags & RX_CALL_TQ_CLEARME) {
1224         rxi_ClearTransmitQueue(call, 0);
1225         queue_Init(&call->tq);
1226     }
1227     MUTEX_EXIT(&call->lock);
1228 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
1229
1230     dpf(("rx_NewCall(call %x)\n", call));
1231     return call;
1232 }
1233
1234 int
1235 rxi_HasActiveCalls(register struct rx_connection *aconn)
1236 {
1237     register int i;
1238     register struct rx_call *tcall;
1239     SPLVAR;
1240
1241     NETPRI;
1242     for (i = 0; i < RX_MAXCALLS; i++) {
1243         if ((tcall = aconn->call[i])) {
1244             if ((tcall->state == RX_STATE_ACTIVE)
1245                 || (tcall->state == RX_STATE_PRECALL)) {
1246                 USERPRI;
1247                 return 1;
1248             }
1249         }
1250     }
1251     USERPRI;
1252     return 0;
1253 }
1254
1255 int
1256 rxi_GetCallNumberVector(register struct rx_connection *aconn,
1257                         register afs_int32 * aint32s)
1258 {
1259     register int i;
1260     register struct rx_call *tcall;
1261     SPLVAR;
1262
1263     NETPRI;
1264     for (i = 0; i < RX_MAXCALLS; i++) {
1265         if ((tcall = aconn->call[i]) && (tcall->state == RX_STATE_DALLY))
1266             aint32s[i] = aconn->callNumber[i] + 1;
1267         else
1268             aint32s[i] = aconn->callNumber[i];
1269     }
1270     USERPRI;
1271     return 0;
1272 }
1273
1274 int
1275 rxi_SetCallNumberVector(register struct rx_connection *aconn,
1276                         register afs_int32 * aint32s)
1277 {
1278     register int i;
1279     register struct rx_call *tcall;
1280     SPLVAR;
1281
1282     NETPRI;
1283     for (i = 0; i < RX_MAXCALLS; i++) {
1284         if ((tcall = aconn->call[i]) && (tcall->state == RX_STATE_DALLY))
1285             aconn->callNumber[i] = aint32s[i] - 1;
1286         else
1287             aconn->callNumber[i] = aint32s[i];
1288     }
1289     USERPRI;
1290     return 0;
1291 }
1292
1293 /* Advertise a new service.  A service is named locally by a UDP port
1294  * number plus a 16-bit service id.  Returns (struct rx_service *) 0
1295  * on a failure. 
1296  *
1297      char *serviceName;  Name for identification purposes (e.g. the
1298                          service name might be used for probing for
1299                          statistics) */
1300 struct rx_service *
1301 rx_NewServiceHost(afs_uint32 host, u_short port, u_short serviceId, 
1302                   char *serviceName, struct rx_securityClass **securityObjects,
1303                   int nSecurityObjects, 
1304                   afs_int32(*serviceProc) (struct rx_call * acall))
1305 {
1306     osi_socket socket = OSI_NULLSOCKET;
1307     register struct rx_service *tservice;
1308     register int i;
1309     SPLVAR;
1310
1311     clock_NewTime();
1312
1313     if (serviceId == 0) {
1314         (osi_Msg
1315          "rx_NewService:  service id for service %s is not non-zero.\n",
1316          serviceName);
1317         return 0;
1318     }
1319     if (port == 0) {
1320         if (rx_port == 0) {
1321             (osi_Msg
1322              "rx_NewService: A non-zero port must be specified on this call if a non-zero port was not provided at Rx initialization (service %s).\n",
1323              serviceName);
1324             return 0;
1325         }
1326         port = rx_port;
1327         socket = rx_socket;
1328     }
1329
1330     tservice = rxi_AllocService();
1331     NETPRI;
1332     for (i = 0; i < RX_MAX_SERVICES; i++) {
1333         register struct rx_service *service = rx_services[i];
1334         if (service) {
1335             if (port == service->servicePort && host == service->serviceHost) {
1336                 if (service->serviceId == serviceId) {
1337                     /* The identical service has already been
1338                      * installed; if the caller was intending to
1339                      * change the security classes used by this
1340                      * service, he/she loses. */
1341                     (osi_Msg
1342                      "rx_NewService: tried to install service %s with service id %d, which is already in use for service %s\n",
1343                      serviceName, serviceId, service->serviceName);
1344                     USERPRI;
1345                     rxi_FreeService(tservice);
1346                     return service;
1347                 }
1348                 /* Different service, same port: re-use the socket
1349                  * which is bound to the same port */
1350                 socket = service->socket;
1351             }
1352         } else {
1353             if (socket == OSI_NULLSOCKET) {
1354                 /* If we don't already have a socket (from another
1355                  * service on same port) get a new one */
1356                 socket = rxi_GetHostUDPSocket(host, port);
1357                 if (socket == OSI_NULLSOCKET) {
1358                     USERPRI;
1359                     rxi_FreeService(tservice);
1360                     return 0;
1361                 }
1362             }
1363             service = tservice;
1364             service->socket = socket;
1365             service->serviceHost = host;
1366             service->servicePort = port;
1367             service->serviceId = serviceId;
1368             service->serviceName = serviceName;
1369             service->nSecurityObjects = nSecurityObjects;
1370             service->securityObjects = securityObjects;
1371             service->minProcs = 0;
1372             service->maxProcs = 1;
1373             service->idleDeadTime = 60;
1374             service->idleDeadErr = 0;
1375             service->connDeadTime = rx_connDeadTime;
1376             service->executeRequestProc = serviceProc;
1377             service->checkReach = 0;
1378             rx_services[i] = service;   /* not visible until now */
1379             USERPRI;
1380             return service;
1381         }
1382     }
1383     USERPRI;
1384     rxi_FreeService(tservice);
1385     (osi_Msg "rx_NewService: cannot support > %d services\n",
1386      RX_MAX_SERVICES);
1387     return 0;
1388 }
1389
1390 /* Set configuration options for all of a service's security objects */
1391
1392 afs_int32 
1393 rx_SetSecurityConfiguration(struct rx_service *service, 
1394                             rx_securityConfigVariables type,
1395                             void *value)
1396 {
1397     int i;
1398     for (i = 0; i<service->nSecurityObjects; i++) {
1399         if (service->securityObjects[i]) {
1400             RXS_SetConfiguration(service->securityObjects[i], NULL, type, 
1401                                  value, NULL);
1402         }
1403     }
1404     return 0;
1405 }
1406
1407 struct rx_service *
1408 rx_NewService(u_short port, u_short serviceId, char *serviceName,
1409               struct rx_securityClass **securityObjects, int nSecurityObjects,
1410               afs_int32(*serviceProc) (struct rx_call * acall))
1411 {
1412     return rx_NewServiceHost(htonl(INADDR_ANY), port, serviceId, serviceName, securityObjects, nSecurityObjects, serviceProc);
1413 }
1414
1415 /* Generic request processing loop. This routine should be called
1416  * by the implementation dependent rx_ServerProc. If socketp is
1417  * non-null, it will be set to the file descriptor that this thread
1418  * is now listening on. If socketp is null, this routine will never
1419  * returns. */
1420 void
1421 rxi_ServerProc(int threadID, struct rx_call *newcall, osi_socket * socketp)
1422 {
1423     register struct rx_call *call;
1424     register afs_int32 code;
1425     register struct rx_service *tservice = NULL;
1426
1427     for (;;) {
1428         if (newcall) {
1429             call = newcall;
1430             newcall = NULL;
1431         } else {
1432             call = rx_GetCall(threadID, tservice, socketp);
1433             if (socketp && *socketp != OSI_NULLSOCKET) {
1434                 /* We are now a listener thread */
1435                 return;
1436             }
1437         }
1438
1439         /* if server is restarting( typically smooth shutdown) then do not
1440          * allow any new calls.
1441          */
1442
1443         if (rx_tranquil && (call != NULL)) {
1444             SPLVAR;
1445
1446             NETPRI;
1447             MUTEX_ENTER(&call->lock);
1448
1449             rxi_CallError(call, RX_RESTARTING);
1450             rxi_SendCallAbort(call, (struct rx_packet *)0, 0, 0);
1451
1452             MUTEX_EXIT(&call->lock);
1453             USERPRI;
1454         }
1455 #ifdef  KERNEL
1456         if (afs_termState == AFSOP_STOP_RXCALLBACK) {
1457 #ifdef RX_ENABLE_LOCKS
1458             AFS_GLOCK();
1459 #endif /* RX_ENABLE_LOCKS */
1460             afs_termState = AFSOP_STOP_AFS;
1461             afs_osi_Wakeup(&afs_termState);
1462 #ifdef RX_ENABLE_LOCKS
1463             AFS_GUNLOCK();
1464 #endif /* RX_ENABLE_LOCKS */
1465             return;
1466         }
1467 #endif
1468
1469         tservice = call->conn->service;
1470
1471         if (tservice->beforeProc)
1472             (*tservice->beforeProc) (call);
1473
1474         code = call->conn->service->executeRequestProc(call);
1475
1476         if (tservice->afterProc)
1477             (*tservice->afterProc) (call, code);
1478
1479         rx_EndCall(call, code);
1480         MUTEX_ENTER(&rx_stats_mutex);
1481         rxi_nCalls++;
1482         MUTEX_EXIT(&rx_stats_mutex);
1483     }
1484 }
1485
1486
1487 void
1488 rx_WakeupServerProcs(void)
1489 {
1490     struct rx_serverQueueEntry *np, *tqp;
1491     SPLVAR;
1492
1493     NETPRI;
1494     MUTEX_ENTER(&rx_serverPool_lock);
1495
1496 #ifdef RX_ENABLE_LOCKS
1497     if (rx_waitForPacket)
1498         CV_BROADCAST(&rx_waitForPacket->cv);
1499 #else /* RX_ENABLE_LOCKS */
1500     if (rx_waitForPacket)
1501         osi_rxWakeup(rx_waitForPacket);
1502 #endif /* RX_ENABLE_LOCKS */
1503     MUTEX_ENTER(&freeSQEList_lock);
1504     for (np = rx_FreeSQEList; np; np = tqp) {
1505         tqp = *(struct rx_serverQueueEntry **)np;
1506 #ifdef RX_ENABLE_LOCKS
1507         CV_BROADCAST(&np->cv);
1508 #else /* RX_ENABLE_LOCKS */
1509         osi_rxWakeup(np);
1510 #endif /* RX_ENABLE_LOCKS */
1511     }
1512     MUTEX_EXIT(&freeSQEList_lock);
1513     for (queue_Scan(&rx_idleServerQueue, np, tqp, rx_serverQueueEntry)) {
1514 #ifdef RX_ENABLE_LOCKS
1515         CV_BROADCAST(&np->cv);
1516 #else /* RX_ENABLE_LOCKS */
1517         osi_rxWakeup(np);
1518 #endif /* RX_ENABLE_LOCKS */
1519     }
1520     MUTEX_EXIT(&rx_serverPool_lock);
1521     USERPRI;
1522 }
1523
1524 /* meltdown:
1525  * One thing that seems to happen is that all the server threads get
1526  * tied up on some empty or slow call, and then a whole bunch of calls
1527  * arrive at once, using up the packet pool, so now there are more 
1528  * empty calls.  The most critical resources here are server threads
1529  * and the free packet pool.  The "doreclaim" code seems to help in
1530  * general.  I think that eventually we arrive in this state: there
1531  * are lots of pending calls which do have all their packets present,
1532  * so they won't be reclaimed, are multi-packet calls, so they won't
1533  * be scheduled until later, and thus are tying up most of the free 
1534  * packet pool for a very long time.
1535  * future options:
1536  * 1.  schedule multi-packet calls if all the packets are present.  
1537  * Probably CPU-bound operation, useful to return packets to pool. 
1538  * Do what if there is a full window, but the last packet isn't here?
1539  * 3.  preserve one thread which *only* runs "best" calls, otherwise
1540  * it sleeps and waits for that type of call.
1541  * 4.  Don't necessarily reserve a whole window for each thread.  In fact, 
1542  * the current dataquota business is badly broken.  The quota isn't adjusted
1543  * to reflect how many packets are presently queued for a running call.
1544  * So, when we schedule a queued call with a full window of packets queued
1545  * up for it, that *should* free up a window full of packets for other 2d-class
1546  * calls to be able to use from the packet pool.  But it doesn't.
1547  *
1548  * NB.  Most of the time, this code doesn't run -- since idle server threads
1549  * sit on the idle server queue and are assigned by "...ReceivePacket" as soon
1550  * as a new call arrives.
1551  */
1552 /* Sleep until a call arrives.  Returns a pointer to the call, ready
1553  * for an rx_Read. */
1554 #ifdef RX_ENABLE_LOCKS
1555 struct rx_call *
1556 rx_GetCall(int tno, struct rx_service *cur_service, osi_socket * socketp)
1557 {
1558     struct rx_serverQueueEntry *sq;
1559     register struct rx_call *call = (struct rx_call *)0;
1560     struct rx_service *service = NULL;
1561     SPLVAR;
1562
1563     MUTEX_ENTER(&freeSQEList_lock);
1564
1565     if ((sq = rx_FreeSQEList)) {
1566         rx_FreeSQEList = *(struct rx_serverQueueEntry **)sq;
1567         MUTEX_EXIT(&freeSQEList_lock);
1568     } else {                    /* otherwise allocate a new one and return that */
1569         MUTEX_EXIT(&freeSQEList_lock);
1570         sq = (struct rx_serverQueueEntry *)
1571             rxi_Alloc(sizeof(struct rx_serverQueueEntry));
1572         MUTEX_INIT(&sq->lock, "server Queue lock", MUTEX_DEFAULT, 0);
1573         CV_INIT(&sq->cv, "server Queue lock", CV_DEFAULT, 0);
1574     }
1575
1576     MUTEX_ENTER(&rx_serverPool_lock);
1577     if (cur_service != NULL) {
1578         ReturnToServerPool(cur_service);
1579     }
1580     while (1) {
1581         if (queue_IsNotEmpty(&rx_incomingCallQueue)) {
1582             register struct rx_call *tcall, *ncall, *choice2 = NULL;
1583
1584             /* Scan for eligible incoming calls.  A call is not eligible
1585              * if the maximum number of calls for its service type are
1586              * already executing */
1587             /* One thread will process calls FCFS (to prevent starvation),
1588              * while the other threads may run ahead looking for calls which
1589              * have all their input data available immediately.  This helps 
1590              * keep threads from blocking, waiting for data from the client. */
1591             for (queue_Scan(&rx_incomingCallQueue, tcall, ncall, rx_call)) {
1592                 service = tcall->conn->service;
1593                 if (!QuotaOK(service)) {
1594                     continue;
1595                 }
1596                 if (tno == rxi_fcfs_thread_num
1597                     || !tcall->queue_item_header.next) {
1598                     /* If we're the fcfs thread , then  we'll just use 
1599                      * this call. If we haven't been able to find an optimal 
1600                      * choice, and we're at the end of the list, then use a 
1601                      * 2d choice if one has been identified.  Otherwise... */
1602                     call = (choice2 ? choice2 : tcall);
1603                     service = call->conn->service;
1604                 } else if (!queue_IsEmpty(&tcall->rq)) {
1605                     struct rx_packet *rp;
1606                     rp = queue_First(&tcall->rq, rx_packet);
1607                     if (rp->header.seq == 1) {
1608                         if (!meltdown_1pkt
1609                             || (rp->header.flags & RX_LAST_PACKET)) {
1610                             call = tcall;
1611                         } else if (rxi_2dchoice && !choice2
1612                                    && !(tcall->flags & RX_CALL_CLEARED)
1613                                    && (tcall->rprev > rxi_HardAckRate)) {
1614                             choice2 = tcall;
1615                         } else
1616                             rxi_md2cnt++;
1617                     }
1618                 }
1619                 if (call) {
1620                     break;
1621                 } else {
1622                     ReturnToServerPool(service);
1623                 }
1624             }
1625         }
1626
1627         if (call) {
1628             queue_Remove(call);
1629             MUTEX_EXIT(&rx_serverPool_lock);
1630             MUTEX_ENTER(&call->lock);
1631
1632             if (call->flags & RX_CALL_WAIT_PROC) {
1633                 call->flags &= ~RX_CALL_WAIT_PROC;
1634                 MUTEX_ENTER(&rx_stats_mutex);
1635                 rx_nWaiting--;
1636                 MUTEX_EXIT(&rx_stats_mutex);
1637             }
1638
1639             if (call->state != RX_STATE_PRECALL || call->error) {
1640                 MUTEX_EXIT(&call->lock);
1641                 MUTEX_ENTER(&rx_serverPool_lock);
1642                 ReturnToServerPool(service);
1643                 call = NULL;
1644                 continue;
1645             }
1646
1647             if (queue_IsEmpty(&call->rq)
1648                 || queue_First(&call->rq, rx_packet)->header.seq != 1)
1649                 rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
1650
1651             CLEAR_CALL_QUEUE_LOCK(call);
1652             break;
1653         } else {
1654             /* If there are no eligible incoming calls, add this process
1655              * to the idle server queue, to wait for one */
1656             sq->newcall = 0;
1657             sq->tno = tno;
1658             if (socketp) {
1659                 *socketp = OSI_NULLSOCKET;
1660             }
1661             sq->socketp = socketp;
1662             queue_Append(&rx_idleServerQueue, sq);
1663 #ifndef AFS_AIX41_ENV
1664             rx_waitForPacket = sq;
1665 #else
1666             rx_waitingForPacket = sq;
1667 #endif /* AFS_AIX41_ENV */
1668             do {
1669                 CV_WAIT(&sq->cv, &rx_serverPool_lock);
1670 #ifdef  KERNEL
1671                 if (afs_termState == AFSOP_STOP_RXCALLBACK) {
1672                     MUTEX_EXIT(&rx_serverPool_lock);
1673                     return (struct rx_call *)0;
1674                 }
1675 #endif
1676             } while (!(call = sq->newcall)
1677                      && !(socketp && *socketp != OSI_NULLSOCKET));
1678             MUTEX_EXIT(&rx_serverPool_lock);
1679             if (call) {
1680                 MUTEX_ENTER(&call->lock);
1681             }
1682             break;
1683         }
1684     }
1685
1686     MUTEX_ENTER(&freeSQEList_lock);
1687     *(struct rx_serverQueueEntry **)sq = rx_FreeSQEList;
1688     rx_FreeSQEList = sq;
1689     MUTEX_EXIT(&freeSQEList_lock);
1690
1691     if (call) {
1692         clock_GetTime(&call->startTime);
1693         call->state = RX_STATE_ACTIVE;
1694         call->mode = RX_MODE_RECEIVING;
1695 #ifdef RX_KERNEL_TRACE
1696         if (ICL_SETACTIVE(afs_iclSetp)) {
1697             int glockOwner = ISAFS_GLOCK();
1698             if (!glockOwner)
1699                 AFS_GLOCK();
1700             afs_Trace3(afs_iclSetp, CM_TRACE_WASHERE, ICL_TYPE_STRING,
1701                        __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER,
1702                        call);
1703             if (!glockOwner)
1704                 AFS_GUNLOCK();
1705         }
1706 #endif
1707
1708         rxi_calltrace(RX_CALL_START, call);
1709         dpf(("rx_GetCall(port=%d, service=%d) ==> call %x\n",
1710              call->conn->service->servicePort, call->conn->service->serviceId,
1711              call));
1712
1713         CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN);
1714         MUTEX_EXIT(&call->lock);
1715     } else {
1716         dpf(("rx_GetCall(socketp=0x%x, *socketp=0x%x)\n", socketp, *socketp));
1717     }
1718
1719     return call;
1720 }
1721 #else /* RX_ENABLE_LOCKS */
1722 struct rx_call *
1723 rx_GetCall(int tno, struct rx_service *cur_service, osi_socket * socketp)
1724 {
1725     struct rx_serverQueueEntry *sq;
1726     register struct rx_call *call = (struct rx_call *)0, *choice2;
1727     struct rx_service *service = NULL;
1728     SPLVAR;
1729
1730     NETPRI;
1731     MUTEX_ENTER(&freeSQEList_lock);
1732
1733     if ((sq = rx_FreeSQEList)) {
1734         rx_FreeSQEList = *(struct rx_serverQueueEntry **)sq;
1735         MUTEX_EXIT(&freeSQEList_lock);
1736     } else {                    /* otherwise allocate a new one and return that */
1737         MUTEX_EXIT(&freeSQEList_lock);
1738         sq = (struct rx_serverQueueEntry *)
1739             rxi_Alloc(sizeof(struct rx_serverQueueEntry));
1740         MUTEX_INIT(&sq->lock, "server Queue lock", MUTEX_DEFAULT, 0);
1741         CV_INIT(&sq->cv, "server Queue lock", CV_DEFAULT, 0);
1742     }
1743     MUTEX_ENTER(&sq->lock);
1744
1745     if (cur_service != NULL) {
1746         cur_service->nRequestsRunning--;
1747         if (cur_service->nRequestsRunning < cur_service->minProcs)
1748             rxi_minDeficit++;
1749         rxi_availProcs++;
1750     }
1751     if (queue_IsNotEmpty(&rx_incomingCallQueue)) {
1752         register struct rx_call *tcall, *ncall;
1753         /* Scan for eligible incoming calls.  A call is not eligible
1754          * if the maximum number of calls for its service type are
1755          * already executing */
1756         /* One thread will process calls FCFS (to prevent starvation),
1757          * while the other threads may run ahead looking for calls which
1758          * have all their input data available immediately.  This helps 
1759          * keep threads from blocking, waiting for data from the client. */
1760         choice2 = (struct rx_call *)0;
1761         for (queue_Scan(&rx_incomingCallQueue, tcall, ncall, rx_call)) {
1762             service = tcall->conn->service;
1763             if (QuotaOK(service)) {
1764                 if (tno == rxi_fcfs_thread_num
1765                     || !tcall->queue_item_header.next) {
1766                     /* If we're the fcfs thread, then  we'll just use 
1767                      * this call. If we haven't been able to find an optimal 
1768                      * choice, and we're at the end of the list, then use a 
1769                      * 2d choice if one has been identified.  Otherwise... */
1770                     call = (choice2 ? choice2 : tcall);
1771                     service = call->conn->service;
1772                 } else if (!queue_IsEmpty(&tcall->rq)) {
1773                     struct rx_packet *rp;
1774                     rp = queue_First(&tcall->rq, rx_packet);
1775                     if (rp->header.seq == 1
1776                         && (!meltdown_1pkt
1777                             || (rp->header.flags & RX_LAST_PACKET))) {
1778                         call = tcall;
1779                     } else if (rxi_2dchoice && !choice2
1780                                && !(tcall->flags & RX_CALL_CLEARED)
1781                                && (tcall->rprev > rxi_HardAckRate)) {
1782                         choice2 = tcall;
1783                     } else
1784                         rxi_md2cnt++;
1785                 }
1786             }
1787             if (call)
1788                 break;
1789         }
1790     }
1791
1792     if (call) {
1793         queue_Remove(call);
1794         /* we can't schedule a call if there's no data!!! */
1795         /* send an ack if there's no data, if we're missing the
1796          * first packet, or we're missing something between first 
1797          * and last -- there's a "hole" in the incoming data. */
1798         if (queue_IsEmpty(&call->rq)
1799             || queue_First(&call->rq, rx_packet)->header.seq != 1
1800             || call->rprev != queue_Last(&call->rq, rx_packet)->header.seq)
1801             rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
1802
1803         call->flags &= (~RX_CALL_WAIT_PROC);
1804         service->nRequestsRunning++;
1805         /* just started call in minProcs pool, need fewer to maintain
1806          * guarantee */
1807         if (service->nRequestsRunning <= service->minProcs)
1808             rxi_minDeficit--;
1809         rxi_availProcs--;
1810         rx_nWaiting--;
1811         /* MUTEX_EXIT(&call->lock); */
1812     } else {
1813         /* If there are no eligible incoming calls, add this process
1814          * to the idle server queue, to wait for one */
1815         sq->newcall = 0;
1816         if (socketp) {
1817             *socketp = OSI_NULLSOCKET;
1818         }
1819         sq->socketp = socketp;
1820         queue_Append(&rx_idleServerQueue, sq);
1821         do {
1822             osi_rxSleep(sq);
1823 #ifdef  KERNEL
1824             if (afs_termState == AFSOP_STOP_RXCALLBACK) {
1825                 USERPRI;
1826                 rxi_Free(sq, sizeof(struct rx_serverQueueEntry));
1827                 return (struct rx_call *)0;
1828             }
1829 #endif
1830         } while (!(call = sq->newcall)
1831                  && !(socketp && *socketp != OSI_NULLSOCKET));
1832     }
1833     MUTEX_EXIT(&sq->lock);
1834
1835     MUTEX_ENTER(&freeSQEList_lock);
1836     *(struct rx_serverQueueEntry **)sq = rx_FreeSQEList;
1837     rx_FreeSQEList = sq;
1838     MUTEX_EXIT(&freeSQEList_lock);
1839
1840     if (call) {
1841         clock_GetTime(&call->startTime);
1842         call->state = RX_STATE_ACTIVE;
1843         call->mode = RX_MODE_RECEIVING;
1844 #ifdef RX_KERNEL_TRACE
1845         if (ICL_SETACTIVE(afs_iclSetp)) {
1846             int glockOwner = ISAFS_GLOCK();
1847             if (!glockOwner)
1848                 AFS_GLOCK();
1849             afs_Trace3(afs_iclSetp, CM_TRACE_WASHERE, ICL_TYPE_STRING,
1850                        __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER,
1851                        call);
1852             if (!glockOwner)
1853                 AFS_GUNLOCK();
1854         }
1855 #endif
1856
1857         rxi_calltrace(RX_CALL_START, call);
1858         dpf(("rx_GetCall(port=%d, service=%d) ==> call %x\n",
1859              call->conn->service->servicePort, call->conn->service->serviceId,
1860              call));
1861     } else {
1862         dpf(("rx_GetCall(socketp=0x%x, *socketp=0x%x)\n", socketp, *socketp));
1863     }
1864
1865     USERPRI;
1866
1867     return call;
1868 }
1869 #endif /* RX_ENABLE_LOCKS */
1870
1871
1872
1873 /* Establish a procedure to be called when a packet arrives for a
1874  * call.  This routine will be called at most once after each call,
1875  * and will also be called if there is an error condition on the or
1876  * the call is complete.  Used by multi rx to build a selection
1877  * function which determines which of several calls is likely to be a
1878  * good one to read from.  
1879  * NOTE: the way this is currently implemented it is probably only a
1880  * good idea to (1) use it immediately after a newcall (clients only)
1881  * and (2) only use it once.  Other uses currently void your warranty
1882  */
1883 void
1884 rx_SetArrivalProc(register struct rx_call *call,
1885                   register void (*proc) (register struct rx_call * call,
1886                                         register void * mh,
1887                                         register int index),
1888                   register void * handle, register int arg)
1889 {
1890     call->arrivalProc = proc;
1891     call->arrivalProcHandle = handle;
1892     call->arrivalProcArg = arg;
1893 }
1894
1895 /* Call is finished (possibly prematurely).  Return rc to the peer, if
1896  * appropriate, and return the final error code from the conversation
1897  * to the caller */
1898
1899 afs_int32
1900 rx_EndCall(register struct rx_call *call, afs_int32 rc)
1901 {
1902     register struct rx_connection *conn = call->conn;
1903     register struct rx_service *service;
1904     afs_int32 error;
1905     SPLVAR;
1906
1907
1908
1909     dpf(("rx_EndCall(call %x rc %d error %d abortCode %d)\n", call, rc, call->error, call->abortCode));
1910
1911     NETPRI;
1912     MUTEX_ENTER(&call->lock);
1913
1914     if (rc == 0 && call->error == 0) {
1915         call->abortCode = 0;
1916         call->abortCount = 0;
1917     }
1918
1919     call->arrivalProc = (void (*)())0;
1920     if (rc && call->error == 0) {
1921         rxi_CallError(call, rc);
1922         /* Send an abort message to the peer if this error code has
1923          * only just been set.  If it was set previously, assume the
1924          * peer has already been sent the error code or will request it 
1925          */
1926         rxi_SendCallAbort(call, (struct rx_packet *)0, 0, 0);
1927     }
1928     if (conn->type == RX_SERVER_CONNECTION) {
1929         /* Make sure reply or at least dummy reply is sent */
1930         if (call->mode == RX_MODE_RECEIVING) {
1931             rxi_WriteProc(call, 0, 0);
1932         }
1933         if (call->mode == RX_MODE_SENDING) {
1934             rxi_FlushWrite(call);
1935         }
1936         service = conn->service;
1937         rxi_calltrace(RX_CALL_END, call);
1938         /* Call goes to hold state until reply packets are acknowledged */
1939         if (call->tfirst + call->nSoftAcked < call->tnext) {
1940             call->state = RX_STATE_HOLD;
1941         } else {
1942             call->state = RX_STATE_DALLY;
1943             rxi_ClearTransmitQueue(call, 0);
1944             rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
1945             rxevent_Cancel(call->keepAliveEvent, call,
1946                            RX_CALL_REFCOUNT_ALIVE);
1947         }
1948     } else {                    /* Client connection */
1949         char dummy;
1950         /* Make sure server receives input packets, in the case where
1951          * no reply arguments are expected */
1952         if ((call->mode == RX_MODE_SENDING)
1953             || (call->mode == RX_MODE_RECEIVING && call->rnext == 1)) {
1954             (void)rxi_ReadProc(call, &dummy, 1);
1955         }
1956
1957         /* If we had an outstanding delayed ack, be nice to the server
1958          * and force-send it now.
1959          */
1960         if (call->delayedAckEvent) {
1961             rxevent_Cancel(call->delayedAckEvent, call,
1962                            RX_CALL_REFCOUNT_DELAY);
1963             call->delayedAckEvent = NULL;
1964             rxi_SendDelayedAck(NULL, call, NULL);
1965         }
1966
1967         /* We need to release the call lock since it's lower than the
1968          * conn_call_lock and we don't want to hold the conn_call_lock
1969          * over the rx_ReadProc call. The conn_call_lock needs to be held
1970          * here for the case where rx_NewCall is perusing the calls on
1971          * the connection structure. We don't want to signal until
1972          * rx_NewCall is in a stable state. Otherwise, rx_NewCall may
1973          * have checked this call, found it active and by the time it
1974          * goes to sleep, will have missed the signal.
1975          *
1976          * Do not clear the RX_CONN_MAKECALL_WAITING flag as long as
1977          * there are threads waiting to use the conn object.
1978          */
1979         MUTEX_EXIT(&call->lock);
1980         MUTEX_ENTER(&conn->conn_call_lock);
1981         MUTEX_ENTER(&call->lock);
1982         MUTEX_ENTER(&conn->conn_data_lock);
1983         conn->flags |= RX_CONN_BUSY;
1984         if (conn->flags & RX_CONN_MAKECALL_WAITING) {
1985             if (conn->makeCallWaiters == 0)
1986                 conn->flags &= (~RX_CONN_MAKECALL_WAITING);
1987             MUTEX_EXIT(&conn->conn_data_lock);
1988 #ifdef  RX_ENABLE_LOCKS
1989             CV_BROADCAST(&conn->conn_call_cv);
1990 #else
1991             osi_rxWakeup(conn);
1992 #endif
1993         }
1994 #ifdef RX_ENABLE_LOCKS
1995         else {
1996             MUTEX_EXIT(&conn->conn_data_lock);
1997         }
1998 #endif /* RX_ENABLE_LOCKS */
1999         call->state = RX_STATE_DALLY;
2000     }
2001     error = call->error;
2002
2003     /* currentPacket, nLeft, and NFree must be zeroed here, because
2004      * ResetCall cannot: ResetCall may be called at splnet(), in the
2005      * kernel version, and may interrupt the macros rx_Read or
2006      * rx_Write, which run at normal priority for efficiency. */
2007     if (call->currentPacket) {
2008         queue_Prepend(&call->iovq, call->currentPacket);
2009         call->currentPacket = (struct rx_packet *)0;
2010     }
2011         
2012     call->nLeft = call->nFree = call->curlen = 0;
2013
2014     /* Free any packets from the last call to ReadvProc/WritevProc */
2015     rxi_FreePackets(0, &call->iovq);
2016
2017     CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
2018     MUTEX_EXIT(&call->lock);
2019     if (conn->type == RX_CLIENT_CONNECTION) {
2020         MUTEX_EXIT(&conn->conn_call_lock);
2021         conn->flags &= ~RX_CONN_BUSY;
2022     }
2023     USERPRI;
2024     /*
2025      * Map errors to the local host's errno.h format.
2026      */
2027     error = ntoh_syserr_conv(error);
2028     return error;
2029 }
2030
2031 #if !defined(KERNEL)
2032
2033 /* Call this routine when shutting down a server or client (especially
2034  * clients).  This will allow Rx to gracefully garbage collect server
2035  * connections, and reduce the number of retries that a server might
2036  * make to a dead client.
2037  * This is not quite right, since some calls may still be ongoing and
2038  * we can't lock them to destroy them. */
2039 void
2040 rx_Finalize(void)
2041 {
2042     register struct rx_connection **conn_ptr, **conn_end;
2043
2044     INIT_PTHREAD_LOCKS;
2045     LOCK_RX_INIT;
2046     if (rxinit_status == 1) {
2047         UNLOCK_RX_INIT;
2048         return;                 /* Already shutdown. */
2049     }
2050     rxi_DeleteCachedConnections();
2051     if (rx_connHashTable) {
2052         MUTEX_ENTER(&rx_connHashTable_lock);
2053         for (conn_ptr = &rx_connHashTable[0], conn_end =
2054              &rx_connHashTable[rx_hashTableSize]; conn_ptr < conn_end;
2055              conn_ptr++) {
2056             struct rx_connection *conn, *next;
2057             for (conn = *conn_ptr; conn; conn = next) {
2058                 next = conn->next;
2059                 if (conn->type == RX_CLIENT_CONNECTION) {
2060                     /* MUTEX_ENTER(&conn->conn_data_lock); when used in kernel */
2061                     conn->refCount++;
2062                     /* MUTEX_EXIT(&conn->conn_data_lock); when used in kernel */
2063 #ifdef RX_ENABLE_LOCKS
2064                     rxi_DestroyConnectionNoLock(conn);
2065 #else /* RX_ENABLE_LOCKS */
2066                     rxi_DestroyConnection(conn);
2067 #endif /* RX_ENABLE_LOCKS */
2068                 }
2069             }
2070         }
2071 #ifdef RX_ENABLE_LOCKS
2072         while (rx_connCleanup_list) {
2073             struct rx_connection *conn;
2074             conn = rx_connCleanup_list;
2075             rx_connCleanup_list = rx_connCleanup_list->next;
2076             MUTEX_EXIT(&rx_connHashTable_lock);
2077             rxi_CleanupConnection(conn);
2078             MUTEX_ENTER(&rx_connHashTable_lock);
2079         }
2080         MUTEX_EXIT(&rx_connHashTable_lock);
2081 #endif /* RX_ENABLE_LOCKS */
2082     }
2083     rxi_flushtrace();
2084
2085 #ifdef AFS_NT40_ENV
2086     afs_winsockCleanup();
2087 #endif
2088
2089     rxinit_status = 1;
2090     UNLOCK_RX_INIT;
2091 }
2092 #endif
2093
2094 /* if we wakeup packet waiter too often, can get in loop with two
2095     AllocSendPackets each waking each other up (from ReclaimPacket calls) */
2096 void
2097 rxi_PacketsUnWait(void)
2098 {
2099     if (!rx_waitingForPackets) {
2100         return;
2101     }
2102 #ifdef KERNEL
2103     if (rxi_OverQuota(RX_PACKET_CLASS_SEND)) {
2104         return;                 /* still over quota */
2105     }
2106 #endif /* KERNEL */
2107     rx_waitingForPackets = 0;
2108 #ifdef  RX_ENABLE_LOCKS
2109     CV_BROADCAST(&rx_waitingForPackets_cv);
2110 #else
2111     osi_rxWakeup(&rx_waitingForPackets);
2112 #endif
2113     return;
2114 }
2115
2116
2117 /* ------------------Internal interfaces------------------------- */
2118
2119 /* Return this process's service structure for the
2120  * specified socket and service */
2121 struct rx_service *
2122 rxi_FindService(register osi_socket socket, register u_short serviceId)
2123 {
2124     register struct rx_service **sp;
2125     for (sp = &rx_services[0]; *sp; sp++) {
2126         if ((*sp)->serviceId == serviceId && (*sp)->socket == socket)
2127             return *sp;
2128     }
2129     return 0;
2130 }
2131
2132 /* Allocate a call structure, for the indicated channel of the
2133  * supplied connection.  The mode and state of the call must be set by
2134  * the caller. Returns the call with mutex locked. */
2135 struct rx_call *
2136 rxi_NewCall(register struct rx_connection *conn, register int channel)
2137 {
2138     register struct rx_call *call;
2139 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
2140     register struct rx_call *cp;        /* Call pointer temp */
2141     register struct rx_call *nxp;       /* Next call pointer, for queue_Scan */
2142 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2143
2144     dpf(("rxi_NewCall(conn %x, channel %d)\n", conn, channel));
2145
2146     /* Grab an existing call structure, or allocate a new one.
2147      * Existing call structures are assumed to have been left reset by
2148      * rxi_FreeCall */
2149     MUTEX_ENTER(&rx_freeCallQueue_lock);
2150
2151 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
2152     /*
2153      * EXCEPT that the TQ might not yet be cleared out.
2154      * Skip over those with in-use TQs.
2155      */
2156     call = NULL;
2157     for (queue_Scan(&rx_freeCallQueue, cp, nxp, rx_call)) {
2158         if (!(cp->flags & RX_CALL_TQ_BUSY)) {
2159             call = cp;
2160             break;
2161         }
2162     }
2163     if (call) {
2164 #else /* AFS_GLOBAL_RXLOCK_KERNEL */
2165     if (queue_IsNotEmpty(&rx_freeCallQueue)) {
2166         call = queue_First(&rx_freeCallQueue, rx_call);
2167 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2168         queue_Remove(call);
2169         rx_MutexDecrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
2170         MUTEX_EXIT(&rx_freeCallQueue_lock);
2171         MUTEX_ENTER(&call->lock);
2172         CLEAR_CALL_QUEUE_LOCK(call);
2173 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
2174         /* Now, if TQ wasn't cleared earlier, do it now. */
2175         if (call->flags & RX_CALL_TQ_CLEARME) {
2176             rxi_ClearTransmitQueue(call, 0);
2177             queue_Init(&call->tq);
2178         }
2179 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2180         /* Bind the call to its connection structure */
2181         call->conn = conn;
2182         rxi_ResetCall(call, 1);
2183     } else {
2184
2185         call = (struct rx_call *)rxi_Alloc(sizeof(struct rx_call));
2186
2187         MUTEX_EXIT(&rx_freeCallQueue_lock);
2188         MUTEX_INIT(&call->lock, "call lock", MUTEX_DEFAULT, NULL);
2189         MUTEX_ENTER(&call->lock);
2190         CV_INIT(&call->cv_twind, "call twind", CV_DEFAULT, 0);
2191         CV_INIT(&call->cv_rq, "call rq", CV_DEFAULT, 0);
2192         CV_INIT(&call->cv_tq, "call tq", CV_DEFAULT, 0);
2193
2194         rx_MutexIncrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
2195         /* Initialize once-only items */
2196         queue_Init(&call->tq);
2197         queue_Init(&call->rq);
2198         queue_Init(&call->iovq);
2199         /* Bind the call to its connection structure (prereq for reset) */
2200         call->conn = conn;
2201         rxi_ResetCall(call, 1);
2202     }
2203     call->channel = channel;
2204     call->callNumber = &conn->callNumber[channel];
2205     call->rwind = conn->rwind[channel];
2206     call->twind = conn->twind[channel];
2207     /* Note that the next expected call number is retained (in
2208      * conn->callNumber[i]), even if we reallocate the call structure
2209      */
2210     conn->call[channel] = call;
2211     /* if the channel's never been used (== 0), we should start at 1, otherwise
2212      * the call number is valid from the last time this channel was used */
2213     if (*call->callNumber == 0)
2214         *call->callNumber = 1;
2215
2216     return call;
2217 }
2218
2219 /* A call has been inactive long enough that so we can throw away
2220  * state, including the call structure, which is placed on the call
2221  * free list.
2222  * Call is locked upon entry.
2223  * haveCTLock set if called from rxi_ReapConnections
2224  */
2225 #ifdef RX_ENABLE_LOCKS
2226 void
2227 rxi_FreeCall(register struct rx_call *call, int haveCTLock)
2228 #else /* RX_ENABLE_LOCKS */
2229 void
2230 rxi_FreeCall(register struct rx_call *call)
2231 #endif                          /* RX_ENABLE_LOCKS */
2232 {
2233     register int channel = call->channel;
2234     register struct rx_connection *conn = call->conn;
2235
2236
2237     if (call->state == RX_STATE_DALLY || call->state == RX_STATE_HOLD)
2238         (*call->callNumber)++;
2239     rxi_ResetCall(call, 0);
2240     call->conn->call[channel] = (struct rx_call *)0;
2241
2242     MUTEX_ENTER(&rx_freeCallQueue_lock);
2243     SET_CALL_QUEUE_LOCK(call, &rx_freeCallQueue_lock);
2244 #ifdef AFS_GLOBAL_RXLOCK_KERNEL
2245     /* A call may be free even though its transmit queue is still in use.
2246      * Since we search the call list from head to tail, put busy calls at
2247      * the head of the list, and idle calls at the tail.
2248      */
2249     if (call->flags & RX_CALL_TQ_BUSY)
2250         queue_Prepend(&rx_freeCallQueue, call);
2251     else
2252         queue_Append(&rx_freeCallQueue, call);
2253 #else /* AFS_GLOBAL_RXLOCK_KERNEL */
2254     queue_Append(&rx_freeCallQueue, call);
2255 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2256     rx_MutexIncrement(rx_stats.nFreeCallStructs, rx_stats_mutex);
2257     MUTEX_EXIT(&rx_freeCallQueue_lock);
2258
2259     /* Destroy the connection if it was previously slated for
2260      * destruction, i.e. the Rx client code previously called
2261      * rx_DestroyConnection (client connections), or
2262      * rxi_ReapConnections called the same routine (server
2263      * connections).  Only do this, however, if there are no
2264      * outstanding calls. Note that for fine grain locking, there appears
2265      * to be a deadlock in that rxi_FreeCall has a call locked and
2266      * DestroyConnectionNoLock locks each call in the conn. But note a
2267      * few lines up where we have removed this call from the conn.
2268      * If someone else destroys a connection, they either have no
2269      * call lock held or are going through this section of code.
2270      */
2271     if (conn->flags & RX_CONN_DESTROY_ME && !(conn->flags & RX_CONN_MAKECALL_WAITING)) {
2272         MUTEX_ENTER(&conn->conn_data_lock);
2273         conn->refCount++;
2274         MUTEX_EXIT(&conn->conn_data_lock);
2275 #ifdef RX_ENABLE_LOCKS
2276         if (haveCTLock)
2277             rxi_DestroyConnectionNoLock(conn);
2278         else
2279             rxi_DestroyConnection(conn);
2280 #else /* RX_ENABLE_LOCKS */
2281         rxi_DestroyConnection(conn);
2282 #endif /* RX_ENABLE_LOCKS */
2283     }
2284 }
2285
2286 afs_int32 rxi_Alloccnt = 0, rxi_Allocsize = 0;
2287 char *
2288 rxi_Alloc(register size_t size)
2289 {
2290     register char *p;
2291
2292     rx_MutexAdd1Increment2(rxi_Allocsize, (afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
2293
2294 p = (char *)
2295 #if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV)
2296   afs_osi_Alloc_NoSleep(size);
2297 #else
2298   osi_Alloc(size);
2299 #endif
2300     if (!p)
2301         osi_Panic("rxi_Alloc error");
2302     memset(p, 0, size);
2303     return p;
2304 }
2305
2306 void
2307 rxi_Free(void *addr, register size_t size)
2308 {
2309     rx_MutexAdd1Decrement2(rxi_Allocsize, -(afs_int32)size, rxi_Alloccnt, rx_stats_mutex);
2310     osi_Free(addr, size);
2311 }
2312
2313 void 
2314 rxi_SetPeerMtu(register afs_uint32 host, register afs_uint32 port, int mtu)
2315 {
2316     struct rx_peer **peer_ptr, **peer_end;
2317     int hashIndex;
2318
2319     MUTEX_ENTER(&rx_peerHashTable_lock);
2320     if (port == 0) {
2321        for (peer_ptr = &rx_peerHashTable[0], peer_end =
2322                 &rx_peerHashTable[rx_hashTableSize]; peer_ptr < peer_end;
2323             peer_ptr++) {
2324            struct rx_peer *peer, *next;
2325            for (peer = *peer_ptr; peer; peer = next) {
2326                next = peer->next;
2327                if (host == peer->host) {
2328                    MUTEX_ENTER(&peer->peer_lock);
2329                    peer->ifMTU=MIN(mtu, peer->ifMTU);
2330                    peer->natMTU = rxi_AdjustIfMTU(peer->ifMTU);
2331                    MUTEX_EXIT(&peer->peer_lock);
2332                }
2333            }
2334        }
2335     } else {
2336        struct rx_peer *peer;
2337        hashIndex = PEER_HASH(host, port);
2338        for (peer = rx_peerHashTable[hashIndex]; peer; peer = peer->next) {
2339            if ((peer->host == host) && (peer->port == port)) {
2340                MUTEX_ENTER(&peer->peer_lock);
2341                peer->ifMTU=MIN(mtu, peer->ifMTU);
2342                peer->natMTU = rxi_AdjustIfMTU(peer->ifMTU);
2343                MUTEX_EXIT(&peer->peer_lock);
2344            }
2345        }
2346     }
2347     MUTEX_EXIT(&rx_peerHashTable_lock);
2348 }
2349
2350 /* Find the peer process represented by the supplied (host,port)
2351  * combination.  If there is no appropriate active peer structure, a
2352  * new one will be allocated and initialized 
2353  * The origPeer, if set, is a pointer to a peer structure on which the
2354  * refcount will be be decremented. This is used to replace the peer
2355  * structure hanging off a connection structure */
2356 struct rx_peer *
2357 rxi_FindPeer(register afs_uint32 host, register u_short port,
2358              struct rx_peer *origPeer, int create)
2359 {
2360     register struct rx_peer *pp;
2361     int hashIndex;
2362     hashIndex = PEER_HASH(host, port);
2363     MUTEX_ENTER(&rx_peerHashTable_lock);
2364     for (pp = rx_peerHashTable[hashIndex]; pp; pp = pp->next) {
2365         if ((pp->host == host) && (pp->port == port))
2366             break;
2367     }
2368     if (!pp) {
2369         if (create) {
2370             pp = rxi_AllocPeer();       /* This bzero's *pp */
2371             pp->host = host;    /* set here or in InitPeerParams is zero */
2372             pp->port = port;
2373             MUTEX_INIT(&pp->peer_lock, "peer_lock", MUTEX_DEFAULT, 0);
2374             queue_Init(&pp->congestionQueue);
2375             queue_Init(&pp->rpcStats);
2376             pp->next = rx_peerHashTable[hashIndex];
2377             rx_peerHashTable[hashIndex] = pp;
2378             rxi_InitPeerParams(pp);
2379             rx_MutexIncrement(rx_stats.nPeerStructs, rx_stats_mutex);
2380         }
2381     }
2382     if (pp && create) {
2383         pp->refCount++;
2384     }
2385     if (origPeer)
2386         origPeer->refCount--;
2387     MUTEX_EXIT(&rx_peerHashTable_lock);
2388     return pp;
2389 }
2390
2391
2392 /* Find the connection at (host, port) started at epoch, and with the
2393  * given connection id.  Creates the server connection if necessary.
2394  * The type specifies whether a client connection or a server
2395  * connection is desired.  In both cases, (host, port) specify the
2396  * peer's (host, pair) pair.  Client connections are not made
2397  * automatically by this routine.  The parameter socket gives the
2398  * socket descriptor on which the packet was received.  This is used,
2399  * in the case of server connections, to check that *new* connections
2400  * come via a valid (port, serviceId).  Finally, the securityIndex
2401  * parameter must match the existing index for the connection.  If a
2402  * server connection is created, it will be created using the supplied
2403  * index, if the index is valid for this service */
2404 struct rx_connection *
2405 rxi_FindConnection(osi_socket socket, register afs_int32 host,
2406                    register u_short port, u_short serviceId, afs_uint32 cid,
2407                    afs_uint32 epoch, int type, u_int securityIndex)
2408 {
2409     int hashindex, flag, i;
2410     register struct rx_connection *conn;
2411     hashindex = CONN_HASH(host, port, cid, epoch, type);
2412     MUTEX_ENTER(&rx_connHashTable_lock);
2413     rxLastConn ? (conn = rxLastConn, flag = 0) : (conn =
2414                                                   rx_connHashTable[hashindex],
2415                                                   flag = 1);
2416     for (; conn;) {
2417         if ((conn->type == type) && ((cid & RX_CIDMASK) == conn->cid)
2418             && (epoch == conn->epoch)) {
2419             register struct rx_peer *pp = conn->peer;
2420             if (securityIndex != conn->securityIndex) {
2421                 /* this isn't supposed to happen, but someone could forge a packet
2422                  * like this, and there seems to be some CM bug that makes this
2423                  * happen from time to time -- in which case, the fileserver
2424                  * asserts. */
2425                 MUTEX_EXIT(&rx_connHashTable_lock);
2426                 return (struct rx_connection *)0;
2427             }
2428             if (pp->host == host && pp->port == port)
2429                 break;
2430             if (type == RX_CLIENT_CONNECTION && pp->port == port)
2431                 break;
2432             /* So what happens when it's a callback connection? */
2433             if (                /*type == RX_CLIENT_CONNECTION && */
2434                    (conn->epoch & 0x80000000))
2435                 break;
2436         }
2437         if (!flag) {
2438             /* the connection rxLastConn that was used the last time is not the
2439              ** one we are looking for now. Hence, start searching in the hash */
2440             flag = 1;
2441             conn = rx_connHashTable[hashindex];
2442         } else
2443             conn = conn->next;
2444     }
2445     if (!conn) {
2446         struct rx_service *service;
2447         if (type == RX_CLIENT_CONNECTION) {
2448             MUTEX_EXIT(&rx_connHashTable_lock);
2449             return (struct rx_connection *)0;
2450         }
2451         service = rxi_FindService(socket, serviceId);
2452         if (!service || (securityIndex >= service->nSecurityObjects)
2453             || (service->securityObjects[securityIndex] == 0)) {
2454             MUTEX_EXIT(&rx_connHashTable_lock);
2455             return (struct rx_connection *)0;
2456         }
2457         conn = rxi_AllocConnection();   /* This bzero's the connection */
2458         MUTEX_INIT(&conn->conn_call_lock, "conn call lock", MUTEX_DEFAULT, 0);
2459         MUTEX_INIT(&conn->conn_data_lock, "conn data lock", MUTEX_DEFAULT, 0);
2460         CV_INIT(&conn->conn_call_cv, "conn call cv", CV_DEFAULT, 0);
2461         conn->next = rx_connHashTable[hashindex];
2462         rx_connHashTable[hashindex] = conn;
2463         conn->peer = rxi_FindPeer(host, port, 0, 1);
2464         conn->type = RX_SERVER_CONNECTION;
2465         conn->lastSendTime = clock_Sec();       /* don't GC immediately */
2466         conn->epoch = epoch;
2467         conn->cid = cid & RX_CIDMASK;
2468         /* conn->serial = conn->lastSerial = 0; */
2469         /* conn->timeout = 0; */
2470         conn->ackRate = RX_FAST_ACK_RATE;
2471         conn->service = service;
2472         conn->serviceId = serviceId;
2473         conn->securityIndex = securityIndex;
2474         conn->securityObject = service->securityObjects[securityIndex];
2475         conn->nSpecific = 0;
2476         conn->specific = NULL;
2477         rx_SetConnDeadTime(conn, service->connDeadTime);
2478         rx_SetConnIdleDeadTime(conn, service->idleDeadTime);
2479         rx_SetServerConnIdleDeadErr(conn, service->idleDeadErr);
2480         for (i = 0; i < RX_MAXCALLS; i++) {
2481             conn->twind[i] = rx_initSendWindow;
2482             conn->rwind[i] = rx_initReceiveWindow;
2483         }
2484         /* Notify security object of the new connection */
2485         RXS_NewConnection(conn->securityObject, conn);
2486         /* XXXX Connection timeout? */
2487         if (service->newConnProc)
2488             (*service->newConnProc) (conn);
2489         rx_MutexIncrement(rx_stats.nServerConns, rx_stats_mutex);
2490     }
2491
2492     MUTEX_ENTER(&conn->conn_data_lock);
2493     conn->refCount++;
2494     MUTEX_EXIT(&conn->conn_data_lock);
2495
2496     rxLastConn = conn;          /* store this connection as the last conn used */
2497     MUTEX_EXIT(&rx_connHashTable_lock);
2498     return conn;
2499 }
2500
2501 /* There are two packet tracing routines available for testing and monitoring
2502  * Rx.  One is called just after every packet is received and the other is
2503  * called just before every packet is sent.  Received packets, have had their
2504  * headers decoded, and packets to be sent have not yet had their headers
2505  * encoded.  Both take two parameters: a pointer to the packet and a sockaddr
2506  * containing the network address.  Both can be modified.  The return value, if
2507  * non-zero, indicates that the packet should be dropped.  */
2508
2509 int (*rx_justReceived) (struct rx_packet *, struct sockaddr_in *) = 0;
2510 int (*rx_almostSent) (struct rx_packet *, struct sockaddr_in *) = 0;
2511
2512 /* A packet has been received off the interface.  Np is the packet, socket is
2513  * the socket number it was received from (useful in determining which service
2514  * this packet corresponds to), and (host, port) reflect the host,port of the
2515  * sender.  This call returns the packet to the caller if it is finished with
2516  * it, rather than de-allocating it, just as a small performance hack */
2517
2518 struct rx_packet *
2519 rxi_ReceivePacket(register struct rx_packet *np, osi_socket socket,
2520                   afs_uint32 host, u_short port, int *tnop,
2521                   struct rx_call **newcallp)
2522 {
2523     register struct rx_call *call;
2524     register struct rx_connection *conn;
2525     int channel;
2526     afs_uint32 currentCallNumber;
2527     int type;
2528     int skew;
2529 #ifdef RXDEBUG
2530     char *packetType;
2531 #endif
2532     struct rx_packet *tnp;
2533
2534 #ifdef RXDEBUG
2535 /* We don't print out the packet until now because (1) the time may not be
2536  * accurate enough until now in the lwp implementation (rx_Listener only gets
2537  * the time after the packet is read) and (2) from a protocol point of view,
2538  * this is the first time the packet has been seen */
2539     packetType = (np->header.type > 0 && np->header.type < RX_N_PACKET_TYPES)
2540         ? rx_packetTypes[np->header.type - 1] : "*UNKNOWN*";
2541     dpf(("R %d %s: %x.%d.%d.%d.%d.%d.%d flags %d, packet %x",
2542          np->header.serial, packetType, ntohl(host), ntohs(port), np->header.serviceId,
2543          np->header.epoch, np->header.cid, np->header.callNumber,
2544          np->header.seq, np->header.flags, np));
2545 #endif
2546
2547     if (np->header.type == RX_PACKET_TYPE_VERSION) {
2548         return rxi_ReceiveVersionPacket(np, socket, host, port, 1);
2549     }
2550
2551     if (np->header.type == RX_PACKET_TYPE_DEBUG) {
2552         return rxi_ReceiveDebugPacket(np, socket, host, port, 1);
2553     }
2554 #ifdef RXDEBUG
2555     /* If an input tracer function is defined, call it with the packet and
2556      * network address.  Note this function may modify its arguments. */
2557     if (rx_justReceived) {
2558         struct sockaddr_in addr;
2559         int drop;
2560         addr.sin_family = AF_INET;
2561         addr.sin_port = port;
2562         addr.sin_addr.s_addr = host;
2563 #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
2564         addr.sin_len = sizeof(addr);
2565 #endif /* AFS_OSF_ENV */
2566         drop = (*rx_justReceived) (np, &addr);
2567         /* drop packet if return value is non-zero */
2568         if (drop)
2569             return np;
2570         port = addr.sin_port;   /* in case fcn changed addr */
2571         host = addr.sin_addr.s_addr;
2572     }
2573 #endif
2574
2575     /* If packet was not sent by the client, then *we* must be the client */
2576     type = ((np->header.flags & RX_CLIENT_INITIATED) != RX_CLIENT_INITIATED)
2577         ? RX_CLIENT_CONNECTION : RX_SERVER_CONNECTION;
2578
2579     /* Find the connection (or fabricate one, if we're the server & if
2580      * necessary) associated with this packet */
2581     conn =
2582         rxi_FindConnection(socket, host, port, np->header.serviceId,
2583                            np->header.cid, np->header.epoch, type,
2584                            np->header.securityIndex);
2585
2586     if (!conn) {
2587         /* If no connection found or fabricated, just ignore the packet.
2588          * (An argument could be made for sending an abort packet for
2589          * the conn) */
2590         return np;
2591     }
2592
2593     MUTEX_ENTER(&conn->conn_data_lock);
2594     if (conn->maxSerial < np->header.serial)
2595         conn->maxSerial = np->header.serial;
2596     MUTEX_EXIT(&conn->conn_data_lock);
2597
2598     /* If the connection is in an error state, send an abort packet and ignore
2599      * the incoming packet */
2600     if (conn->error) {
2601         /* Don't respond to an abort packet--we don't want loops! */
2602         MUTEX_ENTER(&conn->conn_data_lock);
2603         if (np->header.type != RX_PACKET_TYPE_ABORT)
2604             np = rxi_SendConnectionAbort(conn, np, 1, 0);
2605         conn->refCount--;
2606         MUTEX_EXIT(&conn->conn_data_lock);
2607         return np;
2608     }
2609
2610     /* Check for connection-only requests (i.e. not call specific). */
2611     if (np->header.callNumber == 0) {
2612         switch (np->header.type) {
2613         case RX_PACKET_TYPE_ABORT: {
2614             /* What if the supplied error is zero? */
2615             afs_int32 errcode = ntohl(rx_GetInt32(np, 0));
2616             dpf(("rxi_ReceivePacket ABORT rx_GetInt32 = %d", errcode));
2617             rxi_ConnectionError(conn, errcode);
2618             MUTEX_ENTER(&conn->conn_data_lock);
2619             conn->refCount--;
2620             MUTEX_EXIT(&conn->conn_data_lock);
2621             return np;
2622         }
2623         case RX_PACKET_TYPE_CHALLENGE:
2624             tnp = rxi_ReceiveChallengePacket(conn, np, 1);
2625             MUTEX_ENTER(&conn->conn_data_lock);
2626             conn->refCount--;
2627             MUTEX_EXIT(&conn->conn_data_lock);
2628             return tnp;
2629         case RX_PACKET_TYPE_RESPONSE:
2630             tnp = rxi_ReceiveResponsePacket(conn, np, 1);
2631             MUTEX_ENTER(&conn->conn_data_lock);
2632             conn->refCount--;
2633             MUTEX_EXIT(&conn->conn_data_lock);
2634             return tnp;
2635         case RX_PACKET_TYPE_PARAMS:
2636         case RX_PACKET_TYPE_PARAMS + 1:
2637         case RX_PACKET_TYPE_PARAMS + 2:
2638             /* ignore these packet types for now */
2639             MUTEX_ENTER(&conn->conn_data_lock);
2640             conn->refCount--;
2641             MUTEX_EXIT(&conn->conn_data_lock);
2642             return np;
2643
2644
2645         default:
2646             /* Should not reach here, unless the peer is broken: send an
2647              * abort packet */
2648             rxi_ConnectionError(conn, RX_PROTOCOL_ERROR);
2649             MUTEX_ENTER(&conn->conn_data_lock);
2650             tnp = rxi_SendConnectionAbort(conn, np, 1, 0);
2651             conn->refCount--;
2652             MUTEX_EXIT(&conn->conn_data_lock);
2653             return tnp;
2654         }
2655     }
2656
2657     channel = np->header.cid & RX_CHANNELMASK;
2658     call = conn->call[channel];
2659 #ifdef  RX_ENABLE_LOCKS
2660     if (call)
2661         MUTEX_ENTER(&call->lock);
2662     /* Test to see if call struct is still attached to conn. */
2663     if (call != conn->call[channel]) {
2664         if (call)
2665             MUTEX_EXIT(&call->lock);
2666         if (type == RX_SERVER_CONNECTION) {
2667             call = conn->call[channel];
2668             /* If we started with no call attached and there is one now,
2669              * another thread is also running this routine and has gotten
2670              * the connection channel. We should drop this packet in the tests
2671              * below. If there was a call on this connection and it's now
2672              * gone, then we'll be making a new call below.
2673              * If there was previously a call and it's now different then
2674              * the old call was freed and another thread running this routine
2675              * has created a call on this channel. One of these two threads
2676              * has a packet for the old call and the code below handles those
2677              * cases.
2678              */
2679             if (call)
2680                 MUTEX_ENTER(&call->lock);
2681         } else {
2682             /* This packet can't be for this call. If the new call address is
2683              * 0 then no call is running on this channel. If there is a call
2684              * then, since this is a client connection we're getting data for
2685              * it must be for the previous call.
2686              */
2687             rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
2688             MUTEX_ENTER(&conn->conn_data_lock);
2689             conn->refCount--;
2690             MUTEX_EXIT(&conn->conn_data_lock);
2691             return np;
2692         }
2693     }
2694 #endif
2695     currentCallNumber = conn->callNumber[channel];
2696
2697     if (type == RX_SERVER_CONNECTION) { /* We're the server */
2698         if (np->header.callNumber < currentCallNumber) {
2699             rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
2700 #ifdef  RX_ENABLE_LOCKS
2701             if (call)
2702                 MUTEX_EXIT(&call->lock);
2703 #endif
2704             MUTEX_ENTER(&conn->conn_data_lock);
2705             conn->refCount--;
2706             MUTEX_EXIT(&conn->conn_data_lock);
2707             return np;
2708         }
2709         if (!call) {
2710             MUTEX_ENTER(&conn->conn_call_lock);
2711             call = rxi_NewCall(conn, channel);
2712             MUTEX_EXIT(&conn->conn_call_lock);
2713             *call->callNumber = np->header.callNumber;
2714             if (np->header.callNumber == 0) 
2715                 dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
2716
2717             call->state = RX_STATE_PRECALL;
2718             clock_GetTime(&call->queueTime);
2719             hzero(call->bytesSent);
2720             hzero(call->bytesRcvd);
2721             /*
2722              * If the number of queued calls exceeds the overload
2723              * threshold then abort this call.
2724              */
2725             if ((rx_BusyThreshold > 0) && (rx_nWaiting > rx_BusyThreshold)) {
2726                 struct rx_packet *tp;
2727                 
2728                 rxi_CallError(call, rx_BusyError);
2729                 tp = rxi_SendCallAbort(call, np, 1, 0);
2730                 MUTEX_EXIT(&call->lock);
2731                 MUTEX_ENTER(&conn->conn_data_lock);
2732                 conn->refCount--;
2733                 MUTEX_EXIT(&conn->conn_data_lock);
2734                 rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
2735                 return tp;
2736             }
2737             rxi_KeepAliveOn(call);
2738         } else if (np->header.callNumber != currentCallNumber) {
2739             /* Wait until the transmit queue is idle before deciding
2740              * whether to reset the current call. Chances are that the
2741              * call will be in ether DALLY or HOLD state once the TQ_BUSY
2742              * flag is cleared.
2743              */
2744 #ifdef AFS_GLOBAL_RXLOCK_KERNEL
2745             while ((call->state == RX_STATE_ACTIVE)
2746                    && (call->flags & RX_CALL_TQ_BUSY)) {
2747                 call->flags |= RX_CALL_TQ_WAIT;
2748                 call->tqWaiters++;
2749 #ifdef RX_ENABLE_LOCKS
2750                 osirx_AssertMine(&call->lock, "rxi_Start lock3");
2751                 CV_WAIT(&call->cv_tq, &call->lock);
2752 #else /* RX_ENABLE_LOCKS */
2753                 osi_rxSleep(&call->tq);
2754 #endif /* RX_ENABLE_LOCKS */
2755                 call->tqWaiters--;
2756                 if (call->tqWaiters == 0)
2757                     call->flags &= ~RX_CALL_TQ_WAIT;
2758             }
2759 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2760             /* If the new call cannot be taken right now send a busy and set
2761              * the error condition in this call, so that it terminates as
2762              * quickly as possible */
2763             if (call->state == RX_STATE_ACTIVE) {
2764                 struct rx_packet *tp;
2765
2766                 rxi_CallError(call, RX_CALL_DEAD);
2767                 tp = rxi_SendSpecial(call, conn, np, RX_PACKET_TYPE_BUSY,
2768                                      NULL, 0, 1);
2769                 MUTEX_EXIT(&call->lock);
2770                 MUTEX_ENTER(&conn->conn_data_lock);
2771                 conn->refCount--;
2772                 MUTEX_EXIT(&conn->conn_data_lock);
2773                 return tp;
2774             }
2775             rxi_ResetCall(call, 0);
2776             *call->callNumber = np->header.callNumber;
2777             if (np->header.callNumber == 0) 
2778                 dpf(("RecPacket call 0 %d %s: %x.%u.%u.%u.%u.%u.%u flags %d, packet %lx resend %d.%0.3d len %d", np->header.serial, rx_packetTypes[np->header.type - 1], ntohl(conn->peer->host), ntohs(conn->peer->port), np->header.serial, np->header.epoch, np->header.cid, np->header.callNumber, np->header.seq, np->header.flags, (unsigned long)np, np->retryTime.sec, np->retryTime.usec / 1000, np->length));
2779
2780             call->state = RX_STATE_PRECALL;
2781             clock_GetTime(&call->queueTime);
2782             hzero(call->bytesSent);
2783             hzero(call->bytesRcvd);
2784             /*
2785              * If the number of queued calls exceeds the overload
2786              * threshold then abort this call.
2787              */
2788             if ((rx_BusyThreshold > 0) && (rx_nWaiting > rx_BusyThreshold)) {
2789                 struct rx_packet *tp;
2790
2791                 rxi_CallError(call, rx_BusyError);
2792                 tp = rxi_SendCallAbort(call, np, 1, 0);
2793                 MUTEX_EXIT(&call->lock);
2794                 MUTEX_ENTER(&conn->conn_data_lock);
2795                 conn->refCount--;
2796                 MUTEX_EXIT(&conn->conn_data_lock);
2797                 rx_MutexIncrement(rx_stats.nBusies, rx_stats_mutex);
2798                 return tp;
2799             }
2800             rxi_KeepAliveOn(call);
2801         } else {
2802             /* Continuing call; do nothing here. */
2803         }
2804     } else {                    /* we're the client */
2805         /* Ignore all incoming acknowledgements for calls in DALLY state */
2806         if (call && (call->state == RX_STATE_DALLY)
2807             && (np->header.type == RX_PACKET_TYPE_ACK)) {
2808             rx_MutexIncrement(rx_stats.ignorePacketDally, rx_stats_mutex);
2809 #ifdef  RX_ENABLE_LOCKS
2810             if (call) {
2811                 MUTEX_EXIT(&call->lock);
2812             }
2813 #endif
2814             MUTEX_ENTER(&conn->conn_data_lock);
2815             conn->refCount--;
2816             MUTEX_EXIT(&conn->conn_data_lock);
2817             return np;
2818         }
2819
2820         /* Ignore anything that's not relevant to the current call.  If there
2821          * isn't a current call, then no packet is relevant. */
2822         if (!call || (np->header.callNumber != currentCallNumber)) {
2823             rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
2824 #ifdef  RX_ENABLE_LOCKS
2825             if (call) {
2826                 MUTEX_EXIT(&call->lock);
2827             }
2828 #endif
2829             MUTEX_ENTER(&conn->conn_data_lock);
2830             conn->refCount--;
2831             MUTEX_EXIT(&conn->conn_data_lock);
2832             return np;
2833         }
2834         /* If the service security object index stamped in the packet does not
2835          * match the connection's security index, ignore the packet */
2836         if (np->header.securityIndex != conn->securityIndex) {
2837 #ifdef  RX_ENABLE_LOCKS
2838             MUTEX_EXIT(&call->lock);
2839 #endif
2840             MUTEX_ENTER(&conn->conn_data_lock);
2841             conn->refCount--;
2842             MUTEX_EXIT(&conn->conn_data_lock);
2843             return np;
2844         }
2845
2846         /* If we're receiving the response, then all transmit packets are
2847          * implicitly acknowledged.  Get rid of them. */
2848         if (np->header.type == RX_PACKET_TYPE_DATA) {
2849 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
2850             /* XXX Hack. Because we must release the global rx lock when
2851              * sending packets (osi_NetSend) we drop all acks while we're
2852              * traversing the tq in rxi_Start sending packets out because
2853              * packets may move to the freePacketQueue as result of being here!
2854              * So we drop these packets until we're safely out of the
2855              * traversing. Really ugly! 
2856              * For fine grain RX locking, we set the acked field in the
2857              * packets and let rxi_Start remove them from the transmit queue.
2858              */
2859             if (call->flags & RX_CALL_TQ_BUSY) {
2860 #ifdef  RX_ENABLE_LOCKS
2861                 rxi_SetAcksInTransmitQueue(call);
2862 #else
2863                 conn->refCount--;
2864                 return np;      /* xmitting; drop packet */
2865 #endif
2866             } else {
2867                 rxi_ClearTransmitQueue(call, 0);
2868             }
2869 #else /* AFS_GLOBAL_RXLOCK_KERNEL */
2870             rxi_ClearTransmitQueue(call, 0);
2871 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2872         } else {
2873             if (np->header.type == RX_PACKET_TYPE_ACK) {
2874                 /* now check to see if this is an ack packet acknowledging that the
2875                  * server actually *lost* some hard-acked data.  If this happens we
2876                  * ignore this packet, as it may indicate that the server restarted in
2877                  * the middle of a call.  It is also possible that this is an old ack
2878                  * packet.  We don't abort the connection in this case, because this
2879                  * *might* just be an old ack packet.  The right way to detect a server
2880                  * restart in the midst of a call is to notice that the server epoch
2881                  * changed, btw.  */
2882                 /* XXX I'm not sure this is exactly right, since tfirst **IS**
2883                  * XXX unacknowledged.  I think that this is off-by-one, but
2884                  * XXX I don't dare change it just yet, since it will
2885                  * XXX interact badly with the server-restart detection 
2886                  * XXX code in receiveackpacket.  */
2887                 if (ntohl(rx_GetInt32(np, FIRSTACKOFFSET)) < call->tfirst) {
2888                     rx_MutexIncrement(rx_stats.spuriousPacketsRead, rx_stats_mutex);
2889                     MUTEX_EXIT(&call->lock);
2890                     MUTEX_ENTER(&conn->conn_data_lock);
2891                     conn->refCount--;
2892                     MUTEX_EXIT(&conn->conn_data_lock);
2893                     return np;
2894                 }
2895             }
2896         }                       /* else not a data packet */
2897     }
2898
2899     osirx_AssertMine(&call->lock, "rxi_ReceivePacket middle");
2900     /* Set remote user defined status from packet */
2901     call->remoteStatus = np->header.userStatus;
2902
2903     /* Note the gap between the expected next packet and the actual
2904      * packet that arrived, when the new packet has a smaller serial number
2905      * than expected.  Rioses frequently reorder packets all by themselves,
2906      * so this will be quite important with very large window sizes.
2907      * Skew is checked against 0 here to avoid any dependence on the type of
2908      * inPacketSkew (which may be unsigned).  In C, -1 > (unsigned) 0 is always
2909      * true! 
2910      * The inPacketSkew should be a smoothed running value, not just a maximum.  MTUXXX
2911      * see CalculateRoundTripTime for an example of how to keep smoothed values.
2912      * I think using a beta of 1/8 is probably appropriate.  93.04.21
2913      */
2914     MUTEX_ENTER(&conn->conn_data_lock);
2915     skew = conn->lastSerial - np->header.serial;
2916     conn->lastSerial = np->header.serial;
2917     MUTEX_EXIT(&conn->conn_data_lock);
2918     if (skew > 0) {
2919         register struct rx_peer *peer;
2920         peer = conn->peer;
2921         if (skew > peer->inPacketSkew) {
2922             dpf(("*** In skew changed from %d to %d\n", peer->inPacketSkew,
2923                  skew));
2924             peer->inPacketSkew = skew;
2925         }
2926     }
2927
2928     /* Now do packet type-specific processing */
2929     switch (np->header.type) {
2930     case RX_PACKET_TYPE_DATA:
2931         np = rxi_ReceiveDataPacket(call, np, 1, socket, host, port, tnop,
2932                                    newcallp);
2933         break;
2934     case RX_PACKET_TYPE_ACK:
2935         /* Respond immediately to ack packets requesting acknowledgement
2936          * (ping packets) */
2937         if (np->header.flags & RX_REQUEST_ACK) {
2938             if (call->error)
2939                 (void)rxi_SendCallAbort(call, 0, 1, 0);
2940             else
2941                 (void)rxi_SendAck(call, 0, np->header.serial,
2942                                   RX_ACK_PING_RESPONSE, 1);
2943         }
2944         np = rxi_ReceiveAckPacket(call, np, 1);
2945         break;
2946     case RX_PACKET_TYPE_ABORT: {
2947         /* An abort packet: reset the call, passing the error up to the user. */
2948         /* What if error is zero? */
2949         /* What if the error is -1? the application will treat it as a timeout. */
2950         afs_int32 errdata = ntohl(*(afs_int32 *) rx_DataOf(np));
2951         dpf(("rxi_ReceivePacket ABORT rx_DataOf = %d", errdata));
2952         rxi_CallError(call, errdata);
2953         MUTEX_EXIT(&call->lock);
2954         MUTEX_ENTER(&conn->conn_data_lock);
2955         conn->refCount--;
2956         MUTEX_EXIT(&conn->conn_data_lock);
2957         return np;              /* xmitting; drop packet */
2958     }
2959     case RX_PACKET_TYPE_BUSY:
2960         /* XXXX */
2961         break;
2962     case RX_PACKET_TYPE_ACKALL:
2963         /* All packets acknowledged, so we can drop all packets previously
2964          * readied for sending */
2965 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
2966         /* XXX Hack. We because we can't release the global rx lock when
2967          * sending packets (osi_NetSend) we drop all ack pkts while we're
2968          * traversing the tq in rxi_Start sending packets out because
2969          * packets may move to the freePacketQueue as result of being
2970          * here! So we drop these packets until we're safely out of the
2971          * traversing. Really ugly! 
2972          * For fine grain RX locking, we set the acked field in the packets
2973          * and let rxi_Start remove the packets from the transmit queue.
2974          */
2975         if (call->flags & RX_CALL_TQ_BUSY) {
2976 #ifdef  RX_ENABLE_LOCKS
2977             rxi_SetAcksInTransmitQueue(call);
2978             break;
2979 #else /* RX_ENABLE_LOCKS */
2980             MUTEX_EXIT(&call->lock);
2981             MUTEX_ENTER(&conn->conn_data_lock);
2982             conn->refCount--;
2983             MUTEX_EXIT(&conn->conn_data_lock);
2984             return np;          /* xmitting; drop packet */
2985 #endif /* RX_ENABLE_LOCKS */
2986         }
2987 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
2988         rxi_ClearTransmitQueue(call, 0);
2989         rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
2990         break;
2991     default:
2992         /* Should not reach here, unless the peer is broken: send an abort
2993          * packet */
2994         rxi_CallError(call, RX_PROTOCOL_ERROR);
2995         np = rxi_SendCallAbort(call, np, 1, 0);
2996         break;
2997     };
2998     /* Note when this last legitimate packet was received, for keep-alive
2999      * processing.  Note, we delay getting the time until now in the hope that
3000      * the packet will be delivered to the user before any get time is required
3001      * (if not, then the time won't actually be re-evaluated here). */
3002     call->lastReceiveTime = clock_Sec();
3003     MUTEX_EXIT(&call->lock);
3004     MUTEX_ENTER(&conn->conn_data_lock);
3005     conn->refCount--;
3006     MUTEX_EXIT(&conn->conn_data_lock);
3007     return np;
3008 }
3009
3010 /* return true if this is an "interesting" connection from the point of view
3011     of someone trying to debug the system */
3012 int
3013 rxi_IsConnInteresting(struct rx_connection *aconn)
3014 {
3015     register int i;
3016     register struct rx_call *tcall;
3017
3018     if (aconn->flags & (RX_CONN_MAKECALL_WAITING | RX_CONN_DESTROY_ME))
3019         return 1;
3020     for (i = 0; i < RX_MAXCALLS; i++) {
3021         tcall = aconn->call[i];
3022         if (tcall) {
3023             if ((tcall->state == RX_STATE_PRECALL)
3024                 || (tcall->state == RX_STATE_ACTIVE))
3025                 return 1;
3026             if ((tcall->mode == RX_MODE_SENDING)
3027                 || (tcall->mode == RX_MODE_RECEIVING))
3028                 return 1;
3029         }
3030     }
3031     return 0;
3032 }
3033
3034 #ifdef KERNEL
3035 /* if this is one of the last few packets AND it wouldn't be used by the
3036    receiving call to immediately satisfy a read request, then drop it on
3037    the floor, since accepting it might prevent a lock-holding thread from
3038    making progress in its reading. If a call has been cleared while in
3039    the precall state then ignore all subsequent packets until the call
3040    is assigned to a thread. */
3041
3042 static int
3043 TooLow(struct rx_packet *ap, struct rx_call *acall)
3044 {
3045     int rc = 0;
3046     MUTEX_ENTER(&rx_stats_mutex);
3047     if (((ap->header.seq != 1) && (acall->flags & RX_CALL_CLEARED)
3048          && (acall->state == RX_STATE_PRECALL))
3049         || ((rx_nFreePackets < rxi_dataQuota + 2)
3050             && !((ap->header.seq < acall->rnext + rx_initSendWindow)
3051                  && (acall->flags & RX_CALL_READER_WAIT)))) {
3052         rc = 1;
3053     }
3054     MUTEX_EXIT(&rx_stats_mutex);
3055     return rc;
3056 }
3057 #endif /* KERNEL */
3058
3059 static void
3060 rxi_CheckReachEvent(struct rxevent *event, void *arg1, void *arg2)
3061 {
3062     struct rx_connection *conn = arg1;
3063     struct rx_call *acall = arg2;
3064     struct rx_call *call = acall;
3065     struct clock when, now;
3066     int i, waiting;
3067
3068     MUTEX_ENTER(&conn->conn_data_lock);
3069     conn->checkReachEvent = NULL;
3070     waiting = conn->flags & RX_CONN_ATTACHWAIT;
3071     if (event)
3072         conn->refCount--;
3073     MUTEX_EXIT(&conn->conn_data_lock);
3074
3075     if (waiting) {
3076         if (!call) {
3077             MUTEX_ENTER(&conn->conn_call_lock);
3078             MUTEX_ENTER(&conn->conn_data_lock);
3079             for (i = 0; i < RX_MAXCALLS; i++) {
3080                 struct rx_call *tc = conn->call[i];
3081                 if (tc && tc->state == RX_STATE_PRECALL) {
3082                     call = tc;
3083                     break;
3084                 }
3085             }
3086             if (!call)
3087                 /* Indicate that rxi_CheckReachEvent is no longer running by
3088                  * clearing the flag.  Must be atomic under conn_data_lock to
3089                  * avoid a new call slipping by: rxi_CheckConnReach holds
3090                  * conn_data_lock while checking RX_CONN_ATTACHWAIT.
3091                  */
3092                 conn->flags &= ~RX_CONN_ATTACHWAIT;
3093             MUTEX_EXIT(&conn->conn_data_lock);
3094             MUTEX_EXIT(&conn->conn_call_lock);
3095         }
3096
3097         if (call) {
3098             if (call != acall)
3099                 MUTEX_ENTER(&call->lock);
3100             rxi_SendAck(call, NULL, 0, RX_ACK_PING, 0);
3101             if (call != acall)
3102                 MUTEX_EXIT(&call->lock);
3103
3104             clock_GetTime(&now);
3105             when = now;
3106             when.sec += RX_CHECKREACH_TIMEOUT;
3107             MUTEX_ENTER(&conn->conn_data_lock);
3108             if (!conn->checkReachEvent) {
3109                 conn->refCount++;
3110                 conn->checkReachEvent =
3111                     rxevent_PostNow(&when, &now, rxi_CheckReachEvent, conn, 
3112                                     NULL);
3113             }
3114             MUTEX_EXIT(&conn->conn_data_lock);
3115         }
3116     }
3117 }
3118
3119 static int
3120 rxi_CheckConnReach(struct rx_connection *conn, struct rx_call *call)
3121 {
3122     struct rx_service *service = conn->service;
3123     struct rx_peer *peer = conn->peer;
3124     afs_uint32 now, lastReach;
3125
3126     if (service->checkReach == 0)
3127         return 0;
3128
3129     now = clock_Sec();
3130     MUTEX_ENTER(&peer->peer_lock);
3131     lastReach = peer->lastReachTime;
3132     MUTEX_EXIT(&peer->peer_lock);
3133     if (now - lastReach < RX_CHECKREACH_TTL)
3134         return 0;
3135
3136     MUTEX_ENTER(&conn->conn_data_lock);
3137     if (conn->flags & RX_CONN_ATTACHWAIT) {
3138         MUTEX_EXIT(&conn->conn_data_lock);
3139         return 1;
3140     }
3141     conn->flags |= RX_CONN_ATTACHWAIT;
3142     MUTEX_EXIT(&conn->conn_data_lock);
3143     if (!conn->checkReachEvent)
3144         rxi_CheckReachEvent(NULL, conn, call);
3145
3146     return 1;
3147 }
3148
3149 /* try to attach call, if authentication is complete */
3150 static void
3151 TryAttach(register struct rx_call *acall, register osi_socket socket,
3152           register int *tnop, register struct rx_call **newcallp,
3153           int reachOverride)
3154 {
3155     struct rx_connection *conn = acall->conn;
3156
3157     if (conn->type == RX_SERVER_CONNECTION
3158         && acall->state == RX_STATE_PRECALL) {
3159         /* Don't attach until we have any req'd. authentication. */
3160         if (RXS_CheckAuthentication(conn->securityObject, conn) == 0) {
3161             if (reachOverride || rxi_CheckConnReach(conn, acall) == 0)
3162                 rxi_AttachServerProc(acall, socket, tnop, newcallp);
3163             /* Note:  this does not necessarily succeed; there
3164              * may not any proc available
3165              */
3166         } else {
3167             rxi_ChallengeOn(acall->conn);
3168         }
3169     }
3170 }
3171
3172 /* A data packet has been received off the interface.  This packet is
3173  * appropriate to the call (the call is in the right state, etc.).  This
3174  * routine can return a packet to the caller, for re-use */
3175
3176 struct rx_packet *
3177 rxi_ReceiveDataPacket(register struct rx_call *call,
3178                       register struct rx_packet *np, int istack,
3179                       osi_socket socket, afs_uint32 host, u_short port,
3180                       int *tnop, struct rx_call **newcallp)
3181 {
3182     int ackNeeded = 0;          /* 0 means no, otherwise ack_reason */
3183     int newPackets = 0;
3184     int didHardAck = 0;
3185     int haveLast = 0;
3186     afs_uint32 seq, serial, flags;
3187     int isFirst;
3188     struct rx_packet *tnp;
3189     struct clock when, now;
3190     rx_MutexIncrement(rx_stats.dataPacketsRead, rx_stats_mutex);
3191
3192 #ifdef KERNEL
3193     /* If there are no packet buffers, drop this new packet, unless we can find
3194      * packet buffers from inactive calls */
3195     if (!call->error
3196         && (rxi_OverQuota(RX_PACKET_CLASS_RECEIVE) || TooLow(np, call))) {
3197         MUTEX_ENTER(&rx_freePktQ_lock);
3198         rxi_NeedMorePackets = TRUE;
3199         MUTEX_EXIT(&rx_freePktQ_lock);
3200         rx_MutexIncrement(rx_stats.noPacketBuffersOnRead, rx_stats_mutex);
3201         call->rprev = np->header.serial;
3202         rxi_calltrace(RX_TRACE_DROP, call);
3203         dpf(("packet %x dropped on receipt - quota problems", np));
3204         if (rxi_doreclaim)
3205             rxi_ClearReceiveQueue(call);
3206         clock_GetTime(&now);
3207         when = now;
3208         clock_Add(&when, &rx_softAckDelay);
3209         if (!call->delayedAckEvent
3210             || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
3211             rxevent_Cancel(call->delayedAckEvent, call,
3212                            RX_CALL_REFCOUNT_DELAY);
3213             CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
3214             call->delayedAckEvent =
3215                 rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
3216         }
3217         /* we've damaged this call already, might as well do it in. */
3218         return np;
3219     }
3220 #endif /* KERNEL */
3221
3222     /*
3223      * New in AFS 3.5, if the RX_JUMBO_PACKET flag is set then this
3224      * packet is one of several packets transmitted as a single
3225      * datagram. Do not send any soft or hard acks until all packets
3226      * in a jumbogram have been processed. Send negative acks right away.
3227      */
3228     for (isFirst = 1, tnp = NULL; isFirst || tnp; isFirst = 0) {
3229         /* tnp is non-null when there are more packets in the
3230          * current jumbo gram */
3231         if (tnp) {
3232             if (np)
3233                 rxi_FreePacket(np);
3234             np = tnp;
3235         }
3236
3237         seq = np->header.seq;
3238         serial = np->header.serial;
3239         flags = np->header.flags;
3240
3241         /* If the call is in an error state, send an abort message */
3242         if (call->error)
3243             return rxi_SendCallAbort(call, np, istack, 0);
3244
3245         /* The RX_JUMBO_PACKET is set in all but the last packet in each
3246          * AFS 3.5 jumbogram. */
3247         if (flags & RX_JUMBO_PACKET) {
3248             tnp = rxi_SplitJumboPacket(np, host, port, isFirst);
3249         } else {
3250             tnp = NULL;
3251         }
3252
3253         if (np->header.spare != 0) {
3254             MUTEX_ENTER(&call->conn->conn_data_lock);
3255             call->conn->flags |= RX_CONN_USING_PACKET_CKSUM;
3256             MUTEX_EXIT(&call->conn->conn_data_lock);
3257         }
3258
3259         /* The usual case is that this is the expected next packet */
3260         if (seq == call->rnext) {
3261
3262             /* Check to make sure it is not a duplicate of one already queued */
3263             if (queue_IsNotEmpty(&call->rq)
3264                 && queue_First(&call->rq, rx_packet)->header.seq == seq) {
3265                 rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
3266                 dpf(("packet %x dropped on receipt - duplicate", np));
3267                 rxevent_Cancel(call->delayedAckEvent, call,
3268                                RX_CALL_REFCOUNT_DELAY);
3269                 np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE, istack);
3270                 ackNeeded = 0;
3271                 call->rprev = seq;
3272                 continue;
3273             }
3274
3275             /* It's the next packet. Stick it on the receive queue
3276              * for this call. Set newPackets to make sure we wake
3277              * the reader once all packets have been processed */
3278             queue_Prepend(&call->rq, np);
3279             call->nSoftAcks++;
3280             np = NULL;          /* We can't use this anymore */
3281             newPackets = 1;
3282
3283             /* If an ack is requested then set a flag to make sure we
3284              * send an acknowledgement for this packet */
3285             if (flags & RX_REQUEST_ACK) {
3286                 ackNeeded = RX_ACK_REQUESTED;
3287             }
3288
3289             /* Keep track of whether we have received the last packet */
3290             if (flags & RX_LAST_PACKET) {
3291                 call->flags |= RX_CALL_HAVE_LAST;
3292                 haveLast = 1;
3293             }
3294
3295             /* Check whether we have all of the packets for this call */
3296             if (call->flags & RX_CALL_HAVE_LAST) {
3297                 afs_uint32 tseq;        /* temporary sequence number */
3298                 struct rx_packet *tp;   /* Temporary packet pointer */
3299                 struct rx_packet *nxp;  /* Next pointer, for queue_Scan */
3300
3301                 for (tseq = seq, queue_Scan(&call->rq, tp, nxp, rx_packet)) {
3302                     if (tseq != tp->header.seq)
3303                         break;
3304                     if (tp->header.flags & RX_LAST_PACKET) {
3305                         call->flags |= RX_CALL_RECEIVE_DONE;
3306                         break;
3307                     }
3308                     tseq++;
3309                 }
3310             }
3311
3312             /* Provide asynchronous notification for those who want it
3313              * (e.g. multi rx) */
3314             if (call->arrivalProc) {
3315                 (*call->arrivalProc) (call, call->arrivalProcHandle,
3316                                       call->arrivalProcArg);
3317                 call->arrivalProc = (void (*)())0;
3318             }
3319
3320             /* Update last packet received */
3321             call->rprev = seq;
3322
3323             /* If there is no server process serving this call, grab
3324              * one, if available. We only need to do this once. If a
3325              * server thread is available, this thread becomes a server
3326              * thread and the server thread becomes a listener thread. */
3327             if (isFirst) {
3328                 TryAttach(call, socket, tnop, newcallp, 0);
3329             }
3330         }
3331         /* This is not the expected next packet. */
3332         else {
3333             /* Determine whether this is a new or old packet, and if it's
3334              * a new one, whether it fits into the current receive window.
3335              * Also figure out whether the packet was delivered in sequence.
3336              * We use the prev variable to determine whether the new packet
3337              * is the successor of its immediate predecessor in the
3338              * receive queue, and the missing flag to determine whether
3339              * any of this packets predecessors are missing.  */
3340
3341             afs_uint32 prev;    /* "Previous packet" sequence number */
3342             struct rx_packet *tp;       /* Temporary packet pointer */
3343             struct rx_packet *nxp;      /* Next pointer, for queue_Scan */
3344             int missing;        /* Are any predecessors missing? */
3345
3346             /* If the new packet's sequence number has been sent to the
3347              * application already, then this is a duplicate */
3348             if (seq < call->rnext) {
3349                 rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
3350                 rxevent_Cancel(call->delayedAckEvent, call,
3351                                RX_CALL_REFCOUNT_DELAY);
3352                 np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE, istack);
3353                 ackNeeded = 0;
3354                 call->rprev = seq;
3355                 continue;
3356             }
3357
3358             /* If the sequence number is greater than what can be
3359              * accomodated by the current window, then send a negative
3360              * acknowledge and drop the packet */
3361             if ((call->rnext + call->rwind) <= seq) {
3362                 rxevent_Cancel(call->delayedAckEvent, call,
3363                                RX_CALL_REFCOUNT_DELAY);
3364                 np = rxi_SendAck(call, np, serial, RX_ACK_EXCEEDS_WINDOW,
3365                                  istack);
3366                 ackNeeded = 0;
3367                 call->rprev = seq;
3368                 continue;
3369             }
3370
3371             /* Look for the packet in the queue of old received packets */
3372             for (prev = call->rnext - 1, missing =
3373                  0, queue_Scan(&call->rq, tp, nxp, rx_packet)) {
3374                 /*Check for duplicate packet */
3375                 if (seq == tp->header.seq) {
3376                     rx_MutexIncrement(rx_stats.dupPacketsRead, rx_stats_mutex);
3377                     rxevent_Cancel(call->delayedAckEvent, call,
3378                                    RX_CALL_REFCOUNT_DELAY);
3379                     np = rxi_SendAck(call, np, serial, RX_ACK_DUPLICATE,
3380                                      istack);
3381                     ackNeeded = 0;
3382                     call->rprev = seq;
3383                     goto nextloop;
3384                 }
3385                 /* If we find a higher sequence packet, break out and
3386                  * insert the new packet here. */
3387                 if (seq < tp->header.seq)
3388                     break;
3389                 /* Check for missing packet */
3390                 if (tp->header.seq != prev + 1) {
3391                     missing = 1;
3392                 }
3393
3394                 prev = tp->header.seq;
3395             }
3396
3397             /* Keep track of whether we have received the last packet. */
3398             if (flags & RX_LAST_PACKET) {
3399                 call->flags |= RX_CALL_HAVE_LAST;
3400             }
3401
3402             /* It's within the window: add it to the the receive queue.
3403              * tp is left by the previous loop either pointing at the
3404              * packet before which to insert the new packet, or at the
3405              * queue head if the queue is empty or the packet should be
3406              * appended. */
3407             queue_InsertBefore(tp, np);
3408             call->nSoftAcks++;
3409             np = NULL;
3410
3411             /* Check whether we have all of the packets for this call */
3412             if ((call->flags & RX_CALL_HAVE_LAST)
3413                 && !(call->flags & RX_CALL_RECEIVE_DONE)) {
3414                 afs_uint32 tseq;        /* temporary sequence number */
3415
3416                 for (tseq =
3417                      call->rnext, queue_Scan(&call->rq, tp, nxp, rx_packet)) {
3418                     if (tseq != tp->header.seq)
3419                         break;
3420                     if (tp->header.flags & RX_LAST_PACKET) {
3421                         call->flags |= RX_CALL_RECEIVE_DONE;
3422                         break;
3423                     }
3424                     tseq++;
3425                 }
3426             }
3427
3428             /* We need to send an ack of the packet is out of sequence, 
3429              * or if an ack was requested by the peer. */
3430             if (seq != prev + 1 || missing) {
3431                 ackNeeded = RX_ACK_OUT_OF_SEQUENCE;
3432             } else if (flags & RX_REQUEST_ACK) {
3433                 ackNeeded = RX_ACK_REQUESTED;
3434             }
3435
3436             /* Acknowledge the last packet for each call */
3437             if (flags & RX_LAST_PACKET) {
3438                 haveLast = 1;
3439             }
3440
3441             call->rprev = seq;
3442         }
3443       nextloop:;
3444     }
3445
3446     if (newPackets) {
3447         /*
3448          * If the receiver is waiting for an iovec, fill the iovec
3449          * using the data from the receive queue */
3450         if (call->flags & RX_CALL_IOVEC_WAIT) {
3451             didHardAck = rxi_FillReadVec(call, serial);
3452             /* the call may have been aborted */
3453             if (call->error) {
3454                 return NULL;
3455             }
3456             if (didHardAck) {
3457                 ackNeeded = 0;
3458             }
3459         }
3460
3461         /* Wakeup the reader if any */
3462         if ((call->flags & RX_CALL_READER_WAIT)
3463             && (!(call->flags & RX_CALL_IOVEC_WAIT) || !(call->iovNBytes)
3464                 || (call->iovNext >= call->iovMax)
3465                 || (call->flags & RX_CALL_RECEIVE_DONE))) {
3466             call->flags &= ~RX_CALL_READER_WAIT;
3467 #ifdef  RX_ENABLE_LOCKS
3468             CV_BROADCAST(&call->cv_rq);
3469 #else
3470             osi_rxWakeup(&call->rq);
3471 #endif
3472         }
3473     }
3474
3475     /*
3476      * Send an ack when requested by the peer, or once every
3477      * rxi_SoftAckRate packets until the last packet has been
3478      * received. Always send a soft ack for the last packet in
3479      * the server's reply. */
3480     if (ackNeeded) {
3481         rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
3482         np = rxi_SendAck(call, np, serial, ackNeeded, istack);
3483     } else if (call->nSoftAcks > (u_short) rxi_SoftAckRate) {
3484         rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
3485         np = rxi_SendAck(call, np, serial, RX_ACK_IDLE, istack);
3486     } else if (call->nSoftAcks) {
3487         clock_GetTime(&now);
3488         when = now;
3489         if (haveLast && !(flags & RX_CLIENT_INITIATED)) {
3490             clock_Add(&when, &rx_lastAckDelay);
3491         } else {
3492             clock_Add(&when, &rx_softAckDelay);
3493         }
3494         if (!call->delayedAckEvent
3495             || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
3496             rxevent_Cancel(call->delayedAckEvent, call,
3497                            RX_CALL_REFCOUNT_DELAY);
3498             CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
3499             call->delayedAckEvent =
3500                 rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
3501         }
3502     } else if (call->flags & RX_CALL_RECEIVE_DONE) {
3503         rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
3504     }
3505
3506     return np;
3507 }
3508
3509 #ifdef  ADAPT_WINDOW
3510 static void rxi_ComputeRate();
3511 #endif
3512
3513 static void
3514 rxi_UpdatePeerReach(struct rx_connection *conn, struct rx_call *acall)
3515 {
3516     struct rx_peer *peer = conn->peer;
3517
3518     MUTEX_ENTER(&peer->peer_lock);
3519     peer->lastReachTime = clock_Sec();
3520     MUTEX_EXIT(&peer->peer_lock);
3521
3522     MUTEX_ENTER(&conn->conn_data_lock);
3523     if (conn->flags & RX_CONN_ATTACHWAIT) {
3524         int i;
3525
3526         conn->flags &= ~RX_CONN_ATTACHWAIT;
3527         MUTEX_EXIT(&conn->conn_data_lock);
3528
3529         for (i = 0; i < RX_MAXCALLS; i++) {
3530             struct rx_call *call = conn->call[i];
3531             if (call) {
3532                 if (call != acall)
3533                     MUTEX_ENTER(&call->lock);
3534                 /* tnop can be null if newcallp is null */
3535                 TryAttach(call, (osi_socket) - 1, NULL, NULL, 1);
3536                 if (call != acall)
3537                     MUTEX_EXIT(&call->lock);
3538             }
3539         }
3540     } else
3541         MUTEX_EXIT(&conn->conn_data_lock);
3542 }
3543
3544 static const char *
3545 rx_ack_reason(int reason)
3546 {
3547     switch (reason) {
3548     case RX_ACK_REQUESTED:
3549         return "requested";
3550     case RX_ACK_DUPLICATE:
3551         return "duplicate";
3552     case RX_ACK_OUT_OF_SEQUENCE:
3553         return "sequence";
3554     case RX_ACK_EXCEEDS_WINDOW:
3555         return "window";
3556     case RX_ACK_NOSPACE:
3557         return "nospace";
3558     case RX_ACK_PING:
3559         return "ping";
3560     case RX_ACK_PING_RESPONSE:
3561         return "response";
3562     case RX_ACK_DELAY:
3563         return "delay";
3564     case RX_ACK_IDLE:
3565         return "idle";
3566     default:
3567         return "unknown!!";
3568     }
3569 }
3570
3571
3572 /* rxi_ComputePeerNetStats
3573  *
3574  * Called exclusively by rxi_ReceiveAckPacket to compute network link
3575  * estimates (like RTT and throughput) based on ack packets.  Caller
3576  * must ensure that the packet in question is the right one (i.e.
3577  * serial number matches).
3578  */
3579 static void
3580 rxi_ComputePeerNetStats(struct rx_call *call, struct rx_packet *p,
3581                         struct rx_ackPacket *ap, struct rx_packet *np)
3582 {
3583     struct rx_peer *peer = call->conn->peer;
3584
3585     /* Use RTT if not delayed by client. */
3586     if (ap->reason != RX_ACK_DELAY)
3587         rxi_ComputeRoundTripTime(p, &p->timeSent, peer);
3588 #ifdef ADAPT_WINDOW
3589     rxi_ComputeRate(peer, call, p, np, ap->reason);
3590 #endif
3591 }
3592
3593 /* The real smarts of the whole thing.  */
3594 struct rx_packet *
3595 rxi_ReceiveAckPacket(register struct rx_call *call, struct rx_packet *np,
3596                      int istack)
3597 {
3598     struct rx_ackPacket *ap;
3599     int nAcks;
3600     register struct rx_packet *tp;
3601     register struct rx_packet *nxp;     /* Next packet pointer for queue_Scan */
3602     register struct rx_connection *conn = call->conn;
3603     struct rx_peer *peer = conn->peer;
3604     afs_uint32 first;
3605     afs_uint32 serial;
3606     /* because there are CM's that are bogus, sending weird values for this. */
3607     afs_uint32 skew = 0;
3608     int nbytes;
3609     int missing;
3610     int acked;
3611     int nNacked = 0;
3612     int newAckCount = 0;
3613     u_short maxMTU = 0;         /* Set if peer supports AFS 3.4a jumbo datagrams */
3614     int maxDgramPackets = 0;    /* Set if peer supports AFS 3.5 jumbo datagrams */
3615
3616     rx_MutexIncrement(rx_stats.ackPacketsRead, rx_stats_mutex);
3617     ap = (struct rx_ackPacket *)rx_DataOf(np);
3618     nbytes = rx_Contiguous(np) - (int)((ap->acks) - (u_char *) ap);
3619     if (nbytes < 0)
3620         return np;              /* truncated ack packet */
3621
3622     /* depends on ack packet struct */
3623     nAcks = MIN((unsigned)nbytes, (unsigned)ap->nAcks);
3624     first = ntohl(ap->firstPacket);
3625     serial = ntohl(ap->serial);
3626     /* temporarily disabled -- needs to degrade over time 
3627      * skew = ntohs(ap->maxSkew); */
3628
3629     /* Ignore ack packets received out of order */
3630     if (first < call->tfirst) {
3631         return np;
3632     }
3633
3634     if (np->header.flags & RX_SLOW_START_OK) {
3635         call->flags |= RX_CALL_SLOW_START_OK;
3636     }
3637
3638     if (ap->reason == RX_ACK_PING_RESPONSE)
3639         rxi_UpdatePeerReach(conn, call);
3640
3641 #ifdef RXDEBUG
3642 #ifdef AFS_NT40_ENV
3643     if (rxdebug_active) {
3644         char msg[512];
3645         size_t len;
3646
3647         len = _snprintf(msg, sizeof(msg),
3648                         "tid[%d] RACK: reason %s serial %u previous %u seq %u skew %d first %u acks %u space %u ",
3649                          GetCurrentThreadId(), rx_ack_reason(ap->reason), 
3650                          ntohl(ap->serial), ntohl(ap->previousPacket),
3651                          (unsigned int)np->header.seq, (unsigned int)skew, 
3652                          ntohl(ap->firstPacket), ap->nAcks, ntohs(ap->bufferSpace) );
3653         if (nAcks) {
3654             int offset;
3655
3656             for (offset = 0; offset < nAcks && len < sizeof(msg); offset++) 
3657                 msg[len++] = (ap->acks[offset] == RX_ACK_TYPE_NACK ? '-' : '*');
3658         }
3659         msg[len++]='\n';
3660         msg[len] = '\0';
3661         OutputDebugString(msg);
3662     }
3663 #else /* AFS_NT40_ENV */
3664     if (rx_Log) {
3665         fprintf(rx_Log,
3666                 "RACK: reason %x previous %u seq %u serial %u skew %d first %u",
3667                 ap->reason, ntohl(ap->previousPacket),
3668                 (unsigned int)np->header.seq, (unsigned int)serial,
3669                 (unsigned int)skew, ntohl(ap->firstPacket));
3670         if (nAcks) {
3671             int offset;
3672             for (offset = 0; offset < nAcks; offset++)
3673                 putc(ap->acks[offset] == RX_ACK_TYPE_NACK ? '-' : '*',
3674                      rx_Log);
3675         }
3676         putc('\n', rx_Log);
3677     }
3678 #endif /* AFS_NT40_ENV */
3679 #endif
3680
3681     /* Update the outgoing packet skew value to the latest value of
3682      * the peer's incoming packet skew value.  The ack packet, of
3683      * course, could arrive out of order, but that won't affect things
3684      * much */
3685     MUTEX_ENTER(&peer->peer_lock);
3686     peer->outPacketSkew = skew;
3687
3688     /* Check for packets that no longer need to be transmitted, and
3689      * discard them.  This only applies to packets positively
3690      * acknowledged as having been sent to the peer's upper level.
3691      * All other packets must be retained.  So only packets with
3692      * sequence numbers < ap->firstPacket are candidates. */
3693     for (queue_Scan(&call->tq, tp, nxp, rx_packet)) {
3694         if (tp->header.seq >= first)
3695             break;
3696         call->tfirst = tp->header.seq + 1;
3697         if (serial
3698             && (tp->header.serial == serial || tp->firstSerial == serial))
3699             rxi_ComputePeerNetStats(call, tp, ap, np);
3700         if (!(tp->flags & RX_PKTFLAG_ACKED)) {
3701             newAckCount++;
3702         }
3703 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
3704         /* XXX Hack. Because we have to release the global rx lock when sending
3705          * packets (osi_NetSend) we drop all acks while we're traversing the tq
3706          * in rxi_Start sending packets out because packets may move to the
3707          * freePacketQueue as result of being here! So we drop these packets until
3708          * we're safely out of the traversing. Really ugly! 
3709          * To make it even uglier, if we're using fine grain locking, we can
3710          * set the ack bits in the packets and have rxi_Start remove the packets
3711          * when it's done transmitting.
3712          */
3713         if (call->flags & RX_CALL_TQ_BUSY) {
3714 #ifdef RX_ENABLE_LOCKS
3715             tp->flags |= RX_PKTFLAG_ACKED;
3716             call->flags |= RX_CALL_TQ_SOME_ACKED;
3717 #else /* RX_ENABLE_LOCKS */
3718             break;
3719 #endif /* RX_ENABLE_LOCKS */
3720         } else
3721 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
3722         {
3723             queue_Remove(tp);
3724             rxi_FreePacket(tp); /* rxi_FreePacket mustn't wake up anyone, preemptively. */
3725         }
3726     }
3727
3728 #ifdef ADAPT_WINDOW
3729     /* Give rate detector a chance to respond to ping requests */
3730     if (ap->reason == RX_ACK_PING_RESPONSE) {
3731         rxi_ComputeRate(peer, call, 0, np, ap->reason);
3732     }
3733 #endif
3734
3735     /* N.B. we don't turn off any timers here.  They'll go away by themselves, anyway */
3736
3737     /* Now go through explicit acks/nacks and record the results in
3738      * the waiting packets.  These are packets that can't be released
3739      * yet, even with a positive acknowledge.  This positive
3740      * acknowledge only means the packet has been received by the
3741      * peer, not that it will be retained long enough to be sent to
3742      * the peer's upper level.  In addition, reset the transmit timers
3743      * of any missing packets (those packets that must be missing
3744      * because this packet was out of sequence) */
3745
3746     call->nSoftAcked = 0;
3747     for (missing = 0, queue_Scan(&call->tq, tp, nxp, rx_packet)) {
3748         /* Update round trip time if the ack was stimulated on receipt
3749          * of this packet */
3750 #ifdef AFS_GLOBAL_RXLOCK_KERNEL
3751 #ifdef RX_ENABLE_LOCKS
3752         if (tp->header.seq >= first)
3753 #endif /* RX_ENABLE_LOCKS */
3754 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
3755             if (serial
3756                 && (tp->header.serial == serial || tp->firstSerial == serial))
3757                 rxi_ComputePeerNetStats(call, tp, ap, np);
3758
3759         /* Set the acknowledge flag per packet based on the
3760          * information in the ack packet. An acknowlegded packet can
3761          * be downgraded when the server has discarded a packet it
3762          * soacked previously, or when an ack packet is received
3763          * out of sequence. */
3764         if (tp->header.seq < first) {
3765             /* Implicit ack information */
3766             if (!(tp->flags & RX_PKTFLAG_ACKED)) {
3767                 newAckCount++;
3768             }
3769             tp->flags |= RX_PKTFLAG_ACKED;
3770         } else if (tp->header.seq < first + nAcks) {
3771             /* Explicit ack information:  set it in the packet appropriately */
3772             if (ap->acks[tp->header.seq - first] == RX_ACK_TYPE_ACK) {
3773                 if (!(tp->flags & RX_PKTFLAG_ACKED)) {
3774                     newAckCount++;
3775                     tp->flags |= RX_PKTFLAG_ACKED;
3776                 }
3777                 if (missing) {
3778                     nNacked++;
3779                 } else {
3780                     call->nSoftAcked++;
3781                 }
3782             } else /* RX_ACK_TYPE_NACK */ {
3783                 tp->flags &= ~RX_PKTFLAG_ACKED;
3784                 missing = 1;
3785             }
3786         } else {
3787             tp->flags &= ~RX_PKTFLAG_ACKED;
3788             missing = 1;
3789         }
3790
3791         /* If packet isn't yet acked, and it has been transmitted at least 
3792          * once, reset retransmit time using latest timeout 
3793          * ie, this should readjust the retransmit timer for all outstanding 
3794          * packets...  So we don't just retransmit when we should know better*/
3795
3796         if (!(tp->flags & RX_PKTFLAG_ACKED) && !clock_IsZero(&tp->retryTime)) {
3797             tp->retryTime = tp->timeSent;
3798             clock_Add(&tp->retryTime, &peer->timeout);
3799             /* shift by eight because one quarter-sec ~ 256 milliseconds */
3800             clock_Addmsec(&(tp->retryTime), ((afs_uint32) tp->backoff) << 8);
3801         }
3802     }
3803
3804     /* If the window has been extended by this acknowledge packet,
3805      * then wakeup a sender waiting in alloc for window space, or try
3806      * sending packets now, if he's been sitting on packets due to
3807      * lack of window space */
3808     if (call->tnext < (call->tfirst + call->twind)) {
3809 #ifdef  RX_ENABLE_LOCKS
3810         CV_SIGNAL(&call->cv_twind);
3811 #else
3812         if (call->flags & RX_CALL_WAIT_WINDOW_ALLOC) {
3813             call->flags &= ~RX_CALL_WAIT_WINDOW_ALLOC;
3814             osi_rxWakeup(&call->twind);
3815         }
3816 #endif
3817         if (call->flags & RX_CALL_WAIT_WINDOW_SEND) {
3818             call->flags &= ~RX_CALL_WAIT_WINDOW_SEND;
3819         }
3820     }
3821
3822     /* if the ack packet has a receivelen field hanging off it,
3823      * update our state */
3824     if (np->length >= rx_AckDataSize(ap->nAcks) + 2 * sizeof(afs_int32)) {
3825         afs_uint32 tSize;
3826
3827         /* If the ack packet has a "recommended" size that is less than 
3828          * what I am using now, reduce my size to match */
3829         rx_packetread(np, rx_AckDataSize(ap->nAcks) + sizeof(afs_int32),
3830                       (int)sizeof(afs_int32), &tSize);
3831         tSize = (afs_uint32) ntohl(tSize);
3832         peer->natMTU = rxi_AdjustIfMTU(MIN(tSize, peer->ifMTU));
3833
3834         /* Get the maximum packet size to send to this peer */
3835         rx_packetread(np, rx_AckDataSize(ap->nAcks), (int)sizeof(afs_int32),
3836                       &tSize);
3837         tSize = (afs_uint32) ntohl(tSize);
3838         tSize = (afs_uint32) MIN(tSize, rx_MyMaxSendSize);
3839         tSize = rxi_AdjustMaxMTU(peer->natMTU, tSize);
3840
3841         /* sanity check - peer might have restarted with different params.
3842          * If peer says "send less", dammit, send less...  Peer should never 
3843          * be unable to accept packets of the size that prior AFS versions would
3844          * send without asking.  */
3845         if (peer->maxMTU != tSize) {
3846             if (peer->maxMTU > tSize) /* possible cong., maxMTU decreased */
3847                 peer->congestSeq++;
3848             peer->maxMTU = tSize;
3849             peer->MTU = MIN(tSize, peer->MTU);
3850             call->MTU = MIN(call->MTU, tSize);
3851         }
3852
3853         if (np->length == rx_AckDataSize(ap->nAcks) + 3 * sizeof(afs_int32)) {
3854             /* AFS 3.4a */
3855             rx_packetread(np,
3856                           rx_AckDataSize(ap->nAcks) + 2 * sizeof(afs_int32),
3857                           (int)sizeof(afs_int32), &tSize);
3858             tSize = (afs_uint32) ntohl(tSize);  /* peer's receive window, if it's */
3859             if (tSize < call->twind) {  /* smaller than our send */
3860                 call->twind = tSize;    /* window, we must send less... */
3861                 call->ssthresh = MIN(call->twind, call->ssthresh);
3862                 call->conn->twind[call->channel] = call->twind;
3863             }
3864
3865             /* Only send jumbograms to 3.4a fileservers. 3.3a RX gets the
3866              * network MTU confused with the loopback MTU. Calculate the
3867              * maximum MTU here for use in the slow start code below.
3868              */
3869             maxMTU = peer->maxMTU;
3870             /* Did peer restart with older RX version? */
3871             if (peer->maxDgramPackets > 1) {
3872                 peer->maxDgramPackets = 1;
3873             }
3874         } else if (np->length >=
3875                    rx_AckDataSize(ap->nAcks) + 4 * sizeof(afs_int32)) {
3876             /* AFS 3.5 */
3877             rx_packetread(np,
3878                           rx_AckDataSize(ap->nAcks) + 2 * sizeof(afs_int32),
3879                           sizeof(afs_int32), &tSize);
3880             tSize = (afs_uint32) ntohl(tSize);
3881             /*
3882              * As of AFS 3.5 we set the send window to match the receive window. 
3883              */
3884             if (tSize < call->twind) {
3885                 call->twind = tSize;
3886                 call->conn->twind[call->channel] = call->twind;
3887                 call->ssthresh = MIN(call->twind, call->ssthresh);
3888             } else if (tSize > call->twind) {
3889                 call->twind = tSize;
3890                 call->conn->twind[call->channel] = call->twind;
3891             }
3892
3893             /*
3894              * As of AFS 3.5, a jumbogram is more than one fixed size
3895              * packet transmitted in a single UDP datagram. If the remote
3896              * MTU is smaller than our local MTU then never send a datagram
3897              * larger than the natural MTU.
3898              */
3899             rx_packetread(np,
3900                           rx_AckDataSize(ap->nAcks) + 3 * sizeof(afs_int32),
3901                           sizeof(afs_int32), &tSize);
3902             maxDgramPackets = (afs_uint32) ntohl(tSize);
3903             maxDgramPackets = MIN(maxDgramPackets, rxi_nDgramPackets);
3904             maxDgramPackets =
3905                 MIN(maxDgramPackets, (int)(peer->ifDgramPackets));
3906             maxDgramPackets = MIN(maxDgramPackets, tSize);
3907             if (maxDgramPackets > 1) {
3908                 peer->maxDgramPackets = maxDgramPackets;
3909                 call->MTU = RX_JUMBOBUFFERSIZE + RX_HEADER_SIZE;
3910             } else {
3911                 peer->maxDgramPackets = 1;
3912                 call->MTU = peer->natMTU;
3913             }
3914         } else if (peer->maxDgramPackets > 1) {
3915             /* Restarted with lower version of RX */
3916             peer->maxDgramPackets = 1;
3917         }
3918     } else if (peer->maxDgramPackets > 1
3919                || peer->maxMTU != OLD_MAX_PACKET_SIZE) {
3920         /* Restarted with lower version of RX */
3921         peer->maxMTU = OLD_MAX_PACKET_SIZE;
3922         peer->natMTU = OLD_MAX_PACKET_SIZE;
3923         peer->MTU = OLD_MAX_PACKET_SIZE;
3924         peer->maxDgramPackets = 1;
3925         peer->nDgramPackets = 1;
3926         peer->congestSeq++;
3927         call->MTU = OLD_MAX_PACKET_SIZE;
3928     }
3929
3930     if (nNacked) {
3931         /*
3932          * Calculate how many datagrams were successfully received after
3933          * the first missing packet and adjust the negative ack counter
3934          * accordingly.
3935          */
3936         call->nAcks = 0;
3937         call->nNacks++;
3938         nNacked = (nNacked + call->nDgramPackets - 1) / call->nDgramPackets;
3939         if (call->nNacks < nNacked) {
3940             call->nNacks = nNacked;
3941         }
3942     } else {
3943         call->nAcks += newAckCount;
3944         call->nNacks = 0;
3945     }
3946
3947     if (call->flags & RX_CALL_FAST_RECOVER) {
3948         if (nNacked) {
3949             call->cwind = MIN((int)(call->cwind + 1), rx_maxSendWindow);
3950         } else {
3951             call->flags &= ~RX_CALL_FAST_RECOVER;
3952             call->cwind = call->nextCwind;
3953             call->nextCwind = 0;
3954             call->nAcks = 0;
3955         }
3956         call->nCwindAcks = 0;
3957     } else if (nNacked && call->nNacks >= (u_short) rx_nackThreshold) {
3958         /* Three negative acks in a row trigger congestion recovery */
3959 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
3960         MUTEX_EXIT(&peer->peer_lock);
3961         if (call->flags & RX_CALL_FAST_RECOVER_WAIT) {
3962             /* someone else is waiting to start recovery */
3963             return np;
3964         }
3965         call->flags |= RX_CALL_FAST_RECOVER_WAIT;
3966         rxi_WaitforTQBusy(call);
3967         MUTEX_ENTER(&peer->peer_lock);
3968 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
3969         call->flags &= ~RX_CALL_FAST_RECOVER_WAIT;
3970         call->flags |= RX_CALL_FAST_RECOVER;
3971         call->ssthresh = MAX(4, MIN((int)call->cwind, (int)call->twind)) >> 1;
3972         call->cwind =
3973             MIN((int)(call->ssthresh + rx_nackThreshold), rx_maxSendWindow);
3974         call->nDgramPackets = MAX(2, (int)call->nDgramPackets) >> 1;
3975         call->nextCwind = call->ssthresh;
3976         call->nAcks = 0;
3977         call->nNacks = 0;
3978         peer->MTU = call->MTU;
3979         peer->cwind = call->nextCwind;
3980         peer->nDgramPackets = call->nDgramPackets;
3981         peer->congestSeq++;
3982         call->congestSeq = peer->congestSeq;
3983         /* Reset the resend times on the packets that were nacked
3984          * so we will retransmit as soon as the window permits*/
3985         for (acked = 0, queue_ScanBackwards(&call->tq, tp, nxp, rx_packet)) {
3986             if (acked) {
3987                 if (!(tp->flags & RX_PKTFLAG_ACKED)) {
3988                     clock_Zero(&tp->retryTime);
3989                 }
3990             } else if (tp->flags & RX_PKTFLAG_ACKED) {
3991                 acked = 1;
3992             }
3993         }
3994     } else {
3995         /* If cwind is smaller than ssthresh, then increase
3996          * the window one packet for each ack we receive (exponential
3997          * growth).
3998          * If cwind is greater than or equal to ssthresh then increase
3999          * the congestion window by one packet for each cwind acks we
4000          * receive (linear growth).  */
4001         if (call->cwind < call->ssthresh) {
4002             call->cwind =
4003                 MIN((int)call->ssthresh, (int)(call->cwind + newAckCount));
4004             call->nCwindAcks = 0;
4005         } else {
4006             call->nCwindAcks += newAckCount;
4007             if (call->nCwindAcks >= call->cwind) {
4008                 call->nCwindAcks = 0;
4009                 call->cwind = MIN((int)(call->cwind + 1), rx_maxSendWindow);
4010             }
4011         }
4012         /*
4013          * If we have received several acknowledgements in a row then
4014          * it is time to increase the size of our datagrams
4015          */
4016         if ((int)call->nAcks > rx_nDgramThreshold) {
4017             if (peer->maxDgramPackets > 1) {
4018                 if (call->nDgramPackets < peer->maxDgramPackets) {
4019                     call->nDgramPackets++;
4020                 }
4021                 call->MTU = RX_HEADER_SIZE + RX_JUMBOBUFFERSIZE;
4022             } else if (call->MTU < peer->maxMTU) {
4023                 call->MTU += peer->natMTU;
4024                 call->MTU = MIN(call->MTU, peer->maxMTU);
4025             }
4026             call->nAcks = 0;
4027         }
4028     }
4029
4030     MUTEX_EXIT(&peer->peer_lock);       /* rxi_Start will lock peer. */
4031
4032     /* Servers need to hold the call until all response packets have
4033      * been acknowledged. Soft acks are good enough since clients
4034      * are not allowed to clear their receive queues. */
4035     if (call->state == RX_STATE_HOLD
4036         && call->tfirst + call->nSoftAcked >= call->tnext) {
4037         call->state = RX_STATE_DALLY;
4038         rxi_ClearTransmitQueue(call, 0);
4039         rxevent_Cancel(call->keepAliveEvent, call, RX_CALL_REFCOUNT_ALIVE);
4040     } else if (!queue_IsEmpty(&call->tq)) {
4041         rxi_Start(0, call, 0, istack);
4042     }
4043     return np;
4044 }
4045
4046 /* Received a response to a challenge packet */
4047 struct rx_packet *
4048 rxi_ReceiveResponsePacket(register struct rx_connection *conn,
4049                           register struct rx_packet *np, int istack)
4050 {
4051     int error;
4052
4053     /* Ignore the packet if we're the client */
4054     if (conn->type == RX_CLIENT_CONNECTION)
4055         return np;
4056
4057     /* If already authenticated, ignore the packet (it's probably a retry) */
4058     if (RXS_CheckAuthentication(conn->securityObject, conn) == 0)
4059         return np;
4060
4061     /* Otherwise, have the security object evaluate the response packet */
4062     error = RXS_CheckResponse(conn->securityObject, conn, np);
4063     if (error) {
4064         /* If the response is invalid, reset the connection, sending
4065          * an abort to the peer */
4066 #ifndef KERNEL
4067         rxi_Delay(1);
4068 #endif
4069         rxi_ConnectionError(conn, error);
4070         MUTEX_ENTER(&conn->conn_data_lock);
4071         np = rxi_SendConnectionAbort(conn, np, istack, 0);
4072         MUTEX_EXIT(&conn->conn_data_lock);
4073         return np;
4074     } else {
4075         /* If the response is valid, any calls waiting to attach
4076          * servers can now do so */
4077         int i;
4078
4079         for (i = 0; i < RX_MAXCALLS; i++) {
4080             struct rx_call *call = conn->call[i];
4081             if (call) {
4082                 MUTEX_ENTER(&call->lock);
4083                 if (call->state == RX_STATE_PRECALL)
4084                     rxi_AttachServerProc(call, (osi_socket) - 1, NULL, NULL);
4085                 /* tnop can be null if newcallp is null */
4086                 MUTEX_EXIT(&call->lock);
4087             }
4088         }
4089
4090         /* Update the peer reachability information, just in case
4091          * some calls went into attach-wait while we were waiting
4092          * for authentication..
4093          */
4094         rxi_UpdatePeerReach(conn, NULL);
4095     }
4096     return np;
4097 }
4098
4099 /* A client has received an authentication challenge: the security
4100  * object is asked to cough up a respectable response packet to send
4101  * back to the server.  The server is responsible for retrying the
4102  * challenge if it fails to get a response. */
4103
4104 struct rx_packet *
4105 rxi_ReceiveChallengePacket(register struct rx_connection *conn,
4106                            register struct rx_packet *np, int istack)
4107 {
4108     int error;
4109
4110     /* Ignore the challenge if we're the server */
4111     if (conn->type == RX_SERVER_CONNECTION)
4112         return np;
4113
4114     /* Ignore the challenge if the connection is otherwise idle; someone's
4115      * trying to use us as an oracle. */
4116     if (!rxi_HasActiveCalls(conn))
4117         return np;
4118
4119     /* Send the security object the challenge packet.  It is expected to fill
4120      * in the response. */
4121     error = RXS_GetResponse(conn->securityObject, conn, np);
4122
4123     /* If the security object is unable to return a valid response, reset the
4124      * connection and send an abort to the peer.  Otherwise send the response
4125      * packet to the peer connection. */
4126     if (error) {
4127         rxi_ConnectionError(conn, error);
4128         MUTEX_ENTER(&conn->conn_data_lock);
4129         np = rxi_SendConnectionAbort(conn, np, istack, 0);
4130         MUTEX_EXIT(&conn->conn_data_lock);
4131     } else {
4132         np = rxi_SendSpecial((struct rx_call *)0, conn, np,
4133                              RX_PACKET_TYPE_RESPONSE, NULL, -1, istack);
4134     }
4135     return np;
4136 }
4137
4138
4139 /* Find an available server process to service the current request in
4140  * the given call structure.  If one isn't available, queue up this
4141  * call so it eventually gets one */
4142 void
4143 rxi_AttachServerProc(register struct rx_call *call,
4144                      register osi_socket socket, register int *tnop,
4145                      register struct rx_call **newcallp)
4146 {
4147     register struct rx_serverQueueEntry *sq;
4148     register struct rx_service *service = call->conn->service;
4149     register int haveQuota = 0;
4150
4151     /* May already be attached */
4152     if (call->state == RX_STATE_ACTIVE)
4153         return;
4154
4155     MUTEX_ENTER(&rx_serverPool_lock);
4156
4157     haveQuota = QuotaOK(service);
4158     if ((!haveQuota) || queue_IsEmpty(&rx_idleServerQueue)) {
4159         /* If there are no processes available to service this call,
4160          * put the call on the incoming call queue (unless it's
4161          * already on the queue).
4162          */
4163 #ifdef RX_ENABLE_LOCKS
4164         if (haveQuota)
4165             ReturnToServerPool(service);
4166 #endif /* RX_ENABLE_LOCKS */
4167
4168         if (!(call->flags & RX_CALL_WAIT_PROC)) {
4169             call->flags |= RX_CALL_WAIT_PROC;
4170             MUTEX_ENTER(&rx_stats_mutex);
4171             rx_nWaiting++;
4172             rx_nWaited++;
4173             MUTEX_EXIT(&rx_stats_mutex);
4174             rxi_calltrace(RX_CALL_ARRIVAL, call);
4175             SET_CALL_QUEUE_LOCK(call, &rx_serverPool_lock);
4176             queue_Append(&rx_incomingCallQueue, call);
4177         }
4178     } else {
4179         sq = queue_First(&rx_idleServerQueue, rx_serverQueueEntry);
4180
4181         /* If hot threads are enabled, and both newcallp and sq->socketp
4182          * are non-null, then this thread will process the call, and the
4183          * idle server thread will start listening on this threads socket.
4184          */
4185         queue_Remove(sq);
4186         if (rx_enable_hot_thread && newcallp && sq->socketp) {
4187             *newcallp = call;
4188             *tnop = sq->tno;
4189             *sq->socketp = socket;
4190             clock_GetTime(&call->startTime);
4191             CALL_HOLD(call, RX_CALL_REFCOUNT_BEGIN);
4192         } else {
4193             sq->newcall = call;
4194         }
4195         if (call->flags & RX_CALL_WAIT_PROC) {
4196             /* Conservative:  I don't think this should happen */
4197             call->flags &= ~RX_CALL_WAIT_PROC;
4198             if (queue_IsOnQueue(call)) {
4199                 queue_Remove(call);
4200                 MUTEX_ENTER(&rx_stats_mutex);
4201                 rx_nWaiting--;
4202                 MUTEX_EXIT(&rx_stats_mutex);
4203             }
4204         }
4205         call->state = RX_STATE_ACTIVE;
4206         call->mode = RX_MODE_RECEIVING;
4207 #ifdef RX_KERNEL_TRACE
4208         {
4209             int glockOwner = ISAFS_GLOCK();
4210             if (!glockOwner)
4211                 AFS_GLOCK();
4212             afs_Trace3(afs_iclSetp, CM_TRACE_WASHERE, ICL_TYPE_STRING,
4213                        __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER,
4214                        call);
4215             if (!glockOwner)
4216                 AFS_GUNLOCK();
4217         }
4218 #endif
4219         if (call->flags & RX_CALL_CLEARED) {
4220             /* send an ack now to start the packet flow up again */
4221             call->flags &= ~RX_CALL_CLEARED;
4222             rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
4223         }
4224 #ifdef  RX_ENABLE_LOCKS
4225         CV_SIGNAL(&sq->cv);
4226 #else
4227         service->nRequestsRunning++;
4228         if (service->nRequestsRunning <= service->minProcs)
4229             rxi_minDeficit--;
4230         rxi_availProcs--;
4231         osi_rxWakeup(sq);
4232 #endif
4233     }
4234     MUTEX_EXIT(&rx_serverPool_lock);
4235 }
4236
4237 /* Delay the sending of an acknowledge event for a short while, while
4238  * a new call is being prepared (in the case of a client) or a reply
4239  * is being prepared (in the case of a server).  Rather than sending
4240  * an ack packet, an ACKALL packet is sent. */
4241 void
4242 rxi_AckAll(struct rxevent *event, register struct rx_call *call, char *dummy)
4243 {
4244 #ifdef RX_ENABLE_LOCKS
4245     if (event) {
4246         MUTEX_ENTER(&call->lock);
4247         call->delayedAckEvent = NULL;
4248         CALL_RELE(call, RX_CALL_REFCOUNT_ACKALL);
4249     }
4250     rxi_SendSpecial(call, call->conn, (struct rx_packet *)0,
4251                     RX_PACKET_TYPE_ACKALL, NULL, 0, 0);
4252     if (event)
4253         MUTEX_EXIT(&call->lock);
4254 #else /* RX_ENABLE_LOCKS */
4255     if (event)
4256         call->delayedAckEvent = NULL;
4257     rxi_SendSpecial(call, call->conn, (struct rx_packet *)0,
4258                     RX_PACKET_TYPE_ACKALL, NULL, 0, 0);
4259 #endif /* RX_ENABLE_LOCKS */
4260 }
4261
4262 void
4263 rxi_SendDelayedAck(struct rxevent *event, void *arg1, void *unused)
4264 {
4265     struct rx_call *call = arg1;
4266 #ifdef RX_ENABLE_LOCKS
4267     if (event) {
4268         MUTEX_ENTER(&call->lock);
4269         if (event == call->delayedAckEvent)
4270             call->delayedAckEvent = NULL;
4271         CALL_RELE(call, RX_CALL_REFCOUNT_DELAY);
4272     }
4273     (void)rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
4274     if (event)
4275         MUTEX_EXIT(&call->lock);
4276 #else /* RX_ENABLE_LOCKS */
4277     if (event)
4278         call->delayedAckEvent = NULL;
4279     (void)rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
4280 #endif /* RX_ENABLE_LOCKS */
4281 }
4282
4283
4284 #ifdef RX_ENABLE_LOCKS
4285 /* Set ack in all packets in transmit queue. rxi_Start will deal with
4286  * clearing them out.
4287  */
4288 static void
4289 rxi_SetAcksInTransmitQueue(register struct rx_call *call)
4290 {
4291     register struct rx_packet *p, *tp;
4292     int someAcked = 0;
4293
4294     for (queue_Scan(&call->tq, p, tp, rx_packet)) {
4295         p->flags |= RX_PKTFLAG_ACKED;
4296         someAcked = 1;
4297     }
4298     if (someAcked) {
4299         call->flags |= RX_CALL_TQ_CLEARME;
4300         call->flags |= RX_CALL_TQ_SOME_ACKED;
4301     }
4302
4303     rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
4304     call->tfirst = call->tnext;
4305     call->nSoftAcked = 0;
4306
4307     if (call->flags & RX_CALL_FAST_RECOVER) {
4308         call->flags &= ~RX_CALL_FAST_RECOVER;
4309         call->cwind = call->nextCwind;
4310         call->nextCwind = 0;
4311     }
4312
4313     CV_SIGNAL(&call->cv_twind);
4314 }
4315 #endif /* RX_ENABLE_LOCKS */
4316
4317 /* Clear out the transmit queue for the current call (all packets have
4318  * been received by peer) */
4319 void
4320 rxi_ClearTransmitQueue(register struct rx_call *call, register int force)
4321 {
4322 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
4323     register struct rx_packet *p, *tp;
4324
4325     if (!force && (call->flags & RX_CALL_TQ_BUSY)) {
4326         int someAcked = 0;
4327         for (queue_Scan(&call->tq, p, tp, rx_packet)) {
4328             p->flags |= RX_PKTFLAG_ACKED;
4329             someAcked = 1;
4330         }
4331         if (someAcked) {
4332             call->flags |= RX_CALL_TQ_CLEARME;
4333             call->flags |= RX_CALL_TQ_SOME_ACKED;
4334         }
4335     } else {
4336 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
4337         rxi_FreePackets(0, &call->tq);
4338 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
4339         call->flags &= ~RX_CALL_TQ_CLEARME;
4340     }
4341 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
4342
4343     rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
4344     call->tfirst = call->tnext; /* implicitly acknowledge all data already sent */
4345     call->nSoftAcked = 0;
4346
4347     if (call->flags & RX_CALL_FAST_RECOVER) {
4348         call->flags &= ~RX_CALL_FAST_RECOVER;
4349         call->cwind = call->nextCwind;
4350     }
4351 #ifdef  RX_ENABLE_LOCKS
4352     CV_SIGNAL(&call->cv_twind);
4353 #else
4354     osi_rxWakeup(&call->twind);
4355 #endif
4356 }
4357
4358 void
4359 rxi_ClearReceiveQueue(register struct rx_call *call)
4360 {
4361     if (queue_IsNotEmpty(&call->rq)) {
4362         rx_packetReclaims += rxi_FreePackets(0, &call->rq);
4363         call->flags &= ~(RX_CALL_RECEIVE_DONE | RX_CALL_HAVE_LAST);
4364     }
4365     if (call->state == RX_STATE_PRECALL) {
4366         call->flags |= RX_CALL_CLEARED;
4367     }
4368 }
4369
4370 /* Send an abort packet for the specified call */
4371 struct rx_packet *
4372 rxi_SendCallAbort(register struct rx_call *call, struct rx_packet *packet,
4373                   int istack, int force)
4374 {
4375     afs_int32 error;
4376     struct clock when, now;
4377
4378     if (!call->error)
4379         return packet;
4380
4381     /* Clients should never delay abort messages */
4382     if (rx_IsClientConn(call->conn))
4383         force = 1;
4384
4385     if (call->abortCode != call->error) {
4386         call->abortCode = call->error;
4387         call->abortCount = 0;
4388     }
4389
4390     if (force || rxi_callAbortThreshhold == 0
4391         || call->abortCount < rxi_callAbortThreshhold) {
4392         if (call->delayedAbortEvent) {
4393             rxevent_Cancel(call->delayedAbortEvent, call,
4394                            RX_CALL_REFCOUNT_ABORT);
4395         }
4396         error = htonl(call->error);
4397         call->abortCount++;
4398         packet =
4399             rxi_SendSpecial(call, call->conn, packet, RX_PACKET_TYPE_ABORT,
4400                             (char *)&error, sizeof(error), istack);
4401     } else if (!call->delayedAbortEvent) {
4402         clock_GetTime(&now);
4403         when = now;
4404         clock_Addmsec(&when, rxi_callAbortDelay);
4405         CALL_HOLD(call, RX_CALL_REFCOUNT_ABORT);
4406         call->delayedAbortEvent =
4407             rxevent_PostNow(&when, &now, rxi_SendDelayedCallAbort, call, 0);
4408     }
4409     return packet;
4410 }
4411
4412 /* Send an abort packet for the specified connection.  Packet is an
4413  * optional pointer to a packet that can be used to send the abort.
4414  * Once the number of abort messages reaches the threshhold, an
4415  * event is scheduled to send the abort. Setting the force flag
4416  * overrides sending delayed abort messages.
4417  *
4418  * NOTE: Called with conn_data_lock held. conn_data_lock is dropped
4419  *       to send the abort packet.
4420  */
4421 struct rx_packet *
4422 rxi_SendConnectionAbort(register struct rx_connection *conn,
4423                         struct rx_packet *packet, int istack, int force)
4424 {
4425     afs_int32 error;
4426     struct clock when, now;
4427
4428     if (!conn->error)
4429         return packet;
4430
4431     /* Clients should never delay abort messages */
4432     if (rx_IsClientConn(conn))
4433         force = 1;
4434
4435     if (force || rxi_connAbortThreshhold == 0
4436         || conn->abortCount < rxi_connAbortThreshhold) {
4437         if (conn->delayedAbortEvent) {
4438             rxevent_Cancel(conn->delayedAbortEvent, (struct rx_call *)0, 0);
4439         }
4440         error = htonl(conn->error);
4441         conn->abortCount++;
4442         MUTEX_EXIT(&conn->conn_data_lock);
4443         packet =
4444             rxi_SendSpecial((struct rx_call *)0, conn, packet,
4445                             RX_PACKET_TYPE_ABORT, (char *)&error,
4446                             sizeof(error), istack);
4447         MUTEX_ENTER(&conn->conn_data_lock);
4448     } else if (!conn->delayedAbortEvent) {
4449         clock_GetTime(&now);
4450         when = now;
4451         clock_Addmsec(&when, rxi_connAbortDelay);
4452         conn->delayedAbortEvent =
4453             rxevent_PostNow(&when, &now, rxi_SendDelayedConnAbort, conn, 0);
4454     }
4455     return packet;
4456 }
4457
4458 /* Associate an error all of the calls owned by a connection.  Called
4459  * with error non-zero.  This is only for really fatal things, like
4460  * bad authentication responses.  The connection itself is set in
4461  * error at this point, so that future packets received will be
4462  * rejected. */
4463 void
4464 rxi_ConnectionError(register struct rx_connection *conn,
4465                     register afs_int32 error)
4466 {
4467     if (error) {
4468         register int i;
4469
4470         dpf(("rxi_ConnectionError conn %x error %d", conn, error));
4471
4472         MUTEX_ENTER(&conn->conn_data_lock);
4473         if (conn->challengeEvent)
4474             rxevent_Cancel(conn->challengeEvent, (struct rx_call *)0, 0);
4475         if (conn->checkReachEvent) {
4476             rxevent_Cancel(conn->checkReachEvent, (struct rx_call *)0, 0);
4477             conn->checkReachEvent = 0;
4478             conn->flags &= ~RX_CONN_ATTACHWAIT;
4479             conn->refCount--;
4480         }
4481         MUTEX_EXIT(&conn->conn_data_lock);
4482         for (i = 0; i < RX_MAXCALLS; i++) {
4483             struct rx_call *call = conn->call[i];
4484             if (call) {
4485                 MUTEX_ENTER(&call->lock);
4486                 rxi_CallError(call, error);
4487                 MUTEX_EXIT(&call->lock);
4488             }
4489         }
4490         conn->error = error;
4491         rx_MutexIncrement(rx_stats.fatalErrors, rx_stats_mutex);
4492     }
4493 }
4494
4495 void
4496 rxi_CallError(register struct rx_call *call, afs_int32 error)
4497 {
4498     dpf(("rxi_CallError call %x error %d call->error %d", call, error, call->error));
4499     if (call->error)
4500         error = call->error;
4501
4502 #ifdef RX_GLOBAL_RXLOCK_KERNEL
4503     if (!((call->flags & RX_CALL_TQ_BUSY) || (call->tqWaiters > 0))) {
4504         rxi_ResetCall(call, 0);
4505     }
4506 #else
4507     rxi_ResetCall(call, 0);
4508 #endif
4509     call->error = error;
4510     call->mode = RX_MODE_ERROR;
4511 }
4512
4513 /* Reset various fields in a call structure, and wakeup waiting
4514  * processes.  Some fields aren't changed: state & mode are not
4515  * touched (these must be set by the caller), and bufptr, nLeft, and
4516  * nFree are not reset, since these fields are manipulated by
4517  * unprotected macros, and may only be reset by non-interrupting code.
4518  */
4519 #ifdef ADAPT_WINDOW
4520 /* this code requires that call->conn be set properly as a pre-condition. */
4521 #endif /* ADAPT_WINDOW */
4522
4523 void
4524 rxi_ResetCall(register struct rx_call *call, register int newcall)
4525 {
4526     register int flags;
4527     register struct rx_peer *peer;
4528     struct rx_packet *packet;
4529
4530     dpf(("rxi_ResetCall(call %x, newcall %d)\n", call, newcall));
4531
4532     /* Notify anyone who is waiting for asynchronous packet arrival */
4533     if (call->arrivalProc) {
4534         (*call->arrivalProc) (call, call->arrivalProcHandle,
4535                               call->arrivalProcArg);
4536         call->arrivalProc = (void (*)())0;
4537     }
4538
4539     if (call->delayedAbortEvent) {
4540         rxevent_Cancel(call->delayedAbortEvent, call, RX_CALL_REFCOUNT_ABORT);
4541         packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
4542         if (packet) {
4543             rxi_SendCallAbort(call, packet, 0, 1);
4544             rxi_FreePacket(packet);
4545         }
4546     }
4547
4548     /*
4549      * Update the peer with the congestion information in this call
4550      * so other calls on this connection can pick up where this call
4551      * left off. If the congestion sequence numbers don't match then
4552      * another call experienced a retransmission.
4553      */
4554     peer = call->conn->peer;
4555     MUTEX_ENTER(&peer->peer_lock);
4556     if (!newcall) {
4557         if (call->congestSeq == peer->congestSeq) {
4558             peer->cwind = MAX(peer->cwind, call->cwind);
4559             peer->MTU = MAX(peer->MTU, call->MTU);
4560             peer->nDgramPackets =
4561                 MAX(peer->nDgramPackets, call->nDgramPackets);
4562         }
4563     } else {
4564         call->abortCode = 0;
4565         call->abortCount = 0;
4566     }
4567     if (peer->maxDgramPackets > 1) {
4568         call->MTU = RX_HEADER_SIZE + RX_JUMBOBUFFERSIZE;
4569     } else {
4570         call->MTU = peer->MTU;
4571     }
4572     call->cwind = MIN((int)peer->cwind, (int)peer->nDgramPackets);
4573     call->ssthresh = rx_maxSendWindow;
4574     call->nDgramPackets = peer->nDgramPackets;
4575     call->congestSeq = peer->congestSeq;
4576     MUTEX_EXIT(&peer->peer_lock);
4577
4578     flags = call->flags;
4579     rxi_ClearReceiveQueue(call);
4580 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
4581     if (flags & RX_CALL_TQ_BUSY) {
4582         call->flags = RX_CALL_TQ_CLEARME | RX_CALL_TQ_BUSY;
4583         call->flags |= (flags & RX_CALL_TQ_WAIT);
4584     } else
4585 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
4586     {
4587         rxi_ClearTransmitQueue(call, 0);
4588         queue_Init(&call->tq);
4589         if (call->tqWaiters || (flags & RX_CALL_TQ_WAIT)) {
4590             dpf(("rcall %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
4591         }
4592         call->flags = 0;
4593         while (call->tqWaiters) {
4594 #ifdef RX_ENABLE_LOCKS
4595             CV_BROADCAST(&call->cv_tq);
4596 #else /* RX_ENABLE_LOCKS */
4597             osi_rxWakeup(&call->tq);
4598 #endif /* RX_ENABLE_LOCKS */
4599             call->tqWaiters--;
4600         }
4601     }
4602     queue_Init(&call->rq);
4603     call->error = 0;
4604     call->twind = call->conn->twind[call->channel];
4605     call->rwind = call->conn->rwind[call->channel];
4606     call->nSoftAcked = 0;
4607     call->nextCwind = 0;
4608     call->nAcks = 0;
4609     call->nNacks = 0;
4610     call->nCwindAcks = 0;
4611     call->nSoftAcks = 0;
4612     call->nHardAcks = 0;
4613
4614     call->tfirst = call->rnext = call->tnext = 1;
4615     call->rprev = 0;
4616     call->lastAcked = 0;
4617     call->localStatus = call->remoteStatus = 0;
4618
4619     if (flags & RX_CALL_READER_WAIT) {
4620 #ifdef  RX_ENABLE_LOCKS
4621         CV_BROADCAST(&call->cv_rq);
4622 #else
4623         osi_rxWakeup(&call->rq);
4624 #endif
4625     }
4626     if (flags & RX_CALL_WAIT_PACKETS) {
4627         MUTEX_ENTER(&rx_freePktQ_lock);
4628         rxi_PacketsUnWait();    /* XXX */
4629         MUTEX_EXIT(&rx_freePktQ_lock);
4630     }
4631 #ifdef  RX_ENABLE_LOCKS
4632     CV_SIGNAL(&call->cv_twind);
4633 #else
4634     if (flags & RX_CALL_WAIT_WINDOW_ALLOC)
4635         osi_rxWakeup(&call->twind);
4636 #endif
4637
4638 #ifdef RX_ENABLE_LOCKS
4639     /* The following ensures that we don't mess with any queue while some
4640      * other thread might also be doing so. The call_queue_lock field is
4641      * is only modified under the call lock. If the call is in the process
4642      * of being removed from a queue, the call is not locked until the
4643      * the queue lock is dropped and only then is the call_queue_lock field
4644      * zero'd out. So it's safe to lock the queue if call_queue_lock is set.
4645      * Note that any other routine which removes a call from a queue has to
4646      * obtain the queue lock before examing the queue and removing the call.
4647      */
4648     if (call->call_queue_lock) {
4649         MUTEX_ENTER(call->call_queue_lock);
4650         if (queue_IsOnQueue(call)) {
4651             queue_Remove(call);
4652             if (flags & RX_CALL_WAIT_PROC) {
4653                 MUTEX_ENTER(&rx_stats_mutex);
4654                 rx_nWaiting--;
4655                 MUTEX_EXIT(&rx_stats_mutex);
4656             }
4657         }
4658         MUTEX_EXIT(call->call_queue_lock);
4659         CLEAR_CALL_QUEUE_LOCK(call);
4660     }
4661 #else /* RX_ENABLE_LOCKS */
4662     if (queue_IsOnQueue(call)) {
4663         queue_Remove(call);
4664         if (flags & RX_CALL_WAIT_PROC)
4665             rx_nWaiting--;
4666     }
4667 #endif /* RX_ENABLE_LOCKS */
4668
4669     rxi_KeepAliveOff(call);
4670     rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
4671 }
4672
4673 /* Send an acknowledge for the indicated packet (seq,serial) of the
4674  * indicated call, for the indicated reason (reason).  This
4675  * acknowledge will specifically acknowledge receiving the packet, and
4676  * will also specify which other packets for this call have been
4677  * received.  This routine returns the packet that was used to the
4678  * caller.  The caller is responsible for freeing it or re-using it.
4679  * This acknowledgement also returns the highest sequence number
4680  * actually read out by the higher level to the sender; the sender
4681  * promises to keep around packets that have not been read by the
4682  * higher level yet (unless, of course, the sender decides to abort
4683  * the call altogether).  Any of p, seq, serial, pflags, or reason may
4684  * be set to zero without ill effect.  That is, if they are zero, they
4685  * will not convey any information.  
4686  * NOW there is a trailer field, after the ack where it will safely be
4687  * ignored by mundanes, which indicates the maximum size packet this 
4688  * host can swallow.  */
4689 /*
4690     register struct rx_packet *optionalPacket;  use to send ack (or null) 
4691     int seq;                     Sequence number of the packet we are acking 
4692     int serial;                  Serial number of the packet 
4693     int pflags;                  Flags field from packet header 
4694     int reason;                  Reason an acknowledge was prompted 
4695 */
4696
4697 struct rx_packet *
4698 rxi_SendAck(register struct rx_call *call,
4699             register struct rx_packet *optionalPacket, int serial, int reason,
4700             int istack)
4701 {
4702     struct rx_ackPacket *ap;
4703     register struct rx_packet *rqp;
4704     register struct rx_packet *nxp;     /* For queue_Scan */
4705     register struct rx_packet *p;
4706     u_char offset;
4707     afs_int32 templ;
4708 #ifdef RX_ENABLE_TSFPQ
4709     struct rx_ts_info_t * rx_ts_info;
4710 #endif
4711
4712     /*
4713      * Open the receive window once a thread starts reading packets
4714      */
4715     if (call->rnext > 1) {
4716         call->conn->rwind[call->channel] = call->rwind = rx_maxReceiveWindow;
4717     }
4718
4719     call->nHardAcks = 0;
4720     call->nSoftAcks = 0;
4721     if (call->rnext > call->lastAcked)
4722         call->lastAcked = call->rnext;
4723     p = optionalPacket;
4724
4725     if (p) {
4726         rx_computelen(p, p->length);    /* reset length, you never know */
4727     } /* where that's been...         */
4728 #ifdef RX_ENABLE_TSFPQ
4729     else {
4730         RX_TS_INFO_GET(rx_ts_info);
4731         if ((p = rx_ts_info->local_special_packet)) {
4732             rx_computelen(p, p->length);
4733         } else if ((p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL))) {
4734             rx_ts_info->local_special_packet = p;
4735         } else { /* We won't send the ack, but don't panic. */
4736             return optionalPacket;
4737         }
4738     }
4739 #else
4740     else if (!(p = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL))) {
4741         /* We won't send the ack, but don't panic. */
4742         return optionalPacket;
4743     }
4744 #endif
4745
4746     templ =
4747         rx_AckDataSize(call->rwind) + 4 * sizeof(afs_int32) -
4748         rx_GetDataSize(p);
4749     if (templ > 0) {
4750         if (rxi_AllocDataBuf(p, templ, RX_PACKET_CLASS_SPECIAL) > 0) {
4751 #ifndef RX_ENABLE_TSFPQ
4752             if (!optionalPacket)
4753                 rxi_FreePacket(p);
4754 #endif
4755             return optionalPacket;
4756         }
4757         templ = rx_AckDataSize(call->rwind) + 2 * sizeof(afs_int32);
4758         if (rx_Contiguous(p) < templ) {
4759 #ifndef RX_ENABLE_TSFPQ
4760             if (!optionalPacket)
4761                 rxi_FreePacket(p);
4762 #endif
4763             return optionalPacket;
4764         }
4765     }
4766
4767
4768     /* MTUXXX failing to send an ack is very serious.  We should */
4769     /* try as hard as possible to send even a partial ack; it's */
4770     /* better than nothing. */
4771     ap = (struct rx_ackPacket *)rx_DataOf(p);
4772     ap->bufferSpace = htonl(0); /* Something should go here, sometime */
4773     ap->reason = reason;
4774
4775     /* The skew computation used to be bogus, I think it's better now. */
4776     /* We should start paying attention to skew.    XXX  */
4777     ap->serial = htonl(serial);
4778     ap->maxSkew = 0;            /* used to be peer->inPacketSkew */
4779
4780     ap->firstPacket = htonl(call->rnext);       /* First packet not yet forwarded to reader */
4781     ap->previousPacket = htonl(call->rprev);    /* Previous packet received */
4782
4783     /* No fear of running out of ack packet here because there can only be at most
4784      * one window full of unacknowledged packets.  The window size must be constrained 
4785      * to be less than the maximum ack size, of course.  Also, an ack should always
4786      * fit into a single packet -- it should not ever be fragmented.  */
4787     for (offset = 0, queue_Scan(&call->rq, rqp, nxp, rx_packet)) {
4788         if (!rqp || !call->rq.next
4789             || (rqp->header.seq > (call->rnext + call->rwind))) {
4790 #ifndef RX_ENABLE_TSFPQ
4791             if (!optionalPacket)
4792                 rxi_FreePacket(p);
4793 #endif
4794             rxi_CallError(call, RX_CALL_DEAD);
4795             return optionalPacket;
4796         }
4797
4798         while (rqp->header.seq > call->rnext + offset)
4799             ap->acks[offset++] = RX_ACK_TYPE_NACK;
4800         ap->acks[offset++] = RX_ACK_TYPE_ACK;
4801
4802         if ((offset > (u_char) rx_maxReceiveWindow) || (offset > call->rwind)) {
4803 #ifndef RX_ENABLE_TSFPQ
4804             if (!optionalPacket)
4805                 rxi_FreePacket(p);
4806 #endif
4807             rxi_CallError(call, RX_CALL_DEAD);
4808             return optionalPacket;
4809         }
4810     }
4811
4812     ap->nAcks = offset;
4813     p->length = rx_AckDataSize(offset) + 4 * sizeof(afs_int32);
4814
4815     /* these are new for AFS 3.3 */
4816     templ = rxi_AdjustMaxMTU(call->conn->peer->ifMTU, rx_maxReceiveSize);
4817     templ = htonl(templ);
4818     rx_packetwrite(p, rx_AckDataSize(offset), sizeof(afs_int32), &templ);
4819     templ = htonl(call->conn->peer->ifMTU);
4820     rx_packetwrite(p, rx_AckDataSize(offset) + sizeof(afs_int32),
4821                    sizeof(afs_int32), &templ);
4822
4823     /* new for AFS 3.4 */
4824     templ = htonl(call->rwind);
4825     rx_packetwrite(p, rx_AckDataSize(offset) + 2 * sizeof(afs_int32),
4826                    sizeof(afs_int32), &templ);
4827
4828     /* new for AFS 3.5 */
4829     templ = htonl(call->conn->peer->ifDgramPackets);
4830     rx_packetwrite(p, rx_AckDataSize(offset) + 3 * sizeof(afs_int32),
4831                    sizeof(afs_int32), &templ);
4832
4833     p->header.serviceId = call->conn->serviceId;
4834     p->header.cid = (call->conn->cid | call->channel);
4835     p->header.callNumber = *call->callNumber;
4836     p->header.seq = 0;
4837     p->header.securityIndex = call->conn->securityIndex;
4838     p->header.epoch = call->conn->epoch;
4839     p->header.type = RX_PACKET_TYPE_ACK;
4840     p->header.flags = RX_SLOW_START_OK;
4841     if (reason == RX_ACK_PING) {
4842         p->header.flags |= RX_REQUEST_ACK;
4843 #ifdef ADAPT_WINDOW
4844         clock_GetTime(&call->pingRequestTime);
4845 #endif
4846     }
4847     if (call->conn->type == RX_CLIENT_CONNECTION)
4848         p->header.flags |= RX_CLIENT_INITIATED;
4849
4850 #ifdef RXDEBUG
4851 #ifdef AFS_NT40_ENV
4852     if (rxdebug_active) {
4853         char msg[512];
4854         size_t len;
4855
4856         len = _snprintf(msg, sizeof(msg),
4857                         "tid[%d] SACK: reason %s serial %u previous %u seq %u first %u acks %u space %u ",
4858                          GetCurrentThreadId(), rx_ack_reason(ap->reason), 
4859                          ntohl(ap->serial), ntohl(ap->previousPacket),
4860                          (unsigned int)p->header.seq, ntohl(ap->firstPacket),
4861                          ap->nAcks, ntohs(ap->bufferSpace) );
4862         if (ap->nAcks) {
4863             int offset;
4864
4865             for (offset = 0; offset < ap->nAcks && len < sizeof(msg); offset++) 
4866                 msg[len++] = (ap->acks[offset] == RX_ACK_TYPE_NACK ? '-' : '*');
4867         }
4868         msg[len++]='\n';
4869         msg[len] = '\0';
4870         OutputDebugString(msg);
4871     }
4872 #else /* AFS_NT40_ENV */
4873     if (rx_Log) {
4874         fprintf(rx_Log, "SACK: reason %x previous %u seq %u first %u ",
4875                 ap->reason, ntohl(ap->previousPacket),
4876                 (unsigned int)p->header.seq, ntohl(ap->firstPacket));
4877         if (ap->nAcks) {
4878             for (offset = 0; offset < ap->nAcks; offset++)
4879                 putc(ap->acks[offset] == RX_ACK_TYPE_NACK ? '-' : '*',
4880                      rx_Log);
4881         }
4882         putc('\n', rx_Log);
4883     }
4884 #endif /* AFS_NT40_ENV */
4885 #endif
4886     {
4887         register int i, nbytes = p->length;
4888
4889         for (i = 1; i < p->niovecs; i++) {      /* vec 0 is ALWAYS header */
4890             if (nbytes <= p->wirevec[i].iov_len) {
4891                 register int savelen, saven;
4892
4893                 savelen = p->wirevec[i].iov_len;
4894                 saven = p->niovecs;
4895                 p->wirevec[i].iov_len = nbytes;
4896                 p->niovecs = i + 1;
4897                 rxi_Send(call, p, istack);
4898                 p->wirevec[i].iov_len = savelen;
4899                 p->niovecs = saven;
4900                 break;
4901             } else
4902                 nbytes -= p->wirevec[i].iov_len;
4903         }
4904     }
4905     rx_MutexIncrement(rx_stats.ackPacketsSent, rx_stats_mutex);
4906 #ifndef RX_ENABLE_TSFPQ
4907     if (!optionalPacket)
4908         rxi_FreePacket(p);
4909 #endif
4910     return optionalPacket;      /* Return packet for re-use by caller */
4911 }
4912
4913 /* Send all of the packets in the list in single datagram */
4914 static void
4915 rxi_SendList(struct rx_call *call, struct rx_packet **list, int len,
4916              int istack, int moreFlag, struct clock *now,
4917              struct clock *retryTime, int resending)
4918 {
4919     int i;
4920     int requestAck = 0;
4921     int lastPacket = 0;
4922     struct rx_connection *conn = call->conn;
4923     struct rx_peer *peer = conn->peer;
4924
4925     MUTEX_ENTER(&peer->peer_lock);
4926     peer->nSent += len;
4927     if (resending)
4928         peer->reSends += len;
4929     rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
4930     MUTEX_EXIT(&peer->peer_lock);
4931
4932     if (list[len - 1]->header.flags & RX_LAST_PACKET) {
4933         lastPacket = 1;
4934     }
4935
4936     /* Set the packet flags and schedule the resend events */
4937     /* Only request an ack for the last packet in the list */
4938     for (i = 0; i < len; i++) {
4939         list[i]->retryTime = *retryTime;
4940         if (list[i]->header.serial) {
4941             /* Exponentially backoff retry times */
4942             if (list[i]->backoff < MAXBACKOFF) {
4943                 /* so it can't stay == 0 */
4944                 list[i]->backoff = (list[i]->backoff << 1) + 1;
4945             } else
4946                 list[i]->backoff++;
4947             clock_Addmsec(&(list[i]->retryTime),
4948                           ((afs_uint32) list[i]->backoff) << 8);
4949         }
4950
4951         /* Wait a little extra for the ack on the last packet */
4952         if (lastPacket && !(list[i]->header.flags & RX_CLIENT_INITIATED)) {
4953             clock_Addmsec(&(list[i]->retryTime), 400);
4954         }
4955
4956         /* Record the time sent */
4957         list[i]->timeSent = *now;
4958
4959         /* Ask for an ack on retransmitted packets,  on every other packet
4960          * if the peer doesn't support slow start. Ask for an ack on every
4961          * packet until the congestion window reaches the ack rate. */
4962         if (list[i]->header.serial) {
4963             requestAck = 1;
4964             rx_MutexIncrement(rx_stats.dataPacketsReSent, rx_stats_mutex);
4965         } else {
4966             /* improved RTO calculation- not Karn */
4967             list[i]->firstSent = *now;
4968             if (!lastPacket && (call->cwind <= (u_short) (conn->ackRate + 1)
4969                                 || (!(call->flags & RX_CALL_SLOW_START_OK)
4970                                     && (list[i]->header.seq & 1)))) {
4971                 requestAck = 1;
4972             }
4973         }
4974
4975         MUTEX_ENTER(&peer->peer_lock);
4976         peer->nSent++;
4977         if (resending)
4978             peer->reSends++;
4979         rx_MutexIncrement(rx_stats.dataPacketsSent, rx_stats_mutex);
4980         MUTEX_EXIT(&peer->peer_lock);
4981
4982         /* Tag this packet as not being the last in this group,
4983          * for the receiver's benefit */
4984         if (i < len - 1 || moreFlag) {
4985             list[i]->header.flags |= RX_MORE_PACKETS;
4986         }
4987
4988         /* Install the new retransmit time for the packet, and
4989          * record the time sent */
4990         list[i]->timeSent = *now;
4991     }
4992
4993     if (requestAck) {
4994         list[len - 1]->header.flags |= RX_REQUEST_ACK;
4995     }
4996
4997     /* Since we're about to send a data packet to the peer, it's
4998      * safe to nuke any scheduled end-of-packets ack */
4999     rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
5000
5001     CALL_HOLD(call, RX_CALL_REFCOUNT_SEND);
5002     MUTEX_EXIT(&call->lock);
5003     if (len > 1) {
5004         rxi_SendPacketList(call, conn, list, len, istack);
5005     } else {
5006         rxi_SendPacket(call, conn, list[0], istack);
5007     }
5008     MUTEX_ENTER(&call->lock);
5009     CALL_RELE(call, RX_CALL_REFCOUNT_SEND);
5010
5011     /* Update last send time for this call (for keep-alive
5012      * processing), and for the connection (so that we can discover
5013      * idle connections) */
5014     call->lastSendData = conn->lastSendTime = call->lastSendTime = clock_Sec();
5015 }
5016
5017 /* When sending packets we need to follow these rules:
5018  * 1. Never send more than maxDgramPackets in a jumbogram.
5019  * 2. Never send a packet with more than two iovecs in a jumbogram.
5020  * 3. Never send a retransmitted packet in a jumbogram.
5021  * 4. Never send more than cwind/4 packets in a jumbogram
5022  * We always keep the last list we should have sent so we
5023  * can set the RX_MORE_PACKETS flags correctly.
5024  */
5025 static void
5026 rxi_SendXmitList(struct rx_call *call, struct rx_packet **list, int len,
5027                  int istack, struct clock *now, struct clock *retryTime,
5028                  int resending)
5029 {
5030     int i, cnt, lastCnt = 0;
5031     struct rx_packet **listP, **lastP = 0;
5032     struct rx_peer *peer = call->conn->peer;
5033     int morePackets = 0;
5034
5035     for (cnt = 0, listP = &list[0], i = 0; i < len; i++) {
5036         /* Does the current packet force us to flush the current list? */
5037         if (cnt > 0
5038             && (list[i]->header.serial || (list[i]->flags & RX_PKTFLAG_ACKED)
5039                 || list[i]->length > RX_JUMBOBUFFERSIZE)) {
5040             if (lastCnt > 0) {
5041                 rxi_SendList(call, lastP, lastCnt, istack, 1, now, retryTime,
5042                              resending);
5043                 /* If the call enters an error state stop sending, or if
5044                  * we entered congestion recovery mode, stop sending */
5045                 if (call->error || (call->flags & RX_CALL_FAST_RECOVER_WAIT))
5046                     return;
5047             }
5048             lastP = listP;
5049             lastCnt = cnt;
5050             listP = &list[i];
5051             cnt = 0;
5052         }
5053         /* Add the current packet to the list if it hasn't been acked.
5054          * Otherwise adjust the list pointer to skip the current packet.  */
5055         if (!(list[i]->flags & RX_PKTFLAG_ACKED)) {
5056             cnt++;
5057             /* Do we need to flush the list? */
5058             if (cnt >= (int)peer->maxDgramPackets
5059                 || cnt >= (int)call->nDgramPackets || cnt >= (int)call->cwind
5060                 || list[i]->header.serial
5061                 || list[i]->length != RX_JUMBOBUFFERSIZE) {
5062                 if (lastCnt > 0) {
5063                     rxi_SendList(call, lastP, lastCnt, istack, 1, now,
5064                                  retryTime, resending);
5065                     /* If the call enters an error state stop sending, or if
5066                      * we entered congestion recovery mode, stop sending */
5067                     if (call->error
5068                         || (call->flags & RX_CALL_FAST_RECOVER_WAIT))
5069                         return;
5070                 }
5071                 lastP = listP;
5072                 lastCnt = cnt;
5073                 listP = &list[i + 1];
5074                 cnt = 0;
5075             }
5076         } else {
5077             if (cnt != 0) {
5078                 osi_Panic("rxi_SendList error");
5079             }
5080             listP = &list[i + 1];
5081         }
5082     }
5083
5084     /* Send the whole list when the call is in receive mode, when
5085      * the call is in eof mode, when we are in fast recovery mode,
5086      * and when we have the last packet */
5087     if ((list[len - 1]->header.flags & RX_LAST_PACKET)
5088         || call->mode == RX_MODE_RECEIVING || call->mode == RX_MODE_EOF
5089         || (call->flags & RX_CALL_FAST_RECOVER)) {
5090         /* Check for the case where the current list contains
5091          * an acked packet. Since we always send retransmissions
5092          * in a separate packet, we only need to check the first
5093          * packet in the list */
5094         if (cnt > 0 && !(listP[0]->flags & RX_PKTFLAG_ACKED)) {
5095             morePackets = 1;
5096         }
5097         if (lastCnt > 0) {
5098             rxi_SendList(call, lastP, lastCnt, istack, morePackets, now,
5099                          retryTime, resending);
5100             /* If the call enters an error state stop sending, or if
5101              * we entered congestion recovery mode, stop sending */
5102             if (call->error || (call->flags & RX_CALL_FAST_RECOVER_WAIT))
5103                 return;
5104         }
5105         if (morePackets) {
5106             rxi_SendList(call, listP, cnt, istack, 0, now, retryTime,
5107                          resending);
5108         }
5109     } else if (lastCnt > 0) {
5110         rxi_SendList(call, lastP, lastCnt, istack, 0, now, retryTime,
5111                      resending);
5112     }
5113 }
5114
5115 #ifdef  RX_ENABLE_LOCKS
5116 /* Call rxi_Start, below, but with the call lock held. */
5117 void
5118 rxi_StartUnlocked(struct rxevent *event, 
5119                   void *arg0, void *arg1, int istack)
5120 {
5121     struct rx_call *call = arg0;
5122     
5123     MUTEX_ENTER(&call->lock);
5124     rxi_Start(event, call, arg1, istack);
5125     MUTEX_EXIT(&call->lock);
5126 }
5127 #endif /* RX_ENABLE_LOCKS */
5128
5129 /* This routine is called when new packets are readied for
5130  * transmission and when retransmission may be necessary, or when the
5131  * transmission window or burst count are favourable.  This should be
5132  * better optimized for new packets, the usual case, now that we've
5133  * got rid of queues of send packets. XXXXXXXXXXX */
5134 void
5135 rxi_Start(struct rxevent *event, 
5136           void *arg0, void *arg1, int istack)
5137 {
5138     struct rx_call *call = arg0;
5139     
5140     struct rx_packet *p;
5141     register struct rx_packet *nxp;     /* Next pointer for queue_Scan */
5142     struct rx_peer *peer = call->conn->peer;
5143     struct clock now, usenow, retryTime;
5144     int haveEvent;
5145     int nXmitPackets;
5146     int maxXmitPackets;
5147     struct rx_packet **xmitList;
5148     int resending = 0;
5149
5150     /* If rxi_Start is being called as a result of a resend event,
5151      * then make sure that the event pointer is removed from the call
5152      * structure, since there is no longer a per-call retransmission
5153      * event pending. */
5154     if (event && event == call->resendEvent) {
5155         CALL_RELE(call, RX_CALL_REFCOUNT_RESEND);
5156         call->resendEvent = NULL;
5157         resending = 1;
5158         if (queue_IsEmpty(&call->tq)) {
5159             /* Nothing to do */
5160             return;
5161         }
5162         /* Timeouts trigger congestion recovery */
5163 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5164         if (call->flags & RX_CALL_FAST_RECOVER_WAIT) {
5165             /* someone else is waiting to start recovery */
5166             return;
5167         }
5168         call->flags |= RX_CALL_FAST_RECOVER_WAIT;
5169         rxi_WaitforTQBusy(call);
5170 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
5171         call->flags &= ~RX_CALL_FAST_RECOVER_WAIT;
5172         call->flags |= RX_CALL_FAST_RECOVER;
5173         if (peer->maxDgramPackets > 1) {
5174             call->MTU = RX_JUMBOBUFFERSIZE + RX_HEADER_SIZE;
5175         } else {
5176             call->MTU = MIN(peer->natMTU, peer->maxMTU);
5177         }
5178         call->ssthresh = MAX(4, MIN((int)call->cwind, (int)call->twind)) >> 1;
5179         call->nDgramPackets = 1;
5180         call->cwind = 1;
5181         call->nextCwind = 1;
5182         call->nAcks = 0;
5183         call->nNacks = 0;
5184         MUTEX_ENTER(&peer->peer_lock);
5185         peer->MTU = call->MTU;
5186         peer->cwind = call->cwind;
5187         peer->nDgramPackets = 1;
5188         peer->congestSeq++;
5189         call->congestSeq = peer->congestSeq;
5190         MUTEX_EXIT(&peer->peer_lock);
5191         /* Clear retry times on packets. Otherwise, it's possible for
5192          * some packets in the queue to force resends at rates faster
5193          * than recovery rates.
5194          */
5195         for (queue_Scan(&call->tq, p, nxp, rx_packet)) {
5196             if (!(p->flags & RX_PKTFLAG_ACKED)) {
5197                 clock_Zero(&p->retryTime);
5198             }
5199         }
5200     }
5201     if (call->error) {
5202 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5203         rx_MutexIncrement(rx_tq_debug.rxi_start_in_error, rx_stats_mutex);
5204 #endif
5205         return;
5206     }
5207
5208     if (queue_IsNotEmpty(&call->tq)) {  /* If we have anything to send */
5209         /* Get clock to compute the re-transmit time for any packets
5210          * in this burst.  Note, if we back off, it's reasonable to
5211          * back off all of the packets in the same manner, even if
5212          * some of them have been retransmitted more times than more
5213          * recent additions.
5214          * Do a dance to avoid blocking after setting now. */
5215         clock_Zero(&retryTime);
5216         MUTEX_ENTER(&peer->peer_lock);
5217         clock_Add(&retryTime, &peer->timeout);
5218         MUTEX_EXIT(&peer->peer_lock);
5219         clock_GetTime(&now);
5220         clock_Add(&retryTime, &now);
5221         usenow = now;
5222         /* Send (or resend) any packets that need it, subject to
5223          * window restrictions and congestion burst control
5224          * restrictions.  Ask for an ack on the last packet sent in
5225          * this burst.  For now, we're relying upon the window being
5226          * considerably bigger than the largest number of packets that
5227          * are typically sent at once by one initial call to
5228          * rxi_Start.  This is probably bogus (perhaps we should ask
5229          * for an ack when we're half way through the current
5230          * window?).  Also, for non file transfer applications, this
5231          * may end up asking for an ack for every packet.  Bogus. XXXX
5232          */
5233         /*
5234          * But check whether we're here recursively, and let the other guy
5235          * do the work.
5236          */
5237 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5238         if (!(call->flags & RX_CALL_TQ_BUSY)) {
5239             call->flags |= RX_CALL_TQ_BUSY;
5240             do {
5241 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
5242             restart:
5243 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5244                 call->flags &= ~RX_CALL_NEED_START;
5245 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
5246                 nXmitPackets = 0;
5247                 maxXmitPackets = MIN(call->twind, call->cwind);
5248                 xmitList = (struct rx_packet **)
5249 #if defined(KERNEL) && !defined(UKERNEL) && defined(AFS_FBSD80_ENV)
5250                     /* XXXX else we must drop any mtx we hold */
5251                     afs_osi_Alloc_NoSleep(maxXmitPackets * sizeof(struct rx_packet *));
5252 #else
5253                 osi_Alloc(maxXmitPackets * sizeof(struct rx_packet *));
5254 #endif
5255                 if (xmitList == NULL)
5256                     osi_Panic("rxi_Start, failed to allocate xmit list");
5257                 for (queue_Scan(&call->tq, p, nxp, rx_packet)) {
5258                     if (call->flags & RX_CALL_FAST_RECOVER_WAIT) {
5259                         /* We shouldn't be sending packets if a thread is waiting
5260                          * to initiate congestion recovery */
5261                         break;
5262                     }
5263                     if ((nXmitPackets)
5264                         && (call->flags & RX_CALL_FAST_RECOVER)) {
5265                         /* Only send one packet during fast recovery */
5266                         break;
5267                     }
5268                     if ((p->flags & RX_PKTFLAG_FREE)
5269                         || (!queue_IsEnd(&call->tq, nxp)
5270                             && (nxp->flags & RX_PKTFLAG_FREE))
5271                         || (p == (struct rx_packet *)&rx_freePacketQueue)
5272                         || (nxp == (struct rx_packet *)&rx_freePacketQueue)) {
5273                         osi_Panic("rxi_Start: xmit queue clobbered");
5274                     }
5275                     if (p->flags & RX_PKTFLAG_ACKED) {
5276                         /* Since we may block, don't trust this */
5277                         usenow.sec = usenow.usec = 0;
5278                         rx_MutexIncrement(rx_stats.ignoreAckedPacket, rx_stats_mutex);
5279                         continue;       /* Ignore this packet if it has been acknowledged */
5280                     }
5281
5282                     /* Turn off all flags except these ones, which are the same
5283                      * on each transmission */
5284                     p->header.flags &= RX_PRESET_FLAGS;
5285
5286                     if (p->header.seq >=
5287                         call->tfirst + MIN((int)call->twind,
5288                                            (int)(call->nSoftAcked +
5289                                                  call->cwind))) {
5290                         call->flags |= RX_CALL_WAIT_WINDOW_SEND;        /* Wait for transmit window */
5291                         /* Note: if we're waiting for more window space, we can
5292                          * still send retransmits; hence we don't return here, but
5293                          * break out to schedule a retransmit event */
5294                         dpf(("call %d waiting for window",
5295                              *(call->callNumber)));
5296                         break;
5297                     }
5298
5299                     /* Transmit the packet if it needs to be sent. */
5300                     if (!clock_Lt(&now, &p->retryTime)) {
5301                         if (nXmitPackets == maxXmitPackets) {
5302                             rxi_SendXmitList(call, xmitList, nXmitPackets, 
5303                                              istack, &now, &retryTime, 
5304                                              resending);
5305                             osi_Free(xmitList, maxXmitPackets * 
5306                                      sizeof(struct rx_packet *));
5307                             goto restart;
5308                         }
5309                         xmitList[nXmitPackets++] = p;
5310                     }
5311                 }
5312
5313                 /* xmitList now hold pointers to all of the packets that are
5314                  * ready to send. Now we loop to send the packets */
5315                 if (nXmitPackets > 0) {
5316                     rxi_SendXmitList(call, xmitList, nXmitPackets, istack,
5317                                      &now, &retryTime, resending);
5318                 }
5319                 osi_Free(xmitList,
5320                          maxXmitPackets * sizeof(struct rx_packet *));
5321
5322 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5323                 /*
5324                  * TQ references no longer protected by this flag; they must remain
5325                  * protected by the global lock.
5326                  */
5327                 if (call->flags & RX_CALL_FAST_RECOVER_WAIT) {
5328                     call->flags &= ~RX_CALL_TQ_BUSY;
5329                     if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
5330                         dpf(("call %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
5331 #ifdef RX_ENABLE_LOCKS
5332                         osirx_AssertMine(&call->lock, "rxi_Start start");
5333                         CV_BROADCAST(&call->cv_tq);
5334 #else /* RX_ENABLE_LOCKS */
5335                         osi_rxWakeup(&call->tq);
5336 #endif /* RX_ENABLE_LOCKS */
5337                     }
5338                     return;
5339                 }
5340                 if (call->error) {
5341                     /* We went into the error state while sending packets. Now is
5342                      * the time to reset the call. This will also inform the using
5343                      * process that the call is in an error state.
5344                      */
5345                     rx_MutexIncrement(rx_tq_debug.rxi_start_aborted, rx_stats_mutex);
5346                     call->flags &= ~RX_CALL_TQ_BUSY;
5347                     if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
5348                         dpf(("call %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
5349 #ifdef RX_ENABLE_LOCKS
5350                         osirx_AssertMine(&call->lock, "rxi_Start middle");
5351                         CV_BROADCAST(&call->cv_tq);
5352 #else /* RX_ENABLE_LOCKS */
5353                         osi_rxWakeup(&call->tq);
5354 #endif /* RX_ENABLE_LOCKS */
5355                     }
5356                     rxi_CallError(call, call->error);
5357                     return;
5358                 }
5359 #ifdef RX_ENABLE_LOCKS
5360                 if (call->flags & RX_CALL_TQ_SOME_ACKED) {
5361                     register int missing;
5362                     call->flags &= ~RX_CALL_TQ_SOME_ACKED;
5363                     /* Some packets have received acks. If they all have, we can clear
5364                      * the transmit queue.
5365                      */
5366                     for (missing =
5367                          0, queue_Scan(&call->tq, p, nxp, rx_packet)) {
5368                         if (p->header.seq < call->tfirst
5369                             && (p->flags & RX_PKTFLAG_ACKED)) {
5370                             queue_Remove(p);
5371                             rxi_FreePacket(p);
5372                         } else
5373                             missing = 1;
5374                     }
5375                     if (!missing)
5376                         call->flags |= RX_CALL_TQ_CLEARME;
5377                 }
5378 #endif /* RX_ENABLE_LOCKS */
5379                 /* Don't bother doing retransmits if the TQ is cleared. */
5380                 if (call->flags & RX_CALL_TQ_CLEARME) {
5381                     rxi_ClearTransmitQueue(call, 1);
5382                 } else
5383 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
5384                 {
5385
5386                     /* Always post a resend event, if there is anything in the
5387                      * queue, and resend is possible.  There should be at least
5388                      * one unacknowledged packet in the queue ... otherwise none
5389                      * of these packets should be on the queue in the first place.
5390                      */
5391                     if (call->resendEvent) {
5392                         /* Cancel the existing event and post a new one */
5393                         rxevent_Cancel(call->resendEvent, call,
5394                                        RX_CALL_REFCOUNT_RESEND);
5395                     }
5396
5397                     /* The retry time is the retry time on the first unacknowledged
5398                      * packet inside the current window */
5399                     for (haveEvent =
5400                          0, queue_Scan(&call->tq, p, nxp, rx_packet)) {
5401                         /* Don't set timers for packets outside the window */
5402                         if (p->header.seq >= call->tfirst + call->twind) {
5403                             break;
5404                         }
5405
5406                         if (!(p->flags & RX_PKTFLAG_ACKED)
5407                             && !clock_IsZero(&p->retryTime)) {
5408                             haveEvent = 1;
5409                             retryTime = p->retryTime;
5410                             break;
5411                         }
5412                     }
5413
5414                     /* Post a new event to re-run rxi_Start when retries may be needed */
5415                     if (haveEvent && !(call->flags & RX_CALL_NEED_START)) {
5416 #ifdef RX_ENABLE_LOCKS
5417                         CALL_HOLD(call, RX_CALL_REFCOUNT_RESEND);
5418                         call->resendEvent =
5419                             rxevent_PostNow2(&retryTime, &usenow, 
5420                                              rxi_StartUnlocked,
5421                                              (void *)call, 0, istack);
5422 #else /* RX_ENABLE_LOCKS */
5423                         call->resendEvent =
5424                             rxevent_PostNow2(&retryTime, &usenow, rxi_Start, 
5425                                              (void *)call, 0, istack);
5426 #endif /* RX_ENABLE_LOCKS */
5427                     }
5428                 }
5429 #ifdef  AFS_GLOBAL_RXLOCK_KERNEL
5430             } while (call->flags & RX_CALL_NEED_START);
5431             /*
5432              * TQ references no longer protected by this flag; they must remain
5433              * protected by the global lock.
5434              */
5435             call->flags &= ~RX_CALL_TQ_BUSY;
5436             if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
5437                 dpf(("call %x has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
5438 #ifdef RX_ENABLE_LOCKS
5439                 osirx_AssertMine(&call->lock, "rxi_Start end");
5440                 CV_BROADCAST(&call->cv_tq);
5441 #else /* RX_ENABLE_LOCKS */
5442                 osi_rxWakeup(&call->tq);
5443 #endif /* RX_ENABLE_LOCKS */
5444             }
5445         } else {
5446             call->flags |= RX_CALL_NEED_START;
5447         }
5448 #endif /* AFS_GLOBAL_RXLOCK_KERNEL */
5449     } else {
5450         if (call->resendEvent) {
5451             rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
5452         }
5453     }
5454 }
5455
5456 /* Also adjusts the keep alive parameters for the call, to reflect
5457  * that we have just sent a packet (so keep alives aren't sent
5458  * immediately) */
5459 void
5460 rxi_Send(register struct rx_call *call, register struct rx_packet *p,
5461          int istack)
5462 {
5463     register struct rx_connection *conn = call->conn;
5464
5465     /* Stamp each packet with the user supplied status */
5466     p->header.userStatus = call->localStatus;
5467
5468     /* Allow the security object controlling this call's security to
5469      * make any last-minute changes to the packet */
5470     RXS_SendPacket(conn->securityObject, call, p);
5471
5472     /* Since we're about to send SOME sort of packet to the peer, it's
5473      * safe to nuke any scheduled end-of-packets ack */
5474     rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
5475
5476     /* Actually send the packet, filling in more connection-specific fields */
5477     CALL_HOLD(call, RX_CALL_REFCOUNT_SEND);
5478     MUTEX_EXIT(&call->lock);
5479     rxi_SendPacket(call, conn, p, istack);
5480     MUTEX_ENTER(&call->lock);
5481     CALL_RELE(call, RX_CALL_REFCOUNT_SEND);
5482
5483     /* Update last send time for this call (for keep-alive
5484      * processing), and for the connection (so that we can discover
5485      * idle connections) */
5486     conn->lastSendTime = call->lastSendTime = clock_Sec();
5487     /* Don't count keepalives here, so idleness can be tracked. */
5488     if (p->header.type != RX_PACKET_TYPE_ACK)
5489         call->lastSendData = call->lastSendTime;
5490 }
5491
5492
5493 /* Check if a call needs to be destroyed.  Called by keep-alive code to ensure
5494  * that things are fine.  Also called periodically to guarantee that nothing
5495  * falls through the cracks (e.g. (error + dally) connections have keepalive
5496  * turned off.  Returns 0 if conn is well, -1 otherwise.  If otherwise, call
5497  *  may be freed!
5498  * haveCTLock Set if calling from rxi_ReapConnections
5499  */
5500 #ifdef RX_ENABLE_LOCKS
5501 int
5502 rxi_CheckCall(register struct rx_call *call, int haveCTLock)
5503 #else /* RX_ENABLE_LOCKS */
5504 int
5505 rxi_CheckCall(register struct rx_call *call)
5506 #endif                          /* RX_ENABLE_LOCKS */
5507 {
5508     register struct rx_connection *conn = call->conn;
5509     afs_uint32 now;
5510     afs_uint32 deadTime;
5511
5512 #ifdef RX_GLOBAL_RXLOCK_KERNEL
5513     if (call->flags & RX_CALL_TQ_BUSY) {
5514         /* Call is active and will be reset by rxi_Start if it's
5515          * in an error state.
5516          */
5517         return 0;
5518     }
5519 #endif
5520     /* dead time + RTT + 8*MDEV, rounded up to next second. */
5521     deadTime =
5522         (((afs_uint32) conn->secondsUntilDead << 10) +
5523          ((afs_uint32) conn->peer->rtt >> 3) +
5524          ((afs_uint32) conn->peer->rtt_dev << 1) + 1023) >> 10;
5525     now = clock_Sec();
5526     /* These are computed to the second (+- 1 second).  But that's
5527      * good enough for these values, which should be a significant
5528      * number of seconds. */
5529     if (now > (call->lastReceiveTime + deadTime)) {
5530         if (call->state == RX_STATE_ACTIVE) {
5531 #ifdef ADAPT_PMTU
5532 #if defined(KERNEL) && defined(AFS_SUN57_ENV)
5533             ire_t *ire;
5534 #if defined(AFS_SUN510_ENV) && defined(GLOBAL_NETSTACKID)
5535             netstack_t *ns =  netstack_find_by_stackid(GLOBAL_NETSTACKID);
5536             ip_stack_t *ipst = ns->netstack_ip;
5537 #endif
5538             ire = ire_cache_lookup(call->conn->peer->host
5539 #if defined(AFS_SUN510_ENV) && defined(ALL_ZONES)
5540                                    , ALL_ZONES
5541 #if defined(AFS_SUN510_ENV) && (defined(ICL_3_ARG) || defined(GLOBAL_NETSTACKID))
5542                                    , NULL
5543 #if defined(AFS_SUN510_ENV) && defined(GLOBAL_NETSTACKID)
5544                                    , ipst
5545 #endif
5546 #endif
5547 #endif
5548                 );
5549             
5550             if (ire && ire->ire_max_frag > 0)
5551                 rxi_SetPeerMtu(call->conn->peer->host, 0, ire->ire_max_frag);
5552 #if defined(GLOBAL_NETSTACKID)
5553             netstack_rele(ns);
5554 #endif
5555 #endif
5556 #endif /* ADAPT_PMTU */
5557             rxi_CallError(call, RX_CALL_DEAD);
5558             return -1;
5559         } else {
5560 #ifdef RX_ENABLE_LOCKS
5561             /* Cancel pending events */
5562             rxevent_Cancel(call->delayedAckEvent, call,
5563                            RX_CALL_REFCOUNT_DELAY);
5564             rxevent_Cancel(call->resendEvent, call, RX_CALL_REFCOUNT_RESEND);
5565             rxevent_Cancel(call->keepAliveEvent, call,
5566                            RX_CALL_REFCOUNT_ALIVE);
5567             if (call->refCount == 0) {
5568                 rxi_FreeCall(call, haveCTLock);
5569                 return -2;
5570             }
5571             return -1;
5572 #else /* RX_ENABLE_LOCKS */
5573             rxi_FreeCall(call);
5574             return -2;
5575 #endif /* RX_ENABLE_LOCKS */
5576         }
5577         /* Non-active calls are destroyed if they are not responding
5578          * to pings; active calls are simply flagged in error, so the
5579          * attached process can die reasonably gracefully. */
5580     }
5581     /* see if we have a non-activity timeout */
5582     if (call->startWait && conn->idleDeadTime
5583         && ((call->startWait + conn->idleDeadTime) < now)) {
5584         if (call->state == RX_STATE_ACTIVE) {
5585             rxi_CallError(call, RX_CALL_TIMEOUT);
5586             return -1;
5587         }
5588     }
5589     if (call->lastSendData && conn->idleDeadTime && (conn->idleDeadErr != 0)
5590         && ((call->lastSendData + conn->idleDeadTime) < now)) {
5591         if (call->state == RX_STATE_ACTIVE) {
5592             rxi_CallError(call, conn->idleDeadErr);
5593             return -1;
5594         }
5595     }
5596     /* see if we have a hard timeout */
5597     if (conn->hardDeadTime
5598         && (now > (conn->hardDeadTime + call->startTime.sec))) {
5599         if (call->state == RX_STATE_ACTIVE)
5600             rxi_CallError(call, RX_CALL_TIMEOUT);
5601         return -1;
5602     }
5603     return 0;
5604 }
5605
5606
5607 /* When a call is in progress, this routine is called occasionally to
5608  * make sure that some traffic has arrived (or been sent to) the peer.
5609  * If nothing has arrived in a reasonable amount of time, the call is
5610  * declared dead; if nothing has been sent for a while, we send a
5611  * keep-alive packet (if we're actually trying to keep the call alive)
5612  */
5613 void
5614 rxi_KeepAliveEvent(struct rxevent *event, void *arg1, void *dummy)
5615 {
5616     struct rx_call *call = arg1;
5617     struct rx_connection *conn;
5618     afs_uint32 now;
5619
5620     MUTEX_ENTER(&call->lock);
5621     CALL_RELE(call, RX_CALL_REFCOUNT_ALIVE);
5622     if (event == call->keepAliveEvent)
5623         call->keepAliveEvent = NULL;
5624     now = clock_Sec();
5625
5626 #ifdef RX_ENABLE_LOCKS
5627     if (rxi_CheckCall(call, 0)) {
5628         MUTEX_EXIT(&call->lock);
5629         return;
5630     }
5631 #else /* RX_ENABLE_LOCKS */
5632     if (rxi_CheckCall(call))
5633         return;
5634 #endif /* RX_ENABLE_LOCKS */
5635
5636     /* Don't try to keep alive dallying calls */
5637     if (call->state == RX_STATE_DALLY) {
5638         MUTEX_EXIT(&call->lock);
5639         return;
5640     }
5641
5642     conn = call->conn;
5643     if ((now - call->lastSendTime) > conn->secondsUntilPing) {
5644         /* Don't try to send keepalives if there is unacknowledged data */
5645         /* the rexmit code should be good enough, this little hack 
5646          * doesn't quite work XXX */
5647         (void)rxi_SendAck(call, NULL, 0, RX_ACK_PING, 0);
5648     }
5649     rxi_ScheduleKeepAliveEvent(call);
5650     MUTEX_EXIT(&call->lock);
5651 }
5652
5653
5654 void
5655 rxi_ScheduleKeepAliveEvent(register struct rx_call *call)
5656 {
5657     if (!call->keepAliveEvent) {
5658         struct clock when, now;
5659         clock_GetTime(&now);
5660         when = now;
5661         when.sec += call->conn->secondsUntilPing;
5662         CALL_HOLD(call, RX_CALL_REFCOUNT_ALIVE);
5663         call->keepAliveEvent =
5664             rxevent_PostNow(&when, &now, rxi_KeepAliveEvent, call, 0);
5665     }
5666 }
5667
5668 /* N.B. rxi_KeepAliveOff:  is defined earlier as a macro */
5669 void
5670 rxi_KeepAliveOn(register struct rx_call *call)
5671 {
5672     /* Pretend last packet received was received now--i.e. if another
5673      * packet isn't received within the keep alive time, then the call
5674      * will die; Initialize last send time to the current time--even
5675      * if a packet hasn't been sent yet.  This will guarantee that a
5676      * keep-alive is sent within the ping time */
5677     call->lastReceiveTime = call->lastSendTime = clock_Sec();
5678     rxi_ScheduleKeepAliveEvent(call);
5679 }
5680
5681 /* This routine is called to send connection abort messages
5682  * that have been delayed to throttle looping clients. */
5683 void
5684 rxi_SendDelayedConnAbort(struct rxevent *event,
5685                          void *arg1, void *unused)
5686 {
5687     struct rx_connection *conn = arg1;
5688     
5689     afs_int32 error;
5690     struct rx_packet *packet;
5691
5692     MUTEX_ENTER(&conn->conn_data_lock);
5693     conn->delayedAbortEvent = NULL;
5694     error = htonl(conn->error);
5695     conn->abortCount++;
5696     MUTEX_EXIT(&conn->conn_data_lock);
5697     packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
5698     if (packet) {
5699         packet =
5700             rxi_SendSpecial((struct rx_call *)0, conn, packet,
5701                             RX_PACKET_TYPE_ABORT, (char *)&error,
5702                             sizeof(error), 0);
5703         rxi_FreePacket(packet);
5704     }
5705 }
5706
5707 /* This routine is called to send call abort messages
5708  * that have been delayed to throttle looping clients. */
5709 void
5710 rxi_SendDelayedCallAbort(struct rxevent *event, 
5711                          void *arg1, void *dummy)
5712 {
5713     struct rx_call *call = arg1;
5714     
5715     afs_int32 error;
5716     struct rx_packet *packet;
5717
5718     MUTEX_ENTER(&call->lock);
5719     call->delayedAbortEvent = NULL;
5720     error = htonl(call->error);
5721     call->abortCount++;
5722     packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
5723     if (packet) {
5724         packet =
5725             rxi_SendSpecial(call, call->conn, packet, RX_PACKET_TYPE_ABORT,
5726                             (char *)&error, sizeof(error), 0);
5727         rxi_FreePacket(packet);
5728     }
5729     CALL_RELE(call, RX_CALL_REFCOUNT_ABORT);
5730     MUTEX_EXIT(&call->lock);
5731 }
5732
5733 /* This routine is called periodically (every RX_AUTH_REQUEST_TIMEOUT
5734  * seconds) to ask the client to authenticate itself.  The routine
5735  * issues a challenge to the client, which is obtained from the
5736  * security object associated with the connection */
5737 void
5738 rxi_ChallengeEvent(struct rxevent *event, 
5739                    void *arg0, void *arg1, int tries)
5740 {
5741     struct rx_connection *conn = arg0;
5742     
5743     conn->challengeEvent = NULL;
5744     if (RXS_CheckAuthentication(conn->securityObject, conn) != 0) {
5745         register struct rx_packet *packet;
5746         struct clock when, now;
5747
5748         if (tries <= 0) {
5749             /* We've failed to authenticate for too long.
5750              * Reset any calls waiting for authentication;
5751              * they are all in RX_STATE_PRECALL.
5752              */
5753             int i;
5754
5755             MUTEX_ENTER(&conn->conn_call_lock);
5756             for (i = 0; i < RX_MAXCALLS; i++) {
5757                 struct rx_call *call = conn->call[i];
5758                 if (call) {
5759                     MUTEX_ENTER(&call->lock);
5760                     if (call->state == RX_STATE_PRECALL) {
5761                         rxi_CallError(call, RX_CALL_DEAD);
5762                         rxi_SendCallAbort(call, NULL, 0, 0);
5763                     }
5764                     MUTEX_EXIT(&call->lock);
5765                 }
5766             }
5767             MUTEX_EXIT(&conn->conn_call_lock);
5768             return;
5769         }
5770
5771         packet = rxi_AllocPacket(RX_PACKET_CLASS_SPECIAL);
5772         if (packet) {
5773             /* If there's no packet available, do this later. */
5774             RXS_GetChallenge(conn->securityObject, conn, packet);
5775             rxi_SendSpecial((struct rx_call *)0, conn, packet,
5776                             RX_PACKET_TYPE_CHALLENGE, NULL, -1, 0);
5777             rxi_FreePacket(packet);
5778         }
5779         clock_GetTime(&now);
5780         when = now;
5781         when.sec += RX_CHALLENGE_TIMEOUT;
5782         conn->challengeEvent =
5783             rxevent_PostNow2(&when, &now, rxi_ChallengeEvent, conn, 0,
5784                          (tries - 1));
5785     }
5786 }
5787
5788 /* Call this routine to start requesting the client to authenticate
5789  * itself.  This will continue until authentication is established,
5790  * the call times out, or an invalid response is returned.  The
5791  * security object associated with the connection is asked to create
5792  * the challenge at this time.  N.B.  rxi_ChallengeOff is a macro,
5793  * defined earlier. */
5794 void
5795 rxi_ChallengeOn(register struct rx_connection *conn)
5796 {
5797     if (!conn->challengeEvent) {
5798         RXS_CreateChallenge(conn->securityObject, conn);
5799         rxi_ChallengeEvent(NULL, conn, 0, RX_CHALLENGE_MAXTRIES);
5800     };
5801 }
5802
5803
5804 /* Compute round trip time of the packet provided, in *rttp.
5805  */
5806
5807 /* rxi_ComputeRoundTripTime is called with peer locked. */
5808 /* sentp and/or peer may be null */
5809 void
5810 rxi_ComputeRoundTripTime(register struct rx_packet *p,
5811                          register struct clock *sentp,
5812                          register struct rx_peer *peer)
5813 {
5814     struct clock thisRtt, *rttp = &thisRtt;
5815
5816     register int rtt_timeout;
5817
5818     clock_GetTime(rttp);
5819
5820     if (clock_Lt(rttp, sentp)) {
5821         clock_Zero(rttp);
5822         return;                 /* somebody set the clock back, don't count this time. */
5823     }
5824     clock_Sub(rttp, sentp);
5825     MUTEX_ENTER(&rx_stats_mutex);
5826     if (clock_Lt(rttp, &rx_stats.minRtt))
5827         rx_stats.minRtt = *rttp;
5828     if (clock_Gt(rttp, &rx_stats.maxRtt)) {
5829         if (rttp->sec > 60) {
5830             MUTEX_EXIT(&rx_stats_mutex);
5831             return;             /* somebody set the clock ahead */
5832         }
5833         rx_stats.maxRtt = *rttp;
5834     }
5835     clock_Add(&rx_stats.totalRtt, rttp);
5836     rx_stats.nRttSamples++;
5837     MUTEX_EXIT(&rx_stats_mutex);
5838
5839     /* better rtt calculation courtesy of UMich crew (dave,larry,peter,?) */
5840
5841     /* Apply VanJacobson round-trip estimations */
5842     if (peer->rtt) {
5843         register int delta;
5844
5845         /*
5846          * srtt (peer->rtt) is in units of one-eighth-milliseconds.
5847          * srtt is stored as fixed point with 3 bits after the binary
5848          * point (i.e., scaled by 8). The following magic is
5849          * equivalent to the smoothing algorithm in rfc793 with an
5850          * alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed point).
5851          * srtt*8 = srtt*8 + rtt - srtt
5852          * srtt = srtt + rtt/8 - srtt/8
5853          */
5854
5855         delta = MSEC(rttp) - (peer->rtt >> 3);
5856         peer->rtt += delta;
5857
5858         /*
5859          * We accumulate a smoothed rtt variance (actually, a smoothed
5860          * mean difference), then set the retransmit timer to smoothed
5861          * rtt + 4 times the smoothed variance (was 2x in van's original
5862          * paper, but 4x works better for me, and apparently for him as
5863          * well).
5864          * rttvar is stored as
5865          * fixed point with 2 bits after the binary point (scaled by
5866          * 4).  The following is equivalent to rfc793 smoothing with
5867          * an alpha of .75 (rttvar = rttvar*3/4 + |delta| / 4).  This
5868          * replaces rfc793's wired-in beta.
5869          * dev*4 = dev*4 + (|actual - expected| - dev)
5870          */
5871
5872         if (delta < 0)
5873             delta = -delta;
5874
5875         delta -= (peer->rtt_dev >> 2);
5876         peer->rtt_dev += delta;
5877     } else {
5878         /* I don't have a stored RTT so I start with this value.  Since I'm
5879          * probably just starting a call, and will be pushing more data down
5880          * this, I expect congestion to increase rapidly.  So I fudge a 
5881          * little, and I set deviance to half the rtt.  In practice,
5882          * deviance tends to approach something a little less than
5883          * half the smoothed rtt. */
5884         peer->rtt = (MSEC(rttp) << 3) + 8;
5885         peer->rtt_dev = peer->rtt >> 2; /* rtt/2: they're scaled differently */
5886     }
5887     /* the timeout is RTT + 4*MDEV + 0.35 sec   This is because one end or
5888      * the other of these connections is usually in a user process, and can
5889      * be switched and/or swapped out.  So on fast, reliable networks, the
5890      * timeout would otherwise be too short.  
5891      */
5892     rtt_timeout = (peer->rtt >> 3) + peer->rtt_dev + 350;
5893     clock_Zero(&(peer->timeout));
5894     clock_Addmsec(&(peer->timeout), rtt_timeout);
5895
5896     dpf(("rxi_ComputeRoundTripTime(rtt=%d ms, srtt=%d ms, rtt_dev=%d ms, timeout=%d.%0.3d sec)\n", MSEC(rttp), peer->rtt >> 3, peer->rtt_dev >> 2, (peer->timeout.sec), (peer->timeout.usec)));
5897 }
5898
5899
5900 /* Find all server connections that have not been active for a long time, and
5901  * toss them */
5902 void
5903 rxi_ReapConnections(struct rxevent *unused, void *unused1, void *unused2)
5904 {
5905     struct clock now, when;
5906     clock_GetTime(&now);
5907
5908     /* Find server connection structures that haven't been used for
5909      * greater than rx_idleConnectionTime */
5910     {
5911         struct rx_connection **conn_ptr, **conn_end;
5912         int i, havecalls = 0;
5913         MUTEX_ENTER(&rx_connHashTable_lock);
5914         for (conn_ptr = &rx_connHashTable[0], conn_end =
5915              &rx_connHashTable[rx_hashTableSize]; conn_ptr < conn_end;
5916              conn_ptr++) {
5917             struct rx_connection *conn, *next;
5918             struct rx_call *call;
5919             int result;
5920
5921           rereap:
5922             for (conn = *conn_ptr; conn; conn = next) {
5923                 /* XXX -- Shouldn't the connection be locked? */
5924                 next = conn->next;
5925                 havecalls = 0;
5926                 for (i = 0; i < RX_MAXCALLS; i++) {
5927                     call = conn->call[i];
5928                     if (call) {
5929                         havecalls = 1;
5930                         MUTEX_ENTER(&call->lock);
5931 #ifdef RX_ENABLE_LOCKS
5932                         result = rxi_CheckCall(call, 1);
5933 #else /* RX_ENABLE_LOCKS */
5934                         result = rxi_CheckCall(call);
5935 #endif /* RX_ENABLE_LOCKS */
5936                         MUTEX_EXIT(&call->lock);
5937                         if (result == -2) {
5938                             /* If CheckCall freed the call, it might
5939                              * have destroyed  the connection as well,
5940                              * which screws up the linked lists.
5941                              */
5942                             goto rereap;
5943                         }
5944                     }
5945                 }
5946                 if (conn->type == RX_SERVER_CONNECTION) {
5947                     /* This only actually destroys the connection if
5948                      * there are no outstanding calls */
5949                     MUTEX_ENTER(&conn->conn_data_lock);
5950                     if (!havecalls && !conn->refCount
5951                         && ((conn->lastSendTime + rx_idleConnectionTime) <
5952                             now.sec)) {
5953                         conn->refCount++;       /* it will be decr in rx_DestroyConn */
5954                         MUTEX_EXIT(&conn->conn_data_lock);
5955 #ifdef RX_ENABLE_LOCKS
5956                         rxi_DestroyConnectionNoLock(conn);
5957 #else /* RX_ENABLE_LOCKS */
5958                         rxi_DestroyConnection(conn);
5959 #endif /* RX_ENABLE_LOCKS */
5960                     }
5961 #ifdef RX_ENABLE_LOCKS
5962                     else {
5963                         MUTEX_EXIT(&conn->conn_data_lock);
5964                     }
5965 #endif /* RX_ENABLE_LOCKS */
5966                 }
5967             }
5968         }
5969 #ifdef RX_ENABLE_LOCKS
5970         while (rx_connCleanup_list) {
5971             struct rx_connection *conn;
5972             conn = rx_connCleanup_list;
5973             rx_connCleanup_list = rx_connCleanup_list->next;
5974             MUTEX_EXIT(&rx_connHashTable_lock);
5975             rxi_CleanupConnection(conn);
5976             MUTEX_ENTER(&rx_connHashTable_lock);
5977         }
5978         MUTEX_EXIT(&rx_connHashTable_lock);
5979 #endif /* RX_ENABLE_LOCKS */
5980     }
5981
5982     /* Find any peer structures that haven't been used (haven't had an
5983      * associated connection) for greater than rx_idlePeerTime */
5984     {
5985         struct rx_peer **peer_ptr, **peer_end;
5986         int code;
5987         MUTEX_ENTER(&rx_rpc_stats);
5988         MUTEX_ENTER(&rx_peerHashTable_lock);
5989         for (peer_ptr = &rx_peerHashTable[0], peer_end =
5990              &rx_peerHashTable[rx_hashTableSize]; peer_ptr < peer_end;
5991              peer_ptr++) {
5992             struct rx_peer *peer, *next, *prev;
5993             for (prev = peer = *peer_ptr; peer; peer = next) {
5994                 next = peer->next;
5995                 code = MUTEX_TRYENTER(&peer->peer_lock);
5996                 if ((code) && (peer->refCount == 0)
5997                     && ((peer->idleWhen + rx_idlePeerTime) < now.sec)) {
5998                     rx_interface_stat_p rpc_stat, nrpc_stat;
5999                     size_t space;
6000                     MUTEX_EXIT(&peer->peer_lock);
6001                     MUTEX_DESTROY(&peer->peer_lock);
6002                     for (queue_Scan
6003                          (&peer->rpcStats, rpc_stat, nrpc_stat,
6004                           rx_interface_stat)) {
6005                         unsigned int num_funcs;
6006                         if (!rpc_stat)
6007                             break;
6008                         queue_Remove(&rpc_stat->queue_header);
6009                         queue_Remove(&rpc_stat->all_peers);
6010                         num_funcs = rpc_stat->stats[0].func_total;
6011                         space =
6012                             sizeof(rx_interface_stat_t) +
6013                             rpc_stat->stats[0].func_total *
6014                             sizeof(rx_function_entry_v1_t);
6015
6016                         rxi_Free(rpc_stat, space);
6017                         rxi_rpc_peer_stat_cnt -= num_funcs;
6018                     }
6019                     rxi_FreePeer(peer);
6020                     rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
6021                     if (peer == *peer_ptr) {
6022                         *peer_ptr = next;
6023                         prev = next;
6024                     } else
6025                         prev->next = next;
6026                 } else {
6027                     if (code) {
6028                         MUTEX_EXIT(&peer->peer_lock);
6029                     }
6030                     prev = peer;
6031                 }
6032             }
6033         }
6034         MUTEX_EXIT(&rx_peerHashTable_lock);
6035         MUTEX_EXIT(&rx_rpc_stats);
6036     }
6037
6038     /* THIS HACK IS A TEMPORARY HACK.  The idea is that the race condition in
6039      * rxi_AllocSendPacket, if it hits, will be handled at the next conn
6040      * GC, just below.  Really, we shouldn't have to keep moving packets from
6041      * one place to another, but instead ought to always know if we can
6042      * afford to hold onto a packet in its particular use.  */
6043     MUTEX_ENTER(&rx_freePktQ_lock);
6044     if (rx_waitingForPackets) {
6045         rx_waitingForPackets = 0;
6046 #ifdef  RX_ENABLE_LOCKS
6047         CV_BROADCAST(&rx_waitingForPackets_cv);
6048 #else
6049         osi_rxWakeup(&rx_waitingForPackets);
6050 #endif
6051     }
6052     MUTEX_EXIT(&rx_freePktQ_lock);
6053
6054     when = now;
6055     when.sec += RX_REAP_TIME;   /* Check every RX_REAP_TIME seconds */
6056     rxevent_Post(&when, rxi_ReapConnections, 0, 0);
6057 }
6058
6059
6060 /* rxs_Release - This isn't strictly necessary but, since the macro name from
6061  * rx.h is sort of strange this is better.  This is called with a security
6062  * object before it is discarded.  Each connection using a security object has
6063  * its own refcount to the object so it won't actually be freed until the last
6064  * connection is destroyed.
6065  *
6066  * This is the only rxs module call.  A hold could also be written but no one
6067  * needs it. */
6068
6069 int
6070 rxs_Release(struct rx_securityClass *aobj)
6071 {
6072     return RXS_Close(aobj);
6073 }
6074
6075 #ifdef ADAPT_WINDOW
6076 #define RXRATE_PKT_OH   (RX_HEADER_SIZE + RX_IPUDP_SIZE)
6077 #define RXRATE_SMALL_PKT    (RXRATE_PKT_OH + sizeof(struct rx_ackPacket))
6078 #define RXRATE_AVG_SMALL_PKT    (RXRATE_PKT_OH + (sizeof(struct rx_ackPacket)/2))
6079 #define RXRATE_LARGE_PKT    (RXRATE_SMALL_PKT + 256)
6080
6081 /* Adjust our estimate of the transmission rate to this peer, given
6082  * that the packet p was just acked. We can adjust peer->timeout and
6083  * call->twind. Pragmatically, this is called
6084  * only with packets of maximal length.
6085  * Called with peer and call locked.
6086  */
6087
6088 static void
6089 rxi_ComputeRate(register struct rx_peer *peer, register struct rx_call *call,
6090                 struct rx_packet *p, struct rx_packet *ackp, u_char ackReason)
6091 {
6092     afs_int32 xferSize, xferMs;
6093     register afs_int32 minTime;
6094     struct clock newTO;
6095
6096     /* Count down packets */
6097     if (peer->rateFlag > 0)
6098         peer->rateFlag--;
6099     /* Do nothing until we're enabled */
6100     if (peer->rateFlag != 0)
6101         return;
6102     if (!call->conn)
6103         return;
6104
6105     /* Count only when the ack seems legitimate */
6106     switch (ackReason) {
6107     case RX_ACK_REQUESTED:
6108         xferSize =
6109             p->length + RX_HEADER_SIZE + call->conn->securityMaxTrailerSize;
6110         xferMs = peer->rtt;
6111         break;
6112
6113     case RX_ACK_PING_RESPONSE:
6114         if (p)                  /* want the response to ping-request, not data send */
6115             return;
6116         clock_GetTime(&newTO);
6117         if (clock_Gt(&newTO, &call->pingRequestTime)) {
6118             clock_Sub(&newTO, &call->pingRequestTime);
6119             xferMs = (newTO.sec * 1000) + (newTO.usec / 1000);
6120         } else {
6121             return;
6122         }
6123         xferSize = rx_AckDataSize(rx_Window) + RX_HEADER_SIZE;
6124         break;
6125
6126     default:
6127         return;
6128     }
6129
6130     dpf(("CONG peer %lx/%u: sample (%s) size %ld, %ld ms (to %lu.%06lu, rtt %u, ps %u)", ntohl(peer->host), ntohs(peer->port), (ackReason == RX_ACK_REQUESTED ? "dataack" : "pingack"), xferSize, xferMs, peer->timeout.sec, peer->timeout.usec, peer->smRtt, peer->ifMTU));
6131
6132     /* Track only packets that are big enough. */
6133     if ((p->length + RX_HEADER_SIZE + call->conn->securityMaxTrailerSize) <
6134         peer->ifMTU)
6135         return;
6136
6137     /* absorb RTT data (in milliseconds) for these big packets */
6138     if (peer->smRtt == 0) {
6139         peer->smRtt = xferMs;
6140     } else {
6141         peer->smRtt = ((peer->smRtt * 15) + xferMs + 4) >> 4;
6142         if (!peer->smRtt)
6143             peer->smRtt = 1;
6144     }
6145
6146     if (peer->countDown) {
6147         peer->countDown--;
6148         return;
6149     }
6150     peer->countDown = 10;       /* recalculate only every so often */
6151
6152     /* In practice, we can measure only the RTT for full packets,
6153      * because of the way Rx acks the data that it receives.  (If it's
6154      * smaller than a full packet, it often gets implicitly acked
6155      * either by the call response (from a server) or by the next call
6156      * (from a client), and either case confuses transmission times
6157      * with processing times.)  Therefore, replace the above
6158      * more-sophisticated processing with a simpler version, where the
6159      * smoothed RTT is kept for full-size packets, and the time to
6160      * transmit a windowful of full-size packets is simply RTT *
6161      * windowSize. Again, we take two steps:
6162      - ensure the timeout is large enough for a single packet's RTT;
6163      - ensure that the window is small enough to fit in the desired timeout.*/
6164
6165     /* First, the timeout check. */
6166     minTime = peer->smRtt;
6167     /* Get a reasonable estimate for a timeout period */
6168     minTime += minTime;
6169     newTO.sec = minTime / 1000;
6170     newTO.usec = (minTime - (newTO.sec * 1000)) * 1000;
6171
6172     /* Increase the timeout period so that we can always do at least
6173      * one packet exchange */
6174     if (clock_Gt(&newTO, &peer->timeout)) {
6175
6176         dpf(("CONG peer %lx/%u: timeout %lu.%06lu ==> %lu.%06lu (rtt %u, ps %u)", ntohl(peer->host), ntohs(peer->port), peer->timeout.sec, peer->timeout.usec, newTO.sec, newTO.usec, peer->smRtt, peer->packetSize));
6177
6178         peer->timeout = newTO;
6179     }
6180
6181     /* Now, get an estimate for the transmit window size. */
6182     minTime = peer->timeout.sec * 1000 + (peer->timeout.usec / 1000);
6183     /* Now, convert to the number of full packets that could fit in a
6184      * reasonable fraction of that interval */
6185     minTime /= (peer->smRtt << 1);
6186     xferSize = minTime;         /* (make a copy) */
6187
6188     /* Now clamp the size to reasonable bounds. */
6189     if (minTime <= 1)
6190         minTime = 1;
6191     else if (minTime > rx_Window)
6192         minTime = rx_Window;
6193 /*    if (minTime != peer->maxWindow) {
6194       dpf(("CONG peer %lx/%u: windowsize %lu ==> %lu (to %lu.%06lu, rtt %u, ps %u)",
6195              ntohl(peer->host), ntohs(peer->port), peer->maxWindow, minTime,
6196              peer->timeout.sec, peer->timeout.usec, peer->smRtt,
6197              peer->packetSize));
6198       peer->maxWindow = minTime;
6199         elide... call->twind = minTime; 
6200     }
6201 */
6202
6203     /* Cut back on the peer timeout if it had earlier grown unreasonably.
6204      * Discern this by calculating the timeout necessary for rx_Window
6205      * packets. */
6206     if ((xferSize > rx_Window) && (peer->timeout.sec >= 3)) {
6207         /* calculate estimate for transmission interval in milliseconds */
6208         minTime = rx_Window * peer->smRtt;
6209         if (minTime < 1000) {
6210             dpf(("CONG peer %lx/%u: cut TO %lu.%06lu by 0.5 (rtt %u, ps %u)",
6211                  ntohl(peer->host), ntohs(peer->port), peer->timeout.sec,
6212                  peer->timeout.usec, peer->smRtt, peer->packetSize));
6213
6214             newTO.sec = 0;      /* cut back on timeout by half a second */
6215             newTO.usec = 500000;
6216             clock_Sub(&peer->timeout, &newTO);
6217         }
6218     }
6219
6220     return;
6221 }                               /* end of rxi_ComputeRate */
6222 #endif /* ADAPT_WINDOW */
6223
6224
6225 #ifdef RXDEBUG
6226 void
6227 rxi_DebugInit(void)
6228 {
6229 #ifdef AFS_NT40_ENV
6230 #define TRACE_OPTION_DEBUGLOG 4
6231     HKEY parmKey;
6232     DWORD dummyLen;
6233     DWORD TraceOption;
6234     long code;
6235
6236     rxdebug_active = 0;
6237
6238     code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
6239                          0, KEY_QUERY_VALUE, &parmKey);
6240     if (code != ERROR_SUCCESS)
6241         return;
6242
6243     dummyLen = sizeof(TraceOption);
6244     code = RegQueryValueEx(parmKey, "TraceOption", NULL, NULL,
6245                            (BYTE *) &TraceOption, &dummyLen);
6246     if (code == ERROR_SUCCESS) {
6247         rxdebug_active = (TraceOption & TRACE_OPTION_DEBUGLOG) ? 1 : 0;
6248     }
6249     RegCloseKey (parmKey);
6250 #endif /* AFS_NT40_ENV */
6251 }
6252
6253 #ifdef AFS_NT40_ENV
6254 void
6255 rx_DebugOnOff(int on)
6256 {
6257     rxdebug_active = on;
6258 }
6259 #endif /* AFS_NT40_ENV */
6260
6261
6262 /* Don't call this debugging routine directly; use dpf */
6263 void
6264 rxi_DebugPrint(char *format, int a1, int a2, int a3, int a4, int a5, int a6,
6265                int a7, int a8, int a9, int a10, int a11, int a12, int a13,
6266                int a14, int a15)
6267 {
6268 #ifdef AFS_NT40_ENV
6269     char msg[512];
6270     char tformat[256];
6271     size_t len;
6272
6273     len = _snprintf(tformat, sizeof(tformat), "tid[%d] %s", GetCurrentThreadId(), format);
6274
6275     if (len > 0) {
6276         len = _snprintf(msg, sizeof(msg)-2, 
6277                         tformat, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 
6278                         a11, a12, a13, a14, a15);
6279         if (len > 0) {
6280             if (msg[len-1] != '\n') {
6281                 msg[len] = '\n';
6282                 msg[len+1] = '\0';
6283             }
6284             OutputDebugString(msg);
6285         }
6286     }
6287 #else
6288     struct clock now;
6289     clock_GetTime(&now);
6290     fprintf(rx_Log, " %u.%.3u:", (unsigned int)now.sec,
6291             (unsigned int)now.usec / 1000);
6292     fprintf(rx_Log, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
6293             a13, a14, a15);
6294     putc('\n', rx_Log);
6295 #endif
6296 }
6297
6298 /*
6299  * This function is used to process the rx_stats structure that is local
6300  * to a process as well as an rx_stats structure received from a remote
6301  * process (via rxdebug).  Therefore, it needs to do minimal version
6302  * checking.
6303  */
6304 void
6305 rx_PrintTheseStats(FILE * file, struct rx_stats *s, int size,
6306                    afs_int32 freePackets, char version)
6307 {
6308     int i;
6309
6310     if (size != sizeof(struct rx_stats)) {
6311         fprintf(file,
6312                 "Unexpected size of stats structure: was %d, expected %lud\n",
6313                 size, sizeof(struct rx_stats));
6314     }
6315
6316     fprintf(file, "rx stats: free packets %d, allocs %d, ", (int)freePackets,
6317             s->packetRequests);
6318
6319     if (version >= RX_DEBUGI_VERSION_W_NEWPACKETTYPES) {
6320         fprintf(file, "alloc-failures(rcv %d/%d,send %d/%d,ack %d)\n",
6321                 s->receivePktAllocFailures, s->receiveCbufPktAllocFailures,
6322                 s->sendPktAllocFailures, s->sendCbufPktAllocFailures,
6323                 s->specialPktAllocFailures);
6324     } else {
6325         fprintf(file, "alloc-failures(rcv %d,send %d,ack %d)\n",
6326                 s->receivePktAllocFailures, s->sendPktAllocFailures,
6327                 s->specialPktAllocFailures);
6328     }
6329
6330     fprintf(file,
6331             "   greedy %d, " "bogusReads %d (last from host %x), "
6332             "noPackets %d, " "noBuffers %d, " "selects %d, "
6333             "sendSelects %d\n", s->socketGreedy, s->bogusPacketOnRead,
6334             s->bogusHost, s->noPacketOnRead, s->noPacketBuffersOnRead,
6335             s->selects, s->sendSelects);
6336
6337     fprintf(file, "   packets read: ");
6338     for (i = 0; i < RX_N_PACKET_TYPES; i++) {
6339         fprintf(file, "%s %d ", rx_packetTypes[i], s->packetsRead[i]);
6340     }
6341     fprintf(file, "\n");
6342
6343     fprintf(file,
6344             "   other read counters: data %d, " "ack %d, " "dup %d "
6345             "spurious %d " "dally %d\n", s->dataPacketsRead,
6346             s->ackPacketsRead, s->dupPacketsRead, s->spuriousPacketsRead,
6347             s->ignorePacketDally);
6348
6349     fprintf(file, "   packets sent: ");
6350     for (i = 0; i < RX_N_PACKET_TYPES; i++) {
6351         fprintf(file, "%s %d ", rx_packetTypes[i], s->packetsSent[i]);
6352     }
6353     fprintf(file, "\n");
6354
6355     fprintf(file,
6356             "   other send counters: ack %d, " "data %d (not resends), "
6357             "resends %d, " "pushed %d, " "acked&ignored %d\n",
6358             s->ackPacketsSent, s->dataPacketsSent, s->dataPacketsReSent,
6359             s->dataPacketsPushed, s->ignoreAckedPacket);
6360
6361     fprintf(file,
6362             "   \t(these should be small) sendFailed %d, " "fatalErrors %d\n",
6363             s->netSendFailures, (int)s->fatalErrors);
6364
6365     if (s->nRttSamples) {
6366         fprintf(file, "   Average rtt is %0.3f, with %d samples\n",
6367                 clock_Float(&s->totalRtt) / s->nRttSamples, s->nRttSamples);
6368
6369         fprintf(file, "   Minimum rtt is %0.3f, maximum is %0.3f\n",
6370                 clock_Float(&s->minRtt), clock_Float(&s->maxRtt));
6371     }
6372
6373     fprintf(file,
6374             "   %d server connections, " "%d client connections, "
6375             "%d peer structs, " "%d call structs, " "%d free call structs\n",
6376             s->nServerConns, s->nClientConns, s->nPeerStructs,
6377             s->nCallStructs, s->nFreeCallStructs);
6378
6379 #if     !defined(AFS_PTHREAD_ENV) && !defined(AFS_USE_GETTIMEOFDAY)
6380     fprintf(file, "   %d clock updates\n", clock_nUpdates);
6381 #endif
6382
6383 }
6384
6385 /* for backward compatibility */
6386 void
6387 rx_PrintStats(FILE * file)
6388 {
6389     MUTEX_ENTER(&rx_stats_mutex);
6390     rx_PrintTheseStats(file, &rx_stats, sizeof(rx_stats), rx_nFreePackets,
6391                        RX_DEBUGI_VERSION);
6392     MUTEX_EXIT(&rx_stats_mutex);
6393 }
6394
6395 void
6396 rx_PrintPeerStats(FILE * file, struct rx_peer *peer)
6397 {
6398     fprintf(file, "Peer %x.%d.  " "Burst size %d, " "burst wait %u.%d.\n",
6399             ntohl(peer->host), (int)peer->port, (int)peer->burstSize,
6400             (int)peer->burstWait.sec, (int)peer->burstWait.usec);
6401
6402     fprintf(file,
6403             "   Rtt %d, " "retry time %u.%06d, " "total sent %d, "
6404             "resent %d\n", peer->rtt, (int)peer->timeout.sec,
6405             (int)peer->timeout.usec, peer->nSent, peer->reSends);
6406
6407     fprintf(file,
6408             "   Packet size %d, " "max in packet skew %d, "
6409             "max out packet skew %d\n", peer->ifMTU, (int)peer->inPacketSkew,
6410             (int)peer->outPacketSkew);
6411 }
6412
6413 #ifdef AFS_PTHREAD_ENV
6414 /*
6415  * This mutex protects the following static variables:
6416  * counter
6417  */
6418
6419 #define LOCK_RX_DEBUG assert(pthread_mutex_lock(&rx_debug_mutex)==0)
6420 #define UNLOCK_RX_DEBUG assert(pthread_mutex_unlock(&rx_debug_mutex)==0)
6421 #else
6422 #define LOCK_RX_DEBUG
6423 #define UNLOCK_RX_DEBUG
6424 #endif /* AFS_PTHREAD_ENV */
6425
6426 static int
6427 MakeDebugCall(osi_socket socket, afs_uint32 remoteAddr, afs_uint16 remotePort,
6428               u_char type, void *inputData, size_t inputLength,
6429               void *outputData, size_t outputLength)
6430 {
6431     static afs_int32 counter = 100;
6432     time_t waitTime, waitCount, startTime;
6433     struct rx_header theader;
6434     char tbuffer[1500];
6435     register afs_int32 code;
6436     struct timeval tv_now, tv_wake, tv_delta;
6437     struct sockaddr_in taddr, faddr;
6438 #ifdef AFS_NT40_ENV
6439     int faddrLen;
6440 #else
6441     socklen_t faddrLen;
6442 #endif
6443     fd_set imask;
6444     register char *tp;
6445
6446     startTime = time(0);
6447     waitTime = 1;
6448     waitCount = 5;
6449     LOCK_RX_DEBUG;
6450     counter++;
6451     UNLOCK_RX_DEBUG;
6452     tp = &tbuffer[sizeof(struct rx_header)];
6453     taddr.sin_family = AF_INET;
6454     taddr.sin_port = remotePort;
6455     taddr.sin_addr.s_addr = remoteAddr;
6456 #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
6457     taddr.sin_len = sizeof(struct sockaddr_in);
6458 #endif
6459     while (1) {
6460         memset(&theader, 0, sizeof(theader));
6461         theader.epoch = htonl(999);
6462         theader.cid = 0;
6463         theader.callNumber = htonl(counter);
6464         theader.seq = 0;
6465         theader.serial = 0;
6466         theader.type = type;
6467         theader.flags = RX_CLIENT_INITIATED | RX_LAST_PACKET;
6468         theader.serviceId = 0;
6469
6470         memcpy(tbuffer, &theader, sizeof(theader));
6471         memcpy(tp, inputData, inputLength);
6472         code =
6473             sendto(socket, tbuffer, inputLength + sizeof(struct rx_header), 0,
6474                    (struct sockaddr *)&taddr, sizeof(struct sockaddr_in));
6475
6476         /* see if there's a packet available */
6477         gettimeofday(&tv_wake,0);
6478         tv_wake.tv_sec += waitTime;
6479         for (;;) {
6480             FD_ZERO(&imask);
6481             FD_SET(socket, &imask);
6482             tv_delta.tv_sec = tv_wake.tv_sec;
6483             tv_delta.tv_usec = tv_wake.tv_usec;
6484             gettimeofday(&tv_now, 0);
6485             
6486             if (tv_delta.tv_usec < tv_now.tv_usec) {
6487                 /* borrow */
6488                 tv_delta.tv_usec += 1000000;
6489                 tv_delta.tv_sec--;
6490             }
6491             tv_delta.tv_usec -= tv_now.tv_usec;
6492             
6493             if (tv_delta.tv_sec < tv_now.tv_sec) {
6494                 /* time expired */
6495                 break;
6496             }
6497             tv_delta.tv_sec -= tv_now.tv_sec;
6498             
6499             code = select(socket + 1, &imask, 0, 0, &tv_delta);
6500             if (code == 1 && FD_ISSET(socket, &imask)) {
6501                 /* now receive a packet */
6502                 faddrLen = sizeof(struct sockaddr_in);
6503                 code =
6504                     recvfrom(socket, tbuffer, sizeof(tbuffer), 0,
6505                              (struct sockaddr *)&faddr, &faddrLen);
6506                 
6507                 if (code > 0) {
6508                     memcpy(&theader, tbuffer, sizeof(struct rx_header));
6509                     if (counter == ntohl(theader.callNumber))
6510                         goto success;
6511                     continue;
6512                 }
6513             }
6514             break;
6515         }
6516
6517         /* see if we've timed out */
6518         if (!--waitCount) {
6519             return -1;
6520         }
6521         waitTime <<= 1;
6522     }
6523     
6524  success:
6525     code -= sizeof(struct rx_header);
6526     if (code > outputLength)
6527         code = outputLength;
6528     memcpy(outputData, tp, code);
6529     return code;
6530 }
6531
6532 afs_int32
6533 rx_GetServerDebug(osi_socket socket, afs_uint32 remoteAddr,
6534                   afs_uint16 remotePort, struct rx_debugStats * stat,
6535                   afs_uint32 * supportedValues)
6536 {
6537     struct rx_debugIn in;
6538     afs_int32 rc = 0;
6539
6540     *supportedValues = 0;
6541     in.type = htonl(RX_DEBUGI_GETSTATS);
6542     in.index = 0;
6543
6544     rc = MakeDebugCall(socket, remoteAddr, remotePort, RX_PACKET_TYPE_DEBUG,
6545                        &in, sizeof(in), stat, sizeof(*stat));
6546
6547     /*
6548      * If the call was successful, fixup the version and indicate
6549      * what contents of the stat structure are valid.
6550      * Also do net to host conversion of fields here.
6551      */
6552
6553     if (rc >= 0) {
6554         if (stat->version >= RX_DEBUGI_VERSION_W_SECSTATS) {
6555             *supportedValues |= RX_SERVER_DEBUG_SEC_STATS;
6556         }
6557         if (stat->version >= RX_DEBUGI_VERSION_W_GETALLCONN) {
6558             *supportedValues |= RX_SERVER_DEBUG_ALL_CONN;
6559         }
6560         if (stat->version >= RX_DEBUGI_VERSION_W_RXSTATS) {
6561             *supportedValues |= RX_SERVER_DEBUG_RX_STATS;
6562         }
6563         if (stat->version >= RX_DEBUGI_VERSION_W_WAITERS) {
6564             *supportedValues |= RX_SERVER_DEBUG_WAITER_CNT;
6565         }
6566         if (stat->version >= RX_DEBUGI_VERSION_W_IDLETHREADS) {
6567             *supportedValues |= RX_SERVER_DEBUG_IDLE_THREADS;
6568         }
6569         if (stat->version >= RX_DEBUGI_VERSION_W_NEWPACKETTYPES) {
6570             *supportedValues |= RX_SERVER_DEBUG_NEW_PACKETS;
6571         }
6572         if (stat->version >= RX_DEBUGI_VERSION_W_GETPEER) {
6573             *supportedValues |= RX_SERVER_DEBUG_ALL_PEER;
6574         }
6575         if (stat->version >= RX_DEBUGI_VERSION_W_WAITED) {
6576             *supportedValues |= RX_SERVER_DEBUG_WAITED_CNT;
6577         }
6578
6579         stat->nFreePackets = ntohl(stat->nFreePackets);
6580         stat->packetReclaims = ntohl(stat->packetReclaims);
6581         stat->callsExecuted = ntohl(stat->callsExecuted);
6582         stat->nWaiting = ntohl(stat->nWaiting);
6583         stat->idleThreads = ntohl(stat->idleThreads);
6584     }
6585
6586     return rc;
6587 }
6588
6589 afs_int32
6590 rx_GetServerStats(osi_socket socket, afs_uint32 remoteAddr,
6591                   afs_uint16 remotePort, struct rx_stats * stat,
6592                   afs_uint32 * supportedValues)
6593 {
6594     struct rx_debugIn in;
6595     afs_int32 *lp = (afs_int32 *) stat;
6596     int i;
6597     afs_int32 rc = 0;
6598
6599     /*
6600      * supportedValues is currently unused, but added to allow future
6601      * versioning of this function.
6602      */
6603
6604     *supportedValues = 0;
6605     in.type = htonl(RX_DEBUGI_RXSTATS);
6606     in.index = 0;
6607     memset(stat, 0, sizeof(*stat));
6608
6609     rc = MakeDebugCall(socket, remoteAddr, remotePort, RX_PACKET_TYPE_DEBUG,
6610                        &in, sizeof(in), stat, sizeof(*stat));
6611
6612     if (rc >= 0) {
6613
6614         /*
6615          * Do net to host conversion here
6616          */
6617
6618         for (i = 0; i < sizeof(*stat) / sizeof(afs_int32); i++, lp++) {
6619             *lp = ntohl(*lp);
6620         }
6621     }
6622
6623     return rc;
6624 }
6625
6626 afs_int32
6627 rx_GetServerVersion(osi_socket socket, afs_uint32 remoteAddr,
6628                     afs_uint16 remotePort, size_t version_length,
6629                     char *version)
6630 {
6631     char a[1] = { 0 };
6632     return MakeDebugCall(socket, remoteAddr, remotePort,
6633                          RX_PACKET_TYPE_VERSION, a, 1, version,
6634                          version_length);
6635 }
6636
6637 afs_int32
6638 rx_GetServerConnections(osi_socket socket, afs_uint32 remoteAddr,
6639                         afs_uint16 remotePort, afs_int32 * nextConnection,
6640                         int allConnections, afs_uint32 debugSupportedValues,
6641                         struct rx_debugConn * conn,
6642                         afs_uint32 * supportedValues)
6643 {
6644     struct rx_debugIn in;
6645     afs_int32 rc = 0;
6646     int i;
6647
6648     /*
6649      * supportedValues is currently unused, but added to allow future
6650      * versioning of this function.
6651      */
6652
6653     *supportedValues = 0;
6654     if (allConnections) {
6655         in.type = htonl(RX_DEBUGI_GETALLCONN);
6656     } else {
6657         in.type = htonl(RX_DEBUGI_GETCONN);
6658     }
6659     in.index = htonl(*nextConnection);
6660     memset(conn, 0, sizeof(*conn));
6661
6662     rc = MakeDebugCall(socket, remoteAddr, remotePort, RX_PACKET_TYPE_DEBUG,
6663                        &in, sizeof(in), conn, sizeof(*conn));
6664
6665     if (rc >= 0) {
6666         *nextConnection += 1;
6667
6668         /*
6669          * Convert old connection format to new structure.
6670          */
6671
6672         if (debugSupportedValues & RX_SERVER_DEBUG_OLD_CONN) {
6673             struct rx_debugConn_vL *vL = (struct rx_debugConn_vL *)conn;
6674 #define MOVEvL(a) (conn->a = vL->a)
6675
6676             /* any old or unrecognized version... */
6677             for (i = 0; i < RX_MAXCALLS; i++) {
6678                 MOVEvL(callState[i]);
6679                 MOVEvL(callMode[i]);
6680                 MOVEvL(callFlags[i]);
6681                 MOVEvL(callOther[i]);
6682             }
6683             if (debugSupportedValues & RX_SERVER_DEBUG_SEC_STATS) {
6684                 MOVEvL(secStats.type);
6685                 MOVEvL(secStats.level);
6686                 MOVEvL(secStats.flags);
6687                 MOVEvL(secStats.expires);
6688                 MOVEvL(secStats.packetsReceived);
6689                 MOVEvL(secStats.packetsSent);
6690                 MOVEvL(secStats.bytesReceived);
6691                 MOVEvL(secStats.bytesSent);
6692             }
6693         }
6694
6695         /*
6696          * Do net to host conversion here
6697          * NOTE:
6698          *    I don't convert host or port since we are most likely
6699          *    going to want these in NBO.
6700          */
6701         conn->cid = ntohl(conn->cid);
6702         conn->serial = ntohl(conn->serial);
6703         for (i = 0; i < RX_MAXCALLS; i++) {
6704             conn->callNumber[i] = ntohl(conn->callNumber[i]);
6705         }
6706         conn->error = ntohl(conn->error);
6707         conn->secStats.flags = ntohl(conn->secStats.flags);
6708         conn->secStats.expires = ntohl(conn->secStats.expires);
6709         conn->secStats.packetsReceived =
6710             ntohl(conn->secStats.packetsReceived);
6711         conn->secStats.packetsSent = ntohl(conn->secStats.packetsSent);
6712         conn->secStats.bytesReceived = ntohl(conn->secStats.bytesReceived);
6713         conn->secStats.bytesSent = ntohl(conn->secStats.bytesSent);
6714         conn->epoch = ntohl(conn->epoch);
6715         conn->natMTU = ntohl(conn->natMTU);
6716     }
6717
6718     return rc;
6719 }
6720
6721 afs_int32
6722 rx_GetServerPeers(osi_socket socket, afs_uint32 remoteAddr,
6723                   afs_uint16 remotePort, afs_int32 * nextPeer,
6724                   afs_uint32 debugSupportedValues, struct rx_debugPeer * peer,
6725                   afs_uint32 * supportedValues)
6726 {
6727     struct rx_debugIn in;
6728     afs_int32 rc = 0;
6729
6730     /*
6731      * supportedValues is currently unused, but added to allow future
6732      * versioning of this function.
6733      */
6734
6735     *supportedValues = 0;
6736     in.type = htonl(RX_DEBUGI_GETPEER);
6737     in.index = htonl(*nextPeer);
6738     memset(peer, 0, sizeof(*peer));
6739
6740     rc = MakeDebugCall(socket, remoteAddr, remotePort, RX_PACKET_TYPE_DEBUG,
6741                        &in, sizeof(in), peer, sizeof(*peer));
6742
6743     if (rc >= 0) {
6744         *nextPeer += 1;
6745
6746         /*
6747          * Do net to host conversion here
6748          * NOTE:
6749          *    I don't convert host or port since we are most likely
6750          *    going to want these in NBO.
6751          */
6752         peer->ifMTU = ntohs(peer->ifMTU);
6753         peer->idleWhen = ntohl(peer->idleWhen);
6754         peer->refCount = ntohs(peer->refCount);
6755         peer->burstWait.sec = ntohl(peer->burstWait.sec);
6756         peer->burstWait.usec = ntohl(peer->burstWait.usec);
6757         peer->rtt = ntohl(peer->rtt);
6758         peer->rtt_dev = ntohl(peer->rtt_dev);
6759         peer->timeout.sec = ntohl(peer->timeout.sec);
6760         peer->timeout.usec = ntohl(peer->timeout.usec);
6761         peer->nSent = ntohl(peer->nSent);
6762         peer->reSends = ntohl(peer->reSends);
6763         peer->inPacketSkew = ntohl(peer->inPacketSkew);
6764         peer->outPacketSkew = ntohl(peer->outPacketSkew);
6765         peer->rateFlag = ntohl(peer->rateFlag);
6766         peer->natMTU = ntohs(peer->natMTU);
6767         peer->maxMTU = ntohs(peer->maxMTU);
6768         peer->maxDgramPackets = ntohs(peer->maxDgramPackets);
6769         peer->ifDgramPackets = ntohs(peer->ifDgramPackets);
6770         peer->MTU = ntohs(peer->MTU);
6771         peer->cwind = ntohs(peer->cwind);
6772         peer->nDgramPackets = ntohs(peer->nDgramPackets);
6773         peer->congestSeq = ntohs(peer->congestSeq);
6774         peer->bytesSent.high = ntohl(peer->bytesSent.high);
6775         peer->bytesSent.low = ntohl(peer->bytesSent.low);
6776         peer->bytesReceived.high = ntohl(peer->bytesReceived.high);
6777         peer->bytesReceived.low = ntohl(peer->bytesReceived.low);
6778     }
6779
6780     return rc;
6781 }
6782 #endif /* RXDEBUG */
6783
6784 void
6785 shutdown_rx(void)
6786 {
6787     struct rx_serverQueueEntry *np;
6788     register int i, j;
6789 #ifndef KERNEL
6790     register struct rx_call *call;
6791     register struct rx_serverQueueEntry *sq;
6792 #endif /* KERNEL */
6793
6794     LOCK_RX_INIT;
6795     if (rxinit_status == 1) {
6796         UNLOCK_RX_INIT;
6797         return;                 /* Already shutdown. */
6798     }
6799 #ifndef KERNEL
6800     rx_port = 0;
6801 #ifndef AFS_PTHREAD_ENV
6802     FD_ZERO(&rx_selectMask);
6803 #endif /* AFS_PTHREAD_ENV */
6804     rxi_dataQuota = RX_MAX_QUOTA;
6805 #ifndef AFS_PTHREAD_ENV
6806     rxi_StopListener();
6807 #endif /* AFS_PTHREAD_ENV */
6808     shutdown_rxevent();
6809     rx_SetEpoch(0);
6810 #ifndef AFS_PTHREAD_ENV
6811 #ifndef AFS_USE_GETTIMEOFDAY
6812     clock_UnInit();
6813 #endif /* AFS_USE_GETTIMEOFDAY */
6814 #endif /* AFS_PTHREAD_ENV */
6815
6816     while (!queue_IsEmpty(&rx_freeCallQueue)) {
6817         call = queue_First(&rx_freeCallQueue, rx_call);
6818         queue_Remove(call);
6819         rxi_Free(call, sizeof(struct rx_call));
6820     }
6821
6822     while (!queue_IsEmpty(&rx_idleServerQueue)) {
6823         sq = queue_First(&rx_idleServerQueue, rx_serverQueueEntry);
6824         queue_Remove(sq);
6825     }
6826 #endif /* KERNEL */
6827
6828     {
6829         struct rx_peer **peer_ptr, **peer_end;
6830         for (peer_ptr = &rx_peerHashTable[0], peer_end =
6831              &rx_peerHashTable[rx_hashTableSize]; peer_ptr < peer_end;
6832              peer_ptr++) {
6833             struct rx_peer *peer, *next;
6834             for (peer = *peer_ptr; peer; peer = next) {
6835                 rx_interface_stat_p rpc_stat, nrpc_stat;
6836                 size_t space;
6837                 for (queue_Scan
6838                      (&peer->rpcStats, rpc_stat, nrpc_stat,
6839                       rx_interface_stat)) {
6840                     unsigned int num_funcs;
6841                     if (!rpc_stat)
6842                         break;
6843                     queue_Remove(&rpc_stat->queue_header);
6844                     queue_Remove(&rpc_stat->all_peers);
6845                     num_funcs = rpc_stat->stats[0].func_total;
6846                     space =
6847                         sizeof(rx_interface_stat_t) +
6848                         rpc_stat->stats[0].func_total *
6849                         sizeof(rx_function_entry_v1_t);
6850
6851                     rxi_Free(rpc_stat, space);
6852                     MUTEX_ENTER(&rx_rpc_stats);
6853                     rxi_rpc_peer_stat_cnt -= num_funcs;
6854                     MUTEX_EXIT(&rx_rpc_stats);
6855                 }
6856                 next = peer->next;
6857                 rxi_FreePeer(peer);
6858                 rx_MutexDecrement(rx_stats.nPeerStructs, rx_stats_mutex);
6859             }
6860         }
6861     }
6862     for (i = 0; i < RX_MAX_SERVICES; i++) {
6863         if (rx_services[i])
6864             rxi_Free(rx_services[i], sizeof(*rx_services[i]));
6865     }
6866     for (i = 0; i < rx_hashTableSize; i++) {
6867         register struct rx_connection *tc, *ntc;
6868         MUTEX_ENTER(&rx_connHashTable_lock);
6869         for (tc = rx_connHashTable[i]; tc; tc = ntc) {
6870             ntc = tc->next;
6871             for (j = 0; j < RX_MAXCALLS; j++) {
6872                 if (tc->call[j]) {
6873                     rxi_Free(tc->call[j], sizeof(*tc->call[j]));
6874                 }
6875             }
6876             rxi_Free(tc, sizeof(*tc));
6877         }
6878         MUTEX_EXIT(&rx_connHashTable_lock);
6879     }
6880
6881     MUTEX_ENTER(&freeSQEList_lock);
6882
6883     while ((np = rx_FreeSQEList)) {
6884         rx_FreeSQEList = *(struct rx_serverQueueEntry **)np;
6885         MUTEX_DESTROY(&np->lock);
6886         rxi_Free(np, sizeof(*np));
6887     }
6888
6889     MUTEX_EXIT(&freeSQEList_lock);
6890     MUTEX_DESTROY(&freeSQEList_lock);
6891     MUTEX_DESTROY(&rx_freeCallQueue_lock);
6892     MUTEX_DESTROY(&rx_connHashTable_lock);
6893     MUTEX_DESTROY(&rx_peerHashTable_lock);
6894     MUTEX_DESTROY(&rx_serverPool_lock);
6895
6896     osi_Free(rx_connHashTable,
6897              rx_hashTableSize * sizeof(struct rx_connection *));
6898     osi_Free(rx_peerHashTable, rx_hashTableSize * sizeof(struct rx_peer *));
6899
6900     UNPIN(rx_connHashTable,
6901           rx_hashTableSize * sizeof(struct rx_connection *));
6902     UNPIN(rx_peerHashTable, rx_hashTableSize * sizeof(struct rx_peer *));
6903
6904     rxi_FreeAllPackets();
6905
6906     MUTEX_ENTER(&rx_stats_mutex);
6907     rxi_dataQuota = RX_MAX_QUOTA;
6908     rxi_availProcs = rxi_totalMin = rxi_minDeficit = 0;
6909     MUTEX_EXIT(&rx_stats_mutex);
6910
6911     rxinit_status = 1;
6912     UNLOCK_RX_INIT;
6913 }
6914
6915 #ifdef RX_ENABLE_LOCKS
6916 void
6917 osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg)
6918 {
6919     if (!MUTEX_ISMINE(lockaddr))
6920         osi_Panic("Lock not held: %s", msg);
6921 }
6922 #endif /* RX_ENABLE_LOCKS */
6923
6924 #ifndef KERNEL
6925
6926 /*
6927  * Routines to implement connection specific data.
6928  */
6929
6930 int
6931 rx_KeyCreate(rx_destructor_t rtn)
6932 {
6933     int key;
6934     MUTEX_ENTER(&rxi_keyCreate_lock);
6935     key = rxi_keyCreate_counter++;
6936     rxi_keyCreate_destructor = (rx_destructor_t *)
6937         realloc((void *)rxi_keyCreate_destructor,
6938                 (key + 1) * sizeof(rx_destructor_t));
6939     rxi_keyCreate_destructor[key] = rtn;
6940     MUTEX_EXIT(&rxi_keyCreate_lock);
6941     return key;
6942 }
6943
6944 void
6945 rx_SetSpecific(struct rx_connection *conn, int key, void *ptr)
6946 {
6947     int i;
6948     MUTEX_ENTER(&conn->conn_data_lock);
6949     if (!conn->specific) {
6950         conn->specific = (void **)malloc((key + 1) * sizeof(void *));
6951         for (i = 0; i < key; i++)
6952             conn->specific[i] = NULL;
6953         conn->nSpecific = key + 1;
6954         conn->specific[key] = ptr;
6955     } else if (key >= conn->nSpecific) {
6956         conn->specific = (void **)
6957             realloc(conn->specific, (key + 1) * sizeof(void *));
6958         for (i = conn->nSpecific; i < key; i++)
6959             conn->specific[i] = NULL;
6960         conn->nSpecific = key + 1;
6961         conn->specific[key] = ptr;
6962     } else {
6963         if (conn->specific[key] && rxi_keyCreate_destructor[key])
6964             (*rxi_keyCreate_destructor[key]) (conn->specific[key]);
6965         conn->specific[key] = ptr;
6966     }
6967     MUTEX_EXIT(&conn->conn_data_lock);
6968 }
6969
6970 void *
6971 rx_GetSpecific(struct rx_connection *conn, int key)
6972 {
6973     void *ptr;
6974     MUTEX_ENTER(&conn->conn_data_lock);
6975     if (key >= conn->nSpecific)
6976         ptr = NULL;
6977     else
6978         ptr = conn->specific[key];
6979     MUTEX_EXIT(&conn->conn_data_lock);
6980     return ptr;
6981 }
6982
6983 #endif /* !KERNEL */
6984
6985 /*
6986  * processStats is a queue used to store the statistics for the local
6987  * process.  Its contents are similar to the contents of the rpcStats
6988  * queue on a rx_peer structure, but the actual data stored within
6989  * this queue contains totals across the lifetime of the process (assuming
6990  * the stats have not been reset) - unlike the per peer structures
6991  * which can come and go based upon the peer lifetime.
6992  */
6993
6994 static struct rx_queue processStats = { &processStats, &processStats };
6995
6996 /*
6997  * peerStats is a queue used to store the statistics for all peer structs.
6998  * Its contents are the union of all the peer rpcStats queues.
6999  */
7000
7001 static struct rx_queue peerStats = { &peerStats, &peerStats };
7002
7003 /*
7004  * rxi_monitor_processStats is used to turn process wide stat collection
7005  * on and off
7006  */
7007
7008 static int rxi_monitor_processStats = 0;
7009
7010 /*
7011  * rxi_monitor_peerStats is used to turn per peer stat collection on and off
7012  */
7013
7014 static int rxi_monitor_peerStats = 0;
7015
7016 /*
7017  * rxi_AddRpcStat - given all of the information for a particular rpc
7018  * call, create (if needed) and update the stat totals for the rpc.
7019  *
7020  * PARAMETERS
7021  *
7022  * IN stats - the queue of stats that will be updated with the new value
7023  *
7024  * IN rxInterface - a unique number that identifies the rpc interface
7025  *
7026  * IN currentFunc - the index of the function being invoked
7027  *
7028  * IN totalFunc - the total number of functions in this interface
7029  *
7030  * IN queueTime - the amount of time this function waited for a thread
7031  *
7032  * IN execTime - the amount of time this function invocation took to execute
7033  *
7034  * IN bytesSent - the number bytes sent by this invocation
7035  *
7036  * IN bytesRcvd - the number bytes received by this invocation
7037  *
7038  * IN isServer - if true, this invocation was made to a server
7039  *
7040  * IN remoteHost - the ip address of the remote host
7041  *
7042  * IN remotePort - the port of the remote host
7043  *
7044  * IN addToPeerList - if != 0, add newly created stat to the global peer list
7045  *
7046  * INOUT counter - if a new stats structure is allocated, the counter will
7047  * be updated with the new number of allocated stat structures
7048  *
7049  * RETURN CODES
7050  *
7051  * Returns void.
7052  */
7053
7054 static int
7055 rxi_AddRpcStat(struct rx_queue *stats, afs_uint32 rxInterface,
7056                afs_uint32 currentFunc, afs_uint32 totalFunc,
7057                struct clock *queueTime, struct clock *execTime,
7058                afs_hyper_t * bytesSent, afs_hyper_t * bytesRcvd, int isServer,
7059                afs_uint32 remoteHost, afs_uint32 remotePort,
7060                int addToPeerList, unsigned int *counter)
7061 {
7062     int rc = 0;
7063     rx_interface_stat_p rpc_stat, nrpc_stat;
7064
7065     /*
7066      * See if there's already a structure for this interface
7067      */
7068
7069     for (queue_Scan(stats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7070         if ((rpc_stat->stats[0].interfaceId == rxInterface)
7071             && (rpc_stat->stats[0].remote_is_server == isServer))
7072             break;
7073     }
7074
7075     /*
7076      * Didn't find a match so allocate a new structure and add it to the
7077      * queue.
7078      */
7079
7080     if (queue_IsEnd(stats, rpc_stat) || (rpc_stat == NULL)
7081         || (rpc_stat->stats[0].interfaceId != rxInterface)
7082         || (rpc_stat->stats[0].remote_is_server != isServer)) {
7083         int i;
7084         size_t space;
7085
7086         space =
7087             sizeof(rx_interface_stat_t) +
7088             totalFunc * sizeof(rx_function_entry_v1_t);
7089
7090         rpc_stat = (rx_interface_stat_p) rxi_Alloc(space);
7091         if (rpc_stat == NULL) {
7092             rc = 1;
7093             goto fail;
7094         }
7095         *counter += totalFunc;
7096         for (i = 0; i < totalFunc; i++) {
7097             rpc_stat->stats[i].remote_peer = remoteHost;
7098             rpc_stat->stats[i].remote_port = remotePort;
7099             rpc_stat->stats[i].remote_is_server = isServer;
7100             rpc_stat->stats[i].interfaceId = rxInterface;
7101             rpc_stat->stats[i].func_total = totalFunc;
7102             rpc_stat->stats[i].func_index = i;
7103             hzero(rpc_stat->stats[i].invocations);
7104             hzero(rpc_stat->stats[i].bytes_sent);
7105             hzero(rpc_stat->stats[i].bytes_rcvd);
7106             rpc_stat->stats[i].queue_time_sum.sec = 0;
7107             rpc_stat->stats[i].queue_time_sum.usec = 0;
7108             rpc_stat->stats[i].queue_time_sum_sqr.sec = 0;
7109             rpc_stat->stats[i].queue_time_sum_sqr.usec = 0;
7110             rpc_stat->stats[i].queue_time_min.sec = 9999999;
7111             rpc_stat->stats[i].queue_time_min.usec = 9999999;
7112             rpc_stat->stats[i].queue_time_max.sec = 0;
7113             rpc_stat->stats[i].queue_time_max.usec = 0;
7114             rpc_stat->stats[i].execution_time_sum.sec = 0;
7115             rpc_stat->stats[i].execution_time_sum.usec = 0;
7116             rpc_stat->stats[i].execution_time_sum_sqr.sec = 0;
7117             rpc_stat->stats[i].execution_time_sum_sqr.usec = 0;
7118             rpc_stat->stats[i].execution_time_min.sec = 9999999;
7119             rpc_stat->stats[i].execution_time_min.usec = 9999999;
7120             rpc_stat->stats[i].execution_time_max.sec = 0;
7121             rpc_stat->stats[i].execution_time_max.usec = 0;
7122         }
7123         queue_Prepend(stats, rpc_stat);
7124         if (addToPeerList) {
7125             queue_Prepend(&peerStats, &rpc_stat->all_peers);
7126         }
7127     }
7128
7129     /*
7130      * Increment the stats for this function
7131      */
7132
7133     hadd32(rpc_stat->stats[currentFunc].invocations, 1);
7134     hadd(rpc_stat->stats[currentFunc].bytes_sent, *bytesSent);
7135     hadd(rpc_stat->stats[currentFunc].bytes_rcvd, *bytesRcvd);
7136     clock_Add(&rpc_stat->stats[currentFunc].queue_time_sum, queueTime);
7137     clock_AddSq(&rpc_stat->stats[currentFunc].queue_time_sum_sqr, queueTime);
7138     if (clock_Lt(queueTime, &rpc_stat->stats[currentFunc].queue_time_min)) {
7139         rpc_stat->stats[currentFunc].queue_time_min = *queueTime;
7140     }
7141     if (clock_Gt(queueTime, &rpc_stat->stats[currentFunc].queue_time_max)) {
7142         rpc_stat->stats[currentFunc].queue_time_max = *queueTime;
7143     }
7144     clock_Add(&rpc_stat->stats[currentFunc].execution_time_sum, execTime);
7145     clock_AddSq(&rpc_stat->stats[currentFunc].execution_time_sum_sqr,
7146                 execTime);
7147     if (clock_Lt(execTime, &rpc_stat->stats[currentFunc].execution_time_min)) {
7148         rpc_stat->stats[currentFunc].execution_time_min = *execTime;
7149     }
7150     if (clock_Gt(execTime, &rpc_stat->stats[currentFunc].execution_time_max)) {
7151         rpc_stat->stats[currentFunc].execution_time_max = *execTime;
7152     }
7153
7154   fail:
7155     return rc;
7156 }
7157
7158 /*
7159  * rx_IncrementTimeAndCount - increment the times and count for a particular
7160  * rpc function.
7161  *
7162  * PARAMETERS
7163  *
7164  * IN peer - the peer who invoked the rpc
7165  *
7166  * IN rxInterface - a unique number that identifies the rpc interface
7167  *
7168  * IN currentFunc - the index of the function being invoked
7169  *
7170  * IN totalFunc - the total number of functions in this interface
7171  *
7172  * IN queueTime - the amount of time this function waited for a thread
7173  *
7174  * IN execTime - the amount of time this function invocation took to execute
7175  *
7176  * IN bytesSent - the number bytes sent by this invocation
7177  *
7178  * IN bytesRcvd - the number bytes received by this invocation
7179  *
7180  * IN isServer - if true, this invocation was made to a server
7181  *
7182  * RETURN CODES
7183  *
7184  * Returns void.
7185  */
7186
7187 void
7188 rx_IncrementTimeAndCount(struct rx_peer *peer, afs_uint32 rxInterface,
7189                          afs_uint32 currentFunc, afs_uint32 totalFunc,
7190                          struct clock *queueTime, struct clock *execTime,
7191                          afs_hyper_t * bytesSent, afs_hyper_t * bytesRcvd,
7192                          int isServer)
7193 {
7194
7195     if (!(rxi_monitor_peerStats || rxi_monitor_processStats))
7196         return;
7197
7198     MUTEX_ENTER(&rx_rpc_stats);
7199     MUTEX_ENTER(&peer->peer_lock);
7200
7201     if (rxi_monitor_peerStats) {
7202         rxi_AddRpcStat(&peer->rpcStats, rxInterface, currentFunc, totalFunc,
7203                        queueTime, execTime, bytesSent, bytesRcvd, isServer,
7204                        peer->host, peer->port, 1, &rxi_rpc_peer_stat_cnt);
7205     }
7206
7207     if (rxi_monitor_processStats) {
7208         rxi_AddRpcStat(&processStats, rxInterface, currentFunc, totalFunc,
7209                        queueTime, execTime, bytesSent, bytesRcvd, isServer,
7210                        0xffffffff, 0xffffffff, 0, &rxi_rpc_process_stat_cnt);
7211     }
7212
7213     MUTEX_EXIT(&peer->peer_lock);
7214     MUTEX_EXIT(&rx_rpc_stats);
7215
7216 }
7217
7218 /*
7219  * rx_MarshallProcessRPCStats - marshall an array of rpc statistics
7220  *
7221  * PARAMETERS
7222  *
7223  * IN callerVersion - the rpc stat version of the caller.
7224  *
7225  * IN count - the number of entries to marshall.
7226  *
7227  * IN stats - pointer to stats to be marshalled.
7228  *
7229  * OUT ptr - Where to store the marshalled data.
7230  *
7231  * RETURN CODES
7232  *
7233  * Returns void.
7234  */
7235 void
7236 rx_MarshallProcessRPCStats(afs_uint32 callerVersion, int count,
7237                            rx_function_entry_v1_t * stats, afs_uint32 ** ptrP)
7238 {
7239     int i;
7240     afs_uint32 *ptr;
7241
7242     /*
7243      * We only support the first version
7244      */
7245     for (ptr = *ptrP, i = 0; i < count; i++, stats++) {
7246         *(ptr++) = stats->remote_peer;
7247         *(ptr++) = stats->remote_port;
7248         *(ptr++) = stats->remote_is_server;
7249         *(ptr++) = stats->interfaceId;
7250         *(ptr++) = stats->func_total;
7251         *(ptr++) = stats->func_index;
7252         *(ptr++) = hgethi(stats->invocations);
7253         *(ptr++) = hgetlo(stats->invocations);
7254         *(ptr++) = hgethi(stats->bytes_sent);
7255         *(ptr++) = hgetlo(stats->bytes_sent);
7256         *(ptr++) = hgethi(stats->bytes_rcvd);
7257         *(ptr++) = hgetlo(stats->bytes_rcvd);
7258         *(ptr++) = stats->queue_time_sum.sec;
7259         *(ptr++) = stats->queue_time_sum.usec;
7260         *(ptr++) = stats->queue_time_sum_sqr.sec;
7261         *(ptr++) = stats->queue_time_sum_sqr.usec;
7262         *(ptr++) = stats->queue_time_min.sec;
7263         *(ptr++) = stats->queue_time_min.usec;
7264         *(ptr++) = stats->queue_time_max.sec;
7265         *(ptr++) = stats->queue_time_max.usec;
7266         *(ptr++) = stats->execution_time_sum.sec;
7267         *(ptr++) = stats->execution_time_sum.usec;
7268         *(ptr++) = stats->execution_time_sum_sqr.sec;
7269         *(ptr++) = stats->execution_time_sum_sqr.usec;
7270         *(ptr++) = stats->execution_time_min.sec;
7271         *(ptr++) = stats->execution_time_min.usec;
7272         *(ptr++) = stats->execution_time_max.sec;
7273         *(ptr++) = stats->execution_time_max.usec;
7274     }
7275     *ptrP = ptr;
7276 }
7277
7278 /*
7279  * rx_RetrieveProcessRPCStats - retrieve all of the rpc statistics for
7280  * this process
7281  *
7282  * PARAMETERS
7283  *
7284  * IN callerVersion - the rpc stat version of the caller
7285  *
7286  * OUT myVersion - the rpc stat version of this function
7287  *
7288  * OUT clock_sec - local time seconds
7289  *
7290  * OUT clock_usec - local time microseconds
7291  *
7292  * OUT allocSize - the number of bytes allocated to contain stats
7293  *
7294  * OUT statCount - the number stats retrieved from this process.
7295  *
7296  * OUT stats - the actual stats retrieved from this process.
7297  *
7298  * RETURN CODES
7299  *
7300  * Returns void.  If successful, stats will != NULL.
7301  */
7302
7303 int
7304 rx_RetrieveProcessRPCStats(afs_uint32 callerVersion, afs_uint32 * myVersion,
7305                            afs_uint32 * clock_sec, afs_uint32 * clock_usec,
7306                            size_t * allocSize, afs_uint32 * statCount,
7307                            afs_uint32 ** stats)
7308 {
7309     size_t space = 0;
7310     afs_uint32 *ptr;
7311     struct clock now;
7312     int rc = 0;
7313
7314     *stats = 0;
7315     *allocSize = 0;
7316     *statCount = 0;
7317     *myVersion = RX_STATS_RETRIEVAL_VERSION;
7318
7319     /*
7320      * Check to see if stats are enabled
7321      */
7322
7323     MUTEX_ENTER(&rx_rpc_stats);
7324     if (!rxi_monitor_processStats) {
7325         MUTEX_EXIT(&rx_rpc_stats);
7326         return rc;
7327     }
7328
7329     clock_GetTime(&now);
7330     *clock_sec = now.sec;
7331     *clock_usec = now.usec;
7332
7333     /*
7334      * Allocate the space based upon the caller version
7335      *
7336      * If the client is at an older version than we are,
7337      * we return the statistic data in the older data format, but
7338      * we still return our version number so the client knows we
7339      * are maintaining more data than it can retrieve.
7340      */
7341
7342     if (callerVersion >= RX_STATS_RETRIEVAL_FIRST_EDITION) {
7343         space = rxi_rpc_process_stat_cnt * sizeof(rx_function_entry_v1_t);
7344         *statCount = rxi_rpc_process_stat_cnt;
7345     } else {
7346         /*
7347          * This can't happen yet, but in the future version changes
7348          * can be handled by adding additional code here
7349          */
7350     }
7351
7352     if (space > (size_t) 0) {
7353         *allocSize = space;
7354         ptr = *stats = (afs_uint32 *) rxi_Alloc(space);
7355
7356         if (ptr != NULL) {
7357             rx_interface_stat_p rpc_stat, nrpc_stat;
7358
7359
7360             for (queue_Scan
7361                  (&processStats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7362                 /*
7363                  * Copy the data based upon the caller version
7364                  */
7365                 rx_MarshallProcessRPCStats(callerVersion,
7366                                            rpc_stat->stats[0].func_total,
7367                                            rpc_stat->stats, &ptr);
7368             }
7369         } else {
7370             rc = ENOMEM;
7371         }
7372     }
7373     MUTEX_EXIT(&rx_rpc_stats);
7374     return rc;
7375 }
7376
7377 /*
7378  * rx_RetrievePeerRPCStats - retrieve all of the rpc statistics for the peers
7379  *
7380  * PARAMETERS
7381  *
7382  * IN callerVersion - the rpc stat version of the caller
7383  *
7384  * OUT myVersion - the rpc stat version of this function
7385  *
7386  * OUT clock_sec - local time seconds
7387  *
7388  * OUT clock_usec - local time microseconds
7389  *
7390  * OUT allocSize - the number of bytes allocated to contain stats
7391  *
7392  * OUT statCount - the number of stats retrieved from the individual
7393  * peer structures.
7394  *
7395  * OUT stats - the actual stats retrieved from the individual peer structures.
7396  *
7397  * RETURN CODES
7398  *
7399  * Returns void.  If successful, stats will != NULL.
7400  */
7401
7402 int
7403 rx_RetrievePeerRPCStats(afs_uint32 callerVersion, afs_uint32 * myVersion,
7404                         afs_uint32 * clock_sec, afs_uint32 * clock_usec,
7405                         size_t * allocSize, afs_uint32 * statCount,
7406                         afs_uint32 ** stats)
7407 {
7408     size_t space = 0;
7409     afs_uint32 *ptr;
7410     struct clock now;
7411     int rc = 0;
7412
7413     *stats = 0;
7414     *statCount = 0;
7415     *allocSize = 0;
7416     *myVersion = RX_STATS_RETRIEVAL_VERSION;
7417
7418     /*
7419      * Check to see if stats are enabled
7420      */
7421
7422     MUTEX_ENTER(&rx_rpc_stats);
7423     if (!rxi_monitor_peerStats) {
7424         MUTEX_EXIT(&rx_rpc_stats);
7425         return rc;
7426     }
7427
7428     clock_GetTime(&now);
7429     *clock_sec = now.sec;
7430     *clock_usec = now.usec;
7431
7432     /*
7433      * Allocate the space based upon the caller version
7434      *
7435      * If the client is at an older version than we are,
7436      * we return the statistic data in the older data format, but
7437      * we still return our version number so the client knows we
7438      * are maintaining more data than it can retrieve.
7439      */
7440
7441     if (callerVersion >= RX_STATS_RETRIEVAL_FIRST_EDITION) {
7442         space = rxi_rpc_peer_stat_cnt * sizeof(rx_function_entry_v1_t);
7443         *statCount = rxi_rpc_peer_stat_cnt;
7444     } else {
7445         /*
7446          * This can't happen yet, but in the future version changes
7447          * can be handled by adding additional code here
7448          */
7449     }
7450
7451     if (space > (size_t) 0) {
7452         *allocSize = space;
7453         ptr = *stats = (afs_uint32 *) rxi_Alloc(space);
7454
7455         if (ptr != NULL) {
7456             rx_interface_stat_p rpc_stat, nrpc_stat;
7457             char *fix_offset;
7458
7459             for (queue_Scan
7460                  (&peerStats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7461                 /*
7462                  * We have to fix the offset of rpc_stat since we are
7463                  * keeping this structure on two rx_queues.  The rx_queue
7464                  * package assumes that the rx_queue member is the first
7465                  * member of the structure.  That is, rx_queue assumes that
7466                  * any one item is only on one queue at a time.  We are
7467                  * breaking that assumption and so we have to do a little
7468                  * math to fix our pointers.
7469                  */
7470
7471                 fix_offset = (char *)rpc_stat;
7472                 fix_offset -= offsetof(rx_interface_stat_t, all_peers);
7473                 rpc_stat = (rx_interface_stat_p) fix_offset;
7474
7475                 /*
7476                  * Copy the data based upon the caller version
7477                  */
7478                 rx_MarshallProcessRPCStats(callerVersion,
7479                                            rpc_stat->stats[0].func_total,
7480                                            rpc_stat->stats, &ptr);
7481             }
7482         } else {
7483             rc = ENOMEM;
7484         }
7485     }
7486     MUTEX_EXIT(&rx_rpc_stats);
7487     return rc;
7488 }
7489
7490 /*
7491  * rx_FreeRPCStats - free memory allocated by
7492  *                   rx_RetrieveProcessRPCStats and rx_RetrievePeerRPCStats
7493  *
7494  * PARAMETERS
7495  *
7496  * IN stats - stats previously returned by rx_RetrieveProcessRPCStats or
7497  * rx_RetrievePeerRPCStats
7498  *
7499  * IN allocSize - the number of bytes in stats.
7500  *
7501  * RETURN CODES
7502  *
7503  * Returns void.
7504  */
7505
7506 void
7507 rx_FreeRPCStats(afs_uint32 * stats, size_t allocSize)
7508 {
7509     rxi_Free(stats, allocSize);
7510 }
7511
7512 /*
7513  * rx_queryProcessRPCStats - see if process rpc stat collection is
7514  * currently enabled.
7515  *
7516  * PARAMETERS
7517  *
7518  * RETURN CODES
7519  *
7520  * Returns 0 if stats are not enabled != 0 otherwise
7521  */
7522
7523 int
7524 rx_queryProcessRPCStats(void)
7525 {
7526     int rc;
7527     MUTEX_ENTER(&rx_rpc_stats);
7528     rc = rxi_monitor_processStats;
7529     MUTEX_EXIT(&rx_rpc_stats);
7530     return rc;
7531 }
7532
7533 /*
7534  * rx_queryPeerRPCStats - see if peer stat collection is currently enabled.
7535  *
7536  * PARAMETERS
7537  *
7538  * RETURN CODES
7539  *
7540  * Returns 0 if stats are not enabled != 0 otherwise
7541  */
7542
7543 int
7544 rx_queryPeerRPCStats(void)
7545 {
7546     int rc;
7547     MUTEX_ENTER(&rx_rpc_stats);
7548     rc = rxi_monitor_peerStats;
7549     MUTEX_EXIT(&rx_rpc_stats);
7550     return rc;
7551 }
7552
7553 /*
7554  * rx_enableProcessRPCStats - begin rpc stat collection for entire process
7555  *
7556  * PARAMETERS
7557  *
7558  * RETURN CODES
7559  *
7560  * Returns void.
7561  */
7562
7563 void
7564 rx_enableProcessRPCStats(void)
7565 {
7566     MUTEX_ENTER(&rx_rpc_stats);
7567     rx_enable_stats = 1;
7568     rxi_monitor_processStats = 1;
7569     MUTEX_EXIT(&rx_rpc_stats);
7570 }
7571
7572 /*
7573  * rx_enablePeerRPCStats - begin rpc stat collection per peer structure
7574  *
7575  * PARAMETERS
7576  *
7577  * RETURN CODES
7578  *
7579  * Returns void.
7580  */
7581
7582 void
7583 rx_enablePeerRPCStats(void)
7584 {
7585     MUTEX_ENTER(&rx_rpc_stats);
7586     rx_enable_stats = 1;
7587     rxi_monitor_peerStats = 1;
7588     MUTEX_EXIT(&rx_rpc_stats);
7589 }
7590
7591 /*
7592  * rx_disableProcessRPCStats - stop rpc stat collection for entire process
7593  *
7594  * PARAMETERS
7595  *
7596  * RETURN CODES
7597  *
7598  * Returns void.
7599  */
7600
7601 void
7602 rx_disableProcessRPCStats(void)
7603 {
7604     rx_interface_stat_p rpc_stat, nrpc_stat;
7605     size_t space;
7606
7607     MUTEX_ENTER(&rx_rpc_stats);
7608
7609     /*
7610      * Turn off process statistics and if peer stats is also off, turn
7611      * off everything
7612      */
7613
7614     rxi_monitor_processStats = 0;
7615     if (rxi_monitor_peerStats == 0) {
7616         rx_enable_stats = 0;
7617     }
7618
7619     for (queue_Scan(&processStats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7620         unsigned int num_funcs = 0;
7621         if (!rpc_stat)
7622             break;
7623         queue_Remove(rpc_stat);
7624         num_funcs = rpc_stat->stats[0].func_total;
7625         space =
7626             sizeof(rx_interface_stat_t) +
7627             rpc_stat->stats[0].func_total * sizeof(rx_function_entry_v1_t);
7628
7629         rxi_Free(rpc_stat, space);
7630         rxi_rpc_process_stat_cnt -= num_funcs;
7631     }
7632     MUTEX_EXIT(&rx_rpc_stats);
7633 }
7634
7635 /*
7636  * rx_disablePeerRPCStats - stop rpc stat collection for peers
7637  *
7638  * PARAMETERS
7639  *
7640  * RETURN CODES
7641  *
7642  * Returns void.
7643  */
7644
7645 void
7646 rx_disablePeerRPCStats(void)
7647 {
7648     struct rx_peer **peer_ptr, **peer_end;
7649     int code;
7650
7651     MUTEX_ENTER(&rx_rpc_stats);
7652
7653     /*
7654      * Turn off peer statistics and if process stats is also off, turn
7655      * off everything
7656      */
7657
7658     rxi_monitor_peerStats = 0;
7659     if (rxi_monitor_processStats == 0) {
7660         rx_enable_stats = 0;
7661     }
7662
7663     MUTEX_ENTER(&rx_peerHashTable_lock);
7664     for (peer_ptr = &rx_peerHashTable[0], peer_end =
7665          &rx_peerHashTable[rx_hashTableSize]; peer_ptr < peer_end;
7666          peer_ptr++) {
7667         struct rx_peer *peer, *next, *prev;
7668         for (prev = peer = *peer_ptr; peer; peer = next) {
7669             next = peer->next;
7670             code = MUTEX_TRYENTER(&peer->peer_lock);
7671             if (code) {
7672                 rx_interface_stat_p rpc_stat, nrpc_stat;
7673                 size_t space;
7674                 for (queue_Scan
7675                      (&peer->rpcStats, rpc_stat, nrpc_stat,
7676                       rx_interface_stat)) {
7677                     unsigned int num_funcs = 0;
7678                     if (!rpc_stat)
7679                         break;
7680                     queue_Remove(&rpc_stat->queue_header);
7681                     queue_Remove(&rpc_stat->all_peers);
7682                     num_funcs = rpc_stat->stats[0].func_total;
7683                     space =
7684                         sizeof(rx_interface_stat_t) +
7685                         rpc_stat->stats[0].func_total *
7686                         sizeof(rx_function_entry_v1_t);
7687
7688                     rxi_Free(rpc_stat, space);
7689                     rxi_rpc_peer_stat_cnt -= num_funcs;
7690                 }
7691                 MUTEX_EXIT(&peer->peer_lock);
7692                 if (prev == *peer_ptr) {
7693                     *peer_ptr = next;
7694                     prev = next;
7695                 } else
7696                     prev->next = next;
7697             } else {
7698                 prev = peer;
7699             }
7700         }
7701     }
7702     MUTEX_EXIT(&rx_peerHashTable_lock);
7703     MUTEX_EXIT(&rx_rpc_stats);
7704 }
7705
7706 /*
7707  * rx_clearProcessRPCStats - clear the contents of the rpc stats according
7708  * to clearFlag
7709  *
7710  * PARAMETERS
7711  *
7712  * IN clearFlag - flag indicating which stats to clear
7713  *
7714  * RETURN CODES
7715  *
7716  * Returns void.
7717  */
7718
7719 void
7720 rx_clearProcessRPCStats(afs_uint32 clearFlag)
7721 {
7722     rx_interface_stat_p rpc_stat, nrpc_stat;
7723
7724     MUTEX_ENTER(&rx_rpc_stats);
7725
7726     for (queue_Scan(&processStats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7727         unsigned int num_funcs = 0, i;
7728         num_funcs = rpc_stat->stats[0].func_total;
7729         for (i = 0; i < num_funcs; i++) {
7730             if (clearFlag & AFS_RX_STATS_CLEAR_INVOCATIONS) {
7731                 hzero(rpc_stat->stats[i].invocations);
7732             }
7733             if (clearFlag & AFS_RX_STATS_CLEAR_BYTES_SENT) {
7734                 hzero(rpc_stat->stats[i].bytes_sent);
7735             }
7736             if (clearFlag & AFS_RX_STATS_CLEAR_BYTES_RCVD) {
7737                 hzero(rpc_stat->stats[i].bytes_rcvd);
7738             }
7739             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_SUM) {
7740                 rpc_stat->stats[i].queue_time_sum.sec = 0;
7741                 rpc_stat->stats[i].queue_time_sum.usec = 0;
7742             }
7743             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_SQUARE) {
7744                 rpc_stat->stats[i].queue_time_sum_sqr.sec = 0;
7745                 rpc_stat->stats[i].queue_time_sum_sqr.usec = 0;
7746             }
7747             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_MIN) {
7748                 rpc_stat->stats[i].queue_time_min.sec = 9999999;
7749                 rpc_stat->stats[i].queue_time_min.usec = 9999999;
7750             }
7751             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_MAX) {
7752                 rpc_stat->stats[i].queue_time_max.sec = 0;
7753                 rpc_stat->stats[i].queue_time_max.usec = 0;
7754             }
7755             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_SUM) {
7756                 rpc_stat->stats[i].execution_time_sum.sec = 0;
7757                 rpc_stat->stats[i].execution_time_sum.usec = 0;
7758             }
7759             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_SQUARE) {
7760                 rpc_stat->stats[i].execution_time_sum_sqr.sec = 0;
7761                 rpc_stat->stats[i].execution_time_sum_sqr.usec = 0;
7762             }
7763             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_MIN) {
7764                 rpc_stat->stats[i].execution_time_min.sec = 9999999;
7765                 rpc_stat->stats[i].execution_time_min.usec = 9999999;
7766             }
7767             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_MAX) {
7768                 rpc_stat->stats[i].execution_time_max.sec = 0;
7769                 rpc_stat->stats[i].execution_time_max.usec = 0;
7770             }
7771         }
7772     }
7773
7774     MUTEX_EXIT(&rx_rpc_stats);
7775 }
7776
7777 /*
7778  * rx_clearPeerRPCStats - clear the contents of the rpc stats according
7779  * to clearFlag
7780  *
7781  * PARAMETERS
7782  *
7783  * IN clearFlag - flag indicating which stats to clear
7784  *
7785  * RETURN CODES
7786  *
7787  * Returns void.
7788  */
7789
7790 void
7791 rx_clearPeerRPCStats(afs_uint32 clearFlag)
7792 {
7793     rx_interface_stat_p rpc_stat, nrpc_stat;
7794
7795     MUTEX_ENTER(&rx_rpc_stats);
7796
7797     for (queue_Scan(&peerStats, rpc_stat, nrpc_stat, rx_interface_stat)) {
7798         unsigned int num_funcs = 0, i;
7799         char *fix_offset;
7800         /*
7801          * We have to fix the offset of rpc_stat since we are
7802          * keeping this structure on two rx_queues.  The rx_queue
7803          * package assumes that the rx_queue member is the first
7804          * member of the structure.  That is, rx_queue assumes that
7805          * any one item is only on one queue at a time.  We are
7806          * breaking that assumption and so we have to do a little
7807          * math to fix our pointers.
7808          */
7809
7810         fix_offset = (char *)rpc_stat;
7811         fix_offset -= offsetof(rx_interface_stat_t, all_peers);
7812         rpc_stat = (rx_interface_stat_p) fix_offset;
7813
7814         num_funcs = rpc_stat->stats[0].func_total;
7815         for (i = 0; i < num_funcs; i++) {
7816             if (clearFlag & AFS_RX_STATS_CLEAR_INVOCATIONS) {
7817                 hzero(rpc_stat->stats[i].invocations);
7818             }
7819             if (clearFlag & AFS_RX_STATS_CLEAR_BYTES_SENT) {
7820                 hzero(rpc_stat->stats[i].bytes_sent);
7821             }
7822             if (clearFlag & AFS_RX_STATS_CLEAR_BYTES_RCVD) {
7823                 hzero(rpc_stat->stats[i].bytes_rcvd);
7824             }
7825             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_SUM) {
7826                 rpc_stat->stats[i].queue_time_sum.sec = 0;
7827                 rpc_stat->stats[i].queue_time_sum.usec = 0;
7828             }
7829             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_SQUARE) {
7830                 rpc_stat->stats[i].queue_time_sum_sqr.sec = 0;
7831                 rpc_stat->stats[i].queue_time_sum_sqr.usec = 0;
7832             }
7833             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_MIN) {
7834                 rpc_stat->stats[i].queue_time_min.sec = 9999999;
7835                 rpc_stat->stats[i].queue_time_min.usec = 9999999;
7836             }
7837             if (clearFlag & AFS_RX_STATS_CLEAR_QUEUE_TIME_MAX) {
7838                 rpc_stat->stats[i].queue_time_max.sec = 0;
7839                 rpc_stat->stats[i].queue_time_max.usec = 0;
7840             }
7841             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_SUM) {
7842                 rpc_stat->stats[i].execution_time_sum.sec = 0;
7843                 rpc_stat->stats[i].execution_time_sum.usec = 0;
7844             }
7845             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_SQUARE) {
7846                 rpc_stat->stats[i].execution_time_sum_sqr.sec = 0;
7847                 rpc_stat->stats[i].execution_time_sum_sqr.usec = 0;
7848             }
7849             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_MIN) {
7850                 rpc_stat->stats[i].execution_time_min.sec = 9999999;
7851                 rpc_stat->stats[i].execution_time_min.usec = 9999999;
7852             }
7853             if (clearFlag & AFS_RX_STATS_CLEAR_EXEC_TIME_MAX) {
7854                 rpc_stat->stats[i].execution_time_max.sec = 0;
7855                 rpc_stat->stats[i].execution_time_max.usec = 0;
7856             }
7857         }
7858     }
7859
7860     MUTEX_EXIT(&rx_rpc_stats);
7861 }
7862
7863 /*
7864  * rxi_rxstat_userok points to a routine that returns 1 if the caller
7865  * is authorized to enable/disable/clear RX statistics.
7866  */
7867 static int (*rxi_rxstat_userok) (struct rx_call * call) = NULL;
7868
7869 void
7870 rx_SetRxStatUserOk(int (*proc) (struct rx_call * call))
7871 {
7872     rxi_rxstat_userok = proc;
7873 }
7874
7875 int
7876 rx_RxStatUserOk(struct rx_call *call)
7877 {
7878     if (!rxi_rxstat_userok)
7879         return 0;
7880     return rxi_rxstat_userok(call);
7881 }
7882
7883 #ifdef AFS_NT40_ENV
7884 /*
7885  * DllMain() -- Entry-point function called by the DllMainCRTStartup()
7886  *     function in the MSVC runtime DLL (msvcrt.dll).
7887  *
7888  *     Note: the system serializes calls to this function.
7889  */
7890 BOOL WINAPI
7891 DllMain(HINSTANCE dllInstHandle,        /* instance handle for this DLL module */
7892         DWORD reason,                   /* reason function is being called */
7893         LPVOID reserved)                /* reserved for future use */
7894 {
7895     switch (reason) {
7896     case DLL_PROCESS_ATTACH:
7897         /* library is being attached to a process */
7898         INIT_PTHREAD_LOCKS;
7899         return TRUE;
7900
7901     case DLL_PROCESS_DETACH:
7902         return TRUE;
7903
7904     default:
7905         return FALSE;
7906     }
7907 }
7908 #endif
7909