diff options
author | Richard Scheffenegger <rscheff@FreeBSD.org> | 2024-02-10 09:16:08 +0000 |
---|---|---|
committer | Richard Scheffenegger <rscheff@FreeBSD.org> | 2024-02-10 09:20:00 +0000 |
commit | 3eeb22cb819409b49296ecb0acbd453671168313 (patch) | |
tree | cdc2c345979dea74200928f123be05b8eff3a4fa | |
parent | 89c3cc20d643d9c77537d7aa1ff10ba218e76568 (diff) | |
download | src-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.c | 1 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 5 | ||||
-rw-r--r-- | sys/netinet/tcp_timewait.c | 1 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 1 |
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) { |