From 3fdcd065cf9b4bc4a8a961e06374c0bc9d9ea5f8 Mon Sep 17 00:00:00 2001 From: meijian Date: Tue, 10 Dec 2024 15:08:00 +0800 Subject: [PATCH] net/tcp_timer: fix tcp RTO abnormally large after retransmission occurs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when tcp retransmission only double conn->timer in Karn(tcp_timer.c L602), after retransmission in Jacobson M is is now rtt test will become a negative value. ``` signed char m; m = conn->rto - conn->timer; // M is now rtt test /* This is taken directly from VJs original code in his paper */ m = m - (conn->sa >> 3); conn->sa += m; //conn->sa is a negative value if (m < 0) { m = -m; } m = m - (conn->sv >> 2); conn->sv += m; conn->rto = (conn->sa >> 3) + conn->sv; //rto ``` For example,we lost one ack packet, we will set conn->timer = 6 by backoff,conn->rto still 3. After retransmission we will Do RTT estimation, then will get ``` conn->sa = 253 conn->rto = 46 ``` Then if any packets lost it will wait for a long time before triggering a retransmission. Test method. We can reproduce this issue by adding drop ACK packets in tcp_input, and debug conn->rto after Jacobson. Signed-off-by: meijian --- net/tcp/tcp_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 568743e251308..1e6c9f9fb8312 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -599,7 +599,8 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn) /* Exponential backoff. */ - conn->timer = TCP_RTO << (conn->nrtx > 4 ? 4: conn->nrtx); + conn->rto = TCP_RTO << (conn->nrtx > 4 ? 4: conn->nrtx); + tcp_update_retrantimer(conn, conn->rto); conn->nrtx++; /* Ok, so we need to retransmit. We do this differently