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 */