Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/uipc_socket.c
Show First 20 Lines • Show All 799 Lines • ▼ Show 20 Lines | if (so->so_options & SO_ACCEPTCONN) { | ||||
KASSERT((TAILQ_EMPTY(&so->so_incomp)), | KASSERT((TAILQ_EMPTY(&so->so_incomp)), | ||||
("sofree: so_incomp populated")); | ("sofree: so_incomp populated")); | ||||
} | } | ||||
SOCK_UNLOCK(so); | SOCK_UNLOCK(so); | ||||
ACCEPT_UNLOCK(); | ACCEPT_UNLOCK(); | ||||
VNET_SO_ASSERT(so); | VNET_SO_ASSERT(so); | ||||
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) | if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) | ||||
(*pr->pr_domain->dom_dispose)(so->so_rcv.sb_mb); | (*pr->pr_domain->dom_dispose)(so); | ||||
if (pr->pr_usrreqs->pru_detach != NULL) | if (pr->pr_usrreqs->pru_detach != NULL) | ||||
(*pr->pr_usrreqs->pru_detach)(so); | (*pr->pr_usrreqs->pru_detach)(so); | ||||
/* | /* | ||||
* From this point on, we assume that no other references to this | * From this point on, we assume that no other references to this | ||||
* socket exist anywhere else in the stack. Therefore, no locks need | * socket exist anywhere else in the stack. Therefore, no locks need | ||||
* to be acquired or held. | * to be acquired or held. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 1,534 Lines • ▼ Show 20 Lines | soshutdown(struct socket *so, int how) | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
sorflush(struct socket *so) | sorflush(struct socket *so) | ||||
{ | { | ||||
struct sockbuf *sb = &so->so_rcv; | struct sockbuf *sb = &so->so_rcv; | ||||
struct protosw *pr = so->so_proto; | struct protosw *pr = so->so_proto; | ||||
struct sockbuf asb; | struct socket aso; | ||||
VNET_SO_ASSERT(so); | VNET_SO_ASSERT(so); | ||||
/* | /* | ||||
* In order to avoid calling dom_dispose with the socket buffer mutex | * In order to avoid calling dom_dispose with the socket buffer mutex | ||||
* held, and in order to generally avoid holding the lock for a long | * held, and in order to generally avoid holding the lock for a long | ||||
* time, we make a copy of the socket buffer and clear the original | * time, we make a copy of the socket buffer and clear the original | ||||
* (except locks, state). The new socket buffer copy won't have | * (except locks, state). The new socket buffer copy won't have | ||||
* initialized locks so we can only call routines that won't use or | * initialized locks so we can only call routines that won't use or | ||||
* assert those locks. | * assert those locks. | ||||
* | * | ||||
* Dislodge threads currently blocked in receive and wait to acquire | * Dislodge threads currently blocked in receive and wait to acquire | ||||
* a lock against other simultaneous readers before clearing the | * a lock against other simultaneous readers before clearing the | ||||
* socket buffer. Don't let our acquire be interrupted by a signal | * socket buffer. Don't let our acquire be interrupted by a signal | ||||
* despite any existing socket disposition on interruptable waiting. | * despite any existing socket disposition on interruptable waiting. | ||||
*/ | */ | ||||
socantrcvmore(so); | socantrcvmore(so); | ||||
(void) sblock(sb, SBL_WAIT | SBL_NOINTR); | (void) sblock(sb, SBL_WAIT | SBL_NOINTR); | ||||
/* | /* | ||||
* Invalidate/clear most of the sockbuf structure, but leave selinfo | * Invalidate/clear most of the sockbuf structure, but leave selinfo | ||||
* and mutex data unchanged. | * and mutex data unchanged. | ||||
*/ | */ | ||||
SOCKBUF_LOCK(sb); | SOCKBUF_LOCK(sb); | ||||
bzero(&asb, offsetof(struct sockbuf, sb_startzero)); | bzero(&aso, sizeof(aso)); | ||||
bcopy(&sb->sb_startzero, &asb.sb_startzero, | aso.so_pcb = so->so_pcb; | ||||
bcopy(&sb->sb_startzero, &aso.so_rcv.sb_startzero, | |||||
sizeof(*sb) - offsetof(struct sockbuf, sb_startzero)); | sizeof(*sb) - offsetof(struct sockbuf, sb_startzero)); | ||||
bzero(&sb->sb_startzero, | bzero(&sb->sb_startzero, | ||||
sizeof(*sb) - offsetof(struct sockbuf, sb_startzero)); | sizeof(*sb) - offsetof(struct sockbuf, sb_startzero)); | ||||
SOCKBUF_UNLOCK(sb); | SOCKBUF_UNLOCK(sb); | ||||
sbunlock(sb); | sbunlock(sb); | ||||
/* | /* | ||||
* Dispose of special rights and flush the socket buffer. Don't call | * Dispose of special rights and flush the copied socket. Don't call | ||||
* any unsafe routines (that rely on locks being initialized) on asb. | * any unsafe routines (that rely on locks being initialized) on aso. | ||||
*/ | */ | ||||
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) | if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) | ||||
(*pr->pr_domain->dom_dispose)(asb.sb_mb); | (*pr->pr_domain->dom_dispose)(&aso); | ||||
sbrelease_internal(&asb, so); | sbrelease_internal(&aso.so_rcv, so); | ||||
} | } | ||||
/* | /* | ||||
* Wrapper for Socket established helper hook. | * Wrapper for Socket established helper hook. | ||||
* Parameters: socket, context of the hook point, hook id. | * Parameters: socket, context of the hook point, hook id. | ||||
*/ | */ | ||||
static int inline | static int inline | ||||
hhook_run_socket(struct socket *so, void *hctx, int32_t h_id) | hhook_run_socket(struct socket *so, void *hctx, int32_t h_id) | ||||
▲ Show 20 Lines • Show All 1,300 Lines • Show Last 20 Lines |