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