Ticket #13633: 0005-tcp-rfc-6298-7323-updated-rto-calculations-and-seman.patch

File 0005-tcp-rfc-6298-7323-updated-rto-calculations-and-seman.patch, 6.0 KB (added by a-star, 2 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From 642173f3999dcc86a23e0feb4299035e8d396900 Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Sat, 29 Jul 2017 22:19:47 +0530
    Subject: [PATCH 5/6] tcp: rfc 6298 & 7323: updated rto calculations and
     semantics
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp   | 61 +++++++++++++---------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |  7 +--
     2 files changed, 41 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 28f6c1c..3aaaae7 100644
    a b TCPEndpoint::TCPEndpoint(net_socket* socket)  
    439439    fReceiveWindow(socket->receive.buffer_size),
    440440    fReceiveMaxSegmentSize(TCP_DEFAULT_MAX_SEGMENT_SIZE),
    441441    fReceiveQueue(socket->receive.buffer_size),
    442     fRoundTripTime(TCP_INITIAL_RTT / kTimestampFactor),
    443     fRoundTripDeviation(TCP_INITIAL_RTT / kTimestampFactor),
     442    fSmoothedRoundTripTime(0),
     443    fRoundTripVariation(0),
     444    fSendTime(0),
    444445    fRetransmitTimeout(TCP_INITIAL_RTT),
    445446    fReceivedTimestamp(0),
    446447    fCongestionWindow(0),
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    21702171            return status;
    21712172        }
    21722173
     2174        if (fSendTime == 0 && (segmentLength != 0 || (segment.flags & TCP_FLAG_SYNCHRONIZE ) == 1))
     2175            fSendTime = tcp_now();
     2176
    21732177        if (shouldStartRetransmitTimer && size > 0) {
    21742178            TRACE("starting initial retransmit timer of: %" B_PRIdBIGTIME,
    21752179                fRetransmitTimeout);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22782282        if (fSendNext < fSendUnacknowledged)
    22792283            fSendNext = fSendUnacknowledged;
    22802284
    2281         if (segment.options & TCP_HAS_TIMESTAMPS)
    2282             _UpdateRoundTripTime(tcp_diff_timestamp(segment.timestamp_reply));
    2283         else {
    2284             // TODO: Fallback to RFC 793 type estimation; This just resets
    2285             // any potential exponential back off that happened due to
    2286             // retransmits.
    2287             fRetransmitTimeout = TCP_INITIAL_RTT;
     2285        if (fFlags & FLAG_OPTION_TIMESTAMP) {
     2286            uint32 flightSize = (fSendMax - fSendUnacknowledged).Number();
     2287            _UpdateRoundTripTime(tcp_diff_timestamp(segment.timestamp_reply),
     2288                1 + ((flightSize - 1) / (fSendMaxSegmentSize << 1)));
     2289        }
     2290
     2291        // Karn's algorithm: RTT measurement must not be made using segments that were retransmitted
     2292        else if (fSendTime > 1 && fSendNext == fSendMax) {
     2293            _UpdateRoundTripTime(tcp_diff_timestamp(fSendTime), 1);
     2294            fSendTime = 1;
    22882295        }
    22892296
    22902297        if (fSendUnacknowledged == fSendMax) {
    22912298            TRACE("all acknowledged, cancelling retransmission timer");
    22922299            gStackModule->cancel_timer(&fRetransmitTimer);
    22932300            T(TimerSet(this, "retransmit", -1));
     2301
     2302            fSendTime = 0;
     2303
    22942304        } else {
    22952305            TRACE("data acknowledged, resetting retransmission timer to: %"
    22962306                B_PRIdBIGTIME, fRetransmitTimeout);
    TCPEndpoint::_Retransmit()  
    23342344
    23352345
    23362346void
    2337 TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime)
     2347TCPEndpoint::_UpdateRoundTripTime(int32 roundTripTime, uint32 expectedSamples)
    23382348{
    2339     int32 rtt = roundTripTime;
    2340 
    2341     // "smooth" round trip time as per Van Jacobson
    2342     rtt -= fRoundTripTime / 8;
    2343     fRoundTripTime += rtt;
    2344     if (rtt < 0)
    2345         rtt = -rtt;
    2346     rtt -= fRoundTripDeviation / 4;
    2347     fRoundTripDeviation += rtt;
     2349    if(fSmoothedRoundTripTime == 0) {
     2350        fSmoothedRoundTripTime = roundTripTime;
     2351        fRoundTripVariation = roundTripTime >> 1;
     2352        fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation << 2))
     2353                * kTimestampFactor;
     2354    } else {
     2355        int32 delta = fSmoothedRoundTripTime - roundTripTime;
     2356        if (delta < 0)
     2357            delta = -delta;
     2358        fRoundTripVariation += ((delta - fRoundTripVariation) >> 2) / expectedSamples;
     2359        fSmoothedRoundTripTime += ((roundTripTime - fSmoothedRoundTripTime) >> 3) / expectedSamples;
     2360        fRetransmitTimeout = (fSmoothedRoundTripTime + max_c(100, fRoundTripVariation << 2))
     2361            * kTimestampFactor;
     2362    }
    23482363
    2349     fRetransmitTimeout = ((fRoundTripTime / 4 + fRoundTripDeviation) / 2)
    2350         * kTimestampFactor;
    23512364    if (fRetransmitTimeout < TCP_MIN_RETRANSMIT_TIMEOUT)
    23522365        fRetransmitTimeout = TCP_MIN_RETRANSMIT_TIMEOUT;
    23532366
    TCPEndpoint::_RetransmitTimer(net_timer* timer, void* _endpoint)  
    23752388    T(TimerTriggered(endpoint, "retransmit"));
    23762389
    23772390    MutexLocker locker(endpoint->fLock);
    2378     if (!locker.IsLocked())
     2391    if (!locker.IsLocked() || gStackModule->is_timer_active(timer))
    23792392        return;
    23802393
    23812394    endpoint->_Retransmit();
    TCPEndpoint::Dump() const  
    25032516        fInitialReceiveSequence.Number());
    25042517    kprintf("    duplicate acknowledge count: %" B_PRIu32 "\n",
    25052518        fDuplicateAcknowledgeCount);
    2506     kprintf("  round trip time: %" B_PRId32 " (deviation %" B_PRId32 ")\n",
    2507         fRoundTripTime, fRoundTripDeviation);
     2519    kprintf("  smoothed round trip time: %" B_PRId32 " (deviation %" B_PRId32 ")\n",
     2520        fSmoothedRoundTripTime, fRoundTripVariation);
    25082521    kprintf("  retransmit timeout: %" B_PRId64 "\n", fRetransmitTimeout);
    25092522    kprintf("  congestion window: %" B_PRIu32 "\n", fCongestionWindow);
    25102523    kprintf("  slow start threshold: %" B_PRIu32 "\n", fSlowStartThreshold);
  • 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 fd59c46..ff6739e 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);
     109            void        _UpdateRoundTripTime(int32 roundTripTime, uint32 expectedSamples);
    110110            void        _ResetSlowStart();
    111111            void        _DuplicateAcknowledge(tcp_segment_header& segment);
    112112
    private:  
    166166    tcp_sequence    fInitialReceiveSequence;
    167167
    168168    // round trip time and retransmit timeout computation
    169     int32           fRoundTripTime;
    170     int32           fRoundTripDeviation;
     169    int32           fSmoothedRoundTripTime;
     170    int32           fRoundTripVariation;
     171    uint32          fSendTime;
    171172    bigtime_t       fRetransmitTimeout;
    172173
    173174    uint32          fReceivedTimestamp;