From 1c80675e87521f2868592337c1d715f4ae597ea3 Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Mon, 4 Jul 2022 00:58:44 +0800 Subject: [PATCH] net/tcp: fix regression of invalid update the rexmit_seq in buffer mode fix regression of invalid update the rexmit_seq in buffer mode rexmit_seq should not be used instead of sndseq in fast retransmission, sndseq of retransmission in the packet does not need to be re-updated Signed-off-by: chao.an --- net/tcp/tcp.h | 3 +++ net/tcp/tcp_appsend.c | 30 +++++++++++++++++++----------- net/tcp/tcp_send_buffered.c | 3 --- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 78147ed352..c11550d742 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -175,7 +175,10 @@ struct tcp_conn_s uint8_t rcvseq[4]; /* The sequence number that we expect to * receive next */ uint8_t sndseq[4]; /* The sequence number that was last sent by us */ +#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) || \ + defined(CONFIG_NET_SENDFILE) uint32_t rexmit_seq; /* The sequence number to be retrasmitted */ +#endif uint8_t crefs; /* Reference counts on this instance */ #if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) uint8_t domain; /* IP domain: PF_INET or PF_INET6 */ diff --git a/net/tcp/tcp_appsend.c b/net/tcp/tcp_appsend.c index 39b120f3d8..1f87f87431 100644 --- a/net/tcp/tcp_appsend.c +++ b/net/tcp/tcp_appsend.c @@ -322,23 +322,31 @@ void tcp_rexmit(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, * new data in it, we must send out a packet. */ - if ((result & TCP_REXMIT) != 0 && - dev->d_sndlen > 0 && conn->tx_unacked > 0) +#if defined(CONFIG_NET_TCP_WRITE_BUFFERS) && defined(CONFIG_NET_SENDFILE) + if (conn->sendfile) +#endif { - uint32_t saveseq; +#if !defined(CONFIG_NET_TCP_WRITE_BUFFERS) || defined(CONFIG_NET_SENDFILE) + if ((result & TCP_REXMIT) != 0 && + dev->d_sndlen > 0 && conn->tx_unacked > 0 && + conn->rexmit_seq > 0) + { + uint32_t saveseq; - /* According to RFC 6298 (5.4), retransmit the earliest segment - * that has not been acknowledged by the TCP receiver. - */ + /* According to RFC 6298 (5.4), retransmit the earliest segment + * that has not been acknowledged by the TCP receiver. + */ - saveseq = tcp_getsequence(conn->sndseq); - tcp_setsequence(conn->sndseq, conn->rexmit_seq); + saveseq = tcp_getsequence(conn->sndseq); + tcp_setsequence(conn->sndseq, conn->rexmit_seq); - tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + hdrlen); + tcp_send(dev, conn, TCP_ACK | TCP_PSH, dev->d_sndlen + hdrlen); - tcp_setsequence(conn->sndseq, saveseq); + tcp_setsequence(conn->sndseq, saveseq); - return; + return; + } +#endif } #if defined(CONFIG_NET_TCP_WRITE_BUFFERS) diff --git a/net/tcp/tcp_send_buffered.c b/net/tcp/tcp_send_buffered.c index d00962c8ae..752a2920e6 100644 --- a/net/tcp/tcp_send_buffered.c +++ b/net/tcp/tcp_send_buffered.c @@ -594,8 +594,6 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, continue; } - conn->rexmit_seq = rexmitno; - /* Reconstruct the length of the earliest segment to be * retransmitted. */ @@ -612,7 +610,6 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev, */ DEBUGASSERT(TCP_WBSEQNO(wrb) != (unsigned)-1); - conn->rexmit_seq = TCP_WBSEQNO(wrb); #ifdef NEED_IPDOMAIN_SUPPORT /* If both IPv4 and IPv6 support are enabled, then we will need to