* 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
This commit is contained in:
parent
4caadfdb36
commit
1a19981411
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user