when sending pure ACKs, use an artificial window of 0.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20778 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -672,10 +672,9 @@ TCPEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer)
|
|||||||
|
|
||||||
TRACE(" ReadData(): %lu bytes kept.", fReceiveQueue.Available());
|
TRACE(" ReadData(): %lu bytes kept.", fReceiveQueue.Available());
|
||||||
|
|
||||||
if (!clone) {
|
// if we are opening the window, check if we should send an ACK
|
||||||
// we are opening the window, check if we should send an ACK
|
if (!clone)
|
||||||
_SendQueued();
|
SendAcknowledge(false);
|
||||||
}
|
|
||||||
|
|
||||||
return receivedBytes;
|
return receivedBytes;
|
||||||
}
|
}
|
||||||
@@ -740,7 +739,7 @@ TCPEndpoint::DelayedAcknowledge()
|
|||||||
if (gStackModule->cancel_timer(&fDelayedAcknowledgeTimer)) {
|
if (gStackModule->cancel_timer(&fDelayedAcknowledgeTimer)) {
|
||||||
// timer was active, send an ACK now (with the exception above,
|
// timer was active, send an ACK now (with the exception above,
|
||||||
// we send every other ACK)
|
// we send every other ACK)
|
||||||
return SendAcknowledge();
|
return SendAcknowledge(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
gStackModule->set_timer(&fDelayedAcknowledgeTimer, TCP_DELAYED_ACKNOWLEDGE_TIMEOUT);
|
gStackModule->set_timer(&fDelayedAcknowledgeTimer, TCP_DELAYED_ACKNOWLEDGE_TIMEOUT);
|
||||||
@@ -749,9 +748,9 @@ TCPEndpoint::DelayedAcknowledge()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
TCPEndpoint::SendAcknowledge()
|
TCPEndpoint::SendAcknowledge(bool force)
|
||||||
{
|
{
|
||||||
return _SendQueued(true);
|
return _SendQueued(force, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -916,7 +915,7 @@ TCPEndpoint::SegmentReceived(tcp_segment_header &segment, net_buffer *buffer)
|
|||||||
|
|
||||||
// process acknowledge action as asked for by the *Receive() method
|
// process acknowledge action as asked for by the *Receive() method
|
||||||
if (segmentAction & IMMEDIATE_ACKNOWLEDGE)
|
if (segmentAction & IMMEDIATE_ACKNOWLEDGE)
|
||||||
SendAcknowledge();
|
SendAcknowledge(true);
|
||||||
else if (segmentAction & ACKNOWLEDGE)
|
else if (segmentAction & ACKNOWLEDGE)
|
||||||
DelayedAcknowledge();
|
DelayedAcknowledge();
|
||||||
|
|
||||||
@@ -1049,12 +1048,19 @@ TCPEndpoint::_ShouldSendSegment(tcp_segment_header &segment, uint32 length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TCPEndpoint::_SendQueued(bool force)
|
||||||
|
{
|
||||||
|
return _SendQueued(force, fSendWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sends one or more TCP segments with the data waiting in the queue, or some
|
Sends one or more TCP segments with the data waiting in the queue, or some
|
||||||
specific flags that need to be sent.
|
specific flags that need to be sent.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
TCPEndpoint::_SendQueued(bool force)
|
TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
||||||
{
|
{
|
||||||
if (fRoute == NULL)
|
if (fRoute == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -1092,9 +1098,8 @@ TCPEndpoint::_SendQueued(bool force)
|
|||||||
segment.acknowledge = fReceiveNext;
|
segment.acknowledge = fReceiveNext;
|
||||||
segment.urgent_offset = 0;
|
segment.urgent_offset = 0;
|
||||||
|
|
||||||
uint32 sendWindow = fSendWindow;
|
if (fCongestionWindow > 0 && fCongestionWindow < sendWindow)
|
||||||
if (fCongestionWindow > 0)
|
sendWindow = fCongestionWindow;
|
||||||
sendWindow = min_c(sendWindow, fCongestionWindow);
|
|
||||||
|
|
||||||
// SND.UNA SND.NXT SND.MAX
|
// SND.UNA SND.NXT SND.MAX
|
||||||
// | | |
|
// | | |
|
||||||
@@ -1793,7 +1798,7 @@ TCPEndpoint::_DelayedAcknowledgeTimer(struct net_timer *timer, void *data)
|
|||||||
if (!locker.IsLocked())
|
if (!locker.IsLocked())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
endpoint->SendAcknowledge();
|
endpoint->SendAcknowledge(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class TCPEndpoint : public net_protocol {
|
|||||||
void DeleteSocket();
|
void DeleteSocket();
|
||||||
|
|
||||||
status_t DelayedAcknowledge();
|
status_t DelayedAcknowledge();
|
||||||
status_t SendAcknowledge();
|
status_t SendAcknowledge(bool force);
|
||||||
status_t UpdateTimeWait();
|
status_t UpdateTimeWait();
|
||||||
|
|
||||||
int32 SegmentReceived(tcp_segment_header& segment, net_buffer *buffer);
|
int32 SegmentReceived(tcp_segment_header& segment, net_buffer *buffer);
|
||||||
@@ -90,6 +90,7 @@ class TCPEndpoint : public net_protocol {
|
|||||||
bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length,
|
bool _ShouldSendSegment(tcp_segment_header &segment, uint32 length,
|
||||||
uint32 segmentMaxSize, uint32 flightSize);
|
uint32 segmentMaxSize, uint32 flightSize);
|
||||||
status_t _SendQueued(bool force = false);
|
status_t _SendQueued(bool force = false);
|
||||||
|
status_t _SendQueued(bool force, uint32 sendWindow);
|
||||||
int _GetMSS(const struct sockaddr *) const;
|
int _GetMSS(const struct sockaddr *) const;
|
||||||
status_t _ShutdownEgress(bool closing);
|
status_t _ShutdownEgress(bool closing);
|
||||||
ssize_t _AvailableData() const;
|
ssize_t _AvailableData() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user