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