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