Ticket #13629: 2.tcp-slow-start-rfc5681-updated-rules-for-congestion-window.patch

File 2.tcp-slow-start-rfc5681-updated-rules-for-congestion-window.patch, 6.7 KB (added by a-star, 2 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From 321433cfc32c3715a9a9cdca9a0f19143dbe17dc 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   | 78 ++++++++++++++--------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |  1 +
     src/add-ons/kernel/network/protocols/tcp/tcp.h     |  2 +
     3 files changed, 54 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..8589e29 100644
    a b  
    1818#include <signal.h>
    1919#include <stdlib.h>
    2020#include <string.h>
     21#include <stdint.h>
    2122
    2223#include <KernelExport.h>
    2324#include <Select.h>
    TCPEndpoint::TCPEndpoint(net_socket* socket)  
    427428    fSendWindow(0),
    428429    fSendMaxWindow(0),
    429430    fSendMaxSegmentSize(TCP_DEFAULT_MAX_SEGMENT_SIZE),
     431    fSendMaxSegments(0),
    430432    fSendQueue(socket->send.buffer_size),
    431433    fInitialSendSequence(0),
    432434    fDuplicateAcknowledgeCount(0),
    TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment)  
    13921394            fFlags &= ~FLAG_OPTION_TIMESTAMP;
    13931395    }
    13941396
    1395     fCongestionWindow = 2 * fSendMaxSegmentSize;
     1397    if (fSendMaxSegmentSize > 2190)
     1398        fCongestionWindow = 2 * fSendMaxSegmentSize;
     1399    else if (fSendMaxSegmentSize > 1095)
     1400        fCongestionWindow = 3 * fSendMaxSegmentSize;
     1401    else
     1402        fCongestionWindow = 4 * fSendMaxSegmentSize;
     1403
     1404    fSendMaxSegments = fCongestionWindow / fSendMaxSegmentSize;
    13961405    fSlowStartThreshold = (uint32)segment.advertised_window << fSendWindowShift;
    13971406}
    13981407
    inline bool  
    18971906TCPEndpoint::_ShouldSendSegment(tcp_segment_header& segment, uint32 length,
    18981907    uint32 segmentMaxSize, uint32 flightSize)
    18991908{
     1909    if(fSendMaxSegments == 0)
     1910        return false;
     1911
    19001912    if (length > 0) {
    19011913        // Avoid the silly window syndrome - we only send a segment in case:
    19021914        // - we have a full segment to send, or
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20332045    bool retransmit = fSendNext < fSendMax;
    20342046
    20352047    do {
    2036         uint32 segmentMaxSize = fSendMaxSegmentSize
    2037             - tcp_options_length(segment);
    2038         uint32 segmentLength = min_c(length, segmentMaxSize);
     2048        uint32 segmentLength = min_c(length, fSendMaxSegmentSize);
    20392049
    20402050        if (fSendNext + segmentLength == fSendQueue.LastSequence()) {
    20412051            if (state_needs_finish(fState))
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20462056
    20472057        // Determine if we should really send this segment
    20482058        if (!force && !retransmit && !_ShouldSendSegment(segment, segmentLength,
    2049                 segmentMaxSize, flightSize)) {
     2059                fSendMaxSegmentSize, flightSize)) {
    20502060            if (fSendQueue.Available()
    20512061                && !gStackModule->is_timer_active(&fPersistTimer)
    20522062                && !gStackModule->is_timer_active(&fRetransmitTimer))
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    21142124        fReceiveMaxAdvertised = fReceiveNext
    21152125            + ((uint32)segment.advertised_window << fReceiveWindowShift);
    21162126
     2127        if (segmentLength !=0 && fState == ESTABLISHED)
     2128            fSendMaxSegments -= 1;
     2129
    21172130        status = next->module->send_routed_data(next, fRoute, buffer);
    21182131        if (status < B_OK) {
    21192132            gBufferModule->free(buffer);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22072220
    22082221    if (fSendUnacknowledged < segment.acknowledge) {
    22092222        fSendQueue.RemoveUntil(segment.acknowledge);
     2223
     2224        // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window
     2225        if (fSendUnacknowledged != fInitialSendSequence) {
     2226            if (fCongestionWindow < fSlowStartThreshold)
     2227                fCongestionWindow += min_c(segment.acknowledge - fSendUnacknowledged.Number(),
     2228                    fSendMaxSegmentSize);
     2229            else {
     2230                uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize;
     2231
     2232                if (increment < fCongestionWindow)
     2233                    increment = 1;
     2234                else
     2235                    increment /= fCongestionWindow;
     2236
     2237                fCongestionWindow += increment;
     2238            }
     2239
     2240            fSendMaxSegments = UINT32_MAX;
     2241        }
     2242
    22102243        fSendUnacknowledged = segment.acknowledge;
    22112244        if (fSendNext < fSendUnacknowledged)
    22122245            fSendNext = fSendUnacknowledged;
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22362269            fSendCondition.NotifyAll();
    22372270            gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    22382271        }
    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;
    22532272    }
    22542273
    22552274    // if there is data left to be sent, send it now
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22612280void
    22622281TCPEndpoint::_Retransmit()
    22632282{
    2264     TRACE("Retransmit()");
     2283    if (fState < ESTABLISHED) {
     2284        fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
     2285        fCongestionWindow = fSendMaxSegmentSize;
     2286    } else {
     2287        TRACE("Retransmit()");
    22652288
    2266     _ResetSlowStart();
    2267     fSendNext = fSendUnacknowledged;
     2289        _ResetSlowStart();
     2290        fSendNext = fSendUnacknowledged;
    22682291
    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;
     2292        // Do exponential back off of the retransmit timeout
     2293        fRetransmitTimeout *= 2;
     2294        if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
     2295            fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
    22732296
    2274     _SendQueued();
     2297        _SendQueued();
     2298    }
    22752299}
    22762300
    22772301
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h

    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 b private:  
    145145    uint32          fSendWindow;
    146146    uint32          fSendMaxWindow;
    147147    uint32          fSendMaxSegmentSize;
     148    uint32          fSendMaxSegments;
    148149    BufferQueue     fSendQueue;
    149150    tcp_sequence    fLastAcknowledgeSent;
    150151    tcp_sequence    fInitialSendSequence;
  • src/add-ons/kernel/network/protocols/tcp/tcp.h

    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)  
    193193#define TCP_MIN_RETRANSMIT_TIMEOUT      200000      // 200 msecs
    194194// Maximum retransmit timeout (per RFC6298)
    195195#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
    196198
    197199struct tcp_sack {
    198200    uint32 left_edge;