• Ilpo Järvinen's avatar
    tcp: Fix inconsistency source (CA_Open only when !tcp_left_out(tp)) · 8aca6cb1
    Ilpo Järvinen authored
    It is possible that this skip path causes TCP to end up into an
    invalid state where ca_state was left to CA_Open while some
    segments already came into sacked_out. If next valid ACK doesn't
    contain new SACK information TCP fails to enter into
    tcp_fastretrans_alert(). Thus at least high_seq is set
    incorrectly to a too high seqno because some new data segments
    could be sent in between (and also, limited transmit is not
    being correctly invoked there). Reordering in both directions
    can easily cause this situation to occur.
    
    I guess we would want to use tcp_moderate_cwnd(tp) there as well
    as it may be possible to use this to trigger oversized burst to
    network by sending an old ACK with huge amount of SACK info, but
    I'm a bit unsure about its effects (mainly to FlightSize), so to
    be on the safe side I just currently fixed it minimally to keep
    TCP's state consistent (obviously, such nasty ACKs have been
    possible this far). Though it seems that FlightSize is already
    underestimated by some amount, so probably on the long term we
    might want to trigger recovery there too, if appropriate, to make
    FlightSize calculation to resemble reality at the time when the
    losses where discovered (but such change scares me too much now
    and requires some more thinking anyway how to do that as it
    likely involves some code shuffling).
    
    This bug was found by Brian Vowell while running my TCP debug
    patch to find cause of another TCP issue (fackets_out
    miscount).
    Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    8aca6cb1
tcp_input.c 156 KB