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 <anchao@xiaomi.com>
This commit is contained in:
chao.an 2022-07-04 00:58:44 +08:00 committed by Petro Karashchenko
parent 1867bc2210
commit 1c80675e87
3 changed files with 22 additions and 14 deletions

View File

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

View File

@ -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)

View File

@ -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