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