Ticket #13769: 0001-tcp-fixed-RTO-update-and-dup-ACKs-generation.patch

File 0001-tcp-fixed-RTO-update-and-dup-ACKs-generation.patch, 5.8 KB (added by a-star, 4 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From 64dc0ded362b815bbb67cb04306921bf9fc6655c Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Mon, 4 Dec 2017 23:01:02 +0530
    Subject: [PATCH] tcp : fixed RTO update and dup ACKs generation
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp   | 38 +++++++++++++---------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |  3 +-
     2 files changed, 25 insertions(+), 16 deletions(-)
    
    diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
    index e3194da..007f772 100644
    a b TCPEndpoint::TCPEndpoint(net_socket* socket)  
    445445    fSmoothedRoundTripTime(0),
    446446    fRoundTripVariation(0),
    447447    fSendTime(0),
     448    fRoundTripStartSequence(0),
    448449    fRetransmitTimeout(TCP_INITIAL_RTT),
    449450    fReceivedTimestamp(0),
    450451    fCongestionWindow(0),
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    20352036    }
    20362037
    20372038    size_t availableBytes = fReceiveQueue.Free();
     2039    // window size must remain same for duplicate acknowledgements
     2040    if (!fReceiveQueue.IsContiguous())
     2041        availableBytes = (fReceiveMaxAdvertised - fReceiveNext).Number();
     2042
    20382043    if (fFlags & FLAG_OPTION_WINDOW_SCALE)
    20392044        segment.advertised_window = availableBytes >> fReceiveWindowShift;
    20402045    else
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    21892194            return status;
    21902195        }
    21912196
    2192         if (fSendTime == 0 && (segmentLength != 0 || (segment.flags & TCP_FLAG_SYNCHRONIZE ) == 1))
     2197        if (fSendTime == 0 && !retransmit
     2198            && (segmentLength != 0 || (segment.flags & TCP_FLAG_SYNCHRONIZE) !=0)) {
    21932199            fSendTime = tcp_now();
     2200            fRoundTripStartSequence = segment.sequence;
     2201        }
    21942202
    21952203        if (shouldStartRetransmitTimer && size > 0) {
    21962204            TRACE("starting initial retransmit timer of: %" B_PRIdBIGTIME,
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22802288        uint32 bytesAcknowledged = segment.acknowledge - fSendUnacknowledged.Number();
    22812289        fPreviousHighestAcknowledge = fSendUnacknowledged;
    22822290        fSendUnacknowledged = segment.acknowledge;
     2291        uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
     2292        int32 expectedSamples = flightSize / (fSendMaxSegmentSize << 1);
    22832293
    22842294        if (fPreviousHighestAcknowledge > fSendUnacknowledged) {
    22852295            // need to update the recover variable upon a sequence wraparound
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    23202330            fSendNext = fSendUnacknowledged;
    23212331
    23222332        if (fFlags & FLAG_OPTION_TIMESTAMP) {
    2323             uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
    23242333            _UpdateRoundTripTime(tcp_diff_timestamp(segment.timestamp_reply),
    2325                 1 + ((flightSize - 1) / (fSendMaxSegmentSize << 1)));
    2326         }
    2327 
    2328         // Karn's algorithm: RTT measurement must not be made using segments that were retransmitted
    2329         else if (fSendTime > 1 && fSendNext == fSendMax) {
     2334                expectedSamples > 0 ? expectedSamples : 1);
     2335        } else if (fSendTime != 0 && fRoundTripStartSequence < segment.acknowledge) {
    23302336            _UpdateRoundTripTime(tcp_diff_timestamp(fSendTime), 1);
    2331             fSendTime = 1;
     2337            fSendTime = 0;
    23322338        }
    23332339
    23342340        if (fSendUnacknowledged == fSendMax) {
    23352341            TRACE("all acknowledged, cancelling retransmission timer.");
    23362342            gStackModule->cancel_timer(&fRetransmitTimer);
    23372343            T(TimerSet(this, "retransmit", -1));
    2338             fSendTime = 0;
    23392344        } else {
    23402345            TRACE("data acknowledged, resetting retransmission timer to: %"
    23412346                B_PRIdBIGTIME, fRetransmitTimeout);
    TCPEndpoint::_Retransmit()  
    23832388
    23842389
    23852390void
    2386 TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime, uint32 expectedSamples)
     2391TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime, int32 expectedSamples)
    23872392{
    23882393    if(fSmoothedRoundTripTime == 0) {
    23892394        fSmoothedRoundTripTime = roundTripTime;
    2390         fRoundTripVariation = roundTripTime >> 1;
    2391         fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation << 2))
     2395        fRoundTripVariation = roundTripTime / 2;
     2396        fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation * 4))
    23922397                * kTimestampFactor;
    23932398    } else {
    23942399        int32 delta = fSmoothedRoundTripTime - roundTripTime;
    23952400        if (delta < 0)
    23962401            delta = -delta;
    2397         fRoundTripVariation += ((delta - fRoundTripVariation) >> 2) / expectedSamples;
    2398         fSmoothedRoundTripTime += ((roundTripTime - fSmoothedRoundTripTime) >> 3) / expectedSamples;
    2399         fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation << 2))
     2402        fRoundTripVariation += (delta - fRoundTripVariation) / (expectedSamples * 4);
     2403        fSmoothedRoundTripTime += (roundTripTime - fSmoothedRoundTripTime) / (expectedSamples * 8);
     2404        fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation * 4))
    24002405            * kTimestampFactor;
    24012406    }
    24022407
     2408    if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
     2409        fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
     2410
    24032411    if (fRetransmitTimeout < TCP_MIN_RETRANSMIT_TIMEOUT)
    24042412        fRetransmitTimeout = TCP_MIN_RETRANSMIT_TIMEOUT;
    24052413
  • 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 6a62e07..e73cef0 100644
    a b private:  
    106106            status_t    _PrepareSendPath(const sockaddr* peer);
    107107            void        _Acknowledged(tcp_segment_header& segment);
    108108            void        _Retransmit();
    109             void        _UpdateRoundTripTime(int32 roundTripTime, uint32 expectedSamples);
     109            void        _UpdateRoundTripTime(int32 roundTripTime, int32 expectedSamples);
    110110            void        _ResetSlowStart();
    111111            void        _DuplicateAcknowledge(tcp_segment_header& segment);
    112112
    private:  
    171171    int32           fSmoothedRoundTripTime;
    172172    int32           fRoundTripVariation;
    173173    uint32          fSendTime;
     174    tcp_sequence    fRoundTripStartSequence;
    174175    bigtime_t       fRetransmitTimeout;
    175176
    176177    uint32          fReceivedTimestamp;