From e19a0bfa1b996109522c62e5784fe792eb0113d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 31 Dec 2006 14:27:12 +0000 Subject: [PATCH] Could not connect locally anymore, as fSendNext and fSendMax must be set before the segment is sent in this case (as receive/send will currently stack up in a single thread). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19660 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/tcp/TCPEndpoint.cpp | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 777a15d5d2..5d034b1145 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -1162,31 +1162,39 @@ TCPEndpoint::_SendQueued(bool force) // TODO: we need to trim the segment to the max segment size in case // the options made it too large - status = next->module->send_routed_data(next, fRoute, buffer); - if (status < B_OK) { - gBufferModule->free(buffer); - return status; - } + // Update send status - we need to do this before we send the data + // for local connections as the answer is directly handled - // Only count 1 SYN, the 1 sent when transitioning from CLOSED or LISTEN if ((segment.flags & TCP_FLAG_SYNCHRONIZE) != 0) { + // count SYN into sequence length and reset options for the next segment segment.max_segment_size = 0; segment.has_window_shift = false; size++; } - // Only count 1 FIN, the 1 sent when transitioning from - // ESTABLISHED, SYNCHRONIZE_RECEIVED or FINISH_RECEIVED - if ((segment.flags & TCP_FLAG_FINISH) != 0) + if ((segment.flags & TCP_FLAG_FINISH) != 0) { + // count FIN into sequence length size++; + } - if (fSendMax == fSendNext) - fSendMax += size; + uint32 sendMax = fSendMax; fSendNext += size; + if (fSendMax < fSendNext) + fSendMax = fSendNext; fReceiveMaxAdvertised = fReceiveNext + ((uint32)segment.advertised_window << fReceiveWindowShift); + status = next->module->send_routed_data(next, fRoute, buffer); + if (status < B_OK) { + gBufferModule->free(buffer); + + fSendNext = segment.sequence; + fSendMax = sendMax; + // restore send status + return status; + } + length -= segmentLength; if (length == 0) break;