aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_sack.c
diff options
context:
space:
mode:
authorRichard Scheffenegger <rscheff@FreeBSD.org>2021-03-17 15:44:29 +0000
committerRichard Scheffenegger <rscheff@FreeBSD.org>2021-03-17 19:05:33 +0000
commit703419774f86525a2441d615733993a6fddcd047 (patch)
treed2cf023ad58dfd212bbf8fff4416108d8e21315c /sys/netinet/tcp_sack.c
parentdb3b5695e61b1f23c65d0235a9f1707ed1df5227 (diff)
fix panic when rescue retransmission and FIN overlap
PR: 254244 PR: 254309 Reviewed By: #transport, hselasky, tuexen Approved by: re (cperciva) MFC after: immediately Sponsored By: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D29315 (cherry picked from commit e9f029831fa5747ae1b405f5716c52cb4ebf1e04)
Diffstat (limited to 'sys/netinet/tcp_sack.c')
-rw-r--r--sys/netinet/tcp_sack.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index 37db30007580..f8d983da723b 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -831,8 +831,18 @@ tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th)
(tp->snd_recover == tp->snd_max) &&
TAILQ_EMPTY(&tp->snd_holes) &&
(tp->sackhint.delivered_data > 0)) {
- struct sackhole *hole;
- hole = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack, tp->snd_max - maxseg), tp->snd_max, NULL);
+ /*
+ * Exclude FIN sequence space in
+ * the hole for the rescue retransmission,
+ * and also don't create a hole, if only
+ * the ACK for a FIN is outstanding.
+ */
+ tcp_seq highdata = tp->snd_max;
+ if (tp->t_flags & TF_SENTFIN)
+ highdata--;
+ if (th->th_ack != highdata)
+ (void)tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack,
+ highdata - maxseg), highdata, NULL);
}
(void) tp->t_fb->tfb_tcp_output(tp);
}