tcp: When we have an out-of-order FIN we do want to strip off the FIN bit.

The last set of commits fixed both a panic (in rack) and an ACK-war (in freebsd and bbr).
However there was a missing case, i.e. where we get an out-of-order FIN by itself.
In such a case we don't want to leave the FIN bit set, otherwise we will do the
wrong thing and ack the FIN incorrectly. Instead we need to go through the
tcp_reasm() code and that way the FIN will be stripped and all will be well.

Reviewed by: mtuexen,rscheff
Sponsored by: Netflix Inc
Differential Revision:	https://reviews.freebsd.org/D30497
This commit is contained in:
Randall Stewart 2021-05-27 10:50:32 -04:00
parent 4cc8a9da49
commit 8c69d988a8
3 changed files with 18 additions and 3 deletions

View File

@ -3191,7 +3191,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
* when trimming from the head. * when trimming from the head.
*/ */
tcp_seq temp = save_start; tcp_seq temp = save_start;
if (tlen) { if (tlen || (th->th_seq != tp->rcv_nxt)) {
/*
* We add the th_seq != rcv_nxt to
* catch the case of a stand alone out
* of order FIN.
*/
thflags = tcp_reass(tp, th, &temp, &tlen, m); thflags = tcp_reass(tp, th, &temp, &tlen, m);
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
} }

View File

@ -8320,7 +8320,12 @@ bbr_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so,
* trimming from the head. * trimming from the head.
*/ */
tcp_seq temp = save_start; tcp_seq temp = save_start;
if (tlen) { if (tlen || (th->th_seq != tp->rcv_nxt)) {
/*
* We add the th_seq != rcv_nxt to
* catch the case of a stand alone out
* of order FIN.
*/
thflags = tcp_reass(tp, th, &temp, &tlen, m); thflags = tcp_reass(tp, th, &temp, &tlen, m);
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
} }

View File

@ -10235,7 +10235,12 @@ rack_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so,
* trimming from the head. * trimming from the head.
*/ */
tcp_seq temp = save_start; tcp_seq temp = save_start;
if (tlen) { if (tlen || (th->th_seq != tp->rcv_nxt)) {
/*
* We add the th_seq != rcv_nxt to
* catch the case of a stand alone out
* of order FIN.
*/
thflags = tcp_reass(tp, th, &temp, &tlen, m); thflags = tcp_reass(tp, th, &temp, &tlen, m);
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
} }