diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/platform.h | 15 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipcconn.c | 93 | ||||
| -rw-r--r-- | src/platform/windows/win_impl.h | 4 | ||||
| -rw-r--r-- | src/platform/windows/win_ipc.h | 38 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcconn.c | 48 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcdial.c | 17 | ||||
| -rw-r--r-- | src/platform/windows/win_ipclisten.c | 13 | ||||
| -rw-r--r-- | src/platform/windows/win_sockaddr.c | 5 | ||||
| -rw-r--r-- | src/supplemental/ipc/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | src/supplemental/ipc/ipc.c | 136 | ||||
| -rw-r--r-- | src/supplemental/util/options.c | 4 |
12 files changed, 341 insertions, 49 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0380a0f..c31539c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -183,6 +183,7 @@ add_subdirectory(transport/zerotier) add_subdirectory(supplemental/base64) add_subdirectory(supplemental/http) +add_subdirectory(supplemental/ipc) add_subdirectory(supplemental/sha1) add_subdirectory(supplemental/tcp) add_subdirectory(supplemental/tls) diff --git a/src/core/platform.h b/src/core/platform.h index 0a0709d1..2b7eb9f1 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -1,6 +1,7 @@ // // Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <infos@devolutions.net> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -375,6 +376,20 @@ extern int nni_ipc_conn_get_peer_pid(nni_ipc_conn *, uint64_t *); // NB: Only illumos & SunOS systems have the notion of "zones". extern int nni_ipc_conn_get_peer_zoneid(nni_ipc_conn *, uint64_t *); +// nni_ipc_conn_setopt is like setsockopt, but uses string names. These +// are the same names from the IPC transport, generally. There are no +// options that are generally settable on an IPC connection. +// NNG_OPT_REMADDR, NNG_OPT_LOCADDR, NNG_OPT_IPC_PERMISSIONS, +// NNG_OPT_ +extern int nni_ipc_conn_setopt( + nni_ipc_conn *, const char *, const void *, size_t); + +// nni_ipc_conn_getopt is like getsockopt, but uses string names. +// We support NNG_OPT_REMADDR and NNG_OPT_LOCADDR (with argument type +// nng_sockaddr), and on some platforms NNG_OPT_IPC_PEER_[UID,GID,ZONEID] +// (with type uint64_t.) +extern int nni_ipc_conn_getopt(nni_ipc_conn *, const char *, void *, size_t *); + // nni_ipc_dialer_init creates a new dialer object. extern int nni_ipc_dialer_init(nni_ipc_dialer **); diff --git a/src/platform/posix/posix_ipcconn.c b/src/platform/posix/posix_ipcconn.c index 0dae8bae..595ebe62 100644 --- a/src/platform/posix/posix_ipcconn.c +++ b/src/platform/posix/posix_ipcconn.c @@ -1,6 +1,7 @@ // // Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <infos@devolutions.net> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -10,8 +11,6 @@ #include "core/nng_impl.h" -#ifdef NNG_PLATFORM_POSIX - #include <errno.h> #include <fcntl.h> #include <poll.h> @@ -40,6 +39,8 @@ #include "posix_ipc.h" +#include <nng/transport/ipc/ipc.h> + static void ipc_conn_dowrite(nni_ipc_conn *c) { @@ -464,6 +465,19 @@ nni_ipc_conn_get_peer_pid(nni_ipc_conn *c, uint64_t *pid) } int +nni_ipc_conn_sockname(nni_ipc_conn *c, nni_sockaddr *sa) +{ + struct sockaddr_storage ss; + socklen_t sslen = sizeof(ss); + int fd = nni_posix_pfd_fd(c->pfd); + + if (getsockname(fd, (void *) &ss, &sslen) != 0) { + return (nni_plat_errno(errno)); + } + return (nni_posix_sockaddr2nn(sa, &ss)); +} + +int nni_posix_ipc_conn_init(nni_ipc_conn **cp, nni_posix_pfd *pfd) { nni_ipc_conn *c; @@ -502,4 +516,77 @@ nni_ipc_conn_fini(nni_ipc_conn *c) NNI_FREE_STRUCT(c); } -#endif // NNG_PLATFORM_POSIX +int +nni_ipc_conn_setopt( + nni_ipc_conn *c, const char *name, const void *val, size_t sz) +{ + NNI_ARG_UNUSED(c); + NNI_ARG_UNUSED(val); + NNI_ARG_UNUSED(sz); + if ((strcmp(name, NNG_OPT_LOCADDR) == 0) || + (strcmp(name, NNG_OPT_REMADDR) == 0) || + (strcmp(name, NNG_OPT_IPC_PEER_PID) == 0) || + (strcmp(name, NNG_OPT_IPC_PEER_UID) == 0) || + (strcmp(name, NNG_OPT_IPC_PEER_GID) == 0) || + (strcmp(name, NNG_OPT_IPC_PEER_ZONEID) == 0)) { + return (NNG_EREADONLY); + } + return (NNG_ENOTSUP); +} + +int +nni_ipc_conn_getopt(nni_ipc_conn *c, const char *name, void *val, size_t *szp) +{ + int rv; + uint64_t *idp = val; + + if ((strcmp(name, NNG_OPT_LOCADDR) == 0) || + (strcmp(name, NNG_OPT_REMADDR) == 0)) { + nng_sockaddr *sa = val; + if (*szp < sizeof(*sa)) { + return (NNG_EINVAL); + } + + if ((rv = nni_ipc_conn_sockname(c, sa)) == 0) { + *szp = sizeof(*sa); + } + return (rv); + } + if (strcmp(name, NNG_OPT_IPC_PEER_PID) == 0) { + if (*szp < sizeof(*idp)) { + return (NNG_EINVAL); + } + if ((rv = nni_ipc_conn_get_peer_pid(c, idp)) == 0) { + *szp = sizeof(*idp); + } + return (rv); + } + if (strcmp(name, NNG_OPT_IPC_PEER_UID) == 0) { + if (*szp < sizeof(*idp)) { + return (NNG_EINVAL); + } + if ((rv = nni_ipc_conn_get_peer_uid(c, idp)) == 0) { + *szp = sizeof(*idp); + } + return (rv); + } + if (strcmp(name, NNG_OPT_IPC_PEER_GID) == 0) { + if (*szp < sizeof(*idp)) { + return (NNG_EINVAL); + } + if ((rv = nni_ipc_conn_get_peer_gid(c, idp)) == 0) { + *szp = sizeof(*idp); + } + return (rv); + } + if (strcmp(name, NNG_OPT_IPC_PEER_ZONEID) == 0) { + if (*szp < sizeof(*idp)) { + return (NNG_EINVAL); + } + if ((rv = nni_ipc_conn_get_peer_zoneid(c, idp)) == 0) { + *szp = sizeof(*idp); + } + return (rv); + } + return (NNG_ENOTSUP); +} diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h index 462e1707..fd4c9343 100644 --- a/src/platform/windows/win_impl.h +++ b/src/platform/windows/win_impl.h @@ -11,8 +11,6 @@ #ifndef PLATFORM_WIN_IMPL_H #define PLATFORM_WIN_IMPL_H -#ifdef NNG_PLATFORM_WINDOWS - #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -106,6 +104,4 @@ extern int nni_win_nn2sockaddr(SOCKADDR_STORAGE *, const nni_sockaddr *); #define NNG_PLATFORM_DIR_SEP "\\" -#endif // NNG_PLATFORM_WINDOWS - #endif // PLATFORM_WIN_IMPL_H diff --git a/src/platform/windows/win_ipc.h b/src/platform/windows/win_ipc.h index 51ce5548..9a4e245a 100644 --- a/src/platform/windows/win_ipc.h +++ b/src/platform/windows/win_ipc.h @@ -1,6 +1,7 @@ // // Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <infos@devolutions.net> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -14,26 +15,27 @@ // This header file is private to the IPC (named pipes) support for Windows. #include "core/nng_impl.h" +#include "win_impl.h" -#ifdef NNG_PLATFORM_WINDOWS +#define IPC_PIPE_PREFIX "\\\\.\\pipe\\" struct nni_ipc_conn { - HANDLE f; - nni_win_io recv_io; - nni_win_io send_io; - nni_win_io conn_io; - nni_list recv_aios; - nni_list send_aios; - nni_aio * conn_aio; - nni_ipc_dialer * dialer; - nni_ipc_listener *listener; - int recv_rv; - int send_rv; - int conn_rv; - bool closed; - nni_mtx mtx; - nni_cv cv; - nni_reap_item reap; + HANDLE f; + nni_win_io recv_io; + nni_win_io send_io; + nni_win_io conn_io; + nni_list recv_aios; + nni_list send_aios; + nni_aio * conn_aio; + nng_sockaddr sa; + bool dialer; + int recv_rv; + int send_rv; + int conn_rv; + bool closed; + nni_mtx mtx; + nni_cv cv; + nni_reap_item reap; }; struct nni_ipc_dialer { @@ -57,6 +59,4 @@ struct nni_ipc_listener { extern int nni_win_ipc_conn_init(nni_ipc_conn **, HANDLE); -#endif // NNG_PLATFORM_WINDOWS - #endif // NNG_PLATFORM_WIN_WINIPC_H diff --git a/src/platform/windows/win_ipcconn.c b/src/platform/windows/win_ipcconn.c index d4e7f5ac..107ffb9d 100644 --- a/src/platform/windows/win_ipcconn.c +++ b/src/platform/windows/win_ipcconn.c @@ -1,6 +1,7 @@ // // Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <infos@devolutions.net> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -10,12 +11,12 @@ #include "core/nng_impl.h" -#ifdef NNG_PLATFORM_WINDOWS - #include "win_ipc.h" #include <stdio.h> +#include <nng/transport/ipc/ipc.h> + static void ipc_recv_start(nni_ipc_conn *c) { @@ -385,4 +386,45 @@ nni_ipc_conn_get_peer_pid(nni_ipc_conn *c, uint64_t *pid) return (0); } -#endif // NNG_PLATFORM_WINDOWS +int +nni_ipc_conn_setopt( + nni_ipc_conn *c, const char *name, const void *val, size_t sz) +{ + NNI_ARG_UNUSED(c); + NNI_ARG_UNUSED(val); + NNI_ARG_UNUSED(sz); + if ((strcmp(name, NNG_OPT_LOCADDR) == 0) || + (strcmp(name, NNG_OPT_REMADDR) == 0) || + (strcmp(name, NNG_OPT_IPC_PEER_PID) == 0)) { + return (NNG_EREADONLY); + } + return (NNG_ENOTSUP); +} + +int +nni_ipc_conn_getopt(nni_ipc_conn *c, const char *name, void *val, size_t *szp) +{ + if ((strcmp(name, NNG_OPT_LOCADDR) == 0) || + (strcmp(name, NNG_OPT_REMADDR) == 0)) { + if (*szp < sizeof(c->sa)) { + return (NNG_EINVAL); + } + + memcpy(val, &c->sa, sizeof(c->sa)); + *szp = sizeof(c->sa); + return (0); + } + if (strcmp(name, NNG_OPT_IPC_PEER_PID) == 0) { + int rv; + uint64_t *idp = val; + if (*szp < sizeof(*idp)) { + return (NNG_EINVAL); + } + if ((rv = nni_ipc_conn_get_peer_pid(c, idp)) == 0) { + ; + *szp = sizeof(*idp); + } + return (rv); + } + return (NNG_ENOTSUP); +} diff --git a/src/platform/windows/win_ipcdial.c b/src/platform/windows/win_ipcdial.c index 67865687..4c3d5c6c 100644 --- a/src/platform/windows/win_ipcdial.c +++ b/src/platform/windows/win_ipcdial.c @@ -10,8 +10,6 @@ #include "core/nng_impl.h" -#ifdef NNG_PLATFORM_WINDOWS - #include "win_ipc.h" #include <stdio.h> @@ -108,16 +106,21 @@ ipc_dial_thr(void *arg) nni_list_remove(&d->aios, aio); nni_aio_set_prov_extra(aio, 0, NULL); - nni_strfree(path); if (((rv = nni_win_io_register(f)) != 0) || ((rv = nni_win_ipc_conn_init(&c, f)) != 0)) { DisconnectNamedPipe(f); CloseHandle(f); nni_aio_finish_error(aio, rv); + nni_strfree(path); continue; } - c->dialer = d; + c->dialer = true; + c->sa.s_ipc.sa_family = NNG_AF_IPC; + snprintf(c->sa.s_ipc.sa_path, + sizeof(c->sa.s_ipc.sa_path), "%s", + path + strlen(IPC_PIPE_PREFIX)); + nni_strfree(path); nni_aio_set_output(aio, 0, c); nni_aio_finish(aio, 0, 0); } @@ -169,8 +172,8 @@ nni_ipc_dialer_dial(nni_ipc_dialer *d, const nni_sockaddr *sa, nni_aio *aio) nni_aio_finish_error(aio, NNG_EADDRINVAL); return; } - if ((rv = nni_asprintf(&path, "\\\\.\\pipe\\%s", sa->s_ipc.sa_path)) != - 0) { + if ((rv = nni_asprintf( + &path, IPC_PIPE_PREFIX "%s", sa->s_ipc.sa_path)) != 0) { nni_aio_finish_error(aio, rv); return; } @@ -261,5 +264,3 @@ nni_win_ipc_sysfini(void) nni_cv_fini(&worker->cv); nni_mtx_fini(&worker->mtx); } - -#endif // NNG_PLATFORM_WINDOWS diff --git a/src/platform/windows/win_ipclisten.c b/src/platform/windows/win_ipclisten.c index 0fc1c9fc..d0fd6ef9 100644 --- a/src/platform/windows/win_ipclisten.c +++ b/src/platform/windows/win_ipclisten.c @@ -10,8 +10,6 @@ #include "core/nng_impl.h" -#ifdef NNG_PLATFORM_WINDOWS - #include "win_ipc.h" #include <stdio.h> @@ -58,8 +56,11 @@ ipc_accept_done(nni_ipc_listener *l, int rv) nni_aio_finish_error(aio, rv); return; } - l->f = f; - c->listener = l; + l->f = f; + c->sa.s_ipc.sa_family = NNG_AF_IPC; + snprintf(c->sa.s_ipc.sa_path, sizeof(c->sa.s_ipc.sa_path), "%s", + l->path + strlen(IPC_PIPE_PREFIX)); + c->dialer = false; nni_aio_set_output(aio, 0, c); nni_aio_finish(aio, 0, 0); } @@ -185,7 +186,7 @@ nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) nni_mtx_unlock(&l->mtx); return (NNG_ECLOSED); } - rv = nni_asprintf(&path, "\\\\.\\pipe\\%s", sa->s_ipc.sa_path); + rv = nni_asprintf(&path, IPC_PIPE_PREFIX "%s", sa->s_ipc.sa_path); if (rv != 0) { nni_mtx_unlock(&l->mtx); return (rv); @@ -292,5 +293,3 @@ nni_ipc_listener_fini(nni_ipc_listener *l) nni_mtx_fini(&l->mtx); NNI_FREE_STRUCT(l); } - -#endif // NNG_PLATFORM_WINDOWS diff --git a/src/platform/windows/win_sockaddr.c b/src/platform/windows/win_sockaddr.c index fbb960b7..d1fed2c7 100644 --- a/src/platform/windows/win_sockaddr.c +++ b/src/platform/windows/win_sockaddr.c @@ -9,8 +9,7 @@ // #include "core/nng_impl.h" - -#ifdef NNG_PLATFORM_WINDOWS +#include "win_impl.h" #include <string.h> @@ -69,5 +68,3 @@ nni_win_sockaddr2nn(nni_sockaddr *sa, const SOCKADDR_STORAGE *ss) } return (-1); } - -#endif // NNG_PLATFORM_WINDOWS diff --git a/src/supplemental/ipc/CMakeLists.txt b/src/supplemental/ipc/CMakeLists.txt new file mode 100644 index 00000000..691522f0 --- /dev/null +++ b/src/supplemental/ipc/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Copyright 2018 Capitar IT Group BV <info@capitar.com> +# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +# Copyright 2018 Devolutions <infos@devolutions.net> +# +# This software is supplied under the terms of the MIT License, a +# copy of which should be located in the distribution where this +# file was obtained (LICENSE.txt). A copy of the license may also be +# found online at https://opensource.org/licenses/MIT. +# + +set(_SRCS supplemental/ipc/ipc.c + ${PROJECT_SOURCE_DIR}/include/nng/supplemental/ipc/ipc.h +) + +set(NNG_SRCS ${NNG_SRCS} ${_SRCS} PARENT_SCOPE) diff --git a/src/supplemental/ipc/ipc.c b/src/supplemental/ipc/ipc.c new file mode 100644 index 00000000..36c18563 --- /dev/null +++ b/src/supplemental/ipc/ipc.c @@ -0,0 +1,136 @@ +// +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Devolutions <infos@devolutions.net> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include <stddef.h> +#include <stdint.h> + +#include <nng/nng.h> +#include <nng/supplemental/ipc/ipc.h> + +#include "core/nng_impl.h" + +// This is our "public" IPC API. This allows applications to access +// basic IPC functions, using our AIO framework. Most applications will +// not need this. + +// We treat nng_ipc as nni_ipc_conn, nng_ipc_dialer as nni_ipc_dialer, +// and nng_ipc_listener as nni_ipc_listener. We cast through void to +// provide isolation of the names in a way that makes the compiler happy. +// It turns out we can pretty much just wrap the platform API for IPC that +// we have already created. + +void +nng_ipc_close(nng_ipc *ipc) +{ + nni_ipc_conn_close((void *) ipc); +} + +void +nng_ipc_free(nng_ipc *ipc) +{ + nni_ipc_conn_fini((void *) ipc); +} + +void +nng_ipc_send(nng_ipc *ipc, nng_aio *aio) +{ + nni_ipc_conn_send((void *) ipc, aio); +} + +void +nng_ipc_recv(nng_ipc *ipc, nng_aio *aio) +{ + nni_ipc_conn_recv((void *) ipc, aio); +} + +int +nng_ipc_setopt(nng_ipc *ipc, const char *name, const void *val, size_t sz) +{ + return (nni_ipc_conn_setopt((void *) ipc, name, val, sz)); +} + +int +nng_ipc_getopt(nng_ipc *ipc, const char *name, void *val, size_t *szp) +{ + return (nni_ipc_conn_getopt((void *) ipc, name, val, szp)); +} + +int +nng_ipc_dialer_alloc(nng_ipc_dialer **dp) +{ + nni_ipc_dialer *d; + int rv; + + if ((rv = nni_init()) != 0) { + return (rv); + } + if ((rv = nni_ipc_dialer_init(&d)) == 0) { + *dp = (void *) d; + } + return (rv); +} + +void +nng_ipc_dialer_close(nng_ipc_dialer *d) +{ + nni_ipc_dialer_close((void *) d); +} + +void +nng_ipc_dialer_free(nng_ipc_dialer *d) +{ + nni_ipc_dialer_fini((void *) d); +} + +void +nng_ipc_dialer_dial(nng_ipc_dialer *d, const nng_sockaddr *sa, nng_aio *aio) +{ + nni_ipc_dialer_dial((void *) d, sa, aio); +} + +int +nng_ipc_listener_alloc(nng_ipc_listener **lp) +{ + nni_ipc_listener *l; + int rv; + + if ((rv = nni_init()) != 0) { + return (rv); + } + if ((rv = nni_ipc_listener_init(&l)) == 0) { + *lp = (void *) l; + } + return (rv); +} + +void +nng_ipc_listener_close(nng_ipc_listener *l) +{ + nni_ipc_listener_close((void *) l); +} + +void +nng_ipc_listener_free(nng_ipc_listener *l) +{ + nni_ipc_listener_fini((void *) l); +} + +int +nng_ipc_listener_listen(nng_ipc_listener *l, const nng_sockaddr *sa) +{ + return (nni_ipc_listener_listen((void *) l, sa)); +} + +void +nng_ipc_listener_accept(nng_ipc_listener *l, nng_aio *aio) +{ + nni_ipc_listener_accept((void *) l, aio); +} diff --git a/src/supplemental/util/options.c b/src/supplemental/util/options.c index c8dafed8..961e0bb2 100644 --- a/src/supplemental/util/options.c +++ b/src/supplemental/util/options.c @@ -11,8 +11,10 @@ #include <stdlib.h> #include <string.h> +#include <nng/nng.h> +#include <nng/supplemental/util/options.h> + #include "core/nng_impl.h" -#include "nng/supplemental/util/options.h" // Call with optidx set to 1 to start parsing. int |
