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