From 9c1af36c30c80d73fe3f642937d1c525a0c1835d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 6 May 2023 15:17:01 +0200 Subject: [PATCH] tcp: report disconnected events for tcp * FIONREAD shouldn't report errors, only EINVAL when listening * read available data in closing and closing-wait states * fix #18327 Change-Id: Idd53a043a72ef6c7b282ea669895ff2e947adbb4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6420 Reviewed-by: waddlesplash --- src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp | 5 ++++- src/add-ons/kernel/network/stack/net_socket.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 33c8cb92e6..26bbeb7e6e 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -964,6 +964,8 @@ TCPEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer) if (fState == CLOSING || fState == WAIT_FOR_FINISH_ACKNOWLEDGE || fState == TIME_WAIT) { // ``Connection closing''. + if (fReceiveQueue.Available() > 0) + break; return B_OK; } @@ -1345,7 +1347,8 @@ TCPEndpoint::_AvailableData() const if (availableData == 0 && !_ShouldReceive()) return ENOTCONN; - + if (availableData == 0 && (fState == FINISH_RECEIVED || fState == WAIT_FOR_FINISH_ACKNOWLEDGE)) + return ESHUTDOWN; return availableData; } diff --git a/src/add-ons/kernel/network/stack/net_socket.cpp b/src/add-ons/kernel/network/stack/net_socket.cpp index 59ecb3048f..62775b14e0 100644 --- a/src/add-ons/kernel/network/stack/net_socket.cpp +++ b/src/add-ons/kernel/network/stack/net_socket.cpp @@ -540,12 +540,12 @@ socket_control(net_socket* socket, uint32 op, void* data, size_t length) case FIONREAD: { - if (data == NULL) + if (data == NULL || (socket->options & SO_ACCEPTCONN) != 0) return B_BAD_VALUE; int available = (int)socket_read_avail(socket); if (available < 0) - return available; + available = 0; if (is_syscall()) { if (!IS_USER_ADDRESS(data)