Rx: Reject out of order ACK packets
[openafs.git] / src / rx / rx.h
index 333b5fc..2c05d30 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
 #define _RX_
 
 #ifndef KDUMP_RX_LOCK
-/* Substitute VOID (char) for void, because some compilers are confused by void
- * in some situations */
-#ifndef AFS_NT40_ENV
-#define        VOID    char
-#endif
-
 #ifdef KERNEL
 #include "rx_kmutex.h"
 #include "rx_kernel.h"
@@ -46,6 +40,7 @@
 #else /* KERNEL */
 # include <sys/types.h>
 # include <stdio.h>
+# include <string.h>
 #ifdef AFS_PTHREAD_ENV
 # include "rx_pthread.h"
 #else
@@ -98,7 +93,7 @@
 #ifndef KERNEL
 typedef void (*rx_destructor_t) (void *);
 int rx_KeyCreate(rx_destructor_t);
-osi_socket rxi_GetHostUDPSocket(struct sockaddr_storage *saddr, int salen);
+osi_socket rxi_GetHostUDPSocket(u_int host, u_short port);
 osi_socket rxi_GetUDPSocket(u_short port);
 #endif /* KERNEL */
 
@@ -110,18 +105,8 @@ int ntoh_syserr_conv(int error);
 
 #define        rx_ConnectionOf(call)           ((call)->conn)
 #define        rx_PeerOf(conn)                 ((conn)->peer)
-#ifdef AF_INET6
-#define        rx_HostOf(peer)                 ((peer)->saddr.ss_family == AF_INET ? \
-               ((struct sockaddr_in *) &(peer)->saddr)->sin_addr.s_addr : \
-                                                               0xffffffff)
-#define        rx_PortOf(peer)                 ((peer)->saddr.ss_family == AF_INET ? \
-               ((struct sockaddr_in *) &(peer)->saddr)->sin_port : \
-               ((struct sockaddr_in6 *) &(peer)->saddr)->sin6_port)
-#else /* AF_INET6 */
-#define rx_HostOf(peer)                        (((struct sockaddr_in *) &(peer)->saddr)->sin_addr.saddr)
-#define rx_PortOf(peer)                        (((struct sockaddr_in *) &(peer)->saddr)->sin_port)
-#endif /* AF_INET6 */
-#define rx_AddrStringOf(peer)          ((peer)->addrstring)
+#define        rx_HostOf(peer)                 ((peer)->host)
+#define        rx_PortOf(peer)                 ((peer)->port)
 #define        rx_SetLocalStatus(call, status) ((call)->localStatus = (status))
 #define rx_GetLocalStatus(call, status) ((call)->localStatus)
 #define        rx_GetRemoteStatus(call)        ((call)->remoteStatus)
@@ -137,6 +122,12 @@ int ntoh_syserr_conv(int error);
 #define        rx_SecurityClassOf(conn)        ((conn)->securityIndex)
 #define rx_SecurityObjectOf(conn)      ((conn)->securityObject)
 
+static_inline int
+rx_IsLoopbackAddr(afs_uint32 addr)
+{
+    return ((addr & 0xffff0000) == 0x7f000000);
+}
+
 /*******************
  * Macros callable by the user to further define attributes of a
  * service.  Must be called before rx_StartServer
@@ -162,6 +153,9 @@ int ntoh_syserr_conv(int error);
 /* Define procedure to set service dead time */
 #define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time))
 
+/* Define error to return in server connections when failing to answer */
+#define rx_SetServerIdleDeadErr(service,err) ((service)->idleDeadErr = (err))
+
 /* Define procedures for getting and setting before and after execute-request procs */
 #define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc))
 #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc))
@@ -179,13 +173,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) ((conn)->hardDeadTime = (seconds))
-#define rx_SetConnIdleDeadTime(conn, seconds) ((conn)->idleDeadTime = (seconds))
+#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)
@@ -225,7 +220,7 @@ returned with an error code of RX_CALL_DEAD ( transient error ) */
 
 #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 {
@@ -250,11 +245,15 @@ struct rx_connection {
     struct rx_call *call[RX_MAXCALLS];
 #endif
     afs_uint32 callNumber[RX_MAXCALLS];        /* Current call numbers */
+    afs_uint32 rwind[RX_MAXCALLS];
+    u_short twind[RX_MAXCALLS];
     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 */
@@ -262,14 +261,14 @@ 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) */
-    afs_uint32 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 */
     /* securityObject for this conn */
     struct rx_securityClass *securityObject;   /* Security object for this connection */
-    VOID *securityData;                /* Private data for this conn's security class */
+    void *securityData;                /* Private data for this conn's security class */
     u_short securityHeaderSize;        /* Length of security module's packet header data */
     u_short securityMaxTrailerSize;    /* Length of security module's packet trailer data */
 
@@ -280,6 +279,10 @@ struct rx_connection {
     u_short idleDeadTime;      /* max time a call can be idle (no data) */
     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 */
 };
@@ -307,6 +310,7 @@ struct rx_connection {
 
 struct rx_service {
     u_short serviceId;         /* Service number */
+    afs_uint32 serviceHost;    /* IP address for this service */
     u_short servicePort;       /* UDP port for this service */
     char *serviceName;         /* Name of the service */
     osi_socket socket;         /* socket structure or file descriptor */
@@ -323,6 +327,13 @@ struct rx_service {
     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 */
@@ -357,10 +368,6 @@ struct rx_serverQueueEntry {
     osi_socket *socketp;
 };
 
-/* If we don't support IPv6, use this as a fallback */
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif /* INET6_ADDRSTRLEN */
 
 /* A peer refers to a peer process, specified by a (host,port) pair.  There may be more than one peer on a given host. */
 #ifdef KDUMP_RX_LOCK
@@ -373,26 +380,25 @@ struct rx_peer {
 #ifdef RX_ENABLE_LOCKS
     afs_kmutex_t peer_lock;    /* Lock peer */
 #endif                         /* RX_ENABLE_LOCKS */
-    struct sockaddr_storage saddr;     /* Remote address structure */
-    int saddrlen;                      /* Length of saddr */
-    int socktype;                      /* Socket type (SOCK_DGRAM, etc) */
-    char addrstring[INET6_ADDRSTRLEN];  /* Printable address format */
+    afs_uint32 host;           /* Remote IP address, in net byte order */
+    u_short port;              /* Remote UDP port, in net byte order */
 
     /* interface mtu probably used for this host  -  includes RX Header */
     u_short ifMTU;             /* doesn't include IP header */
 
     /* For garbage collection */
     afs_uint32 idleWhen;       /* When the refcountwent to zero */
-    afs_uint32 refCount;               /* Reference count for this structure */
+    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 */
+    int rtt;                   /* Smoothed round trip time, measured in milliseconds/8 */
+    int rtt_dev;               /* Smoothed rtt mean difference, in milliseconds/4 */
     struct clock timeout;      /* Current retransmission delay */
+    int backedOff;              /* Has the timeout been backed off due to a missing packet? */
     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 */
 
@@ -429,24 +435,33 @@ 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 */
 
+#ifdef ADAPT_WINDOW
+    afs_int32 smRtt;
+    afs_int32 countDown;
+#endif
+};
 
 #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_CONN_MAKECALL_ACTIVE   128   /* a thread is actively in rx_NewCall */
 
 /* 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 {
@@ -460,8 +475,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.
@@ -503,6 +518,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 */
@@ -510,7 +526,7 @@ struct rx_call {
     u_short nCwindAcks;                /* Number acks received at current cwind */
     u_short ssthresh;          /* The slow start threshold */
     u_short nDgramPackets;     /* Packets per AFS 3.5 jumbogram */
-    u_short nAcks;             /* The number of consecttive acks */
+    u_short nAcks;             /* The number of consecutive acks */
     u_short nNacks;            /* Number packets acked that follow the
                                 * first negatively acked packet */
     u_short nSoftAcks;         /* The number of delayed soft acks */
@@ -519,14 +535,16 @@ struct rx_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 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 */
-    void (*arrivalProc) (register struct rx_call * call, register VOID * mh, register int index);      /* Procedure to call when reply is received */
-    VOID *arrivalProcHandle;   /* Handle to pass to replyFunc */
+    u_int lastSendData;                /* Last time a nonping was sent on this call */
+    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 */
     afs_uint32 startWait;      /* time server began waiting for input data/send quota */
@@ -535,8 +553,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 */
@@ -550,15 +568,42 @@ 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 ADAPT_WINDOW
+    struct clock pingRequestTime;
+#endif
+#ifdef RXDEBUG_PACKET
+    u_short tqc;                /* packet count in tq */
+    u_short rqc;                /* packet count in rq */
+    u_short iovqc;              /* packet count in iovq */
+
+#ifdef KDUMP_RX_LOCK
+    struct rx_call_rx_lock *allNextp;
+#else
+    struct rx_call *allNextp;
+#endif
+    afs_uint32 call_id;
+#endif
 };
 
 #ifndef KDUMP_RX_LOCK
@@ -568,6 +613,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 */
@@ -594,8 +640,6 @@ struct rx_call {
 #define RX_CALL_HAVE_LAST      32768   /* Last packet has been received */
 #define RX_CALL_NEED_START     0x10000 /* tells rxi_Start to start again */
 
-/* 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
@@ -651,8 +695,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 
-                                        * be */
+#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 */
@@ -696,6 +741,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;
@@ -710,6 +762,21 @@ struct rx_securityObjectStats {
     afs_int32 sparel[8];
 };
 
+/* Configuration settings */
+
+/* Enum for storing configuration variables which can be set via the
+ * SetConfiguration method in the rx_securityClass, below
+ */
+
+typedef enum {
+     RXS_CONFIG_FLAGS /* afs_uint32 set of bitwise flags */
+} rx_securityConfigVariables;
+
+/* For the RXS_CONFIG_FLAGS, the following bit values are defined */
+
+/* Disable the principal name contains dot check in rxkad */
+#define RXS_CONFIG_FLAGS_DISABLE_DOTCHECK      0x01
+
 /* XXXX (rewrite this description) A security class object contains a set of
  * procedures and some private data to implement a security model for rx
  * connections.  These routines are called by rx as appropriate.  Rx knows
@@ -750,11 +817,15 @@ struct rx_securityClass {
        int (*op_GetStats) (struct rx_securityClass * aobj,
                            struct rx_connection * aconn,
                            struct rx_securityObjectStats * astats);
-       int (*op_Spare1) (void);
+       int (*op_SetConfiguration) (struct rx_securityClass * aobj,
+                                   struct rx_connection * aconn,
+                                   rx_securityConfigVariables atype,
+                                   void * avalue,
+                                   void ** acurrentValue);
        int (*op_Spare2) (void);
        int (*op_Spare3) (void);
     } *ops;
-    VOID *privateData;
+    void *privateData;
     int refCount;
 };
 
@@ -772,7 +843,7 @@ struct rx_securityClass {
 #define RXS_CheckPacket(obj,call,packet) RXS_OP(obj,CheckPacket,(obj,call,packet))
 #define RXS_DestroyConnection(obj,conn) RXS_OP(obj,DestroyConnection,(obj,conn))
 #define RXS_GetStats(obj,conn,stats) RXS_OP(obj,GetStats,(obj,conn,stats))
-
+#define RXS_SetConfiguration(obj, conn, type, value, currentValue) RXS_OP(obj, SetConfiguration,(obj,conn,type,value,currentValue))
 
 
 /* Structure for keeping rx statistics.  Note that this structure is returned
@@ -783,7 +854,7 @@ struct rx_securityClass {
  * Clearly we assume that ntohl will work on these structures so sizeof(int)
  * must equal sizeof(afs_int32). */
 
-struct rx_stats {              /* General rx statistics */
+struct rx_statistics {         /* General rx statistics */
     int packetRequests;                /* Number of packet allocation requests */
     int receivePktAllocFailures;
     int sendPktAllocFailures;
@@ -839,7 +910,7 @@ struct rx_debugIn {
 #define RX_DEBUGI_BADTYPE     (-8)
 
 #define RX_DEBUGI_VERSION_MINIMUM ('L')        /* earliest real version */
-#define RX_DEBUGI_VERSION     ('R')    /* Latest version */
+#define RX_DEBUGI_VERSION     ('S')    /* Latest version */
     /* first version w/ secStats */
 #define RX_DEBUGI_VERSION_W_SECSTATS ('L')
     /* version M is first supporting GETALLCONN and RXSTATS type */
@@ -852,6 +923,7 @@ struct rx_debugIn {
 #define RX_DEBUGI_VERSION_W_NEWPACKETTYPES ('P')
 #define RX_DEBUGI_VERSION_W_GETPEER ('Q')
 #define RX_DEBUGI_VERSION_W_WAITED ('R')
+#define RX_DEBUGI_VERSION_W_PACKETS ('S')
 
 #define        RX_DEBUGI_GETSTATS      1       /* get basic rx stats */
 #define        RX_DEBUGI_GETCONN       2       /* get connection info */
@@ -870,11 +942,12 @@ struct rx_debugStats {
     afs_int32 nWaiting;
     afs_int32 idleThreads;     /* Number of server threads that are idle */
     afs_int32 nWaited;
-    afs_int32 spare2[7];
+    afs_int32 nPackets;
+    afs_int32 spare2[6];
 };
 
 struct rx_debugConn_vL {
-    afs_int32 host;
+    afs_uint32 host;
     afs_int32 cid;
     afs_int32 serial;
     afs_int32 callNumber[RX_MAXCALLS];
@@ -893,7 +966,7 @@ struct rx_debugConn_vL {
 };
 
 struct rx_debugConn {
-    afs_int32 host;
+    afs_uint32 host;
     afs_int32 cid;
     afs_int32 serial;
     afs_int32 callNumber[RX_MAXCALLS];
@@ -996,6 +1069,7 @@ extern int rx_callHoldType;
 #define RX_SERVER_DEBUG_NEW_PACKETS            0x40
 #define RX_SERVER_DEBUG_ALL_PEER               0x80
 #define RX_SERVER_DEBUG_WAITED_CNT              0x100
+#define RX_SERVER_DEBUG_PACKETS_CNT              0x200
 
 #define AFS_RX_STATS_CLEAR_ALL                 0xffffffff
 #define AFS_RX_STATS_CLEAR_INVOCATIONS         0x1
@@ -1050,27 +1124,9 @@ typedef struct rx_interface_stat {
 
 #define RX_STATS_SERVICE_ID 409
 
-/*
- * Definitions for handling struct sockaddr_storage casts, and IPv6
- */
-
-#ifdef AF_INET6
-#define rx_ss2pn(x) ((x)->ss_family == AF_INET6 ? \
-                       ((struct sockaddr_in6 *) (x))->sin6_port : \
-                       ((struct sockaddr_in *) (x))->sin_port)
-#define rx_ss2sin6(x) ((struct sockaddr_in6 *) (x))
-#define rx_ssfamily(x) ((x)->ss_family)
-#define rx_ss2addrp6(x) ((afs_uint16 *) &(((struct sockaddr_in6 *) (x))->sin6_addr.s6_addr))
-#define rx_ss2v4addr(x) ((x)->ss_family == AF_INET ? \
-                       ((struct sockaddr_in *) (x))->sin_addr.s_addr : \
-                       0xffffffff)
-#else /* AF_INET6 */
-#define rx_ss2pn(x) (((struct sockaddr_in *) (x))->sin_port)
-#define rx_ssfamily(x) (((struct sockaddr_in *) (x))->sin_family)
-#define rx_ss2v4addr(x) (((struct sockaddr_in *) (x))->sin_addr.s_addr)
-#endif /* AF_INET6 */
-#define rx_ss2sin(x) ((struct sockaddr_in *) (x))
-#define rx_ss2addrp(x) ((unsigned char *) &(((struct sockaddr_in *) (x))->sin_addr.s_addr))
+#ifdef AFS_NT40_ENV
+extern int rx_DumpCalls(FILE *outputFile, char *cookie);
+#endif
 
 #endif /* _RX_   End of rx.h */