aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-12-29 18:54:22 -0800
committerGarrett D'Amore <garrett@damore.org>2018-12-29 18:54:22 -0800
commit27b7827532abcbdbecc54795da5b5ac66e7f5e9f (patch)
tree7c8fad19dbb874af35324603204aae87f93d63b8
parent5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c (diff)
downloadnng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.tar.gz
nng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.tar.bz2
nng-27b7827532abcbdbecc54795da5b5ac66e7f5e9f.zip
progress on IPC endpoints
-rw-r--r--src/core/dialer.c14
-rw-r--r--src/core/listener.c1
-rw-r--r--src/core/platform.h29
-rw-r--r--src/platform/windows/win_ipc.h4
-rw-r--r--src/platform/windows/win_ipcconn.c4
-rw-r--r--src/platform/windows/win_ipcdial.c21
-rw-r--r--src/platform/windows/win_ipclisten.c67
-rw-r--r--src/transport/ipc/ipc.c136
-rw-r--r--tests/ipc.c52
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();
})