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