summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-12-29 16:16:57 -0800
committerGarrett D'Amore <garrett@damore.org>2018-12-29 16:16:57 -0800
commit5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c (patch)
tree24c383103cc3ff3e98e2e8179d0633e9b2f6010a /src
parentd3bd35ab49ad74528fd9e34cce9016d74dd91943 (diff)
downloadnng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.tar.gz
nng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.tar.bz2
nng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.zip
IPC option rework (pipe/conn) to reduce code duplication.
Diffstat (limited to 'src')
-rw-r--r--src/core/defs.h6
-rw-r--r--src/core/listener.c14
-rw-r--r--src/core/options.c32
-rw-r--r--src/core/options.h44
-rw-r--r--src/core/pipe.c7
-rw-r--r--src/core/platform.h7
-rw-r--r--src/core/socket.c107
-rw-r--r--src/core/transport.c10
-rw-r--r--src/core/transport.h19
-rw-r--r--src/platform/posix/posix_ipcconn.c174
-rw-r--r--src/platform/windows/win_ipcconn.c101
-rw-r--r--src/supplemental/ipc/ipc.c6
-rw-r--r--src/transport/ipc/ipc.c110
13 files changed, 286 insertions, 351 deletions
diff --git a/src/core/defs.h b/src/core/defs.h
index 5c06cf53..32d6782a 100644
--- a/src/core/defs.h
+++ b/src/core/defs.h
@@ -139,7 +139,7 @@ typedef struct {
// Types. These are used to provide more structured access to options
// (and maybe later statistics). For now these are internal only.
-typedef enum nni_opt_type {
+typedef enum {
NNI_TYPE_OPAQUE,
NNI_TYPE_BOOL,
NNI_TYPE_INT32,
@@ -151,6 +151,8 @@ typedef enum nni_opt_type {
NNI_TYPE_STRING,
NNI_TYPE_SOCKADDR,
NNI_TYPE_POINTER,
-} nni_opt_type;
+} nni_type;
+
+typedef nni_type nni_opt_type;
#endif // CORE_DEFS_H
diff --git a/src/core/listener.c b/src/core/listener.c
index 84f8cafd..83f6ca41 100644
--- a/src/core/listener.c
+++ b/src/core/listener.c
@@ -370,6 +370,13 @@ nni_listener_setopt(nni_listener *l, const char *name, const void *val,
return (NNG_EREADONLY);
}
+ if (l->l_ops.l_setopt != NULL) {
+ int rv = l->l_ops.l_setopt(l->l_data, name, val, sz, t);
+ if (rv != NNG_ENOTSUP) {
+ return (rv);
+ }
+ }
+
for (o = l->l_ops.l_options; o && o->o_name; o++) {
if (strcmp(o->o_name, name) != 0) {
continue;
@@ -390,6 +397,13 @@ nni_listener_getopt(
{
nni_option *o;
+ if (l->l_ops.l_getopt != NULL) {
+ int rv = l->l_ops.l_getopt(l->l_data, name, valp, szp, t);
+ if (rv != NNG_ENOTSUP) {
+ return (rv);
+ }
+ }
+
for (o = l->l_ops.l_options; o && o->o_name; o++) {
if (strcmp(o->o_name, name) != 0) {
continue;
diff --git a/src/core/options.c b/src/core/options.c
index d61b35ac..097b92b2 100644
--- a/src/core/options.c
+++ b/src/core/options.c
@@ -366,3 +366,35 @@ nni_copyout_str(const char *str, void *dst, size_t *szp, nni_opt_type t)
return (NNG_EBADTYPE);
}
}
+
+int
+nni_getopt(const nni_option *opts, const char *nm, void *arg, void *buf,
+ size_t *szp, nni_opt_type otype)
+{
+ while (opts->o_name != NULL) {
+ if (strcmp(opts->o_name, nm) == 0) {
+ if (opts->o_get == NULL) {
+ return (NNG_EWRITEONLY);
+ }
+ return (opts->o_get(arg, buf, szp, otype));
+ }
+ opts++;
+ }
+ return (NNG_ENOTSUP);
+}
+
+int
+nni_setopt(const nni_option *opts, const char *nm, void *arg, const void *buf,
+ size_t sz, nni_opt_type otype)
+{
+ while (opts->o_name != NULL) {
+ if (strcmp(opts->o_name, nm) == 0) {
+ if (opts->o_set == NULL) {
+ return (NNG_EREADONLY);
+ }
+ return (opts->o_set(arg, buf, sz, otype));
+ }
+ opts++;
+ }
+ return (NNG_ENOTSUP);
+} \ No newline at end of file
diff --git a/src/core/options.h b/src/core/options.h
index f0ab9811..c0d5b23d 100644
--- a/src/core/options.h
+++ b/src/core/options.h
@@ -24,32 +24,31 @@
// in their own option handling, centralizing the logic for dealing with
// variable sized options.
-extern int nni_copyin_ms(nni_duration *, const void *, size_t, nni_opt_type);
-extern int nni_copyin_bool(bool *, const void *, size_t, nni_opt_type);
-extern int nni_copyin_int(int *, const void *, size_t, int, int, nni_opt_type);
+extern int nni_copyin_ms(nni_duration *, const void *, size_t, nni_type);
+extern int nni_copyin_bool(bool *, const void *, size_t, nni_type);
+extern int nni_copyin_int(int *, const void *, size_t, int, int, nni_type);
extern int nni_copyin_size(
- size_t *, const void *, size_t, size_t, size_t, nni_opt_type);
-extern int nni_copyin_str(char *, const void *, size_t, size_t, nni_opt_type);
-extern int nni_copyin_ptr(void **, const void *, size_t, nni_opt_type);
-extern int nni_copyin_u64(uint64_t *, const void *, size_t, nni_opt_type);
-extern int nni_copyin_sockaddr(
- nng_sockaddr *, const void *, size_t, nni_opt_type);
+ size_t *, const void *, size_t, size_t, size_t, nni_type);
+extern int nni_copyin_str(char *, const void *, size_t, size_t, nni_type);
+extern int nni_copyin_ptr(void **, const void *, size_t, nni_type);
+extern int nni_copyin_u64(uint64_t *, const void *, size_t, nni_type);
+extern int nni_copyin_sockaddr(nng_sockaddr *, const void *, size_t, nni_type);
// nni_copyout_xxx copies out a type of the named value. It assumes that
// the type is aligned and the size correct, unless NNI_TYPE_OPAQUE is passed.
extern int nni_copyout(const void *, size_t, void *, size_t *);
-extern int nni_copyout_bool(bool, void *, size_t *, nni_opt_type);
-extern int nni_copyout_int(int, void *, size_t *, nni_opt_type);
-extern int nni_copyout_ms(nng_duration, void *, size_t *, nni_opt_type);
-extern int nni_copyout_ptr(void *, void *, size_t *, nni_opt_type);
-extern int nni_copyout_size(size_t, void *, size_t *, nni_opt_type);
+extern int nni_copyout_bool(bool, void *, size_t *, nni_type);
+extern int nni_copyout_int(int, void *, size_t *, nni_type);
+extern int nni_copyout_ms(nng_duration, void *, size_t *, nni_type);
+extern int nni_copyout_ptr(void *, void *, size_t *, nni_type);
+extern int nni_copyout_size(size_t, void *, size_t *, nni_type);
extern int nni_copyout_sockaddr(
- const nng_sockaddr *, void *, size_t *, nni_opt_type);
-extern int nni_copyout_u64(uint64_t, void *, size_t *, nni_opt_type);
+ const nng_sockaddr *, void *, size_t *, nni_type);
+extern int nni_copyout_u64(uint64_t, void *, size_t *, nni_type);
// nni_copyout_str copies out a string. If the type is NNI_TYPE_STRING,
// then it passes through a pointer, created by nni_strdup().
-extern int nni_copyout_str(const char *, void *, size_t *, nni_opt_type);
+extern int nni_copyout_str(const char *, void *, size_t *, nni_type);
// nni_option is used for socket, protocol, transport, and similar options.
// Note that only for transports, the o_set member may be called with a NULL
@@ -65,13 +64,20 @@ struct nni_option_s {
// the actual size of the object that would have been copied
// is supplied by the function in the size. If the object did
// not fit, then NNG_EINVAL is returned.
- int (*o_get)(void *, void *, size_t *, nni_opt_type);
+ int (*o_get)(void *, void *, size_t *, nni_type);
// o_set is used to set the value of the option. For transport
// endpoints only, the instance parameter (first argument) may be
// NULL, in which case only a generic validation of the parameters
// is performed. (This is used when setting socket options before
- int (*o_set)(void *, const void *, size_t, nni_opt_type);
+ int (*o_set)(void *, const void *, size_t, nni_type);
};
+// nni_getopt and nni_setopt are helper functions to implement options
+// based on arrays of nni_option structures.
+extern int nni_getopt(
+ const nni_option *, const char *, void *, void *, size_t *, nni_type);
+extern int nni_setopt(
+ const nni_option *, const char *, void *, const void *, size_t, nni_type);
+
#endif // CORE_OPTIONS_H
diff --git a/src/core/pipe.c b/src/core/pipe.c
index 9357cee4..664dd3c2 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -291,6 +291,13 @@ nni_pipe_getopt(
{
nni_option *o;
+ if (p->p_tran_ops.p_getopt != NULL) {
+ int rv;
+ rv = p->p_tran_ops.p_getopt(p->p_tran_data, name, val, szp, t);
+ if (rv != NNG_ENOTSUP) {
+ return (rv);
+ }
+ }
for (o = p->p_tran_ops.p_options; o && o->o_name; o++) {
if (strcmp(o->o_name, name) != 0) {
continue;
diff --git a/src/core/platform.h b/src/core/platform.h
index 2b7eb9f1..a512c39f 100644
--- a/src/core/platform.h
+++ b/src/core/platform.h
@@ -379,16 +379,15 @@ 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 *, const char *, const void *, size_t, nni_opt_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 *);
+extern int nni_ipc_conn_getopt(
+ nni_ipc_conn *, const char *, void *, size_t *, nni_opt_type);
// nni_ipc_dialer_init creates a new dialer object.
extern int nni_ipc_dialer_init(nni_ipc_dialer **);
diff --git a/src/core/socket.c b/src/core/socket.c
index 888200ef..387796a6 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -36,7 +36,7 @@ struct nni_ctx {
typedef struct nni_sockopt {
nni_list_node node;
char * name;
- nni_opt_type typ;
+ nni_type typ;
size_t sz;
void * data;
} nni_sockopt;
@@ -145,7 +145,7 @@ sock_get_fd(void *s, int flag, int *fdp)
}
static int
-sock_get_sendfd(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_sendfd(void *s, void *buf, size_t *szp, nni_type t)
{
int fd;
int rv;
@@ -157,7 +157,7 @@ sock_get_sendfd(void *s, void *buf, size_t *szp, nni_opt_type t)
}
static int
-sock_get_recvfd(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_recvfd(void *s, void *buf, size_t *szp, nni_type t)
{
int fd;
int rv;
@@ -169,38 +169,38 @@ sock_get_recvfd(void *s, void *buf, size_t *szp, nni_opt_type t)
}
static int
-sock_get_raw(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_raw(void *s, void *buf, size_t *szp, nni_type t)
{
bool raw = ((nni_sock_flags(SOCK(s)) & NNI_PROTO_FLAG_RAW) != 0);
return (nni_copyout_bool(raw, buf, szp, t));
}
static int
-sock_set_recvtimeo(void *s, const void *buf, size_t sz, nni_opt_type t)
+sock_set_recvtimeo(void *s, const void *buf, size_t sz, nni_type t)
{
return (nni_copyin_ms(&SOCK(s)->s_rcvtimeo, buf, sz, t));
}
static int
-sock_get_recvtimeo(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_recvtimeo(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_ms(SOCK(s)->s_rcvtimeo, buf, szp, t));
}
static int
-sock_set_sendtimeo(void *s, const void *buf, size_t sz, nni_opt_type t)
+sock_set_sendtimeo(void *s, const void *buf, size_t sz, nni_type t)
{
return (nni_copyin_ms(&SOCK(s)->s_sndtimeo, buf, sz, t));
}
static int
-sock_get_sendtimeo(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_sendtimeo(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_ms(SOCK(s)->s_sndtimeo, buf, szp, t));
}
static int
-sock_set_recvbuf(void *s, const void *buf, size_t sz, nni_opt_type t)
+sock_set_recvbuf(void *s, const void *buf, size_t sz, nni_type t)
{
int len;
int rv;
@@ -212,7 +212,7 @@ sock_set_recvbuf(void *s, const void *buf, size_t sz, nni_opt_type t)
}
static int
-sock_get_recvbuf(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_recvbuf(void *s, void *buf, size_t *szp, nni_type t)
{
int len = nni_msgq_cap(SOCK(s)->s_urq);
@@ -220,7 +220,7 @@ sock_get_recvbuf(void *s, void *buf, size_t *szp, nni_opt_type t)
}
static int
-sock_set_sendbuf(void *s, const void *buf, size_t sz, nni_opt_type t)
+sock_set_sendbuf(void *s, const void *buf, size_t sz, nni_type t)
{
int len;
int rv;
@@ -232,7 +232,7 @@ sock_set_sendbuf(void *s, const void *buf, size_t sz, nni_opt_type t)
}
static int
-sock_get_sendbuf(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_sendbuf(void *s, void *buf, size_t *szp, nni_type t)
{
int len = nni_msgq_cap(SOCK(s)->s_uwq);
@@ -240,38 +240,38 @@ sock_get_sendbuf(void *s, void *buf, size_t *szp, nni_opt_type t)
}
static int
-sock_get_sockname(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_sockname(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_str(SOCK(s)->s_name, buf, szp, t));
}
static int
-sock_set_sockname(void *s, const void *buf, size_t sz, nni_opt_type t)
+sock_set_sockname(void *s, const void *buf, size_t sz, nni_type t)
{
return (nni_copyin_str(
SOCK(s)->s_name, buf, sizeof(SOCK(s)->s_name), sz, t));
}
static int
-sock_get_proto(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_proto(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_int(nni_sock_proto_id(SOCK(s)), buf, szp, t));
}
static int
-sock_get_peer(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_peer(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_int(nni_sock_peer_id(SOCK(s)), buf, szp, t));
}
static int
-sock_get_protoname(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_protoname(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_str(nni_sock_proto_name(SOCK(s)), buf, szp, t));
}
static int
-sock_get_peername(void *s, void *buf, size_t *szp, nni_opt_type t)
+sock_get_peername(void *s, void *buf, size_t *szp, nni_type t)
{
return (nni_copyout_str(nni_sock_peer_name(SOCK(s)), buf, szp, t));
}
@@ -957,14 +957,13 @@ nni_sock_add_dialer(nni_sock *s, nni_dialer *d)
int
nni_sock_setopt(
- nni_sock *s, const char *name, const void *v, size_t sz, nni_opt_type t)
+ nni_sock *s, const char *name, const void *v, size_t sz, nni_type t)
{
- int rv = NNG_ENOTSUP;
- nni_dialer * d;
- nni_listener * l;
- nni_sockopt * optv;
- nni_sockopt * oldv = NULL;
- const nni_option *opt;
+ int rv;
+ nni_dialer * d;
+ nni_listener *l;
+ nni_sockopt * optv;
+ nni_sockopt * oldv = NULL;
nni_mtx_lock(&s->s_mx);
if (s->s_closing) {
@@ -975,33 +974,18 @@ nni_sock_setopt(
// Protocol options. The protocol can override options that
// the socket framework would otherwise supply, like buffer
// sizes.
- for (opt = s->s_sock_ops.sock_options; opt->o_name != NULL; opt++) {
- if (strcmp(opt->o_name, name) != 0) {
- continue;
- }
- if (opt->o_set == NULL) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EREADONLY);
- }
- rv = opt->o_set(s->s_data, v, sz, t);
+ rv = nni_setopt(s->s_sock_ops.sock_options, name, s->s_data, v, sz, t);
+ if (rv != NNG_ENOTSUP) {
nni_mtx_unlock(&s->s_mx);
return (rv);
}
// Some options do not go down to transports. Handle them directly.
- for (opt = sock_options; opt->o_name != NULL; opt++) {
- if (strcmp(opt->o_name, name) != 0) {
- continue;
- }
- if (opt->o_set == NULL) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EREADONLY);
- }
- rv = opt->o_set(s, v, sz, t);
+ rv = nni_setopt(sock_options, name, s, v, sz, t);
+ if (rv != NNG_ENOTSUP) {
nni_mtx_unlock(&s->s_mx);
return (rv);
}
-
nni_mtx_unlock(&s->s_mx);
// If the option was already handled one way or the other,
@@ -1103,11 +1087,10 @@ nni_sock_setopt(
int
nni_sock_getopt(
- nni_sock *s, const char *name, void *val, size_t *szp, nni_opt_type t)
+ nni_sock *s, const char *name, void *val, size_t *szp, nni_type t)
{
- int rv = NNG_ENOTSUP;
- nni_sockopt * sopt;
- const nni_option *opt;
+ int rv = NNG_ENOTSUP;
+ nni_sockopt *sopt;
nni_mtx_lock(&s->s_mx);
if (s->s_closing) {
@@ -1118,29 +1101,16 @@ nni_sock_getopt(
// Protocol specific options. The protocol can override
// options like the send buffer or notification descriptors
// this way.
- for (opt = s->s_sock_ops.sock_options; opt->o_name != NULL; opt++) {
- if (strcmp(name, opt->o_name) != 0) {
- continue;
- }
- if (opt->o_get == NULL) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EWRITEONLY);
- }
- rv = opt->o_get(s->s_data, val, szp, t);
+ rv = nni_getopt(
+ s->s_sock_ops.sock_options, name, s->s_data, val, szp, t);
+ if (rv != NNG_ENOTSUP) {
nni_mtx_unlock(&s->s_mx);
return (rv);
}
// Socket generic options.
- for (opt = sock_options; opt->o_name != NULL; opt++) {
- if (strcmp(name, opt->o_name) != 0) {
- continue;
- }
- if (opt->o_get == NULL) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EWRITEONLY);
- }
- rv = opt->o_get(s, val, szp, t);
+ rv = nni_getopt(sock_options, name, s, val, szp, t);
+ if (rv != NNG_ENOTSUP) {
nni_mtx_unlock(&s->s_mx);
return (rv);
}
@@ -1351,8 +1321,7 @@ nni_ctx_recv(nni_ctx *ctx, nni_aio *aio)
}
int
-nni_ctx_getopt(
- nni_ctx *ctx, const char *opt, void *v, size_t *szp, nni_opt_type t)
+nni_ctx_getopt(nni_ctx *ctx, const char *opt, void *v, size_t *szp, nni_type t)
{
nni_sock * sock = ctx->c_sock;
nni_option *o;
@@ -1382,7 +1351,7 @@ nni_ctx_getopt(
int
nni_ctx_setopt(
- nni_ctx *ctx, const char *opt, const void *v, size_t sz, nni_opt_type t)
+ nni_ctx *ctx, const char *opt, const void *v, size_t sz, nni_type t)
{
nni_sock * sock = ctx->c_sock;
nni_option *o;
diff --git a/src/core/transport.c b/src/core/transport.c
index 185ab779..da192416 100644
--- a/src/core/transport.c
+++ b/src/core/transport.c
@@ -125,6 +125,11 @@ nni_tran_chkopt(const char *name, const void *v, size_t sz, int typ)
// Generally we look for endpoint options. We check both
// dialers and listeners.
dops = t->t_tran.tran_dialer;
+ if ((dops->d_setopt != NULL) &&
+ ((rv = dops->d_setopt(NULL, name, v, sz, typ)) !=
+ NNG_ENOTSUP)) {
+ return (rv);
+ }
for (o = dops->d_options; o && o->o_name != NULL; o++) {
if (strcmp(name, o->o_name) != 0) {
continue;
@@ -138,6 +143,11 @@ nni_tran_chkopt(const char *name, const void *v, size_t sz, int typ)
return (rv);
}
lops = t->t_tran.tran_listener;
+ if ((lops->l_setopt != NULL) &&
+ ((rv = lops->l_setopt(NULL, name, v, sz, typ)) !=
+ NNG_ENOTSUP)) {
+ return (rv);
+ }
for (o = lops->l_options; o && o->o_name != NULL; o++) {
if (strcmp(name, o->o_name) != 0) {
continue;
diff --git a/src/core/transport.h b/src/core/transport.h
index 1736f8ea..338b3f67 100644
--- a/src/core/transport.h
+++ b/src/core/transport.h
@@ -27,7 +27,8 @@
#define NNI_TRANSPORT_V3 0x54520003
#define NNI_TRANSPORT_V4 0x54520004
#define NNI_TRANSPORT_V5 0x54520005
-#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V5
+#define NNI_TRANSPORT_V6 0x54220006
+#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V6
// Endpoint operations are called by the socket in a
// protocol-independent fashion. The socket makes individual calls,
@@ -58,6 +59,12 @@ struct nni_tran_dialer_ops {
// nonblocking.
void (*d_close)(void *);
+ // d_getopt is used to obtain an option.
+ int (*d_getopt)(void *, const char *, void *, size_t *, nni_type);
+
+ // d_setopt is used to set or change an option.
+ int (*d_setopt)(void *, const char *, const void *, size_t, nni_type);
+
// d_options is an array of dialer options. The final
// element must have a NULL name. If this member is NULL, then
// no dialer specific options are available.
@@ -88,6 +95,12 @@ struct nni_tran_listener_ops {
// nonblocking.
void (*l_close)(void *);
+ // l_getopt is used to obtain an option.
+ int (*l_getopt)(void *, const char *, void *, size_t *, nni_type);
+
+ // l_setopt is used to set or change an option.
+ int (*l_setopt)(void *, const char *, const void *, size_t, nni_type);
+
// l_options is an array of listener options. The final
// element must have a NULL name. If this member is NULL, then
// no dialer specific options are available.
@@ -137,6 +150,10 @@ struct nni_tran_pipe_ops {
// whatever transport specific manner is appropriate.
uint16_t (*p_peer)(void *);
+ // p_getopt is used to obtain an option. Pipes don't implement
+ // option setting.
+ int (*p_getopt)(void *, const char *, void *, size_t *, nni_type);
+
// p_options is an array of pipe options. The final element
// must have a NULL name. If this member is NULL, then no
// transport specific options are available.
diff --git a/src/platform/posix/posix_ipcconn.c b/src/platform/posix/posix_ipcconn.c
index 595ebe62..8e4ae2f6 100644
--- a/src/platform/posix/posix_ipcconn.c
+++ b/src/platform/posix/posix_ipcconn.c
@@ -323,7 +323,7 @@ nni_ipc_conn_recv(nni_ipc_conn *c, nni_aio *aio)
nni_mtx_unlock(&c->mtx);
}
-int
+static int
ipc_conn_peerid(nni_ipc_conn *c, uint64_t *euid, uint64_t *egid,
uint64_t *prid, uint64_t *znid)
{
@@ -404,36 +404,42 @@ ipc_conn_peerid(nni_ipc_conn *c, uint64_t *euid, uint64_t *egid,
return (NNG_ENOTSUP);
#endif
}
+
int
-nni_ipc_conn_get_peer_uid(nni_ipc_conn *c, uint64_t *uid)
+ipc_conn_get_peer_uid(void *arg, void *buf, size_t *szp, nni_type t)
{
- int rv;
- uint64_t ignore;
+ nni_ipc_conn *c = arg;
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
- if ((rv = ipc_conn_peerid(c, uid, &ignore, &ignore, &ignore)) != 0) {
+ if ((rv = ipc_conn_peerid(c, &id, &ignore, &ignore, &ignore)) != 0) {
return (rv);
}
- return (0);
+ return (nni_copyout_u64(id, buf, szp, t));
}
-int
-nni_ipc_conn_get_peer_gid(nni_ipc_conn *c, uint64_t *gid)
+static int
+ipc_conn_get_peer_gid(void *arg, void *buf, size_t *szp, nni_type t)
{
- int rv;
- uint64_t ignore;
+ nni_ipc_conn *c = arg;
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
- if ((rv = ipc_conn_peerid(c, &ignore, gid, &ignore, &ignore)) != 0) {
+ if ((rv = ipc_conn_peerid(c, &ignore, &id, &ignore, &ignore)) != 0) {
return (rv);
}
- return (0);
+ return (nni_copyout_u64(id, buf, szp, t));
}
-int
-nni_ipc_conn_get_peer_zoneid(nni_ipc_conn *c, uint64_t *zid)
+static int
+ipc_conn_get_peer_zoneid(void *arg, void *buf, size_t *szp, nni_type t)
{
- int rv;
- uint64_t ignore;
- uint64_t id;
+ nni_ipc_conn *c = arg;
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
if ((rv = ipc_conn_peerid(c, &ignore, &ignore, &ignore, &id)) != 0) {
return (rv);
@@ -442,16 +448,16 @@ nni_ipc_conn_get_peer_zoneid(nni_ipc_conn *c, uint64_t *zid)
// NB: -1 is not a legal zone id (illumos/Solaris)
return (NNG_ENOTSUP);
}
- *zid = id;
- return (0);
+ return (nni_copyout_u64(id, buf, szp, t));
}
-int
-nni_ipc_conn_get_peer_pid(nni_ipc_conn *c, uint64_t *pid)
+static int
+ipc_conn_get_peer_pid(void *arg, void *buf, size_t *szp, nni_type t)
{
- int rv;
- uint64_t ignore;
- uint64_t id;
+ nni_ipc_conn *c = arg;
+ int rv;
+ uint64_t ignore;
+ uint64_t id;
if ((rv = ipc_conn_peerid(c, &ignore, &ignore, &id, &ignore)) != 0) {
return (rv);
@@ -460,21 +466,26 @@ nni_ipc_conn_get_peer_pid(nni_ipc_conn *c, uint64_t *pid)
// NB: -1 is not a legal process id
return (NNG_ENOTSUP);
}
- *pid = id;
- return (0);
+ return (nni_copyout_u64(id, buf, szp, t));
}
-int
-nni_ipc_conn_sockname(nni_ipc_conn *c, nni_sockaddr *sa)
+static int
+ipc_conn_get_addr(void *arg, void *buf, size_t *szp, nni_type t)
{
+ nni_ipc_conn * c = arg;
+ nni_sockaddr sa;
struct sockaddr_storage ss;
socklen_t sslen = sizeof(ss);
int fd = nni_posix_pfd_fd(c->pfd);
+ int rv;
if (getsockname(fd, (void *) &ss, &sslen) != 0) {
return (nni_plat_errno(errno));
}
- return (nni_posix_sockaddr2nn(sa, &ss));
+ if ((rv = nni_posix_sockaddr2nn(&sa, &ss)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_sockaddr(&sa, buf, szp, t));
}
int
@@ -516,77 +527,46 @@ nni_ipc_conn_fini(nni_ipc_conn *c)
NNI_FREE_STRUCT(c);
}
+static const nni_option ipc_conn_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = ipc_conn_get_addr,
+ },
+ {
+ .o_name = NNG_OPT_REMADDR,
+ .o_get = ipc_conn_get_addr,
+ },
+ {
+ .o_name = NNG_OPT_IPC_PEER_PID,
+ .o_get = ipc_conn_get_peer_pid,
+ },
+ {
+ .o_name = NNG_OPT_IPC_PEER_UID,
+ .o_get = ipc_conn_get_peer_uid,
+ },
+ {
+ .o_name = NNG_OPT_IPC_PEER_GID,
+ .o_get = ipc_conn_get_peer_gid,
+ },
+ {
+ .o_name = NNG_OPT_IPC_PEER_ZONEID,
+ .o_get = ipc_conn_get_peer_zoneid,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
int
-nni_ipc_conn_setopt(
- nni_ipc_conn *c, const char *name, const void *val, size_t sz)
+nni_ipc_conn_getopt(
+ nni_ipc_conn *c, const char *name, void *val, size_t *szp, nni_type t)
{
- 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);
+ return (nni_getopt(ipc_conn_options, name, c, val, szp, t));
}
int
-nni_ipc_conn_getopt(nni_ipc_conn *c, const char *name, void *val, size_t *szp)
+nni_ipc_conn_setopt(
+ nni_ipc_conn *c, const char *name, const void *val, size_t sz, nni_type t)
{
- 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);
-}
+ return (nni_setopt(ipc_conn_options, name, c, val, sz, t));
+} \ No newline at end of file
diff --git a/src/platform/windows/win_ipcconn.c b/src/platform/windows/win_ipcconn.c
index 107ffb9d..5a1e4743 100644
--- a/src/platform/windows/win_ipcconn.c
+++ b/src/platform/windows/win_ipcconn.c
@@ -17,6 +17,8 @@
#include <nng/transport/ipc/ipc.h>
+#define CONN(c) ((nni_ipc_conn *) (c))
+
static void
ipc_recv_start(nni_ipc_conn *c)
{
@@ -342,89 +344,60 @@ nni_ipc_conn_fini(nni_ipc_conn *c)
{
nni_ipc_conn_close(c);
- nni_reap(&c->reap, (nni_cb) ipc_conn_reap, c);
-}
-
-int
-nni_ipc_conn_get_peer_uid(nni_ipc_conn *c, uint64_t *id)
-{
- NNI_ARG_UNUSED(c);
- NNI_ARG_UNUSED(id);
- return (NNG_ENOTSUP);
+ nni_reap(&c->reap, (nni_cb) ipc_conn_reap, CONN(c));
}
-int
-nni_ipc_conn_get_peer_gid(nni_ipc_conn *c, uint64_t *id)
+static int
+ipc_conn_get_addr(void *c, void *buf, size_t *szp, nni_opt_type t)
{
- NNI_ARG_UNUSED(c);
- NNI_ARG_UNUSED(id);
- return (NNG_ENOTSUP);
+ return (nni_copyout_sockaddr(&(CONN(c))->sa, buf, szp, t));
}
-int
-nni_ipc_conn_get_peer_zoneid(nni_ipc_conn *c, uint64_t *id)
-{
- NNI_ARG_UNUSED(c);
- NNI_ARG_UNUSED(id);
- return (NNG_ENOTSUP);
-}
-
-int
-nni_ipc_conn_get_peer_pid(nni_ipc_conn *c, uint64_t *pid)
+static int
+ipc_conn_get_peer_pid(void *c, void *buf, size_t *szp, nni_opt_type t)
{
ULONG id;
- if (c->dialer) {
- if (!GetNamedPipeServerProcessId(c->f, &id)) {
+
+ if (CONN(c)->dialer) {
+ if (!GetNamedPipeServerProcessId(CONN(c)->f, &id)) {
return (nni_win_error(GetLastError()));
}
} else {
- if (!GetNamedPipeClientProcessId(c->f, &id)) {
+ if (!GetNamedPipeClientProcessId(CONN(c)->f, &id)) {
return (nni_win_error(GetLastError()));
}
}
- *pid = id;
- return (0);
+ return (nni_copyout_u64(id, buf, szp, t));
}
+static const nni_option ipc_conn_options[] = {
+ {
+ .o_name = NNG_OPT_LOCADDR,
+ .o_get = ipc_conn_get_addr,
+ },
+ {
+ .o_name = NNG_OPT_REMADDR,
+ .o_get = ipc_conn_get_addr,
+ },
+ {
+ .o_name = NNG_OPT_IPC_PEER_PID,
+ .o_get = ipc_conn_get_peer_pid,
+ },
+ {
+ .o_name = NULL, // terminator
+ },
+};
+
int
-nni_ipc_conn_setopt(
- nni_ipc_conn *c, const char *name, const void *val, size_t sz)
+nni_ipc_conn_setopt(nni_ipc_conn *c, const char *name, const void *val,
+ size_t sz, nni_opt_type t)
{
- 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);
+ return (nni_setopt(ipc_conn_options, name, c, val, sz, t));
}
int
-nni_ipc_conn_getopt(nni_ipc_conn *c, const char *name, void *val, size_t *szp)
+nni_ipc_conn_getopt(
+ nni_ipc_conn *c, const char *name, void *val, size_t *szp, nni_opt_type t)
{
- 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);
+ return (nni_getopt(ipc_conn_options, name, c, val, szp, t));
}
diff --git a/src/supplemental/ipc/ipc.c b/src/supplemental/ipc/ipc.c
index 36c18563..f5e590fc 100644
--- a/src/supplemental/ipc/ipc.c
+++ b/src/supplemental/ipc/ipc.c
@@ -54,13 +54,15 @@ nng_ipc_recv(nng_ipc *ipc, nng_aio *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));
+ return (
+ nni_ipc_conn_setopt((void *) ipc, name, val, sz, NNI_TYPE_OPAQUE));
}
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));
+ return (nni_ipc_conn_getopt(
+ (void *) ipc, name, val, szp, NNI_TYPE_OPAQUE));
}
int
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 25d53be8..73354edc 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -641,61 +641,6 @@ ipctran_pipe_peer(void *arg)
return (p->peer);
}
-static int
-ipctran_pipe_get_addr(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- ipctran_pipe *p = arg;
- return (nni_copyout_sockaddr(&p->sa, buf, szp, t));
-}
-
-static int
-ipctran_pipe_get_peer_uid(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- ipctran_pipe *p = arg;
- uint64_t id;
- int rv;
- if ((rv = nni_ipc_conn_get_peer_uid(p->conn, &id)) != 0) {
- return (rv);
- }
- return (nni_copyout_u64(id, buf, szp, t));
-}
-
-static int
-ipctran_pipe_get_peer_gid(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- ipctran_pipe *p = arg;
- uint64_t id;
- int rv;
- if ((rv = nni_ipc_conn_get_peer_gid(p->conn, &id)) != 0) {
- return (rv);
- }
- return (nni_copyout_u64(id, buf, szp, t));
-}
-
-static int
-ipctran_pipe_get_peer_pid(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- ipctran_pipe *p = arg;
- uint64_t id;
- int rv;
- if ((rv = nni_ipc_conn_get_peer_pid(p->conn, &id)) != 0) {
- return (rv);
- }
- return (nni_copyout_u64(id, buf, szp, t));
-}
-
-static int
-ipctran_pipe_get_peer_zoneid(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- ipctran_pipe *p = arg;
- uint64_t id;
- int rv;
- if ((rv = nni_ipc_conn_get_peer_zoneid(p->conn, &id)) != 0) {
- return (rv);
- }
- return (nni_copyout_u64(id, buf, szp, t));
-}
-
static void
ipctran_pipe_conn_cancel(nni_aio *aio, void *arg, int rv)
{
@@ -972,46 +917,25 @@ ipctran_ep_set_sec_desc(void *arg, const void *data, size_t sz, nni_opt_type t)
return (rv);
}
-static nni_option ipctran_pipe_options[] = {
- {
- .o_name = NNG_OPT_REMADDR,
- .o_get = ipctran_pipe_get_addr,
- },
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = ipctran_pipe_get_addr,
- },
- {
- .o_name = NNG_OPT_IPC_PEER_UID,
- .o_get = ipctran_pipe_get_peer_uid,
- },
- {
- .o_name = NNG_OPT_IPC_PEER_GID,
- .o_get = ipctran_pipe_get_peer_gid,
- },
- {
- .o_name = NNG_OPT_IPC_PEER_PID,
- .o_get = ipctran_pipe_get_peer_pid,
- },
- {
- .o_name = NNG_OPT_IPC_PEER_ZONEID,
- .o_get = ipctran_pipe_get_peer_zoneid,
- },
- // terminate list
- {
- .o_name = NULL,
- },
-};
+static int
+ipctran_pipe_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ ipctran_pipe *p = arg;
+
+ // We defer to the platform getopt code for IPC connections.
+ return (nni_ipc_conn_getopt(p->conn, name, buf, szp, t));
+}
static nni_tran_pipe_ops ipctran_pipe_ops = {
- .p_init = ipctran_pipe_init,
- .p_fini = ipctran_pipe_fini,
- .p_stop = ipctran_pipe_stop,
- .p_send = ipctran_pipe_send,
- .p_recv = ipctran_pipe_recv,
- .p_close = ipctran_pipe_close,
- .p_peer = ipctran_pipe_peer,
- .p_options = ipctran_pipe_options,
+ .p_init = ipctran_pipe_init,
+ .p_fini = ipctran_pipe_fini,
+ .p_stop = ipctran_pipe_stop,
+ .p_send = ipctran_pipe_send,
+ .p_recv = ipctran_pipe_recv,
+ .p_close = ipctran_pipe_close,
+ .p_peer = ipctran_pipe_peer,
+ .p_getopt = ipctran_pipe_getopt,
};
static nni_option ipctran_ep_dialer_options[] = {