• Randall Stewart's avatar
    tcp: Fix bugs related to the PUSH bit and rack and an ack war · 13c0e198
    Randall Stewart authored
    Michaels testing with UDP tunneling found an issue with the push bit, which was only partly fixed
    in the last commit. The problem is the left edge gets transmitted before the adjustments are done
    to the send_map, this means that right edge bits must be considered to be added only if
    the entire RSM is being retransmitted.
    Now syzkaller also continued to find a crash, which Michael sent me the reproducer for. Turns
    out that the reproducer on default (freebsd) stack made the stack get into an ack-war with itself.
    After fixing the reference issues in rack the same ack-war was found in rack (and bbr). Basically
    what happens is we go into the reassembly code and lose the FIN bit. The trick here is we
    should not be going into the reassembly code if tlen == 0 i.e. the peer never sent you anything.
    That then gets the proper action on the FIN bit but then you end up in LAST_ACK with no
    timers running. This is because the usrclosed function gets called and the FIN's and such have
    already been exchanged. So when we should be entering FIN_WAIT2 (or even FIN_WAIT1) we get
    stuck in LAST_ACK. Fixing this means tweaking the usrclosed function so that we properly
    recognize the condition and drop into FIN_WAIT2 where a timer will allow at least TP_MAXIDLE
    before closing (to allow time for the peer to retransmit its FIN if the ack is lost). Setting the fast_finwait2
    timer can speed this up in testing.
    Reviewed by: mtuexen,rscheff
    Sponsored by: Netflix Inc
    Differential Revision:	https://reviews.freebsd.org/D30451