From c0eef6c1379880037fb296e1371fed4739adc507 Mon Sep 17 00:00:00 2001 From: meijian Date: Thu, 22 Aug 2024 21:35:16 +0800 Subject: [PATCH] net/tcp_timer: fix tcp_timer idle loop and retransmission bug 1. Tcp will idle loop by tcp_timer when have no packet to send. This will cause low-power devices to be frequently woken up. 2. We should add tcp_timer when timer has been canceled and have packet to send. Signed-off-by: meijian --- net/tcp/tcp_input.c | 18 +++++++++++++----- net/tcp/tcp_send.c | 7 +++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 41be1024d7..5904e2d9fd 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -1028,6 +1028,7 @@ found: { uint32_t unackseq; uint32_t ackseq; + int timeout; /* The next sequence number is equal to the current sequence * number (sndseq) plus the size of the outstanding, unacknowledged @@ -1137,9 +1138,20 @@ found: flags |= TCP_ACKDATA; + /* Check if no packet need to retransmission, clear timer. */ + + if (conn->tx_unacked == 0 && conn->tcpstateflags == TCP_ESTABLISHED) + { + timeout = 0; + } + else + { + timeout = conn->rto; + } + /* Reset the retransmission timer. */ - tcp_update_retrantimer(conn, conn->rto); + tcp_update_retrantimer(conn, timeout); } /* Check if the sequence number of the incoming packet is what we are @@ -1211,10 +1223,6 @@ found: /* Window updated, set the acknowledged flag. */ flags |= TCP_ACKDATA; - - /* Reset the retransmission timer. */ - - tcp_update_retrantimer(conn, conn->rto); } } diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c index 1ef6b23bab..3c4481f01a 100644 --- a/net/tcp/tcp_send.c +++ b/net/tcp/tcp_send.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "netdev/netdev.h" #include "devif/devif.h" @@ -146,6 +147,12 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev, } else { + if (work_available(&conn->work) && conn->tx_unacked != 0) + { + conn->timeout = false; + tcp_update_retrantimer(conn, conn->rto); + } + /* Update the TCP received window based on I/O buffer availability */ uint32_t rcvseq = tcp_getsequence(conn->rcvseq);