diff options
| author | Garrett D'Amore <garrett@damore.org> | 2020-11-01 22:05:35 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-11-08 17:50:24 -0800 |
| commit | fc6882305f0b5e06e58a0a25740f422d133015b5 (patch) | |
| tree | 714b1fa4656253c8731a8f3f0861c24715440f95 /src/platform | |
| parent | 4bf06d03f6ebead7f4e0603a2da3b1b891887878 (diff) | |
| download | nng-fc6882305f0b5e06e58a0a25740f422d133015b5.tar.gz nng-fc6882305f0b5e06e58a0a25740f422d133015b5.tar.bz2 nng-fc6882305f0b5e06e58a0a25740f422d133015b5.zip | |
fixes #1041 Abstract socket address for IPC
fixes #1326 Linux IPC could use fchmod
fixes #1327 getsockname on ipc may not work
This introduces an abstract:// style transport, which on Linux
results in using the abstract socket with the given name (not
including the leading NULL byte). A new NNG_AF_ABSTRACT is
provided. Auto bind abstract sockets are also supported.
While here we have inlined the aios for the POSIX ipc pipe
objects, eliminating at least one set of failure paths, and
have also performed various other cleanups.
A unix:// alias is available on POSIX systems, which acts just
like ipc:// (and is fact just an alias). This is supplied so
that in the future we can add support for AF_UNIX on Windows.
We've also absorbed the ipcperms test into the new ipc_test suite.
Finally we are now enforcing that IPC path names on Windows are
not over the maximum size, rather than just silently truncating
them.
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/posix/posix_impl.h | 2 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipc.h | 4 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipcconn.c | 21 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipcdial.c | 44 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipclisten.c | 163 | ||||
| -rw-r--r-- | src/platform/posix/posix_resolv_gai.c | 3 | ||||
| -rw-r--r-- | src/platform/posix/posix_sockaddr.c | 75 | ||||
| -rw-r--r-- | src/platform/posix/posix_tcpconn.c | 12 | ||||
| -rw-r--r-- | src/platform/posix/posix_tcpdial.c | 8 | ||||
| -rw-r--r-- | src/platform/posix/posix_tcplisten.c | 2 | ||||
| -rw-r--r-- | src/platform/posix/posix_udp.c | 7 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcdial.c | 3 | ||||
| -rw-r--r-- | src/platform/windows/win_ipclisten.c | 5 |
13 files changed, 255 insertions, 94 deletions
diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h index 2a6fd6a1..978afc01 100644 --- a/src/platform/posix/posix_impl.h +++ b/src/platform/posix/posix_impl.h @@ -37,7 +37,7 @@ #ifdef NNG_PLATFORM_POSIX_SOCKADDR #include <sys/socket.h> -extern int nni_posix_sockaddr2nn(nni_sockaddr *, const void *); +extern int nni_posix_sockaddr2nn(nni_sockaddr *, const void *, size_t); extern size_t nni_posix_nn2sockaddr(void *, const nni_sockaddr *); #endif diff --git a/src/platform/posix/posix_ipc.h b/src/platform/posix/posix_ipc.h index 894a5e96..2c2c9af7 100644 --- a/src/platform/posix/posix_ipc.h +++ b/src/platform/posix/posix_ipc.h @@ -29,6 +29,7 @@ struct nni_ipc_conn { nni_mtx mtx; nni_aio * dial_aio; nni_ipc_dialer *dialer; + nng_sockaddr sa; nni_reap_item reap; }; @@ -42,7 +43,8 @@ struct nni_ipc_dialer { nni_atomic_bool fini; }; -extern int nni_posix_ipc_alloc(nni_ipc_conn **, nni_ipc_dialer *); +extern int nni_posix_ipc_alloc( + nni_ipc_conn **, nni_sockaddr *, nni_ipc_dialer *); extern void nni_posix_ipc_init(nni_ipc_conn *, nni_posix_pfd *); extern void nni_posix_ipc_start(nni_ipc_conn *); extern void nni_posix_ipc_dialer_rele(nni_ipc_dialer *); diff --git a/src/platform/posix/posix_ipcconn.c b/src/platform/posix/posix_ipcconn.c index c5760e53..cbf2610e 100644 --- a/src/platform/posix/posix_ipcconn.c +++ b/src/platform/posix/posix_ipcconn.c @@ -385,7 +385,7 @@ ipc_peerid(ipc_conn *c, uint64_t *euid, uint64_t *egid, uint64_t *prid, *prid = (uint64_t) pid; } } -#endif // NNG_HAVE_LOCALPEERPID +#endif // NNG_HAVE_LOCALPEERPID return (0); #else if (fd < 0) { @@ -466,20 +466,8 @@ ipc_get_peer_pid(void *arg, void *buf, size_t *szp, nni_type t) static int ipc_get_addr(void *arg, void *buf, size_t *szp, nni_type t) { - ipc_conn * c = arg; - nni_sockaddr sa; - struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); - int fd = nni_posix_pfd_fd(c->pfd); - int rv; - - if (getsockname(fd, (void *) &ss, &sslen) != 0) { - return (nni_plat_errno(errno)); - } - if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) != 0) { - return (rv); - } - return (nni_copyout_sockaddr(&sa, buf, szp, t)); + ipc_conn *c = arg; + return (nni_copyout_sockaddr(&c->sa, buf, szp, t)); } void @@ -557,7 +545,7 @@ ipc_setx(void *arg, const char *name, const void *val, size_t sz, nni_type t) } int -nni_posix_ipc_alloc(nni_ipc_conn **cp, nni_ipc_dialer *d) +nni_posix_ipc_alloc(nni_ipc_conn **cp, nni_sockaddr *sa, nni_ipc_dialer *d) { ipc_conn *c; @@ -573,6 +561,7 @@ nni_posix_ipc_alloc(nni_ipc_conn **cp, nni_ipc_dialer *d) c->stream.s_recv = ipc_recv; c->stream.s_getx = ipc_getx; c->stream.s_setx = ipc_setx; + c->sa = *sa; nni_mtx_init(&c->mtx); nni_aio_list_init(&c->readq); diff --git a/src/platform/posix/posix_ipcdial.c b/src/platform/posix/posix_ipcdial.c index 65061767..b25f7340 100644 --- a/src/platform/posix/posix_ipcdial.c +++ b/src/platform/posix/posix_ipcdial.c @@ -178,7 +178,7 @@ ipc_dialer_dial(void *arg, nni_aio *aio) nni_atomic_inc64(&d->ref); - if ((rv = nni_posix_ipc_alloc(&c, d)) != 0) { + if ((rv = nni_posix_ipc_alloc(&c, &d->sa, d)) != 0) { (void) close(fd); nni_posix_ipc_dialer_rele(d); nni_aio_finish_error(aio, rv); @@ -263,20 +263,46 @@ int nni_ipc_dialer_alloc(nng_stream_dialer **dp, const nng_url *url) { ipc_dialer *d; + size_t len; - if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || - (strlen(url->u_path) == 0) || - (strlen(url->u_path) >= NNG_MAXADDRLEN)) { - return (NNG_EADDRINVAL); - } if ((d = NNI_ALLOC_STRUCT(d)) == NULL) { return (NNG_ENOMEM); } + + if ((strcmp(url->u_scheme, "ipc") == 0) || + (strcmp(url->u_scheme, "unix") == 0)) { + if ((url->u_path == NULL) || + ((len = strlen(url->u_path)) == 0) || + (len > NNG_MAXADDRLEN)) { + NNI_FREE_STRUCT(d); + return (NNG_EADDRINVAL); + } + d->sa.s_ipc.sa_family = NNG_AF_IPC; + nni_strlcpy(d->sa.s_ipc.sa_path, url->u_path, NNG_MAXADDRLEN); + +#ifdef NNG_HAVE_ABSTRACT_SOCKETS + } else if (strcmp(url->u_scheme, "abstract") == 0) { + + // path is url encoded. + len = nni_url_decode(d->sa.s_abstract.sa_name, url->u_path, + sizeof(d->sa.s_abstract.sa_name)); + if (len == (size_t) -1) { + NNI_FREE_STRUCT(d); + return (NNG_EADDRINVAL); + } + + d->sa.s_abstract.sa_family = NNG_AF_ABSTRACT; + d->sa.s_abstract.sa_len = len; +#endif + + } else { + NNI_FREE_STRUCT(d); + return (NNG_EADDRINVAL); + } + nni_mtx_init(&d->mtx); nni_aio_list_init(&d->connq); - d->closed = false; - d->sa.s_ipc.sa_family = NNG_AF_IPC; - strcpy(d->sa.s_ipc.sa_path, url->u_path); + d->closed = false; d->sd.sd_free = ipc_dialer_free; d->sd.sd_close = ipc_dialer_close; d->sd.sd_dial = ipc_dialer_dial; diff --git a/src/platform/posix/posix_ipclisten.c b/src/platform/posix/posix_ipclisten.c index 43febcfb..9c0b55db 100644 --- a/src/platform/posix/posix_ipclisten.c +++ b/src/platform/posix/posix_ipclisten.c @@ -124,7 +124,7 @@ ipc_listener_doaccept(ipc_listener *l) } } - if ((rv = nni_posix_ipc_alloc(&c, NULL)) != 0) { + if ((rv = nni_posix_ipc_alloc(&c, &l->sa, NULL)) != 0) { (void) close(newfd); nni_aio_list_remove(aio); nni_aio_finish_error(aio, rv); @@ -188,8 +188,12 @@ ipc_remove_stale(const char *path) struct sockaddr_un sa; size_t sz; + if (path == NULL) { + return (0); + } + sa.sun_family = AF_UNIX; - sz = sizeof(sa.sun_path); + sz = sizeof(sa.sun_path); if (nni_strlcpy(sa.sun_path, path, sz) >= sz) { return (NNG_EADDRINVAL); @@ -231,6 +235,11 @@ ipc_listener_set_perms(void *arg, const void *buf, size_t sz, nni_type t) if ((rv = nni_copyin_int(&mode, buf, sz, 0, S_IFMT, t)) != 0) { return (rv); } + if (l->sa.s_family == NNG_AF_ABSTRACT) { + // We ignore permissions on abstract sockets. + // They succeed, but have no effect. + return (0); + } if ((mode & S_IFMT) != 0) { return (NNG_EINVAL); } @@ -275,6 +284,23 @@ ipc_listener_setx( return (nni_setopt(ipc_listener_options, name, l, buf, sz, t)); } +#ifndef NNG_PLATFORM_LINUX +static int +ipc_listener_chmod(ipc_listener *l, const char *path) +{ + if (path == NULL) { + return (0); + } + if (l->perms == 0) { + return (0); + } + if (chmod(path, l->perms & ~S_IFMT) != 0) { + return (-1); + } + return (0); +} +#endif + int ipc_listener_listen(void *arg) { @@ -286,8 +312,7 @@ ipc_listener_listen(void *arg) nni_posix_pfd * pfd; char * path; - if (((len = nni_posix_nn2sockaddr(&ss, &l->sa)) == 0) || - (ss.ss_family != AF_UNIX)) { + if ((len = nni_posix_nn2sockaddr(&ss, &l->sa)) < sizeof(sa_family_t)) { return (NNG_EADDRINVAL); } @@ -300,9 +325,20 @@ ipc_listener_listen(void *arg) nni_mtx_unlock(&l->mtx); return (NNG_ECLOSED); } - path = nni_strdup(l->sa.s_ipc.sa_path); - if (path == NULL) { - return (NNG_ENOMEM); + + switch (l->sa.s_family) { + case NNG_AF_IPC: + if ((path = nni_strdup(l->sa.s_ipc.sa_path)) == NULL) { + nni_mtx_unlock(&l->mtx); + return (NNG_ENOMEM); + } + break; + case NNG_AF_ABSTRACT: + path = NULL; + break; + default: + nni_mtx_unlock(&l->mtx); + return (NNG_EADDRINVAL); } if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) { @@ -311,37 +347,69 @@ ipc_listener_listen(void *arg) nni_strfree(path); return (rv); } - - if ((rv = nni_posix_pfd_init(&pfd, fd)) != 0) { - nni_mtx_unlock(&l->mtx); - nni_strfree(path); - (void) close(fd); - return (rv); + // Linux supports fchmod on a socket, which will + // be race condition free. +#ifdef NNG_PLATFORM_LINUX + if ((l->perms != 0) && (path != NULL)) { + if (fchmod(fd, l->perms & ~S_IFMT) != 0) { + rv = nni_plat_errno(errno); + nni_mtx_unlock(&l->mtx); + (void) close(fd); + nni_strfree(path); + return (rv); + } } +#endif if ((rv = bind(fd, (struct sockaddr *) &ss, len)) != 0) { - if ((errno == EEXIST) || (errno == EADDRINUSE)) { + if ((l->sa.s_family == NNG_AF_IPC) && + ((errno == EEXIST) || (errno == EADDRINUSE))) { ipc_remove_stale(path); rv = bind(fd, (struct sockaddr *) &ss, len); } + if (rv != 0) { + nni_strfree(path); + path = NULL; + } } - if (rv != 0) { + if ((rv != 0) || +#ifndef NNG_PLATFORM_LINUX + // Linux uses fchmod instead (which is race free). + (ipc_listener_chmod(l, path) != 0) || +#endif + (listen(fd, 128) != 0)) { rv = nni_plat_errno(errno); + } + if ((rv != 0) || ((rv = nni_posix_pfd_init(&pfd, fd)) != 0)) { nni_mtx_unlock(&l->mtx); + (void) close(fd); + if (path != NULL) { + unlink(path); + } nni_strfree(path); - nni_posix_pfd_fini(pfd); return (rv); } - if (((l->perms != 0) && (chmod(path, l->perms & ~S_IFMT) != 0)) || - (listen(fd, 128) != 0)) { - rv = nni_plat_errno(errno); - (void) unlink(path); - nni_mtx_unlock(&l->mtx); - nni_strfree(path); - nni_posix_pfd_fini(pfd); - return (rv); +#ifdef NNG_HAVE_ABSTRACT_SOCKETS + // If the original address was for a system assigned value, + // then figure out what we got. This is analogous to TCP + // binding to port 0. + if ((l->sa.s_family == NNG_AF_ABSTRACT) && + (l->sa.s_abstract.sa_len == 0)) { + struct sockaddr_un *su = (void *) &ss; + len = sizeof(ss); + if ((getsockname(fd, (struct sockaddr *) &ss, &len) == 0) && + (len > sizeof(sa_family_t)) && + (len <= sizeof(l->sa.s_abstract.sa_name)) && + (su->sun_path[0] == '\0')) { + len -= sizeof(sa_family_t); + len--; // don't count the leading NUL. + l->sa.s_abstract.sa_len = len; + memcpy( + l->sa.s_abstract.sa_name, &su->sun_path[1], len); + } } +#endif nni_posix_pfd_set_cb(pfd, ipc_listener_cb, l); @@ -412,26 +480,49 @@ int nni_ipc_listener_alloc(nng_stream_listener **lp, const nng_url *url) { ipc_listener *l; - - if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || - (strlen(url->u_path) == 0) || - (strlen(url->u_path) >= NNG_MAXADDRLEN)) { - return (NNG_EADDRINVAL); - } + size_t len; if ((l = NNI_ALLOC_STRUCT(l)) == NULL) { return (NNG_ENOMEM); } + if ((strcmp(url->u_scheme, "ipc") == 0) || + (strcmp(url->u_scheme, "unix") == 0)) { + if ((url->u_path == NULL) || + ((len = strlen(url->u_path)) == 0) || + (len > NNG_MAXADDRLEN)) { + NNI_FREE_STRUCT(l); + return (NNG_EADDRINVAL); + } + l->sa.s_ipc.sa_family = NNG_AF_IPC; + nni_strlcpy(l->sa.s_ipc.sa_path, url->u_path, NNG_MAXADDRLEN); + +#ifdef NNG_HAVE_ABSTRACT_SOCKETS + } else if (strcmp(url->u_scheme, "abstract") == 0) { + // path is url encoded. + len = nni_url_decode(l->sa.s_abstract.sa_name, url->u_path, + sizeof(l->sa.s_abstract.sa_name)); + if (len == (size_t) -1) { + NNI_FREE_STRUCT(l); + return (NNG_EADDRINVAL); + } + + l->sa.s_abstract.sa_family = NNG_AF_ABSTRACT; + l->sa.s_abstract.sa_len = len; +#endif + + } else { + NNI_FREE_STRUCT(l); + return (NNG_EADDRINVAL); + } + nni_mtx_init(&l->mtx); nni_aio_list_init(&l->acceptq); - l->pfd = NULL; - l->closed = false; - l->started = false; - l->perms = 0; - l->sa.s_ipc.sa_family = NNG_AF_IPC; - strcpy(l->sa.s_ipc.sa_path, url->u_path); + l->pfd = NULL; + l->closed = false; + l->started = false; + l->perms = 0; l->sl.sl_free = ipc_listener_free; l->sl.sl_close = ipc_listener_close; l->sl.sl_listen = ipc_listener_listen; diff --git a/src/platform/posix/posix_resolv_gai.c b/src/platform/posix/posix_resolv_gai.c index 888cc9b7..36a0924e 100644 --- a/src/platform/posix/posix_resolv_gai.c +++ b/src/platform/posix/posix_resolv_gai.c @@ -419,7 +419,8 @@ parse_ip(const char *addr, nng_sockaddr *sa, bool want_port) rv = nni_plat_errno(rv); goto done; } - nni_posix_sockaddr2nn(sa, (void *) results->ai_addr); + nni_posix_sockaddr2nn( + sa, (void *) results->ai_addr, results->ai_addrlen); freeaddrinfo(results); done: diff --git a/src/platform/posix/posix_sockaddr.c b/src/platform/posix/posix_sockaddr.c index dc795cfe..a569132c 100644 --- a/src/platform/posix/posix_sockaddr.c +++ b/src/platform/posix/posix_sockaddr.c @@ -25,13 +25,14 @@ size_t nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na) { - struct sockaddr_in * sin; - struct sockaddr_in6 * sin6; - struct sockaddr_un * spath; - const nng_sockaddr_in * nsin; - const nng_sockaddr_in6 * nsin6; - const nng_sockaddr_path *nspath; - size_t sz; + struct sockaddr_in * sin; + struct sockaddr_in6 * sin6; + struct sockaddr_un * spath; + const nng_sockaddr_in * nsin; + const nng_sockaddr_in6 * nsin6; + const nng_sockaddr_path * nspath; + const nng_sockaddr_abstract *nsabs; + size_t sz; if ((sa == NULL) || (na == NULL)) { return (0); @@ -70,12 +71,33 @@ nni_posix_nn2sockaddr(void *sa, const nni_sockaddr *na) } spath->sun_family = PF_UNIX; return (sizeof(*spath)); + + case NNG_AF_ABSTRACT: + spath = (void *) sa; + nsabs = &na->s_abstract; + if (nsabs->sa_len >= sizeof (spath->sun_path)) { + return (0); + } + memset(spath, 0, sizeof(*spath)); + spath->sun_family = PF_UNIX; + spath->sun_path[0] = '\0'; // abstract starts with nul + + // We support auto-bind with an empty string. There is + // a subtle caveat here, which is that we cannot bind to + // the *empty* name. + if (nsabs->sa_len == 0) { + return (sizeof (sa_family_t)); // auto bind + } else { + memcpy(&spath->sun_path[1], nsabs->sa_name, + nsabs->sa_len); + return (sizeof(sa_family_t) + 1 + nsabs->sa_len); + } } return (0); } int -nni_posix_sockaddr2nn(nni_sockaddr *na, const void *sa) +nni_posix_sockaddr2nn(nni_sockaddr *na, const void *sa, size_t sz) { const struct sockaddr_in * sin; const struct sockaddr_in6 *sin6; @@ -83,12 +105,16 @@ nni_posix_sockaddr2nn(nni_sockaddr *na, const void *sa) nng_sockaddr_in * nsin; nng_sockaddr_in6 * nsin6; nng_sockaddr_path * nspath; + nng_sockaddr_abstract * nsabs; if ((na == NULL) || (sa == NULL)) { return (-1); } switch (((struct sockaddr *) sa)->sa_family) { case AF_INET: + if (sz < sizeof(*sin)) { + return (-1); + } sin = (void *) sa; nsin = &na->s_in; nsin->sa_family = NNG_AF_INET; @@ -96,6 +122,9 @@ nni_posix_sockaddr2nn(nni_sockaddr *na, const void *sa) nsin->sa_addr = sin->sin_addr.s_addr; break; case AF_INET6: + if (sz < sizeof(*sin6)) { + return (-1); + } sin6 = (void *) sa; nsin6 = &na->s_in6; nsin6->sa_family = NNG_AF_INET6; @@ -104,11 +133,31 @@ nni_posix_sockaddr2nn(nni_sockaddr *na, const void *sa) memcpy(nsin6->sa_addr, sin6->sin6_addr.s6_addr, 16); break; case AF_UNIX: - spath = (void *) sa; - nspath = &na->s_ipc; - nspath->sa_family = NNG_AF_IPC; - (void) snprintf(nspath->sa_path, sizeof(nspath->sa_path), "%s", - spath->sun_path); + // AF_UNIX can be NNG_AF_IPC, or NNG_AF_ABSTRACT. + spath = (void *) sa; + if ((sz < sizeof(sa_family_t)) || (sz > sizeof(*spath))) { + return (-1); + } + // Now we need to look more closely. + sz -= sizeof(sa_family_t); + if (sz == 0) { + // Unnamed socket. These will be treated using + // auto-bind if we actually listen to them, and + // it is impossible to connect them. + nsabs = &na->s_abstract; + nsabs->sa_family = NNG_AF_ABSTRACT; + nsabs->sa_len = 0; + } else if (spath->sun_path[0] == 0) { + nsabs = &na->s_abstract; + nsabs->sa_family = NNG_AF_ABSTRACT; + nsabs->sa_len = sz - 1; + memcpy(nsabs->sa_name, &spath->sun_path[1], sz - 1); + } else { + nspath = &na->s_ipc; + nspath->sa_family = NNG_AF_IPC; + nni_strlcpy(nspath->sa_path, spath->sun_path, + sizeof(nspath->sa_path)); + } break; default: // We should never see this - the OS should always be diff --git a/src/platform/posix/posix_tcpconn.c b/src/platform/posix/posix_tcpconn.c index 2a209984..3c8c3715 100644 --- a/src/platform/posix/posix_tcpconn.c +++ b/src/platform/posix/posix_tcpconn.c @@ -335,15 +335,15 @@ tcp_get_peername(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn * c = arg; struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); + socklen_t len = sizeof(ss); int fd = nni_posix_pfd_fd(c->pfd); int rv; nng_sockaddr sa; - if (getpeername(fd, (void *) &ss, &sslen) != 0) { + if (getpeername(fd, (void *) &ss, &len) != 0) { return (nni_plat_errno(errno)); } - if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) == 0) { + if ((rv = nni_posix_sockaddr2nn(&sa, &ss, len)) == 0) { rv = nni_copyout_sockaddr(&sa, buf, szp, t); } return (rv); @@ -354,15 +354,15 @@ tcp_get_sockname(void *arg, void *buf, size_t *szp, nni_type t) { nni_tcp_conn * c = arg; struct sockaddr_storage ss; - socklen_t sslen = sizeof(ss); + socklen_t len = sizeof(ss); int fd = nni_posix_pfd_fd(c->pfd); int rv; nng_sockaddr sa; - if (getsockname(fd, (void *) &ss, &sslen) != 0) { + if (getsockname(fd, (void *) &ss, &len) != 0) { return (nni_plat_errno(errno)); } - if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) == 0) { + if ((rv = nni_posix_sockaddr2nn(&sa, &ss, len)) == 0) { rv = nni_copyout_sockaddr(&sa, buf, szp, t); } return (rv); diff --git a/src/platform/posix/posix_tcpdial.c b/src/platform/posix/posix_tcpdial.c index 9b3a91f5..767717af 100644 --- a/src/platform/posix/posix_tcpdial.c +++ b/src/platform/posix/posix_tcpdial.c @@ -321,7 +321,7 @@ tcp_dialer_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t) nng_sockaddr sa; nni_mtx_lock(&d->mtx); - if (nni_posix_sockaddr2nn(&sa, &d->src) != 0) { + if (nni_posix_sockaddr2nn(&sa, &d->src, d->srclen) != 0) { sa.s_family = NNG_AF_UNSPEC; } nni_mtx_unlock(&d->mtx); @@ -336,13 +336,13 @@ tcp_dialer_set_locaddr(void *arg, const void *buf, size_t sz, nni_type t) struct sockaddr_storage ss; struct sockaddr_in * sin; struct sockaddr_in6 * sin6; - size_t sslen; + size_t len; int rv; if ((rv = nni_copyin_sockaddr(&sa, buf, sz, t)) != 0) { return (rv); } - if ((sslen = nni_posix_nn2sockaddr(&ss, &sa)) == 0) { + if ((len = nni_posix_nn2sockaddr(&ss, &sa)) == 0) { return (NNG_EADDRINVAL); } // Ensure we are either IPv4 or IPv6, and port is not set. (We @@ -370,7 +370,7 @@ tcp_dialer_set_locaddr(void *arg, const void *buf, size_t sz, nni_type t) return (NNG_ECLOSED); } d->src = ss; - d->srclen = sslen; + d->srclen = len; nni_mtx_unlock(&d->mtx); } return (0); diff --git a/src/platform/posix/posix_tcplisten.c b/src/platform/posix/posix_tcplisten.c index a463a198..3a2ea62b 100644 --- a/src/platform/posix/posix_tcplisten.c +++ b/src/platform/posix/posix_tcplisten.c @@ -333,7 +333,7 @@ tcp_listener_get_locaddr(void *arg, void *buf, size_t *szp, nni_type t) socklen_t len = sizeof(ss); (void) getsockname( nni_posix_pfd_fd(l->pfd), (void *) &ss, &len); - (void) nni_posix_sockaddr2nn(&sa, &ss); + (void) nni_posix_sockaddr2nn(&sa, &ss, len); } else { sa.s_family = NNG_AF_UNSPEC; } diff --git a/src/platform/posix/posix_udp.c b/src/platform/posix/posix_udp.c index b8939d68..735953fa 100644 --- a/src/platform/posix/posix_udp.c +++ b/src/platform/posix/posix_udp.c @@ -1,5 +1,5 @@ // -// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a @@ -91,7 +91,8 @@ nni_posix_udp_dorecv(nni_plat_udp *udp) // We need to store the address information. // It is incumbent on the AIO submitter to supply // storage for the address. - nni_posix_sockaddr2nn(sa, (void *) &ss); + nni_posix_sockaddr2nn( + sa, (void *) &ss, hdr.msg_namelen); } nni_list_remove(q, aio); nni_aio_finish(aio, rv, cnt); @@ -319,7 +320,7 @@ nni_plat_udp_sockname(nni_plat_udp *udp, nni_sockaddr *sa) if (getsockname(udp->udp_fd, (struct sockaddr *) &ss, &sz) < 0) { return (nni_plat_errno(errno)); } - return (nni_posix_sockaddr2nn(sa, &ss)); + return (nni_posix_sockaddr2nn(sa, &ss, sz)); } #endif // NNG_PLATFORM_POSIX diff --git a/src/platform/windows/win_ipcdial.c b/src/platform/windows/win_ipcdial.c index 65d1b544..c210b7be 100644 --- a/src/platform/windows/win_ipcdial.c +++ b/src/platform/windows/win_ipcdial.c @@ -228,7 +228,8 @@ nni_ipc_dialer_alloc(nng_stream_dialer **dp, const nng_url *url) int rv; if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || - (strlen(url->u_path) == 0)) { + (strlen(url->u_path) == 0)|| + (strlen(url->u_path) >= NNG_MAXADDRLEN)) { return (NNG_EADDRINVAL); } if ((d = NNI_ALLOC_STRUCT(d)) == NULL) { diff --git a/src/platform/windows/win_ipclisten.c b/src/platform/windows/win_ipclisten.c index a3922d06..65a7a8d7 100644 --- a/src/platform/windows/win_ipclisten.c +++ b/src/platform/windows/win_ipclisten.c @@ -1,5 +1,5 @@ // -// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // Copyright 2019 Devolutions <info@devolutions.net> // @@ -328,7 +328,8 @@ nni_ipc_listener_alloc(nng_stream_listener **lp, const nng_url *url) int rv; if ((strcmp(url->u_scheme, "ipc") != 0) || (url->u_path == NULL) || - (strlen(url->u_path) == 0)) { + (strlen(url->u_path) == 0) || + (strlen(url->u_path) >= NNG_MAXADDRLEN)) { return (NNG_EADDRINVAL); } if ((l = NNI_ALLOC_STRUCT(l)) == NULL) { |
