Ticket #13704: 0001-tcp-fixed-no-response-from-window-update-removed-ide.patch

File 0001-tcp-fixed-no-response-from-window-update-removed-ide.patch, 7.8 KB (added by a-star, 6 years ago)
  • src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp

    From 5fb6e02242be840a99cd978d4681951551bb1bef Mon Sep 17 00:00:00 2001
    From: A-star-ayush <myselfthebest@yahoo.com>
    Date: Fri, 10 Nov 2017 01:46:37 +0530
    Subject: [PATCH] tcp: fixed no response from window update, removed ideal
     timer
    
    ---
     .../kernel/network/protocols/tcp/TCPEndpoint.cpp   | 106 ++++++++++++++-------
     .../kernel/network/protocols/tcp/TCPEndpoint.h     |   1 +
     src/add-ons/kernel/network/protocols/tcp/tcp.h     |   2 +
     3 files changed, 76 insertions(+), 33 deletions(-)
    
    diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp
    index 49e85d2..e3194da 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)  
    428429    fSendWindow(0),
    429430    fSendMaxWindow(0),
    430431    fSendMaxSegmentSize(TCP_DEFAULT_MAX_SEGMENT_SIZE),
     432    fSendMaxSegments(0),
    431433    fSendQueue(socket->send.buffer_size),
    432434    fInitialSendSequence(0),
    433435    fPreviousHighestAcknowledge(0),
    TCPEndpoint::_AddData(tcp_segment_header& segment, net_buffer* buffer)  
    13841386    if ((segment.flags & TCP_FLAG_PUSH) != 0)
    13851387        fReceiveQueue.SetPushPointer();
    13861388
    1387     if (fSendUnacknowledged == fSendMax) {
    1388         TRACE("data received, resetting ideal timer to: %"
    1389                 B_PRIdBIGTIME, fRetransmitTimeout);
    1390         gStackModule->set_timer(&fRetransmitTimer, fRetransmitTimeout);
    1391         T(TimerSet(this, "ideal", fRetransmitTimeout));
    1392     }
    1393 
    13941389    return fReceiveQueue.Available() > 0;
    13951390}
    13961391
    TCPEndpoint::_PrepareReceivePath(tcp_segment_header& segment)  
    14261421            fFlags &= ~FLAG_OPTION_TIMESTAMP;
    14271422    }
    14281423
    1429     fCongestionWindow = 2 * fSendMaxSegmentSize;
     1424    if (fSendMaxSegmentSize > 2190)
     1425        fCongestionWindow = 2 * fSendMaxSegmentSize;
     1426    else if (fSendMaxSegmentSize > 1095)
     1427        fCongestionWindow = 3 * fSendMaxSegmentSize;
     1428    else
     1429        fCongestionWindow = 4 * fSendMaxSegmentSize;
     1430
     1431    fSendMaxSegments = fCongestionWindow / fSendMaxSegmentSize;
    14301432    fSlowStartThreshold = (uint32)segment.advertised_window << fSendWindowShift;
    14311433}
    14321434
    TCPEndpoint::_Receive(tcp_segment_header& segment, net_buffer* buffer)  
    17091711    }
    17101712#endif
    17111713
     1714    if (advertisedWindow > fSendWindow)
     1715        action |= IMMEDIATE_ACKNOWLEDGE;
     1716
    17121717    fSendWindow = advertisedWindow;
    17131718    if (advertisedWindow > fSendMaxWindow)
    17141719        fSendMaxWindow = advertisedWindow;
    inline bool  
    19461951TCPEndpoint::_ShouldSendSegment(tcp_segment_header& segment, uint32 length,
    19471952    uint32 segmentMaxSize, uint32 flightSize)
    19481953{
     1954    if (fState == ESTABLISHED && fSendMaxSegments == 0)
     1955        return false;
     1956
    19491957    if (length > 0) {
    19501958        // Avoid the silly window syndrome - we only send a segment in case:
    19511959        // - we have a full segment to send, or
    TCPEndpoint::_SendQueued(bool force, uint32 sendWindow)  
    21682176        fReceiveMaxAdvertised = fReceiveNext
    21692177            + ((uint32)segment.advertised_window << fReceiveWindowShift);
    21702178
     2179        if (segmentLength != 0 && fState == ESTABLISHED)
     2180            --fSendMaxSegments;
     2181
    21712182        status = next->module->send_routed_data(next, fRoute, buffer);
    21722183        if (status < B_OK) {
    21732184            gBufferModule->free(buffer);
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22652276
    22662277    if (fSendUnacknowledged < segment.acknowledge) {
    22672278        fSendQueue.RemoveUntil(segment.acknowledge);
     2279
     2280        uint32 bytesAcknowledged = segment.acknowledge - fSendUnacknowledged.Number();
     2281        fPreviousHighestAcknowledge = fSendUnacknowledged;
    22682282        fSendUnacknowledged = segment.acknowledge;
     2283
     2284        if (fPreviousHighestAcknowledge > fSendUnacknowledged) {
     2285            // need to update the recover variable upon a sequence wraparound
     2286            fRecover = segment.acknowledge - 1;
     2287        }
     2288
     2289        // the acknowledgment of the SYN/ACK MUST NOT increase the size of the congestion window
     2290        if (fSendUnacknowledged != fInitialSendSequence) {
     2291            if (fCongestionWindow < fSlowStartThreshold)
     2292                fCongestionWindow += min_c(bytesAcknowledged, fSendMaxSegmentSize);
     2293            else {
     2294                uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize;
     2295
     2296                if (increment < fCongestionWindow)
     2297                    increment = 1;
     2298                else
     2299                    increment /= fCongestionWindow;
     2300
     2301                fCongestionWindow += increment;
     2302            }
     2303
     2304            fSendMaxSegments = UINT32_MAX;
     2305        }
     2306
     2307        if ((fFlags & FLAG_RECOVERY) != 0) {
     2308            fSendNext = fSendUnacknowledged;
     2309            _SendQueued();
     2310            fCongestionWindow -= bytesAcknowledged;
     2311
     2312            if (bytesAcknowledged > fSendMaxSegmentSize)
     2313                fCongestionWindow += fSendMaxSegmentSize;
     2314
     2315            fSendNext = fSendMax;
     2316        } else
     2317            fDuplicateAcknowledgeCount = 0;
     2318
    22692319        if (fSendNext < fSendUnacknowledged)
    22702320            fSendNext = fSendUnacknowledged;
    22712321
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22822332        }
    22832333
    22842334        if (fSendUnacknowledged == fSendMax) {
    2285             TRACE("all acknowledged, cancelling retransmission timer. Using it as ideal timer for: %"
    2286                 B_PRIdBIGTIME, fRetransmitTimeout);
    2287             gStackModule->set_timer(&fRetransmitTimer, fRetransmitTimeout);
    2288             T(TimerSet(this, "ideal", fRetransmitTimeout));
     2335            TRACE("all acknowledged, cancelling retransmission timer.");
     2336            gStackModule->cancel_timer(&fRetransmitTimer);
     2337            T(TimerSet(this, "retransmit", -1));
    22892338            fSendTime = 0;
    22902339        } else {
    22912340            TRACE("data acknowledged, resetting retransmission timer to: %"
    TCPEndpoint::_Acknowledged(tcp_segment_header& segment)  
    22992348            fSendCondition.NotifyAll();
    23002349            gSocketModule->notify(socket, B_SELECT_WRITE, fSendQueue.Free());
    23012350        }
    2302 
    2303         if (fCongestionWindow < fSlowStartThreshold)
    2304             fCongestionWindow += fSendMaxSegmentSize;
    2305     }
    2306 
    2307     if (fCongestionWindow >= fSlowStartThreshold) {
    2308         uint32 increment = fSendMaxSegmentSize * fSendMaxSegmentSize;
    2309 
    2310         if (increment < fCongestionWindow)
    2311             increment = 1;
    2312         else
    2313             increment /= fCongestionWindow;
    2314 
    2315         fCongestionWindow += increment;
    23162351    }
    23172352
    23182353    // if there is data left to be sent, send it now
    TCPEndpoint::_Retransmit()  
    23262361{
    23272362    TRACE("Retransmit()");
    23282363
    2329     _ResetSlowStart();
    2330     fSendNext = fSendUnacknowledged;
    2331 
    2332     // Do exponential back off of the retransmit timeout
    2333     fRetransmitTimeout *= 2;
    2334     if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
    2335         fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
     2364    if (fState < ESTABLISHED) {
     2365        fRetransmitTimeout = TCP_SYN_RETRANSMIT_TIMEOUT;
     2366        fCongestionWindow = fSendMaxSegmentSize;
     2367    } else {
     2368        _ResetSlowStart();
     2369        fDuplicateAcknowledgeCount = 0;
     2370        // Do exponential back off of the retransmit timeout
     2371        fRetransmitTimeout *= 2;
     2372        if (fRetransmitTimeout > TCP_MAX_RETRANSMIT_TIMEOUT)
     2373            fRetransmitTimeout = TCP_MAX_RETRANSMIT_TIMEOUT;
     2374    }
    23362375
     2376    fSendNext = fSendUnacknowledged;
    23372377    _SendQueued();
    23382378
    23392379    fRecover = fSendNext.Number() - 1;
  • 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 22bf859..6a62e07 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;