rx: Don't malloc the xmit list
[openafs.git] / src / rx / rx.h
index eb9699e..8704990 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
@@ -122,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
@@ -167,14 +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)
@@ -214,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 {
@@ -244,8 +250,10 @@ struct rx_connection {
     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 */
@@ -253,8 +261,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) */
-    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 */
@@ -272,6 +280,9 @@ 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 */
 };
@@ -317,6 +328,12 @@ struct rx_service {
     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 */
@@ -371,7 +388,7 @@ struct rx_peer {
 
     /* 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 */
@@ -381,6 +398,7 @@ struct rx_peer {
     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 */
 
@@ -417,23 +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 {
@@ -447,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.
@@ -506,6 +534,7 @@ 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 */
@@ -523,8 +552,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 */
@@ -539,7 +568,7 @@ struct rx_call {
     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.
@@ -557,6 +586,11 @@ struct rx_call {
     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 */
@@ -578,6 +612,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 */
@@ -604,8 +639,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
@@ -661,8 +694,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 */
@@ -706,6 +740,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;
@@ -722,7 +763,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
  */
 
@@ -905,7 +946,7 @@ struct rx_debugStats {
 };
 
 struct rx_debugConn_vL {
-    afs_int32 host;
+    afs_uint32 host;
     afs_int32 cid;
     afs_int32 serial;
     afs_int32 callNumber[RX_MAXCALLS];
@@ -924,7 +965,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];
@@ -1084,58 +1125,7 @@ typedef struct rx_interface_stat {
 
 #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
 
 #endif /* _RX_   End of rx.h */