| 2054 | } |
| 2055 | |
| 2056 | void |
| 2057 | tcp_timer_discard(void *ptp) |
| 2058 | { |
| 2059 | struct inpcb *inp; |
| 2060 | struct tcpcb *tp; |
| 2061 | struct epoch_tracker et; |
| 2062 | |
| 2063 | tp = (struct tcpcb *)ptp; |
| 2064 | CURVNET_SET(tp->t_vnet); |
| 2065 | NET_EPOCH_ENTER(et); |
| 2066 | inp = tp->t_inpcb; |
| 2067 | KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", |
| 2068 | __func__, tp)); |
| 2069 | INP_WLOCK(inp); |
| 2070 | KASSERT((tp->t_timers->tt_flags & TT_STOPPED) != 0, |
| 2071 | ("%s: tcpcb has to be stopped here", __func__)); |
| 2072 | tp->t_timers->tt_draincnt--; |
| 2073 | if (tp->t_timers->tt_draincnt == 0) { |
| 2074 | /* We own the last reference on this tcpcb, let's free it. */ |
| 2075 | #ifdef TCP_BLACKBOX |
| 2076 | tcp_log_tcpcbfini(tp); |
| 2077 | #endif |
| 2078 | TCPSTATES_DEC(tp->t_state); |
| 2079 | if (tp->t_fb->tfb_tcp_fb_fini) |
| 2080 | (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1); |
| 2081 | refcount_release(&tp->t_fb->tfb_refcnt); |
| 2082 | tp->t_inpcb = NULL; |
| 2083 | uma_zfree(V_tcpcb_zone, tp); |
| 2084 | if (in_pcbrele_wlocked(inp)) { |
| 2085 | NET_EPOCH_EXIT(et); |
| 2086 | CURVNET_RESTORE(); |
| 2087 | return; |
| 2088 | } |
| 2089 | } |
| 2090 | INP_WUNLOCK(inp); |
| 2091 | NET_EPOCH_EXIT(et); |
| 2092 | CURVNET_RESTORE(); |
| 2093 | } |
| 2094 | |
| 2095 | /* |
| 2096 | * Attempt to close a TCP control block, marking it as dropped, and freeing |
nothing calls this directly
no test coverage detected