Ticket #13630: 0002-tcp-rfc-5681-implemented-fast-retransmit-and-recover.patch

File 0002-tcp-rfc-5681-implemented-fast-retransmit-and-recover.patch, 5.0 KB (added by a-star, 2 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From 077e0ba92809d0a7306bbabe13729774c717d1b1 Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Tue, 15 Aug 2017 01:16:31 +0530
    Subject: [PATCH] tcp: rfc 5681: implemented fast retransmit and recovery
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp   | 43 ++++++++++++++++------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |  1 +
     2 files changed, 32 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 061df2a..44dfc9b 100644
    a b TCPEndpoint::TCPEndpoint(net_socket* socket)  
    432432    fSendQueue(socket->send.buffer_size),
    433433    fInitialSendSequence(0),
    434434    fDuplicateAcknowledgeCount(0),
     435    fPreviousFlightSize(0),
    435436    fRoute(NULL),
    436437    fReceiveNext(0),
    437438    fReceiveMaxAdvertised(0),
    TCPEndpoint::_HandleReset(status_t error)  
    12771278void
    12781279TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header &segment)
    12791280{
     1281    if (fDuplicateAcknowledgeCount == 0)
     1282        fPreviousFlightSize = (fSendMax - fSendUnacknowledged).Number();
     1283
    12801284    if (++fDuplicateAcknowledgeCount < 3)
    12811285        return;
    12821286
    12831287    if (fDuplicateAcknowledgeCount == 3) {
    1284         _ResetSlowStart();
     1288        fSlowStartThreshold = max_c(fPreviousFlightSize / 2, 2 * fSendMaxSegmentSize);
    12851289        fCongestionWindow = fSlowStartThreshold + 3 * fSendMaxSegmentSize;
    12861290        fSendNext = segment.acknowledge;
    1287     } else if (fDuplicateAcknowledgeCount > 3)
    1288         fCongestionWindow += fSendMaxSegmentSize;
    1289 
    1290     _SendQueued();
     1291        _SendQueued();
     1292        TRACE("_DuplicateAcknowledge(): packet sent under fast restransmit on the receipt of 3rd dup ack");
     1293
     1294    } else if (fDuplicateAcknowledgeCount > 3) {
     1295        uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
     1296        if ((fDuplicateAcknowledgeCount - 3) * fSendMaxSegmentSize <= flightSize)
     1297            fCongestionWindow += fSendMaxSegmentSize;
     1298        if (fSendQueue.Available(fSendMax) != 0) {
     1299            fSendNext = fSendMax;
     1300            _SendQueued();
     1301        }
     1302    }
    12911303}
    12921304
    12931305
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    16411653
    16421654    int32 action = KEEP;
    16431655
     1656    // immediately acknowledge out-of-order segment to trigger fast-retransmit at the sender
     1657    if (drop != 0)
     1658        action |= IMMEDIATE_ACKNOWLEDGE;
     1659
    16441660    drop = (int32)(segment.sequence + buffer->size
    16451661        - (fReceiveNext + fReceiveWindow)).Number();
    16461662    if (drop > 0) {
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    16851701        if (fSendMax < segment.acknowledge)
    16861702            return DROP | IMMEDIATE_ACKNOWLEDGE;
    16871703
    1688         if (segment.acknowledge < fSendUnacknowledged) {
     1704        if (segment.acknowledge == fSendUnacknowledged) {
    16891705            if (buffer->size == 0 && advertisedWindow == fSendWindow
    1690                 && (segment.flags & TCP_FLAG_FINISH) == 0) {
     1706                && (segment.flags & TCP_FLAG_FINISH) == 0 && fSendUnacknowledged != fSendMax) {
    16911707                TRACE("Receive(): duplicate ack!");
    1692 
    16931708                _DuplicateAcknowledge(segment);
    16941709            }
    1695 
     1710        } else if (segment.acknowledge < fSendUnacknowledged) {
    16961711            return DROP;
    16971712        } else {
    16981713            // this segment acknowledges in flight data
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    17021717                fCongestionWindow = fSlowStartThreshold;
    17031718            }
    17041719
    1705             fDuplicateAcknowledgeCount = 0;
    1706 
    17071720            if (fSendMax == segment.acknowledge)
    17081721                TRACE("Receive(): all inflight data ack'd!");
    17091722
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20442057    bool shouldStartRetransmitTimer = fSendNext == fSendUnacknowledged;
    20452058    bool retransmit = fSendNext < fSendMax;
    20462059
     2060    if (fDuplicateAcknowledgeCount != 0) {
     2061        // send at most 1 SMSS of data when under limited transmit, fast transmit/recovery
     2062        length = min_c(length, fSendMaxSegmentSize);
     2063    }
     2064
    20472065    do {
    20482066        uint32 segmentMaxSize = fSendMaxSegmentSize
    20492067                - tcp_options_length(segment);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22212239    ASSERT(fSendUnacknowledged <= segment.acknowledge);
    22222240
    22232241    if (fSendUnacknowledged < segment.acknowledge) {
     2242        fDuplicateAcknowledgeCount = 0;
    22242243        fSendQueue.RemoveUntil(segment.acknowledge);
    22252244
    22262245        // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window
    TCPEndpoint::_Retransmit()  
    22872306        fCongestionWindow = fSendMaxSegmentSize;
    22882307    } else {
    22892308        _ResetSlowStart();
    2290 
     2309        fDuplicateAcknowledgeCount = 0;
    22912310        // Do exponential back off of the retransmit timeout
    22922311        fRetransmitTimeout *= 2;
    22932312        if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
  • 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 f0bd4e4..fd59c46 100644
    a b private:  
    150150    tcp_sequence    fLastAcknowledgeSent;
    151151    tcp_sequence    fInitialSendSequence;
    152152    uint32          fDuplicateAcknowledgeCount;
     153    uint32          fPreviousFlightSize;
    153154
    154155    net_route       *fRoute;
    155156        // TODO: don't use a net_route, but a net_route_info!!!