Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/uipc_usrreq.c
Show First 20 Lines • Show All 272 Lines • ▼ Show 20 Lines | |||||
static int uipc_ctloutput(struct socket *, struct sockopt *); | static int uipc_ctloutput(struct socket *, struct sockopt *); | ||||
static int unp_connect(struct socket *, struct sockaddr *, | static int unp_connect(struct socket *, struct sockaddr *, | ||||
struct thread *); | struct thread *); | ||||
static int unp_connectat(int, struct socket *, struct sockaddr *, | static int unp_connectat(int, struct socket *, struct sockaddr *, | ||||
struct thread *); | struct thread *); | ||||
static int unp_connect2(struct socket *so, struct socket *so2, int); | static int unp_connect2(struct socket *so, struct socket *so2, int); | ||||
static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2); | static void unp_disconnect(struct unpcb *unp, struct unpcb *unp2); | ||||
static void unp_dispose(struct mbuf *); | static void unp_dispose(struct mbuf *); | ||||
static void unp_dispose_so(struct socket *so); | |||||
static void unp_shutdown(struct unpcb *); | static void unp_shutdown(struct unpcb *); | ||||
static void unp_drop(struct unpcb *, int); | static void unp_drop(struct unpcb *, int); | ||||
static void unp_gc(__unused void *, int); | static void unp_gc(__unused void *, int); | ||||
static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int)); | static void unp_scan(struct mbuf *, void (*)(struct filedescent **, int)); | ||||
static void unp_discard(struct file *); | static void unp_discard(struct file *); | ||||
static void unp_freerights(struct filedescent **, int); | static void unp_freerights(struct filedescent **, int); | ||||
static void unp_init(void); | static void unp_init(void); | ||||
static int unp_internalize(struct mbuf **, struct thread *); | static int unp_internalize(struct mbuf **, struct thread *); | ||||
Show All 40 Lines | |||||
}, | }, | ||||
}; | }; | ||||
static struct domain localdomain = { | static struct domain localdomain = { | ||||
.dom_family = AF_LOCAL, | .dom_family = AF_LOCAL, | ||||
.dom_name = "local", | .dom_name = "local", | ||||
.dom_init = unp_init, | .dom_init = unp_init, | ||||
.dom_externalize = unp_externalize, | .dom_externalize = unp_externalize, | ||||
.dom_dispose = unp_dispose, | .dom_dispose = unp_dispose_so, | ||||
.dom_protosw = localsw, | .dom_protosw = localsw, | ||||
.dom_protoswNPROTOSW = &localsw[sizeof(localsw)/sizeof(localsw[0])] | .dom_protoswNPROTOSW = &localsw[sizeof(localsw)/sizeof(localsw[0])] | ||||
}; | }; | ||||
DOMAIN_SET(local); | DOMAIN_SET(local); | ||||
static void | static void | ||||
uipc_abort(struct socket *so) | uipc_abort(struct socket *so) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,865 Lines • ▼ Show 20 Lines | if ((unp->unp_gcflag & UNPGC_REF) == 0 && fp && | ||||
unp_unreachable++; | unp_unreachable++; | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Mark all sockets we reference with RIGHTS. | * Mark all sockets we reference with RIGHTS. | ||||
*/ | */ | ||||
so = unp->unp_socket; | so = unp->unp_socket; | ||||
if ((unp->unp_gcflag & UNPGC_IGNORE_RIGHTS) == 0) { | |||||
SOCKBUF_LOCK(&so->so_rcv); | SOCKBUF_LOCK(&so->so_rcv); | ||||
unp_scan(so->so_rcv.sb_mb, unp_accessable); | unp_scan(so->so_rcv.sb_mb, unp_accessable); | ||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCKBUF_UNLOCK(&so->so_rcv); | ||||
} | |||||
/* | /* | ||||
* Mark all sockets in our accept queue. | * Mark all sockets in our accept queue. | ||||
*/ | */ | ||||
ACCEPT_LOCK(); | ACCEPT_LOCK(); | ||||
TAILQ_FOREACH(soa, &so->so_comp, so_list) { | TAILQ_FOREACH(soa, &so->so_comp, so_list) { | ||||
if ((sotounpcb(soa)->unp_gcflag & UNPGC_IGNORE_RIGHTS) != 0) | |||||
continue; | |||||
SOCKBUF_LOCK(&soa->so_rcv); | SOCKBUF_LOCK(&soa->so_rcv); | ||||
unp_scan(soa->so_rcv.sb_mb, unp_accessable); | unp_scan(soa->so_rcv.sb_mb, unp_accessable); | ||||
SOCKBUF_UNLOCK(&soa->so_rcv); | SOCKBUF_UNLOCK(&soa->so_rcv); | ||||
} | } | ||||
ACCEPT_UNLOCK(); | ACCEPT_UNLOCK(); | ||||
unp->unp_gcflag |= UNPGC_SCANNED; | unp->unp_gcflag |= UNPGC_SCANNED; | ||||
} | } | ||||
Show All 13 Lines | unp_gc(__unused void *arg, int pending) | ||||
struct unp_head **head; | struct unp_head **head; | ||||
struct file *f, **unref; | struct file *f, **unref; | ||||
struct unpcb *unp; | struct unpcb *unp; | ||||
int i, total; | int i, total; | ||||
unp_taskcount++; | unp_taskcount++; | ||||
UNP_LIST_LOCK(); | UNP_LIST_LOCK(); | ||||
/* | /* | ||||
* First clear all gc flags from previous runs. | * First clear all gc flags from previous runs, apart from | ||||
* UNPGC_IGNORE_RIGHTS. | |||||
*/ | */ | ||||
for (head = heads; *head != NULL; head++) | for (head = heads; *head != NULL; head++) | ||||
LIST_FOREACH(unp, *head, unp_link) | LIST_FOREACH(unp, *head, unp_link) | ||||
unp->unp_gcflag = 0; | unp->unp_gcflag = | ||||
(unp->unp_gcflag & UNPGC_IGNORE_RIGHTS); | |||||
/* | /* | ||||
* Scan marking all reachable sockets with UNPGC_REF. Once a socket | * Scan marking all reachable sockets with UNPGC_REF. Once a socket | ||||
* is reachable all of the sockets it references are reachable. | * is reachable all of the sockets it references are reachable. | ||||
* Stop the scan once we do a complete loop without discovering | * Stop the scan once we do a complete loop without discovering | ||||
* a new reachable socket. | * a new reachable socket. | ||||
*/ | */ | ||||
do { | do { | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void | static void | ||||
unp_dispose(struct mbuf *m) | unp_dispose(struct mbuf *m) | ||||
{ | { | ||||
if (m) | if (m) | ||||
unp_scan(m, unp_freerights); | unp_scan(m, unp_freerights); | ||||
} | |||||
/* | |||||
* Synchronize against unp_gc, which can trip over data as we are freeing it. | |||||
*/ | |||||
static void | |||||
unp_dispose_so(struct socket *so) | |||||
{ | |||||
struct unpcb *unp; | |||||
unp = sotounpcb(so); | |||||
UNP_LIST_LOCK(); | |||||
unp->unp_gcflag |= UNPGC_IGNORE_RIGHTS; | |||||
UNP_LIST_UNLOCK(); | |||||
unp_dispose(so->so_rcv.sb_mb); | |||||
} | } | ||||
static void | static void | ||||
unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int)) | unp_scan(struct mbuf *m0, void (*op)(struct filedescent **, int)) | ||||
{ | { | ||||
struct mbuf *m; | struct mbuf *m; | ||||
struct cmsghdr *cm; | struct cmsghdr *cm; | ||||
void *data; | void *data; | ||||
▲ Show 20 Lines • Show All 189 Lines • Show Last 20 Lines |