void in_pcbdetach(struct inpcb *inp) { struct socket *so = inp->inp_socket; struct inpcbinfo *ipi = inp->inp_pcbinfo; int s; inp->inp_gencnt = ++ipi->ipi_gencnt; so->so_pcb = 0; sofree(so); if (inp->inp_options) (void)m_free(inp->inp_options); if (inp->inp_route.ro_rt) rtfree(inp->inp_route.ro_rt); ip_freemoptions(inp->inp_moptions); s = splnet(); LIST_REMOVE(inp, inp_hash); LIST_REMOVE(inp, inp_list); splx(s); FREE(inp, M_PCB); }
void sofree(struct socket * so) { INET_TRACE (INETM_SOCKET|INETM_CLOSE, ("INET: sofree, so %lx so_pcb %lx so_state %x so_head %lx\n", so, so->so_pcb, so->so_state, so->so_head)); if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) return; if (so->so_head) { if (!soqremque(so, 0) && !soqremque(so, 1)) panic("sofree"); so->so_head = 0; } sbrelease(&so->so_snd); sorflush(so); #ifdef SAVE_SOCK_ENDPOINTS if (so->so_endpoint) _socket_free_entry (so); #endif /* SAVE_SOCK_ENDPOINTS */ #ifdef IP_MULTICAST /* multicast opts? */ if (so->inp_moptions) ip_freemoptions(so->inp_moptions); #endif /* IP_MULTICAST */ /* IP_TOS opts? */ if (so->so_optsPack) SOCOPT_FREE(so->so_optsPack); qdel(&soq, so); /* Delete the socket entry from the queue */ if (so_evtmap) (*so_evtmap_delete) (so); SOC_FREE(so); }