Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/uipc_usrreq.c
Show First 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | |||||
#define UNP_PCB_UNLOCK_ASSERT(unp) mtx_assert(&(unp)->unp_mtx, MA_NOTOWNED) | #define UNP_PCB_UNLOCK_ASSERT(unp) mtx_assert(&(unp)->unp_mtx, MA_NOTOWNED) | ||||
static int uipc_connect2(struct socket *, struct socket *); | static int uipc_connect2(struct socket *, struct socket *); | ||||
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 void 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 socket *so); | static void unp_dispose(struct socket *so); | ||||
static void unp_dispose_mbuf(struct mbuf *); | static void unp_dispose_mbuf(struct mbuf *); | ||||
static void unp_shutdown(struct unpcb *); | static void unp_shutdown(struct unpcb *); | ||||
static void unp_drop(struct unpcb *); | static void unp_drop(struct unpcb *); | ||||
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 *); | ||||
▲ Show 20 Lines • Show All 454 Lines • ▼ Show 20 Lines | if (vp) { | ||||
vrele(vp); | vrele(vp); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
uipc_connect2(struct socket *so1, struct socket *so2) | uipc_connect2(struct socket *so1, struct socket *so2) | ||||
{ | { | ||||
struct unpcb *unp, *unp2; | struct unpcb *unp, *unp2; | ||||
int error; | |||||
if (so1->so_type != so2->so_type) | |||||
return (EPROTOTYPE); | |||||
unp = so1->so_pcb; | unp = so1->so_pcb; | ||||
KASSERT(unp != NULL, ("uipc_connect2: unp == NULL")); | KASSERT(unp != NULL, ("uipc_connect2: unp == NULL")); | ||||
unp2 = so2->so_pcb; | unp2 = so2->so_pcb; | ||||
KASSERT(unp2 != NULL, ("uipc_connect2: unp2 == NULL")); | KASSERT(unp2 != NULL, ("uipc_connect2: unp2 == NULL")); | ||||
unp_pcb_lock_pair(unp, unp2); | unp_pcb_lock_pair(unp, unp2); | ||||
error = unp_connect2(so1, so2, PRU_CONNECT2); | unp_connect2(so1, so2, PRU_CONNECT2); | ||||
unp_pcb_unlock_pair(unp, unp2); | unp_pcb_unlock_pair(unp, unp2); | ||||
return (error); | |||||
return (0); | |||||
} | } | ||||
static void | static void | ||||
uipc_detach(struct socket *so) | uipc_detach(struct socket *so) | ||||
{ | { | ||||
struct unpcb *unp, *unp2; | struct unpcb *unp, *unp2; | ||||
struct mtx *vplock; | struct mtx *vplock; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
▲ Show 20 Lines • Show All 840 Lines • ▼ Show 20 Lines | #ifdef MAC | ||||
mac_socketpeer_set_from_socket(so2, so); | mac_socketpeer_set_from_socket(so2, so); | ||||
#endif | #endif | ||||
} else { | } else { | ||||
unp_pcb_lock_pair(unp, unp2); | unp_pcb_lock_pair(unp, unp2); | ||||
} | } | ||||
KASSERT(unp2 != NULL && so2 != NULL && unp2->unp_socket == so2 && | KASSERT(unp2 != NULL && so2 != NULL && unp2->unp_socket == so2 && | ||||
sotounpcb(so2) == unp2, | sotounpcb(so2) == unp2, | ||||
("%s: unp2 %p so2 %p", __func__, unp2, so2)); | ("%s: unp2 %p so2 %p", __func__, unp2, so2)); | ||||
error = unp_connect2(so, so2, PRU_CONNECT); | unp_connect2(so, so2, PRU_CONNECT); | ||||
unp_pcb_unlock_pair(unp, unp2); | unp_pcb_unlock_pair(unp, unp2); | ||||
bad2: | bad2: | ||||
mtx_unlock(vplock); | mtx_unlock(vplock); | ||||
bad: | bad: | ||||
if (vp != NULL) { | if (vp != NULL) { | ||||
vput(vp); | vput(vp); | ||||
} | } | ||||
free(sa, M_SONAME); | free(sa, M_SONAME); | ||||
Show All 20 Lines | unp_copy_peercred(struct thread *td, struct unpcb *client_unp, | ||||
client_unp->unp_flags |= UNP_HAVEPC; | client_unp->unp_flags |= UNP_HAVEPC; | ||||
memcpy(&server_unp->unp_peercred, &listen_unp->unp_peercred, | memcpy(&server_unp->unp_peercred, &listen_unp->unp_peercred, | ||||
sizeof(server_unp->unp_peercred)); | sizeof(server_unp->unp_peercred)); | ||||
server_unp->unp_flags |= UNP_HAVEPC; | server_unp->unp_flags |= UNP_HAVEPC; | ||||
client_unp->unp_flags |= (listen_unp->unp_flags & UNP_WANTCRED_MASK); | client_unp->unp_flags |= (listen_unp->unp_flags & UNP_WANTCRED_MASK); | ||||
} | } | ||||
static int | static void | ||||
unp_connect2(struct socket *so, struct socket *so2, int req) | unp_connect2(struct socket *so, struct socket *so2, int req) | ||||
{ | { | ||||
struct unpcb *unp; | struct unpcb *unp; | ||||
struct unpcb *unp2; | struct unpcb *unp2; | ||||
MPASS(so2->so_type == so->so_type); | |||||
unp = sotounpcb(so); | unp = sotounpcb(so); | ||||
KASSERT(unp != NULL, ("unp_connect2: unp == NULL")); | KASSERT(unp != NULL, ("unp_connect2: unp == NULL")); | ||||
unp2 = sotounpcb(so2); | unp2 = sotounpcb(so2); | ||||
KASSERT(unp2 != NULL, ("unp_connect2: unp2 == NULL")); | KASSERT(unp2 != NULL, ("unp_connect2: unp2 == NULL")); | ||||
UNP_PCB_LOCK_ASSERT(unp); | UNP_PCB_LOCK_ASSERT(unp); | ||||
UNP_PCB_LOCK_ASSERT(unp2); | UNP_PCB_LOCK_ASSERT(unp2); | ||||
KASSERT(unp->unp_conn == NULL, | KASSERT(unp->unp_conn == NULL, | ||||
("%s: socket %p is already connected", __func__, unp)); | ("%s: socket %p is already connected", __func__, unp)); | ||||
if (so2->so_type != so->so_type) | |||||
return (EPROTOTYPE); | |||||
unp->unp_conn = unp2; | unp->unp_conn = unp2; | ||||
unp_pcb_hold(unp2); | unp_pcb_hold(unp2); | ||||
unp_pcb_hold(unp); | unp_pcb_hold(unp); | ||||
switch (so->so_type) { | switch (so->so_type) { | ||||
case SOCK_DGRAM: | case SOCK_DGRAM: | ||||
UNP_REF_LIST_LOCK(); | UNP_REF_LIST_LOCK(); | ||||
LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink); | LIST_INSERT_HEAD(&unp2->unp_refs, unp, unp_reflink); | ||||
UNP_REF_LIST_UNLOCK(); | UNP_REF_LIST_UNLOCK(); | ||||
Show All 11 Lines | case SOCK_SEQPACKET: | ||||
else | else | ||||
soisconnected(so); | soisconnected(so); | ||||
soisconnected(so2); | soisconnected(so2); | ||||
break; | break; | ||||
default: | default: | ||||
panic("unp_connect2"); | panic("unp_connect2"); | ||||
} | } | ||||
return (0); | |||||
} | } | ||||
static void | static void | ||||
unp_disconnect(struct unpcb *unp, struct unpcb *unp2) | unp_disconnect(struct unpcb *unp, struct unpcb *unp2) | ||||
{ | { | ||||
struct socket *so, *so2; | struct socket *so, *so2; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
struct unpcb *unptmp; | struct unpcb *unptmp; | ||||
▲ Show 20 Lines • Show All 1,251 Lines • Show Last 20 Lines |