hrev51385 adds 8 changesets to branch 'master'
old head: e9300454b6a8a7e33b018bc760daed8ac1e1dda5
new head: 5c31f5a67a0aa37c8f2a1464252b2c5b0a959f33
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=5c31f5a67a0a+%5Ee9300454b6a8
----------------------------------------------------------------------------
05743f6a1331: tcp: slow start@rfc5681 : updated rules for congestion window
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
ec63a32913ad: tcp: rfc 5681: implemented fast retransmit and recovery
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
39bba929ac3f: tcp: rfc 3042: implemented limited transmit
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
aaa7cebc24f0: tcp: rfc 7323: added PAWS timestamp check on Receive
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
30982ed7b94d: tcp: rfc 6298 & 7323: updated rto calculations and semantics
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
15c58f0cb7a0: tcp: rfc 5681: implemented ideal timer
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
515cda7241ba: tcp: rfc 6582: implemented NewReno modification
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
5c31f5a67a0a: tcp: rfc 2018: implemented SACK option
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
[ A-star-ayush <myselfthebest@xxxxxxxxx> ]
----------------------------------------------------------------------------
6 files changed, 283 insertions(+), 80 deletions(-)
.../kernel/network/protocols/tcp/BufferQueue.cpp | 35 +++
.../kernel/network/protocols/tcp/BufferQueue.h | 1 +
.../kernel/network/protocols/tcp/TCPEndpoint.cpp | 281 ++++++++++++++-----
.../kernel/network/protocols/tcp/TCPEndpoint.h | 11 +-
src/add-ons/kernel/network/protocols/tcp/tcp.cpp | 28 +-
src/add-ons/kernel/network/protocols/tcp/tcp.h | 7 +-
############################################################################
Commit: 05743f6a13319a9dc332603eb5d98ba4c5374b25
URL: http://cgit.haiku-os.org/haiku/commit/?id=05743f6a1331
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Mon Aug 14 19:41:58 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: slow start@rfc5681 : updated rules for congestion window
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index eb8ed47..1cbe262 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -18,6 +18,7 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include <KernelExport.h>
#include <Select.h>
@@ -427,6 +428,7 @@ TCPEndpoint::TCPEndpoint(net_socket* socket)
fSendWindow(0),
fSendMaxWindow(0),
fSendMaxSegmentSize(TCP_DEFAULT_MAX_SEGMENT_SIZE),
+ fSendMaxSegments(0),
fSendQueue(socket->send.buffer_size),
fInitialSendSequence(0),
fDuplicateAcknowledgeCount(0),
@@ -1392,7 +1394,14 @@ TCPEndpoint::_PrepareReceivePath(tcp_segment_header&
segment)
fFlags &= ~FLAG_OPTION_TIMESTAMP;
}
- fCongestionWindow = 2 * fSendMaxSegmentSize;
+ if (fSendMaxSegmentSize > 2190)
+ fCongestionWindow = 2 * fSendMaxSegmentSize;
+ else if (fSendMaxSegmentSize > 1095)
+ fCongestionWindow = 3 * fSendMaxSegmentSize;
+ else
+ fCongestionWindow = 4 * fSendMaxSegmentSize;
+
+ fSendMaxSegments = fCongestionWindow / fSendMaxSegmentSize;
fSlowStartThreshold = (uint32)segment.advertised_window <<
fSendWindowShift;
}
@@ -1897,6 +1906,9 @@ inline bool
TCPEndpoint::_ShouldSendSegment(tcp_segment_header& segment, uint32 length,
uint32 segmentMaxSize, uint32 flightSize)
{
+ if (fState == ESTABLISHED && fSendMaxSegments == 0)
+ return false;
+
if (length > 0) {
// Avoid the silly window syndrome - we only send a segment in
case:
// - we have a full segment to send, or
@@ -2114,6 +2126,9 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
fReceiveMaxAdvertised = fReceiveNext
+ ((uint32)segment.advertised_window <<
fReceiveWindowShift);
+ if (segmentLength != 0 && fState == ESTABLISHED)
+ --fSendMaxSegments;
+
status = next->module->send_routed_data(next, fRoute, buffer);
if (status < B_OK) {
gBufferModule->free(buffer);
@@ -2207,6 +2222,26 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
if (fSendUnacknowledged < segment.acknowledge) {
fSendQueue.RemoveUntil(segment.acknowledge);
+
+ // the acknowledgment of the SYN/ACK MUST NOT increase the size
of the congestion window
+ if (fSendUnacknowledged != fInitialSendSequence) {
+ if (fCongestionWindow < fSlowStartThreshold)
+ fCongestionWindow += min_c(segment.acknowledge
- fSendUnacknowledged.Number(),
+ fSendMaxSegmentSize);
+ else {
+ uint32 increment = fSendMaxSegmentSize *
fSendMaxSegmentSize;
+
+ if (increment < fCongestionWindow)
+ increment = 1;
+ else
+ increment /= fCongestionWindow;
+
+ fCongestionWindow += increment;
+ }
+
+ fSendMaxSegments = UINT32_MAX;
+ }
+
fSendUnacknowledged = segment.acknowledge;
if (fSendNext < fSendUnacknowledged)
fSendNext = fSendUnacknowledged;
@@ -2236,20 +2271,6 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
fSendCondition.NotifyAll();
gSocketModule->notify(socket, B_SELECT_WRITE,
fSendQueue.Free());
}
-
- if (fCongestionWindow < fSlowStartThreshold)
- fCongestionWindow += fSendMaxSegmentSize;
- }
-
- if (fCongestionWindow >= fSlowStartThreshold) {
- uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize;
-
- if (increment < fCongestionWindow)
- increment = 1;
- else
- increment /= fCongestionWindow;
-
- fCongestionWindow += increment;
}
// if there is data left to be sent, send it now
@@ -2261,16 +2282,21 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
void
TCPEndpoint::_Retransmit()
{
- TRACE("Retransmit()");
+ if (fState < ESTABLISHED) {
+ fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
+ fCongestionWindow = fSendMaxSegmentSize;
+ } else {
+ _ResetSlowStart();
- _ResetSlowStart();
- fSendNext = fSendUnacknowledged;
+ // Do exponential back off of the retransmit timeout
+ fRetransmitTimeout *= 2;
+ if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
+ fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
+ }
- // Do exponential back off of the retransmit timeout
- fRetransmitTimeout *= 2;
- if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
- fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
+ TRACE("Retransmit()");
+ fSendNext = fSendUnacknowledged;
_SendQueued();
}
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
index 1ff167b..f0bd4e4 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
@@ -145,6 +145,7 @@ private:
uint32 fSendWindow;
uint32 fSendMaxWindow;
uint32 fSendMaxSegmentSize;
+ uint32 fSendMaxSegments;
BufferQueue fSendQueue;
tcp_sequence fLastAcknowledgeSent;
tcp_sequence fInitialSendSequence;
diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.h
b/src/add-ons/kernel/network/protocols/tcp/tcp.h
index 6f30ec2..24890a3 100644
--- a/src/add-ons/kernel/network/protocols/tcp/tcp.h
+++ b/src/add-ons/kernel/network/protocols/tcp/tcp.h
@@ -193,6 +193,8 @@ operator==(tcp_sequence a, tcp_sequence b)
#define TCP_MIN_RETRANSMIT_TIMEOUT 200000 // 200 msecs
// Maximum retransmit timeout (per RFC6298)
#define TCP_MAX_RETRANSMIT_TIMEOUT 60000000 // 60 secs
+// New value for timeout in case of lost SYN (RFC 6298)
+#define TCP_SYN_RETRANSMIT_TIMEOUT 3000000 // 3 secs
struct tcp_sack {
uint32 left_edge;
############################################################################
Commit: ec63a32913addc83f55cb293a4a1a308adfc73cc
URL: http://cgit.haiku-os.org/haiku/commit/?id=ec63a32913ad
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Mon Aug 14 19:46:31 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 5681: implemented fast retransmit and recovery
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index 1cbe262..4ddec8f 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -432,6 +432,7 @@ TCPEndpoint::TCPEndpoint(net_socket* socket)
fSendQueue(socket->send.buffer_size),
fInitialSendSequence(0),
fDuplicateAcknowledgeCount(0),
+ fPreviousFlightSize(0),
fRoute(NULL),
fReceiveNext(0),
fReceiveMaxAdvertised(0),
@@ -1277,17 +1278,28 @@ TCPEndpoint::_HandleReset(status_t error)
void
TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header &segment)
{
+ if (fDuplicateAcknowledgeCount == 0)
+ fPreviousFlightSize = (fSendMax - fSendUnacknowledged).Number();
+
if (++fDuplicateAcknowledgeCount < 3)
return;
if (fDuplicateAcknowledgeCount == 3) {
- _ResetSlowStart();
+ fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 *
fSendMaxSegmentSize);
fCongestionWindow = fSlowStartThreshold + 3 *
fSendMaxSegmentSize;
fSendNext = segment.acknowledge;
- } else if (fDuplicateAcknowledgeCount > 3)
- fCongestionWindow += fSendMaxSegmentSize;
-
- _SendQueued();
+ _SendQueued();
+ TRACE("_DuplicateAcknowledge(): packet sent under fast
restransmit on the receipt of 3rd dup ack");
+
+ } else if (fDuplicateAcknowledgeCount > 3) {
+ uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
+ if ((fDuplicateAcknowledgeCount - 3) * fSendMaxSegmentSize <=
flightSize)
+ fCongestionWindow += fSendMaxSegmentSize;
+ if (fSendQueue.Available(fSendMax) != 0) {
+ fSendNext = fSendMax;
+ _SendQueued();
+ }
+ }
}
@@ -1641,6 +1653,10 @@ TCPEndpoint::_Receive(tcp_segment_header& segment,
net_buffer* buffer)
int32 action = KEEP;
+ // immediately acknowledge out-of-order segment to trigger
fast-retransmit at the sender
+ if (drop != 0)
+ action |= IMMEDIATE_ACKNOWLEDGE;
+
drop = (int32)(segment.sequence + buffer->size
- (fReceiveNext + fReceiveWindow)).Number();
if (drop > 0) {
@@ -1685,14 +1701,13 @@ TCPEndpoint::_Receive(tcp_segment_header& segment,
net_buffer* buffer)
if (fSendMax < segment.acknowledge)
return DROP | IMMEDIATE_ACKNOWLEDGE;
- if (segment.acknowledge < fSendUnacknowledged) {
+ if (segment.acknowledge == fSendUnacknowledged) {
if (buffer->size == 0 && advertisedWindow == fSendWindow
- && (segment.flags & TCP_FLAG_FINISH) == 0) {
+ && (segment.flags & TCP_FLAG_FINISH) == 0 &&
fSendUnacknowledged != fSendMax) {
TRACE("Receive(): duplicate ack!");
-
_DuplicateAcknowledge(segment);
}
-
+ } else if (segment.acknowledge < fSendUnacknowledged) {
return DROP;
} else {
// this segment acknowledges in flight data
@@ -1702,8 +1717,6 @@ TCPEndpoint::_Receive(tcp_segment_header& segment,
net_buffer* buffer)
fCongestionWindow = fSlowStartThreshold;
}
- fDuplicateAcknowledgeCount = 0;
-
if (fSendMax == segment.acknowledge)
TRACE("Receive(): all inflight data ack'd!");
@@ -2044,6 +2057,11 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
bool shouldStartRetransmitTimer = fSendNext == fSendUnacknowledged;
bool retransmit = fSendNext < fSendMax;
+ if (fDuplicateAcknowledgeCount != 0) {
+ // send at most 1 SMSS of data when under limited transmit,
fast transmit/recovery
+ length = min_c(length, fSendMaxSegmentSize);
+ }
+
do {
uint32 segmentMaxSize = fSendMaxSegmentSize
- tcp_options_length(segment);
@@ -2221,6 +2239,7 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
ASSERT(fSendUnacknowledged <= segment.acknowledge);
if (fSendUnacknowledged < segment.acknowledge) {
+ fDuplicateAcknowledgeCount = 0;
fSendQueue.RemoveUntil(segment.acknowledge);
// the acknowledgment of the SYN/ACK MUST NOT increase the size
of the congestion window
@@ -2287,7 +2306,7 @@ TCPEndpoint::_Retransmit()
fCongestionWindow = fSendMaxSegmentSize;
} else {
_ResetSlowStart();
-
+ fDuplicateAcknowledgeCount = 0;
// Do exponential back off of the retransmit timeout
fRetransmitTimeout *= 2;
if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
index f0bd4e4..fd59c46 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
@@ -150,6 +150,7 @@ private:
tcp_sequence fLastAcknowledgeSent;
tcp_sequence fInitialSendSequence;
uint32 fDuplicateAcknowledgeCount;
+ uint32 fPreviousFlightSize;
net_route *fRoute;
// TODO: don't use a net_route, but a net_route_info!!!
############################################################################
Commit: 39bba929ac3ff2fa697f1d260eb5686522539d6f
URL: http://cgit.haiku-os.org/haiku/commit/?id=39bba929ac3f
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Mon Aug 14 19:55:04 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 3042: implemented limited transmit
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index 4ddec8f..1cbe610 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -1281,8 +1281,15 @@ TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header
&segment)
if (fDuplicateAcknowledgeCount == 0)
fPreviousFlightSize = (fSendMax - fSendUnacknowledged).Number();
- if (++fDuplicateAcknowledgeCount < 3)
- return;
+ if (++fDuplicateAcknowledgeCount < 3) {
+ if (fSendQueue.Available(fSendMax) != 0 && fSendWindow != 0) {
+ fSendNext = fSendMax;
+ fCongestionWindow += fDuplicateAcknowledgeCount *
fSendMaxSegmentSize;
+ _SendQueued();
+ TRACE("_DuplicateAcknowledge(): packet sent under
limited transmit on receipt of dup ack");
+ fCongestionWindow -= fDuplicateAcknowledgeCount *
fSendMaxSegmentSize;
+ }
+ }
if (fDuplicateAcknowledgeCount == 3) {
fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 *
fSendMaxSegmentSize);
############################################################################
Commit: aaa7cebc24f067fe26d3ba9ae805158f8c5b75b1
URL: http://cgit.haiku-os.org/haiku/commit/?id=aaa7cebc24f0
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Thu Aug 17 06:59:56 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 7323: added PAWS timestamp check on Receive
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index 1cbe610..ec98efa 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -1551,6 +1551,15 @@ TCPEndpoint::_SynchronizeSentReceive(tcp_segment_header
&segment,
int32
TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
{
+ // PAWS processing takes precedence over regular TCP acceptability check
+ if ((fFlags & FLAG_OPTION_TIMESTAMP) != 0 && (segment.flags &
TCP_FLAG_RESET) == 0) {
+ if ((segment.options & TCP_HAS_TIMESTAMPS) == 0)
+ return DROP;
+ if ((int32)(fReceivedTimestamp - segment.timestamp_value) > 0
+ && (fReceivedTimestamp - segment.timestamp_value) <=
INT32_MAX)
+ return DROP | IMMEDIATE_ACKNOWLEDGE;
+ }
+
uint32 advertisedWindow = (uint32)segment.advertised_window
<< fSendWindowShift;
size_t segmentLength = buffer->size;
diff --git a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp
b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp
index 7c1dbb4..b14f662 100644
--- a/src/add-ons/kernel/network/protocols/tcp/tcp.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/tcp.cpp
@@ -117,8 +117,7 @@ add_options(tcp_segment_header &segment, uint8 *buffer,
size_t bufferSize)
option->kind = TCP_OPTION_TIMESTAMP;
option->length = 10;
option->timestamp.value = htonl(segment.timestamp_value);
- // TSecr is opaque to us, we send it as we received it.
- option->timestamp.reply = segment.timestamp_reply;
+ option->timestamp.reply = htonl(segment.timestamp_reply);
bump_option(option, length);
}
@@ -210,7 +209,7 @@ process_options(tcp_segment_header &segment, net_buffer
*buffer, size_t size)
case TCP_OPTION_TIMESTAMP:
if (option->length == 10 && size >= 10) {
segment.options |= TCP_HAS_TIMESTAMPS;
- segment.timestamp_value =
option->timestamp.value;
+ segment.timestamp_value =
ntohl(option->timestamp.value);
segment.timestamp_reply =
ntohl(option->timestamp.reply);
}
############################################################################
Commit: 30982ed7b94d61be02c704fe12a8519f18741db2
URL: http://cgit.haiku-os.org/haiku/commit/?id=30982ed7b94d
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Sat Jul 29 16:49:47 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 6298 & 7323: updated rto calculations and semantics
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index ec98efa..11b512d 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -439,8 +439,9 @@ TCPEndpoint::TCPEndpoint(net_socket* socket)
fReceiveWindow(socket->receive.buffer_size),
fReceiveMaxSegmentSize(TCP_DEFAULT_MAX_SEGMENT_SIZE),
fReceiveQueue(socket->receive.buffer_size),
- fRoundTripTime(TCP_INITIAL_RTT / kTimestampFactor),
- fRoundTripDeviation(TCP_INITIAL_RTT / kTimestampFactor),
+ fSmoothedRoundTripTime(0),
+ fRoundTripVariation(0),
+ fSendTime(0),
fRetransmitTimeout(TCP_INITIAL_RTT),
fReceivedTimestamp(0),
fCongestionWindow(0),
@@ -2173,6 +2174,9 @@ TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
return status;
}
+ if (fSendTime == 0 && (segmentLength != 0 || (segment.flags &
TCP_FLAG_SYNCHRONIZE ) == 1))
+ fSendTime = tcp_now();
+
if (shouldStartRetransmitTimer && size > 0) {
TRACE("starting initial retransmit timer of: %"
B_PRIdBIGTIME,
fRetransmitTimeout);
@@ -2281,19 +2285,23 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
if (fSendNext < fSendUnacknowledged)
fSendNext = fSendUnacknowledged;
- if (segment.options & TCP_HAS_TIMESTAMPS)
-
_UpdateRoundTripTime(tcp_diff_timestamp(segment.timestamp_reply));
- else {
- // TODO: Fallback to RFC 793 type estimation; This just
resets
- // any potential exponential back off that happened due
to
- // retransmits.
- fRetransmitTimeout = TCP_INITIAL_RTT;
+ if (fFlags & FLAG_OPTION_TIMESTAMP) {
+ uint32 flightSize = (fSendMax -
fSendUnacknowledged).Number();
+
_UpdateRoundTripTime(tcp_diff_timestamp(segment.timestamp_reply),
+ 1 + ((flightSize - 1) / (fSendMaxSegmentSize <<
1)));
+ }
+
+ // Karn's algorithm: RTT measurement must not be made using
segments that were retransmitted
+ else if (fSendTime > 1 && fSendNext == fSendMax) {
+ _UpdateRoundTripTime(tcp_diff_timestamp(fSendTime), 1);
+ fSendTime = 1;
}
if (fSendUnacknowledged == fSendMax) {
TRACE("all acknowledged, cancelling retransmission
timer");
gStackModule->cancel_timer(&fRetransmitTimer);
T(TimerSet(this, "retransmit", -1));
+ fSendTime = 0;
} else {
TRACE("data acknowledged, resetting retransmission
timer to: %"
B_PRIdBIGTIME, fRetransmitTimeout);
@@ -2337,20 +2345,23 @@ TCPEndpoint::_Retransmit()
void
-TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime)
+TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime, uint32 expectedSamples)
{
- int32 rtt = roundTripTime;
-
- // "smooth" round trip time as per Van Jacobson
- rtt -= fRoundTripTime / 8;
- fRoundTripTime += rtt;
- if (rtt < 0)
- rtt = -rtt;
- rtt -= fRoundTripDeviation / 4;
- fRoundTripDeviation += rtt;
+ if(fSmoothedRoundTripTime == 0) {
+ fSmoothedRoundTripTime = roundTripTime;
+ fRoundTripVariation = roundTripTime >> 1;
+ fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100,
fRoundTripVariation << 2))
+ * kTimestampFactor;
+ } else {
+ int32 delta = fSmoothedRoundTripTime - roundTripTime;
+ if (delta < 0)
+ delta = -delta;
+ fRoundTripVariation += ((delta - fRoundTripVariation) >> 2) /
expectedSamples;
+ fSmoothedRoundTripTime += ((roundTripTime -
fSmoothedRoundTripTime) >> 3) / expectedSamples;
+ fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100,
fRoundTripVariation << 2))
+ * kTimestampFactor;
+ }
- fRetransmitTimeout = ((fRoundTripTime / 4 + fRoundTripDeviation) / 2)
- * kTimestampFactor;
if (fRetransmitTimeout < TCP_MIN_RETRANSMIT_TIMEOUT)
fRetransmitTimeout = TCP_MIN_RETRANSMIT_TIMEOUT;
@@ -2378,7 +2389,7 @@ TCPEndpoint::_RetransmitTimer(net_timer* timer, void*
_endpoint)
T(TimerTriggered(endpoint, "retransmit"));
MutexLocker locker(endpoint->fLock);
- if (!locker.IsLocked())
+ if (!locker.IsLocked() || gStackModule->is_timer_active(timer))
return;
endpoint->_Retransmit();
@@ -2506,8 +2517,8 @@ TCPEndpoint::Dump() const
fInitialReceiveSequence.Number());
kprintf(" duplicate acknowledge count: %" B_PRIu32 "\n",
fDuplicateAcknowledgeCount);
- kprintf(" round trip time: %" B_PRId32 " (deviation %" B_PRId32 ")\n",
- fRoundTripTime, fRoundTripDeviation);
+ kprintf(" smoothed round trip time: %" B_PRId32 " (deviation %"
B_PRId32 ")\n",
+ fSmoothedRoundTripTime, fRoundTripVariation);
kprintf(" retransmit timeout: %" B_PRId64 "\n", fRetransmitTimeout);
kprintf(" congestion window: %" B_PRIu32 "\n", fCongestionWindow);
kprintf(" slow start threshold: %" B_PRIu32 "\n", fSlowStartThreshold);
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
index fd59c46..ff6739e 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
@@ -106,7 +106,7 @@ private:
status_t _PrepareSendPath(const sockaddr* peer);
void _Acknowledged(tcp_segment_header&
segment);
void _Retransmit();
- void _UpdateRoundTripTime(int32
roundTripTime);
+ void _UpdateRoundTripTime(int32
roundTripTime, uint32 expectedSamples);
void _ResetSlowStart();
void
_DuplicateAcknowledge(tcp_segment_header& segment);
@@ -166,8 +166,9 @@ private:
tcp_sequence fInitialReceiveSequence;
// round trip time and retransmit timeout computation
- int32 fRoundTripTime;
- int32 fRoundTripDeviation;
+ int32 fSmoothedRoundTripTime;
+ int32 fRoundTripVariation;
+ uint32 fSendTime;
bigtime_t fRetransmitTimeout;
uint32 fReceivedTimestamp;
############################################################################
Commit: 15c58f0cb7a0afb7361945e4596f83f7b6212cf8
URL: http://cgit.haiku-os.org/haiku/commit/?id=15c58f0cb7a0
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Sat Jul 29 16:55:11 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 5681: implemented ideal timer
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index 11b512d..daba44e 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -1379,6 +1379,13 @@ TCPEndpoint::_AddData(tcp_segment_header& segment,
net_buffer* buffer)
if ((segment.flags & TCP_FLAG_PUSH) != 0)
fReceiveQueue.SetPushPointer();
+ if (fSendUnacknowledged == fSendMax) {
+ TRACE("data received, resetting ideal timer to: %"
+ B_PRIdBIGTIME, fRetransmitTimeout);
+ gStackModule->set_timer(&fRetransmitTimer, fRetransmitTimeout);
+ T(TimerSet(this, "ideal", fRetransmitTimeout));
+ }
+
return fReceiveQueue.Available() > 0;
}
@@ -2298,9 +2305,10 @@ TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
}
if (fSendUnacknowledged == fSendMax) {
- TRACE("all acknowledged, cancelling retransmission
timer");
- gStackModule->cancel_timer(&fRetransmitTimer);
- T(TimerSet(this, "retransmit", -1));
+ TRACE("all acknowledged, cancelling retransmission
timer. Using it as ideal timer for: %"
+ B_PRIdBIGTIME, fRetransmitTimeout);
+ gStackModule->set_timer(&fRetransmitTimer,
fRetransmitTimeout);
+ T(TimerSet(this, "ideal", fRetransmitTimeout));
fSendTime = 0;
} else {
TRACE("data acknowledged, resetting retransmission
timer to: %"
@@ -2328,6 +2336,21 @@ TCPEndpoint::_Retransmit()
if (fState < ESTABLISHED) {
fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
fCongestionWindow = fSendMaxSegmentSize;
+ } else if (fSendUnacknowledged == fSendMax) {
+ TRACE("Ideal timeout");
+ // idle period time out - did not receive any segment for a
time equal
+ // to the retransmission timeout
+
+ uint32 initialWindow;
+ if (fSendMaxSegmentSize > 2190)
+ initialWindow = 2 * fSendMaxSegmentSize;
+ else if (fSendMaxSegmentSize > 1095)
+ initialWindow = 3 * fSendMaxSegmentSize;
+ else
+ initialWindow = 4 * fSendMaxSegmentSize;
+
+ fCongestionWindow = min_c(initialWindow, fCongestionWindow);
+ return;
} else {
_ResetSlowStart();
fDuplicateAcknowledgeCount = 0;
############################################################################
Commit: 515cda7241baf3b40d6e3f340f73958a2d40b2d0
URL: http://cgit.haiku-os.org/haiku/commit/?id=515cda7241ba
Author: A-star-ayush <myselfthebest@xxxxxxxxx>
Date: Fri Aug 18 20:45:51 2017 UTC
Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
Commit-Date: Mon Aug 28 08:52:19 2017 UTC
tcp: rfc 6582: implemented NewReno modification
Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx>
----------------------------------------------------------------------------
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index daba44e..91b4b91 100644
--- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
+++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
@@ -318,7 +318,8 @@ enum {
FLAG_NO_RECEIVE = 0x04,
FLAG_CLOSED = 0x08,
FLAG_DELETE_ON_CLOSE = 0x10,
- FLAG_LOCAL = 0x20
+ FLAG_LOCAL = 0x20,
+ FLAG_RECOVERY = 0x40
};
@@ -431,8 +432,10 @@ TCPEndpoint::TCPEndpoint(net_socket* socket)
fSendMaxSegments(0),
fSendQueue(socket->send.buffer_size),
fInitialSendSequence(0),
+ fPreviousHighestAcknowledge(0),
fDuplicateAcknowledgeCount(0),
fPreviousFlightSize(0),
+ fRecover(0),
fRoute(NULL),
fReceiveNext(0),
fReceiveMaxAdvertised(0),
@@ -1293,12 +1296,16 @@ TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header
&segment)
}
if (fDuplicateAcknowledgeCount == 3) {
- fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 *
fSendMaxSegmentSize);
- fCongestionWindow = fSlowStartThreshold + 3 *
fSendMaxSegmentSize;
- fSendNext = segment.acknowledge;
- _SendQueued();
- TRACE("_DuplicateAcknowledge(): packet sent under fast
restransmit on the receipt of 3rd dup ack");
-
+ if ((segment.acknowledge - 1) > fRecover || (fCongestionWindow
fSendMaxSegmentSize &&+ (fSendUnacknowledged - fPreviousHighestAcknowledge) <=