MCPcopy Create free account
hub / github.com/F-Stack/f-stack / tcp_usr_detach

Function tcp_usr_detach

freebsd/netinet/tcp_usrreq.c:221–311  ·  view source on GitHub ↗

* tcp_usr_detach is called when the socket layer loses its final reference * to the socket, be it a file descriptor reference, a reference from TCP, * etc. At this point, there is only one case in which we will keep around * inpcb state: time wait. */

Source from the content-addressed store, hash-verified

219 * inpcb state: time wait.
220 */
221static void
222tcp_usr_detach(struct socket *so)
223{
224 struct inpcb *inp;
225 struct tcpcb *tp;
226
227 inp = sotoinpcb(so);
228 KASSERT(inp != NULL, ("%s: inp == NULL", __func__));
229 INP_WLOCK(inp);
230 KASSERT(so->so_pcb == inp && inp->inp_socket == so,
231 ("%s: socket %p inp %p mismatch", __func__, so, inp));
232
233 tp = intotcpcb(inp);
234
235 if (inp->inp_flags & INP_TIMEWAIT) {
236 /*
237 * There are two cases to handle: one in which the time wait
238 * state is being discarded (INP_DROPPED), and one in which
239 * this connection will remain in timewait. In the former,
240 * it is time to discard all state (except tcptw, which has
241 * already been discarded by the timewait close code, which
242 * should be further up the call stack somewhere). In the
243 * latter case, we detach from the socket, but leave the pcb
244 * present until timewait ends.
245 *
246 * XXXRW: Would it be cleaner to free the tcptw here?
247 *
248 * Astute question indeed, from twtcp perspective there are
249 * four cases to consider:
250 *
251 * #1 tcp_usr_detach is called at tcptw creation time by
252 * tcp_twstart, then do not discard the newly created tcptw
253 * and leave inpcb present until timewait ends
254 * #2 tcp_usr_detach is called at tcptw creation time by
255 * tcp_twstart, but connection is local and tw will be
256 * discarded immediately
257 * #3 tcp_usr_detach is called at timewait end (or reuse) by
258 * tcp_twclose, then the tcptw has already been discarded
259 * (or reused) and inpcb is freed here
260 * #4 tcp_usr_detach is called() after timewait ends (or reuse)
261 * (e.g. by soclose), then tcptw has already been discarded
262 * (or reused) and inpcb is freed here
263 *
264 * In all three cases the tcptw should not be freed here.
265 */
266 if (inp->inp_flags & INP_DROPPED) {
267 in_pcbdetach(inp);
268 if (__predict_true(tp == NULL)) {
269 in_pcbfree(inp);
270 } else {
271 /*
272 * This case should not happen as in TIMEWAIT
273 * state the inp should not be destroyed before
274 * its tcptw. If INVARIANTS is defined, panic.
275 */
276#ifdef INVARIANTS
277 panic("%s: Panic before an inp double-free: "
278 "INP_TIMEWAIT && INP_DROPPED && tp != NULL"

Callers

nothing calls this directly

Calls 5

in_pcbdetachFunction · 0.85
in_pcbfreeFunction · 0.85
tcp_discardcbFunction · 0.85
panicFunction · 0.50
logFunction · 0.50

Tested by

no test coverage detected