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