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