summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/in_pcb.c39
-rw-r--r--sys/netinet/in_pcb.h1
-rw-r--r--sys/netinet6/in6_pcb.c24
-rw-r--r--sys/netinet6/in6_pcb.h1
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 *
OpenPOWER on IntegriCloud