You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ar...@apache.org on 2022/01/26 03:50:56 UTC

[incubator-nuttx] branch master updated: net/tcp: transformed NET_TCP_FAST_RETRANSMIT_WATERMARK option to boolean. According to RFC 5681 (3.2) the TCP Fast Retransmit algorithm should start if the threshold of 3 duplicate ACKs is reached. Thus the threshold should be a constant, not an integer option.

This is an automated email from the ASF dual-hosted git repository.

archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 2a6de30  net/tcp: transformed NET_TCP_FAST_RETRANSMIT_WATERMARK option to boolean. According to RFC 5681 (3.2) the TCP Fast Retransmit algorithm should start if the threshold of 3 duplicate ACKs is reached. Thus the threshold should be a constant, not an integer option.
2a6de30 is described below

commit 2a6de301ee34a2978f0530eea60fe2b1c5732dfa
Author: Alexander Lunev <al...@mail.ru>
AuthorDate: Tue Jan 25 20:49:04 2022 +0300

    net/tcp: transformed NET_TCP_FAST_RETRANSMIT_WATERMARK option to boolean.
    According to RFC 5681 (3.2) the TCP Fast Retransmit algorithm should start
    if the threshold of 3 duplicate ACKs is reached.
    Thus the threshold should be a constant, not an integer option.
---
 net/tcp/Kconfig               |  6 +++---
 net/tcp/tcp.h                 | 10 ++++++++++
 net/tcp/tcp_send_buffered.c   |  8 ++++----
 net/tcp/tcp_send_unbuffered.c |  7 +++++--
 net/tcp/tcp_sendfile.c        |  7 +++++--
 net/tcp/tcp_wrbuffer.c        |  2 ++
 6 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/net/tcp/Kconfig b/net/tcp/Kconfig
index d41368b..f16dd5b 100644
--- a/net/tcp/Kconfig
+++ b/net/tcp/Kconfig
@@ -79,9 +79,9 @@ config NET_MAX_LISTENPORTS
 	---help---
 		Maximum number of listening TCP/IP ports (all tasks).  Default: 20
 
-config NET_TCP_FAST_RETRANSMIT_WATERMARK
-	int "WaterMark to trigger Fast Retransmission"
-	default 3
+config NET_TCP_FAST_RETRANSMIT
+	bool "Enable the Fast Retransmit algorithm"
+	default y
 	---help---
 		RFC2001:
 		3.  Fast Retransmit
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index 60dd1e3..0c6e539 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -65,7 +65,9 @@
 #  define TCP_WBPKTLEN(wrb)          ((wrb)->wb_iob->io_pktlen)
 #  define TCP_WBSENT(wrb)            ((wrb)->wb_sent)
 #  define TCP_WBNRTX(wrb)            ((wrb)->wb_nrtx)
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
 #  define TCP_WBNACK(wrb)            ((wrb)->wb_nack)
+#endif
 #  define TCP_WBIOB(wrb)             ((wrb)->wb_iob)
 #  define TCP_WBCOPYOUT(wrb,dest,n)  (iob_copyout(dest,(wrb)->wb_iob,(n),0))
 #  define TCP_WBCOPYIN(wrb,src,n,off) \
@@ -101,6 +103,12 @@
 
 #define TCP_WSCALE            0x01U /* Window Scale option enabled */
 
+/* After receiving 3 duplicate ACKs, TCP performs a retransmission
+ * (RFC 5681 (3.2))
+ */
+
+#define TCP_FAST_RETRANSMISSION_THRESH 3
+
 /****************************************************************************
  * Public Type Definitions
  ****************************************************************************/
@@ -330,7 +338,9 @@ struct tcp_wrbuffer_s
   uint16_t   wb_sent;      /* Number of bytes sent from the I/O buffer chain */
   uint8_t    wb_nrtx;      /* The number of retransmissions for the last
                             * segment sent */
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
   uint8_t    wb_nack;      /* The number of ack count */
+#endif
   struct iob_s *wb_iob;    /* Head of the I/O buffer chain */
 };
 #endif
diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c
index f79baa1..894e9ed 100644
--- a/net/tcp/tcp_send_buffered.c
+++ b/net/tcp/tcp_send_buffered.c
@@ -543,6 +543,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
                         wrb, TCP_WBSEQNO(wrb), TCP_WBPKTLEN(wrb));
                 }
             }
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
           else if (ackno == TCP_WBSEQNO(wrb))
             {
               /* Reset the duplicate ack counter */
@@ -554,15 +555,13 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
 
               /* Duplicate ACK? Retransmit data if need */
 
-              if (++TCP_WBNACK(wrb) ==
-                  CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
+              if (++TCP_WBNACK(wrb) == TCP_FAST_RETRANSMISSION_THRESH)
                 {
                   /* Do fast retransmit */
 
                   rexmit = true;
                 }
-              else if ((TCP_WBNACK(wrb) >
-                       CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK) &&
+              else if ((TCP_WBNACK(wrb) > TCP_FAST_RETRANSMISSION_THRESH) &&
                        TCP_WBNACK(wrb) == sq_count(&conn->unacked_q) - 1)
                 {
                   /* Reset the duplicate ack counter */
@@ -570,6 +569,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
                   TCP_WBNACK(wrb) = 0;
                 }
             }
+#endif
         }
 
       /* A special case is the head of the write_q which may be partially
diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c
index d8cd411..8145ae5 100644
--- a/net/tcp/tcp_send_unbuffered.c
+++ b/net/tcp/tcp_send_unbuffered.c
@@ -88,6 +88,7 @@ struct send_s
   ssize_t                 snd_sent;     /* The number of bytes sent */
   uint32_t                snd_isn;      /* Initial sequence number */
   uint32_t                snd_acked;    /* The number of bytes acked */
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
   uint32_t                snd_prev_ack; /* The previous ACKed seq number */
 #ifdef CONFIG_NET_TCP_WINDOW_SCALE
   uint32_t                snd_prev_wnd; /* The advertised window in the last
@@ -97,6 +98,7 @@ struct send_s
   uint16_t                snd_prev_wnd;
 #endif
   int                     snd_dup_acks; /* Duplicate ACK counter */
+#endif
 };
 
 /****************************************************************************
@@ -274,6 +276,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
           goto end_wait;
         }
 
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
       /* Fast Retransmit (RFC 5681): an acknowledgment is considered a
        * "duplicate" when (a) the receiver of the ACK has outstanding data,
        * (b) the incoming acknowledgment carries no data, (c) the SYN and
@@ -289,8 +292,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
           ackno == pstate->snd_prev_ack &&
           conn->snd_wnd == pstate->snd_prev_wnd)
         {
-          if (++pstate->snd_dup_acks >=
-                CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
+          if (++pstate->snd_dup_acks >= TCP_FAST_RETRANSMISSION_THRESH)
             {
               flags |= TCP_REXMIT;
               pstate->snd_dup_acks = 0;
@@ -303,6 +305,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
 
       pstate->snd_prev_ack = ackno;
       pstate->snd_prev_wnd = conn->snd_wnd;
+#endif
     }
 
   /* Check if we are being asked to retransmit data.
diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c
index 5ee6f40..1c1a109 100644
--- a/net/tcp/tcp_sendfile.c
+++ b/net/tcp/tcp_sendfile.c
@@ -84,6 +84,7 @@ struct sendfile_s
   ssize_t            snd_sent;             /* The number of bytes sent */
   uint32_t           snd_isn;              /* Initial sequence number */
   uint32_t           snd_acked;            /* The number of bytes acked */
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
   uint32_t           snd_prev_ack;         /* The previous ACKed seq number */
 #ifdef CONFIG_NET_TCP_WINDOW_SCALE
   uint32_t           snd_prev_wnd;         /* The advertised window in the last
@@ -93,6 +94,7 @@ struct sendfile_s
   uint16_t           snd_prev_wnd;
 #endif
   int                snd_dup_acks;         /* Duplicate ACK counter */
+#endif
 };
 
 /****************************************************************************
@@ -227,6 +229,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
           goto end_wait;
         }
 
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
       /* Fast Retransmit (RFC 5681): an acknowledgment is considered a
        * "duplicate" when (a) the receiver of the ACK has outstanding data,
        * (b) the incoming acknowledgment carries no data, (c) the SYN and
@@ -242,8 +245,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
           ackno == pstate->snd_prev_ack &&
           conn->snd_wnd == pstate->snd_prev_wnd)
         {
-          if (++pstate->snd_dup_acks >=
-                CONFIG_NET_TCP_FAST_RETRANSMIT_WATERMARK)
+          if (++pstate->snd_dup_acks >= TCP_FAST_RETRANSMISSION_THRESH)
             {
               flags |= TCP_REXMIT;
               pstate->snd_dup_acks = 0;
@@ -256,6 +258,7 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev,
 
       pstate->snd_prev_ack = ackno;
       pstate->snd_prev_wnd = conn->snd_wnd;
+#endif
     }
 
   /* Check if we are being asked to retransmit data.
diff --git a/net/tcp/tcp_wrbuffer.c b/net/tcp/tcp_wrbuffer.c
index 27d9121..a93a2bc 100644
--- a/net/tcp/tcp_wrbuffer.c
+++ b/net/tcp/tcp_wrbuffer.c
@@ -243,9 +243,11 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb)
       iob_free_chain(wrb->wb_iob, IOBUSER_NET_TCP_WRITEBUFFER);
     }
 
+#ifdef CONFIG_NET_TCP_FAST_RETRANSMIT
   /* Reset the ack counter */
 
   TCP_WBNACK(wrb) = 0;
+#endif
 
   /* Then free the write buffer structure */