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:
Gleb Smirnoff 2023-11-30 08:30:55 -08:00
parent cfb1e92912
commit 0fac350c54
43 changed files with 420 additions and 698 deletions

View file

@ -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;

View file

@ -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);
}

View file

@ -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[] = {

View file

@ -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

View file

@ -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 *,

View file

@ -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);
}
}

View file

@ -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));

View file

@ -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);
}

View file

@ -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)
{

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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,

View file

@ -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);
}

View file

@ -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);
}
/*****************************************************************************
*****************************************************************************

View file

@ -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

View file

@ -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.

View file

@ -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);
}
/*****************************************************************************
*****************************************************************************

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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)
*/
/*

View file

@ -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 *
/*

View file

@ -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);
}

View file

@ -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 *);

View file

@ -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.
*/

View file

@ -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))

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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 = {

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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 **,

View file

@ -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);

View file

@ -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);