diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-12-29 16:16:57 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-12-29 16:16:57 -0800 |
| commit | 5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c (patch) | |
| tree | 24c383103cc3ff3e98e2e8179d0633e9b2f6010a | |
| parent | d3bd35ab49ad74528fd9e34cce9016d74dd91943 (diff) | |
| download | nng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.tar.gz nng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.tar.bz2 nng-5b35daaf2fe6c6fbe0b15740efbffe16ff278e6c.zip | |
IPC option rework (pipe/conn) to reduce code duplication.
| -rw-r--r-- | src/core/defs.h | 6 | ||||
| -rw-r--r-- | src/core/listener.c | 14 | ||||
| -rw-r--r-- | src/core/options.c | 32 | ||||
| -rw-r--r-- | src/core/options.h | 44 | ||||
| -rw-r--r-- | src/core/pipe.c | 7 | ||||
| -rw-r--r-- | src/core/platform.h | 7 | ||||
| -rw-r--r-- | src/core/socket.c | 107 | ||||
| -rw-r--r-- | src/core/transport.c | 10 | ||||
| -rw-r--r-- | src/core/transport.h | 19 | ||||
| -rw-r--r-- | src/platform/posix/posix_ipcconn.c | 174 | ||||
| -rw-r--r-- | src/platform/windows/win_ipcconn.c | 101 | ||||
| -rw-r--r-- | src/supplemental/ipc/ipc.c | 6 | ||||
| -rw-r--r-- | src/transport/ipc/ipc.c | 110 |
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[] = { |
