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