Rx: make conn_call_lock and conn_data_lock usage consistent
[openafs.git] / src / rx / rx.h
index 333b5fc..b51822a 100644 (file)
 #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)
@@ -162,6 +147,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))
@@ -182,6 +170,7 @@ int ntoh_syserr_conv(int error);
 /* 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))
@@ -250,6 +239,8 @@ 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 */
@@ -263,13 +254,13 @@ struct rx_connection {
     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 */
+    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 +271,9 @@ 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 */
     int nSpecific;             /* number entries in specific data */
     void **specific;           /* pointer to connection specific data */
 };
@@ -307,6 +301,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 +318,7 @@ 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;
 };
 
 #endif /* KDUMP_RX_LOCK */
@@ -357,10 +353,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,25 +365,23 @@ 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 */
 
     /* 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 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 */
@@ -431,16 +421,16 @@ struct rx_peer {
     int lastReachTime;         /* Last time we verified reachability */
 };
 
-
 #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
@@ -510,7 +500,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 */
@@ -525,8 +515,9 @@ struct rx_call {
     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 */
@@ -550,15 +541,37 @@ 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;
+
+#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 +581,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 */
@@ -652,7 +666,7 @@ struct rx_ackPacket {
 #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 */
+                                        * be used to compute RTT */
 
 /* Packet acknowledgement type */
 #define        RX_ACK_TYPE_NACK        0       /* I Don't have this packet */
@@ -696,6 +710,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 +731,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 +786,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 +812,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 +823,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 +879,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 +892,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,7 +911,8 @@ 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 {
@@ -996,6 +1038,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 +1093,60 @@ 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);
+
+#define rx_MutexIncrement(object, mutex) InterlockedIncrement(&object)
+#define rx_MutexAdd(object, addend, mutex) InterlockedExchangeAdd(&object, addend)
+#define rx_MutexDecrement(object, mutex) InterlockedDecrement(&object)
+#define rx_MutexAdd1Increment2(object1, addend, object2, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object1 += addend; \
+        InterlockedIncrement(&object2); \
+        MUTEX_EXIT(&mutex); \
+    } while (0)
+#define rx_MutexAdd1Decrement2(object1, addend, object2, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object1 += addend; \
+        InterlockedDecrement(&object2); \
+        MUTEX_EXIT(&mutex); \
+    } while (0)
+#else
+#define rx_MutexIncrement(object, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object++; \
+        MUTEX_EXIT(&mutex); \
+    } while(0)
+#define rx_MutexAdd(object, addend, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object += addend; \
+        MUTEX_EXIT(&mutex); \
+    } while(0)
+#define rx_MutexAdd1Increment2(object1, addend, object2, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object1 += addend; \
+        object2++; \
+        MUTEX_EXIT(&mutex); \
+    } while(0)
+#define rx_MutexAdd1Decrement2(object1, addend, object2, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object1 += addend; \
+        object2--; \
+        MUTEX_EXIT(&mutex); \
+    } while(0)
+#define rx_MutexDecrement(object, mutex) \
+    do { \
+        MUTEX_ENTER(&mutex); \
+        object--; \
+        MUTEX_EXIT(&mutex); \
+    } while(0)
+#endif 
 
 #endif /* _RX_   End of rx.h */