tcp: send RST instead of FIN, when user closed and received data get lost
this is the abort way of closing a connection.
tested with golang's http test TestTransportGzip. All TestTransport* pass.
Change-Id: Ib79516eb8a16480d7a4425675748ff76554e9c6c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10054
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Diff
src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
@@ -323,7 +323,8 @@
FLAG_RECOVERY = 0x40,
FLAG_OPTION_SACK_PERMITTED = 0x80,
FLAG_AUTO_RECEIVE_BUFFER_SIZE = 0x100,
FLAG_CAN_NOTIFY = 0x200
FLAG_CAN_NOTIFY = 0x200,
FLAG_USER_CLOSED = 0x400
};
@@ -821,7 +822,7 @@
TRACE("SendData(buffer %p, size %" B_PRIu32 ", flags %#" B_PRIx32
") [total %" B_PRIuSIZE " bytes, has %" B_PRIuSIZE "]", buffer,
buffer->size, buffer->flags, fSendQueue.Size(), fSendQueue.Free());
buffer->size, buffer->msg_flags, fSendQueue.Size(), fSendQueue.Free());
T(APICall(this, "senddata"));
const uint32 flags = buffer->msg_flags;
@@ -1222,9 +1223,14 @@
{
tcp_state previousState = fState;
if (fState == SYNCHRONIZE_RECEIVED || fState == ESTABLISHED)
if (fState == SYNCHRONIZE_RECEIVED || fState == ESTABLISHED) {
if (closing && fReceiveQueue.Available() > 0)
fFlags |= FLAG_USER_CLOSED;
fState = FINISH_SENT;
else if (fState == FINISH_RECEIVED)
} else if (fState == FINISH_RECEIVED)
fState = WAIT_FOR_FINISH_ACKNOWLEDGE;
else
return B_OK;
@@ -1238,6 +1244,9 @@
return status;
}
if ((fFlags & FLAG_USER_CLOSED) != 0)
fState = CLOSED;
return B_OK;
}
@@ -2344,7 +2353,7 @@
if ((fSendNext + segmentLength) == fSendQueue.LastSequence() && !force) {
if (state_needs_finish(fState))
segment.flags |= TCP_FLAG_FINISH;
segment.flags |= (fFlags & FLAG_USER_CLOSED) != 0 ? TCP_FLAG_RESET : TCP_FLAG_FINISH;
if (length > 0)
segment.flags |= TCP_FLAG_PUSH;
}