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