From f2a49b10120787b3c2d0b98b668c3a2faa419ac0 Mon Sep 17 00:00:00 2001
From: A-star-ayush <myselfthebest@yahoo.com>
Date: Wed, 26 Jul 2017 00:41:19 +0530
Subject: [PATCH] tcp: slow start@rfc5681 : updated rules for congestion window
---
.../kernel/network/protocols/tcp/TCPEndpoint.cpp | 67 +++++++++++++---------
src/add-ons/kernel/network/protocols/tcp/tcp.h | 2 +
2 files changed, 42 insertions(+), 27 deletions(-)
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index 0a7c5fa..0f8a254 100644
a
|
b
|
TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment)
|
1392 | 1392 | fFlags &= ~FLAG_OPTION_TIMESTAMP; |
1393 | 1393 | } |
1394 | 1394 | |
1395 | | fCongestionWindow = 2 * fSendMaxSegmentSize; |
| 1395 | if (fSendMaxSegmentSize > 2190) |
| 1396 | fCongestionWindow = 2 * fSendMaxSegmentSize; |
| 1397 | else if (fSendMaxSegmentSize > 1095) |
| 1398 | fCongestionWindow = 3 * fSendMaxSegmentSize; |
| 1399 | else |
| 1400 | fCongestionWindow = 4 * fSendMaxSegmentSize; |
| 1401 | |
1396 | 1402 | fSlowStartThreshold = (uint32)segment.advertised_window << fSendWindowShift; |
1397 | 1403 | } |
1398 | 1404 | |
… |
… |
TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
2033 | 2039 | bool retransmit = fSendNext < fSendMax; |
2034 | 2040 | |
2035 | 2041 | do { |
2036 | | uint32 segmentMaxSize = fSendMaxSegmentSize |
2037 | | - tcp_options_length(segment); |
2038 | | uint32 segmentLength = min_c(length, segmentMaxSize); |
| 2042 | uint32 segmentLength = min_c(length, fSendMaxSegmentSize); |
2039 | 2043 | |
2040 | 2044 | if (fSendNext + segmentLength == fSendQueue.LastSequence()) { |
2041 | 2045 | if (state_needs_finish(fState)) |
… |
… |
TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)
|
2046 | 2050 | |
2047 | 2051 | // Determine if we should really send this segment |
2048 | 2052 | if (!force && !retransmit && !_ShouldSendSegment(segment, segmentLength, |
2049 | | segmentMaxSize, flightSize)) { |
| 2053 | fSendMaxSegmentSize, flightSize)) { |
2050 | 2054 | if (fSendQueue.Available() |
2051 | 2055 | && !gStackModule->is_timer_active(&fPersistTimer) |
2052 | 2056 | && !gStackModule->is_timer_active(&fRetransmitTimer)) |
… |
… |
TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
|
2207 | 2211 | |
2208 | 2212 | if (fSendUnacknowledged < segment.acknowledge) { |
2209 | 2213 | fSendQueue.RemoveUntil(segment.acknowledge); |
| 2214 | |
| 2215 | // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window |
| 2216 | if (fSendUnacknowledged != fInitialSendSequence) { |
| 2217 | if (fCongestionWindow < fSlowStartThreshold) |
| 2218 | fCongestionWindow += min_c(segment.acknowledge - fSendUnacknowledged.Number(), |
| 2219 | fSendMaxSegmentSize); |
| 2220 | else { |
| 2221 | uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize; |
| 2222 | |
| 2223 | if (increment < fCongestionWindow) |
| 2224 | increment = 1; |
| 2225 | else |
| 2226 | increment /= fCongestionWindow; |
| 2227 | |
| 2228 | fCongestionWindow += increment; |
| 2229 | } |
| 2230 | } |
| 2231 | |
2210 | 2232 | fSendUnacknowledged = segment.acknowledge; |
2211 | 2233 | if (fSendNext < fSendUnacknowledged) |
2212 | 2234 | fSendNext = fSendUnacknowledged; |
… |
… |
TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
|
2236 | 2258 | fSendCondition.NotifyAll(); |
2237 | 2259 | gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free()); |
2238 | 2260 | } |
2239 | | |
2240 | | if (fCongestionWindow < fSlowStartThreshold) |
2241 | | fCongestionWindow += fSendMaxSegmentSize; |
2242 | | } |
2243 | | |
2244 | | if (fCongestionWindow >= fSlowStartThreshold) { |
2245 | | uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize; |
2246 | | |
2247 | | if (increment < fCongestionWindow) |
2248 | | increment = 1; |
2249 | | else |
2250 | | increment /= fCongestionWindow; |
2251 | | |
2252 | | fCongestionWindow += increment; |
2253 | 2261 | } |
2254 | 2262 | |
2255 | 2263 | // if there is data left to be sent, send it now |
… |
… |
TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
|
2261 | 2269 | void |
2262 | 2270 | TCPEndpoint::_Retransmit() |
2263 | 2271 | { |
2264 | | TRACE("Retransmit()"); |
| 2272 | if (fState < ESTABLISHED) { |
| 2273 | fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT; |
| 2274 | fCongestionWindow = fSendMaxSegmentSize; |
| 2275 | } else { |
| 2276 | TRACE("Retransmit()"); |
2265 | 2277 | |
2266 | | _ResetSlowStart(); |
2267 | | fSendNext = fSendUnacknowledged; |
| 2278 | _ResetSlowStart(); |
| 2279 | fSendNext = fSendUnacknowledged; |
2268 | 2280 | |
2269 | | // Do exponential back off of the retransmit timeout |
2270 | | fRetransmitTimeout *= 2; |
2271 | | if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT) |
2272 | | fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT; |
| 2281 | // Do exponential back off of the retransmit timeout |
| 2282 | fRetransmitTimeout *= 2; |
| 2283 | if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT) |
| 2284 | fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT; |
2273 | 2285 | |
2274 | | _SendQueued(); |
| 2286 | _SendQueued(); |
| 2287 | } |
2275 | 2288 | } |
2276 | 2289 | |
2277 | 2290 | |
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
|
b
|
operator==(tcp_sequence a, tcp_sequence b)
|
193 | 193 | #define TCP_MIN_RETRANSMIT_TIMEOUT 200000 // 200 msecs |
194 | 194 | // Maximum retransmit timeout (per RFC6298) |
195 | 195 | #define TCP_MAX_RETRANSMIT_TIMEOUT 60000000 // 60 secs |
| 196 | // New value for timeout in case of lost SYN (RFC 6298) |
| 197 | #define TCP_SYN_RETRANSMIT_TIMEOUT 3000000 // 3 secs |
196 | 198 | |
197 | 199 | struct tcp_sack { |
198 | 200 | uint32 left_edge; |