From 5e7d399ef4c077d6c63549c77c9589e68b19efa5 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 30 Dec 2023 21:22:25 -0500 Subject: [PATCH] TCP: Check state in Persist and DelayedAcknowledge timeouts. As the comment already notes, it's possible that we wind up in the timeout routine despite the timer being cancelled, if the cancellation was done after execution was in progress. In either case, do not invoke Send if there is nothing to do, as invoking Send...(force = true) will generate a duplicate ACK. Duplicate ACKs will be noticed by the remote end as a sign of congestion, so we don't want that to happen. Change-Id: Iac30c140c322ccf0b0477e434459e7674bc24e1a Reviewed-on: https://review.haiku-os.org/c/haiku/+/7283 Reviewed-by: waddlesplash Reviewed-by: Alex von Gluck IV --- src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index c999e78117..c68822f78f 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -2492,6 +2492,8 @@ TCPEndpoint::_PersistTimer(net_timer* timer, void* _endpoint) // the timer might not have been canceled early enough if (endpoint->State() == CLOSED) return; + if (endpoint->fSendQueue.Available(endpoint->fSendNext) == 0) + return; endpoint->_SendQueued(true); } @@ -2510,6 +2512,8 @@ TCPEndpoint::_DelayedAcknowledgeTimer(net_timer* timer, void* _endpoint) // the timer might not have been canceled early enough if (endpoint->State() == CLOSED) return; + if (endpoint->fLastAcknowledgeSent == endpoint->fReceiveNext) + return; endpoint->SendAcknowledge(true); }