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