diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-03-19 16:02:37 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-03-20 09:53:58 -0700 |
| commit | 9ca901c1b70b17d851426483d9f54611cfa8e395 (patch) | |
| tree | a26b11e16f505ccdc77b5ac6681e0f9de705ff20 | |
| parent | 9b886a9999247d87c9f6d389c3e65a4bd39be010 (diff) | |
| download | nng-9ca901c1b70b17d851426483d9f54611cfa8e395.tar.gz nng-9ca901c1b70b17d851426483d9f54611cfa8e395.tar.bz2 nng-9ca901c1b70b17d851426483d9f54611cfa8e395.zip | |
fixes #296 Typed options should validate option type
fixes #302 nng_dialer/listener/pipe_getopt_sockaddr desired
This adds plumbing to pass and check the type of options
all the way through.
NNG_ZT_OPT_ORBIT is type UINT64, but you can use the untyped form to
pass two of them if needed.
No typed access for retrieving strings yet. I think this should allocate
a pointer and copy that out, but that's for later.
37 files changed, 713 insertions, 290 deletions
diff --git a/docs/man/nng_dialer_getopt.3.adoc b/docs/man/nng_dialer_getopt.3.adoc index 61aaa576..3fde89d6 100644 --- a/docs/man/nng_dialer_getopt.3.adoc +++ b/docs/man/nng_dialer_getopt.3.adoc @@ -29,7 +29,9 @@ int nng_dialer_getopt_ms(nng_dialer d, const char *opt, nng_duration *durp); int nng_dialer_getopt_ptr(nng_dialer d, const char *opt, void **ptr); -int nng_dialer_setopt_size(nng_dialer d, const char *opt, size_t *zp); +int nng_dialer_getopt_size(nng_dialer d, const char *opt, size_t *zp); + +int nng_dialer_getopt_sockaddr(nng_dialer d, const char *opt, nng_sockaddr *sap); int nng_dialer_getopt_uint64(nng_dialer d, const char *opt, uint64_t *u64p); ---- @@ -79,7 +81,7 @@ the object. ==== `nng_dialer_getopt_bool()` This function is for options which take a boolean (`bool`). -The value will be stored at _ivalp_. +The value will be stored at _bvalp_. ==== `nng_dialer_getopt_int()` This function is for options which take an integer (`int`). @@ -101,6 +103,10 @@ not copied, but instead the *pointer* to the object is copied. This function is used to retrieve a size into the pointer _zp_, typically for buffer sizes, message maximum sizes, and similar options. +==== `nng_dialer_getopt_sockaddr()` +This function is used to retrieve an <<nng_sockaddr.5#,`nng_sockaddr`>> +into the value referenced by _sap_. + ==== `nng_dialer_getopt_uint64()` This function is used to retrieve a 64-bit unsigned value into the value referenced by _u64p_. @@ -125,4 +131,5 @@ These functions returns 0 on success, and non-zero otherwise. <<nng_dialer.5#,nng_dialer(5)>>, <<nng_duration.5#,nng_duration(5)>>, <<nng_options.5#,nng_options(5)>>, +<<nng_sockaddr.5#,nng_sockaddr(5)>>, <<nng.7#,nng(7)>> diff --git a/docs/man/nng_listener_getopt.3.adoc b/docs/man/nng_listener_getopt.3.adoc index 6b2c2fde..1bafd1d6 100644 --- a/docs/man/nng_listener_getopt.3.adoc +++ b/docs/man/nng_listener_getopt.3.adoc @@ -19,8 +19,7 @@ nng_listener_getopt - get listener option ---- #include <nng/nng.h> -int nng_listener_getopt(nng_listener l, const char *opt, void *val, - size_t *valszp); +int nng_listener_getopt(nng_listener l, const char *opt, void *val, size_t *valszp); int nng_listener_getopt_bool(nng_listener l, const char *opt, bool *bvalp); @@ -30,7 +29,9 @@ int nng_listener_getopt_ms(nng_listener l, const char *opt, nng_duration *durp); int nng_listener_getopt_ptr(nng_listener l, const char *opt, void **ptr); -int nng_listener_setopt_size(nng_listener l, const char *opt, size_t *zp); +int nng_listener_getopt_size(nng_listener l, const char *opt, size_t *zp); + +int nng_listener_getopt_sockaddr(nng_listener l, const char *opt, nng_sockaddr *sap); int nng_listener_getopt_uint64(nng_listener l, const char *opt, uint64_t *u64p); ---- @@ -80,7 +81,7 @@ the object. ==== `nng_listener_getopt_bool()` This function is for options which take a boolean (`bool`). -The value will be stored at _ivalp_. +The value will be stored at _bvalp_. ==== `nng_listener_getopt_int()` This function is for options which take an integer (`int`). @@ -89,8 +90,6 @@ The value will be stored at _ivalp_. ==== `nng_listener_getopt_ms()` This function is used to retrieve time <<nng_duration.5#,durations>> (such as timeouts), stored in _durp_ as a number of milliseconds. -(The special value ((`NNG_DUR_INFINITE`)) means an infinite amount of time, and -the special value ((`NNG_DUR_DEFAULT`)) means a context-specific default.) ==== `nng_listener_getopt_ptr()` This function is used to retrieve a pointer, _ptr_, to structured data. @@ -102,6 +101,10 @@ not copied, but instead the *pointer* to the object is copied. This function is used to retrieve a size into the pointer _zp_, typically for buffer sizes, message maximum sizes, and similar options. +==== `nng_listener_getopt_sockaddr()` +This function is used to retrieve an <<nng_sockaddr.5#,`nng_sockaddr`>> +into the value referenced by _sap_. + ==== `nng_listener_getopt_uint64()` This function is used to retrieve a 64-bit unsigned value into the value referenced by _u64p_. @@ -125,4 +128,8 @@ These functions return 0 on success, and non-zero otherwise. <<nng_listener_setopt.3#,nng_listener_setopt(3)>> <<nng_getopt.3#,nng_getopt(3)>>, <<nng_strerror.3#,nng_strerror(3)>>, +<<nng_duration.5#,nng_duration(5)>>, +<<nng_listener.5#,nng_listener(5)>>, +<<nng_options.5#,nng_options(5)>>, +<<nng_sockaddr.5#,nng_sockaddr(5)>>, <<nng.7#,nng(7)>> diff --git a/docs/man/nng_listener_setopt.3.adoc b/docs/man/nng_listener_setopt.3.adoc index 93cae9ab..03a33a57 100644 --- a/docs/man/nng_listener_setopt.3.adoc +++ b/docs/man/nng_listener_setopt.3.adoc @@ -123,6 +123,7 @@ These functions return 0 on success, and non-zero otherwise. <<nng_listener_getopt.3#,nng_listener_getopt(3)>> <<nng_setopt.3#,nng_setopt(3)>>, <<nng_strerror.3#,nng_strerror(3)>>, +<<nng_duration.5#,nng_duration(5)>>, <<nng_listener.5#,nng_listener(5)>>, <<nng_options.5#,nng_options(5)>>, <<nng.7#,nng(7)>> diff --git a/docs/man/nng_pipe_getopt.3.adoc b/docs/man/nng_pipe_getopt.3.adoc index 3198fc21..fd607198 100644 --- a/docs/man/nng_pipe_getopt.3.adoc +++ b/docs/man/nng_pipe_getopt.3.adoc @@ -29,6 +29,8 @@ int nng_pipe_getopt_ms(nng_pipe p, const char *opt, nng_duration *durp); int nng_dialer_getopt_ptr(nng_pipe p, const char *opt, void **ptr); +int nng_pipe_getopt_sockaddr(nng_pipe p, const char *opt, nng_sockaddr *sap); + int nng_pipe_getopt_size(nng_pipe p, const char *opt, size_t *zp); int nng_pipe_getopt_uint64(nng_pipe p, const char *opt, uint64_t *u64p); @@ -110,6 +112,11 @@ not copied, but instead the *pointer* to the object is copied. This function is used to retrieve a size into the pointer _zp_, typically for buffer sizes, message maximum sizes, and similar options. +==== `nng_pipe_getopt_sockaddr()` + +This function is used to retrieve an <<nng_sockaddr.5#,`nng_sockaddr`>> +into _sap_. + ==== `nng_pipe_getopt_uint64()` This function is used to retriev a 64-bit unsigned value into the value @@ -134,5 +141,8 @@ These functions return 0 on success, and non-zero otherwise. <<nng_listener_setopt.3#,nng_listener_setopt(3)>> <<nng_msg_get_pipe.3#,nng_msg_get_pipe(3)>> <<nng_strerror.3#,nng_strerror(3)>>, +<<nng_duration.5#,nng_duration(5)>>, <<nng_options.5#,nng_options(5)>>, +<<nng_pipe.5#,nng_pipe(5)>>, +<<nng_sockaddr.5#,nng_sockaddr(5)>>, <<nng.7#,nng(7)>> diff --git a/src/compat/nanomsg/nn.c b/src/compat/nanomsg/nn.c index fc29083e..caa02c72 100644 --- a/src/compat/nanomsg/nn.c +++ b/src/compat/nanomsg/nn.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Garrett D'Amore <garrett@damore.org> +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a @@ -52,6 +52,15 @@ static const struct { { NNG_ECONNABORTED, ECONNABORTED }, { NNG_ECONNRESET, ECONNRESET }, { NNG_ECANCELED, EBADF }, + { NNG_EEXIST, EEXIST }, + { NNG_EWRITEONLY, EACCES }, + { NNG_EREADONLY, EACCES }, + { NNG_ECRYPTO, EACCES }, + { NNG_EPEERAUTH, EACCES }, + { NNG_EBADTYPE, EINVAL }, + { NNG_EAMBIGUOUS, EINVAL }, + { NNG_ENOFILES, EMFILE }, + { NNG_ENOSPC, ENOSPC }, { 0, 0 }, // clang-format on }; diff --git a/src/compat/nanomsg/nn.h b/src/compat/nanomsg/nn.h index 8c5cee6f..be98ec2f 100644 --- a/src/compat/nanomsg/nn.h +++ b/src/compat/nanomsg/nn.h @@ -1,6 +1,6 @@ // -// Copyright 2017 Garrett D'Amore <garrett@damore.org> -// Copyright 2017 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -196,6 +196,13 @@ extern "C" { #ifndef EIO #define EIO (NN_ERRBASE+32) #endif +#ifndef EEXIST +#define EEXIST (NN_ERRBASE+33) +#endif +#ifndef ENOSPC +#define ENOSPC (NN_ERRBASE+34) +#endif + // Socket options #define NN_LINGER 1 diff --git a/src/core/defs.h b/src/core/defs.h index 0f38b9cf..f64d3df7 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -136,4 +136,20 @@ typedef struct { // A few assorted other items. #define NNI_FLAG_IPV4ONLY 1 +// Types. These are used to provide more structured access to options +// (and maybe later statistics). For now these are internal only. +enum nni_type { + NNI_TYPE_OPAQUE, + NNI_TYPE_BOOL, + NNI_TYPE_INT32, + NNI_TYPE_UINT32, + NNI_TYPE_INT64, + NNI_TYPE_UINT64, + NNI_TYPE_SIZE, + NNI_TYPE_DURATION, + NNI_TYPE_STRING, + NNI_TYPE_SOCKADDR, + NNI_TYPE_POINTER, +}; + #endif // CORE_DEFS_H diff --git a/src/core/endpt.c b/src/core/endpt.c index 4d3d9031..131ee1db 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -581,7 +581,7 @@ nni_ep_pipe_remove(nni_ep *ep, nni_pipe *pipe) } int -nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz) +nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz, int t) { nni_tran_ep_option *eo; @@ -598,6 +598,11 @@ nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz) if (eo->eo_setopt == NULL) { return (NNG_EREADONLY); } + if ((t != NNI_TYPE_OPAQUE) && + (eo->eo_type != NNI_TYPE_OPAQUE) && (t != eo->eo_type)) { + return (NNG_EBADTYPE); + } + nni_mtx_lock(&ep->ep_mtx); rv = eo->eo_setopt(ep->ep_data, val, sz); nni_mtx_unlock(&ep->ep_mtx); @@ -614,7 +619,25 @@ nni_ep_mode(nni_ep *ep) } int -nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) +nni_ep_opttype(nni_ep *ep, const char *name, int *tp) +{ + nni_tran_ep_option *eo; + + for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { + if (strcmp(eo->eo_name, name) == 0) { + *tp = eo->eo_type; + return (0); + } + } + if (strcmp(name, NNG_OPT_URL) == 0) { + *tp = NNI_TYPE_STRING; + return (0); + } + return (NNG_ENOTSUP); +} + +int +nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp, int t) { nni_tran_ep_option *eo; @@ -626,6 +649,10 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) if (eo->eo_getopt == NULL) { return (NNG_EWRITEONLY); } + if ((t != NNI_TYPE_OPAQUE) && + (eo->eo_type != NNI_TYPE_OPAQUE) && (t != eo->eo_type)) { + return (NNG_EBADTYPE); + } nni_mtx_lock(&ep->ep_mtx); rv = eo->eo_getopt(ep->ep_data, valp, szp); nni_mtx_unlock(&ep->ep_mtx); @@ -636,10 +663,14 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) // override. This allows the URL to be created with wildcards, // that are resolved later. if (strcmp(name, NNG_OPT_URL) == 0) { + if (t != NNI_TYPE_OPAQUE) { + // XXX: Add NNI_TYPE_STRING. + return (NNG_EBADTYPE); + } return (nni_getopt_str(ep->ep_url->u_rawurl, valp, szp)); } - return (nni_sock_getopt(ep->ep_sock, name, valp, szp)); + return (nni_sock_getopt(ep->ep_sock, name, valp, szp, t)); } void diff --git a/src/core/endpt.h b/src/core/endpt.h index df4f345b..f08c7bf2 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -27,9 +27,10 @@ extern void nni_ep_close(nni_ep *); extern int nni_ep_dial(nni_ep *, int); extern int nni_ep_listen(nni_ep *, int); extern void nni_ep_list_init(nni_list *); -extern int nni_ep_setopt(nni_ep *, const char *, const void *, size_t); -extern int nni_ep_getopt(nni_ep *, const char *, void *, size_t *); -extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); +extern int nni_ep_setopt(nni_ep *, const char *, const void *, size_t, int); +extern int nni_ep_getopt(nni_ep *, const char *, void *, size_t *, int); +extern int nni_ep_opttype(nni_ep *, const char *, int *); +extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); extern int nni_ep_mode(nni_ep *); diff --git a/src/core/pipe.c b/src/core/pipe.c index daee3834..40720906 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -289,7 +289,7 @@ nni_pipe_create(nni_ep *ep, void *tdata) } int -nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp) +nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp, int typ) { nni_tran_pipe_option *po; @@ -297,10 +297,14 @@ nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp) if (strcmp(po->po_name, name) != 0) { continue; } + if ((typ != NNI_TYPE_OPAQUE) && + (po->po_type != NNI_TYPE_OPAQUE) && (typ != po->po_type)) { + return (NNG_EBADTYPE); + } return (po->po_getopt(p->p_tran_data, val, szp)); } // Maybe the endpoint knows? - return (nni_ep_getopt(p->p_ep, name, val, szp)); + return (nni_ep_getopt(p->p_ep, name, val, szp, typ)); } void diff --git a/src/core/pipe.h b/src/core/pipe.h index 32871335..ea0c16db 100644 --- a/src/core/pipe.h +++ b/src/core/pipe.h @@ -57,7 +57,10 @@ extern void nni_pipe_start(nni_pipe *); extern uint16_t nni_pipe_proto(nni_pipe *); extern uint16_t nni_pipe_peer(nni_pipe *); -extern int nni_pipe_getopt(nni_pipe *, const char *, void *, size_t *); + +// nni_pipe_getopt looks up the option. The last argument is the type, +// which. If the type is NNI_TYPE_OPAQUE, then no format check is performed. +extern int nni_pipe_getopt(nni_pipe *, const char *, void *, size_t *, int); // nni_pipe_get_proto_data gets the protocol private data set with the // nni_pipe_set_proto_data function. No locking is performed. diff --git a/src/core/protocol.h b/src/core/protocol.h index 47ddfd3f..e0e0e0d7 100644 --- a/src/core/protocol.h +++ b/src/core/protocol.h @@ -49,6 +49,7 @@ struct nni_proto_pipe_ops { struct nni_proto_sock_option { const char *pso_name; + int pso_type; int (*pso_getopt)(void *, void *, size_t *); int (*pso_setopt)(void *, const void *, size_t); }; diff --git a/src/core/socket.c b/src/core/socket.c index 440f1bbf..40fdc9c8 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -21,6 +21,7 @@ static nni_mtx nni_sock_lk; typedef struct nni_socket_option { const char *so_name; + int so_type; int (*so_getopt)(nni_sock *, void *, size_t *); int (*so_setopt)(nni_sock *, const void *, size_t); } nni_socket_option; @@ -28,6 +29,7 @@ typedef struct nni_socket_option { typedef struct nni_sockopt { nni_list_node node; char * name; + int typ; size_t sz; void * data; } nni_sockopt; @@ -251,51 +253,62 @@ nni_sock_setopt_sockname(nni_sock *s, const void *buf, size_t sz) static const nni_socket_option nni_sock_options[] = { { .so_name = NNG_OPT_RECVTIMEO, + .so_type = NNI_TYPE_DURATION, .so_getopt = nni_sock_getopt_recvtimeo, .so_setopt = nni_sock_setopt_recvtimeo, }, { .so_name = NNG_OPT_SENDTIMEO, + .so_type = NNI_TYPE_DURATION, .so_getopt = nni_sock_getopt_sendtimeo, .so_setopt = nni_sock_setopt_sendtimeo, }, { .so_name = NNG_OPT_RECVFD, + .so_type = NNI_TYPE_INT32, .so_getopt = nni_sock_getopt_recvfd, .so_setopt = NULL, }, { .so_name = NNG_OPT_SENDFD, + .so_type = NNI_TYPE_INT32, .so_getopt = nni_sock_getopt_sendfd, .so_setopt = NULL, }, { .so_name = NNG_OPT_RECVBUF, + .so_type = NNI_TYPE_INT32, .so_getopt = nni_sock_getopt_recvbuf, .so_setopt = nni_sock_setopt_recvbuf, }, { .so_name = NNG_OPT_SENDBUF, + .so_type = NNI_TYPE_INT32, .so_getopt = nni_sock_getopt_sendbuf, .so_setopt = nni_sock_setopt_sendbuf, }, { .so_name = NNG_OPT_RECONNMINT, + .so_type = NNI_TYPE_DURATION, .so_getopt = nni_sock_getopt_reconnmint, .so_setopt = nni_sock_setopt_reconnmint, }, { .so_name = NNG_OPT_RECONNMAXT, + .so_type = NNI_TYPE_DURATION, .so_getopt = nni_sock_getopt_reconnmaxt, .so_setopt = nni_sock_setopt_reconnmaxt, }, { .so_name = NNG_OPT_SOCKNAME, + .so_type = NNI_TYPE_STRING, .so_getopt = nni_sock_getopt_sockname, .so_setopt = nni_sock_setopt_sockname, }, // terminate list - { NULL, NULL, NULL }, + { + .so_name = NULL, + }, }; static void @@ -513,17 +526,17 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto) ((rv = nni_msgq_init(&s->s_urq, 0)) != 0) || ((rv = s->s_sock_ops.sock_init(&s->s_data, s)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_LINGER, &s->s_linger, - sizeof(nni_duration))) != 0) || + sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_SENDTIMEO, &s->s_sndtimeo, - sizeof(nni_duration))) != 0) || + sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_RECVTIMEO, &s->s_rcvtimeo, - sizeof(nni_duration))) != 0) || + sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_RECONNMINT, &s->s_reconn, - sizeof(nni_duration))) != 0) || + sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_RECONNMAXT, &s->s_reconnmax, - sizeof(nni_duration))) != 0) || + sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_RECVMAXSZ, &s->s_rcvmaxsz, - sizeof(size_t))) != 0)) { + sizeof(size_t), NNI_TYPE_SIZE)) != 0)) { nni_sock_destroy(s); return (rv); } @@ -823,7 +836,8 @@ nni_sock_ep_add(nni_sock *s, nni_ep *ep) NNI_LIST_FOREACH (&s->s_options, sopt) { int rv; - rv = nni_ep_setopt(ep, sopt->name, sopt->data, sopt->sz); + rv = nni_ep_setopt( + ep, sopt->name, sopt->data, sopt->sz, NNI_TYPE_OPAQUE); if ((rv != 0) && (rv != NNG_ENOTSUP)) { nni_mtx_unlock(&s->s_mx); return (rv); @@ -849,7 +863,7 @@ nni_sock_ep_remove(nni_sock *sock, nni_ep *ep) } int -nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) +nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) { int rv = NNG_ENOTSUP; nni_ep * ep; @@ -873,7 +887,12 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) nni_mtx_unlock(&s->s_mx); return (NNG_EREADONLY); } - rv = pso->pso_setopt(s->s_data, val, size); + if ((pso->pso_type != NNI_TYPE_OPAQUE) && + (t != NNI_TYPE_OPAQUE) && (t != pso->pso_type)) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EBADTYPE); + } + rv = pso->pso_setopt(s->s_data, v, sz); nni_mtx_unlock(&s->s_mx); return (rv); } @@ -887,7 +906,12 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) nni_mtx_unlock(&s->s_mx); return (NNG_EREADONLY); } - rv = sso->so_setopt(s, val, size); + if ((sso->so_type != NNI_TYPE_OPAQUE) && + (t != NNI_TYPE_OPAQUE) && (t != sso->so_type)) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EBADTYPE); + } + rv = sso->so_setopt(s, v, sz); nni_mtx_unlock(&s->s_mx); return (rv); } @@ -901,17 +925,17 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) // Validation of transport options. This is stateless, so transports // should not fail to set an option later if they passed it here. - rv = nni_tran_chkopt(name, val, size); + rv = nni_tran_chkopt(name, v, sz); // Also check a few generic things. We do this if no transport // was found, or even if a transport rejected one of the settings. if ((rv == NNG_ENOTSUP) || (rv == 0)) { if ((strcmp(name, NNG_OPT_LINGER) == 0)) { - rv = nni_chkopt_ms(val, size); + rv = nni_chkopt_ms(v, sz); } else if (strcmp(name, NNG_OPT_RECVMAXSZ) == 0) { // just a sanity test on the size; it also ensures that // a size can be set even with no transport configured. - rv = nni_chkopt_size(val, size, 0, NNI_MAXSZ); + rv = nni_chkopt_size(v, sz, 0, NNI_MAXSZ); } } @@ -923,24 +947,25 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) if ((optv = NNI_ALLOC_STRUCT(optv)) == NULL) { return (NNG_ENOMEM); } - if ((optv->data = nni_alloc(size)) == NULL) { + if ((optv->data = nni_alloc(sz)) == NULL) { NNI_FREE_STRUCT(optv); return (NNG_ENOMEM); } if ((optv->name = nni_strdup(name)) == NULL) { - nni_free(optv->data, size); + nni_free(optv->data, sz); NNI_FREE_STRUCT(optv); return (NNG_ENOMEM); } - memcpy(optv->data, val, size); - optv->sz = size; + memcpy(optv->data, v, sz); + optv->sz = sz; + optv->typ = t; NNI_LIST_NODE_INIT(&optv->node); nni_mtx_lock(&s->s_mx); NNI_LIST_FOREACH (&s->s_options, oldv) { if (strcmp(oldv->name, name) == 0) { - if ((oldv->sz != size) || - (memcmp(oldv->data, val, size) != 0)) { + if ((oldv->sz != sz) || + (memcmp(oldv->data, v, sz) != 0)) { break; } @@ -956,7 +981,17 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) // important that transport wide checks properly pre-validate. NNI_LIST_FOREACH (&s->s_eps, ep) { int x; - x = nni_ep_setopt(ep, optv->name, optv->data, size); + if (optv->typ == NNI_TYPE_OPAQUE) { + int t2; + if (nni_ep_opttype(ep, optv->name, &t2) == + NNG_ENOTSUP) { + continue; + } + // This allows us to determine what the type + // *should* be. + optv->typ = t2; + } + x = nni_ep_setopt(ep, optv->name, optv->data, sz, t); if (x != NNG_ENOTSUP) { if ((rv = x) != 0) { nni_mtx_unlock(&s->s_mx); @@ -971,7 +1006,7 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) // will already have had a chance to veto this. if (strcmp(name, NNG_OPT_LINGER) == 0) { - rv = nni_setopt_ms(&s->s_linger, val, size); + rv = nni_setopt_ms(&s->s_linger, v, sz); } if (rv == 0) { @@ -994,7 +1029,7 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) } int -nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp) +nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp, int t) { int rv = NNG_ENOTSUP; nni_sockopt * sopt; @@ -1016,12 +1051,17 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp) nni_mtx_unlock(&s->s_mx); return (NNG_EWRITEONLY); } + if ((pso->pso_type != NNI_TYPE_OPAQUE) && + (t != NNI_TYPE_OPAQUE) && (t != pso->pso_type)) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EBADTYPE); + } rv = pso->pso_getopt(s->s_data, val, szp); nni_mtx_unlock(&s->s_mx); return (rv); } - // Options that are handled by socket core, and never passed down. + // Socket generic options. for (sso = nni_sock_options; sso->so_name != NULL; sso++) { if (strcmp(name, sso->so_name) != 0) { continue; @@ -1030,6 +1070,11 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp) nni_mtx_unlock(&s->s_mx); return (NNG_EWRITEONLY); } + if ((sso->so_type != NNI_TYPE_OPAQUE) && + (t != NNI_TYPE_OPAQUE) && (t != sso->so_type)) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EBADTYPE); + } rv = sso->so_getopt(s, val, szp); nni_mtx_unlock(&s->s_mx); return (rv); @@ -1038,6 +1083,12 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp) NNI_LIST_FOREACH (&s->s_options, sopt) { if (strcmp(sopt->name, name) == 0) { size_t sz = sopt->sz; + + if ((sopt->typ != NNI_TYPE_OPAQUE) && + (t != NNI_TYPE_OPAQUE) && (t != sopt->typ)) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EBADTYPE); + } if (sopt->sz > *szp) { sz = *szp; } diff --git a/src/core/socket.h b/src/core/socket.h index 30561d49..3af6bb9e 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -24,8 +24,10 @@ extern uint16_t nni_sock_proto(nni_sock *); extern uint16_t nni_sock_peer(nni_sock *); extern const char *nni_sock_proto_name(nni_sock *); extern const char *nni_sock_peer_name(nni_sock *); -extern int nni_sock_setopt(nni_sock *, const char *, const void *, size_t); -extern int nni_sock_getopt(nni_sock *, const char *, void *, size_t *); + +extern int nni_sock_setopt( + nni_sock *, const char *, const void *, size_t, int); +extern int nni_sock_getopt(nni_sock *, const char *, void *, size_t *, int); extern int nni_sock_recvmsg(nni_sock *, nni_msg **, int); extern int nni_sock_sendmsg(nni_sock *, nni_msg *, int); extern void nni_sock_send(nni_sock *, nni_aio *); diff --git a/src/core/transport.h b/src/core/transport.h index 0ca9c409..ebc14e83 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -46,13 +46,17 @@ struct nni_tran { // the old version around -- it may be possible to automatically convert // older versions in the future. #define NNI_TRANSPORT_V0 0x54520000 -#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V0 +#define NNI_TRANSPORT_V1 0x54520001 +#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V1 // Endpoint option handlers. struct nni_tran_ep_option { // eo_name is the name of the option. const char *eo_name; + // eo_type is the type of the option. + int eo_type; + // eo_getopt retrieves the value of the option. int (*eo_getopt)(void *, void *, size_t *); @@ -113,6 +117,9 @@ struct nni_tran_pipe_option { // po_name is the name of the option. const char *po_name; + // po_type is the type of the option. + int po_type; + // po_getopt retrieves the value of the option. int (*po_getopt)(void *, void *, size_t *); }; @@ -331,8 +331,8 @@ nng_dialer_start(nng_dialer id, int flags) } static int -nng_ep_setopt( - uint32_t id, const char *name, const void *val, size_t sz, int mode) +nng_ep_setx( + uint32_t id, const char *n, const void *v, size_t sz, int mode, int t) { nni_ep *ep; int rv; @@ -344,7 +344,7 @@ nng_ep_setopt( return (rv); } if (nni_ep_mode(ep) == mode) { - rv = nni_ep_setopt(ep, name, val, sz); + rv = nni_ep_setopt(ep, n, v, sz, t); } else { rv = NNG_ENOENT; } @@ -353,7 +353,7 @@ nng_ep_setopt( } static int -nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp, int mode) +nng_ep_getx(uint32_t id, const char *n, void *v, size_t *szp, int mode, int t) { nni_ep *ep; int rv; @@ -365,7 +365,7 @@ nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp, int mode) return (rv); } if (nni_ep_mode(ep) == mode) { - rv = nni_ep_getopt(ep, name, val, szp); + rv = nni_ep_getopt(ep, n, v, szp, t); } else { rv = NNG_ENOENT; } @@ -373,197 +373,238 @@ nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp, int mode) return (rv); } +static int +nng_dialer_setx(nng_dialer id, const char *nm, const void *v, size_t sz, int t) +{ + return (nng_ep_setx(id, nm, v, sz, NNI_EP_MODE_DIAL, t)); +} + int nng_dialer_setopt(nng_dialer id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, name, v, sz, NNI_EP_MODE_DIAL)); + return (nng_dialer_setx(id, name, v, sz, NNI_TYPE_OPAQUE)); } int -nng_dialer_setopt_bool(nng_dialer id, const char *name, bool val) +nng_dialer_setopt_bool(nng_dialer id, const char *name, bool v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_BOOL)); } int -nng_dialer_setopt_int(nng_dialer id, const char *name, int val) +nng_dialer_setopt_int(nng_dialer id, const char *name, int v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_INT32)); } int -nng_dialer_setopt_size(nng_dialer id, const char *name, size_t val) +nng_dialer_setopt_size(nng_dialer id, const char *name, size_t v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_SIZE)); } int -nng_dialer_setopt_ms(nng_dialer id, const char *name, nng_duration val) +nng_dialer_setopt_ms(nng_dialer id, const char *name, nng_duration v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_DURATION)); } int -nng_dialer_setopt_uint64(nng_dialer id, const char *name, uint64_t val) +nng_dialer_setopt_uint64(nng_dialer id, const char *name, uint64_t v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_UINT64)); } int -nng_dialer_setopt_ptr(nng_dialer id, const char *name, void *val) +nng_dialer_setopt_ptr(nng_dialer id, const char *name, void *v) { - return (nng_dialer_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setx(id, name, &v, sizeof(v), NNI_TYPE_POINTER)); } int -nng_dialer_setopt_string(nng_dialer id, const char *name, const char *val) +nng_dialer_setopt_string(nng_dialer id, const char *name, const char *v) +{ + return (nng_dialer_setx(id, name, v, strlen(v) + 1, NNI_TYPE_STRING)); +} + +static int +nng_dialer_getx(nng_dialer id, const char *n, void *v, size_t *szp, int t) { - return (nng_dialer_setopt(id, name, val, strlen(val) + 1)); + return (nng_ep_getx(id, n, v, szp, NNI_EP_MODE_DIAL, t)); } int nng_dialer_getopt(nng_dialer id, const char *name, void *val, size_t *szp) { - return (nng_ep_getopt(id, name, val, szp, NNI_EP_MODE_DIAL)); + return (nng_dialer_getx(id, name, val, szp, NNI_TYPE_OPAQUE)); } int -nng_dialer_getopt_bool(nng_dialer id, const char *name, bool *valp) +nng_dialer_getopt_bool(nng_dialer id, const char *name, bool *vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_BOOL)); } int -nng_dialer_getopt_int(nng_dialer id, const char *name, int *valp) +nng_dialer_getopt_int(nng_dialer id, const char *name, int *vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_INT32)); } int -nng_dialer_getopt_size(nng_dialer id, const char *name, size_t *valp) +nng_dialer_getopt_size(nng_dialer id, const char *name, size_t *vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_SIZE)); } int -nng_dialer_getopt_uint64(nng_dialer id, const char *name, uint64_t *valp) +nng_dialer_getopt_sockaddr(nng_dialer id, const char *name, nng_sockaddr *vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_SOCKADDR)); } int -nng_dialer_getopt_ptr(nng_dialer id, const char *name, void **valp) +nng_dialer_getopt_uint64(nng_dialer id, const char *name, uint64_t *vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_UINT64)); } int -nng_dialer_getopt_ms(nng_dialer id, const char *name, nng_duration *valp) +nng_dialer_getopt_ptr(nng_dialer id, const char *name, void **vp) { - size_t sz = sizeof(*valp); - return (nng_dialer_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_POINTER)); +} + +int +nng_dialer_getopt_ms(nng_dialer id, const char *name, nng_duration *vp) +{ + size_t sz = sizeof(*vp); + return (nng_dialer_getx(id, name, vp, &sz, NNI_TYPE_DURATION)); +} + +int +nng_listener_setx( + nng_listener id, const char *name, const void *v, size_t sz, int t) +{ + return (nng_ep_setx(id, name, v, sz, NNI_EP_MODE_LISTEN, t)); } int nng_listener_setopt( nng_listener id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, name, v, sz, NNI_EP_MODE_LISTEN)); + return (nng_listener_setx(id, name, v, sz, NNI_TYPE_OPAQUE)); } int -nng_listener_setopt_bool(nng_listener id, const char *name, bool val) +nng_listener_setopt_bool(nng_listener id, const char *name, bool v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_BOOL)); } int -nng_listener_setopt_int(nng_listener id, const char *name, int val) +nng_listener_setopt_int(nng_listener id, const char *name, int v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_INT32)); } int -nng_listener_setopt_size(nng_listener id, const char *name, size_t val) +nng_listener_setopt_size(nng_listener id, const char *name, size_t v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_SIZE)); } int -nng_listener_setopt_ms(nng_listener id, const char *name, nng_duration val) +nng_listener_setopt_ms(nng_listener id, const char *name, nng_duration v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_DURATION)); } int -nng_listener_setopt_uint64(nng_listener id, const char *name, uint64_t val) +nng_listener_setopt_uint64(nng_listener id, const char *name, uint64_t v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_UINT64)); } int -nng_listener_setopt_ptr(nng_listener id, const char *name, void *val) +nng_listener_setopt_ptr(nng_listener id, const char *name, void *v) { - return (nng_listener_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setx(id, name, &v, sizeof(v), NNI_TYPE_POINTER)); } int -nng_listener_setopt_string(nng_listener id, const char *name, const char *val) +nng_listener_setopt_string(nng_listener id, const char *n, const char *v) { - return (nng_listener_setopt(id, name, val, strlen(val) + 1)); + return (nng_listener_setx(id, n, v, strlen(v) + 1, NNI_TYPE_STRING)); } int -nng_listener_getopt(nng_listener id, const char *name, void *val, size_t *szp) +nng_listener_getx( + nng_listener id, const char *name, void *v, size_t *szp, int t) { - return (nng_ep_getopt(id, name, val, szp, NNI_EP_MODE_LISTEN)); + return (nng_ep_getx(id, name, v, szp, NNI_EP_MODE_LISTEN, t)); } int -nng_listener_getopt_bool(nng_listener id, const char *name, bool *valp) +nng_listener_getopt(nng_listener id, const char *name, void *v, size_t *szp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + return (nng_listener_getx(id, name, v, szp, NNI_TYPE_OPAQUE)); } int -nng_listener_getopt_int(nng_listener id, const char *name, int *valp) +nng_listener_getopt_bool(nng_listener id, const char *name, bool *vp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_BOOL)); } int -nng_listener_getopt_size(nng_listener id, const char *name, size_t *valp) +nng_listener_getopt_int(nng_listener id, const char *name, int *vp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_INT32)); } int -nng_listener_getopt_uint64(nng_listener id, const char *name, uint64_t *valp) +nng_listener_getopt_size(nng_listener id, const char *name, size_t *vp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_SIZE)); } int -nng_listener_getopt_ptr(nng_listener id, const char *name, void **valp) +nng_listener_getopt_sockaddr( + nng_listener id, const char *name, nng_sockaddr *vp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_SOCKADDR)); } int -nng_listener_getopt_ms(nng_listener id, const char *name, nng_duration *valp) +nng_listener_getopt_uint64(nng_listener id, const char *name, uint64_t *vp) { - size_t sz = sizeof(*valp); - return (nng_listener_getopt(id, name, valp, &sz)); + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_UINT64)); +} + +int +nng_listener_getopt_ptr(nng_listener id, const char *name, void **vp) +{ + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_POINTER)); +} + +int +nng_listener_getopt_ms(nng_listener id, const char *name, nng_duration *vp) +{ + size_t sz = sizeof(*vp); + return (nng_listener_getx(id, name, vp, &sz, NNI_TYPE_DURATION)); } static int @@ -596,8 +637,8 @@ nng_listener_close(nng_listener l) return (nng_ep_close((uint32_t) l, NNI_EP_MODE_LISTEN)); } -int -nng_setopt(nng_socket sid, const char *name, const void *val, size_t sz) +static int +nng_setx(nng_socket sid, const char *name, const void *val, size_t sz, int t) { nni_sock *sock; int rv; @@ -608,13 +649,19 @@ nng_setopt(nng_socket sid, const char *name, const void *val, size_t sz) if ((rv = nni_sock_find(&sock, sid)) != 0) { return (rv); } - rv = nni_sock_setopt(sock, name, val, sz); + rv = nni_sock_setopt(sock, name, val, sz, t); nni_sock_rele(sock); return (rv); } int -nng_getopt(nng_socket sid, const char *name, void *val, size_t *szp) +nng_setopt(nng_socket sid, const char *name, const void *val, size_t sz) +{ + return (nng_setx(sid, name, val, sz, NNI_TYPE_OPAQUE)); +} + +static int +nng_getx(nng_socket sid, const char *name, void *val, size_t *szp, int t) { nni_sock *sock; int rv; @@ -625,94 +672,100 @@ nng_getopt(nng_socket sid, const char *name, void *val, size_t *szp) if ((rv = nni_sock_find(&sock, sid)) != 0) { return (rv); } - rv = nni_sock_getopt(sock, name, val, szp); + rv = nni_sock_getopt(sock, name, val, szp, t); nni_sock_rele(sock); return (rv); } +int +nng_getopt(nng_socket sid, const char *name, void *val, size_t *szp) +{ + return (nng_getx(sid, name, val, szp, NNI_TYPE_OPAQUE)); +} + // Convenience option wrappers. int nng_setopt_int(nng_socket sid, const char *name, int val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_INT32)); } int nng_setopt_bool(nng_socket sid, const char *name, bool val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_BOOL)); } int nng_setopt_size(nng_socket sid, const char *name, size_t val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_SIZE)); } int nng_setopt_ms(nng_socket sid, const char *name, nng_duration val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_DURATION)); } int nng_setopt_uint64(nng_socket sid, const char *name, uint64_t val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_UINT64)); } int nng_setopt_ptr(nng_socket sid, const char *name, void *val) { - return (nng_setopt(sid, name, &val, sizeof(val))); + return (nng_setx(sid, name, &val, sizeof(val), NNI_TYPE_POINTER)); } int nng_setopt_string(nng_socket sid, const char *name, const char *val) { - return (nng_setopt(sid, name, val, strlen(val) + 1)); + return (nng_setx(sid, name, val, strlen(val) + 1, NNI_TYPE_STRING)); } int nng_getopt_bool(nng_socket sid, const char *name, bool *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_BOOL)); } int nng_getopt_int(nng_socket sid, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_INT32)); } int nng_getopt_size(nng_socket sid, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_SIZE)); } int nng_getopt_uint64(nng_socket sid, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_UINT64)); } int nng_getopt_ms(nng_socket sid, const char *name, nng_duration *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_DURATION)); } int nng_getopt_ptr(nng_socket sid, const char *name, void **valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, name, valp, &sz)); + return (nng_getx(sid, name, valp, &sz, NNI_TYPE_DURATION)); } int @@ -779,6 +832,7 @@ static const struct { { NNG_EPEERAUTH, "Peer could not be authenticated" }, { NNG_ENOARG, "Option requires argument" }, { NNG_EAMBIGUOUS, "Ambiguous option" }, + { NNG_EBADTYPE, "Incorrect type" }, { NNG_EINTERNAL, "Internal error detected" }, { 0, NULL }, // clang-format on @@ -811,8 +865,8 @@ nng_strerror(int num) return (unknownerrbuf); } -int -nng_pipe_getopt(nng_pipe id, const char *name, void *val, size_t *sizep) +static int +nng_pipe_getopt_x(nng_pipe id, const char *name, void *val, size_t *szp, int t) { int rv; nni_pipe *p; @@ -823,51 +877,64 @@ nng_pipe_getopt(nng_pipe id, const char *name, void *val, size_t *sizep) if ((rv = nni_pipe_find(&p, id)) != 0) { return (rv); } - rv = nni_pipe_getopt(p, name, val, sizep); + rv = nni_pipe_getopt(p, name, val, szp, t); nni_pipe_rele(p); return (rv); } int +nng_pipe_getopt(nng_pipe id, const char *name, void *val, size_t *szp) +{ + return (nng_pipe_getopt_x(id, name, val, szp, NNI_TYPE_OPAQUE)); +} + +int nng_pipe_getopt_bool(nng_pipe id, const char *name, bool *valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_BOOL)); } int nng_pipe_getopt_int(nng_pipe id, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_INT32)); } int nng_pipe_getopt_size(nng_pipe id, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_SIZE)); } int nng_pipe_getopt_uint64(nng_pipe id, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_UINT64)); } int nng_pipe_getopt_ms(nng_pipe id, const char *name, nng_duration *valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_DURATION)); } int nng_pipe_getopt_ptr(nng_pipe id, const char *name, void **valp) { size_t sz = sizeof(*valp); - return (nng_pipe_getopt(id, name, valp, &sz)); + return (nng_pipe_getopt_x(id, name, valp, &sz, NNI_TYPE_POINTER)); +} + +int +nng_pipe_getopt_sockaddr(nng_pipe id, const char *name, nng_sockaddr *sap) +{ + size_t sz = sizeof(*sap); + return (nng_pipe_getopt_x(id, name, sap, &sz, NNI_TYPE_SOCKADDR)); } int @@ -51,6 +51,10 @@ extern "C" { #define NNG_MINOR_VERSION 7 #define NNG_PATCH_VERSION 0 +// Maximum length of a socket address. This includes the terminating NUL. +// This limit is built into other implementations, so do not change it. +#define NNG_MAXADDRLEN (128) + // Types common to nng. typedef uint32_t nng_socket; typedef uint32_t nng_dialer; @@ -62,6 +66,68 @@ typedef struct nng_snapshot nng_snapshot; typedef struct nng_stat nng_stat; typedef struct nng_aio nng_aio; +// Some address details. This is in some ways like a traditional sockets +// sockaddr, but we have our own to cope with our unique families, etc. +// The details of this structure are directly exposed to applications. +// These structures can be obtained via property lookups, etc. +struct nng_sockaddr_inproc { + uint16_t sa_family; + char sa_name[NNG_MAXADDRLEN]; +}; +typedef struct nng_sockaddr_inproc nng_sockaddr_inproc; + +struct nng_sockaddr_path { + uint16_t sa_family; + char sa_path[NNG_MAXADDRLEN]; +}; +typedef struct nng_sockaddr_path nng_sockaddr_path; +typedef struct nng_sockaddr_path nng_sockaddr_ipc; + +struct nng_sockaddr_in6 { + uint16_t sa_family; + uint16_t sa_port; + uint8_t sa_addr[16]; +}; +typedef struct nng_sockaddr_in6 nng_sockaddr_in6; +typedef struct nng_sockaddr_in6 nng_sockaddr_udp6; +typedef struct nng_sockaddr_in6 nng_sockaddr_tcp6; + +struct nng_sockaddr_in { + uint16_t sa_family; + uint16_t sa_port; + uint32_t sa_addr; +}; + +struct nng_sockaddr_zt { + uint16_t sa_family; + uint64_t sa_nwid; + uint64_t sa_nodeid; + uint32_t sa_port; +}; + +typedef struct nng_sockaddr_in nng_sockaddr_in; +typedef struct nng_sockaddr_in nng_sockaddr_udp; +typedef struct nng_sockaddr_in nng_sockaddr_tcp; +typedef struct nng_sockaddr_zt nng_sockaddr_zt; + +typedef union nng_sockaddr { + uint16_t s_family; + nng_sockaddr_ipc s_ipc; + nng_sockaddr_inproc s_inproc; + nng_sockaddr_in6 s_in6; + nng_sockaddr_in s_in; + nng_sockaddr_zt s_zt; +} nng_sockaddr; + +enum nng_sockaddr_family { + NNG_AF_UNSPEC = 0, + NNG_AF_INPROC = 1, + NNG_AF_IPC = 2, + NNG_AF_INET = 3, + NNG_AF_INET6 = 4, + NNG_AF_ZT = 5, // ZeroTier +}; + // Scatter/gather I/O. typedef struct nng_iov { void * iov_buf; @@ -171,6 +237,8 @@ NNG_DECL int nng_dialer_getopt_bool(nng_dialer, const char *, bool *); NNG_DECL int nng_dialer_getopt_int(nng_dialer, const char *, int *); NNG_DECL int nng_dialer_getopt_ms(nng_dialer, const char *, nng_duration *); NNG_DECL int nng_dialer_getopt_size(nng_dialer, const char *, size_t *); +NNG_DECL int nng_dialer_getopt_sockaddr( + nng_dialer, const char *, nng_sockaddr *); NNG_DECL int nng_dialer_getopt_uint64(nng_dialer, const char *, uint64_t *); NNG_DECL int nng_dialer_getopt_ptr(nng_dialer, const char *, void **); @@ -198,6 +266,8 @@ NNG_DECL int nng_listener_getopt_int(nng_listener, const char *, int *); NNG_DECL int nng_listener_getopt_ms( nng_listener, const char *, nng_duration *); NNG_DECL int nng_listener_getopt_size(nng_listener, const char *, size_t *); +NNG_DECL int nng_listener_getopt_sockaddr( + nng_listener, const char *, nng_sockaddr *); NNG_DECL int nng_listener_getopt_uint64( nng_listener, const char *, uint64_t *); NNG_DECL int nng_listener_getopt_ptr(nng_listener, const char *, void **); @@ -405,6 +475,7 @@ NNG_DECL int nng_pipe_getopt_bool(nng_pipe, const char *, bool *); NNG_DECL int nng_pipe_getopt_int(nng_pipe, const char *, int *); NNG_DECL int nng_pipe_getopt_ms(nng_pipe, const char *, nng_duration *); NNG_DECL int nng_pipe_getopt_size(nng_pipe, const char *, size_t *); +NNG_DECL int nng_pipe_getopt_sockaddr(nng_pipe, const char *, nng_sockaddr *); NNG_DECL int nng_pipe_getopt_uint64(nng_pipe, const char *, uint64_t *); NNG_DECL int nng_pipe_getopt_ptr(nng_pipe, const char *, void **); NNG_DECL int nng_pipe_close(nng_pipe); @@ -492,15 +563,15 @@ enum nng_flag_enum { // object must be deallocated expressly by the user, and may persist beyond // the lifetime of any socket object used to update it. Note that the // values of the statistics are initially unset. -//NNG_DECL int nng_snapshot_create(nng_socket, nng_snapshot **); +// NNG_DECL int nng_snapshot_create(nng_socket, nng_snapshot **); // nng_snapshot_free frees a snapshot object. All statistic objects // contained therein are destroyed as well. -//NNG_DECL void nng_snapshot_free(nng_snapshot *); +// NNG_DECL void nng_snapshot_free(nng_snapshot *); // nng_snapshot_update updates a snapshot of all the statistics // relevant to a particular socket. All prior values are overwritten. -//NNG_DECL int nng_snapshot_update(nng_snapshot *); +// NNG_DECL int nng_snapshot_update(nng_snapshot *); // nng_snapshot_next is used to iterate over the individual statistic // objects inside the snapshot. Note that the statistic object, and the @@ -511,13 +582,13 @@ enum nng_flag_enum { // Iteration begins by providing NULL in the value referenced. Successive // calls will update this value, returning NULL when no more statistics // are available in the snapshot. -//NNG_DECL int nng_snapshot_next(nng_snapshot *, nng_stat **); +// NNG_DECL int nng_snapshot_next(nng_snapshot *, nng_stat **); // nng_stat_name is used to determine the name of the statistic. // This is a human readable name. Statistic names, as well as the presence // or absence or semantic of any particular statistic are not part of any // stable API, and may be changed without notice in future updates. -//NNG_DECL const char *nng_stat_name(nng_stat *); +// NNG_DECL const char *nng_stat_name(nng_stat *); // nng_stat_type is used to determine the type of the statistic. // At present, only NNG_STAT_TYPE_LEVEL and and NNG_STAT_TYPE_COUNTER @@ -525,7 +596,7 @@ enum nng_flag_enum { // value over time are likely more interesting than the actual level. Level // values reflect some absolute state however, and should be presented to the // user as is. -//NNG_DECL int nng_stat_type(nng_stat *); +// NNG_DECL int nng_stat_type(nng_stat *); enum nng_stat_type_enum { NNG_STAT_LEVEL = 0, @@ -536,7 +607,7 @@ enum nng_stat_type_enum { // such as NNG_UNIT_BYTES or NNG_UNIT_BYTES. If no specific unit is // applicable, such as a relative priority, then NN_UNIT_NONE is // returned. -//NNG_DECL int nng_stat_unit(nng_stat *); +// NNG_DECL int nng_stat_unit(nng_stat *); enum nng_unit_enum { NNG_UNIT_NONE = 0, @@ -550,7 +621,7 @@ enum nng_unit_enum { // nng_stat_value returns returns the actual value of the statistic. // Statistic values reflect their value at the time that the corresponding // snapshot was updated, and are undefined until an update is performed. -//NNG_DECL int64_t nng_stat_value(nng_stat *); +// NNG_DECL int64_t nng_stat_value(nng_stat *); // Device functionality. This connects two sockets together in a device, // which means that messages from one side are forwarded to the other. @@ -612,77 +683,12 @@ enum nng_errno_enum { NNG_EPEERAUTH = 27, NNG_ENOARG = 28, NNG_EAMBIGUOUS = 29, + NNG_EBADTYPE = 30, NNG_EINTERNAL = 1000, NNG_ESYSERR = 0x10000000, NNG_ETRANERR = 0x20000000, }; -// Maximum length of a socket address. This includes the terminating NUL. -// This limit is built into other implementations, so do not change it. -#define NNG_MAXADDRLEN (128) - -// Some address details. This is in some ways like a traditional sockets -// sockaddr, but we have our own to cope with our unique families, etc. -// The details of this structure are directly exposed to applications. -// These structures can be obtained via property lookups, etc. -struct nng_sockaddr_inproc { - uint16_t sa_family; - char sa_name[NNG_MAXADDRLEN]; -}; -typedef struct nng_sockaddr_inproc nng_sockaddr_inproc; - -struct nng_sockaddr_path { - uint16_t sa_family; - char sa_path[NNG_MAXADDRLEN]; -}; -typedef struct nng_sockaddr_path nng_sockaddr_path; -typedef struct nng_sockaddr_path nng_sockaddr_ipc; - -struct nng_sockaddr_in6 { - uint16_t sa_family; - uint16_t sa_port; - uint8_t sa_addr[16]; -}; -typedef struct nng_sockaddr_in6 nng_sockaddr_in6; -typedef struct nng_sockaddr_in6 nng_sockaddr_udp6; -typedef struct nng_sockaddr_in6 nng_sockaddr_tcp6; - -struct nng_sockaddr_in { - uint16_t sa_family; - uint16_t sa_port; - uint32_t sa_addr; -}; - -struct nng_sockaddr_zt { - uint16_t sa_family; - uint64_t sa_nwid; - uint64_t sa_nodeid; - uint32_t sa_port; -}; - -typedef struct nng_sockaddr_in nng_sockaddr_in; -typedef struct nng_sockaddr_in nng_sockaddr_udp; -typedef struct nng_sockaddr_in nng_sockaddr_tcp; -typedef struct nng_sockaddr_zt nng_sockaddr_zt; - -typedef union nng_sockaddr { - uint16_t s_family; - nng_sockaddr_ipc s_ipc; - nng_sockaddr_inproc s_inproc; - nng_sockaddr_in6 s_in6; - nng_sockaddr_in s_in; - nng_sockaddr_zt s_zt; -} nng_sockaddr; - -enum nng_sockaddr_family { - NNG_AF_UNSPEC = 0, - NNG_AF_INPROC = 1, - NNG_AF_IPC = 2, - NNG_AF_INET = 3, - NNG_AF_INET6 = 4, - NNG_AF_ZT = 5, // ZeroTier -}; - // URL support. We frequently want to process a URL, and these methods // give us a convenient way of doing so. diff --git a/src/protocol/bus0/bus.c b/src/protocol/bus0/bus.c index d2b51cd4..31b40fd5 100644 --- a/src/protocol/bus0/bus.c +++ b/src/protocol/bus0/bus.c @@ -373,11 +373,14 @@ static nni_proto_pipe_ops bus0_pipe_ops = { static nni_proto_sock_option bus0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = bus0_sock_getopt_raw, .pso_setopt = bus0_sock_setopt_raw, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops bus0_sock_ops = { diff --git a/src/protocol/pair0/pair.c b/src/protocol/pair0/pair.c index 9e9dfe10..476eadd6 100644 --- a/src/protocol/pair0/pair.c +++ b/src/protocol/pair0/pair.c @@ -271,11 +271,14 @@ static nni_proto_pipe_ops pair0_pipe_ops = { static nni_proto_sock_option pair0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = pair0_sock_getopt_raw, .pso_setopt = pair0_sock_setopt_raw, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + } }; static nni_proto_sock_ops pair0_sock_ops = { diff --git a/src/protocol/pair1/pair.c b/src/protocol/pair1/pair.c index b4519221..564118ae 100644 --- a/src/protocol/pair1/pair.c +++ b/src/protocol/pair1/pair.c @@ -476,21 +476,26 @@ static nni_proto_pipe_ops pair1_pipe_ops = { static nni_proto_sock_option pair1_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = pair1_sock_getopt_raw, .pso_setopt = pair1_sock_setopt_raw, }, { .pso_name = NNG_OPT_MAXTTL, + .pso_type = NNI_TYPE_INT32, .pso_getopt = pair1_sock_getopt_maxttl, .pso_setopt = pair1_sock_setopt_maxttl, }, { .pso_name = NNG_OPT_PAIR1_POLY, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = pair1_sock_getopt_poly, .pso_setopt = pair1_sock_setopt_poly, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops pair1_sock_ops = { diff --git a/src/protocol/pipeline0/pull.c b/src/protocol/pipeline0/pull.c index 5e0a9d00..fec07c39 100644 --- a/src/protocol/pipeline0/pull.c +++ b/src/protocol/pipeline0/pull.c @@ -219,11 +219,14 @@ static nni_proto_pipe_ops pull0_pipe_ops = { static nni_proto_sock_option pull0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = pull0_sock_getopt_raw, .pso_setopt = pull0_sock_setopt_raw, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops pull0_sock_ops = { diff --git a/src/protocol/pipeline0/push.c b/src/protocol/pipeline0/push.c index a0dfa397..b6f6a824 100644 --- a/src/protocol/pipeline0/push.c +++ b/src/protocol/pipeline0/push.c @@ -236,11 +236,14 @@ static nni_proto_pipe_ops push0_pipe_ops = { static nni_proto_sock_option push0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = push0_sock_getopt_raw, .pso_setopt = push0_sock_setopt_raw, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops push0_sock_ops = { diff --git a/src/protocol/pubsub0/pub.c b/src/protocol/pubsub0/pub.c index ff110d56..36c27e7f 100644 --- a/src/protocol/pubsub0/pub.c +++ b/src/protocol/pubsub0/pub.c @@ -312,11 +312,14 @@ static nni_proto_pipe_ops pub0_pipe_ops = { static nni_proto_sock_option pub0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = pub0_sock_getopt_raw, .pso_setopt = pub0_sock_setopt_raw, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops pub0_sock_ops = { diff --git a/src/protocol/pubsub0/sub.c b/src/protocol/pubsub0/sub.c index d9d0d5f3..cb7b0509 100644 --- a/src/protocol/pubsub0/sub.c +++ b/src/protocol/pubsub0/sub.c @@ -361,21 +361,26 @@ static nni_proto_pipe_ops sub0_pipe_ops = { static nni_proto_sock_option sub0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = sub0_sock_getopt_raw, .pso_setopt = sub0_sock_setopt_raw, }, { .pso_name = NNG_OPT_SUB_SUBSCRIBE, + .pso_type = NNI_TYPE_OPAQUE, .pso_getopt = NULL, .pso_setopt = sub0_subscribe, }, { .pso_name = NNG_OPT_SUB_UNSUBSCRIBE, + .pso_type = NNI_TYPE_OPAQUE, .pso_getopt = NULL, .pso_setopt = sub0_unsubscribe, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops sub0_sock_ops = { diff --git a/src/protocol/reqrep0/rep.c b/src/protocol/reqrep0/rep.c index 9906de4b..429d55e7 100644 --- a/src/protocol/reqrep0/rep.c +++ b/src/protocol/reqrep0/rep.c @@ -476,16 +476,20 @@ static nni_proto_pipe_ops rep0_pipe_ops = { static nni_proto_sock_option rep0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = rep0_sock_getopt_raw, .pso_setopt = rep0_sock_setopt_raw, }, { .pso_name = NNG_OPT_MAXTTL, + .pso_type = NNI_TYPE_INT32, .pso_getopt = rep0_sock_getopt_maxttl, .pso_setopt = rep0_sock_setopt_maxttl, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops rep0_sock_ops = { diff --git a/src/protocol/reqrep0/req.c b/src/protocol/reqrep0/req.c index d87a5d1f..63ae07a0 100644 --- a/src/protocol/reqrep0/req.c +++ b/src/protocol/reqrep0/req.c @@ -629,21 +629,26 @@ static nni_proto_pipe_ops req0_pipe_ops = { static nni_proto_sock_option req0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = req0_sock_getopt_raw, .pso_setopt = req0_sock_setopt_raw, }, { .pso_name = NNG_OPT_MAXTTL, + .pso_type = NNI_TYPE_INT32, .pso_getopt = req0_sock_getopt_maxttl, .pso_setopt = req0_sock_setopt_maxttl, }, { .pso_name = NNG_OPT_REQ_RESENDTIME, + .pso_type = NNI_TYPE_DURATION, .pso_getopt = req0_sock_getopt_resendtime, .pso_setopt = req0_sock_setopt_resendtime, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops req0_sock_ops = { diff --git a/src/protocol/survey0/respond.c b/src/protocol/survey0/respond.c index c73f5720..42db2cb0 100644 --- a/src/protocol/survey0/respond.c +++ b/src/protocol/survey0/respond.c @@ -470,16 +470,20 @@ static nni_proto_pipe_ops resp0_pipe_ops = { static nni_proto_sock_option resp0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = resp0_sock_getopt_raw, .pso_setopt = resp0_sock_setopt_raw, }, { .pso_name = NNG_OPT_MAXTTL, + .pso_type = NNI_TYPE_INT32, .pso_getopt = resp0_sock_getopt_maxttl, .pso_setopt = resp0_sock_setopt_maxttl, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops resp0_sock_ops = { diff --git a/src/protocol/survey0/survey.c b/src/protocol/survey0/survey.c index 864287ed..40ace91b 100644 --- a/src/protocol/survey0/survey.c +++ b/src/protocol/survey0/survey.c @@ -465,21 +465,26 @@ static nni_proto_pipe_ops surv0_pipe_ops = { static nni_proto_sock_option surv0_sock_options[] = { { .pso_name = NNG_OPT_RAW, + .pso_type = NNI_TYPE_BOOL, .pso_getopt = surv0_sock_getopt_raw, .pso_setopt = surv0_sock_setopt_raw, }, { .pso_name = NNG_OPT_SURVEYOR_SURVEYTIME, + .pso_type = NNI_TYPE_DURATION, .pso_getopt = surv0_sock_getopt_surveytime, .pso_setopt = surv0_sock_setopt_surveytime, }, { .pso_name = NNG_OPT_MAXTTL, + .pso_type = NNI_TYPE_INT32, .pso_getopt = surv0_sock_getopt_maxttl, .pso_setopt = surv0_sock_setopt_maxttl, }, // terminate list - { NULL, NULL, NULL }, + { + .pso_name = NULL, + }, }; static nni_proto_sock_ops surv0_sock_ops = { diff --git a/src/transport/inproc/inproc.c b/src/transport/inproc/inproc.c index 375d8bdd..14457623 100644 --- a/src/transport/inproc/inproc.c +++ b/src/transport/inproc/inproc.c @@ -421,10 +421,20 @@ nni_inproc_ep_accept(void *arg, nni_aio *aio) } static nni_tran_pipe_option nni_inproc_pipe_options[] = { - { NNG_OPT_LOCADDR, nni_inproc_pipe_get_addr }, - { NNG_OPT_REMADDR, nni_inproc_pipe_get_addr }, + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_inproc_pipe_get_addr, + }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_inproc_pipe_get_addr, + }, // terminate list - { NULL, NULL }, + { + .po_name = NULL, + }, }; static nni_tran_pipe nni_inproc_pipe_ops = { @@ -438,7 +448,9 @@ static nni_tran_pipe nni_inproc_pipe_ops = { static nni_tran_ep_option nni_inproc_ep_options[] = { // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep nni_inproc_ep_ops = { diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c index fa59f0fe..9f95c2a9 100644 --- a/src/transport/ipc/ipc.c +++ b/src/transport/ipc/ipc.c @@ -703,10 +703,20 @@ nni_ipc_ep_get_addr(void *arg, void *data, size_t *szp) } static nni_tran_pipe_option nni_ipc_pipe_options[] = { - { NNG_OPT_REMADDR, nni_ipc_pipe_get_addr }, - { NNG_OPT_LOCADDR, nni_ipc_pipe_get_addr }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_ipc_pipe_get_addr, + }, + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_ipc_pipe_get_addr, + }, // terminate list - { NULL, NULL }, + { + .po_name = NULL, + }, }; static nni_tran_pipe nni_ipc_pipe_ops = { @@ -722,16 +732,20 @@ static nni_tran_pipe nni_ipc_pipe_ops = { static nni_tran_ep_option nni_ipc_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = nni_ipc_ep_getopt_recvmaxsz, .eo_setopt = nni_ipc_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_LOCADDR, + .eo_type = NNI_TYPE_SOCKADDR, .eo_getopt = nni_ipc_ep_get_addr, .eo_setopt = NULL, }, // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep nni_ipc_ep_ops = { diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c index a74f1097..5741beea 100644 --- a/src/transport/tcp/tcp.c +++ b/src/transport/tcp/tcp.c @@ -776,10 +776,20 @@ nni_tcp_ep_getopt_linger(void *arg, void *v, size_t *szp) } static nni_tran_pipe_option nni_tcp_pipe_options[] = { - { NNG_OPT_LOCADDR, nni_tcp_pipe_getopt_locaddr }, - { NNG_OPT_REMADDR, nni_tcp_pipe_getopt_remaddr }, + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_tcp_pipe_getopt_locaddr, + }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_tcp_pipe_getopt_remaddr, + }, // terminate list - { NULL, NULL } + { + .po_name = NULL, + }, }; static nni_tran_pipe nni_tcp_pipe_ops = { @@ -795,21 +805,26 @@ static nni_tran_pipe nni_tcp_pipe_ops = { static nni_tran_ep_option nni_tcp_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = nni_tcp_ep_getopt_recvmaxsz, .eo_setopt = nni_tcp_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_URL, + .eo_type = NNI_TYPE_STRING, .eo_getopt = nni_tcp_ep_getopt_url, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_LINGER, + .eo_type = NNI_TYPE_DURATION, .eo_getopt = nni_tcp_ep_getopt_linger, .eo_setopt = nni_tcp_ep_setopt_linger, }, // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep nni_tcp_ep_ops = { diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c index 59066f5f..9299ba2d 100644 --- a/src/transport/tls/tls.c +++ b/src/transport/tls/tls.c @@ -896,11 +896,25 @@ tls_getopt_verified(void *arg, void *v, size_t *szp) } static nni_tran_pipe_option nni_tls_pipe_options[] = { - { NNG_OPT_LOCADDR, nni_tls_pipe_getopt_locaddr }, - { NNG_OPT_REMADDR, nni_tls_pipe_getopt_remaddr }, - { NNG_OPT_TLS_VERIFIED, tls_getopt_verified }, + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_tls_pipe_getopt_locaddr, + }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = nni_tls_pipe_getopt_remaddr, + }, + { + .po_name = NNG_OPT_TLS_VERIFIED, + .po_type = NNI_TYPE_BOOL, + .po_getopt = tls_getopt_verified, + }, // terminate list - { NULL, NULL } + { + .po_name = NULL, + }, }; static nni_tran_pipe nni_tls_pipe_ops = { @@ -916,46 +930,56 @@ static nni_tran_pipe nni_tls_pipe_ops = { static nni_tran_ep_option nni_tls_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = nni_tls_ep_getopt_recvmaxsz, .eo_setopt = nni_tls_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_LINGER, + .eo_type = NNI_TYPE_DURATION, .eo_getopt = nni_tls_ep_getopt_linger, .eo_setopt = nni_tls_ep_setopt_linger, }, { .eo_name = NNG_OPT_URL, + .eo_type = NNI_TYPE_STRING, .eo_getopt = nni_tls_ep_getopt_url, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_TLS_CONFIG, + .eo_type = NNI_TYPE_POINTER, .eo_getopt = tls_getopt_config, .eo_setopt = tls_setopt_config, }, { .eo_name = NNG_OPT_TLS_CERT_KEY_FILE, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = tls_setopt_cert_key_file, }, { .eo_name = NNG_OPT_TLS_CA_FILE, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = tls_setopt_ca_file, }, { .eo_name = NNG_OPT_TLS_AUTH_MODE, + .eo_type = NNI_TYPE_INT32, // enum really .eo_getopt = NULL, .eo_setopt = tls_setopt_auth_mode, }, { .eo_name = NNG_OPT_TLS_SERVER_NAME, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = tls_setopt_server_name, }, // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep nni_tls_ep_ops = { diff --git a/src/transport/ws/websocket.c b/src/transport/ws/websocket.c index 2aeb6e29..1b862d73 100644 --- a/src/transport/ws/websocket.c +++ b/src/transport/ws/websocket.c @@ -537,16 +537,35 @@ ws_pipe_getopt_tls_verified(void *arg, void *v, size_t *szp) static nni_tran_pipe_option ws_pipe_options[] = { - // clang-format off - { NNG_OPT_LOCADDR, ws_pipe_getopt_locaddr }, - { NNG_OPT_REMADDR, ws_pipe_getopt_remaddr }, - { NNG_OPT_WS_REQUEST_HEADERS, ws_pipe_getopt_reqhdrs }, - { NNG_OPT_WS_RESPONSE_HEADERS, ws_pipe_getopt_reshdrs }, - { NNG_OPT_TLS_VERIFIED, ws_pipe_getopt_tls_verified }, - // clang-format on - + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = ws_pipe_getopt_locaddr, + }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = ws_pipe_getopt_remaddr, + }, + { + .po_name = NNG_OPT_WS_REQUEST_HEADERS, + .po_type = NNI_TYPE_STRING, + .po_getopt = ws_pipe_getopt_reqhdrs, + }, + { + .po_name = NNG_OPT_WS_RESPONSE_HEADERS, + .po_type = NNI_TYPE_STRING, + .po_getopt = ws_pipe_getopt_reshdrs, + }, + { + .po_name = NNG_OPT_TLS_VERIFIED, + .po_type = NNI_TYPE_BOOL, + .po_getopt = ws_pipe_getopt_tls_verified, + }, // terminate list - { NULL, NULL } + { + .po_name = NULL, + } }; static nni_tran_pipe ws_pipe_ops = { @@ -561,22 +580,26 @@ static nni_tran_pipe ws_pipe_ops = { static nni_tran_ep_option ws_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = ws_ep_getopt_recvmaxsz, .eo_setopt = ws_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_WS_REQUEST_HEADERS, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = ws_ep_setopt_reqhdrs, }, { .eo_name = NNG_OPT_WS_RESPONSE_HEADERS, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = ws_ep_setopt_reshdrs, }, - // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static void @@ -910,46 +933,56 @@ wss_ep_setopt_tls_server_name(void *arg, const void *v, size_t sz) static nni_tran_ep_option wss_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = ws_ep_getopt_recvmaxsz, .eo_setopt = ws_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_WS_REQUEST_HEADERS, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = ws_ep_setopt_reqhdrs, }, { .eo_name = NNG_OPT_WS_RESPONSE_HEADERS, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = ws_ep_setopt_reshdrs, }, { .eo_name = NNG_OPT_TLS_CONFIG, + .eo_type = NNI_TYPE_POINTER, .eo_getopt = wss_ep_getopt_tlsconfig, .eo_setopt = wss_ep_setopt_tlsconfig, }, { .eo_name = NNG_OPT_TLS_CERT_KEY_FILE, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = wss_ep_setopt_tls_cert_key_file, }, { .eo_name = NNG_OPT_TLS_CA_FILE, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = wss_ep_setopt_tls_ca_file, }, { .eo_name = NNG_OPT_TLS_AUTH_MODE, + .eo_type = NNI_TYPE_INT32, .eo_getopt = NULL, .eo_setopt = wss_ep_setopt_tls_auth_mode, }, { .eo_name = NNG_OPT_TLS_SERVER_NAME, + .eo_type = NNI_TYPE_STRING, .eo_getopt = NULL, .eo_setopt = wss_ep_setopt_tls_server_name, }, // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep wss_ep_ops = { diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c index 2a427ca0..98dbe2bd 100644 --- a/src/transport/zerotier/zerotier.c +++ b/src/transport/zerotier/zerotier.c @@ -2776,14 +2776,40 @@ zt_pipe_getopt_mtu(void *arg, void *data, size_t *szp) } static nni_tran_pipe_option zt_pipe_options[] = { - { NNG_OPT_LOCADDR, zt_pipe_getopt_locaddr }, - { NNG_OPT_REMADDR, zt_pipe_getopt_remaddr }, - { NNG_OPT_ZT_MTU, zt_pipe_getopt_mtu }, - { NNG_OPT_ZT_NWID, zt_pipe_get_nwid }, - { NNG_OPT_ZT_NODE, zt_pipe_get_node }, - { NNG_OPT_RECVMAXSZ, zt_pipe_get_recvmaxsz }, + { + .po_name = NNG_OPT_LOCADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = zt_pipe_getopt_locaddr, + }, + { + .po_name = NNG_OPT_REMADDR, + .po_type = NNI_TYPE_SOCKADDR, + .po_getopt = zt_pipe_getopt_remaddr, + }, + { + .po_name = NNG_OPT_ZT_MTU, + .po_type = NNI_TYPE_SIZE, + .po_getopt = zt_pipe_getopt_mtu, + }, + { + .po_name = NNG_OPT_ZT_NWID, + .po_type = NNI_TYPE_UINT64, + .po_getopt = zt_pipe_get_nwid, + }, + { + .po_name = NNG_OPT_ZT_NODE, + .po_type = NNI_TYPE_UINT64, + .po_getopt = zt_pipe_get_node, + }, + { + .po_name = NNG_OPT_RECVMAXSZ, + .po_type = NNI_TYPE_SIZE, + .po_getopt = zt_pipe_get_recvmaxsz, + }, // terminate list - { NULL, NULL }, + { + .po_name = NULL, + }, }; static nni_tran_pipe zt_pipe_ops = { @@ -2799,71 +2825,86 @@ static nni_tran_pipe zt_pipe_ops = { static nni_tran_ep_option zt_ep_options[] = { { .eo_name = NNG_OPT_RECVMAXSZ, + .eo_type = NNI_TYPE_SIZE, .eo_getopt = zt_ep_getopt_recvmaxsz, .eo_setopt = zt_ep_setopt_recvmaxsz, }, { .eo_name = NNG_OPT_URL, + .eo_type = NNI_TYPE_STRING, .eo_getopt = zt_ep_getopt_url, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_ZT_HOME, + .eo_type = NNI_TYPE_STRING, .eo_getopt = zt_ep_getopt_home, .eo_setopt = zt_ep_setopt_home, }, { .eo_name = NNG_OPT_ZT_NODE, + .eo_type = NNI_TYPE_UINT64, .eo_getopt = zt_ep_getopt_node, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_ZT_NWID, + .eo_type = NNI_TYPE_UINT64, .eo_getopt = zt_ep_getopt_nwid, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_ZT_NETWORK_STATUS, + .eo_type = NNI_TYPE_INT32, // enumeration really .eo_getopt = zt_ep_getopt_network_status, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_ZT_NETWORK_NAME, + .eo_type = NNI_TYPE_STRING, .eo_getopt = zt_ep_getopt_network_name, .eo_setopt = NULL, }, { .eo_name = NNG_OPT_ZT_PING_TIME, + .eo_type = NNI_TYPE_DURATION, .eo_getopt = zt_ep_getopt_ping_time, .eo_setopt = zt_ep_setopt_ping_time, }, { .eo_name = NNG_OPT_ZT_PING_TRIES, + .eo_type = NNI_TYPE_INT32, .eo_getopt = zt_ep_getopt_ping_tries, .eo_setopt = zt_ep_setopt_ping_tries, }, { .eo_name = NNG_OPT_ZT_CONN_TIME, + .eo_type = NNI_TYPE_DURATION, .eo_getopt = zt_ep_getopt_conn_time, .eo_setopt = zt_ep_setopt_conn_time, }, { .eo_name = NNG_OPT_ZT_CONN_TRIES, + .eo_type = NNI_TYPE_INT32, .eo_getopt = zt_ep_getopt_conn_tries, .eo_setopt = zt_ep_setopt_conn_tries, }, { .eo_name = NNG_OPT_ZT_ORBIT, + .eo_type = NNI_TYPE_UINT64, // use opaque for two .eo_getopt = NULL, .eo_setopt = zt_ep_setopt_orbit, }, { .eo_name = NNG_OPT_ZT_DEORBIT, + .eo_type = NNI_TYPE_UINT64, .eo_getopt = NULL, .eo_setopt = zt_ep_setopt_deorbit, }, // terminate list - { NULL, NULL, NULL }, + { + .eo_name = NULL, + }, }; static nni_tran_ep zt_ep_ops = { diff --git a/tests/sock.c b/tests/sock.c index 8ff8b002..75d7c140 100644 --- a/tests/sock.c +++ b/tests/sock.c @@ -254,11 +254,11 @@ TestMain("Socket Operations", { Convey("Bogus raw fails", { // Bool type is 1 byte. So(nng_setopt_int(s1, NNG_OPT_RAW, 42) == - NNG_EINVAL); + NNG_EBADTYPE); So(nng_setopt_int(s1, NNG_OPT_RAW, -42) == - NNG_EINVAL); + NNG_EBADTYPE); So(nng_setopt_int(s1, NNG_OPT_RAW, 0) == - NNG_EINVAL); + NNG_EBADTYPE); So(nng_setopt(s1, NNG_OPT_RAW, "abcd", 4) == NNG_EINVAL); }); diff --git a/tests/tls.c b/tests/tls.c index f46467fe..a441b453 100644 --- a/tests/tls.c +++ b/tests/tls.c @@ -115,14 +115,14 @@ check_props_v4(nng_msg *msg) nng_sockaddr la; nng_sockaddr ra; - z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); - So(z == sizeof(la)); + // Typed access + So(nng_pipe_getopt_sockaddr(p, NNG_OPT_LOCADDR, &la) == 0); So(la.s_family == NNG_AF_INET); So(la.s_in.sa_port == htons(trantest_port - 1)); So(la.s_in.sa_port != 0); So(la.s_in.sa_addr == htonl(0x7f000001)); + // Untyped access z = sizeof(nng_sockaddr); So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); So(z == sizeof(ra)); @@ -130,6 +130,10 @@ check_props_v4(nng_msg *msg) So(ra.s_in.sa_port != 0); So(ra.s_in.sa_addr == htonl(0x7f000001)); + // Check for type enforcement + int i; + So(nng_pipe_getopt_int(p, NNG_OPT_REMADDR, &i) == NNG_EBADTYPE); + return (0); } @@ -379,7 +383,7 @@ TestMain("TLS Transport", { char addr[NNG_MAXADDRLEN]; nng_msg * msg; nng_pipe p; - int v; + bool b; nng_dialer d; So(nng_pair_open(&s1) == 0); @@ -412,8 +416,8 @@ TestMain("TLS Transport", { So(strcmp(nng_msg_body(msg), "hello") == 0); p = nng_msg_get_pipe(msg); So(p > 0); - So(nng_pipe_getopt_int(p, NNG_OPT_TLS_VERIFIED, &v) == 0); - So(v == 0); + So(nng_pipe_getopt_bool(p, NNG_OPT_TLS_VERIFIED, &b) == 0); + So(b == false); nng_msg_free(msg); }); @@ -425,7 +429,7 @@ TestMain("TLS Transport", { char addr[NNG_MAXADDRLEN]; nng_msg * msg; nng_pipe p; - int v; + bool b; So(nng_pair_open(&s1) == 0); So(nng_pair_open(&s2) == 0); @@ -454,9 +458,11 @@ TestMain("TLS Transport", { So(strcmp(nng_msg_body(msg), "hello") == 0); p = nng_msg_get_pipe(msg); So(p > 0); - So(nng_pipe_getopt_int(p, NNG_OPT_TLS_VERIFIED, &v) == 0); - So(v == 1); + So(nng_pipe_getopt_bool(p, NNG_OPT_TLS_VERIFIED, &b) == 0); + So(b == true); + int i; + So(nng_pipe_getopt_int(p, NNG_OPT_TLS_VERIFIED, &i) == + NNG_EBADTYPE); nng_msg_free(msg); }); - }) diff --git a/tests/wssfile.c b/tests/wssfile.c index 15f7008e..48736117 100644 --- a/tests/wssfile.c +++ b/tests/wssfile.c @@ -144,16 +144,21 @@ check_props(nng_msg *msg) p = nng_msg_get_pipe(msg); So(p > 0); + // Typed z = sizeof(nng_sockaddr); - So(nng_pipe_getopt(p, NNG_OPT_LOCADDR, &la, &z) == 0); + So(nng_pipe_getopt_sockaddr(p, NNG_OPT_LOCADDR, &la) == 0); So(z == sizeof(la)); So(validloopback(&la)); + // Untyped z = sizeof(nng_sockaddr); So(nng_pipe_getopt(p, NNG_OPT_REMADDR, &ra, &z) == 0); So(z == sizeof(ra)); So(validloopback(&ra)); + // Bad type + So(nng_pipe_getopt_size(p, NNG_OPT_LOCADDR, &z) == NNG_EBADTYPE); + // Request header z = 0; buf = NULL; @@ -298,7 +303,7 @@ TestMain("WebSocket Secure (TLS) Transport (file based)", { char addr[NNG_MAXADDRLEN]; nng_msg * msg; nng_pipe p; - int v; + bool b; So(nng_pair_open(&s1) == 0); So(nng_pair_open(&s2) == 0); @@ -337,8 +342,8 @@ TestMain("WebSocket Secure (TLS) Transport (file based)", { So(strcmp(nng_msg_body(msg), "hello") == 0); p = nng_msg_get_pipe(msg); So(p > 0); - So(nng_pipe_getopt_int(p, NNG_OPT_TLS_VERIFIED, &v) == 0); - So(v == 0); + So(nng_pipe_getopt_bool(p, NNG_OPT_TLS_VERIFIED, &b) == 0); + So(b == false); nng_msg_free(msg); }); @@ -350,7 +355,7 @@ TestMain("WebSocket Secure (TLS) Transport (file based)", { char addr[NNG_MAXADDRLEN]; nng_msg * msg; nng_pipe p; - int v; + bool b; So(nng_pair_open(&s1) == 0); So(nng_pair_open(&s2) == 0); @@ -379,8 +384,8 @@ TestMain("WebSocket Secure (TLS) Transport (file based)", { So(strcmp(nng_msg_body(msg), "hello") == 0); p = nng_msg_get_pipe(msg); So(p > 0); - So(nng_pipe_getopt_int(p, NNG_OPT_TLS_VERIFIED, &v) == 0); - So(v == 1); + So(nng_pipe_getopt_bool(p, NNG_OPT_TLS_VERIFIED, &b) == 0); + So(b == true); nng_msg_free(msg); }); |
