• Neal Cardwell's avatar
    tcp: fix ssthresh and undo for consecutive short FRTO episodes · 0c9ab092
    Neal Cardwell authored
    Fix TCP FRTO logic so that it always notices when snd_una advances,
    indicating that any RTO after that point will be a new and distinct
    loss episode.
    
    Previously there was a very specific sequence that could cause FRTO to
    fail to notice a new loss episode had started:
    
    (1) RTO timer fires, enter FRTO and retransmit packet 1 in write queue
    (2) receiver ACKs packet 1
    (3) FRTO sends 2 more packets
    (4) RTO timer fires again (should start a new loss episode)
    
    The problem was in step (3) above, where tcp_process_loss() returned
    early (in the spot marked "Step 2.b"), so that it never got to the
    logic to clear icsk_retransmits. Thus icsk_retransmits stayed
    non-zero. Thus in step (4) tcp_enter_loss() would see the non-zero
    icsk_retransmits, decide that this RTO is not a new episode, and
    decide not to cut ssthresh and remember the current cwnd and ssthresh
    for undo.
    
    There were two main consequences to the bug that we have
    observed. First, ssthresh was not decreased in step (4). Second, when
    there was a series of such FRTO (1-4) sequences that happened to be
    followed by an FRTO undo, we would restore the cwnd and ssthresh from
    before the entire series started (instead of the cwnd and ssthresh
    from before the most recent RTO). This could result in cwnd and
    ssthresh being restored to values much bigger than the proper values.
    Signed-off-by: default avatarNeal Cardwell <ncardwell@google.com>
    Signed-off-by: default avatarYuchung Cheng <ycheng@google.com>
    Fixes: e33099f9 ("tcp: implement RFC5682 F-RTO")
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0c9ab092
tcp_input.c 170 KB