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

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

    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)  
    13921392            fFlags &= ~FLAG_OPTION_TIMESTAMP;
    13931393    }
    13941394
    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
    13961402    fSlowStartThreshold = (uint32)segment.advertised_window << fSendWindowShift;
    13971403}
    13981404
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20332039    bool retransmit = fSendNext < fSendMax;
    20342040
    20352041    do {
    2036         uint32 segmentMaxSize = fSendMaxSegmentSize
    2037             - tcp_options_length(segment);
    2038         uint32 segmentLength = min_c(length, segmentMaxSize);
     2042        uint32 segmentLength = min_c(length, fSendMaxSegmentSize);
    20392043
    20402044        if (fSendNext + segmentLength == fSendQueue.LastSequence()) {
    20412045            if (state_needs_finish(fState))
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20462050
    20472051        // Determine if we should really send this segment
    20482052        if (!force && !retransmit && !_ShouldSendSegment(segment, segmentLength,
    2049                 segmentMaxSize, flightSize)) {
     2053                fSendMaxSegmentSize, flightSize)) {
    20502054            if (fSendQueue.Available()
    20512055                && !gStackModule->is_timer_active(&fPersistTimer)
    20522056                && !gStackModule->is_timer_active(&fRetransmitTimer))
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22072211
    22082212    if (fSendUnacknowledged < segment.acknowledge) {
    22092213        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
    22102232        fSendUnacknowledged = segment.acknowledge;
    22112233        if (fSendNext < fSendUnacknowledged)
    22122234            fSendNext = fSendUnacknowledged;
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22362258            fSendCondition.NotifyAll();
    22372259            gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    22382260        }
    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;
    22532261    }
    22542262
    22552263    // if there is data left to be sent, send it now
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22612269void
    22622270TCPEndpoint::_Retransmit()
    22632271{
    2264     TRACE("Retransmit()");
     2272    if (fState < ESTABLISHED) {
     2273        fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
     2274        fCongestionWindow = fSendMaxSegmentSize;
     2275    } else {
     2276        TRACE("Retransmit()");
    22652277
    2266     _ResetSlowStart();
    2267     fSendNext = fSendUnacknowledged;
     2278        _ResetSlowStart();
     2279        fSendNext = fSendUnacknowledged;
    22682280
    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;
    22732285
    2274     _SendQueued();
     2286        _SendQueued();
     2287    }
    22752288}
    22762289
    22772290
  • 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;