diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-04-01 16:04:42 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-04-01 16:04:42 +0000 |
commit | 71cc03392bbc78f93765e5550fc35f98c373df04 (patch) | |
tree | 84f123a9e4ae49f3aeb4718b6d6dfdba595ac39c | |
parent | 173781a39a4623af3173bfdc1e69f3a3fe4166f2 (diff) | |
download | FreeBSD-src-71cc03392bbc78f93765e5550fc35f98c373df04.zip FreeBSD-src-71cc03392bbc78f93765e5550fc35f98c373df04.tar.gz |
Break out in_pcbdetach() into two functions:
- in_pcbdetach(), which removes the link between an inpcb and its
socket.
- in_pcbfree(), which frees a detached pcb.
Unlike the previous in_pcbdetach(), neither of these functions will
attempt to conditionally free the socket, as they are responsible only
for managing in_pcb memory. Mirror these changes into in6_pcbdetach()
by breaking it into in6_pcbdetach() and in6_pcbfree().
While here, eliminate undesired checks for NULL inpcb pointers in
sockets, as we will now have as an invariant that sockets will always
have valid so_pcb pointers.
MFC after: 3 months
-rw-r--r-- | sys/netinet/in_pcb.c | 39 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 1 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 24 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.h | 1 |
4 files changed, 34 insertions, 31 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index d96a838..2941dfc 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -676,16 +676,30 @@ in_pcbdisconnect(struct inpcb *inp) #ifdef IPSEC ipsec_pcbdisconn(inp->inp_sp); #endif - if (inp->inp_socket->so_state & SS_NOFDREF) - in_pcbdetach(inp); } +/* + * In the old world order, in_pcbdetach() served two functions: to detach the + * pcb from the socket/potentially free the socket, and to free the pcb + * itself. In the new world order, the protocol code is responsible for + * managing the relationship with the socket, and this code simply frees the + * pcb. + */ void in_pcbdetach(struct inpcb *inp) { - struct socket *so = inp->inp_socket; + + KASSERT(inp->inp_socket != NULL, ("in_pcbdetach: inp_socket == NULL")); + inp->inp_socket->so_pcb = NULL; + inp->inp_socket = NULL; +} + +void +in_pcbfree(struct inpcb *inp) +{ struct inpcbinfo *ipi = inp->inp_pcbinfo; + KASSERT(inp->inp_socket == NULL, ("in_pcbfree: inp_socket != NULL")); INP_INFO_WLOCK_ASSERT(ipi); INP_LOCK_ASSERT(inp); @@ -694,12 +708,6 @@ in_pcbdetach(struct inpcb *inp) #endif /*IPSEC*/ inp->inp_gencnt = ++ipi->ipi_gencnt; in_pcbremlists(inp); - if (so) { - ACCEPT_LOCK(); - SOCK_LOCK(so); - so->so_pcb = NULL; - sotryfree(so); - } if (inp->inp_options) (void)m_free(inp->inp_options); ip_freemoptions(inp->inp_moptions); @@ -744,10 +752,7 @@ in_setsockaddr(struct socket *so, struct sockaddr **nam, INP_INFO_RLOCK(pcbinfo); inp = sotoinpcb(so); - if (!inp) { - INP_INFO_RUNLOCK(pcbinfo); - return ECONNRESET; - } + KASSERT(inp != NULL, ("in_setsockaddr: so_pcb == NULL")); INP_LOCK(inp); port = inp->inp_lport; addr = inp->inp_laddr; @@ -771,10 +776,7 @@ in_setpeeraddr(struct socket *so, struct sockaddr **nam, INP_INFO_RLOCK(pcbinfo); inp = sotoinpcb(so); - if (!inp) { - INP_INFO_RUNLOCK(pcbinfo); - return ECONNRESET; - } + KASSERT(inp != NULL, ("in_setpeeraddr: so_pcb == NULL")); INP_LOCK(inp); port = inp->inp_fport; addr = inp->inp_faddr; @@ -1169,7 +1171,8 @@ in_pcbsosetlabel(struct socket *so) #ifdef MAC struct inpcb *inp; - inp = (struct inpcb *)so->so_pcb; + inp = sotoinpcb(so); + KASSERT(inp != NULL, ("in_pcbsosetlabel: so->so_pcb == NULL")); INP_LOCK(inp); SOCK_LOCK(so); mac_inpcb_sosetlabel(so, inp); diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index ffdcad1..1500c18 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -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_pcbfree(struct inpcb *); int in_pcbinshash(struct inpcb *); struct inpcb * in_pcblookup_local(struct inpcbinfo *, diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index d2a03e3..cc0d678 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -422,17 +422,23 @@ in6_pcbdisconnect(inp) #ifdef IPSEC ipsec_pcbdisconn(inp->inp_sp); #endif - if (inp->inp_socket->so_state & SS_NOFDREF) - in6_pcbdetach(inp); } void -in6_pcbdetach(inp) - struct inpcb *inp; +in6_pcbdetach(struct inpcb *inp) +{ + + KASSERT(inp->inp_socket != NULL, ("in6_pcbdetach: inp_socket == NULL")); + inp->inp_socket->so_pcb = NULL; + inp->inp_socket = NULL; +} + +void +in6_pcbfree(struct inpcb *inp) { - struct socket *so = inp->inp_socket; struct inpcbinfo *ipi = inp->inp_pcbinfo; + KASSERT(inp->inp_socket == NULL, ("in6_pcbfree: inp_socket != NULL")); INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); INP_LOCK_ASSERT(inp); @@ -442,14 +448,6 @@ in6_pcbdetach(inp) #endif /* IPSEC */ inp->inp_gencnt = ++ipi->ipi_gencnt; in_pcbremlists(inp); - - if (so) { - ACCEPT_LOCK(); - SOCK_LOCK(so); - so->so_pcb = NULL; - sotryfree(so); - } - ip6_freepcbopts(inp->in6p_outputopts); ip6_freemoptions(inp->in6p_moptions); /* Check and free IPv4 related resources in case of mapped addr */ diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h index 45b46f1..52e566a 100644 --- a/sys/netinet6/in6_pcb.h +++ b/sys/netinet6/in6_pcb.h @@ -76,6 +76,7 @@ int in6_pcbbind __P((struct inpcb *, struct sockaddr *, struct ucred *)); int in6_pcbconnect __P((struct inpcb *, struct sockaddr *, struct ucred *)); void in6_pcbdetach __P((struct inpcb *)); void in6_pcbdisconnect __P((struct inpcb *)); +void in6_pcbfree __P((struct inpcb *)); int in6_pcbladdr __P((struct inpcb *, struct sockaddr *, struct in6_addr **)); struct inpcb * |