rx: Use a red black tree for the event stack
[openafs.git] / src / rx / rx.h
index bfe8c6a..50d2bf2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #ifdef KERNEL
 #include "rx_kmutex.h"
 #include "rx_kernel.h"
-#include "rx_clock.h"
-#include "rx_event.h"
-#include "rx_queue.h"
-#include "rx_packet.h"
-#include "rx_misc.h"
-#include "rx_multi.h"
 #if defined (AFS_OBSD_ENV) && !defined (MLEN)
 #include "sys/mbuf.h"
 #endif
 #include <ws2tcpip.h>
 #endif
 # include "rx_user.h"
-# include "rx_clock.h"
-# include "rx_event.h"
-# include "rx_packet.h"
-# include "rx_misc.h"
-# include "rx_null.h"
-# include "rx_multi.h"
 #ifndef AFS_NT40_ENV
 # include <netinet/in.h>
 # include <sys/socket.h>
 #endif
 #endif /* KERNEL */
 
+#include "rx_clock.h"
+#include "rx_event.h"
+#include "rx_packet.h"
+#include "rx_misc.h"
+#include "rx_null.h"
+#include "rx_multi.h"
 
 /* Configurable parameters */
 #define        RX_IDLE_DEAD_TIME       60      /* default idle dead time */
@@ -77,9 +71,6 @@
 /* This parameter should not normally be changed */
 #define        RX_PROCESS_PRIORITY     LWP_NORMAL_PRIORITY
 
-/* backoff is fixed point binary.  Ie, units of 1/4 seconds */
-#define MAXBACKOFF 0x1F
-
 #define ADDRSPERSITE 16
 
 #ifndef KDUMP_RX_LOCK
@@ -111,24 +102,22 @@ int ntoh_syserr_conv(int error);
 #define rx_GetLocalStatus(call, status) ((call)->localStatus)
 #define        rx_GetRemoteStatus(call)        ((call)->remoteStatus)
 #define        rx_Error(call)                  ((call)->error)
+#define        rx_ConnError(conn)              ((conn)->error)
 #define        rx_IsServerConn(conn)           ((conn)->type == RX_SERVER_CONNECTION)
 #define        rx_IsClientConn(conn)           ((conn)->type == RX_CLIENT_CONNECTION)
 /* Don't use these; use the IsServerConn style */
 #define        rx_ServerConn(conn)             ((conn)->type == RX_SERVER_CONNECTION)
 #define        rx_ClientConn(conn)             ((conn)->type == RX_CLIENT_CONNECTION)
 #define rx_IsUsingPktCksum(conn)       ((conn)->flags & RX_CONN_USING_PACKET_CKSUM)
-#define rx_IsClonedConn(conn)           ((conn)->flags & RX_CLONED_CONNECTION)
 #define rx_ServiceIdOf(conn)           ((conn)->serviceId)
 #define        rx_SecurityClassOf(conn)        ((conn)->securityIndex)
 #define rx_SecurityObjectOf(conn)      ((conn)->securityObject)
-#define rx_ConnError(conn)             (rx_IsClonedConn((conn)) ? (conn)->parent->error : (conn)->error)
-#define rx_SetConnError(conn, err)      (rx_IsClonedConn((conn)) ? ((conn)->parent->error = err): ((conn)->error = err))
-#define rx_ConnHardDeadTime(conn)      (rx_IsClonedConn((conn)) ? (conn)->parent->hardDeadTime : (conn)->hardDeadTime)
-#define rx_ConnIdleDeadTime(conn)      (rx_IsClonedConn((conn)) ? (conn)->parent->idleDeadTime : (conn)->idleDeadTime)
-#define rx_ConnIdleDeadErr(conn)       (rx_IsClonedConn((conn)) ? (conn)->parent->idleDeadErr : (conn)->idleDeadErr)
-#define rx_ConnSecondsUntilDead(conn)  (rx_IsClonedConn((conn)) ? (conn)->parent->secondsUntilDead : (conn)->secondsUntilDead)
-#define rx_ConnSecondsUntilPing(conn)  (rx_IsClonedConn((conn)) ? (conn)->parent->secondsUntilPing : (conn)->secondsUntilPing)
 
+static_inline int
+rx_IsLoopbackAddr(afs_uint32 addr)
+{
+    return ((addr & 0xffff0000) == 0x7f000000);
+}
 
 /*******************
  * Macros callable by the user to further define attributes of a
@@ -163,6 +152,8 @@ int ntoh_syserr_conv(int error);
 #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
 #define rx_GetAfterProc(service) ((service)->afterProc)
 #define rx_GetBeforeProc(service) ((service)->beforeProc)
+#define rx_SetPostProc(service,proc) ((service)->postProc = (proc))
+#define rx_GetPostProc(service) ((service)->postProc)
 
 /* Define a procedure to be called when a server connection is created */
 #define rx_SetNewConnProc(service, proc) ((service)->newConnProc = (proc))
@@ -175,35 +166,14 @@ int ntoh_syserr_conv(int error);
 /* Enable or disable asymmetric client checking for a service */
 #define rx_SetCheckReach(service, x) ((service)->checkReach = (x))
 
-/* Set connection hard and idle timeouts for a connection */
-#define rx_SetConnHardDeadTime(conn, seconds)\
-    {\
-    if (rx_IsClonedConn(conn))                                         \
-       (conn)->parent->hardDeadTime = (seconds);                       \
-    else                                                               \
-       (conn)->hardDeadTime = (seconds);                               \
-    }
-
-#define rx_SetConnIdleDeadTime(conn, seconds)\
-    {\
-    if (rx_IsClonedConn(conn))                                         \
-       (conn)->parent->idleDeadTime = (seconds);                       \
-    else                                                               \
-       (conn)->idleDeadTime = (seconds);                               \
-    }
-
-#define rx_SetServerConnIdleDeadErr(conn, err)\
-    {\
-    if (rx_IsClonedConn(conn))                                         \
-       (conn)->parent->idleDeadErr = (err);                            \
-    else                                                               \
-       (conn)->idleDeadErr = (err);                                    \
-    }
-
+#define rx_SetServerConnIdleDeadErr(conn,err) ((conn)->idleDeadErr = (err))
 
 /* Set the overload threshold and the overload error */
 #define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code))
 
+/* Set the error to use for retrying a connection during MTU tuning */
+#define rx_SetMsgsizeRetryErr(conn, err) ((conn)->msgsizeRetryErr = (err))
+
 /* If this flag is set,no new requests are processed by rx, all new requests are
 returned with an error code of RX_CALL_DEAD ( transient error ) */
 #define        rx_SetRxTranquil()              (rx_tranquil = 1)
@@ -241,25 +211,9 @@ returned with an error code of RX_CALL_DEAD ( transient error ) */
 #define rx_EnableHotThread()           (rx_enable_hot_thread = 1)
 #define rx_DisableHotThread()          (rx_enable_hot_thread = 0)
 
-/* Macros to set max connection clones (each allows RX_MAXCALLS 
- * outstanding calls */
-
-#define rx_SetMaxCalls(v) \
-do {\
-       rx_SetCloneMax(v/4); \
-} while(0);
-
-#define rx_SetCloneMax(v) \
-do {\
-       if(v < RX_HARD_MAX_CLONES) \
-               rx_max_clones_per_connection = v; \
-} while(0);
-
-typedef afs_int32 rx_atomic_t;
-
 #define rx_PutConnection(conn) rx_DestroyConnection(conn)
 
-/* A connection is an authenticated communication path, allowing 
+/* A connection is an authenticated communication path, allowing
    limited multiple asynchronous conversations. */
 #ifdef KDUMP_RX_LOCK
 struct rx_connection_rx_lock {
@@ -267,7 +221,7 @@ struct rx_connection_rx_lock {
     struct rx_peer_rx_lock *peer;
 #else
 struct rx_connection {
-    struct rx_connection *next;        /* on hash chain _or_ free list */
+    struct rx_connection *next;        /*  on hash chain _or_ free list */
     struct rx_peer *peer;
 #endif
 #ifdef RX_ENABLE_LOCKS
@@ -286,11 +240,15 @@ struct rx_connection {
     afs_uint32 callNumber[RX_MAXCALLS];        /* Current call numbers */
     afs_uint32 rwind[RX_MAXCALLS];
     u_short twind[RX_MAXCALLS];
+    afs_uint32 lastBusy[RX_MAXCALLS]; /* timestamp of the last time we got an
+                                       * RX_PACKET_TYPE_BUSY packet for this
+                                       * call slot, or 0 if the slot is not busy */
     afs_uint32 serial;         /* Next outgoing packet serial number */
     afs_uint32 lastSerial;     /* # of last packet received, for computing skew */
-    afs_int32 maxSerial;       /* largest serial number seen on incoming packets */
-/*    afs_int32 maxPacketSize;    max packet size should be per-connection since */
-    /* peer process could be restarted on us. Includes RX Header.       */
+    afs_int32 lastPacketSize; /* last >max attempt */
+    afs_int32 lastPacketSizeSeq; /* seq number of attempt */
+    afs_int32 lastPingSize; /* last MTU ping attempt */
+    afs_int32 lastPingSizeSer; /* serial of last MTU ping attempt */
     struct rxevent *challengeEvent;    /* Scheduled when the server is challenging a     */
     struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */
     struct rxevent *checkReachEvent;   /* Scheduled when checking reachability */
@@ -298,8 +256,8 @@ struct rx_connection {
     /* client-- to retransmit the challenge */
     struct rx_service *service;        /* used by servers only */
     u_short serviceId;         /* To stamp on requests (clients only) */
-    rx_atomic_t refCount;      /* Reference count */
-    u_char flags;              /* Defined below */
+    afs_uint32 refCount;       /* Reference count (rx_refcnt_mutex) */
+    u_char flags;              /* Defined below - (conn_data_lock) */
     u_char type;               /* Type of connection, defined below */
     u_char secondsUntilPing;   /* how often to ping for each active call */
     u_char securityIndex;      /* corresponds to the security class of the */
@@ -317,11 +275,11 @@ struct rx_connection {
     u_char ackRate;            /* how many packets between ack requests */
     u_char makeCallWaiters;    /* how many rx_NewCalls are waiting */
     afs_int32 idleDeadErr;
+    afs_int32 secondsUntilNatPing;     /* how often to ping conn */
+    struct rxevent *natKeepAliveEvent; /* Scheduled to keep connection open */
+    afs_int32 msgsizeRetryErr;
     int nSpecific;             /* number entries in specific data */
     void **specific;           /* pointer to connection specific data */
-    struct rx_connection *parent; /* primary connection, if this is a clone */
-    struct rx_connection *next_clone; /* next in list of clones */
-    afs_uint32 nclones; /* count of clone connections (if not a clone) */
 };
 
 
@@ -359,12 +317,19 @@ struct rx_service {
     void (*newConnProc) (struct rx_connection * tcon); /* Routine to call when a server connection is created */
     void (*beforeProc) (struct rx_call * acall);       /* routine to call before a call is executed */
     void (*afterProc) (struct rx_call * acall, afs_int32 code);        /* routine to call after a call is executed */
+    void (*postProc) (afs_int32 code); /* routine to call after the call has ended */
     u_short maxProcs;          /* Maximum procs to be used for this service */
     u_short minProcs;          /* Minimum # of requests guaranteed executable simultaneously */
     u_short connDeadTime;      /* Seconds until a client of this service will be declared dead, if it is not responding */
     u_short idleDeadTime;      /* Time a server will wait for I/O to start up again */
     u_char checkReach;         /* Check for asymmetric clients? */
     afs_int32 idleDeadErr;
+    int nSpecific;             /* number entries in specific data */
+    void **specific;           /* pointer to connection specific data */
+#ifdef RX_ENABLE_LOCKS
+    afs_kmutex_t svc_data_lock;        /* protect specific data */
+#endif
+
 };
 
 #endif /* KDUMP_RX_LOCK */
@@ -419,17 +384,15 @@ struct rx_peer {
 
     /* For garbage collection */
     afs_uint32 idleWhen;       /* When the refcountwent to zero */
-    rx_atomic_t refCount;              /* Reference count */
-
+    afs_uint32 refCount;       /* Reference count for this structure (rx_peerHashTable_lock) */
 
     /* Congestion control parameters */
     u_char burstSize;          /* Reinitialization size for the burst parameter */
     u_char burst;              /* Number of packets that can be transmitted right now, without pausing */
     struct clock burstWait;    /* Delay until new burst is allowed */
     struct rx_queue congestionQueue;   /* Calls that are waiting for non-zero burst value */
-    int rtt;                   /* Round trip time, measured in milliseconds/8 */
-    int rtt_dev;               /* rtt smoothed error, in milliseconds/4 */
-    struct clock timeout;      /* Current retransmission delay */
+    int rtt;                   /* Smoothed round trip time, measured in milliseconds/8 */
+    int rtt_dev;               /* Smoothed rtt mean difference, in milliseconds/4 */
     int nSent;                 /* Total number of distinct data packets sent, not including retransmissions */
     int reSends;               /* Total number of retransmissions for this peer, since this structure was created */
 
@@ -440,7 +403,6 @@ struct rx_peer {
  * is likely to have been dropped. */
     afs_uint32 inPacketSkew;   /* Maximum skew on incoming packets */
     afs_uint32 outPacketSkew;  /* Peer-reported max skew on our sent packets */
-    int rateFlag;              /* Flag for rate testing (-no 0yes +decrement) */
 
     /* the "natural" MTU, excluding IP,UDP headers, is negotiated by the endpoints */
     u_short natMTU;
@@ -466,25 +428,29 @@ struct rx_peer {
     afs_hyper_t bytesReceived; /* Number of bytes received from this peer */
     struct rx_queue rpcStats;  /* rpc statistic list */
     int lastReachTime;         /* Last time we verified reachability */
+    afs_int32 maxPacketSize;    /* peer packetsize hint */
 };
 
-
 #ifndef KDUMP_RX_LOCK
 /* Flag bits for connection structure */
-#define        RX_CONN_MAKECALL_WAITING    1   /* rx_MakeCall is waiting for a channel */
+#define        RX_CONN_MAKECALL_WAITING    1   /* rx_NewCall is waiting for a channel */
 #define        RX_CONN_DESTROY_ME          2   /* Destroy *client* connection after last call */
 #define RX_CONN_USING_PACKET_CKSUM  4  /* non-zero header.spare field seen */
 #define RX_CONN_KNOW_WINDOW         8  /* window size negotiation works */
 #define RX_CONN_RESET             16   /* connection is reset, remove */
 #define RX_CONN_BUSY               32  /* connection is busy; don't delete */
 #define RX_CONN_ATTACHWAIT        64   /* attach waiting for peer->lastReach */
-#define RX_CLONED_CONNECTION     128   /* connection is a clone */
+#define RX_CONN_MAKECALL_ACTIVE   128   /* a thread is actively in rx_NewCall */
+#define RX_CONN_NAT_PING          256   /* nat ping requested */
 
 /* Type of connection, client or server */
 #define        RX_CLIENT_CONNECTION    0
 #define        RX_SERVER_CONNECTION    1
 #endif /* !KDUMP_RX_LOCK */
 
+/* Maximum number of acknowledgements in an acknowledge packet */
+#define        RX_MAXACKS          255
+
 /* Call structure:  only instantiated for active calls and dallying server calls.  The permanent call state (i.e. the call number as well as state shared with other calls associated with this connection) is maintained in the connection structure. */
 #ifdef KDUMP_RX_LOCK
 struct rx_call_rx_lock {
@@ -498,8 +464,8 @@ struct rx_call {
      * The following fields are accessed while the call is unlocked.
      * These fields are used by the caller/server thread to marshall
      * and unmarshall RPC data. The only time they may be changed by
-     * other threads is when the RX_CALL_IOVEC_WAIT flag is set. 
-     * 
+     * other threads is when the RX_CALL_IOVEC_WAIT flag is set.
+     *
      * NOTE: Be sure that these fields start and end on a double
      *       word boundary. Otherwise threads that are changing
      *       adjacent fields will cause problems.
@@ -541,6 +507,7 @@ struct rx_call {
     afs_uint32 rwind;          /* The receive window:  the peer must not send packets with sequence numbers >= rnext+rwind */
     afs_uint32 tfirst;         /* First unacknowledged transmit packet number */
     afs_uint32 tnext;          /* Next transmit sequence number to use */
+    afs_uint32 tprev;          /* Last packet that we saw an ack for */
     u_short twind;             /* The transmit window:  we cannot assign a sequence number to a packet >= tfirst + twind */
     u_short cwind;             /* The congestion window */
     u_short nSoftAcked;                /* Number soft acked transmit packets */
@@ -554,17 +521,22 @@ struct rx_call {
     u_short nSoftAcks;         /* The number of delayed soft acks */
     u_short nHardAcks;         /* The number of delayed hard acks */
     u_short congestSeq;                /* Peer's congestion sequence counter */
+    int rtt;
+    int rtt_dev;
+    struct clock rto;          /* The round trip timeout calculated for this call */
     struct rxevent *resendEvent;       /* If this is non-Null, there is a retransmission event pending */
     struct rxevent *timeoutEvent;      /* If this is non-Null, then there is an overall timeout for this call */
     struct rxevent *keepAliveEvent;    /* Scheduled periodically in active calls to keep call alive */
+    struct rxevent *growMTUEvent;      /* Scheduled periodically in active calls to discover true maximum MTU */
     struct rxevent *delayedAckEvent;   /* Scheduled after all packets are received to send an ack if a reply or new call is not generated soon */
+    struct clock delayedAckTime;        /* Time that next delayed ack was scheduled  for */
     struct rxevent *delayedAbortEvent; /* Scheduled to throttle looping client */
     int abortCode;             /* error code from last RPC */
     int abortCount;            /* number of times last error was sent */
     u_int lastSendTime;                /* Last time a packet was sent on this call */
     u_int lastReceiveTime;     /* Last time a packet was received for this call */
     u_int lastSendData;                /* Last time a nonping was sent on this call */
-    void (*arrivalProc) (register struct rx_call * call, register void * mh, register int index);      /* Procedure to call when reply is received */
+    void (*arrivalProc) (struct rx_call * call, void * mh, int index); /* Procedure to call when reply is received */
     void *arrivalProcHandle;   /* Handle to pass to replyFunc */
     int arrivalProcArg;         /* Additional arg to pass to reply Proc */
     afs_uint32 lastAcked;      /* last packet "hard" acked by receiver */
@@ -574,8 +546,8 @@ struct rx_call {
     u_short MTU;               /* size of packets currently sending */
 #ifdef RX_ENABLE_LOCKS
     short refCount;            /* Used to keep calls from disappearring
-                                * when we get them from a queue. */
-#endif                         /* RX_ENABLE_LOCKS */
+                                * when we get them from a queue. (rx_refcnt_lock) */
+#endif                          /* RX_ENABLE_LOCKS */
 /* Call refcount modifiers */
 #define RX_CALL_REFCOUNT_BEGIN  0      /* GetCall/NewCall/EndCall */
 #define RX_CALL_REFCOUNT_RESEND 1      /* resend event */
@@ -589,16 +561,27 @@ struct rx_call {
 #ifdef RX_REFCOUNT_CHECK
     short refCDebug[RX_CALL_REFCOUNT_MAX];
 #endif                         /* RX_REFCOUNT_CHECK */
+
+    /*
+     * iov, iovNBytes, iovMax, and iovNext are set in rxi_ReadvProc()
+     * and adjusted by rxi_FillReadVec().  iov does not own the buffers
+     * it refers to.  The buffers belong to the packets stored in iovq.
+     * Only one call to rx_ReadvProc() can be active at a time.
+     */
+
     int iovNBytes;             /* byte count for current iovec */
     int iovMax;                        /* number elements in current iovec */
     int iovNext;               /* next entry in current iovec */
     struct iovec *iov;         /* current iovec */
+
     struct clock queueTime;    /* time call was queued */
     struct clock startTime;    /* time call was started */
     afs_hyper_t bytesSent;     /* Number bytes sent */
     afs_hyper_t bytesRcvd;     /* Number bytes received */
     u_short tqWaiters;
 
+    struct rx_packet *xmitList[RX_MAXACKS]; /* Can't xmit more than we ack */
+                                /* Protected by setting RX_CALL_TQ_BUSY */
 #ifdef RXDEBUG_PACKET
     u_short tqc;                /* packet count in tq */
     u_short rqc;                /* packet count in rq */
@@ -620,6 +603,7 @@ struct rx_call {
 #define        RX_STATE_ACTIVE   2     /* An active call; a process is dealing with this call */
 #define        RX_STATE_DALLY    3     /* Dallying after process is done with call */
 #define        RX_STATE_HOLD     4     /* Waiting for acks on reply data packets */
+#define RX_STATE_RESET    5     /* Call is being reset */
 
 /* Call modes:  the modes of a call in RX_STATE_ACTIVE state (process attached) */
 #define        RX_MODE_SENDING   1     /* Sending or ready to send */
@@ -640,14 +624,15 @@ struct rx_call {
 #define RX_CALL_TQ_SOME_ACKED    512   /* rxi_Start needs to discard ack'd packets. */
 #define RX_CALL_TQ_WAIT                1024    /* Reader is waiting for TQ_BUSY to be reset */
 #define RX_CALL_FAST_RECOVER    2048   /* call is doing congestion recovery */
-#define RX_CALL_FAST_RECOVER_WAIT 4096 /* thread is waiting to start recovery */
+/* 4096 was RX_CALL_FAST_RECOVER_WAIT */
 #define RX_CALL_SLOW_START_OK   8192   /* receiver acks every other packet */
 #define RX_CALL_IOVEC_WAIT     16384   /* waiting thread is using an iovec */
 #define RX_CALL_HAVE_LAST      32768   /* Last packet has been received */
 #define RX_CALL_NEED_START     0x10000 /* tells rxi_Start to start again */
+#define RX_CALL_PEER_BUSY      0x20000 /* the last packet we received on this call was a
+                                         * BUSY packet; i.e. the channel for this call is busy */
+#define RX_CALL_ACKALL_SENT     0x40000 /* ACKALL has been sent on the call */
 
-/* Maximum number of acknowledgements in an acknowledge packet */
-#define        RX_MAXACKS          255
 
 /* The structure of the data portion of an acknowledge packet: An acknowledge
  * packet is in network byte order at all times.  An acknowledgement is always
@@ -703,8 +688,9 @@ struct rx_ackPacket {
 #define        RX_ACK_PING             6       /* This is a keep-alive ack */
 #define        RX_ACK_PING_RESPONSE    7       /* Ack'ing because we were pinged */
 #define        RX_ACK_DELAY            8       /* Ack generated since nothing has happened since receiving packet */
-#define RX_ACK_IDLE             9      /* Similar to RX_ACK_DELAY, but can 
+#define RX_ACK_IDLE             9      /* Similar to RX_ACK_DELAY, but can
                                         * be used to compute RTT */
+#define RX_ACK_MTU             -1       /* will be rewritten to ACK_PING */
 
 /* Packet acknowledgement type */
 #define        RX_ACK_TYPE_NACK        0       /* I Don't have this packet */
@@ -748,6 +734,13 @@ struct rx_ackPacket {
 /* this shud be equal to VRESTARTING ( util/errors.h ) for old clients to work */
 #define RX_RESTARTING              (-100)
 
+typedef enum {
+    RX_SECIDX_NULL = 0,
+    RX_SECIDX_KAD  = 2,
+    RX_SECIDX_GK   = 4,
+    RX_SECIDX_K5   = 5,
+} rx_securityIndex;
+
 struct rx_securityObjectStats {
     char type;                 /* 0:unk 1:null,2:vab 3:kad */
     char level;
@@ -764,7 +757,7 @@ struct rx_securityObjectStats {
 
 /* Configuration settings */
 
-/* Enum for storing configuration variables which can be set via the 
+/* Enum for storing configuration variables which can be set via the
  * SetConfiguration method in the rx_securityClass, below
  */
 
@@ -855,47 +848,47 @@ struct rx_securityClass {
  * must equal sizeof(afs_int32). */
 
 struct rx_statistics {         /* General rx statistics */
-    rx_atomic_t packetRequests;                /* Number of packet allocation requests */
-    rx_atomic_t receivePktAllocFailures;
-    rx_atomic_t sendPktAllocFailures;
-    rx_atomic_t specialPktAllocFailures;
-    rx_atomic_t socketGreedy;          /* Whether SO_GREEDY succeeded */
-    rx_atomic_t bogusPacketOnRead;     /* Number of inappropriately short packets received */
-    rx_atomic_t bogusHost;             /* Host address from bogus packets */
-    rx_atomic_t noPacketOnRead;                /* Number of read packets attempted when there was actually no packet to read off the wire */
-    rx_atomic_t noPacketBuffersOnRead; /* Number of dropped data packets due to lack of packet buffers */
-    rx_atomic_t selects;               /* Number of selects waiting for packet or timeout */
-    rx_atomic_t sendSelects;           /* Number of selects forced when sending packet */
-    rx_atomic_t packetsRead[RX_N_PACKET_TYPES];        /* Total number of packets read, per type */
-    rx_atomic_t dataPacketsRead;       /* Number of unique data packets read off the wire */
-    rx_atomic_t ackPacketsRead;                /* Number of ack packets read */
-    rx_atomic_t dupPacketsRead;                /* Number of duplicate data packets read */
-    rx_atomic_t spuriousPacketsRead;   /* Number of inappropriate data packets */
-    rx_atomic_t packetsSent[RX_N_PACKET_TYPES];        /* Number of rxi_Sends: packets sent over the wire, per type */
-    rx_atomic_t ackPacketsSent;                /* Number of acks sent */
-    rx_atomic_t pingPacketsSent;       /* Total number of ping packets sent */
-    rx_atomic_t abortPacketsSent;      /* Total number of aborts */
-    rx_atomic_t busyPacketsSent;       /* Total number of busies sent received */
-    rx_atomic_t dataPacketsSent;       /* Number of unique data packets sent */
-    rx_atomic_t dataPacketsReSent;     /* Number of retransmissions */
-    rx_atomic_t dataPacketsPushed;     /* Number of retransmissions pushed early by a NACK */
-    rx_atomic_t ignoreAckedPacket;     /* Number of packets with acked flag, on rxi_Start */
+    int packetRequests;                /* Number of packet allocation requests */
+    int receivePktAllocFailures;
+    int sendPktAllocFailures;
+    int specialPktAllocFailures;
+    int socketGreedy;          /* Whether SO_GREEDY succeeded */
+    int bogusPacketOnRead;     /* Number of inappropriately short packets received */
+    int bogusHost;             /* Host address from bogus packets */
+    int noPacketOnRead;                /* Number of read packets attempted when there was actually no packet to read off the wire */
+    int noPacketBuffersOnRead; /* Number of dropped data packets due to lack of packet buffers */
+    int selects;               /* Number of selects waiting for packet or timeout */
+    int sendSelects;           /* Number of selects forced when sending packet */
+    int packetsRead[RX_N_PACKET_TYPES];        /* Total number of packets read, per type */
+    int dataPacketsRead;       /* Number of unique data packets read off the wire */
+    int ackPacketsRead;                /* Number of ack packets read */
+    int dupPacketsRead;                /* Number of duplicate data packets read */
+    int spuriousPacketsRead;   /* Number of inappropriate data packets */
+    int packetsSent[RX_N_PACKET_TYPES];        /* Number of rxi_Sends: packets sent over the wire, per type */
+    int ackPacketsSent;                /* Number of acks sent */
+    int pingPacketsSent;       /* Total number of ping packets sent */
+    int abortPacketsSent;      /* Total number of aborts */
+    int busyPacketsSent;       /* Total number of busies sent received */
+    int dataPacketsSent;       /* Number of unique data packets sent */
+    int dataPacketsReSent;     /* Number of retransmissions */
+    int dataPacketsPushed;     /* Number of retransmissions pushed early by a NACK */
+    int ignoreAckedPacket;     /* Number of packets with acked flag, on rxi_Start */
     struct clock totalRtt;     /* Total round trip time measured (use to compute average) */
     struct clock minRtt;       /* Minimum round trip time measured */
     struct clock maxRtt;       /* Maximum round trip time measured */
-    rx_atomic_t nRttSamples;           /* Total number of round trip samples */
-    rx_atomic_t nServerConns;          /* Total number of server connections */
-    rx_atomic_t nClientConns;          /* Total number of client connections */
-    rx_atomic_t nPeerStructs;          /* Total number of peer structures */
-    rx_atomic_t nCallStructs;          /* Total number of call structures allocated */
-    rx_atomic_t nFreeCallStructs;      /* Total number of previously allocated free call structures */
-    rx_atomic_t netSendFailures;
-    rx_atomic_t fatalErrors;
-    rx_atomic_t ignorePacketDally;     /* packets dropped because call is in dally state */
-    rx_atomic_t receiveCbufPktAllocFailures;
-    rx_atomic_t sendCbufPktAllocFailures;
-    rx_atomic_t nBusies;
-    rx_atomic_t spares[4];
+    int nRttSamples;           /* Total number of round trip samples */
+    int nServerConns;          /* Total number of server connections */
+    int nClientConns;          /* Total number of client connections */
+    int nPeerStructs;          /* Total number of peer structures */
+    int nCallStructs;          /* Total number of call structures allocated */
+    int nFreeCallStructs;      /* Total number of previously allocated free call structures */
+    int netSendFailures;
+    afs_int32 fatalErrors;
+    int ignorePacketDally;     /* packets dropped because call is in dally state */
+    int receiveCbufPktAllocFailures;
+    int sendCbufPktAllocFailures;
+    int nBusies;
+    int spares[4];
 };
 
 /* structures for debug input and output packets */
@@ -948,45 +941,43 @@ struct rx_debugStats {
 
 struct rx_debugConn_vL {
     afs_uint32 host;
-    afs_uint32 cid;
-    struct rx_debugConn_vL *parent;    /* primary connection, if this is a clone */
-    afs_uint32 serial;
-    afs_uint32 callNumber[RX_MAXCALLS];
-    afs_uint32 error;
-    u_short port;
-    u_char flags;
-    u_char type;
-    u_char securityIndex;
-    u_char callState[RX_MAXCALLS];
-    u_char callMode[RX_MAXCALLS];
-    u_char callFlags[RX_MAXCALLS];
-    u_char callOther[RX_MAXCALLS];
+    afs_int32 cid;
+    afs_int32 serial;
+    afs_int32 callNumber[RX_MAXCALLS];
+    afs_int32 error;
+    short port;
+    char flags;
+    char type;
+    char securityIndex;
+    char callState[RX_MAXCALLS];
+    char callMode[RX_MAXCALLS];
+    char callFlags[RX_MAXCALLS];
+    char callOther[RX_MAXCALLS];
     /* old style getconn stops here */
     struct rx_securityObjectStats secStats;
-    afs_uint32 sparel[10];
+    afs_int32 sparel[10];
 };
 
 struct rx_debugConn {
     afs_uint32 host;
-    afs_uint32 cid;
-    struct rx_debugConn *parent;       /* primary connection, if this is a clone */
-    afs_uint32 serial;
-    afs_uint32 callNumber[RX_MAXCALLS];
-    afs_uint32 error;
-    u_short port;
-    u_char flags;
-    u_char type;
-    u_char securityIndex;
-    u_char sparec[3];          /* force correct alignment */
-    u_char callState[RX_MAXCALLS];
-    u_char callMode[RX_MAXCALLS];
-    u_char callFlags[RX_MAXCALLS];
-    u_char callOther[RX_MAXCALLS];
+    afs_int32 cid;
+    afs_int32 serial;
+    afs_int32 callNumber[RX_MAXCALLS];
+    afs_int32 error;
+    short port;
+    char flags;
+    char type;
+    char securityIndex;
+    char sparec[3];            /* force correct alignment */
+    char callState[RX_MAXCALLS];
+    char callMode[RX_MAXCALLS];
+    char callFlags[RX_MAXCALLS];
+    char callOther[RX_MAXCALLS];
     /* old style getconn stops here */
     struct rx_securityObjectStats secStats;
-    afs_uint32 epoch;
-    afs_uint32 natMTU;
-    afs_uint32 sparel[9];
+    afs_int32 epoch;
+    afs_int32 natMTU;
+    afs_int32 sparel[9];
 };
 
 struct rx_debugPeer {
@@ -1128,7 +1119,8 @@ typedef struct rx_interface_stat {
 
 #ifdef AFS_NT40_ENV
 extern int rx_DumpCalls(FILE *outputFile, char *cookie);
-#endif /* AFS_NT40_ENV */
+#endif
+
 #endif /* _RX_   End of rx.h */
 
 #ifdef KERNEL