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