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

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

    From 50b00396097bc8ee844bb2eaf2e6ab200fe50925 Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Wed, 26 Jul 2017 01:01:40 +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, 33 insertions(+), 11 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..36c0bfe 100644
    a b TCPEndpoint::TCPEndpoint(net_socket* socket)  
    430430    fSendQueue(socket->send.buffer_size),
    431431    fInitialSendSequence(0),
    432432    fDuplicateAcknowledgeCount(0),
     433    fFlightSizePrev(0),
    433434    fRoute(NULL),
    434435    fReceiveNext(0),
    435436    fReceiveMaxAdvertised(0),
    TCPEndpoint::_HandleReset(status_t error)  
    12751276void
    12761277TCPEndpoint::_DuplicateAcknowledge(tcp_segment_header &segment)
    12771278{
     1279    if (fDuplicateAcknowledgeCount == 0)
     1280        fFlightSizePrev = (fSendMax - fSendUnacknowledged).Number();
     1281
    12781282    if (++fDuplicateAcknowledgeCount < 3)
    12791283        return;
    12801284
    12811285    if (fDuplicateAcknowledgeCount == 3) {
    1282         _ResetSlowStart();
    1283         fCongestionWindow = fSlowStartThreshold + 3 * fSendMaxSegmentSize;
     1286        uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
     1287        fSlowStartThreshold = max_c(fFlightSizePrev / 2, 2 * fSendMaxSegmentSize);
     1288        fCongestionWindow = fSlowStartThreshold + (flightSize - fFlightSizePrev) + fSendMaxSegmentSize;
    12841289        fSendNext = segment.acknowledge;
    1285     } else if (fDuplicateAcknowledgeCount > 3)
    1286         fCongestionWindow += fSendMaxSegmentSize;
    1287 
    1288     _SendQueued();
     1290        _SendQueued();
     1291        TRACE("_DuplicateAcknowledge(): packet sent under fast restransmit on the receipt of 3rd dup ack");
     1292    } else if (fDuplicateAcknowledgeCount > 3) {
     1293        uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
     1294        if(fDuplicateAcknowledgeCount * fSendMaxSegmentSize <= flightSize)
     1295            fCongestionWindow += fSendMaxSegmentSize;
     1296        if(fSendQueue.Available(fSendMax) != 0) {
     1297            fSendNext = fSendMax;
     1298            _SendQueued();
     1299        }
     1300    }
    12891301}
    12901302
    12911303
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    16321644
    16331645    int32 action = KEEP;
    16341646
     1647    // immediately acknowledge out-of-order segment to trigger fast-retransmit at the sender
     1648    if(drop != 0)
     1649        action |= IMMEDIATE_ACKNOWLEDGE;
     1650
    16351651    drop = (int32)(segment.sequence + buffer->size
    16361652        - (fReceiveNext + fReceiveWindow)).Number();
    16371653    if (drop > 0) {
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    16761692        if (fSendMax < segment.acknowledge)
    16771693            return DROP | IMMEDIATE_ACKNOWLEDGE;
    16781694
    1679         if (segment.acknowledge < fSendUnacknowledged) {
     1695        if (segment.acknowledge == fSendUnacknowledged) {
    16801696            if (buffer->size == 0 && advertisedWindow == fSendWindow
    1681                 && (segment.flags & TCP_FLAG_FINISH) == 0) {
     1697                && (segment.flags & TCP_FLAG_FINISH) == 0 && fSendUnacknowledged != fSendMax) {
    16821698                TRACE("Receive(): duplicate ack!");
    16831699
    16841700                _DuplicateAcknowledge(segment);
     1701                return DROP;
    16851702            }
    1686 
     1703        } else if (segment.acknowledge < fSendUnacknowledged) {
    16871704            return DROP;
    16881705        } else {
    16891706            // this segment acknowledges in flight data
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    16931710                fCongestionWindow = fSlowStartThreshold;
    16941711            }
    16951712
    1696             fDuplicateAcknowledgeCount = 0;
    1697 
    16981713            if (fSendMax == segment.acknowledge)
    16991714                TRACE("Receive(): all inflight data ack'd!");
    17001715
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20322047    bool shouldStartRetransmitTimer = fSendNext == fSendUnacknowledged;
    20332048    bool retransmit = fSendNext < fSendMax;
    20342049
     2050    if(fDuplicateAcknowledgeCount != 0) {
     2051        // send at most 1 SMSS of data when under limited transmit, fast transmit/recovery
     2052        length = min_c(length, fSendMaxSegmentSize);
     2053    }
     2054
    20352055    do {
    20362056        uint32 segmentMaxSize = fSendMaxSegmentSize
    20372057            - tcp_options_length(segment);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22062226    ASSERT(fSendUnacknowledged <= segment.acknowledge);
    22072227
    22082228    if (fSendUnacknowledged < segment.acknowledge) {
     2229        fDuplicateAcknowledgeCount = 0;
    22092230        fSendQueue.RemoveUntil(segment.acknowledge);
    22102231        fSendUnacknowledged = segment.acknowledge;
    22112232        if (fSendNext < fSendUnacknowledged)
  • 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..3d8264e 100644
    a b private:  
    149149    tcp_sequence    fLastAcknowledgeSent;
    150150    tcp_sequence    fInitialSendSequence;
    151151    uint32          fDuplicateAcknowledgeCount;
     152    uint32          fFlightSizePrev;
    152153
    153154    net_route       *fRoute;
    154155        // TODO: don't use a net_route, but a net_route_info!!!