RX: Force sane timeout values
[openafs.git] / src / rx / rx.h
index f1635d2..49614aa 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
@@ -64,6 +64,7 @@
 #endif
 #endif /* KERNEL */
 
+
 /* Configurable parameters */
 #define        RX_IDLE_DEAD_TIME       60      /* default idle dead time */
 #define        RX_MAX_SERVICES         20      /* Maximum number of services that may be installed */
@@ -110,24 +111,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
@@ -174,35 +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)\
-    {\
-    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)
@@ -240,23 +218,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);
-
 #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 {
@@ -264,7 +228,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
@@ -283,20 +247,22 @@ struct rx_connection {
     afs_uint32 callNumber[RX_MAXCALLS];        /* Current call numbers */
     afs_uint32 rwind[RX_MAXCALLS];
     u_short twind[RX_MAXCALLS];
-    u_short serviceId;         /* To stamp on requests (clients only) */
     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 */
     int abortCount;            /* count of abort messages sent */
     /* client-- to retransmit the challenge */
     struct rx_service *service;        /* used by servers only */
-    afs_uint32 refCount;               /* Reference count */
-    u_char flags;              /* Defined below */
+    u_short serviceId;         /* To stamp on requests (clients only) */
+    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 */
@@ -312,14 +278,13 @@ struct rx_connection {
     u_short hardDeadTime;      /* hard max for call execution */
     u_short idleDeadTime;      /* max time a call can be idle (no data) */
     u_char ackRate;            /* how many packets between ack requests */
-    u_char spareb;
-    afs_int32 makeCallWaiters; /* how many rx_NewCalls are waiting */
+    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) */
 };
 
 
@@ -363,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 */
@@ -417,16 +388,17 @@ 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 */
     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 */
 
@@ -463,19 +435,24 @@ 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_CLONED_CONNECTION     128   /* connection is a clone */
+#define RX_CONN_MAKECALL_ACTIVE   128   /* a thread is actively in rx_NewCall */
 
 /* Type of connection, client or server */
 #define        RX_CLIENT_CONNECTION    0
@@ -495,8 +472,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.
@@ -545,7 +522,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 */
@@ -554,6 +531,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 */
@@ -561,7 +539,7 @@ struct rx_call {
     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 */
@@ -571,8 +549,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 */
@@ -586,15 +564,40 @@ 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 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
@@ -604,6 +607,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 */
@@ -687,8 +691,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 */
@@ -732,6 +737,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;
@@ -748,7 +760,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
  */
 
@@ -932,45 +944,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 {
@@ -1110,6 +1120,10 @@ typedef struct rx_interface_stat {
 
 #define RX_STATS_SERVICE_ID 409
 
+#ifdef AFS_NT40_ENV
+extern int rx_DumpCalls(FILE *outputFile, char *cookie);
+#endif
+
 #endif /* _RX_   End of rx.h */
 
 #ifdef KERNEL