• I
    tcp FRTO: SACK variant is errorneously used with NewReno · 62ab2227
    Ilpo Järvinen 提交于
    Note: there's actually another bug in FRTO's SACK variant, which
    is the causing failure in NewReno case because of the error
    that's fixed here. I'll fix the SACK case separately (it's
    a separate bug really, though related, but in order to fix that
    I need to audit tp->snd_nxt usage a bit).
    
    There were two places where SACK variant of FRTO is getting
    incorrectly used even if SACK wasn't negotiated by the TCP flow.
    This leads to incorrect setting of frto_highmark with NewReno
    if a previous recovery was interrupted by another RTO.
    
    An eventual fallback to conventional recovery then incorrectly
    considers one or couple of segments as forward transmissions
    though they weren't, which then are not LOST marked during
    fallback making them "non-retransmittable" until the next RTO.
    In a bad case, those segments are really lost and are the only
    one left in the window. Thus TCP needs another RTO to continue.
    The next FRTO, however, could again repeat the same events
    making the progress of the TCP flow extremely slow.
    
    In order for these events to occur at all, FRTO must occur
    again in FRTOs step 3 while the key segments must be lost as
    well, which is not too likely in practice. It seems to most
    frequently with some small devices such as network printers
    that *seem* to accept TCP segments only in-order. In cases
    were key segments weren't lost, things get automatically
    resolved because those wrongly marked segments don't need to be
    retransmitted in order to continue.
    
    I found a reproducer after digging up relevant reports (few
    reports in total, none at netdev or lkml I know of), some
    cases seemed to indicate middlebox issues which seems now
    to be a false assumption some people had made. Bugzilla
    #10063 _might_ be related. Damon L. Chesser <damon@damtek.com>
    had a reproducable case and was kind enough to tcpdump it
    for me. With the tcpdump log it was quite trivial to figure
    out.
    Signed-off-by: NIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    62ab2227
tcp_input.c 155.5 KB