rx: rx_conn/rx_peer refCount signed
[openafs.git] / src / rx / rx.h
index 81e4190..97a9f49 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
@@ -122,6 +113,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
@@ -155,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))
@@ -167,9 +166,6 @@ 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 */
@@ -217,7 +213,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,12 +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 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 */
@@ -257,7 +256,7 @@ 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 */
+    afs_int32 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 */
@@ -318,6 +317,7 @@ 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 */
@@ -384,7 +384,7 @@ struct rx_peer {
 
     /* For garbage collection */
     afs_uint32 idleWhen;       /* When the refcountwent to zero */
-    afs_uint32 refCount;       /* Reference count for this structure */
+    afs_int32 refCount;                /* Reference count for this structure (rx_peerHashTable_lock) */
 
     /* Congestion control parameters */
     u_char burstSize;          /* Reinitialization size for the burst parameter */
@@ -393,7 +393,6 @@ struct rx_peer {
     struct rx_queue congestionQueue;   /* Calls that are waiting for non-zero burst value */
     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 */
 
@@ -404,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;
@@ -443,12 +441,16 @@ struct rx_peer {
 #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 */
+#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 {
@@ -462,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.
@@ -505,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 */
@@ -518,10 +521,15 @@ 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 */
@@ -538,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 */
@@ -554,7 +562,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.
@@ -572,6 +580,8 @@ 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 RXDEBUG_PACKET
     u_short tqc;                /* packet count in tq */
     u_short rqc;                /* packet count in rq */
@@ -614,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
@@ -677,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 */
@@ -745,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
  */
 
@@ -928,7 +940,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];
@@ -947,7 +959,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];
@@ -1107,58 +1119,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 */