diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -3022,6 +3022,7 @@ * 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 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2383,6 +2383,7 @@ #endif INP_WLOCK_ASSERT(inp); + MPASS(TAILQ_EMPTY(&tp->snd_holes)); tcp_timer_stop(tp); @@ -2394,9 +2395,6 @@ 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 @@ 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 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -119,6 +119,7 @@ "(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 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -2777,6 +2777,7 @@ 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) {