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

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

    From 5520ecf35b33b41fece4587075e8ae18e4a4e710 Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Tue, 15 Aug 2017 01:11:58 +0530
    Subject: [PATCH] tcp: slow start@rfc5681 : updated rules for congestion window
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp   | 72 +++++++++++++++-------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |  1 +
     src/add-ons/kernel/network/protocols/tcp/tcp.h     |  2 +
     3 files changed, 52 insertions(+), 23 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..061df2a 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 (fState == ESTABLISHED && 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)  
    20342046
    20352047    do {
    20362048        uint32 segmentMaxSize = fSendMaxSegmentSize
    2037             - tcp_options_length(segment);
     2049                - tcp_options_length(segment);
    20382050        uint32 segmentLength = min_c(length, segmentMaxSize);
    20392051
    20402052        if (fSendNext + segmentLength == fSendQueue.LastSequence()) {
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    21142126        fReceiveMaxAdvertised = fReceiveNext
    21152127            + ((uint32)segment.advertised_window << fReceiveWindowShift);
    21162128
     2129        if (segmentLength != 0 && fState == ESTABLISHED)
     2130            --fSendMaxSegments;
     2131
    21172132        status = next->module->send_routed_data(next, fRoute, buffer);
    21182133        if (status < B_OK) {
    21192134            gBufferModule->free(buffer);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22072222
    22082223    if (fSendUnacknowledged < segment.acknowledge) {
    22092224        fSendQueue.RemoveUntil(segment.acknowledge);
     2225
     2226        // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window
     2227        if (fSendUnacknowledged != fInitialSendSequence) {
     2228            if (fCongestionWindow < fSlowStartThreshold)
     2229                fCongestionWindow += min_c(segment.acknowledge - fSendUnacknowledged.Number(),
     2230                    fSendMaxSegmentSize);
     2231            else {
     2232                uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize;
     2233
     2234                if (increment < fCongestionWindow)
     2235                    increment = 1;
     2236                else
     2237                    increment /= fCongestionWindow;
     2238
     2239                fCongestionWindow += increment;
     2240            }
     2241
     2242            fSendMaxSegments = UINT32_MAX;
     2243        }
     2244
    22102245        fSendUnacknowledged = segment.acknowledge;
    22112246        if (fSendNext < fSendUnacknowledged)
    22122247            fSendNext = fSendUnacknowledged;
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22362271            fSendCondition.NotifyAll();
    22372272            gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    22382273        }
    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;
    22532274    }
    22542275
    22552276    // if there is data left to be sent, send it now
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22612282void
    22622283TCPEndpoint::_Retransmit()
    22632284{
    2264     TRACE("Retransmit()");
     2285    if (fState < ESTABLISHED) {
     2286        fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
     2287        fCongestionWindow = fSendMaxSegmentSize;
     2288    } else {
     2289        _ResetSlowStart();
    22652290
    2266     _ResetSlowStart();
    2267     fSendNext = fSendUnacknowledged;
     2291        // Do exponential back off of the retransmit timeout
     2292        fRetransmitTimeout *= 2;
     2293        if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
     2294            fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
     2295    }
    22682296
    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;
     2297    TRACE("Retransmit()");
    22732298
     2299    fSendNext = fSendUnacknowledged;
    22742300    _SendQueued();
    22752301}
    22762302
  • 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;