mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 15:40:44 +00:00
sockets: don't malloc/free sockaddr memory on getpeername/getsockname
Just like it was done for accept(2) in cfb1e92912
, use same approach
for two simplier syscalls that return socket addresses. Although,
these two syscalls aren't performance critical, this change generalizes
some code between 3 syscalls trimming code size.
Following example of accept(2), provide VNET-aware and INVARIANT-checking
wrappers sopeeraddr() and sosockaddr() around protosw methods.
Reviewed by: tuexen
Differential Revision: https://reviews.freebsd.org/D42694
This commit is contained in:
parent
cfb1e92912
commit
0fac350c54
|
@ -1106,48 +1106,50 @@ linux_accept4(struct thread *td, struct linux_accept4_args *args)
|
|||
int
|
||||
linux_getsockname(struct thread *td, struct linux_getsockname_args *args)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int len, error;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
error = copyin(PTRIN(args->namelen), &len, sizeof(len));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = kern_getsockname(td, args->s, &sa, &len);
|
||||
error = kern_getsockname(td, args->s, (struct sockaddr *)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (len != 0)
|
||||
error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len);
|
||||
|
||||
free(sa, M_SONAME);
|
||||
if (error == 0)
|
||||
len = min(ss.ss_len, len);
|
||||
error = linux_copyout_sockaddr((struct sockaddr *)&ss,
|
||||
PTRIN(args->addr), len);
|
||||
if (error == 0) {
|
||||
len = ss.ss_len;
|
||||
error = copyout(&len, PTRIN(args->namelen), sizeof(len));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
linux_getpeername(struct thread *td, struct linux_getpeername_args *args)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int len, error;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
error = copyin(PTRIN(args->namelen), &len, sizeof(len));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (len < 0)
|
||||
return (EINVAL);
|
||||
|
||||
error = kern_getpeername(td, args->s, &sa, &len);
|
||||
error = kern_getpeername(td, args->s, (struct sockaddr *)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (len != 0)
|
||||
error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len);
|
||||
|
||||
free(sa, M_SONAME);
|
||||
if (error == 0)
|
||||
len = min(ss.ss_len, len);
|
||||
error = linux_copyout_sockaddr((struct sockaddr *)&ss,
|
||||
PTRIN(args->addr), len);
|
||||
if (error == 0) {
|
||||
len = ss.ss_len;
|
||||
error = copyout(&len, PTRIN(args->namelen), sizeof(len));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1348,6 +1350,7 @@ static int
|
|||
linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
|
||||
l_uint flags)
|
||||
{
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
struct cmsghdr *cmsg;
|
||||
struct mbuf *control;
|
||||
struct msghdr msg;
|
||||
|
@ -1356,7 +1359,6 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
|
|||
struct l_msghdr linux_msghdr;
|
||||
struct iovec *iov;
|
||||
socklen_t datalen;
|
||||
struct sockaddr *sa;
|
||||
struct socket *so;
|
||||
sa_family_t sa_family;
|
||||
struct file *fp;
|
||||
|
@ -1395,11 +1397,10 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
|
|||
|
||||
control = NULL;
|
||||
|
||||
error = kern_getsockname(td, s, &sa, &datalen);
|
||||
error = kern_getsockname(td, s, (struct sockaddr *)&ss);
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
sa_family = sa->sa_family;
|
||||
free(sa, M_SONAME);
|
||||
sa_family = ss.ss_family;
|
||||
|
||||
if (flags & LINUX_MSG_OOB) {
|
||||
error = EOPNOTSUPP;
|
||||
|
|
|
@ -45,26 +45,27 @@ sock_create_kern(int family, int type, int proto, struct socket **res)
|
|||
}
|
||||
|
||||
static inline int
|
||||
sock_getname(struct socket *so, struct sockaddr *addr, int *sockaddr_len,
|
||||
sock_getname(struct socket *so, struct sockaddr *sa, int *sockaddr_len,
|
||||
int peer)
|
||||
{
|
||||
struct sockaddr *nam;
|
||||
int error;
|
||||
|
||||
nam = NULL;
|
||||
/*
|
||||
* XXXGL: we can't use sopeeraddr()/sosockaddr() here since with
|
||||
* INVARIANTS they would check if supplied sockaddr has enough
|
||||
* length. Such notion doesn't even exist in Linux KPI.
|
||||
*/
|
||||
if (peer) {
|
||||
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
|
||||
return (-ENOTCONN);
|
||||
|
||||
error = so->so_proto->pr_peeraddr(so, &nam);
|
||||
error = so->so_proto->pr_peeraddr(so, sa);
|
||||
} else
|
||||
error = so->so_proto->pr_sockaddr(so, &nam);
|
||||
error = so->so_proto->pr_sockaddr(so, sa);
|
||||
if (error)
|
||||
return (-error);
|
||||
*addr = *nam;
|
||||
*sockaddr_len = addr->sa_len;
|
||||
*sockaddr_len = sa->sa_len;
|
||||
|
||||
free(nam, M_SONAME);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,30 +145,24 @@ static void process_newconn(struct c4iw_listen_ep *master_lep,
|
|||
|
||||
#define GET_LOCAL_ADDR(pladdr, so) \
|
||||
do { \
|
||||
struct sockaddr_storage *__a = NULL; \
|
||||
struct inpcb *__inp = sotoinpcb(so); \
|
||||
KASSERT(__inp != NULL, \
|
||||
("GET_LOCAL_ADDR(%s):so:%p, inp = NULL", __func__, so)); \
|
||||
if (__inp->inp_vflag & INP_IPV4) \
|
||||
in_getsockaddr(so, (struct sockaddr **)&__a); \
|
||||
in_getsockaddr(so, (struct sockaddr *)pladdr); \
|
||||
else \
|
||||
in6_getsockaddr(so, (struct sockaddr **)&__a); \
|
||||
*(pladdr) = *__a; \
|
||||
free(__a, M_SONAME); \
|
||||
in6_getsockaddr(so, (struct sockaddr *)pladdr); \
|
||||
} while (0)
|
||||
|
||||
#define GET_REMOTE_ADDR(praddr, so) \
|
||||
do { \
|
||||
struct sockaddr_storage *__a = NULL; \
|
||||
struct inpcb *__inp = sotoinpcb(so); \
|
||||
KASSERT(__inp != NULL, \
|
||||
("GET_REMOTE_ADDR(%s):so:%p, inp = NULL", __func__, so)); \
|
||||
if (__inp->inp_vflag & INP_IPV4) \
|
||||
in_getpeeraddr(so, (struct sockaddr **)&__a); \
|
||||
in_getpeeraddr(so, (struct sockaddr *)praddr); \
|
||||
else \
|
||||
in6_getpeeraddr(so, (struct sockaddr **)&__a); \
|
||||
*(praddr) = *__a; \
|
||||
free(__a, M_SONAME); \
|
||||
in6_getpeeraddr(so, (struct sockaddr *)praddr); \
|
||||
} while (0)
|
||||
|
||||
static char *states[] = {
|
||||
|
|
|
@ -876,7 +876,7 @@ hvs_trans_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
|
|||
}
|
||||
|
||||
int
|
||||
hvs_trans_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
hvs_trans_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct hvs_pcb *pcb = so2hvspcb(so);
|
||||
|
||||
|
@ -886,13 +886,13 @@ hvs_trans_peeraddr(struct socket *so, struct sockaddr **nam)
|
|||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &pcb->remote_addr, M_NOWAIT);
|
||||
memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
hvs_trans_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
hvs_trans_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct hvs_pcb *pcb = so2hvspcb(so);
|
||||
|
||||
|
@ -902,9 +902,9 @@ hvs_trans_sockaddr(struct socket *so, struct sockaddr **nam)
|
|||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &pcb->local_addr, M_NOWAIT);
|
||||
memcpy(sa, &pcb->local_addr, pcb->local_addr.sa_len);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -103,8 +103,8 @@ int hvs_trans_listen(struct socket *, int, struct thread *);
|
|||
int hvs_trans_accept(struct socket *, struct sockaddr *);
|
||||
int hvs_trans_connect(struct socket *,
|
||||
struct sockaddr *, struct thread *);
|
||||
int hvs_trans_peeraddr(struct socket *, struct sockaddr **);
|
||||
int hvs_trans_sockaddr(struct socket *, struct sockaddr **);
|
||||
int hvs_trans_peeraddr(struct socket *, struct sockaddr *);
|
||||
int hvs_trans_sockaddr(struct socket *, struct sockaddr *);
|
||||
int hvs_trans_soreceive(struct socket *, struct sockaddr **,
|
||||
struct uio *, struct mbuf **, struct mbuf **, int *);
|
||||
int hvs_trans_sosend(struct socket *, struct sockaddr *, struct uio *,
|
||||
|
|
|
@ -806,14 +806,15 @@ wg_socket_bind(struct socket **in_so4, struct socket **in_so6, in_port_t *reques
|
|||
if (ret4 && ret4 != EADDRNOTAVAIL)
|
||||
return (ret4);
|
||||
if (!ret4 && !sin.sin_port) {
|
||||
struct sockaddr_in *bound_sin;
|
||||
int ret = so4->so_proto->pr_sockaddr(so4,
|
||||
(struct sockaddr **)&bound_sin);
|
||||
struct sockaddr_in bound_sin =
|
||||
{ .sin_len = sizeof(bound_sin) };
|
||||
int ret;
|
||||
|
||||
ret = sosockaddr(so4, (struct sockaddr *)&bound_sin);
|
||||
if (ret)
|
||||
return (ret);
|
||||
port = ntohs(bound_sin->sin_port);
|
||||
sin6.sin6_port = bound_sin->sin_port;
|
||||
free(bound_sin, M_SONAME);
|
||||
port = ntohs(bound_sin.sin_port);
|
||||
sin6.sin6_port = bound_sin.sin_port;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,13 +823,14 @@ wg_socket_bind(struct socket **in_so4, struct socket **in_so6, in_port_t *reques
|
|||
if (ret6 && ret6 != EADDRNOTAVAIL)
|
||||
return (ret6);
|
||||
if (!ret6 && !sin6.sin6_port) {
|
||||
struct sockaddr_in6 *bound_sin6;
|
||||
int ret = so6->so_proto->pr_sockaddr(so6,
|
||||
(struct sockaddr **)&bound_sin6);
|
||||
struct sockaddr_in6 bound_sin6 =
|
||||
{ .sin6_len = sizeof(bound_sin6) };
|
||||
int ret;
|
||||
|
||||
ret = sosockaddr(so6, (struct sockaddr *)&bound_sin6);
|
||||
if (ret)
|
||||
return (ret);
|
||||
port = ntohs(bound_sin6->sin6_port);
|
||||
free(bound_sin6, M_SONAME);
|
||||
port = ntohs(bound_sin6.sin6_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ soo_close(struct file *fp, struct thread *td)
|
|||
static int
|
||||
soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
struct inpcb *inpcb;
|
||||
struct unpcb *unpcb;
|
||||
struct socket *so;
|
||||
|
@ -404,17 +404,16 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
|||
}
|
||||
break;
|
||||
}
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
error = sosockaddr(so, (struct sockaddr *)&ss);
|
||||
if (error == 0 &&
|
||||
sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) {
|
||||
bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
ss.ss_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) {
|
||||
bcopy(&ss, &kif->kf_un.kf_sock.kf_sa_local, ss.ss_len);
|
||||
}
|
||||
error = so->so_proto->pr_peeraddr(so, &sa);
|
||||
ss.ss_len = sizeof(ss);
|
||||
error = sopeeraddr(so, (struct sockaddr *)&ss);
|
||||
if (error == 0 &&
|
||||
sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) {
|
||||
bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
ss.ss_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) {
|
||||
bcopy(&ss, &kif->kf_un.kf_sock.kf_sa_peer, ss.ss_len);
|
||||
}
|
||||
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
|
||||
sizeof(kif->kf_path));
|
||||
|
|
|
@ -116,7 +116,7 @@ pr_listen_notsupp(struct socket *so, int backlog, struct thread *td)
|
|||
}
|
||||
|
||||
static int
|
||||
pr_peeraddr_notsupp(struct socket *so, struct sockaddr **nam)
|
||||
pr_peeraddr_notsupp(struct socket *so, struct sockaddr *nam)
|
||||
{
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ pr_shutdown_notsupp(struct socket *so)
|
|||
}
|
||||
|
||||
static int
|
||||
pr_sockaddr_notsupp(struct socket *so, struct sockaddr **nam)
|
||||
pr_sockaddr_notsupp(struct socket *so, struct sockaddr *nam)
|
||||
{
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
|
|
@ -1363,6 +1363,40 @@ soaccept(struct socket *so, struct sockaddr *sa)
|
|||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sopeeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
u_char len = sa->sa_len;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_peeraddr(so, sa);
|
||||
KASSERT(sa->sa_len <= len,
|
||||
("%s: protocol %p sockaddr overflow", __func__, so->so_proto));
|
||||
CURVNET_RESTORE();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sosockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
u_char len = sa->sa_len;
|
||||
#endif
|
||||
int error;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, sa);
|
||||
KASSERT(sa->sa_len <= len,
|
||||
("%s: protocol %p sockaddr overflow", __func__, so->so_proto));
|
||||
CURVNET_RESTORE();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
soconnect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
{
|
||||
|
|
|
@ -1308,7 +1308,7 @@ static int
|
|||
user_getsockname(struct thread *td, int fdes, struct sockaddr *asa,
|
||||
socklen_t *alen, bool compat)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
|
@ -1316,30 +1316,28 @@ user_getsockname(struct thread *td, int fdes, struct sockaddr *asa,
|
|||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = kern_getsockname(td, fdes, &sa, &len);
|
||||
error = kern_getsockname(td, fdes, (struct sockaddr *)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (len != 0) {
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
|
||||
((struct osockaddr *)sa)->sa_family = sa->sa_family;
|
||||
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
|
||||
((struct osockaddr *)&ss)->sa_family = ss.ss_family;
|
||||
#endif
|
||||
error = copyout(sa, asa, len);
|
||||
}
|
||||
free(sa, M_SONAME);
|
||||
if (error == 0)
|
||||
len = min(ss.ss_len, len);
|
||||
error = copyout(&ss, asa, len);
|
||||
if (error == 0) {
|
||||
len = ss.ss_len;
|
||||
error = copyout(&len, alen, sizeof(len));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen)
|
||||
kern_getsockname(struct thread *td, int fd, struct sockaddr *sa)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
AUDIT_ARG_FD(fd);
|
||||
|
@ -1347,27 +1345,12 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
|||
if (error != 0)
|
||||
return (error);
|
||||
so = fp->f_data;
|
||||
*sa = NULL;
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, sa);
|
||||
CURVNET_RESTORE();
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
if (*sa == NULL)
|
||||
len = 0;
|
||||
else
|
||||
len = MIN(*alen, (*sa)->sa_len);
|
||||
*alen = len;
|
||||
error = sosockaddr(so, sa);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(td, KTR_STRUCT))
|
||||
ktrsockaddr(*sa);
|
||||
if (error == 0 && KTRPOINT(td, KTR_STRUCT))
|
||||
ktrsockaddr(sa);
|
||||
#endif
|
||||
bad:
|
||||
fdrop(fp, td);
|
||||
if (error != 0 && *sa != NULL) {
|
||||
free(*sa, M_SONAME);
|
||||
*sa = NULL;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1389,7 +1372,7 @@ static int
|
|||
user_getpeername(struct thread *td, int fdes, struct sockaddr *asa,
|
||||
socklen_t *alen, bool compat)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
|
@ -1397,30 +1380,28 @@ user_getpeername(struct thread *td, int fdes, struct sockaddr *asa,
|
|||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = kern_getpeername(td, fdes, &sa, &len);
|
||||
error = kern_getpeername(td, fdes, (struct sockaddr *)&ss);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (len != 0) {
|
||||
#ifdef COMPAT_OLDSOCK
|
||||
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
|
||||
((struct osockaddr *)sa)->sa_family = sa->sa_family;
|
||||
if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT))
|
||||
((struct osockaddr *)&ss)->sa_family = ss.ss_family;
|
||||
#endif
|
||||
error = copyout(sa, asa, len);
|
||||
}
|
||||
free(sa, M_SONAME);
|
||||
if (error == 0)
|
||||
len = min(ss.ss_len, len);
|
||||
error = copyout(&ss, asa, len);
|
||||
if (error == 0) {
|
||||
len = ss.ss_len;
|
||||
error = copyout(&len, alen, sizeof(len));
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen)
|
||||
kern_getpeername(struct thread *td, int fd, struct sockaddr *sa)
|
||||
{
|
||||
struct socket *so;
|
||||
struct file *fp;
|
||||
socklen_t len;
|
||||
int error;
|
||||
|
||||
AUDIT_ARG_FD(fd);
|
||||
|
@ -1432,26 +1413,11 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
|||
error = ENOTCONN;
|
||||
goto done;
|
||||
}
|
||||
*sa = NULL;
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_peeraddr(so, sa);
|
||||
CURVNET_RESTORE();
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
if (*sa == NULL)
|
||||
len = 0;
|
||||
else
|
||||
len = MIN(*alen, (*sa)->sa_len);
|
||||
*alen = len;
|
||||
error = sopeeraddr(so, sa);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(td, KTR_STRUCT))
|
||||
ktrsockaddr(*sa);
|
||||
if (error == 0 && KTRPOINT(td, KTR_STRUCT))
|
||||
ktrsockaddr(sa);
|
||||
#endif
|
||||
bad:
|
||||
if (error != 0 && *sa != NULL) {
|
||||
free(*sa, M_SONAME);
|
||||
*sa = NULL;
|
||||
}
|
||||
done:
|
||||
fdrop(fp, td);
|
||||
return (error);
|
||||
|
|
|
@ -436,33 +436,6 @@ uipc_abort(struct socket *so)
|
|||
UNP_PCB_UNLOCK(unp);
|
||||
}
|
||||
|
||||
static int
|
||||
uipc_accept(struct socket *so, struct sockaddr *ret)
|
||||
{
|
||||
struct unpcb *unp, *unp2;
|
||||
const struct sockaddr *sa;
|
||||
|
||||
/*
|
||||
* Pass back name of connected socket, if it was bound and we are
|
||||
* still connected (our peer may have closed already!).
|
||||
*/
|
||||
unp = sotounpcb(so);
|
||||
KASSERT(unp != NULL, ("uipc_accept: unp == NULL"));
|
||||
|
||||
UNP_PCB_LOCK(unp);
|
||||
unp2 = unp_pcb_lock_peer(unp);
|
||||
if (unp2 != NULL && unp2->unp_addr != NULL)
|
||||
sa = (struct sockaddr *)unp2->unp_addr;
|
||||
else
|
||||
sa = &sun_noname;
|
||||
bcopy(sa, ret, sa->sa_len);
|
||||
if (unp2 != NULL)
|
||||
unp_pcb_unlock_pair(unp, unp2);
|
||||
else
|
||||
UNP_PCB_UNLOCK(unp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
uipc_attach(struct socket *so, int proto, struct thread *td)
|
||||
{
|
||||
|
@ -874,7 +847,7 @@ uipc_listen(struct socket *so, int backlog, struct thread *td)
|
|||
}
|
||||
|
||||
static int
|
||||
uipc_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
uipc_peeraddr(struct socket *so, struct sockaddr *ret)
|
||||
{
|
||||
struct unpcb *unp, *unp2;
|
||||
const struct sockaddr *sa;
|
||||
|
@ -882,8 +855,6 @@ uipc_peeraddr(struct socket *so, struct sockaddr **nam)
|
|||
unp = sotounpcb(so);
|
||||
KASSERT(unp != NULL, ("uipc_peeraddr: unp == NULL"));
|
||||
|
||||
*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
|
||||
|
||||
UNP_PCB_LOCK(unp);
|
||||
unp2 = unp_pcb_lock_peer(unp);
|
||||
if (unp2 != NULL) {
|
||||
|
@ -891,12 +862,12 @@ uipc_peeraddr(struct socket *so, struct sockaddr **nam)
|
|||
sa = (struct sockaddr *)unp2->unp_addr;
|
||||
else
|
||||
sa = &sun_noname;
|
||||
bcopy(sa, *nam, sa->sa_len);
|
||||
bcopy(sa, ret, sa->sa_len);
|
||||
unp_pcb_unlock_pair(unp, unp2);
|
||||
} else {
|
||||
sa = &sun_noname;
|
||||
bcopy(sa, *nam, sa->sa_len);
|
||||
UNP_PCB_UNLOCK(unp);
|
||||
sa = &sun_noname;
|
||||
bcopy(sa, ret, sa->sa_len);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -1704,7 +1675,7 @@ uipc_shutdown(struct socket *so)
|
|||
}
|
||||
|
||||
static int
|
||||
uipc_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
uipc_sockaddr(struct socket *so, struct sockaddr *ret)
|
||||
{
|
||||
struct unpcb *unp;
|
||||
const struct sockaddr *sa;
|
||||
|
@ -1712,13 +1683,12 @@ uipc_sockaddr(struct socket *so, struct sockaddr **nam)
|
|||
unp = sotounpcb(so);
|
||||
KASSERT(unp != NULL, ("uipc_sockaddr: unp == NULL"));
|
||||
|
||||
*nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
|
||||
UNP_PCB_LOCK(unp);
|
||||
if (unp->unp_addr != NULL)
|
||||
sa = (struct sockaddr *) unp->unp_addr;
|
||||
else
|
||||
sa = &sun_noname;
|
||||
bcopy(sa, *nam, sa->sa_len);
|
||||
bcopy(sa, ret, sa->sa_len);
|
||||
UNP_PCB_UNLOCK(unp);
|
||||
return (0);
|
||||
}
|
||||
|
@ -3322,7 +3292,7 @@ static struct protosw streamproto = {
|
|||
PR_CAPATTACH,
|
||||
.pr_ctloutput = &uipc_ctloutput,
|
||||
.pr_abort = uipc_abort,
|
||||
.pr_accept = uipc_accept,
|
||||
.pr_accept = uipc_peeraddr,
|
||||
.pr_attach = uipc_attach,
|
||||
.pr_bind = uipc_bind,
|
||||
.pr_bindat = uipc_bindat,
|
||||
|
@ -3349,7 +3319,7 @@ static struct protosw dgramproto = {
|
|||
PR_SOCKBUF,
|
||||
.pr_ctloutput = &uipc_ctloutput,
|
||||
.pr_abort = uipc_abort,
|
||||
.pr_accept = uipc_accept,
|
||||
.pr_accept = uipc_peeraddr,
|
||||
.pr_attach = uipc_attach,
|
||||
.pr_bind = uipc_bind,
|
||||
.pr_bindat = uipc_bindat,
|
||||
|
@ -3378,7 +3348,7 @@ static struct protosw seqpacketproto = {
|
|||
PR_WANTRCVD|PR_RIGHTS|PR_CAPATTACH,
|
||||
.pr_ctloutput = &uipc_ctloutput,
|
||||
.pr_abort = uipc_abort,
|
||||
.pr_accept = uipc_accept,
|
||||
.pr_accept = uipc_peeraddr,
|
||||
.pr_attach = uipc_attach,
|
||||
.pr_bind = uipc_bind,
|
||||
.pr_bindat = uipc_bindat,
|
||||
|
|
|
@ -508,7 +508,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
|
|||
struct sockaddr_storage remote;
|
||||
struct ovpn_kpeer *peer = NULL;
|
||||
struct file *fp = NULL;
|
||||
struct sockaddr *name = NULL;
|
||||
struct ovpn_softc *sc = ifp->if_softc;
|
||||
struct thread *td = curthread;
|
||||
struct socket *so = NULL;
|
||||
|
@ -574,23 +573,21 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
|
|||
callout_init_rm(&peer->ping_send, &sc->lock, CALLOUT_SHAREDLOCK);
|
||||
callout_init_rm(&peer->ping_rcv, &sc->lock, 0);
|
||||
|
||||
ret = so->so_proto->pr_sockaddr(so, &name);
|
||||
peer->local.ss_len = sizeof(peer->local);
|
||||
ret = sosockaddr(so, (struct sockaddr *)&peer->local);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (ovpn_get_port((struct sockaddr_storage *)name) == 0) {
|
||||
if (ovpn_get_port(&peer->local) == 0) {
|
||||
ret = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
if (name->sa_family != remote.ss_family) {
|
||||
if (peer->local.ss_family != remote.ss_family) {
|
||||
ret = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(&peer->local, name, name->sa_len);
|
||||
memcpy(&peer->remote, &remote, sizeof(remote));
|
||||
free(name, M_SONAME);
|
||||
name = NULL;
|
||||
|
||||
if (peer->local.ss_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&TO_IN6(&peer->remote)->sin6_addr)) {
|
||||
|
@ -656,7 +653,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
|
|||
error_locked:
|
||||
OVPN_WUNLOCK(sc);
|
||||
error:
|
||||
free(name, M_SONAME);
|
||||
COUNTER_ARRAY_FREE(peer->counters, OVPN_PEER_COUNTER_SIZE);
|
||||
uma_zfree_pcpu(pcpu_zone_4, peer->last_active);
|
||||
free(peer, M_OVPN);
|
||||
|
|
|
@ -78,11 +78,10 @@ int ng_btsocket_hci_raw_control (struct socket *, u_long, void *,
|
|||
int ng_btsocket_hci_raw_ctloutput (struct socket *, struct sockopt *);
|
||||
void ng_btsocket_hci_raw_detach (struct socket *);
|
||||
int ng_btsocket_hci_raw_disconnect (struct socket *);
|
||||
int ng_btsocket_hci_raw_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_hci_raw_send (struct socket *, int, struct mbuf *,
|
||||
struct sockaddr *, struct mbuf *,
|
||||
struct thread *);
|
||||
int ng_btsocket_hci_raw_sockaddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_hci_raw_sockaddr (struct socket *, struct sockaddr *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
|
@ -105,11 +105,11 @@ int ng_btsocket_l2cap_raw_control (struct socket *, u_long, void *,
|
|||
struct ifnet *, struct thread *);
|
||||
void ng_btsocket_l2cap_raw_detach (struct socket *);
|
||||
int ng_btsocket_l2cap_raw_disconnect (struct socket *);
|
||||
int ng_btsocket_l2cap_raw_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_l2cap_raw_peeraddr (struct socket *, struct sockaddr *);
|
||||
int ng_btsocket_l2cap_raw_send (struct socket *, int, struct mbuf *,
|
||||
struct sockaddr *, struct mbuf *,
|
||||
struct thread *);
|
||||
int ng_btsocket_l2cap_raw_sockaddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_l2cap_raw_sockaddr (struct socket *, struct sockaddr *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -191,7 +191,6 @@ typedef struct ng_btsocket_l2cap_pcb * ng_btsocket_l2cap_pcb_p;
|
|||
|
||||
void ng_btsocket_l2cap_abort (struct socket *);
|
||||
void ng_btsocket_l2cap_close (struct socket *);
|
||||
int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr *);
|
||||
int ng_btsocket_l2cap_attach (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_l2cap_bind (struct socket *, struct sockaddr *,
|
||||
struct thread *);
|
||||
|
@ -203,11 +202,11 @@ int ng_btsocket_l2cap_ctloutput (struct socket *, struct sockopt *);
|
|||
void ng_btsocket_l2cap_detach (struct socket *);
|
||||
int ng_btsocket_l2cap_disconnect (struct socket *);
|
||||
int ng_btsocket_l2cap_listen (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr *);
|
||||
int ng_btsocket_l2cap_send (struct socket *, int, struct mbuf *,
|
||||
struct sockaddr *, struct mbuf *,
|
||||
struct thread *);
|
||||
int ng_btsocket_l2cap_sockaddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_l2cap_sockaddr (struct socket *, struct sockaddr *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
|
@ -328,11 +328,11 @@ int ng_btsocket_rfcomm_ctloutput (struct socket *, struct sockopt *);
|
|||
void ng_btsocket_rfcomm_detach (struct socket *);
|
||||
int ng_btsocket_rfcomm_disconnect (struct socket *);
|
||||
int ng_btsocket_rfcomm_listen (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr *);
|
||||
int ng_btsocket_rfcomm_send (struct socket *, int, struct mbuf *,
|
||||
struct sockaddr *, struct mbuf *,
|
||||
struct thread *);
|
||||
int ng_btsocket_rfcomm_sockaddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_rfcomm_sockaddr (struct socket *, struct sockaddr *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
|
@ -118,11 +118,11 @@ int ng_btsocket_sco_ctloutput (struct socket *, struct sockopt *);
|
|||
void ng_btsocket_sco_detach (struct socket *);
|
||||
int ng_btsocket_sco_disconnect (struct socket *);
|
||||
int ng_btsocket_sco_listen (struct socket *, int, struct thread *);
|
||||
int ng_btsocket_sco_peeraddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_sco_peeraddr (struct socket *, struct sockaddr *);
|
||||
int ng_btsocket_sco_send (struct socket *, int, struct mbuf *,
|
||||
struct sockaddr *, struct mbuf *,
|
||||
struct thread *);
|
||||
int ng_btsocket_sco_sockaddr (struct socket *, struct sockaddr **);
|
||||
int ng_btsocket_sco_sockaddr (struct socket *, struct sockaddr *);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ static struct protosw ng_btsocket_hci_raw_protosw = {
|
|||
.pr_control = ng_btsocket_hci_raw_control,
|
||||
.pr_detach = ng_btsocket_hci_raw_detach,
|
||||
.pr_disconnect = ng_btsocket_hci_raw_disconnect,
|
||||
.pr_peeraddr = ng_btsocket_hci_raw_peeraddr,
|
||||
.pr_peeraddr = ng_btsocket_hci_raw_sockaddr,
|
||||
.pr_send = ng_btsocket_hci_raw_send,
|
||||
.pr_sockaddr = ng_btsocket_hci_raw_sockaddr,
|
||||
.pr_close = ng_btsocket_hci_raw_close,
|
||||
|
@ -110,7 +110,7 @@ static struct protosw ng_btsocket_l2cap_protosw = {
|
|||
.pr_flags = PR_ATOMIC|PR_CONNREQUIRED,
|
||||
.pr_ctloutput = ng_btsocket_l2cap_ctloutput,
|
||||
.pr_abort = ng_btsocket_l2cap_abort,
|
||||
.pr_accept = ng_btsocket_l2cap_accept,
|
||||
.pr_accept = ng_btsocket_l2cap_peeraddr,
|
||||
.pr_attach = ng_btsocket_l2cap_attach,
|
||||
.pr_bind = ng_btsocket_l2cap_bind,
|
||||
.pr_connect = ng_btsocket_l2cap_connect,
|
||||
|
@ -131,7 +131,7 @@ static struct protosw ng_btsocket_rfcomm_protosw = {
|
|||
.pr_flags = PR_CONNREQUIRED,
|
||||
.pr_ctloutput = ng_btsocket_rfcomm_ctloutput,
|
||||
.pr_abort = ng_btsocket_rfcomm_abort,
|
||||
.pr_accept = ng_btsocket_rfcomm_accept,
|
||||
.pr_accept = ng_btsocket_rfcomm_peeraddr,
|
||||
.pr_attach = ng_btsocket_rfcomm_attach,
|
||||
.pr_bind = ng_btsocket_rfcomm_bind,
|
||||
.pr_connect = ng_btsocket_rfcomm_connect,
|
||||
|
@ -152,7 +152,7 @@ static struct protosw ng_btsocket_sco_protosw = {
|
|||
.pr_flags = PR_ATOMIC|PR_CONNREQUIRED,
|
||||
.pr_ctloutput = ng_btsocket_sco_ctloutput,
|
||||
.pr_abort = ng_btsocket_sco_abort,
|
||||
.pr_accept = ng_btsocket_sco_accept,
|
||||
.pr_accept = ng_btsocket_sco_peeraddr,
|
||||
.pr_attach = ng_btsocket_sco_attach,
|
||||
.pr_bind = ng_btsocket_sco_bind,
|
||||
.pr_connect = ng_btsocket_sco_connect,
|
||||
|
|
|
@ -1556,16 +1556,6 @@ ng_btsocket_hci_raw_disconnect(struct socket *so)
|
|||
return (0);
|
||||
} /* ng_btsocket_hci_raw_disconnect */
|
||||
|
||||
/*
|
||||
* Get socket peer's address
|
||||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_hci_raw_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
return (ng_btsocket_hci_raw_sockaddr(so, nam));
|
||||
} /* ng_btsocket_hci_raw_peeraddr */
|
||||
|
||||
/*
|
||||
* Send data
|
||||
*/
|
||||
|
@ -1656,25 +1646,24 @@ ng_btsocket_hci_raw_send(struct socket *so, int flags, struct mbuf *m,
|
|||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_hci_raw_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_hci_raw_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_hci_raw_pcb_p pcb = so2hci_raw_pcb(so);
|
||||
struct sockaddr_hci sa;
|
||||
struct sockaddr_hci *hci = (struct sockaddr_hci *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_hci_raw_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bzero(&sa, sizeof(sa));
|
||||
sa.hci_len = sizeof(sa);
|
||||
sa.hci_family = AF_BLUETOOTH;
|
||||
*hci = (struct sockaddr_hci ){
|
||||
.hci_len = sizeof(struct sockaddr_hci),
|
||||
.hci_family = AF_BLUETOOTH,
|
||||
};
|
||||
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
strlcpy(sa.hci_node, pcb->addr.hci_node, sizeof(sa.hci_node));
|
||||
strlcpy(hci->hci_node, pcb->addr.hci_node, sizeof(hci->hci_node));
|
||||
mtx_unlock(&pcb->pcb_mtx);
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_hci_raw_sockaddr */
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -2509,68 +2509,43 @@ ng_btsocket_l2cap_listen(struct socket *so, int backlog, struct thread *td)
|
|||
return (error);
|
||||
} /* ng_btsocket_listen */
|
||||
|
||||
static int
|
||||
ng_btsocket_l2cap_peeraddr1(struct socket *so, struct sockaddr_l2cap *sa)
|
||||
/*
|
||||
* Return peer address for getpeername(2) or for accept(2). For the latter
|
||||
* case no extra work to do here, socket must be connected and ready.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so);
|
||||
struct sockaddr_l2cap *l2cap = (struct sockaddr_l2cap *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_l2cap_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*sa = (struct sockaddr_l2cap ){
|
||||
*l2cap = (struct sockaddr_l2cap ){
|
||||
.l2cap_len = sizeof(struct sockaddr_l2cap),
|
||||
.l2cap_family = AF_BLUETOOTH,
|
||||
.l2cap_psm = htole16(pcb->psm),
|
||||
};
|
||||
bcopy(&pcb->dst, &sa->l2cap_bdaddr, sizeof(sa->l2cap_bdaddr));
|
||||
bcopy(&pcb->dst, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
|
||||
switch(pcb->idtype){
|
||||
case NG_L2CAP_L2CA_IDTYPE_ATT:
|
||||
sa->l2cap_cid = NG_L2CAP_ATT_CID;
|
||||
l2cap->l2cap_cid = NG_L2CAP_ATT_CID;
|
||||
break;
|
||||
case NG_L2CAP_L2CA_IDTYPE_SMP:
|
||||
sa->l2cap_cid = NG_L2CAP_SMP_CID;
|
||||
l2cap->l2cap_cid = NG_L2CAP_SMP_CID;
|
||||
break;
|
||||
default:
|
||||
sa->l2cap_cid = 0;
|
||||
l2cap->l2cap_cid = 0;
|
||||
break;
|
||||
}
|
||||
sa->l2cap_bdaddr_type = pcb->dsttype;
|
||||
l2cap->l2cap_bdaddr_type = pcb->dsttype;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get peer address
|
||||
*/
|
||||
int
|
||||
ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
struct sockaddr_l2cap sa;
|
||||
int error;
|
||||
|
||||
error = ng_btsocket_l2cap_peeraddr1(so, &sa);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept connection on socket. Nothing to do here, socket must be connected
|
||||
* and ready, so just return peer address and be done with it.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_l2cap_accept(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
if (ng_btsocket_l2cap_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
return (ng_btsocket_l2cap_peeraddr1(so, (struct sockaddr_l2cap *)sa));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data to socket
|
||||
*/
|
||||
|
@ -2702,29 +2677,27 @@ ng_btsocket_l2cap_send2(ng_btsocket_l2cap_pcb_p pcb)
|
|||
/*
|
||||
* Get socket address
|
||||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_l2cap_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_l2cap_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so);
|
||||
struct sockaddr_l2cap sa;
|
||||
struct sockaddr_l2cap *l2cap = (struct sockaddr_l2cap *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_l2cap_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bcopy(&pcb->src, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
|
||||
sa.l2cap_psm = htole16(pcb->psm);
|
||||
sa.l2cap_len = sizeof(sa);
|
||||
sa.l2cap_family = AF_BLUETOOTH;
|
||||
sa.l2cap_cid = 0;
|
||||
sa.l2cap_bdaddr_type = pcb->srctype;
|
||||
*l2cap = (struct sockaddr_l2cap ){
|
||||
.l2cap_len = sizeof(struct sockaddr_l2cap),
|
||||
.l2cap_family = AF_BLUETOOTH,
|
||||
.l2cap_psm = htole16(pcb->psm),
|
||||
.l2cap_bdaddr_type = pcb->srctype,
|
||||
};
|
||||
bcopy(&pcb->src, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_l2cap_sockaddr */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*****************************************************************************
|
||||
|
|
|
@ -1204,30 +1204,28 @@ ng_btsocket_l2cap_raw_disconnect(struct socket *so)
|
|||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_l2cap_raw_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_l2cap_raw_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_l2cap_raw_pcb_p pcb = so2l2cap_raw_pcb(so);
|
||||
struct sockaddr_l2cap sa;
|
||||
struct sockaddr_l2cap *l2cap = (struct sockaddr_l2cap *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_l2cap_raw_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*l2cap = (struct sockaddr_l2cap ){
|
||||
.l2cap_len = sizeof(struct sockaddr_l2cap),
|
||||
.l2cap_family = AF_BLUETOOTH,
|
||||
.l2cap_bdaddr_type = BDADDR_BREDR,
|
||||
};
|
||||
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
bcopy(&pcb->dst, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
|
||||
bcopy(&pcb->dst, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
|
||||
mtx_unlock(&pcb->pcb_mtx);
|
||||
|
||||
sa.l2cap_psm = 0;
|
||||
sa.l2cap_len = sizeof(sa);
|
||||
sa.l2cap_family = AF_BLUETOOTH;
|
||||
sa.l2cap_cid = 0;
|
||||
sa.l2cap_bdaddr_type = BDADDR_BREDR;
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_l2cap_raw_peeraddr */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data to socket
|
||||
|
@ -1248,29 +1246,28 @@ ng_btsocket_l2cap_raw_send(struct socket *so, int flags, struct mbuf *m,
|
|||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_l2cap_raw_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_l2cap_raw_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_l2cap_raw_pcb_p pcb = so2l2cap_raw_pcb(so);
|
||||
struct sockaddr_l2cap sa;
|
||||
struct sockaddr_l2cap *l2cap = (struct sockaddr_l2cap *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_l2cap_raw_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*l2cap = (struct sockaddr_l2cap ){
|
||||
.l2cap_len = sizeof(struct sockaddr_l2cap),
|
||||
.l2cap_family = AF_BLUETOOTH,
|
||||
.l2cap_bdaddr_type = BDADDR_BREDR,
|
||||
};
|
||||
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
bcopy(&pcb->src, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
|
||||
bcopy(&pcb->src, &l2cap->l2cap_bdaddr, sizeof(l2cap->l2cap_bdaddr));
|
||||
mtx_unlock(&pcb->pcb_mtx);
|
||||
|
||||
sa.l2cap_psm = 0;
|
||||
sa.l2cap_len = sizeof(sa);
|
||||
sa.l2cap_family = AF_BLUETOOTH;
|
||||
sa.l2cap_cid = 0;
|
||||
sa.l2cap_bdaddr_type = BDADDR_BREDR;
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_l2cap_raw_sockaddr */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get next token
|
||||
|
|
|
@ -914,52 +914,29 @@ ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td)
|
|||
return (error);
|
||||
} /* ng_btsocket_listen */
|
||||
|
||||
static int
|
||||
ng_btsocket_rfcomm_peeraddr1(struct socket *so, struct sockaddr_rfcomm *sa)
|
||||
/*
|
||||
* Return peer address for getpeername(2) or for accept(2). For the latter
|
||||
* case no extra work to do here, socket must be connected and ready.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so);
|
||||
struct sockaddr_rfcomm *rfcomm = (struct sockaddr_rfcomm *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*sa = (struct sockaddr_rfcomm ){
|
||||
*rfcomm = (struct sockaddr_rfcomm ){
|
||||
.rfcomm_len = sizeof(struct sockaddr_rfcomm),
|
||||
.rfcomm_family = AF_BLUETOOTH,
|
||||
.rfcomm_channel = pcb->channel,
|
||||
};
|
||||
bcopy(&pcb->dst, &sa->rfcomm_bdaddr, sizeof(sa->rfcomm_bdaddr));
|
||||
bcopy(&pcb->dst, &rfcomm->rfcomm_bdaddr, sizeof(rfcomm->rfcomm_bdaddr));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get peer address
|
||||
*/
|
||||
int
|
||||
ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
struct sockaddr_rfcomm sa;
|
||||
int error;
|
||||
|
||||
error = ng_btsocket_rfcomm_peeraddr1(so, &sa);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept connection on socket. Nothing to do here, socket must be connected
|
||||
* and ready, so just return peer address and be done with it.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
|
||||
return (ng_btsocket_rfcomm_peeraddr1(so, (struct sockaddr_rfcomm *)sa));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data to socket
|
||||
*/
|
||||
|
@ -1008,23 +985,23 @@ ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m,
|
|||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so);
|
||||
struct sockaddr_rfcomm sa;
|
||||
struct sockaddr_rfcomm *rfcomm = (struct sockaddr_rfcomm *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
|
||||
sa.rfcomm_channel = pcb->channel;
|
||||
sa.rfcomm_len = sizeof(sa);
|
||||
sa.rfcomm_family = AF_BLUETOOTH;
|
||||
*rfcomm = (struct sockaddr_rfcomm ){
|
||||
.rfcomm_len = sizeof(struct sockaddr_rfcomm),
|
||||
.rfcomm_family = AF_BLUETOOTH,
|
||||
.rfcomm_channel = pcb->channel,
|
||||
};
|
||||
bcopy(&pcb->src, &rfcomm->rfcomm_bdaddr, sizeof(rfcomm->rfcomm_bdaddr));
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_rfcomm_sockaddr */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Upcall function for L2CAP sockets. Enqueue RFCOMM task.
|
||||
|
|
|
@ -1609,57 +1609,32 @@ ng_btsocket_sco_listen(struct socket *so, int backlog, struct thread *td)
|
|||
return (error);
|
||||
} /* ng_btsocket_listen */
|
||||
|
||||
static int
|
||||
ng_btsocket_sco_peeraddr1(struct socket *so, struct sockaddr_sco *sa)
|
||||
/*
|
||||
* Return peer address for getpeername(2) or for accept(2). For the latter
|
||||
* case no extra work to do here, socket must be connected and ready.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_sco_pcb_p pcb = so2sco_pcb(so);
|
||||
struct sockaddr_sco *sco = (struct sockaddr_sco *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_sco_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*sa = (struct sockaddr_sco ){
|
||||
*sco = (struct sockaddr_sco ){
|
||||
.sco_len = sizeof(struct sockaddr_sco),
|
||||
.sco_family = AF_BLUETOOTH,
|
||||
};
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
bcopy(&pcb->dst, &sa->sco_bdaddr, sizeof(sa->sco_bdaddr));
|
||||
bcopy(&pcb->dst, &sco->sco_bdaddr, sizeof(sco->sco_bdaddr));
|
||||
mtx_unlock(&pcb->pcb_mtx);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get peer address
|
||||
*/
|
||||
int
|
||||
ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
struct sockaddr_sco sa;
|
||||
int error;
|
||||
|
||||
error = ng_btsocket_sco_peeraddr1(so, &sa);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept connection on socket. Nothing to do here, socket must be connected
|
||||
* and ready, so just return peer address and be done with it.
|
||||
*/
|
||||
int
|
||||
ng_btsocket_sco_accept(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
if (ng_btsocket_sco_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
return (ng_btsocket_sco_peeraddr1(so, (struct sockaddr_sco *)sa));
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data to socket
|
||||
*/
|
||||
|
@ -1791,27 +1766,26 @@ ng_btsocket_sco_send2(ng_btsocket_sco_pcb_p pcb)
|
|||
*/
|
||||
|
||||
int
|
||||
ng_btsocket_sco_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
ng_btsocket_sco_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
ng_btsocket_sco_pcb_p pcb = so2sco_pcb(so);
|
||||
struct sockaddr_sco sa;
|
||||
struct sockaddr_sco *sco = (struct sockaddr_sco *)sa;
|
||||
|
||||
if (pcb == NULL)
|
||||
return (EINVAL);
|
||||
if (ng_btsocket_sco_node == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*sco = (struct sockaddr_sco ){
|
||||
.sco_len = sizeof(struct sockaddr_sco),
|
||||
.sco_family = AF_BLUETOOTH,
|
||||
};
|
||||
mtx_lock(&pcb->pcb_mtx);
|
||||
bcopy(&pcb->src, &sa.sco_bdaddr, sizeof(sa.sco_bdaddr));
|
||||
bcopy(&pcb->src, &sco->sco_bdaddr, sizeof(sco->sco_bdaddr));
|
||||
mtx_unlock(&pcb->pcb_mtx);
|
||||
|
||||
sa.sco_len = sizeof(sa);
|
||||
sa.sco_family = AF_BLUETOOTH;
|
||||
|
||||
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
|
||||
|
||||
return ((*nam == NULL)? ENOMEM : 0);
|
||||
} /* ng_btsocket_sco_sockaddr */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*****************************************************************************
|
||||
|
|
|
@ -771,9 +771,8 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
case NGM_KSOCKET_GETNAME:
|
||||
case NGM_KSOCKET_GETPEERNAME:
|
||||
{
|
||||
int (*func)(struct socket *so, struct sockaddr **nam);
|
||||
struct sockaddr *sa = NULL;
|
||||
int len;
|
||||
int (*func)(struct socket *so, struct sockaddr *sa);
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
|
||||
/* Sanity check */
|
||||
if (msg->header.arglen != 0)
|
||||
|
@ -786,27 +785,22 @@ ng_ksocket_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||
if ((so->so_state
|
||||
& (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
|
||||
ERROUT(ENOTCONN);
|
||||
func = so->so_proto->pr_peeraddr;
|
||||
func = sopeeraddr;
|
||||
} else
|
||||
func = so->so_proto->pr_sockaddr;
|
||||
func = sosockaddr;
|
||||
|
||||
/* Get local or peer address */
|
||||
if ((error = (*func)(so, &sa)) != 0)
|
||||
goto bail;
|
||||
len = (sa == NULL) ? 0 : sa->sa_len;
|
||||
error = (*func)(so, (struct sockaddr *)&ss);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
/* Send it back in a response */
|
||||
NG_MKRESPONSE(resp, msg, len, M_NOWAIT);
|
||||
if (resp == NULL) {
|
||||
NG_MKRESPONSE(resp, msg, ss.ss_len, M_NOWAIT);
|
||||
if (resp != NULL)
|
||||
bcopy(&ss, resp->data, ss.ss_len);
|
||||
else
|
||||
error = ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
bcopy(sa, resp->data, len);
|
||||
|
||||
bail:
|
||||
/* Cleanup */
|
||||
if (sa != NULL)
|
||||
free(sa, M_SONAME);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -500,11 +500,10 @@ ngd_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
|||
* Used for both data and control sockets
|
||||
*/
|
||||
static int
|
||||
ng_getsockaddr(struct socket *so, struct sockaddr **addr)
|
||||
ng_getsockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_ng *sg = (struct sockaddr_ng *)sa;
|
||||
struct ngpcb *pcbp;
|
||||
struct sockaddr_ng *sg;
|
||||
int sg_len;
|
||||
int error = 0;
|
||||
|
||||
pcbp = sotongpcb(so);
|
||||
|
@ -512,9 +511,10 @@ ng_getsockaddr(struct socket *so, struct sockaddr **addr)
|
|||
/* XXXGL: can this still happen? */
|
||||
return (EINVAL);
|
||||
|
||||
sg_len = sizeof(struct sockaddr_ng) + NG_NODESIZ -
|
||||
sizeof(sg->sg_data);
|
||||
sg = malloc(sg_len, M_SONAME, M_WAITOK | M_ZERO);
|
||||
*sg = (struct sockaddr_ng ){
|
||||
.sg_len = sizeof(struct sockaddr_ng),
|
||||
.sg_family = AF_NETGRAPH,
|
||||
};
|
||||
|
||||
mtx_lock(&pcbp->sockdata->mtx);
|
||||
if (pcbp->sockdata->node != NULL) {
|
||||
|
@ -526,16 +526,9 @@ ng_getsockaddr(struct socket *so, struct sockaddr **addr)
|
|||
else
|
||||
snprintf(sg->sg_data, sizeof(sg->sg_data), "[%x]",
|
||||
ng_node2ID(node));
|
||||
mtx_unlock(&pcbp->sockdata->mtx);
|
||||
|
||||
sg->sg_len = sg_len;
|
||||
sg->sg_family = AF_NETGRAPH;
|
||||
*addr = (struct sockaddr *)sg;
|
||||
} else {
|
||||
mtx_unlock(&pcbp->sockdata->mtx);
|
||||
free(sg, M_SONAME);
|
||||
} else
|
||||
error = EINVAL;
|
||||
}
|
||||
mtx_unlock(&pcbp->sockdata->mtx);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1824,57 +1824,40 @@ in_pcbdrop(struct inpcb *inp)
|
|||
/*
|
||||
* Common routines to return the socket addresses associated with inpcbs.
|
||||
*/
|
||||
struct sockaddr *
|
||||
in_sockaddr(in_port_t port, struct in_addr *addr_p)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = malloc(sizeof *sin, M_SONAME,
|
||||
M_WAITOK | M_ZERO);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_addr = *addr_p;
|
||||
sin->sin_port = port;
|
||||
|
||||
return (struct sockaddr *)sin;
|
||||
}
|
||||
|
||||
int
|
||||
in_getsockaddr(struct socket *so, struct sockaddr **nam)
|
||||
in_getsockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct in_addr addr;
|
||||
in_port_t port;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("in_getsockaddr: inp == NULL"));
|
||||
|
||||
INP_RLOCK(inp);
|
||||
port = inp->inp_lport;
|
||||
addr = inp->inp_laddr;
|
||||
INP_RUNLOCK(inp);
|
||||
*(struct sockaddr_in *)sa = (struct sockaddr_in ){
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = inp->inp_lport,
|
||||
.sin_addr = inp->inp_laddr,
|
||||
};
|
||||
|
||||
*nam = in_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
in_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
in_getpeeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct in_addr addr;
|
||||
in_port_t port;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("in_getpeeraddr: inp == NULL"));
|
||||
|
||||
INP_RLOCK(inp);
|
||||
port = inp->inp_fport;
|
||||
addr = inp->inp_faddr;
|
||||
INP_RUNLOCK(inp);
|
||||
*(struct sockaddr_in *)sa = (struct sockaddr_in ){
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = inp->inp_fport,
|
||||
.sin_addr = inp->inp_faddr,
|
||||
};
|
||||
|
||||
*nam = in_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -721,10 +721,8 @@ struct inpcb_iterator {
|
|||
struct inpcb *inp_next(struct inpcb_iterator *);
|
||||
void in_losing(struct inpcb *);
|
||||
void in_pcbsetsolabel(struct socket *so);
|
||||
int in_getpeeraddr(struct socket *so, struct sockaddr **nam);
|
||||
int in_getsockaddr(struct socket *so, struct sockaddr **nam);
|
||||
struct sockaddr *
|
||||
in_sockaddr(in_port_t port, struct in_addr *addr);
|
||||
int in_getpeeraddr(struct socket *, struct sockaddr *sa);
|
||||
int in_getsockaddr(struct socket *, struct sockaddr *sa);
|
||||
void in_pcbsosetlabel(struct socket *so);
|
||||
#ifdef RATELIMIT
|
||||
int
|
||||
|
|
|
@ -39,9 +39,6 @@
|
|||
* General kernel memory allocation:
|
||||
* SCTP_MALLOC(element, type, size, name)
|
||||
* SCTP_FREE(element)
|
||||
* Kernel memory allocation for "soname"- memory must be zeroed.
|
||||
* SCTP_MALLOC_SONAME(name, type, size)
|
||||
* SCTP_FREE_SONAME(name)
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -219,13 +219,6 @@ MALLOC_DECLARE(SCTP_M_MCORE);
|
|||
|
||||
#define SCTP_FREE(var, type) free(var, type)
|
||||
|
||||
#define SCTP_MALLOC_SONAME(var, type, size) \
|
||||
do { \
|
||||
var = (type)malloc(size, M_SONAME, M_WAITOK | M_ZERO); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_FREE_SONAME(var) free(var, M_SONAME)
|
||||
|
||||
#define SCTP_PROCESS_STRUCT struct proc *
|
||||
|
||||
/*
|
||||
|
|
|
@ -7367,24 +7367,20 @@ sctp_accept(struct socket *so, struct sockaddr *sa)
|
|||
|
||||
#ifdef INET
|
||||
int
|
||||
sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
|
||||
sctp_ingetaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
uint32_t vrf_id;
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
|
||||
/*
|
||||
* Do the malloc first in case it blocks.
|
||||
*/
|
||||
SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
|
||||
if (sin == NULL)
|
||||
return (ENOMEM);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
*sin = (struct sockaddr_in ){
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_family = AF_INET,
|
||||
};
|
||||
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if (!inp) {
|
||||
SCTP_FREE_SONAME(sin);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
return (ECONNRESET);
|
||||
}
|
||||
|
@ -7453,39 +7449,35 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
|
|||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
SCTP_FREE_SONAME(sin);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
(*addr) = (struct sockaddr *)sin;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sctp_peeraddr(struct socket *so, struct sockaddr **addr)
|
||||
sctp_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
int fnd;
|
||||
struct sockaddr_in *sin_a;
|
||||
struct sctp_inpcb *inp;
|
||||
struct sctp_tcb *stcb;
|
||||
struct sctp_nets *net;
|
||||
|
||||
/* Do the malloc first in case it blocks. */
|
||||
SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
|
||||
if (sin == NULL)
|
||||
return (ENOMEM);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
*sin = (struct sockaddr_in ){
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_family = AF_INET,
|
||||
};
|
||||
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if ((inp == NULL) ||
|
||||
((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
|
||||
/* UDP type and listeners will drop out here */
|
||||
SCTP_FREE_SONAME(sin);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
|
||||
return (ENOTCONN);
|
||||
}
|
||||
|
@ -7496,7 +7488,6 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
if (stcb == NULL) {
|
||||
SCTP_FREE_SONAME(sin);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
|
||||
return (ECONNRESET);
|
||||
}
|
||||
|
@ -7513,11 +7504,10 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
SCTP_TCB_UNLOCK(stcb);
|
||||
if (!fnd) {
|
||||
/* No IPv4 address */
|
||||
SCTP_FREE_SONAME(sin);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
(*addr) = (struct sockaddr *)sin;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -338,8 +338,8 @@ sctp_bindx(struct socket *, int, struct sockaddr_storage *,
|
|||
|
||||
/* can't use sctp_assoc_t here */
|
||||
int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
|
||||
int sctp_ingetaddr(struct socket *, struct sockaddr **);
|
||||
int sctp_peeraddr(struct socket *, struct sockaddr **);
|
||||
int sctp_ingetaddr(struct socket *, struct sockaddr *);
|
||||
int sctp_peeraddr(struct socket *, struct sockaddr *);
|
||||
int sctp_listen(struct socket *, int, struct thread *);
|
||||
int sctp_accept(struct socket *, struct sockaddr *);
|
||||
|
||||
|
|
|
@ -2679,20 +2679,6 @@ in6_sin6_2_sin_in_sock(struct sockaddr *nam)
|
|||
in6_sin6_2_sin(sin_p, &sin6);
|
||||
}
|
||||
|
||||
/* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
|
||||
void
|
||||
in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
|
||||
{
|
||||
struct sockaddr_in *sin_p;
|
||||
struct sockaddr_in6 *sin6_p;
|
||||
|
||||
sin6_p = malloc(sizeof *sin6_p, M_SONAME, M_WAITOK);
|
||||
sin_p = (struct sockaddr_in *)*nam;
|
||||
in6_sin_2_v4mapsin6(sin_p, sin6_p);
|
||||
free(*nam, M_SONAME);
|
||||
*nam = (struct sockaddr *)sin6_p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Join/leave the solicited multicast groups for proxy NDP entries.
|
||||
*/
|
||||
|
|
|
@ -675,7 +675,6 @@ void in6_sin6_2_sin(struct sockaddr_in *sin,
|
|||
void in6_sin_2_v4mapsin6(struct sockaddr_in *sin,
|
||||
struct sockaddr_in6 *sin6);
|
||||
void in6_sin6_2_sin_in_sock(struct sockaddr *nam);
|
||||
void in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam);
|
||||
extern void addrsel_policy_init(void);
|
||||
|
||||
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
|
||||
|
|
|
@ -501,62 +501,48 @@ in6_pcbdisconnect(struct inpcb *inp)
|
|||
inp->inp_flow &= ~IPV6_FLOWLABEL_MASK;
|
||||
}
|
||||
|
||||
struct sockaddr *
|
||||
in6_sockaddr(in_port_t port, struct in6_addr *addr_p)
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
sin6 = malloc(sizeof *sin6, M_SONAME, M_WAITOK);
|
||||
bzero(sin6, sizeof *sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
sin6->sin6_port = port;
|
||||
sin6->sin6_addr = *addr_p;
|
||||
(void)sa6_recoverscope(sin6); /* XXX: should catch errors */
|
||||
|
||||
return (struct sockaddr *)sin6;
|
||||
}
|
||||
|
||||
int
|
||||
in6_getsockaddr(struct socket *so, struct sockaddr **nam)
|
||||
in6_getsockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct in6_addr addr;
|
||||
in_port_t port;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("in6_getsockaddr: inp == NULL"));
|
||||
|
||||
INP_RLOCK(inp);
|
||||
port = inp->inp_lport;
|
||||
addr = inp->in6p_laddr;
|
||||
INP_RUNLOCK(inp);
|
||||
*(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){
|
||||
.sin6_len = sizeof(struct sockaddr_in6),
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = inp->inp_lport,
|
||||
.sin6_addr = inp->in6p_laddr,
|
||||
};
|
||||
/* XXX: should catch errors */
|
||||
(void)sa6_recoverscope((struct sockaddr_in6 *)sa);
|
||||
|
||||
*nam = in6_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
in6_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
in6_getpeeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct in6_addr addr;
|
||||
in_port_t port;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("in6_getpeeraddr: inp == NULL"));
|
||||
|
||||
INP_RLOCK(inp);
|
||||
port = inp->inp_fport;
|
||||
addr = inp->in6p_faddr;
|
||||
INP_RUNLOCK(inp);
|
||||
*(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){
|
||||
.sin6_len = sizeof(struct sockaddr_in6),
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = inp->inp_fport,
|
||||
.sin6_addr = inp->in6p_faddr,
|
||||
};
|
||||
/* XXX: should catch errors */
|
||||
(void)sa6_recoverscope((struct sockaddr_in6 *)sa);
|
||||
|
||||
*nam = in6_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam)
|
||||
in6_mapped_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
@ -566,21 +552,23 @@ in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam)
|
|||
|
||||
#ifdef INET
|
||||
if ((inp->inp_vflag & (INP_IPV4 | INP_IPV6)) == INP_IPV4) {
|
||||
error = in_getsockaddr(so, nam);
|
||||
struct sockaddr_in sin;
|
||||
|
||||
error = in_getsockaddr(so, (struct sockaddr *)&sin);
|
||||
if (error == 0)
|
||||
in6_sin_2_v4mapsin6_in_sock(nam);
|
||||
in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* scope issues will be handled in in6_getsockaddr(). */
|
||||
error = in6_getsockaddr(so, nam);
|
||||
error = in6_getsockaddr(so, sa);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam)
|
||||
in6_mapped_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
int error;
|
||||
|
@ -590,13 +578,15 @@ in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam)
|
|||
|
||||
#ifdef INET
|
||||
if ((inp->inp_vflag & (INP_IPV4 | INP_IPV6)) == INP_IPV4) {
|
||||
error = in_getpeeraddr(so, nam);
|
||||
struct sockaddr_in sin;
|
||||
|
||||
error = in_getpeeraddr(so, (struct sockaddr *)&sin);
|
||||
if (error == 0)
|
||||
in6_sin_2_v4mapsin6_in_sock(nam);
|
||||
in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa);
|
||||
} else
|
||||
#endif
|
||||
/* scope issues will be handled in in6_getpeeraddr(). */
|
||||
error = in6_getpeeraddr(so, nam);
|
||||
error = in6_getpeeraddr(so, sa);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -96,12 +96,10 @@ void in6_pcbnotify(struct inpcbinfo *, struct sockaddr_in6 *, u_int,
|
|||
struct inpcb *(*)(struct inpcb *, int));
|
||||
struct inpcb *
|
||||
in6_rtchange(struct inpcb *, int);
|
||||
struct sockaddr *
|
||||
in6_sockaddr(in_port_t port, struct in6_addr *addr_p);
|
||||
int in6_getpeeraddr(struct socket *so, struct sockaddr **nam);
|
||||
int in6_getsockaddr(struct socket *so, struct sockaddr **nam);
|
||||
int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
|
||||
int in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam);
|
||||
int in6_getpeeraddr(struct socket *, struct sockaddr *);
|
||||
int in6_getsockaddr(struct socket *, struct sockaddr *);
|
||||
int in6_mapped_sockaddr(struct socket *, struct sockaddr *);
|
||||
int in6_mapped_peeraddr(struct socket *, struct sockaddr *);
|
||||
int in6_selecthlim(struct inpcb *, struct ifnet *);
|
||||
int in6_pcbsetport(struct in6_addr *, struct inpcb *, struct ucred *);
|
||||
void init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m, int);
|
||||
|
|
|
@ -880,27 +880,21 @@ sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
|
|||
}
|
||||
|
||||
static int
|
||||
sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
sctp6_getaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
struct sctp_inpcb *inp;
|
||||
uint32_t vrf_id;
|
||||
struct sctp_ifa *sctp_ifa;
|
||||
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Do the malloc first in case it blocks.
|
||||
*/
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6));
|
||||
if (sin6 == NULL)
|
||||
return (ENOMEM);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
*sin6 = (struct sockaddr_in6 ){
|
||||
.sin6_len = sizeof(struct sockaddr_in6),
|
||||
.sin6_family = AF_INET6,
|
||||
};
|
||||
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if (inp == NULL) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
|
||||
return (ECONNRESET);
|
||||
}
|
||||
|
@ -917,7 +911,6 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
stcb = LIST_FIRST(&inp->sctp_asoc_list);
|
||||
if (stcb == NULL) {
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
@ -937,7 +930,6 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
if ((!fnd) || (sin_a6 == NULL)) {
|
||||
/* punt */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
@ -966,7 +958,6 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
}
|
||||
}
|
||||
if (!fnd) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
|
@ -975,17 +966,16 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
SCTP_INP_RUNLOCK(inp);
|
||||
/* Scoping things for v6 */
|
||||
if ((error = sa6_recoverscope(sin6)) != 0) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
return (error);
|
||||
}
|
||||
(*addr) = (struct sockaddr *)sin6;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
||||
sctp6_peeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
int fnd;
|
||||
struct sockaddr_in6 *sin_a6;
|
||||
struct sctp_inpcb *inp;
|
||||
|
@ -993,18 +983,15 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
struct sctp_nets *net;
|
||||
int error;
|
||||
|
||||
/* Do the malloc first in case it blocks. */
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL)
|
||||
return (ENOMEM);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
*sin6 = (struct sockaddr_in6 ){
|
||||
.sin6_len = sizeof(struct sockaddr_in6),
|
||||
.sin6_family = AF_INET6,
|
||||
};
|
||||
|
||||
inp = (struct sctp_inpcb *)so->so_pcb;
|
||||
if ((inp == NULL) ||
|
||||
((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
|
||||
/* UDP type and listeners will drop out here */
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN);
|
||||
return (ENOTCONN);
|
||||
}
|
||||
|
@ -1015,7 +1002,6 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
if (stcb == NULL) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
|
||||
return (ECONNRESET);
|
||||
}
|
||||
|
@ -1032,21 +1018,19 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
SCTP_TCB_UNLOCK(stcb);
|
||||
if (!fnd) {
|
||||
/* No IPv4 address */
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
if ((error = sa6_recoverscope(sin6)) != 0) {
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, error);
|
||||
return (error);
|
||||
}
|
||||
*addr = (struct sockaddr *)sin6;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
|
||||
sctp6_in6getaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
int error;
|
||||
|
@ -1057,31 +1041,23 @@ sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
|
|||
}
|
||||
|
||||
/* allow v6 addresses precedence */
|
||||
error = sctp6_getaddr(so, nam);
|
||||
error = sctp6_getaddr(so, sa);
|
||||
#ifdef INET
|
||||
if (error) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
/* try v4 next if v6 failed */
|
||||
error = sctp_ingetaddr(so, nam);
|
||||
if (error) {
|
||||
error = sctp_ingetaddr(so, (struct sockaddr *)&sin);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL) {
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
return (ENOMEM);
|
||||
}
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
*nam = (struct sockaddr *)sin6;
|
||||
in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa);
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
sctp6_getpeeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
int error;
|
||||
|
@ -1092,24 +1068,16 @@ sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
|||
}
|
||||
|
||||
/* allow v6 addresses precedence */
|
||||
error = sctp6_peeraddr(so, nam);
|
||||
error = sctp6_peeraddr(so, sa);
|
||||
#ifdef INET
|
||||
if (error) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
/* try v4 next if v6 failed */
|
||||
error = sctp_peeraddr(so, nam);
|
||||
if (error) {
|
||||
error = sctp_peeraddr(so, (struct sockaddr *)&sin);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL) {
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
return (ENOMEM);
|
||||
}
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
*nam = (struct sockaddr *)sin6;
|
||||
in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa);
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
|
|
|
@ -540,14 +540,6 @@ nl_pru_disconnect(struct socket *so)
|
|||
return (ENOTCONN);
|
||||
}
|
||||
|
||||
static int
|
||||
nl_pru_peeraddr(struct socket *so, struct sockaddr **sa)
|
||||
{
|
||||
NL_LOG(LOG_DEBUG3, "socket %p, PID %d", so, curproc->p_pid);
|
||||
MPASS(sotonlpcb(so) != NULL);
|
||||
return (ENOTCONN);
|
||||
}
|
||||
|
||||
static int
|
||||
nl_pru_shutdown(struct socket *so)
|
||||
{
|
||||
|
@ -558,16 +550,16 @@ nl_pru_shutdown(struct socket *so)
|
|||
}
|
||||
|
||||
static int
|
||||
nl_pru_sockaddr(struct socket *so, struct sockaddr **sa)
|
||||
nl_sockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_nl *snl;
|
||||
|
||||
snl = malloc(sizeof(struct sockaddr_nl), M_SONAME, M_WAITOK | M_ZERO);
|
||||
/* TODO: set other fields */
|
||||
snl->nl_len = sizeof(struct sockaddr_nl);
|
||||
snl->nl_family = AF_NETLINK;
|
||||
snl->nl_pid = sotonlpcb(so)->nl_port;
|
||||
*sa = (struct sockaddr *)snl;
|
||||
*(struct sockaddr_nl *)sa = (struct sockaddr_nl ){
|
||||
/* TODO: set other fields */
|
||||
.nl_len = sizeof(struct sockaddr_nl),
|
||||
.nl_family = AF_NETLINK,
|
||||
.nl_pid = sotonlpcb(so)->nl_port,
|
||||
};
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -780,11 +772,10 @@ nl_setsbopt(struct socket *so, struct sockopt *sopt)
|
|||
.pr_connect = nl_pru_connect, \
|
||||
.pr_detach = nl_pru_detach, \
|
||||
.pr_disconnect = nl_pru_disconnect, \
|
||||
.pr_peeraddr = nl_pru_peeraddr, \
|
||||
.pr_send = nl_pru_send, \
|
||||
.pr_rcvd = nl_pru_rcvd, \
|
||||
.pr_shutdown = nl_pru_shutdown, \
|
||||
.pr_sockaddr = nl_pru_sockaddr, \
|
||||
.pr_sockaddr = nl_sockaddr, \
|
||||
.pr_close = nl_pru_close
|
||||
|
||||
static struct protosw netlink_raw_sw = {
|
||||
|
|
|
@ -206,37 +206,37 @@ sdp_sockaddr(in_port_t port, struct in_addr *addr_p)
|
|||
}
|
||||
|
||||
static int
|
||||
sdp_getsockaddr(struct socket *so, struct sockaddr **nam)
|
||||
sdp_getsockaddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sdp_sock *ssk;
|
||||
struct in_addr addr;
|
||||
in_port_t port;
|
||||
struct sdp_sock *ssk = sdp_sk(so);
|
||||
|
||||
ssk = sdp_sk(so);
|
||||
SDP_RLOCK(ssk);
|
||||
port = ssk->lport;
|
||||
addr.s_addr = ssk->laddr;
|
||||
*(struct sockaddr_in *)sa = (struct sockaddr_in ){
|
||||
.sin_family = AF_INET,
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_addr.s_addr = ssk->laddr,
|
||||
.sin_port = ssk->lport,
|
||||
};
|
||||
SDP_RUNLOCK(ssk);
|
||||
|
||||
*nam = sdp_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sdp_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
sdp_getpeeraddr(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sdp_sock *ssk;
|
||||
struct in_addr addr;
|
||||
in_port_t port;
|
||||
struct sdp_sock *ssk = sdp_sk(so);
|
||||
|
||||
ssk = sdp_sk(so);
|
||||
SDP_RLOCK(ssk);
|
||||
port = ssk->fport;
|
||||
addr.s_addr = ssk->faddr;
|
||||
*(struct sockaddr_in *)sa = (struct sockaddr_in ){
|
||||
.sin_family = AF_INET,
|
||||
.sin_len = sizeof(struct sockaddr_in),
|
||||
.sin_addr.s_addr = ssk->faddr,
|
||||
.sin_port = ssk->fport,
|
||||
};
|
||||
SDP_RUNLOCK(ssk);
|
||||
|
||||
*nam = sdp_sockaddr(port, &addr);
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -185,20 +185,17 @@ int
|
|||
__rpc_socket2sockinfo(struct socket *so, struct __rpc_sockinfo *sip)
|
||||
{
|
||||
int type, proto;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
sa_family_t family;
|
||||
struct sockopt opt;
|
||||
int error;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
error = sosockaddr(so, (struct sockaddr *)&ss);
|
||||
if (error)
|
||||
return 0;
|
||||
|
||||
sip->si_alen = sa->sa_len;
|
||||
family = sa->sa_family;
|
||||
free(sa, M_SONAME);
|
||||
sip->si_alen = ss.ss_len;
|
||||
family = ss.ss_family;
|
||||
|
||||
opt.sopt_dir = SOPT_GET;
|
||||
opt.sopt_level = SOL_SOCKET;
|
||||
|
@ -698,35 +695,31 @@ __rpc_endconf(void *vhandle)
|
|||
int
|
||||
__rpc_sockisbound(struct socket *so)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
int error, bound;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
error = sosockaddr(so, (struct sockaddr *)&ss);
|
||||
if (error)
|
||||
return (0);
|
||||
|
||||
switch (sa->sa_family) {
|
||||
switch (ss.ss_family) {
|
||||
case AF_INET:
|
||||
bound = (((struct sockaddr_in *) sa)->sin_port != 0);
|
||||
bound = (((struct sockaddr_in *)&ss)->sin_port != 0);
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
bound = (((struct sockaddr_in6 *) sa)->sin6_port != 0);
|
||||
bound = (((struct sockaddr_in6 *)&ss)->sin6_port != 0);
|
||||
break;
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
/* XXX check this */
|
||||
bound = (((struct sockaddr_un *) sa)->sun_path[0] != '\0');
|
||||
bound = (((struct sockaddr_un *)&ss)->sun_path[0] != '\0');
|
||||
break;
|
||||
default:
|
||||
bound = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
free(sa, M_SONAME);
|
||||
|
||||
return bound;
|
||||
}
|
||||
|
||||
|
@ -779,8 +772,8 @@ clnt_call_private(
|
|||
int
|
||||
bindresvport(struct socket *so, struct sockaddr *sa)
|
||||
{
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
int old, error, af;
|
||||
bool_t freesa = FALSE;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
@ -791,12 +784,10 @@ bindresvport(struct socket *so, struct sockaddr *sa)
|
|||
socklen_t salen;
|
||||
|
||||
if (sa == NULL) {
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
sa = (struct sockaddr *)&ss;
|
||||
error = sosockaddr(so, sa);
|
||||
if (error)
|
||||
return (error);
|
||||
freesa = TRUE;
|
||||
af = sa->sa_family;
|
||||
salen = sa->sa_len;
|
||||
memset(sa, 0, sa->sa_len);
|
||||
|
@ -837,15 +828,14 @@ bindresvport(struct socket *so, struct sockaddr *sa)
|
|||
opt.sopt_val = &old;
|
||||
opt.sopt_valsize = sizeof(old);
|
||||
error = sogetopt(so, &opt);
|
||||
if (error) {
|
||||
goto out;
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
opt.sopt_dir = SOPT_SET;
|
||||
opt.sopt_val = &portlow;
|
||||
error = sosetopt(so, &opt);
|
||||
if (error)
|
||||
goto out;
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = sobind(so, sa, curthread);
|
||||
|
@ -857,9 +847,6 @@ bindresvport(struct socket *so, struct sockaddr *sa)
|
|||
sosetopt(so, &opt);
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (freesa)
|
||||
free(sa, M_SONAME);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,6 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
|
|||
{
|
||||
SVCXPRT *xprt;
|
||||
struct __rpc_sockinfo si;
|
||||
struct sockaddr* sa;
|
||||
int error;
|
||||
|
||||
if (jailed(curthread->td_ucred))
|
||||
|
@ -124,15 +123,11 @@ svc_dg_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
|
|||
xprt->xp_p2 = NULL;
|
||||
xprt->xp_ops = &svc_dg_ops;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
xprt->xp_ltaddr.ss_len = sizeof(xprt->xp_ltaddr);
|
||||
error = sosockaddr(so, (struct sockaddr *)&xprt->xp_ltaddr);
|
||||
if (error)
|
||||
goto freedata;
|
||||
|
||||
memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
|
||||
xprt_register(xprt);
|
||||
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
|
|
|
@ -206,19 +206,17 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
|
|||
size_t recvsize)
|
||||
{
|
||||
SVCXPRT *xprt;
|
||||
struct sockaddr* sa;
|
||||
int error;
|
||||
|
||||
SOCK_LOCK(so);
|
||||
if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) {
|
||||
struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
|
||||
|
||||
SOCK_UNLOCK(so);
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_peeraddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
error = sopeeraddr(so, (struct sockaddr *)&ss);
|
||||
if (error)
|
||||
return (NULL);
|
||||
xprt = svc_vc_create_conn(pool, so, sa);
|
||||
free(sa, M_SONAME);
|
||||
xprt = svc_vc_create_conn(pool, so, (struct sockaddr *)&ss);
|
||||
return (xprt);
|
||||
}
|
||||
SOCK_UNLOCK(so);
|
||||
|
@ -231,16 +229,12 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
|
|||
xprt->xp_p2 = NULL;
|
||||
xprt->xp_ops = &svc_vc_rendezvous_ops;
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
xprt->xp_ltaddr.ss_len = sizeof(xprt->xp_ltaddr);
|
||||
error = sosockaddr(so, (struct sockaddr *)&xprt->xp_ltaddr);
|
||||
if (error) {
|
||||
goto cleanup_svc_vc_create;
|
||||
}
|
||||
|
||||
memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
|
||||
xprt_register(xprt);
|
||||
|
||||
solisten(so, -1, curthread);
|
||||
|
@ -267,7 +261,6 @@ svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr)
|
|||
{
|
||||
SVCXPRT *xprt;
|
||||
struct cf_conn *cd;
|
||||
struct sockaddr* sa = NULL;
|
||||
struct sockopt opt;
|
||||
int one = 1;
|
||||
int error;
|
||||
|
@ -315,15 +308,11 @@ svc_vc_create_conn(SVCPOOL *pool, struct socket *so, struct sockaddr *raddr)
|
|||
|
||||
memcpy(&xprt->xp_rtaddr, raddr, raddr->sa_len);
|
||||
|
||||
CURVNET_SET(so->so_vnet);
|
||||
error = so->so_proto->pr_sockaddr(so, &sa);
|
||||
CURVNET_RESTORE();
|
||||
xprt->xp_ltaddr.ss_len = sizeof(xprt->xp_ltaddr);
|
||||
error = sosockaddr(so, (struct sockaddr *)&xprt->xp_ltaddr);
|
||||
if (error)
|
||||
goto cleanup_svc_vc_create;
|
||||
|
||||
memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
|
||||
xprt_register(xprt);
|
||||
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef int pr_control_t(struct socket *, unsigned long, void *,
|
|||
typedef void pr_detach_t(struct socket *);
|
||||
typedef int pr_disconnect_t(struct socket *);
|
||||
typedef int pr_listen_t(struct socket *, int, struct thread *);
|
||||
typedef int pr_peeraddr_t(struct socket *, struct sockaddr **);
|
||||
typedef int pr_peeraddr_t(struct socket *, struct sockaddr *);
|
||||
typedef int pr_rcvd_t(struct socket *, int);
|
||||
typedef int pr_rcvoob_t(struct socket *, struct mbuf *, int);
|
||||
typedef enum {
|
||||
|
@ -88,7 +88,7 @@ typedef int pr_ready_t(struct socket *, struct mbuf *, int);
|
|||
typedef int pr_sense_t(struct socket *, struct stat *);
|
||||
typedef int pr_shutdown_t(struct socket *);
|
||||
typedef int pr_flush_t(struct socket *, int);
|
||||
typedef int pr_sockaddr_t(struct socket *, struct sockaddr **);
|
||||
typedef int pr_sockaddr_t(struct socket *, struct sockaddr *);
|
||||
typedef int pr_sosend_t(struct socket *, struct sockaddr *, struct uio *,
|
||||
struct mbuf *, struct mbuf *, int, struct thread *);
|
||||
typedef int pr_soreceive_t(struct socket *, struct sockaddr **,
|
||||
|
|
|
@ -450,6 +450,8 @@ int getsock(struct thread *td, int fd, cap_rights_t *rightsp,
|
|||
struct file **fpp);
|
||||
void soabort(struct socket *so);
|
||||
int soaccept(struct socket *so, struct sockaddr *sa);
|
||||
int sopeeraddr(struct socket *so, struct sockaddr *sa);
|
||||
int sosockaddr(struct socket *so, struct sockaddr *sa);
|
||||
void soaio_enqueue(struct task *task);
|
||||
void soaio_rcv(void *context, int pending);
|
||||
void soaio_snd(void *context, int pending);
|
||||
|
|
|
@ -187,13 +187,11 @@ int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
|
|||
size_t *countp, enum uio_seg bufseg, int mode);
|
||||
int kern_getitimer(struct thread *, u_int, struct itimerval *);
|
||||
int kern_getppid(struct thread *);
|
||||
int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen);
|
||||
int kern_getpeername(struct thread *td, int fd, struct sockaddr *sa);
|
||||
int kern_getpriority(struct thread *td, int which, int who);
|
||||
int kern_getrusage(struct thread *td, int who, struct rusage *rup);
|
||||
int kern_getsid(struct thread *td, pid_t pid);
|
||||
int kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
|
||||
socklen_t *alen);
|
||||
int kern_getsockname(struct thread *td, int fd, struct sockaddr *sa);
|
||||
int kern_getsockopt(struct thread *td, int s, int level, int name,
|
||||
void *optval, enum uio_seg valseg, socklen_t *valsize);
|
||||
int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data);
|
||||
|
|
Loading…
Reference in a new issue