aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Scheffenegger <rscheff@FreeBSD.org>2024-02-10 09:16:08 +0000
committerRichard Scheffenegger <rscheff@FreeBSD.org>2024-02-10 09:20:00 +0000
commit3eeb22cb819409b49296ecb0acbd453671168313 (patch)
treecdc2c345979dea74200928f123be05b8eff3a4fa
parent89c3cc20d643d9c77537d7aa1ff10ba218e76568 (diff)
downloadsrc-3eeb22cb819409b49296ecb0acbd453671168313.tar.gz
src-3eeb22cb819409b49296ecb0acbd453671168313.zip
tcp: clean scoreboard when releasing the socket buffer
The SACK scoreboard is conceptually an extention of the socket buffer. Remove it when the socket buffer goes away with soisdisconnected(). Verify that this is also the expected state in tcp_discardcb(). PR: 276761 Reviewed by: glebius, tuexen, #transport Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D43805
-rw-r--r--sys/netinet/tcp_input.c1
-rw-r--r--sys/netinet/tcp_subr.c5
-rw-r--r--sys/netinet/tcp_timewait.c1
-rw-r--r--sys/netinet/tcp_usrreq.c1
4 files changed, 5 insertions, 3 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index afcda60137ec..b3201750c1e6 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -3022,6 +3022,7 @@ process_ACK:
* we'll hang forever.
*/
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
+ tcp_free_sackholes(tp);
soisdisconnected(so);
tcp_timer_activate(tp, TT_2MSL,
(tcp_fast_finwait2_recycle ?
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index be38280aef0a..6043a3d458e5 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2383,6 +2383,7 @@ tcp_discardcb(struct tcpcb *tp)
#endif
INP_WLOCK_ASSERT(inp);
+ MPASS(TAILQ_EMPTY(&tp->snd_holes));
tcp_timer_stop(tp);
@@ -2394,9 +2395,6 @@ tcp_discardcb(struct tcpcb *tp)
if (tp->t_flags & TF_TOE)
tcp_offload_detach(tp);
#endif
-
- tcp_free_sackholes(tp);
-
#ifdef TCPPCAP
/* Free the TCP PCAP queues. */
tcp_pcap_drain(&(tp->t_inpkts));
@@ -2531,6 +2529,7 @@ tcp_close(struct tcpcb *tp)
if (tp->t_state != TCPS_CLOSED)
tcp_state_change(tp, TCPS_CLOSED);
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
+ tcp_free_sackholes(tp);
soisdisconnected(so);
if (inp->inp_flags & INP_SOCKREF) {
inp->inp_flags &= ~INP_SOCKREF;
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 328f8fe84a8c..266556274e18 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -119,6 +119,7 @@ tcp_twstart(struct tcpcb *tp)
"(inp->inp_flags & INP_DROPPED) != 0"));
tcp_state_change(tp, TCPS_TIME_WAIT);
+ tcp_free_sackholes(tp);
soisdisconnected(inp->inp_socket);
if (tp->t_flags & TF_ACKNOW)
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index ccd6a6149dae..a283d308801f 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -2777,6 +2777,7 @@ tcp_usrclosed(struct tcpcb *tp)
if (tp->t_acktime == 0)
tp->t_acktime = ticks;
if (tp->t_state >= TCPS_FIN_WAIT_2) {
+ tcp_free_sackholes(tp);
soisdisconnected(tptosocket(tp));
/* Prevent the connection hanging in FIN_WAIT_2 forever. */
if (tp->t_state == TCPS_FIN_WAIT_2) {