diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-04-25 11:17:35 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-04-25 11:17:35 +0000 |
commit | 5d598011b534415b6bfa0b82fe291c836516bbd0 (patch) | |
tree | ac3c32c6d4a4115de24383a3ecb36ad35f4fff67 /sys/netinet/in_pcb.c | |
parent | 38b8fecaba7630458a55dc2790b6057e3ee53b53 (diff) | |
download | FreeBSD-src-5d598011b534415b6bfa0b82fe291c836516bbd0.zip FreeBSD-src-5d598011b534415b6bfa0b82fe291c836516bbd0.tar.gz |
Abstract inpcb drop logic, previously just setting of INP_DROPPED in TCP,
into in_pcbdrop(). Expand logic to detach the inpcb from its bound
address/port so that dropping a TCP connection releases the inpcb resource
reservation, which since the introduction of socket/pcb reference count
updates, has been persisting until the socket closed rather than being
released implicitly due to prior freeing of the inpcb on TCP drop.
MFC after: 3 months
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r-- | sys/netinet/in_pcb.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 9dac3ec..4fa5c6f 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -728,6 +728,34 @@ in_pcbfree(struct inpcb *inp) uma_zfree(ipi->ipi_zone, inp); } +/* + * TCP needs to maintain its inpcb structure after the TCP connection has + * been torn down. However, it must be disconnected from the inpcb hashes as + * it must not prevent binding of future connections to the same port/ip + * combination by other inpcbs. + */ +void +in_pcbdrop(struct inpcb *inp) +{ + struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; + + INP_INFO_WLOCK_ASSERT(pcbinfo); + INP_LOCK_ASSERT(inp); + + inp->inp_vflag |= INP_DROPPED; + if (inp->inp_lport) { + struct inpcbport *phd = inp->inp_phd; + + LIST_REMOVE(inp, inp_hash); + LIST_REMOVE(inp, inp_portlist); + if (LIST_FIRST(&phd->phd_pcblist) == NULL) { + LIST_REMOVE(phd, phd_hash); + free(phd, M_PCB); + } + inp->inp_lport = 0; + } +} + struct sockaddr * in_sockaddr(in_port_t port, struct in_addr *addr_p) { |