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