Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/udp_usrreq.c
Show First 20 Lines • Show All 1,620 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
struct inpcbinfo *pcbinfo; | struct inpcbinfo *pcbinfo; | ||||
int error; | int error; | ||||
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); | pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); | ||||
inp = sotoinpcb(so); | inp = sotoinpcb(so); | ||||
KASSERT(inp != NULL, ("udp_bind: inp == NULL")); | KASSERT(inp != NULL, ("udp_bind: inp == NULL")); | ||||
if (nam->sa_family != AF_INET) | |||||
return (EAFNOSUPPORT); | |||||
if (nam->sa_len != sizeof(struct sockaddr_in)) | |||||
return (EINVAL); | |||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
INP_HASH_WLOCK(pcbinfo); | INP_HASH_WLOCK(pcbinfo); | ||||
error = in_pcbbind(inp, nam, td->td_ucred); | error = in_pcbbind(inp, nam, td->td_ucred); | ||||
INP_HASH_WUNLOCK(pcbinfo); | INP_HASH_WUNLOCK(pcbinfo); | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
return (error); | return (error); | ||||
} | } | ||||
Show All 24 Lines | udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td) | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
struct inpcbinfo *pcbinfo; | struct inpcbinfo *pcbinfo; | ||||
struct sockaddr_in *sin; | struct sockaddr_in *sin; | ||||
int error; | int error; | ||||
pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); | pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); | ||||
inp = sotoinpcb(so); | inp = sotoinpcb(so); | ||||
KASSERT(inp != NULL, ("udp_connect: inp == NULL")); | KASSERT(inp != NULL, ("udp_connect: inp == NULL")); | ||||
sin = (struct sockaddr_in *)nam; | |||||
if (sin->sin_family != AF_INET) | |||||
return (EAFNOSUPPORT); | |||||
if (sin->sin_len != sizeof(*sin)) | |||||
return (EINVAL); | |||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if (inp->inp_faddr.s_addr != INADDR_ANY) { | if (inp->inp_faddr.s_addr != INADDR_ANY) { | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
return (EISCONN); | return (EISCONN); | ||||
} | } | ||||
sin = (struct sockaddr_in *)nam; | |||||
error = prison_remote_ip4(td->td_ucred, &sin->sin_addr); | error = prison_remote_ip4(td->td_ucred, &sin->sin_addr); | ||||
if (error != 0) { | if (error != 0) { | ||||
INP_WUNLOCK(inp); | INP_WUNLOCK(inp); | ||||
return (error); | return (error); | ||||
} | } | ||||
NET_EPOCH_ENTER(et); | NET_EPOCH_ENTER(et); | ||||
INP_HASH_WLOCK(pcbinfo); | INP_HASH_WLOCK(pcbinfo); | ||||
error = in_pcbconnect(inp, nam, td->td_ucred); | error = in_pcbconnect(inp, nam, td->td_ucred); | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | udp_disconnect(struct socket *so) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, | udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, | ||||
struct mbuf *control, struct thread *td) | struct mbuf *control, struct thread *td) | ||||
{ | { | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
int error; | |||||
inp = sotoinpcb(so); | inp = sotoinpcb(so); | ||||
KASSERT(inp != NULL, ("udp_send: inp == NULL")); | KASSERT(inp != NULL, ("udp_send: inp == NULL")); | ||||
if (addr != NULL) { | |||||
error = 0; | |||||
if (addr->sa_family != AF_INET) | |||||
error = EAFNOSUPPORT; | |||||
else if (addr->sa_len != sizeof(struct sockaddr_in)) | |||||
error = EINVAL; | |||||
if (__predict_false(error != 0)) { | |||||
m_freem(control); | |||||
m_freem(m); | |||||
return (error); | |||||
} | |||||
} | |||||
return (udp_output(inp, m, addr, control, td, flags)); | return (udp_output(inp, m, addr, control, td, flags)); | ||||
} | } | ||||
#endif /* INET */ | #endif /* INET */ | ||||
int | int | ||||
udp_shutdown(struct socket *so) | udp_shutdown(struct socket *so) | ||||
{ | { | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
Show All 28 Lines |