aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2023-12-29 15:35:43 -0800
committerGarrett D'Amore <garrett@damore.org>2023-12-29 15:35:43 -0800
commit25bde0dcefca6da42d4168f54692204c83fe2ba4 (patch)
tree750711fa338e573c3d15b5f55b5cdcdb6e587176
parentfeb51d0931c30f58c87caafaf24ed345d27b324b (diff)
downloadnng-25bde0dcefca6da42d4168f54692204c83fe2ba4.tar.gz
nng-25bde0dcefca6da42d4168f54692204c83fe2ba4.tar.bz2
nng-25bde0dcefca6da42d4168f54692204c83fe2ba4.zip
ipc: refactor get peerid support to use common POSIX code
This eliminates some code. A test is added as well, so this should help with coverage.
-rw-r--r--src/platform/posix/posix_ipcconn.c119
-rw-r--r--src/sp/transport/ipc/ipc_test.c55
2 files changed, 69 insertions, 105 deletions
diff --git a/src/platform/posix/posix_ipcconn.c b/src/platform/posix/posix_ipcconn.c
index 04eddd5f..7f979a0a 100644
--- a/src/platform/posix/posix_ipcconn.c
+++ b/src/platform/posix/posix_ipcconn.c
@@ -1,5 +1,5 @@
//
-// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2023 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2019 Devolutions <info@devolutions.net>
//
@@ -10,7 +10,7 @@
//
#include "core/nng_impl.h"
-
+#include "platform/posix/posix_peerid.h"
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
@@ -19,24 +19,11 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
-#if defined(NNG_HAVE_GETPEERUCRED)
-#include <ucred.h>
-#elif defined(NNG_HAVE_LOCALPEERCRED) || defined(NNG_HAVE_SOCKPEERCRED)
-#include <sys/ucred.h>
-#endif
-#if defined(NNG_HAVE_GETPEEREID)
-#include <sys/types.h>
-#include <unistd.h>
-#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
-#ifndef SOL_LOCAL
-#define SOL_LOCAL 0
-#endif
-
#include "posix_ipc.h"
typedef struct nni_ipc_conn ipc_conn;
@@ -56,7 +43,7 @@ ipc_dowrite(ipc_conn *c)
int n;
int niov;
unsigned naiov;
- nni_iov * aiov;
+ nni_iov *aiov;
struct msghdr hdr;
struct iovec iovec[16];
@@ -125,7 +112,7 @@ ipc_doread(ipc_conn *c)
int n;
int niov;
unsigned naiov;
- nni_iov * aiov;
+ nni_iov *aiov;
struct iovec iovec[16];
nni_aio_get_iov(aio, &naiov, &aiov);
@@ -157,7 +144,7 @@ ipc_doread(ipc_conn *c)
}
if (n == 0) {
- // No bytes indicates a closed descriptor.
+ // Zero indicates a closed descriptor.
// This implicitly completes this (all!) aio.
nni_aio_list_remove(aio);
nni_aio_finish_error(aio, NNG_ECONNSHUT);
@@ -179,7 +166,7 @@ static void
ipc_error(void *arg, int err)
{
ipc_conn *c = arg;
- nni_aio * aio;
+ nni_aio *aio;
nni_mtx_lock(&c->mtx);
while (((aio = nni_list_first(&c->readq)) != NULL) ||
@@ -318,88 +305,6 @@ ipc_recv(void *arg, nni_aio *aio)
}
static int
-ipc_peerid(ipc_conn *c, uint64_t *euid, uint64_t *egid, uint64_t *prid,
- uint64_t *znid)
-{
- int fd = nni_posix_pfd_fd(c->pfd);
-#if defined(NNG_HAVE_GETPEEREID) && !defined(NNG_HAVE_LOCALPEERCRED)
- uid_t uid;
- gid_t gid;
-
- if (getpeereid(fd, &uid, &gid) != 0) {
- return (nni_plat_errno(errno));
- }
- *euid = uid;
- *egid = gid;
- *prid = (uint64_t) -1;
- *znid = (uint64_t) -1;
- return (0);
-#elif defined(NNG_HAVE_GETPEERUCRED)
- ucred_t *ucp = NULL;
- if (getpeerucred(fd, &ucp) != 0) {
- return (nni_plat_errno(errno));
- }
- *euid = ucred_geteuid(ucp);
- *egid = ucred_getegid(ucp);
- *prid = ucred_getpid(ucp);
- *znid = ucred_getzoneid(ucp);
- ucred_free(ucp);
- return (0);
-#elif defined(NNG_HAVE_SOCKPEERCRED)
- struct sockpeercred uc;
- socklen_t len = sizeof(uc);
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &uc, &len) != 0) {
- return (nni_plat_errno(errno));
- }
- *euid = uc.uid;
- *egid = uc.gid;
- *prid = uc.pid;
- *znid = (uint64_t) -1;
- return (0);
-#elif defined(NNG_HAVE_SOPEERCRED)
- struct ucred uc;
- socklen_t len = sizeof(uc);
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &uc, &len) != 0) {
- return (nni_plat_errno(errno));
- }
- *euid = uc.uid;
- *egid = uc.gid;
- *prid = uc.pid;
- *znid = (uint64_t) -1;
- return (0);
-#elif defined(NNG_HAVE_LOCALPEERCRED)
- struct xucred xu;
- socklen_t len = sizeof(xu);
- if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERCRED, &xu, &len) != 0) {
- return (nni_plat_errno(errno));
- }
- *euid = xu.cr_uid;
- *egid = xu.cr_gid;
- *prid = (uint64_t) -1;
- *znid = (uint64_t) -1;
-#if defined(NNG_HAVE_LOCALPEERPID) // documented on macOS since 10.8
- {
- pid_t pid;
- if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &pid, &len) ==
- 0) {
- *prid = (uint64_t) pid;
- }
- }
-#endif // NNG_HAVE_LOCALPEERPID
- return (0);
-#else
- if (fd < 0) {
- return (NNG_ECLOSED);
- }
- NNI_ARG_UNUSED(euid);
- NNI_ARG_UNUSED(egid);
- NNI_ARG_UNUSED(prid);
- NNI_ARG_UNUSED(znid);
- return (NNG_ENOTSUP);
-#endif
-}
-
-static int
ipc_get_peer_uid(void *arg, void *buf, size_t *szp, nni_type t)
{
ipc_conn *c = arg;
@@ -407,7 +312,8 @@ ipc_get_peer_uid(void *arg, void *buf, size_t *szp, nni_type t)
uint64_t ignore;
uint64_t id = 0;
- if ((rv = ipc_peerid(c, &id, &ignore, &ignore, &ignore)) != 0) {
+ if ((rv = nni_posix_peerid(nni_posix_pfd_fd(c->pfd), &id, &ignore,
+ &ignore, &ignore)) != 0) {
return (rv);
}
return (nni_copyout_u64(id, buf, szp, t));
@@ -421,7 +327,8 @@ ipc_get_peer_gid(void *arg, void *buf, size_t *szp, nni_type t)
uint64_t ignore;
uint64_t id = 0;
- if ((rv = ipc_peerid(c, &ignore, &id, &ignore, &ignore)) != 0) {
+ if ((rv = nni_posix_peerid(nni_posix_pfd_fd(c->pfd), &ignore, &id,
+ &ignore, &ignore)) != 0) {
return (rv);
}
return (nni_copyout_u64(id, buf, szp, t));
@@ -435,7 +342,8 @@ ipc_get_peer_zoneid(void *arg, void *buf, size_t *szp, nni_type t)
uint64_t ignore;
uint64_t id = 0;
- if ((rv = ipc_peerid(c, &ignore, &ignore, &ignore, &id)) != 0) {
+ if ((rv = nni_posix_peerid(nni_posix_pfd_fd(c->pfd), &ignore, &ignore,
+ &ignore, &id)) != 0) {
return (rv);
}
if (id == (uint64_t) -1) {
@@ -453,7 +361,8 @@ ipc_get_peer_pid(void *arg, void *buf, size_t *szp, nni_type t)
uint64_t ignore;
uint64_t id = 0;
- if ((rv = ipc_peerid(c, &ignore, &ignore, &id, &ignore)) != 0) {
+ if ((rv = nni_posix_peerid(nni_posix_pfd_fd(c->pfd), &ignore, &ignore,
+ &id, &ignore)) != 0) {
return (rv);
}
if (id == (uint64_t) -1) {
diff --git a/src/sp/transport/ipc/ipc_test.c b/src/sp/transport/ipc/ipc_test.c
index 2fb4afa3..b39aa937 100644
--- a/src/sp/transport/ipc/ipc_test.c
+++ b/src/sp/transport/ipc/ipc_test.c
@@ -379,6 +379,60 @@ test_unix_alias(void)
#endif
}
+void
+test_ipc_pipe_peer(void)
+{
+#ifdef NNG_PLATFORM_POSIX
+ // this test verifies that closing a socket peer
+ // during negotiation is ok.
+ nng_socket s0, s1;
+ nng_msg *msg;
+ nng_pipe p;
+ uint64_t id;
+ char *addr;
+
+ NUTS_ADDR(addr, "ipc");
+ NUTS_OPEN(s0);
+ NUTS_PASS(nng_listen(s0, addr, NULL, 0));
+ NUTS_OPEN(s1);
+ NUTS_PASS(nng_dial(s1, addr, NULL, 0));
+
+ NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_SENDTIMEO, 1000));
+ NUTS_PASS(nng_socket_set_ms(s0, NNG_OPT_RECVTIMEO, 1000));
+ NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_SENDTIMEO, 1000));
+ NUTS_PASS(nng_socket_set_ms(s1, NNG_OPT_RECVTIMEO, 1000));
+
+ NUTS_SEND(s0, "something");
+ NUTS_PASS(nng_recvmsg(s1, &msg, 0));
+ p = nng_msg_get_pipe(msg);
+ NUTS_ASSERT(nng_pipe_id(p) != -1);
+#if defined(NNG_PLATFORM_DARWIN) || defined(NNG_PLATFORM_LINUX)
+ NUTS_PASS(nng_pipe_get_uint64(p, NNG_OPT_PEER_PID, &id));
+ NUTS_ASSERT(id == (uint64_t) getpid());
+#endif
+#if defined(NNG_PLATFORM_DARWIN) || defined(NNG_PLATFORM_LINUX)
+ NUTS_PASS(nng_pipe_get_uint64(p, NNG_OPT_PEER_UID, &id));
+ NUTS_ASSERT(id == (uint64_t) getuid());
+#endif
+#if defined(NNG_PLATFORM_DARWIN) || defined(NNG_PLATFORM_LINUX)
+ NUTS_PASS(nng_pipe_get_uint64(p, NNG_OPT_PEER_GID, &id));
+ NUTS_ASSERT(id == (uint64_t) getgid());
+#endif
+#if defined(NNG_PLATFORM_SUNOS)
+ NUTS_PASS(nng_pipe_get_uint64(p, NNG_OPT_PEER_ZONEID, &id));
+ NUTS_ASSERT(id == (uint64_t) getzoneid());
+#else
+ NUTS_FAIL(
+ nng_pipe_get_uint64(p, NNG_OPT_PEER_ZONEID, &id), NNG_ENOTSUP);
+#endif
+
+ nng_msg_free(msg);
+ NUTS_CLOSE(s0);
+ NUTS_CLOSE(s1);
+#endif // NNG_PLATFORM_POSIX
+}
+
+
TEST_LIST = {
{ "ipc path too long", test_path_too_long },
{ "ipc dialer perms", test_ipc_dialer_perms },
@@ -391,5 +445,6 @@ TEST_LIST = {
{ "ipc abstract name too long", test_abstract_too_long },
{ "ipc abstract embedded null", test_abstract_null },
{ "ipc unix alias", test_unix_alias },
+ { "ipc peer id", test_ipc_pipe_peer },
{ NULL, NULL },
}; \ No newline at end of file