From e72ac8e3718807e66018d71f0d550ff041d5c994 Mon Sep 17 00:00:00 2001
From: A-star-ayush <myselfthebest@yahoo.com>
Date: Sat, 19 Aug 2017 02:15:51 +0530
Subject: [PATCH] tcp: rfc 6582: implemented NewReno modification
---
.../kernel/network/protocols/tcp/TCPEndpoint.cpp | 59 +++++++++++++++++-----
.../kernel/network/protocols/tcp/TCPEndpoint.h | 2 +
2 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
index bca88ac..1d02161 100644
a
|
b
|
enum {
|
318 | 318 | FLAG_NO_RECEIVE = 0x04, |
319 | 319 | FLAG_CLOSED = 0x08, |
320 | 320 | FLAG_DELETE_ON_CLOSE = 0x10, |
321 | | FLAG_LOCAL = 0x20 |
| 321 | FLAG_LOCAL = 0x20, |
| 322 | FLAG_RECOVERY = 0x40 |
322 | 323 | }; |
323 | 324 | |
324 | 325 | |
… |
… |
TCPEndpoint::TCPEndpoint(net_socket* socket)
|
431 | 432 | fSendMaxSegments(0), |
432 | 433 | fSendQueue(socket->send.buffer_size), |
433 | 434 | fInitialSendSequence(0), |
| 435 | fPreviousHighestAcknowledge(0), |
434 | 436 | fDuplicateAcknowledgeCount(0), |
435 | 437 | fPreviousFlightSize(0), |
| 438 | fRecover(0), |
436 | 439 | fRoute(NULL), |
437 | 440 | fReceiveNext(0), |
438 | 441 | fReceiveMaxAdvertised(0), |
… |
… |
TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header &segment)
|
1293 | 1296 | } |
1294 | 1297 | |
1295 | 1298 | if (fDuplicateAcknowledgeCount == 3) { |
1296 | | fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 * fSendMaxSegmentSize); |
1297 | | fCongestionWindow = fSlowStartThreshold + 3 * fSendMaxSegmentSize; |
1298 | | fSendNext = segment.acknowledge; |
1299 | | _SendQueued(); |
1300 | | TRACE("_DuplicateAcknowledge(): packet sent under fast restransmit on the receipt of 3rd dup ack"); |
1301 | | |
| 1299 | if ((segment.acknowledge - 1) > fRecover || (fCongestionWindow > fSendMaxSegmentSize && |
| 1300 | (fSendUnacknowledged - fPreviousHighestAcknowledge) <= 4 * fSendMaxSegmentSize)) { |
| 1301 | fFlags |= FLAG_RECOVERY; |
| 1302 | fRecover = fSendMax.Number() - 1; |
| 1303 | fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 * fSendMaxSegmentSize); |
| 1304 | fCongestionWindow = fSlowStartThreshold + 3 * fSendMaxSegmentSize; |
| 1305 | fSendNext = segment.acknowledge; |
| 1306 | _SendQueued(); |
| 1307 | TRACE("_DuplicateAcknowledge(): packet sent under fast restransmit on the receipt of 3rd dup ack"); |
| 1308 | } |
1302 | 1309 | } else if (fDuplicateAcknowledgeCount > 3) { |
1303 | 1310 | uint32 flightSize = (fSendMax - fSendUnacknowledged).Number(); |
1304 | 1311 | if ((fDuplicateAcknowledgeCount - 3) * fSendMaxSegmentSize <= flightSize) |
… |
… |
TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)
|
1738 | 1745 | |
1739 | 1746 | if (fDuplicateAcknowledgeCount >= 3) { |
1740 | 1747 | // deflate the window. |
1741 | | fCongestionWindow = fSlowStartThreshold; |
| 1748 | if (segment.acknowledge > fRecover) { |
| 1749 | uint32 flightSize = (fSendMax - fSendUnacknowledged).Number(); |
| 1750 | fCongestionWindow = min_c(fSlowStartThreshold, |
| 1751 | max_c(flightSize, fSendMaxSegmentSize) + fSendMaxSegmentSize); |
| 1752 | fFlags &= ~FLAG_RECOVERY; |
| 1753 | } |
1742 | 1754 | } |
1743 | 1755 | |
1744 | 1756 | if (fSendMax == segment.acknowledge) |
… |
… |
TCPEndpoint::_PrepareSendPath(const sockaddr* peer)
|
2238 | 2250 | fSendUnacknowledged = fInitialSendSequence; |
2239 | 2251 | fSendMax = fInitialSendSequence; |
2240 | 2252 | fSendUrgentOffset = fInitialSendSequence; |
| 2253 | fRecover = fInitialSendSequence.Number(); |
2241 | 2254 | |
2242 | 2255 | // we are counting the SYN here |
2243 | 2256 | fSendQueue.SetInitialSequence(fSendNext + 1); |
… |
… |
TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
|
2266 | 2279 | ASSERT(fSendUnacknowledged <= segment.acknowledge); |
2267 | 2280 | |
2268 | 2281 | if (fSendUnacknowledged < segment.acknowledge) { |
2269 | | fDuplicateAcknowledgeCount = 0; |
| 2282 | |
2270 | 2283 | fSendQueue.RemoveUntil(segment.acknowledge); |
| 2284 | uint32 bytesAcknowledged = segment.acknowledge - fSendUnacknowledged.Number(); |
| 2285 | fPreviousHighestAcknowledge = fSendUnacknowledged; |
| 2286 | fSendUnacknowledged = segment.acknowledge; |
| 2287 | |
| 2288 | if (fPreviousHighestAcknowledge > fSendUnacknowledged) { |
| 2289 | // need to update the recover variable upon a sequence wraparound |
| 2290 | fRecover = segment.acknowledge - 1; |
| 2291 | } |
2271 | 2292 | |
2272 | 2293 | // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window |
2273 | 2294 | if (fSendUnacknowledged != fInitialSendSequence) { |
2274 | 2295 | if (fCongestionWindow < fSlowStartThreshold) |
2275 | | fCongestionWindow += min_c(segment.acknowledge - fSendUnacknowledged.Number(), |
2276 | | fSendMaxSegmentSize); |
| 2296 | fCongestionWindow += min_c(bytesAcknowledged, fSendMaxSegmentSize); |
2277 | 2297 | else { |
2278 | 2298 | uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize; |
2279 | 2299 | |
… |
… |
TCPEndpoint::_Acknowledged(tcp_segment_header& segment)
|
2288 | 2308 | fSendMaxSegments = UINT32_MAX; |
2289 | 2309 | } |
2290 | 2310 | |
2291 | | fSendUnacknowledged = segment.acknowledge; |
| 2311 | if ((fFlags & FLAG_RECOVERY) != 0) { |
| 2312 | fSendNext = fSendUnacknowledged; |
| 2313 | _SendQueued(); |
| 2314 | fCongestionWindow -= bytesAcknowledged; |
| 2315 | |
| 2316 | if (bytesAcknowledged > fSendMaxSegmentSize) |
| 2317 | fCongestionWindow += fSendMaxSegmentSize; |
| 2318 | |
| 2319 | fSendNext = fSendMax; |
| 2320 | } else |
| 2321 | fDuplicateAcknowledgeCount = 0; |
| 2322 | |
2292 | 2323 | if (fSendNext < fSendUnacknowledged) |
2293 | 2324 | fSendNext = fSendUnacknowledged; |
2294 | 2325 | |
… |
… |
TCPEndpoint::_Retransmit()
|
2366 | 2397 | |
2367 | 2398 | fSendNext = fSendUnacknowledged; |
2368 | 2399 | _SendQueued(); |
| 2400 | |
| 2401 | fRecover = fSendNext.Number() - 1; |
| 2402 | if ((fFlags & FLAG_RECOVERY) != 0) |
| 2403 | fFlags &= ~FLAG_RECOVERY; |
2369 | 2404 | } |
2370 | 2405 | |
2371 | 2406 | |
diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h
index ff6739e..6a62e07 100644
a
|
b
|
private:
|
149 | 149 | BufferQueue fSendQueue; |
150 | 150 | tcp_sequence fLastAcknowledgeSent; |
151 | 151 | tcp_sequence fInitialSendSequence; |
| 152 | tcp_sequence fPreviousHighestAcknowledge; |
152 | 153 | uint32 fDuplicateAcknowledgeCount; |
153 | 154 | uint32 fPreviousFlightSize; |
| 155 | uint32 fRecover; |
154 | 156 | |
155 | 157 | net_route *fRoute; |
156 | 158 | // TODO: don't use a net_route, but a net_route_info!!! |