TCP: Actually invoke SendQueued when the window widens.

IMMEDIATE_ACKNOWLEDGE invokes SendQueued ... but with
a send window size forced to 0, so it just generates an
ACK (or a duplicate ACK as the case may be), and doesn't
actually trigger sending of data.

So, adjust the check, introduce a new action flag, and
invoke it properly.

Fixes traffic stalls caused by waiting for the
persist timeout to occur.

This amends hrev51540 (yes, from 2017.)

Change-Id: I6344463938cfaa0134bb8cf3e224789cded0987c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7285
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2023-12-31 03:36:27 +00:00
committed by waddlesplash
parent d7c71d7b49
commit 141cc59300
2 changed files with 17 additions and 9 deletions
@@ -1737,8 +1737,12 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
}
#endif
if (advertisedWindow > fSendWindow)
action |= IMMEDIATE_ACKNOWLEDGE;
if (fSendWindow < fSendMaxSegmentSize
&& advertisedWindow >= fSendMaxSegmentSize) {
// Our current send window is less than a segment wide, and the new one
// is larger, so trigger a send in case there's anything to be sent.
action |= SEND_QUEUED;
}
fSendWindow = advertisedWindow;
if (advertisedWindow > fSendMaxWindow)
@@ -1824,7 +1828,7 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
// The buffer may be freed if its data is added to the queue, so cache
// the size as we still need it later.
uint32 bufferSize = buffer->size;
const uint32 bufferSize = buffer->size;
if ((bufferSize > 0 || (segment.flags & TCP_FLAG_FINISH) != 0)
&& _ShouldReceive())
@@ -1934,6 +1938,9 @@ TCPEndpoint::SegmentReceived(tcp_segment_header& segment, net_buffer* buffer)
else if (segmentAction & ACKNOWLEDGE)
DelayedAcknowledge();
if (segmentAction & SEND_QUEUED)
_SendQueued();
if ((fFlags & (FLAG_CLOSED | FLAG_DELETE_ON_CLOSE))
== (FLAG_CLOSED | FLAG_DELETE_ON_CLOSE)) {
@@ -269,12 +269,13 @@ struct tcp_segment_header {
};
enum tcp_segment_action {
KEEP = 0x00,
DROP = 0x01,
RESET = 0x02,
ACKNOWLEDGE = 0x04,
IMMEDIATE_ACKNOWLEDGE = 0x08,
DELETED_ENDPOINT = 0x10,
KEEP = 0,
DROP = (1 << 0),
RESET = (1 << 1),
ACKNOWLEDGE = (1 << 2),
IMMEDIATE_ACKNOWLEDGE = (1 << 3),
SEND_QUEUED = (1 << 4),
DELETED_ENDPOINT = (1 << 5),
};