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