diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 4473b87782..ca0f4e6525 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -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)) { diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.h b/src/add-ons/kernel/network/protocols/tcp/tcp.h index 826ed51ed6..7d173af5dd 100644 --- a/src/add-ons/kernel/network/protocols/tcp/tcp.h +++ b/src/add-ons/kernel/network/protocols/tcp/tcp.h @@ -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), };