mirror of
https://git.FreeBSD.org/src.git
synced 2025-02-03 17:11:32 +00:00
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
This commit is contained in:
parent
2eafb39b67
commit
10702a2840
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158009
@ -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)
|
||||
{
|
||||
|
@ -352,6 +352,7 @@ int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
|
||||
struct ucred *);
|
||||
void in_pcbdetach(struct inpcb *);
|
||||
void in_pcbdisconnect(struct inpcb *);
|
||||
void in_pcbdrop(struct inpcb *);
|
||||
void in_pcbfree(struct inpcb *);
|
||||
int in_pcbinshash(struct inpcb *);
|
||||
struct inpcb *
|
||||
|
@ -791,8 +791,7 @@ tcp_close(struct tcpcb *tp)
|
||||
INP_INFO_WLOCK_ASSERT(&tcbinfo);
|
||||
INP_LOCK_ASSERT(inp);
|
||||
|
||||
inp->inp_vflag |= INP_DROPPED;
|
||||
|
||||
in_pcbdrop(inp);
|
||||
tcpstat.tcps_closed++;
|
||||
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
|
||||
so = inp->inp_socket;
|
||||
@ -1852,7 +1851,7 @@ tcp_twclose(struct tcptw *tw, int reuse)
|
||||
tw->tw_inpcb = NULL;
|
||||
tcp_timer_2msl_stop(tw);
|
||||
inp->inp_ppcb = NULL;
|
||||
inp->inp_vflag |= INP_DROPPED;
|
||||
in_pcbdrop(inp);
|
||||
|
||||
so = inp->inp_socket;
|
||||
if (so != NULL) {
|
||||
|
@ -791,8 +791,7 @@ tcp_close(struct tcpcb *tp)
|
||||
INP_INFO_WLOCK_ASSERT(&tcbinfo);
|
||||
INP_LOCK_ASSERT(inp);
|
||||
|
||||
inp->inp_vflag |= INP_DROPPED;
|
||||
|
||||
in_pcbdrop(inp);
|
||||
tcpstat.tcps_closed++;
|
||||
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
|
||||
so = inp->inp_socket;
|
||||
@ -1852,7 +1851,7 @@ tcp_twclose(struct tcptw *tw, int reuse)
|
||||
tw->tw_inpcb = NULL;
|
||||
tcp_timer_2msl_stop(tw);
|
||||
inp->inp_ppcb = NULL;
|
||||
inp->inp_vflag |= INP_DROPPED;
|
||||
in_pcbdrop(inp);
|
||||
|
||||
so = inp->inp_socket;
|
||||
if (so != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user