diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-12-29 18:54:22 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-12-29 18:54:22 -0800 |
| commit | 27b7827532abcbdbecc54795da5b5ac66e7f5e9f (patch) | |
| tree | 7c8fad19dbb874af35324603204aae87f93d63b8 | |
| parent | 5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c (diff) | |
| download | nng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.tar.gz nng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.tar.bz2 nng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.zip | |
progress on IPC endpoints
| -rw-r--r-- | src/core/dialer.c | 14 | ||||
| -rw-r--r-- | src/core/listener.c | 1 | ||||
| -rw-r--r-- | src/core/platform.h | 29 | ||||
| -rw-r--r-- | src/platform/windows/win_ipc.h | 4 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcconn.c | 4 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcdial.c | 21 | ||||
| -rw-r--r-- | src/platform/windows/win_ipclisten.c | 67 | ||||
| -rw-r--r-- | src/transport/ipc/ipc.c | 136 | ||||
| -rw-r--r-- | tests/ipc.c | 52 |
9 files changed, 236 insertions, 92 deletions
diff --git a/src/core/dialer.c b/src/core/dialer.c index a74f30f0..0c800333 100644 --- a/src/core/dialer.c +++ b/src/core/dialer.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 <info@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 @@ -412,6 +413,13 @@ nni_dialer_setopt(nni_dialer *d, const char *name, const void *val, size_t sz, return (rv); } + if (d->d_ops.d_setopt != NULL) { + int rv = d->d_ops.d_setopt(d->d_data, name, val, sz, t); + if (rv != NNG_ENOTSUP) { + return (rv); + } + } + for (o = d->d_ops.d_options; o && o->o_name; o++) { if (strcmp(o->o_name, name) != 0) { continue; @@ -447,6 +455,12 @@ nni_dialer_getopt( return (rv); } + if (d->d_ops.d_getopt != NULL) { + int rv = d->d_ops.d_getopt(d->d_data, name, valp, szp, t); + if (rv != NNG_ENOTSUP) { + return (rv); + } + } for (o = d->d_ops.d_options; o && o->o_name; o++) { if (strcmp(o->o_name, name) != 0) { continue; diff --git a/src/core/listener.c b/src/core/listener.c index 83f6ca41..bb46b6cb 100644 --- a/src/core/listener.c +++ b/src/core/listener.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 <info@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 diff --git a/src/core/platform.h b/src/core/platform.h index a512c39f..b6916b2e 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -1,7 +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> +// Copyright 2018 Devolutions <info@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 @@ -380,14 +380,14 @@ extern int nni_ipc_conn_get_peer_zoneid(nni_ipc_conn *, uint64_t *); // are the same names from the IPC transport, generally. There are no // options that are generally settable on an IPC connection. extern int nni_ipc_conn_setopt( - nni_ipc_conn *, const char *, const void *, size_t, nni_opt_type); + nni_ipc_conn *, const char *, const void *, size_t, nni_type); // 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_opt_type); + nni_ipc_conn *, const char *, void *, size_t *, nni_type); // nni_ipc_dialer_init creates a new dialer object. extern int nni_ipc_dialer_init(nni_ipc_dialer **); @@ -407,6 +407,16 @@ extern void nni_ipc_dialer_close(nni_ipc_dialer *); extern void nni_ipc_dialer_dial( nni_ipc_dialer *, const nni_sockaddr *, nni_aio *); +// nni_ipc_dialer_getopt is used to get options from the dialer. +// At present there aren't any defined options. +extern int nni_ipc_dialer_getopt( + nni_ipc_dialer *, const char *, void *, size_t *, nni_type); + +// nni_ipc_dialer_setopt sets an option for the dialer. There aren't +// any options defined at present. +extern int nni_ipc_dialer_setopt( + nni_ipc_dialer *, const char *, const void *, size_t, nni_type); + // nni_ipc_listener_init creates a new listener object, unbound. extern int nni_ipc_listener_init(nni_ipc_listener **); @@ -445,6 +455,19 @@ extern int nni_ipc_listener_set_permissions(nni_ipc_listener *, int); extern int nni_ipc_listener_set_security_descriptor( nni_ipc_listener *, void *); +// nni_ipc_listener_getopt is used to get options from the listener. +// The only valid option is NNG_OPT_LOCADDR, which will only have +// a valid value if the socket is bound, otherwise the value returned +// will be of type NNG_AF_UNSPEC. +extern int nni_ipc_listener_getopt( + nni_ipc_listener *, const char *, void *, size_t *, nni_type); + +// nni_ipc_listener_setopt sets an option for the listener. The only +// valid options are NNG_OPT_IPC_SECURITY_DESCRIPTORS (Windows) and +// NNG_OPT_IPC_PERMISSIONS (POSIX). +extern int nni_ipc_listener_setopt( + nni_ipc_listener *, const char *, const void *, size_t, nni_type); + // // UDP support. UDP is not connection oriented, and only has the notion // of being bound, sendto, and recvfrom. (It is possible to set up a diff --git a/src/platform/windows/win_ipc.h b/src/platform/windows/win_ipc.h index 9a4e245a..781522b9 100644 --- a/src/platform/windows/win_ipc.h +++ b/src/platform/windows/win_ipc.h @@ -1,7 +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> +// Copyright 2018 Devolutions <info@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 @@ -16,6 +16,7 @@ #include "core/nng_impl.h" #include "win_impl.h" +#include <nng/transport/ipc/ipc.h> #define IPC_PIPE_PREFIX "\\\\.\\pipe\\" @@ -54,6 +55,7 @@ struct nni_ipc_listener { nni_mtx mtx; nni_cv cv; nni_win_io io; + nni_sockaddr sa; int rv; }; diff --git a/src/platform/windows/win_ipcconn.c b/src/platform/windows/win_ipcconn.c index 5a1e4743..ded9ed76 100644 --- a/src/platform/windows/win_ipcconn.c +++ b/src/platform/windows/win_ipcconn.c @@ -1,7 +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> +// Copyright 2018 Devolutions <info@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 @@ -15,8 +15,6 @@ #include <stdio.h> -#include <nng/transport/ipc/ipc.h> - #define CONN(c) ((nni_ipc_conn *) (c)) static void diff --git a/src/platform/windows/win_ipcdial.c b/src/platform/windows/win_ipcdial.c index 4c3d5c6c..98d848ae 100644 --- a/src/platform/windows/win_ipcdial.c +++ b/src/platform/windows/win_ipcdial.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 <info@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 @@ -227,6 +228,26 @@ nni_ipc_dialer_close(nni_ipc_dialer *d) nni_mtx_unlock(&w->mtx); } +static const nni_option ipc_dialer_options[] = { + { + .o_name = NULL, + }, +}; + +int +nni_ipc_dialer_setopt(nni_ipc_dialer *d, const char *name, const void *buf, + size_t sz, nni_type t) +{ + return (nni_setopt(ipc_dialer_options, name, d, buf, sz, t)); +} + +int +nni_ipc_dialer_getopt( + nni_ipc_dialer *d, const char *name, void *buf, size_t *szp, nni_type t) +{ + return (nni_getopt(ipc_dialer_options, name, d, buf, szp, t)); +} + int nni_win_ipc_sysinit(void) { diff --git a/src/platform/windows/win_ipclisten.c b/src/platform/windows/win_ipclisten.c index d0fd6ef9..4b3660ec 100644 --- a/src/platform/windows/win_ipclisten.c +++ b/src/platform/windows/win_ipclisten.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 <info@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 @@ -146,30 +147,66 @@ nni_ipc_listener_init(nni_ipc_listener **lp) return (0); } -int -nni_ipc_listener_set_permissions(nni_ipc_listener *l, int bits) +static int +ipc_listener_set_sec_desc(void *arg, const void *buf, size_t sz, nni_type t) { - NNI_ARG_UNUSED(l); - NNI_ARG_UNUSED(bits); - return (NNG_ENOTSUP); -} + nni_ipc_listener *l = arg; + void * desc; + int rv; -int -nni_ipc_listener_set_security_descriptor(nni_ipc_listener *l, void *desc) -{ + if ((rv = nni_copyin_ptr(&desc, buf, sz, t)) != 0) { + return (rv); + } if (!IsValidSecurityDescriptor((SECURITY_DESCRIPTOR *) desc)) { return (NNG_EINVAL); } - nni_mtx_lock(&l->mtx); - if (l->started) { + if (l != NULL) { + nni_mtx_lock(&l->mtx); + if (l->started) { + nni_mtx_unlock(&l->mtx); + return (NNG_EBUSY); + } + l->sec_attr.lpSecurityDescriptor = desc; nni_mtx_unlock(&l->mtx); - return (NNG_EBUSY); } - l->sec_attr.lpSecurityDescriptor = desc; - nni_mtx_unlock(&l->mtx); return (0); } +static int +ipc_listener_get_addr(void *arg, void *buf, size_t *szp, nni_type t) +{ + nni_ipc_listener *l = arg; + return ((nni_copyout_sockaddr(&l->sa, buf, szp, t))); +} + +static const nni_option ipc_listener_options[] = { + { + .o_name = NNG_OPT_IPC_SECURITY_DESCRIPTOR, + .o_set = ipc_listener_set_sec_desc, + }, + { + .o_name = NNG_OPT_LOCADDR, + .o_get = ipc_listener_get_addr, + }, + { + .o_name = NULL, + }, +}; + +int +nni_ipc_listener_setopt(nni_ipc_listener *l, const char *name, const void *buf, + size_t sz, nni_type t) +{ + return (nni_setopt(ipc_listener_options, name, l, buf, sz, t)); +} + +int +nni_ipc_listener_getopt( + nni_ipc_listener *l, const char *name, void *buf, size_t *szp, nni_type t) +{ + return (nni_getopt(ipc_listener_options, name, l, buf, szp, t)); +} + int nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) { @@ -218,6 +255,7 @@ nni_ipc_listener_listen(nni_ipc_listener *l, const nni_sockaddr *sa) l->f = f; l->path = path; l->started = true; + l->sa = *sa; nni_mtx_unlock(&l->mtx); return (0); } @@ -266,7 +304,6 @@ nni_ipc_listener_accept(nni_ipc_listener *l, nni_aio *aio) void nni_ipc_listener_close(nni_ipc_listener *l) { - nni_mtx_lock(&l->mtx); if (!l->closed) { l->closed = true; diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c index 73354edc..1f8f27c4 100644 --- a/src/transport/ipc/ipc.c +++ b/src/transport/ipc/ipc.c @@ -884,40 +884,6 @@ ipctran_ep_get_locaddr(void *arg, void *buf, size_t *szp, nni_opt_type t) } static int -ipctran_ep_set_perms(void *arg, const void *data, size_t sz, nni_opt_type t) -{ - ipctran_ep *ep = arg; - int val; - int rv; - - // Probably we could further limit this -- most systems don't have - // meaningful chmod beyond the lower 9 bits. - if (((rv = nni_copyin_int(&val, data, sz, 0, 0x7FFFFFFF, t)) == 0) && - (ep != NULL)) { - nni_mtx_lock(&ep->mtx); - rv = nni_ipc_listener_set_permissions(ep->listener, val); - nni_mtx_unlock(&ep->mtx); - } - return (rv); -} - -static int -ipctran_ep_set_sec_desc(void *arg, const void *data, size_t sz, nni_opt_type t) -{ - ipctran_ep *ep = arg; - void * ptr; - int rv; - - if (((rv = nni_copyin_ptr(&ptr, data, sz, t)) == 0) && (ep != NULL)) { - nni_mtx_lock(&ep->mtx); - rv = nni_ipc_listener_set_security_descriptor( - ep->listener, ptr); - nni_mtx_unlock(&ep->mtx); - } - return (rv); -} - -static int ipctran_pipe_getopt( void *arg, const char *name, void *buf, size_t *szp, nni_type t) { @@ -938,61 +904,93 @@ static nni_tran_pipe_ops ipctran_pipe_ops = { .p_getopt = ipctran_pipe_getopt, }; -static nni_option ipctran_ep_dialer_options[] = { +static const nni_option ipctran_ep_options[] = { { .o_name = NNG_OPT_RECVMAXSZ, .o_get = ipctran_ep_get_recvmaxsz, .o_set = ipctran_ep_set_recvmaxsz, }, - { - .o_name = NNG_OPT_LOCADDR, - .o_get = ipctran_ep_get_locaddr, - }, // terminate list { .o_name = NULL, }, }; -static nni_option ipctran_ep_listener_options[] = { - { - .o_name = NNG_OPT_RECVMAXSZ, - .o_get = ipctran_ep_get_recvmaxsz, - .o_set = ipctran_ep_set_recvmaxsz, - }, - { - .o_name = NNG_OPT_LOCADDR, - .o_get = ipctran_ep_get_locaddr, - }, - { - .o_name = NNG_OPT_IPC_SECURITY_DESCRIPTOR, - .o_set = ipctran_ep_set_sec_desc, - }, - { - .o_name = NNG_OPT_IPC_PERMISSIONS, - .o_set = ipctran_ep_set_perms, - }, - // terminate list - { - .o_name = NULL, - }, -}; +static int +ipctran_dialer_getopt( + void *arg, const char *name, void *buf, size_t *szp, nni_type t) +{ + ipctran_ep *ep = arg; + int rv; + + rv = nni_getopt(ipctran_ep_options, name, ep, buf, szp, t); + if (rv == NNG_ENOTSUP) { + rv = nni_ipc_dialer_getopt(ep->dialer, name, buf, szp, t); + } + return (rv); +} + +static int +ipctran_dialer_setopt( + void *arg, const char *name, const void *buf, size_t sz, nni_type t) +{ + ipctran_ep *ep = arg; + int rv; + + rv = nni_setopt(ipctran_ep_options, name, ep, buf, sz, t); + if (rv == NNG_ENOTSUP) { + rv = nni_ipc_dialer_setopt( + ep != NULL ? ep->dialer : NULL, name, buf, sz, t); + } + return (rv); +} + +static int +ipctran_listener_getopt( + void *arg, const char *name, void *buf, size_t *szp, nni_type t) +{ + ipctran_ep *ep = arg; + int rv; + + rv = nni_getopt(ipctran_ep_options, name, ep, buf, szp, t); + if (rv == NNG_ENOTSUP) { + rv = nni_ipc_listener_getopt(ep->listener, name, buf, szp, t); + } + return (rv); +} + +static int +ipctran_listener_setopt( + void *arg, const char *name, const void *buf, size_t sz, nni_type t) +{ + ipctran_ep *ep = arg; + int rv; + + rv = nni_setopt(ipctran_ep_options, name, ep, buf, sz, t); + if (rv == NNG_ENOTSUP) { + rv = nni_ipc_listener_setopt( + ep != NULL ? ep->listener : NULL, name, buf, sz, t); + } + return (rv); +} static nni_tran_dialer_ops ipctran_dialer_ops = { .d_init = ipctran_ep_init_dialer, .d_fini = ipctran_ep_fini, .d_connect = ipctran_ep_connect, .d_close = ipctran_ep_close, - .d_options = ipctran_ep_dialer_options, + .d_getopt = ipctran_dialer_getopt, + .d_setopt = ipctran_dialer_setopt, }; static nni_tran_listener_ops ipctran_listener_ops = { - .l_init = ipctran_ep_init_listener, - .l_fini = ipctran_ep_fini, - .l_bind = ipctran_ep_bind, - .l_accept = ipctran_ep_accept, - .l_close = ipctran_ep_close, - .l_options = ipctran_ep_listener_options, + .l_init = ipctran_ep_init_listener, + .l_fini = ipctran_ep_fini, + .l_bind = ipctran_ep_bind, + .l_accept = ipctran_ep_accept, + .l_close = ipctran_ep_close, + .l_getopt = ipctran_listener_getopt, + .l_setopt = ipctran_listener_setopt, }; static nni_tran ipc_tran = { diff --git a/tests/ipc.c b/tests/ipc.c index be37338e..783529ff 100644 --- a/tests/ipc.c +++ b/tests/ipc.c @@ -17,12 +17,13 @@ #endif #include <nng/nng.h> +#include <nng/protocol/reqrep0/req.h> #include <nng/transport/ipc/ipc.h> #include "convey.h" #include "trantest.h" -// Inproc tests. +// IPC tests. static int check_props(nng_msg *msg) { @@ -83,5 +84,54 @@ check_props(nng_msg *msg) TestMain("IPC Transport", { trantest_test_extended("ipc:///tmp/nng_ipc_test_%u", check_props); + Convey("IPC listener properties", { + nng_socket s; + nng_listener l; + nng_sockaddr sa2; + size_t z; + + So(nng_req0_open(&s) == 0); + Reset({ nng_close(s); }); + So(nng_listen(s, "ipc:///tmp/nng_ipc_addr_test", &l, 0) == 0); + So(nng_listener_getopt_sockaddr(l, NNG_OPT_LOCADDR, &sa2) == + 0); + So(sa2.s_ipc.sa_family == NNG_AF_IPC); + So(strcmp(sa2.s_ipc.sa_path, "/tmp/nng_ipc_addr_test") == 0); + + So(nng_listener_setopt(l, NNG_OPT_LOCADDR, &sa2, + sizeof(sa2)) == NNG_EREADONLY); + z = 8192; + So(nng_listener_setopt_size(l, NNG_OPT_RECVMAXSZ, z) == 0); + z = 0; + So(nng_listener_getopt_size(l, NNG_OPT_RECVMAXSZ, &z) == 0); + So(z == 8192); + So(nng_listener_setopt_bool(l, NNG_OPT_RAW, true) == + NNG_ENOTSUP); + }); + Convey("IPC dialer properties", { + nng_socket s; + nng_dialer d; + nng_sockaddr sa2; + size_t z; + + So(nng_req0_open(&s) == 0); + Reset({ nng_close(s); }); + So(nng_dial(s, "ipc:///tmp/nng_ipc_addr_test", &d, + NNG_FLAG_NONBLOCK) == 0); + // Dialers don't have local addresses. + So(nng_dialer_getopt_sockaddr(d, NNG_OPT_LOCADDR, &sa2) == + NNG_ENOTSUP); + + So(nng_dialer_setopt(d, NNG_OPT_LOCADDR, &sa2, sizeof(sa2)) == + NNG_ENOTSUP); + z = 8192; + So(nng_dialer_setopt_size(d, NNG_OPT_RECVMAXSZ, z) == 0); + z = 0; + So(nng_dialer_getopt_size(d, NNG_OPT_RECVMAXSZ, &z) == 0); + So(z == 8192); + So(nng_dialer_setopt_bool(d, NNG_OPT_RAW, true) == + NNG_ENOTSUP); + }); + nng_fini(); }) |
