Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/uipc_usrreq.c
Show First 20 Lines • Show All 1,034 Lines • ▼ Show 20 Lines | case SOCK_DGRAM: | ||||
*/ | */ | ||||
unp2 = unp_pcb_lock_peer(unp); | unp2 = unp_pcb_lock_peer(unp); | ||||
if (unp2 == NULL) { | if (unp2 == NULL) { | ||||
UNP_PCB_UNLOCK(unp); | UNP_PCB_UNLOCK(unp); | ||||
error = ENOTCONN; | error = ENOTCONN; | ||||
break; | break; | ||||
} | } | ||||
if (unp2->unp_flags & UNP_WANTCRED) | if (unp2->unp_flags & UNP_WANTCRED_MASK) | ||||
control = unp_addsockcred(td, control); | control = unp_addsockcred(td, control); | ||||
if (unp->unp_addr != NULL) | if (unp->unp_addr != NULL) | ||||
from = (struct sockaddr *)unp->unp_addr; | from = (struct sockaddr *)unp->unp_addr; | ||||
else | else | ||||
from = &sun_noname; | from = &sun_noname; | ||||
so2 = unp2->unp_socket; | so2 = unp2->unp_socket; | ||||
SOCKBUF_LOCK(&so2->so_rcv); | SOCKBUF_LOCK(&so2->so_rcv); | ||||
if (sbappendaddr_locked(&so2->so_rcv, from, m, | if (sbappendaddr_locked(&so2->so_rcv, from, m, | ||||
Show All 37 Lines | case SOCK_STREAM: | ||||
} | } | ||||
UNP_PCB_UNLOCK(unp); | UNP_PCB_UNLOCK(unp); | ||||
if ((so2 = unp2->unp_socket) == NULL) { | if ((so2 = unp2->unp_socket) == NULL) { | ||||
UNP_PCB_UNLOCK(unp2); | UNP_PCB_UNLOCK(unp2); | ||||
error = ENOTCONN; | error = ENOTCONN; | ||||
break; | break; | ||||
} | } | ||||
SOCKBUF_LOCK(&so2->so_rcv); | SOCKBUF_LOCK(&so2->so_rcv); | ||||
if (unp2->unp_flags & UNP_WANTCRED) { | if (unp2->unp_flags & UNP_WANTCRED_MASK) { | ||||
/* | /* | ||||
* Credentials are passed only once on SOCK_STREAM | * Credentials are passed only once on SOCK_STREAM and | ||||
* and SOCK_SEQPACKET. | * SOCK_SEQPACKET (LOCAL_CREDS => WANTCRED_ONESHOT), or | ||||
* forever (LOCAL_CREDS_PERSISTENT => WANTCRED_ALWAYS). | |||||
*/ | */ | ||||
unp2->unp_flags &= ~UNP_WANTCRED; | unp2->unp_flags &= ~UNP_WANTCRED_ONESHOT; | ||||
control = unp_addsockcred(td, control); | control = unp_addsockcred(td, control); | ||||
} | } | ||||
/* | /* | ||||
* Send to paired receive port and wake up readers. Don't | * Send to paired receive port and wake up readers. Don't | ||||
* check for space available in the receive buffer if we're | * check for space available in the receive buffer if we're | ||||
* attaching ancillary data; Unix domain sockets only check | * attaching ancillary data; Unix domain sockets only check | ||||
* for space in the sending sockbuf, and that check is | * for space in the sending sockbuf, and that check is | ||||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | case LOCAL_PEERCRED: | ||||
} | } | ||||
UNP_PCB_UNLOCK(unp); | UNP_PCB_UNLOCK(unp); | ||||
if (error == 0) | if (error == 0) | ||||
error = sooptcopyout(sopt, &xu, sizeof(xu)); | error = sooptcopyout(sopt, &xu, sizeof(xu)); | ||||
break; | break; | ||||
case LOCAL_CREDS: | case LOCAL_CREDS: | ||||
/* Unlocked read. */ | /* Unlocked read. */ | ||||
optval = unp->unp_flags & UNP_WANTCRED ? 1 : 0; | optval = unp->unp_flags & UNP_WANTCRED_ONESHOT ? 1 : 0; | ||||
error = sooptcopyout(sopt, &optval, sizeof(optval)); | error = sooptcopyout(sopt, &optval, sizeof(optval)); | ||||
break; | break; | ||||
case LOCAL_CREDS_PERSISTENT: | |||||
/* Unlocked read. */ | |||||
optval = unp->unp_flags & UNP_WANTCRED_ALWAYS ? 1 : 0; | |||||
error = sooptcopyout(sopt, &optval, sizeof(optval)); | |||||
break; | |||||
case LOCAL_CONNWAIT: | case LOCAL_CONNWAIT: | ||||
/* Unlocked read. */ | /* Unlocked read. */ | ||||
optval = unp->unp_flags & UNP_CONNWAIT ? 1 : 0; | optval = unp->unp_flags & UNP_CONNWAIT ? 1 : 0; | ||||
error = sooptcopyout(sopt, &optval, sizeof(optval)); | error = sooptcopyout(sopt, &optval, sizeof(optval)); | ||||
break; | break; | ||||
default: | default: | ||||
error = EOPNOTSUPP; | error = EOPNOTSUPP; | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
case SOPT_SET: | case SOPT_SET: | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case LOCAL_CREDS: | case LOCAL_CREDS: | ||||
case LOCAL_CREDS_PERSISTENT: | |||||
case LOCAL_CONNWAIT: | case LOCAL_CONNWAIT: | ||||
error = sooptcopyin(sopt, &optval, sizeof(optval), | error = sooptcopyin(sopt, &optval, sizeof(optval), | ||||
sizeof(optval)); | sizeof(optval)); | ||||
if (error) | if (error) | ||||
break; | break; | ||||
#define OPTSET(bit) do { \ | #define OPTSET(bit, exclusive) do { \ | ||||
UNP_PCB_LOCK(unp); \ | UNP_PCB_LOCK(unp); \ | ||||
if (optval) \ | if (optval) { \ | ||||
unp->unp_flags |= bit; \ | if ((unp->unp_flags & (exclusive)) != 0) { \ | ||||
else \ | |||||
unp->unp_flags &= ~bit; \ | |||||
UNP_PCB_UNLOCK(unp); \ | UNP_PCB_UNLOCK(unp); \ | ||||
error = EINVAL; \ | |||||
break; \ | |||||
} \ | |||||
unp->unp_flags |= (bit); \ | |||||
} else \ | |||||
unp->unp_flags &= ~(bit); \ | |||||
UNP_PCB_UNLOCK(unp); \ | |||||
} while (0) | } while (0) | ||||
switch (sopt->sopt_name) { | switch (sopt->sopt_name) { | ||||
case LOCAL_CREDS: | case LOCAL_CREDS: | ||||
OPTSET(UNP_WANTCRED); | OPTSET(UNP_WANTCRED_ONESHOT, UNP_WANTCRED_ALWAYS); | ||||
break; | break; | ||||
case LOCAL_CREDS_PERSISTENT: | |||||
OPTSET(UNP_WANTCRED_ALWAYS, UNP_WANTCRED_ONESHOT); | |||||
break; | |||||
case LOCAL_CONNWAIT: | case LOCAL_CONNWAIT: | ||||
OPTSET(UNP_CONNWAIT); | OPTSET(UNP_CONNWAIT, 0); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
#undef OPTSET | #undef OPTSET | ||||
default: | default: | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | unp_copy_peercred(struct thread *td, struct unpcb *client_unp, | ||||
struct unpcb *server_unp, struct unpcb *listen_unp) | struct unpcb *server_unp, struct unpcb *listen_unp) | ||||
{ | { | ||||
cru2xt(td, &client_unp->unp_peercred); | cru2xt(td, &client_unp->unp_peercred); | ||||
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; | ||||
if (listen_unp->unp_flags & UNP_WANTCRED) | client_unp->unp_flags |= (listen_unp->unp_flags & UNP_WANTCRED_MASK); | ||||
client_unp->unp_flags |= UNP_WANTCRED; | |||||
} | } | ||||
static int | static int | ||||
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; | ||||
▲ Show 20 Lines • Show All 1,184 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int comma; | int comma; | ||||
comma = 0; | comma = 0; | ||||
if (unp_flags & UNP_HAVEPC) { | if (unp_flags & UNP_HAVEPC) { | ||||
db_printf("%sUNP_HAVEPC", comma ? ", " : ""); | db_printf("%sUNP_HAVEPC", comma ? ", " : ""); | ||||
comma = 1; | comma = 1; | ||||
} | } | ||||
if (unp_flags & UNP_WANTCRED) { | if (unp_flags & UNP_WANTCRED_ALWAYS) { | ||||
db_printf("%sUNP_WANTCRED", comma ? ", " : ""); | db_printf("%sUNP_WANTCRED_ALWAYS", comma ? ", " : ""); | ||||
comma = 1; | |||||
} | |||||
if (unp_flags & UNP_WANTCRED_ONESHOT) { | |||||
db_printf("%sUNP_WANTCRED_ONESHOT", comma ? ", " : ""); | |||||
comma = 1; | comma = 1; | ||||
} | } | ||||
if (unp_flags & UNP_CONNWAIT) { | if (unp_flags & UNP_CONNWAIT) { | ||||
db_printf("%sUNP_CONNWAIT", comma ? ", " : ""); | db_printf("%sUNP_CONNWAIT", comma ? ", " : ""); | ||||
comma = 1; | comma = 1; | ||||
} | } | ||||
if (unp_flags & UNP_CONNECTING) { | if (unp_flags & UNP_CONNECTING) { | ||||
db_printf("%sUNP_CONNECTING", comma ? ", " : ""); | db_printf("%sUNP_CONNECTING", comma ? ", " : ""); | ||||
▲ Show 20 Lines • Show All 80 Lines • Show Last 20 Lines |