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