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 <alexanderlu...@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 */