From 34c53bacf49f84ef2b18ea80c0238d73ee2d56de Mon Sep 17 00:00:00 2001 From: Hugo Santos Date: Sun, 27 May 2007 03:38:22 +0000 Subject: [PATCH] tcp: fixed an issue where the socket could be waken from ReadData() even when no new data was added to the queue (due to lost packets). Also make sure we only break from the receive loop where there is at least a byte of data to be consumed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21248 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/tcp/TCPEndpoint.cpp | 25 ++++++++++--------- .../network/protocols/tcp/TCPEndpoint.h | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 9d6e03cf11..317fda35f3 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -648,18 +648,18 @@ TCPEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer) return B_OK; } - if (fReceiveQueue.Available() >= dataNeeded || + if (fReceiveQueue.Available() > 0) { + if (fReceiveQueue.Available() >= dataNeeded || ((fReceiveQueue.PushedData() > 0) && (fReceiveQueue.PushedData() >= fReceiveQueue.Available()))) - break; - - if (fState == FINISH_RECEIVED) { + break; + } else if (fState == FINISH_RECEIVED) { // ``If no text is awaiting delivery, the RECEIVE will // get a Connection closing''. return B_OK; } - if (flags & MSG_DONTWAIT) + if ((flags & MSG_DONTWAIT) || (socket->receive.timeout == 0)) return B_WOULD_BLOCK; status_t status = fReceiveList.Wait(locker, timeout, false); @@ -1024,8 +1024,8 @@ TCPEndpoint::_SegmentReceived(tcp_segment_header &segment, net_buffer *buffer) && fReceiveQueue.IsContiguous() && fReceiveQueue.Free() >= buffer->size && !(fFlags & FLAG_NO_RECEIVE)) { - _AddData(segment, buffer); - _NotifyReader(); + if (_AddData(segment, buffer)) + _NotifyReader(); return KEEP | ((segment.flags & TCP_FLAG_PUSH) ? IMMEDIATE_ACKNOWLEDGE : ACKNOWLEDGE); } @@ -1544,10 +1544,9 @@ TCPEndpoint::_Receive(tcp_segment_header &segment, net_buffer *buffer) bool notify = false; - if (buffer->size > 0 && _ShouldReceive()) { - _AddData(segment, buffer); - notify = true; - } else + if (buffer->size > 0 && _ShouldReceive()) + notify = _AddData(segment, buffer); + else action = (action & ~KEEP) | DROP; if (segment.flags & TCP_FLAG_FINISH) { @@ -1639,7 +1638,7 @@ TCPEndpoint::_WaitForEstablished(MutexLocker &locker, bigtime_t timeout) } -void +bool TCPEndpoint::_AddData(tcp_segment_header &segment, net_buffer *buffer) { fReceiveQueue.Add(buffer, segment.sequence); @@ -1650,6 +1649,8 @@ TCPEndpoint::_AddData(tcp_segment_header &segment, net_buffer *buffer) if (segment.flags & TCP_FLAG_PUSH) fReceiveQueue.SetPushPointer(); + + return fReceiveQueue.Available() > 0; } diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h index c88efe5d14..839fff0316 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h @@ -108,7 +108,7 @@ class TCPEndpoint : public net_protocol, public ProtocolSocket { size_t segmentLength); void _MarkEstablished(); status_t _WaitForEstablished(MutexLocker &lock, bigtime_t timeout); - void _AddData(tcp_segment_header &segment, net_buffer *buffer); + bool _AddData(tcp_segment_header &segment, net_buffer *buffer); void _PrepareReceivePath(tcp_segment_header &segment); status_t _PrepareSendPath(const sockaddr *peer); void _Acknowledged(tcp_segment_header &segment);