* When receiving an out of sequence FIN we must ignore it until its part of
our available buffer (we might want to move this into the BufferQueue class). * Now, _AddData() remembers the flag (and its position), and will alter the segment's flags field to reflect the current state. * This fixes not being able to login into mmlr.dyndns.org. * Fixed warnings when TCP_PROBE is defined. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36127 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -72,9 +72,9 @@
|
|||||||
# define PROBE(buffer, window) \
|
# define PROBE(buffer, window) \
|
||||||
dprintf("TCP PROBE %llu %s %s %ld snxt %lu suna %lu cw %lu sst %lu win %lu swin %lu smax-suna %lu savail %lu sqused %lu rto %llu\n", \
|
dprintf("TCP PROBE %llu %s %s %ld snxt %lu suna %lu cw %lu sst %lu win %lu swin %lu smax-suna %lu savail %lu sqused %lu rto %llu\n", \
|
||||||
system_time(), PrintAddress(buffer->source), \
|
system_time(), PrintAddress(buffer->source), \
|
||||||
PrintAddress(buffer->destination), buffer->size, (uint32)fSendNext, \
|
PrintAddress(buffer->destination), buffer->size, fSendNext.Number(), \
|
||||||
(uint32)fSendUnacknowledged, fCongestionWindow, fSlowStartThreshold, \
|
fSendUnacknowledged.Number(), fCongestionWindow, fSlowStartThreshold, \
|
||||||
window, fSendWindow, (uint32)(fSendMax - fSendUnacknowledged), \
|
window, fSendWindow, (fSendMax - fSendUnacknowledged).Number(), \
|
||||||
fSendQueue.Available(fSendNext), fSendQueue.Used(), fRetransmitTimeout)
|
fSendQueue.Available(fSendNext), fSendQueue.Used(), fRetransmitTimeout)
|
||||||
#else
|
#else
|
||||||
# define PROBE(buffer, window) do { } while (0)
|
# define PROBE(buffer, window) do { } while (0)
|
||||||
@@ -1298,13 +1298,27 @@ TCPEndpoint::_NotifyReader()
|
|||||||
bool
|
bool
|
||||||
TCPEndpoint::_AddData(tcp_segment_header& segment, net_buffer* buffer)
|
TCPEndpoint::_AddData(tcp_segment_header& segment, net_buffer* buffer)
|
||||||
{
|
{
|
||||||
|
if ((segment.flags & TCP_FLAG_FINISH) != 0) {
|
||||||
|
// Remember the position of the finish received flag
|
||||||
|
fFinishReceived = true;
|
||||||
|
fFinishReceivedAt = segment.sequence + buffer->size;
|
||||||
|
}
|
||||||
|
|
||||||
fReceiveQueue.Add(buffer, segment.sequence);
|
fReceiveQueue.Add(buffer, segment.sequence);
|
||||||
fReceiveNext = fReceiveQueue.NextSequence();
|
fReceiveNext = fReceiveQueue.NextSequence();
|
||||||
|
|
||||||
|
if (fFinishReceived) {
|
||||||
|
// Set or reset the finish flag on the current segment
|
||||||
|
if (fReceiveNext < fFinishReceivedAt)
|
||||||
|
segment.flags &= ~TCP_FLAG_FINISH;
|
||||||
|
else
|
||||||
|
segment.flags |= TCP_FLAG_FINISH;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE(" _AddData(): adding data, receive next = %lu. Now have %lu bytes.",
|
TRACE(" _AddData(): adding data, receive next = %lu. Now have %lu bytes.",
|
||||||
fReceiveNext.Number(), fReceiveQueue.Available());
|
fReceiveNext.Number(), fReceiveQueue.Available());
|
||||||
|
|
||||||
if (segment.flags & TCP_FLAG_PUSH)
|
if ((segment.flags & TCP_FLAG_PUSH) != 0)
|
||||||
fReceiveQueue.SetPushPointer();
|
fReceiveQueue.SetPushPointer();
|
||||||
|
|
||||||
return fReceiveQueue.Available() > 0;
|
return fReceiveQueue.Available() > 0;
|
||||||
@@ -1315,6 +1329,7 @@ void
|
|||||||
TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment)
|
TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment)
|
||||||
{
|
{
|
||||||
fInitialReceiveSequence = segment.sequence;
|
fInitialReceiveSequence = segment.sequence;
|
||||||
|
fFinishReceived = false;
|
||||||
|
|
||||||
// count the received SYN
|
// count the received SYN
|
||||||
segment.sequence++;
|
segment.sequence++;
|
||||||
@@ -1686,7 +1701,8 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
|
|||||||
|
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
|
||||||
if (buffer->size > 0 && _ShouldReceive())
|
if ((buffer->size > 0 || (segment.flags & TCP_FLAG_FINISH) != 0)
|
||||||
|
&& _ShouldReceive())
|
||||||
notify = _AddData(segment, buffer);
|
notify = _AddData(segment, buffer);
|
||||||
else {
|
else {
|
||||||
if ((fFlags & FLAG_NO_RECEIVE) != 0)
|
if ((fFlags & FLAG_NO_RECEIVE) != 0)
|
||||||
@@ -1695,7 +1711,7 @@ TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
|
|||||||
action = (action & ~KEEP) | DROP;
|
action = (action & ~KEEP) | DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment.flags & TCP_FLAG_FINISH) {
|
if ((segment.flags & TCP_FLAG_FINISH) != 0) {
|
||||||
segmentLength++;
|
segmentLength++;
|
||||||
if (fState != CLOSED && fState != LISTEN && fState != SYNCHRONIZE_SENT) {
|
if (fState != CLOSED && fState != LISTEN && fState != SYNCHRONIZE_SENT) {
|
||||||
TRACE("Receive(): peer is finishing connection!");
|
TRACE("Receive(): peer is finishing connection!");
|
||||||
@@ -1989,7 +2005,7 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
|||||||
|
|
||||||
// Determine if we should really send this segment
|
// Determine if we should really send this segment
|
||||||
if (!force && !_ShouldSendSegment(segment, segmentLength,
|
if (!force && !_ShouldSendSegment(segment, segmentLength,
|
||||||
segmentMaxSize, flightSize)) {
|
segmentMaxSize, flightSize)) {
|
||||||
if (fSendQueue.Available()
|
if (fSendQueue.Available()
|
||||||
&& !gStackModule->is_timer_active(&fPersistTimer)
|
&& !gStackModule->is_timer_active(&fPersistTimer)
|
||||||
&& !gStackModule->is_timer_active(&fRetransmitTimer))
|
&& !gStackModule->is_timer_active(&fRetransmitTimer))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -170,6 +170,8 @@ private:
|
|||||||
uint32 fReceiveWindow;
|
uint32 fReceiveWindow;
|
||||||
uint32 fReceiveMaxSegmentSize;
|
uint32 fReceiveMaxSegmentSize;
|
||||||
BufferQueue fReceiveQueue;
|
BufferQueue fReceiveQueue;
|
||||||
|
bool fFinishReceived;
|
||||||
|
tcp_sequence fFinishReceivedAt;
|
||||||
tcp_sequence fInitialReceiveSequence;
|
tcp_sequence fInitialReceiveSequence;
|
||||||
|
|
||||||
// round trip time and retransmit timeout computation
|
// round trip time and retransmit timeout computation
|
||||||
|
|||||||
Reference in New Issue
Block a user