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