From 1a1998141120a9d44d33814c533339e7f51fa116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 20 May 2008 10:15:14 +0000 Subject: [PATCH] * If we don't add a buffer because of FLAG_NO_RECEIVE, we still have to maintain our fReceiveNext member, or else the other endpoint never gets its data acknowledged. This fixes the ssl_closure test of the neon test suite, all tests finally go through. * Use is_writable() in SendData() instead of checking all the states manually. * Also bail out when the endpoint stops being writable when we were waiting for it to become writable. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25573 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/tcp/TCPEndpoint.cpp | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 305e2afa11..13b7b52cf1 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -726,9 +726,7 @@ TCPEndpoint::SendData(net_buffer *buffer) return ENOTCONN; if (fState == LISTEN) return EDESTADDRREQ; - if (fState == FINISH_SENT || fState == FINISH_ACKNOWLEDGED - || fState == CLOSING || fState == WAIT_FOR_FINISH_ACKNOWLEDGE - || fState == TIME_WAIT) { + if (!is_writable(fState)) { // we only send signals when called from userland if (gStackModule->is_syscall) send_signal(find_thread(NULL), SIGPIPE); @@ -753,6 +751,13 @@ TCPEndpoint::SendData(net_buffer *buffer) strerror(posix_error(status)), (int)posix_error(status)); return posix_error(status); } + + if (!is_writable(fState)) { + // we only send signals when called from userland + if (gStackModule->is_syscall) + send_signal(find_thread(NULL), SIGPIPE); + return EPIPE; + } } size_t size = fSendQueue.Free(); @@ -1280,7 +1285,7 @@ TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment) bool TCPEndpoint::_ShouldReceive() const { - if (fFlags & FLAG_NO_RECEIVE) + if ((fFlags & FLAG_NO_RECEIVE) != 0) return false; return fState == ESTABLISHED || fState == FINISH_SENT @@ -1346,7 +1351,7 @@ TCPEndpoint::_ListenReceive(tcp_segment_header& segment, net_buffer* buffer) // TODO: drop broadcast/multicast // spawn new endpoint for accept() - net_socket *newSocket; + net_socket* newSocket; if (gSocketModule->spawn_pending_socket(socket, &newSocket) < B_OK) return DROP; @@ -1420,7 +1425,7 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer) } else if (segment.acknowledge == fSendUnacknowledged && fReceiveQueue.IsContiguous() && fReceiveQueue.Free() >= segmentLength - && !(fFlags & FLAG_NO_RECEIVE)) { + && (fFlags & FLAG_NO_RECEIVE) == 0) { if (_AddData(segment, buffer)) _NotifyReader(); @@ -1608,8 +1613,12 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer) if (buffer->size > 0 && _ShouldReceive()) notify = _AddData(segment, buffer); - else + else { + if ((fFlags & FLAG_NO_RECEIVE) != 0) + fReceiveNext += buffer->size; + action = (action & ~KEEP) | DROP; + } if (segment.flags & TCP_FLAG_FINISH) { segmentLength++; @@ -1618,7 +1627,7 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer) fReceiveNext++; notify = true; - // FIN implies PSH + // FIN implies PUSH fReceiveQueue.SetPushPointer(); // we'll reply immediately to the FIN if we are not