Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gdamore/ipc peer tweaks #1747

Merged
merged 4 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 14 additions & 105 deletions src/platform/posix/posix_ipcconn.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2020 Staysail Systems, Inc. <[email protected]>
// Copyright 2023 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
// Copyright 2019 Devolutions <[email protected]>
//
Expand All @@ -10,7 +10,7 @@
//

#include "core/nng_impl.h"

#include "platform/posix/posix_peerid.h"
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
Expand All @@ -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;
Expand All @@ -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];

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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) ||
Expand Down Expand Up @@ -317,88 +304,6 @@ ipc_recv(void *arg, nni_aio *aio)
nni_mtx_unlock(&c->mtx);
}

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)
{
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
10 changes: 0 additions & 10 deletions src/sp/transport/ipc/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,18 +953,8 @@ ipc_ep_set_recv_max_sz(void *arg, const void *v, size_t sz, nni_type t)
int rv;
if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {

ipc_pipe *p;
nni_mtx_lock(&ep->mtx);
ep->rcv_max = val;
NNI_LIST_FOREACH (&ep->wait_pipes, p) {
p->rcv_max = val;
}
NNI_LIST_FOREACH (&ep->neg_pipes, p) {
p->rcv_max = val;
}
NNI_LIST_FOREACH (&ep->busy_pipes, p) {
p->rcv_max = val;
}
nni_mtx_unlock(&ep->mtx);
#ifdef NNG_ENABLE_STATS
nni_stat_set_value(&ep->st_rcv_max, val);
Expand Down
55 changes: 55 additions & 0 deletions src/sp/transport/ipc/ipc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand All @@ -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 },
};
10 changes: 0 additions & 10 deletions src/sp/transport/tcp/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,18 +1065,8 @@ tcptran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
size_t val;
int rv;
if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {
tcptran_pipe *p;
nni_mtx_lock(&ep->mtx);
ep->rcvmax = val;
NNI_LIST_FOREACH (&ep->waitpipes, p) {
p->rcvmax = val;
}
NNI_LIST_FOREACH (&ep->negopipes, p) {
p->rcvmax = val;
}
NNI_LIST_FOREACH (&ep->busypipes, p) {
p->rcvmax = val;
}
nni_mtx_unlock(&ep->mtx);
#ifdef NNG_ENABLE_STATS
nni_stat_set_value(&ep->st_rcv_max, val);
Expand Down
10 changes: 0 additions & 10 deletions src/sp/transport/tls/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,18 +1086,8 @@ tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_type t)
size_t val;
int rv;
if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {
tlstran_pipe *p;
nni_mtx_lock(&ep->mtx);
ep->rcvmax = val;
NNI_LIST_FOREACH (&ep->waitpipes, p) {
p->rcvmax = val;
}
NNI_LIST_FOREACH (&ep->negopipes, p) {
p->rcvmax = val;
}
NNI_LIST_FOREACH (&ep->busypipes, p) {
p->rcvmax = val;
}
nni_mtx_unlock(&ep->mtx);
#ifdef NNG_ENABLE_STATS
nni_stat_set_value(&ep->st_rcv_max, val);
Expand Down
2 changes: 1 addition & 1 deletion tests/multistress.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,6 @@ Main({
for (i = 0; i < ncases; i++) {
nng_aio_stop(cases[i].woke);
}
nng_closeall();

Test("MultiProtocol/Transport Stress", {
Convey("All tests worked", {
Expand Down Expand Up @@ -853,4 +852,5 @@ Main({
});

free(cases);
nng_fini();
})
2 changes: 1 addition & 1 deletion tests/reqstress.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ Main({
nng_aio_stop(cases[i].time_aio);
}
nng_msleep(100);
nng_closeall();

Test("Req/Rep Stress", {
Convey("All tests worked", {
Expand All @@ -337,4 +336,5 @@ Main({
});

free(cases);
nng_fini();
})
Loading