diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -592,6 +592,14 @@ * received new blocks from the other side. */ if (to->to_flags & TOF_SACK) { + /* + * Don't allow SACK holes to cover the FIN sequence + * space. + */ + tcp_seq highdata = tp->snd_max; + if (__predict_false(tp->t_flags & TF_SENTFIN)) + highdata--; + for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); @@ -600,9 +608,9 @@ if (SEQ_GT(sack.end, sack.start) && SEQ_GT(sack.start, tp->snd_una) && SEQ_GT(sack.start, th_ack) && - SEQ_LT(sack.start, tp->snd_max) && + SEQ_LT(sack.start, highdata) && SEQ_GT(sack.end, tp->snd_una) && - SEQ_LEQ(sack.end, tp->snd_max)) { + SEQ_LEQ(sack.end, highdata)) { sack_blocks[num_sack_blks++] = sack; } else if (SEQ_LEQ(sack.start, th_ack) && SEQ_LEQ(sack.end, th_ack)) {