diff options
Diffstat (limited to 'src')
31 files changed, 1344 insertions, 1059 deletions
diff --git a/src/core/defs.h b/src/core/defs.h index 4d8e6ffb..ff02b28b 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -32,16 +32,19 @@ typedef struct nng_event nni_event; typedef struct nng_notify nni_notify; // These are our own names. -typedef struct nni_socket nni_sock; -typedef struct nni_ep nni_ep; -typedef struct nni_pipe nni_pipe; -typedef struct nni_tran nni_tran; -typedef struct nni_tran_ep nni_tran_ep; -typedef struct nni_tran_pipe nni_tran_pipe; - -typedef struct nni_proto_sock_ops nni_proto_sock_ops; -typedef struct nni_proto_pipe_ops nni_proto_pipe_ops; -typedef struct nni_proto nni_proto; +typedef struct nni_socket nni_sock; +typedef struct nni_ep nni_ep; +typedef struct nni_pipe nni_pipe; +typedef struct nni_tran nni_tran; +typedef struct nni_tran_ep nni_tran_ep; +typedef struct nni_tran_ep_option nni_tran_ep_option; +typedef struct nni_tran_pipe nni_tran_pipe; +typedef struct nni_tran_pipe_option nni_tran_pipe_option; + +typedef struct nni_proto_sock_ops nni_proto_sock_ops; +typedef struct nni_proto_pipe_ops nni_proto_pipe_ops; +typedef struct nni_proto_sock_option nni_proto_sock_option; +typedef struct nni_proto nni_proto; typedef struct nni_plat_mtx nni_mtx; typedef struct nni_plat_cv nni_cv; diff --git a/src/core/device.c b/src/core/device.c index e7140664..9161e2f0 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -91,10 +91,10 @@ nni_device(nni_sock *sock1, nni_sock *sock2) // No timeouts. sz = sizeof(never); - if ((nni_sock_setopt(sock1, nng_optid_recvtimeo, &never, sz) != 0) || - (nni_sock_setopt(sock2, nng_optid_recvtimeo, &never, sz) != 0) || - (nni_sock_setopt(sock1, nng_optid_sendtimeo, &never, sz) != 0) || - (nni_sock_setopt(sock2, nng_optid_sendtimeo, &never, sz) != 0)) { + if ((nni_sock_setopt(sock1, NNG_OPT_RECVTIMEO, &never, sz) != 0) || + (nni_sock_setopt(sock2, NNG_OPT_RECVTIMEO, &never, sz) != 0) || + (nni_sock_setopt(sock1, NNG_OPT_SENDTIMEO, &never, sz) != 0) || + (nni_sock_setopt(sock2, NNG_OPT_SENDTIMEO, &never, sz) != 0)) { // This should never happen. rv = NNG_EINVAL; goto out; diff --git a/src/core/endpt.c b/src/core/endpt.c index a99041ab..e6216ba3 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -480,7 +480,7 @@ nni_ep_acc_cb(void *arg) break; case NNG_ECLOSED: case NNG_ECANCELED: - // Canceled or closed, no furhter action. + // Canceled or closed, no further action. break; case NNG_ECONNABORTED: case NNG_ECONNRESET: @@ -587,38 +587,62 @@ nni_ep_pipe_remove(nni_ep *ep, nni_pipe *pipe) } int -nni_ep_setopt(nni_ep *ep, int opt, const void *val, size_t sz, int check) +nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz) { - int rv; + nni_tran_ep_option *eo; - if (ep->ep_ops.ep_setopt == NULL) { - return (NNG_ENOTSUP); + if (strcmp(name, NNG_OPT_URL) == 0) { + return (NNG_EREADONLY); } - nni_mtx_lock(&ep->ep_mtx); - if (check && ep->ep_started) { + + for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { + int rv; + + if (strcmp(eo->eo_name, name) != 0) { + continue; + } + if (eo->eo_setopt == NULL) { + return (NNG_EREADONLY); + } + nni_mtx_lock(&ep->ep_mtx); + // XXX: Consider removing this test. + if (ep->ep_started) { + nni_mtx_unlock(&ep->ep_mtx); + return (NNG_ESTATE); + } + rv = eo->eo_setopt(ep->ep_data, val, sz); nni_mtx_unlock(&ep->ep_mtx); - return (NNG_ESTATE); + return (rv); } - rv = ep->ep_ops.ep_setopt(ep->ep_data, opt, val, sz); - nni_mtx_unlock(&ep->ep_mtx); - return (rv); + + // XXX: socket fallback + return (NNG_ENOTSUP); } int -nni_ep_getopt(nni_ep *ep, int opt, void *valp, size_t *szp) +nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) { - int rv; + nni_tran_ep_option *eo; - if (opt == nng_optid_url) { + if (strcmp(name, NNG_OPT_URL) == 0) { return (nni_getopt_str(ep->ep_url, valp, szp)); } - if (ep->ep_ops.ep_getopt == NULL) { - return (NNG_ENOTSUP); + + for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { + int rv; + if (strcmp(eo->eo_name, name) != 0) { + continue; + } + if (eo->eo_getopt == NULL) { + return (NNG_EWRITEONLY); + } + nni_mtx_lock(&ep->ep_mtx); + rv = eo->eo_getopt(ep->ep_data, valp, szp); + nni_mtx_unlock(&ep->ep_mtx); + return (rv); } - nni_mtx_lock(&ep->ep_mtx); - rv = ep->ep_ops.ep_getopt(ep->ep_data, opt, valp, szp); - nni_mtx_unlock(&ep->ep_mtx); - return (rv); + + return (nni_sock_getopt(ep->ep_sock, name, valp, szp)); } void diff --git a/src/core/endpt.h b/src/core/endpt.h index 161c030f..d12d661f 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -11,25 +11,25 @@ #ifndef CORE_ENDPT_H #define CORE_ENDPT_H -extern int nni_ep_sys_init(void); -extern void nni_ep_sys_fini(void); -extern nni_tran * nni_ep_tran(nni_ep *); -extern nni_sock * nni_ep_sock(nni_ep *); -extern int nni_ep_find(nni_ep **, uint32_t); -extern int nni_ep_hold(nni_ep *); -extern void nni_ep_rele(nni_ep *); -extern uint32_t nni_ep_id(nni_ep *); -extern int nni_ep_create_dialer(nni_ep **, nni_sock *, const char *); -extern int nni_ep_create_listener(nni_ep **, nni_sock *, const char *); -extern void nni_ep_stop(nni_ep *); -extern int nni_ep_shutdown(nni_ep *); -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 *, int, const void *, size_t, int); -extern int nni_ep_getopt(nni_ep *, int, void *, size_t *); -extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); +extern int nni_ep_sys_init(void); +extern void nni_ep_sys_fini(void); +extern nni_tran *nni_ep_tran(nni_ep *); +extern nni_sock *nni_ep_sock(nni_ep *); +extern int nni_ep_find(nni_ep **, uint32_t); +extern int nni_ep_hold(nni_ep *); +extern void nni_ep_rele(nni_ep *); +extern uint32_t nni_ep_id(nni_ep *); +extern int nni_ep_create_dialer(nni_ep **, nni_sock *, const char *); +extern int nni_ep_create_listener(nni_ep **, nni_sock *, const char *); +extern void nni_ep_stop(nni_ep *); +extern int nni_ep_shutdown(nni_ep *); +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 void nni_ep_pipe_remove(nni_ep *, nni_pipe *); extern const char *nni_ep_url(nni_ep *); diff --git a/src/core/options.c b/src/core/options.c index b7934a06..e9a79f35 100644 --- a/src/core/options.c +++ b/src/core/options.c @@ -344,23 +344,6 @@ nni_option_lookup(const char *name) return (id); } -const char * -nni_option_name(int id) -{ - nni_option *opt; - const char *name = NULL; - - nni_mtx_lock(&nni_option_lk); - NNI_LIST_FOREACH (&nni_options, opt) { - if (id == opt->o_id) { - name = opt->o_name; - break; - } - } - nni_mtx_unlock(&nni_option_lk); - return (name); -} - int nni_option_register(const char *name, int *idp) { @@ -390,6 +373,15 @@ nni_option_sys_fini(void) nni_option_nextid = 0; } +int nni_optid_raw; +int nni_optid_recvmaxsz; +int nni_optid_maxttl; +int nni_optid_protocol; +int nni_optid_transport; +int nni_optid_locaddr; +int nni_optid_remaddr; +int nni_optid_surveyor_surveytime; + int nni_option_sys_init(void) { @@ -398,28 +390,15 @@ nni_option_sys_init(void) nni_option_nextid = 0x10000; int rv; -#define OPT_REGISTER(o) nni_option_register(nng_opt_##o, &nng_optid_##o) +#define OPT_REGISTER(o) nni_option_register(nng_opt_##o, &nni_optid_##o) // Register our well-known options. if (((rv = OPT_REGISTER(raw)) != 0) || - ((rv = OPT_REGISTER(linger)) != 0) || - ((rv = OPT_REGISTER(recvbuf)) != 0) || - ((rv = OPT_REGISTER(sendbuf)) != 0) || - ((rv = OPT_REGISTER(recvtimeo)) != 0) || - ((rv = OPT_REGISTER(sendtimeo)) != 0) || - ((rv = OPT_REGISTER(reconnmint)) != 0) || - ((rv = OPT_REGISTER(reconnmaxt)) != 0) || ((rv = OPT_REGISTER(recvmaxsz)) != 0) || ((rv = OPT_REGISTER(maxttl)) != 0) || ((rv = OPT_REGISTER(protocol)) != 0) || ((rv = OPT_REGISTER(transport)) != 0) || ((rv = OPT_REGISTER(locaddr)) != 0) || ((rv = OPT_REGISTER(remaddr)) != 0) || - ((rv = OPT_REGISTER(recvfd)) != 0) || - ((rv = OPT_REGISTER(sendfd)) != 0) || - ((rv = OPT_REGISTER(url)) != 0) || - ((rv = OPT_REGISTER(req_resendtime)) != 0) || - ((rv = OPT_REGISTER(sub_subscribe)) != 0) || - ((rv = OPT_REGISTER(sub_unsubscribe)) != 0) || ((rv = OPT_REGISTER(surveyor_surveytime)) != 0)) { nni_option_sys_fini(); return (rv); diff --git a/src/core/options.h b/src/core/options.h index 64036db1..418a5d00 100644 --- a/src/core/options.h +++ b/src/core/options.h @@ -72,4 +72,14 @@ extern const char *nni_option_name(int); extern int nni_option_sys_init(void); extern void nni_option_sys_fini(void); +extern int nni_optid_raw; +extern int nni_optid_recvmaxsz; +extern int nni_optid_maxttl; +extern int nni_optid_protocol; +extern int nni_optid_transport; +extern int nni_optid_locaddr; +extern int nni_optid_remaddr; +extern int nni_optid_req_resendtime; +extern int nni_optid_surveyor_surveytime; + #endif // CORE_OPTIONS_H diff --git a/src/core/pipe.c b/src/core/pipe.c index edc8c15d..7351997a 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -10,6 +10,8 @@ #include "core/nng_impl.h" +#include <string.h> + // This file contains functions relating to pipes. // // Operations on pipes (to the transport) are generally blocking operations, @@ -281,8 +283,7 @@ nni_pipe_create(nni_ep *ep, void *tdata) rv = nni_idhash_alloc(nni_pipes, &p->p_id, p); nni_mtx_unlock(&nni_pipe_lk); - if ((rv != 0) || - ((rv = nni_ep_pipe_add(ep, p)) != 0) || + if ((rv != 0) || ((rv = nni_ep_pipe_add(ep, p)) != 0) || ((rv = nni_sock_pipe_add(sock, p)) != 0)) { nni_pipe_destroy(p); } @@ -291,21 +292,18 @@ nni_pipe_create(nni_ep *ep, void *tdata) } int -nni_pipe_getopt(nni_pipe *p, int opt, void *val, size_t *szp) +nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp) { - int rv = NNG_ENOTSUP; + nni_tran_pipe_option *po; - if (opt == nng_optid_url) { - return (nni_getopt_str(p->p_url, val, szp)); - } - if (p->p_tran_ops.p_getopt != NULL) { - rv = p->p_tran_ops.p_getopt(p->p_tran_data, opt, val, szp); - } - if (rv == NNG_ENOTSUP) { - // Maybe its a generic socket option? - rv = nni_sock_getopt(p->p_sock, opt, val, szp); + for (po = p->p_tran_ops.p_options; po && po->po_name; po++) { + if (strcmp(po->po_name, name) != 0) { + continue; + } + return (po->po_getopt(p->p_tran_data, val, szp)); } - return (rv); + // Maybe the endpoint knows? + return (nni_ep_getopt(p->p_ep, name, val, szp)); } void diff --git a/src/core/pipe.h b/src/core/pipe.h index bb55a8cd..54629810 100644 --- a/src/core/pipe.h +++ b/src/core/pipe.h @@ -57,7 +57,7 @@ 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 *, int, void *, size_t *sizep); +extern int nni_pipe_getopt(nni_pipe *, const char *, void *, size_t *); // 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 9416b2bf..0c0d93ce 100644 --- a/src/core/protocol.h +++ b/src/core/protocol.h @@ -47,6 +47,12 @@ struct nni_proto_pipe_ops { void (*pipe_stop)(void *); }; +struct nni_proto_sock_option { + const char *pso_name; + int (*pso_getopt)(void *, void *, size_t *); + int (*pso_setopt)(void *, const void *, size_t); +}; + struct nni_proto_sock_ops { // sock_init creates the protocol instance, which will be stored on // the socket. This is run without the sock lock held, and allocates @@ -68,10 +74,6 @@ struct nni_proto_sock_ops { // it can signal the socket worker threads to exit. void (*sock_close)(void *); - // Option manipulation. These may be NULL. - int (*sock_setopt)(void *, int, const void *, size_t); - int (*sock_getopt)(void *, int, void *, size_t *); - // Receive filter. This may be NULL, but if it isn't, then // messages coming into the system are routed here just before being // delivered to the application. To drop the message, the prtocol @@ -81,6 +83,9 @@ struct nni_proto_sock_ops { // Send filter. This may be NULL, but if it isn't, then messages // here are filtered just after they come from the application. nni_msg *(*sock_sfilter)(void *, nni_msg *); + + // Options. Must not be NULL. Final entry should have NULL name. + nni_proto_sock_option *sock_options; }; typedef struct nni_proto_id { diff --git a/src/core/socket.c b/src/core/socket.c index 03ae5a9d..dc305b48 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -18,9 +18,15 @@ static nni_list nni_sock_list; static nni_idhash *nni_sock_hash; static nni_mtx nni_sock_lk; +typedef struct nni_socket_option { + const char *so_name; + int (*so_getopt)(nni_sock *, void *, size_t *); + int (*so_setopt)(nni_sock *, const void *, size_t); +} nni_socket_option; + typedef struct nni_sockopt { nni_list_node node; - int opt; + char * name; size_t sz; void * data; } nni_sockopt; @@ -71,9 +77,158 @@ struct nni_socket { nni_notifyfd s_recv_fd; }; +#if 0 +if (opt == nni_optid_reconnmint) { + rv = nni_setopt_usec(&s->s_reconn, val, size); +} else if (opt == nni_optid_reconnmaxt) { + rv = nni_setopt_usec(&s->s_reconnmax, val, size); +} else if (opt == nni_optid_recvtimeo) { + rv = nni_setopt_usec(&s->s_rcvtimeo, val, size); +} else if (opt == nni_optid_sendtimeo) { + rv = nni_setopt_usec(&s->s_sndtimeo, val, size); +} else if (opt == nni_optid_sendbuf) { + rv = nni_setopt_buf(s->s_uwq, val, size); +} else if (opt == nni_optid_recvbuf) { + rv = nni_setopt_buf(s->s_urq, val, size); +} else if ((opt == nni_optid_sendfd) || (opt == nni_optid_recvfd) || + (opt == nni_optid_locaddr) || (opt == nni_optid_remaddr)) { + // these options can be read, but cannot be set + rv = NNG_EINVAL; +#endif + +static int +nni_sock_getopt_sendfd(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_fd(s, &s->s_send_fd, NNG_EV_CAN_SND, buf, szp)); +} + +static int +nni_sock_getopt_recvfd(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_fd(s, &s->s_recv_fd, NNG_EV_CAN_RCV, buf, szp)); +} + +static int +nni_sock_setopt_recvtimeo(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_usec(&s->s_rcvtimeo, buf, sz)); +} + +static int +nni_sock_getopt_recvtimeo(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_usec(s->s_rcvtimeo, buf, szp)); +} + +static int +nni_sock_setopt_sendtimeo(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_usec(&s->s_sndtimeo, buf, sz)); +} + +static int +nni_sock_getopt_sendtimeo(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_usec(s->s_sndtimeo, buf, szp)); +} + +static int +nni_sock_setopt_reconnmint(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_usec(&s->s_reconn, buf, sz)); +} + +static int +nni_sock_getopt_reconnmint(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_usec(s->s_reconn, buf, szp)); +} + +static int +nni_sock_setopt_reconnmaxt(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_usec(&s->s_reconnmax, buf, sz)); +} + +static int +nni_sock_getopt_reconnmaxt(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_usec(s->s_reconnmax, buf, szp)); +} + +static int +nni_sock_setopt_recvbuf(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_buf(s->s_urq, buf, sz)); +} + +static int +nni_sock_getopt_recvbuf(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_buf(s->s_urq, buf, szp)); +} + +static int +nni_sock_setopt_sendbuf(nni_sock *s, const void *buf, size_t sz) +{ + return (nni_setopt_buf(s->s_uwq, buf, sz)); +} + +static int +nni_sock_getopt_sendbuf(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_buf(s->s_uwq, buf, szp)); +} + +static const nni_socket_option nni_sock_options[] = { + { + .so_name = NNG_OPT_RECVTIMEO, + .so_getopt = nni_sock_getopt_recvtimeo, + .so_setopt = nni_sock_setopt_recvtimeo, + }, + { + .so_name = NNG_OPT_SENDTIMEO, + .so_getopt = nni_sock_getopt_sendtimeo, + .so_setopt = nni_sock_setopt_sendtimeo, + }, + { + .so_name = NNG_OPT_RECVFD, + .so_getopt = nni_sock_getopt_recvfd, + .so_setopt = NULL, + }, + { + .so_name = NNG_OPT_SENDFD, + .so_getopt = nni_sock_getopt_sendfd, + .so_setopt = NULL, + }, + { + .so_name = NNG_OPT_RECVBUF, + .so_getopt = nni_sock_getopt_recvbuf, + .so_setopt = nni_sock_setopt_recvbuf, + }, + { + .so_name = NNG_OPT_SENDBUF, + .so_getopt = nni_sock_getopt_sendbuf, + .so_setopt = nni_sock_setopt_sendbuf, + }, + { + .so_name = NNG_OPT_RECONNMINT, + .so_getopt = nni_sock_getopt_reconnmint, + .so_setopt = nni_sock_setopt_reconnmint, + }, + { + .so_name = NNG_OPT_RECONNMAXT, + .so_getopt = nni_sock_getopt_reconnmaxt, + .so_setopt = nni_sock_setopt_reconnmaxt, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static void nni_free_opt(nni_sockopt *opt) { + nni_strfree(opt->name); nni_free(opt->data, opt->sz); NNI_FREE_STRUCT(opt); } @@ -366,17 +521,17 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto) if (((rv = nni_msgq_init(&s->s_uwq, 0)) != 0) || ((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_optid_linger, &s->s_linger, + ((rv = nni_sock_setopt(s, NNG_OPT_LINGER, &s->s_linger, sizeof(nni_duration))) != 0) || - ((rv = nni_sock_setopt(s, nng_optid_sendtimeo, &s->s_sndtimeo, + ((rv = nni_sock_setopt(s, NNG_OPT_SENDTIMEO, &s->s_sndtimeo, sizeof(nni_duration))) != 0) || - ((rv = nni_sock_setopt(s, nng_optid_recvtimeo, &s->s_rcvtimeo, + ((rv = nni_sock_setopt(s, NNG_OPT_RECVTIMEO, &s->s_rcvtimeo, sizeof(nni_duration))) != 0) || - ((rv = nni_sock_setopt(s, nng_optid_reconnmint, &s->s_reconn, + ((rv = nni_sock_setopt(s, NNG_OPT_RECONNMINT, &s->s_reconn, sizeof(nni_duration))) != 0) || - ((rv = nni_sock_setopt(s, nng_optid_reconnmaxt, &s->s_reconnmax, + ((rv = nni_sock_setopt(s, NNG_OPT_RECONNMAXT, &s->s_reconnmax, sizeof(nni_duration))) != 0) || - ((rv = nni_sock_setopt(s, nng_optid_recvmaxsz, &s->s_rcvmaxsz, + ((rv = nni_sock_setopt(s, NNG_OPT_RECVMAXSZ, &s->s_rcvmaxsz, sizeof(size_t))) != 0)) { nni_sock_destroy(s); return (rv); @@ -749,14 +904,16 @@ nni_sock_ep_add(nni_sock *s, nni_ep *ep) nni_mtx_unlock(&s->s_mx); return (NNG_ECLOSED); } + NNI_LIST_FOREACH (&s->s_options, sopt) { int rv; - rv = nni_ep_setopt(ep, sopt->opt, sopt->data, sopt->sz, 0); + rv = nni_ep_setopt(ep, sopt->name, sopt->data, sopt->sz); if ((rv != 0) && (rv != NNG_ENOTSUP)) { nni_mtx_unlock(&s->s_mx); return (rv); } } + nni_list_append(&s->s_eps, ep); nni_mtx_unlock(&s->s_mx); return (0); @@ -788,41 +945,48 @@ nni_sock_senderr(nni_sock *sock, int err) } int -nni_sock_setopt(nni_sock *s, int opt, const void *val, size_t size) +nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) { - int rv = NNG_ENOTSUP; - nni_ep * ep; - int commits = 0; - nni_sockopt *optv; - nni_sockopt *oldv = NULL; + int rv = NNG_ENOTSUP; + nni_ep * ep; + int commits = 0; + nni_sockopt * optv; + nni_sockopt * oldv = NULL; + const nni_socket_option * sso; + const nni_proto_sock_option *pso; nni_mtx_lock(&s->s_mx); if (s->s_closing) { nni_mtx_unlock(&s->s_mx); return (NNG_ECLOSED); } - if (s->s_sock_ops.sock_setopt != NULL) { - rv = s->s_sock_ops.sock_setopt(s->s_data, opt, val, size); - if (rv != NNG_ENOTSUP) { + + // Protocol options. + for (pso = s->s_sock_ops.sock_options; pso->pso_name != NULL; pso++) { + if (strcmp(pso->pso_name, name) != 0) { + continue; + } + if (pso->pso_setopt == NULL) { nni_mtx_unlock(&s->s_mx); - return (rv); + return (NNG_EREADONLY); } + rv = pso->pso_setopt(s->s_data, val, size); + nni_mtx_unlock(&s->s_mx); + return (rv); } - // Some options do not go down to transports. Handle them - // directly. - if (opt == nng_optid_reconnmint) { - rv = nni_setopt_usec(&s->s_reconn, val, size); - } else if (opt == nng_optid_reconnmaxt) { - rv = nni_setopt_usec(&s->s_reconnmax, val, size); - } else if (opt == nng_optid_sendbuf) { - rv = nni_setopt_buf(s->s_uwq, val, size); - } else if (opt == nng_optid_recvbuf) { - rv = nni_setopt_buf(s->s_urq, val, size); - } else if ((opt == nng_optid_sendfd) || (opt == nng_optid_recvfd) || - (opt == nng_optid_locaddr) || (opt == nng_optid_remaddr)) { - // these options can be read, but cannot be set - rv = NNG_EINVAL; + // Some options do not go down to transports. Handle them directly. + for (sso = nni_sock_options; sso->so_name != NULL; sso++) { + if (strcmp(sso->so_name, name) != 0) { + continue; + } + if (sso->so_setopt == NULL) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EREADONLY); + } + rv = sso->so_setopt(s, val, size); + nni_mtx_unlock(&s->s_mx); + return (rv); } nni_mtx_unlock(&s->s_mx); @@ -832,20 +996,16 @@ nni_sock_setopt(nni_sock *s, int opt, const void *val, size_t size) return (rv); } - // 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(opt, val, 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); // Also check a few generic things. We do this if no transport - // check was found, or even if a transport rejected one of the - // settings. + // was found, or even if a transport rejected one of the settings. if ((rv == NNG_ENOTSUP) || (rv == 0)) { - if ((opt == nng_optid_linger) || - (opt == nng_optid_sendtimeo) || - (opt == nng_optid_recvtimeo)) { + if ((strcmp(name, NNG_OPT_LINGER) == 0)) { rv = nni_chkopt_usec(val, size); - } else if (opt == nng_optid_recvmaxsz) { + } 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); @@ -864,14 +1024,18 @@ nni_sock_setopt(nni_sock *s, int opt, const void *val, size_t size) NNI_FREE_STRUCT(optv); return (NNG_ENOMEM); } + if ((optv->name = nni_strdup(name)) == NULL) { + nni_free(optv->data, size); + NNI_FREE_STRUCT(optv); + return (NNG_ENOMEM); + } memcpy(optv->data, val, size); - optv->opt = opt; - optv->sz = size; + optv->sz = size; NNI_LIST_NODE_INIT(&optv->node); nni_mtx_lock(&s->s_mx); NNI_LIST_FOREACH (&s->s_options, oldv) { - if (oldv->opt == opt) { + if (strcmp(oldv->name, name) == 0) { if ((oldv->sz != size) || (memcmp(oldv->data, val, size) != 0)) { break; @@ -889,7 +1053,7 @@ nni_sock_setopt(nni_sock *s, int opt, 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, opt, optv->data, size, 0); + x = nni_ep_setopt(ep, optv->name, optv->data, size); if (x != NNG_ENOTSUP) { if ((rv = x) != 0) { nni_mtx_unlock(&s->s_mx); @@ -903,12 +1067,8 @@ nni_sock_setopt(nni_sock *s, int opt, const void *val, size_t size) // behavior, we save a local value. Note that the transport // will already have had a chance to veto this. - if (opt == nng_optid_linger) { + if (strcmp(name, NNG_OPT_LINGER) == 0) { rv = nni_setopt_usec(&s->s_linger, val, size); - } else if (opt == nng_optid_sendtimeo) { - rv = nni_setopt_usec(&s->s_sndtimeo, val, size); - } else if (opt == nng_optid_recvtimeo) { - rv = nni_setopt_usec(&s->s_rcvtimeo, val, size); } if (rv == 0) { @@ -931,52 +1091,63 @@ nni_sock_setopt(nni_sock *s, int opt, const void *val, size_t size) } int -nni_sock_getopt(nni_sock *s, int opt, void *val, size_t *szp) +nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp) { - int rv = NNG_ENOTSUP; - nni_sockopt *sopt; + int rv = NNG_ENOTSUP; + nni_sockopt * sopt; + int opt; + const nni_socket_option * sso; + const nni_proto_sock_option *pso; + + opt = nni_option_lookup(name); nni_mtx_lock(&s->s_mx); if (s->s_closing) { nni_mtx_unlock(&s->s_mx); return (NNG_ECLOSED); } - if (s->s_sock_ops.sock_getopt != NULL) { - rv = s->s_sock_ops.sock_getopt(s->s_data, opt, val, szp); - if (rv != NNG_ENOTSUP) { + + // Protocol specific options. + for (pso = s->s_sock_ops.sock_options; pso->pso_name != NULL; pso++) { + if (strcmp(name, pso->pso_name) != 0) { + continue; + } + if (pso->pso_getopt == NULL) { nni_mtx_unlock(&s->s_mx); - return (rv); + return (NNG_EWRITEONLY); } + 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. - if (opt == nng_optid_sendbuf) { - rv = nni_getopt_buf(s->s_uwq, val, szp); - } else if (opt == nng_optid_recvbuf) { - rv = nni_getopt_buf(s->s_urq, val, szp); - } else if (opt == nng_optid_sendfd) { - rv = nni_getopt_fd(s, &s->s_send_fd, NNG_EV_CAN_SND, val, szp); - } else if (opt == nng_optid_recvfd) { - rv = nni_getopt_fd(s, &s->s_recv_fd, NNG_EV_CAN_RCV, val, szp); - } else if (opt == nng_optid_reconnmint) { - rv = nni_getopt_usec(s->s_reconn, val, szp); - } else if (opt == nng_optid_reconnmaxt) { - rv = nni_getopt_usec(s->s_reconnmax, val, szp); - } else { - NNI_LIST_FOREACH (&s->s_options, sopt) { - if (sopt->opt == opt) { - size_t sz = sopt->sz; - if (sopt->sz > *szp) { - sz = *szp; - } - *szp = sopt->sz; - memcpy(val, sopt->data, sz); - rv = 0; - break; + // Options that are handled by socket core, and never passed down. + for (sso = nni_sock_options; sso->so_name != NULL; sso++) { + if (strcmp(name, sso->so_name) != 0) { + continue; + } + if (sso->so_getopt == NULL) { + nni_mtx_unlock(&s->s_mx); + return (NNG_EWRITEONLY); + } + rv = sso->so_getopt(s, val, szp); + nni_mtx_unlock(&s->s_mx); + return (rv); + } + + NNI_LIST_FOREACH (&s->s_options, sopt) { + if (strcmp(sopt->name, name) == 0) { + size_t sz = sopt->sz; + if (sopt->sz > *szp) { + sz = *szp; } + *szp = sopt->sz; + memcpy(val, sopt->data, sz); + rv = 0; + break; } } + nni_mtx_unlock(&s->s_mx); return (rv); } diff --git a/src/core/socket.h b/src/core/socket.h index 931fefac..850c4641 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -22,10 +22,10 @@ extern void nni_sock_closeall(void); extern int nni_sock_shutdown(nni_sock *); extern uint16_t nni_sock_proto(nni_sock *); extern uint16_t nni_sock_peer(nni_sock *); -extern int nni_sock_setopt(nni_sock *, int, const void *, size_t); -extern int nni_sock_getopt(nni_sock *, int, void *, size_t *); -extern int nni_sock_recvmsg(nni_sock *, nni_msg **, int); -extern int nni_sock_sendmsg(nni_sock *, nni_msg *, int); +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_recvmsg(nni_sock *, nni_msg **, int); +extern int nni_sock_sendmsg(nni_sock *, nni_msg *, int); extern uint32_t nni_sock_id(nni_sock *); extern void nni_sock_lock(nni_sock *); diff --git a/src/core/transport.c b/src/core/transport.c index eead861b..2697ce74 100644 --- a/src/core/transport.c +++ b/src/core/transport.c @@ -97,19 +97,29 @@ nni_tran_find(const char *addr) } int -nni_tran_chkopt(int o, const void *v, size_t sz) +nni_tran_chkopt(const char *name, const void *v, size_t sz) { nni_transport *t; int rv = NNG_ENOTSUP; + nni_mtx_lock(&nni_tran_lk); NNI_LIST_FOREACH (&nni_tran_list, t) { - int x; - if (t->t_tran.tran_chkopt == NULL) { - continue; - } - if ((x = t->t_tran.tran_chkopt(o, v, sz)) != NNG_ENOTSUP) { - if ((rv = x) != 0) { - break; + const nni_tran_ep * ep; + const nni_tran_ep_option *eo; + + // Generally we look for endpoint options. + ep = t->t_tran.tran_ep; + for (eo = ep->ep_options; eo && eo->eo_name != NULL; eo++) { + if (strcmp(name, eo->eo_name) != 0) { + continue; + } + if (eo->eo_setopt == NULL) { + nni_mtx_unlock(&nni_tran_lk); + return (NNG_EREADONLY); + } + if ((rv = eo->eo_setopt(NULL, v, sz)) != 0) { + nni_mtx_unlock(&nni_tran_lk); + return (rv); } } } diff --git a/src/core/transport.h b/src/core/transport.h index 2891d8a4..b82e2c92 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -29,11 +29,6 @@ struct nni_tran { // tran_pipe links our pipe-specific operations. const nni_tran_pipe *tran_pipe; - // tran_chkopt, if not NULL, is used to validate that the - // option data presented is valid. This allows an option to - // be set on a socket, even if no endpoints are configured. - int (*tran_chkopt)(int, const void *, size_t); - // tran_init, if not NULL, is called once during library // initialization. int (*tran_init)(void); @@ -54,10 +49,31 @@ struct nni_tran { #define NNI_TRANSPORT_V0 0x54520000 #define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V0 +// Endpoint option handlers. +struct nni_tran_ep_option { + // eo_name is the name of the option. + const char *eo_name; + + // eo_getopt retrieves the value of the option. + int (*eo_getopt)(void *, void *, size_t *); + + // eo_set sets the value of the option. If the first argument + // (the endpoint) is NULL, then no actual set operation should be + // performed, but the option should be sanity tested for presence + // and size. (This permits the core to validate that an option + // is reasonable and be set even before endpoints are created.) + int (*eo_setopt)(void *, const void *, size_t); +}; + // Endpoint operations are called by the socket in a protocol-independent // fashion. The socket makes individual calls, which are expected to block -// if appropriate (except for destroy). Endpoints are unable to call back -// into the socket, to prevent recusive entry and deadlock. +// if appropriate (except for destroy), or run asynchronously if an aio +// is provided. Endpoints are unable to call back into the socket, to prevent +// recusive entry and deadlock. +// +// For a given endpoint, the framework holds a lock so that each entry +// point is run exclusively of the others. (Transports must still guard +// against any asynchronous operations they manage themselves, though.) struct nni_tran_ep { // ep_init creates a vanilla endpoint. The value created is // used for the first argument for all other endpoint functions. @@ -86,11 +102,20 @@ struct nni_tran_ep { // not affect pipes that have already been created. void (*ep_close)(void *); - // ep_setopt sets an endpoint (transport-specific) option. - int (*ep_setopt)(void *, int, const void *, size_t); + // ep_options is an array of endpoint options. The final element must + // have a NULL name. If this member is NULL, then no transport specific + // options are available. + nni_tran_ep_option *ep_options; +}; + +// Pipe option handlers. We only have get for pipes; once a pipe is created +// no options may be set on it. +struct nni_tran_pipe_option { + // po_name is the name of the option. + const char *po_name; - // ep_getopt gets an endpoint (transport-specific) option. - int (*ep_getopt)(void *, int, void *, size_t *); + // po_getopt retrieves the value of the option. + int (*po_getopt)(void *, void *, size_t *); }; // Pipe operations are entry points called by the socket. These may be called @@ -132,15 +157,16 @@ struct nni_tran_pipe { // transport specific manner is appropriate. uint16_t (*p_peer)(void *); - // p_getopt gets an pipe (transport-specific) property. These values - // may not be changed once the pipe is created. - int (*p_getopt)(void *, int, void *, size_t *); + // 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. + nni_tran_pipe_option *p_options; }; // These APIs are used by the framework internally, and not for use by // transport implementations. extern nni_tran *nni_tran_find(const char *); -extern int nni_tran_chkopt(int, const void *, size_t); +extern int nni_tran_chkopt(const char *, const void *, size_t); extern int nni_tran_sys_init(void); extern void nni_tran_sys_fini(void); extern int nni_tran_register(const nni_tran *); @@ -328,131 +328,140 @@ nng_dialer_start(nng_dialer id, int flags) } static int -nng_ep_setopt(uint32_t id, int opt, const void *val, size_t sz) +nng_ep_setopt(uint32_t id, const char *name, const void *val, size_t sz) { nni_ep *ep; int rv; + + if ((rv = nni_init()) != 0) { + return (rv); + } if ((rv = nni_ep_find(&ep, id)) != 0) { return (rv); } - rv = nni_ep_setopt(ep, opt, val, sz, 1); + rv = nni_ep_setopt(ep, name, val, sz); nni_ep_rele(ep); return (rv); } static int -nng_ep_getopt(uint32_t id, int opt, void *val, size_t *szp) +nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp) { nni_ep *ep; int rv; + + if ((rv = nni_init()) != 0) { + return (rv); + } if ((rv = nni_ep_find(&ep, id)) != 0) { return (rv); } - rv = nni_ep_getopt(ep, opt, val, szp); + rv = nni_ep_getopt(ep, name, val, szp); nni_ep_rele(ep); return (rv); } int -nng_dialer_setopt(nng_dialer id, int opt, const void *v, size_t sz) +nng_dialer_setopt(nng_dialer id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, opt, v, sz)); + return (nng_ep_setopt(id, name, v, sz)); } int -nng_dialer_setopt_int(nng_dialer id, int opt, int val) +nng_dialer_setopt_int(nng_dialer id, const char *name, int val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_dialer_setopt_size(nng_dialer id, int opt, size_t val) +nng_dialer_setopt_size(nng_dialer id, const char *name, size_t val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_dialer_setopt_usec(nng_dialer id, int opt, uint64_t val) +nng_dialer_setopt_usec(nng_dialer id, const char *name, uint64_t val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_dialer_getopt(nng_dialer id, int opt, void *val, size_t *szp) +nng_dialer_getopt(nng_dialer id, const char *name, void *val, size_t *szp) { - return (nng_ep_getopt(id, opt, val, szp)); + return (nng_ep_getopt(id, name, val, szp)); } int -nng_dialer_getopt_int(nng_dialer id, int opt, int *valp) +nng_dialer_getopt_int(nng_dialer id, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } int -nng_dialer_getopt_size(nng_dialer id, int opt, size_t *valp) +nng_dialer_getopt_size(nng_dialer id, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } int -nng_dialer_getopt_usec(nng_dialer id, int opt, uint64_t *valp) +nng_dialer_getopt_usec(nng_dialer id, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } int -nng_listener_setopt(nng_listener id, int opt, const void *v, size_t sz) +nng_listener_setopt( + nng_listener id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, opt, v, sz)); + return (nng_ep_setopt(id, name, v, sz)); } int -nng_listener_setopt_int(nng_listener id, int opt, int val) +nng_listener_setopt_int(nng_listener id, const char *name, int val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_listener_setopt_size(nng_listener id, int opt, size_t val) +nng_listener_setopt_size(nng_listener id, const char *name, size_t val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_listener_setopt_usec(nng_listener id, int opt, uint64_t val) +nng_listener_setopt_usec(nng_listener id, const char *name, uint64_t val) { - return (nng_ep_setopt(id, opt, &val, sizeof(val))); + return (nng_ep_setopt(id, name, &val, sizeof(val))); } int -nng_listener_getopt(nng_listener id, int opt, void *val, size_t *szp) +nng_listener_getopt(nng_listener id, const char *name, void *val, size_t *szp) { - return (nng_ep_getopt(id, opt, val, szp)); + return (nng_ep_getopt(id, name, val, szp)); } int -nng_listener_getopt_int(nng_listener id, int opt, int *valp) +nng_listener_getopt_int(nng_listener id, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } int -nng_listener_getopt_size(nng_listener id, int opt, size_t *valp) +nng_listener_getopt_size(nng_listener id, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } int -nng_listener_getopt_usec(nng_listener id, int opt, uint64_t *valp) +nng_listener_getopt_usec(nng_listener id, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, opt, valp, &sz)); + return (nng_ep_getopt(id, name, valp, &sz)); } static int @@ -481,71 +490,77 @@ nng_listener_close(nng_listener l) } int -nng_setopt(nng_socket sid, int opt, const void *val, size_t sz) +nng_setopt(nng_socket sid, const char *name, const void *val, size_t sz) { nni_sock *sock; int rv; + if ((rv = nni_init()) != 0) { + return (rv); + } if ((rv = nni_sock_find(&sock, sid)) != 0) { return (rv); } - rv = nni_sock_setopt(sock, opt, val, sz); + rv = nni_sock_setopt(sock, name, val, sz); nni_sock_rele(sock); return (rv); } int -nng_getopt(nng_socket sid, int opt, void *val, size_t *szp) +nng_getopt(nng_socket sid, const char *name, void *val, size_t *szp) { nni_sock *sock; int rv; + if ((rv = nni_init()) != 0) { + return (rv); + } if ((rv = nni_sock_find(&sock, sid)) != 0) { return (rv); } - rv = nni_sock_getopt(sock, opt, val, szp); + rv = nni_sock_getopt(sock, name, val, szp); nni_sock_rele(sock); return (rv); } // Convenience option wrappers. int -nng_setopt_int(nng_socket sid, int opt, int val) +nng_setopt_int(nng_socket sid, const char *name, int val) { - return (nng_setopt(sid, opt, &val, sizeof(val))); + return (nng_setopt(sid, name, &val, sizeof(val))); } int -nng_setopt_size(nng_socket sid, int opt, size_t val) +nng_setopt_size(nng_socket sid, const char *name, size_t val) { - return (nng_setopt(sid, opt, &val, sizeof(val))); + return (nng_setopt(sid, name, &val, sizeof(val))); } int -nng_setopt_usec(nng_socket sid, int opt, uint64_t val) +nng_setopt_usec(nng_socket sid, const char *name, uint64_t val) { - return (nng_setopt(sid, opt, &val, sizeof(val))); + return (nng_setopt(sid, name, &val, sizeof(val))); } int -nng_getopt_int(nng_socket sid, int opt, int *valp) +nng_getopt_int(nng_socket sid, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, opt, valp, &sz)); + return (nng_getopt(sid, name, valp, &sz)); } int -nng_getopt_size(nng_socket sid, int opt, size_t *valp) +nng_getopt_size(nng_socket sid, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, opt, valp, &sz)); + return (nng_getopt(sid, name, valp, &sz)); } int -nng_getopt_usec(nng_socket sid, int opt, uint64_t *valp) +nng_getopt_usec(nng_socket sid, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_getopt(sid, opt, valp, &sz)); + return (nng_getopt(sid, name, valp, &sz)); } nng_notify * @@ -642,8 +657,10 @@ static const struct { { NNG_ENOFILES, "Out of files" }, { NNG_ENOSPC, "Out of space" }, { NNG_EEXIST, "Resource already exists" }, + { NNG_EREADONLY, "Read only resource" }, + { NNG_EWRITEONLY, "Write only resource" }, { NNG_EINTERNAL, "Internal error detected" }, - { 0, NULL } + { 0, NULL }, // clang-format on }; @@ -675,15 +692,18 @@ nng_strerror(int num) } int -nng_pipe_getopt(nng_pipe id, int opt, void *val, size_t *sizep) +nng_pipe_getopt(nng_pipe id, const char *name, void *val, size_t *sizep) { int rv; nni_pipe *p; + if ((rv = nni_init()) < 0) { + return (rv); + } if ((rv = nni_pipe_find(&p, id)) != 0) { return (rv); } - rv = nni_pipe_getopt(p, opt, val, sizep); + rv = nni_pipe_getopt(p, name, val, sizep); nni_pipe_rele(p); return (rv); } @@ -691,7 +711,7 @@ nng_pipe_getopt(nng_pipe id, int opt, void *val, size_t *sizep) int nng_pipe_close(nng_pipe id) { - int rv; + int rv; nni_pipe *p; if ((rv = nni_pipe_find(&p, id)) != 0) { @@ -893,20 +913,6 @@ nng_msg_getopt(nng_msg *msg, int opt, void *ptr, size_t *szp) return (nni_msg_getopt(msg, opt, ptr, szp)); } -int -nng_option_lookup(const char *name) -{ - (void) nni_init(); - return (nni_option_lookup(name)); -} - -const char * -nng_option_name(int id) -{ - (void) nni_init(); - return (nni_option_name(id)); -} - #if 0 int nng_snapshot_create(nng_socket sock, nng_snapshot **snapp) @@ -984,7 +990,7 @@ nng_thread_create(void **thrp, void (*func)(void *), void *arg) nni_thr *thr; int rv; - nni_init(); + (void) nni_init(); if ((thr = NNI_ALLOC_STRUCT(thr)) == NULL) { return (NNG_ENOMEM); @@ -1011,47 +1017,12 @@ nng_thread_destroy(void *arg) // Constant option definitions. These are for well-known options, // so that the vast majority of consumers don't have to look these up. -const char *nng_opt_raw = "raw"; -const char *nng_opt_linger = "linger"; -const char *nng_opt_recvbuf = "recv-buffer"; -const char *nng_opt_sendbuf = "send-buffer"; -const char *nng_opt_recvtimeo = "recv-timeout"; -const char *nng_opt_sendtimeo = "send-timeout"; -const char *nng_opt_recvmaxsz = "recv-size-max"; -const char *nng_opt_reconnmint = "reconnect-time-min"; -const char *nng_opt_reconnmaxt = "reconnect-time-min"; -const char *nng_opt_maxttl = "ttl-max"; -const char *nng_opt_protocol = "protocol"; -const char *nng_opt_transport = "transport"; -const char *nng_opt_recvfd = "recv-fd"; -const char *nng_opt_sendfd = "send-fd"; -const char *nng_opt_locaddr = "local-address"; -const char *nng_opt_remaddr = "remote-address"; -const char *nng_opt_url = "url"; +const char *nng_opt_raw = "raw"; +const char *nng_opt_recvmaxsz = "recv-size-max"; +const char *nng_opt_maxttl = "ttl-max"; +const char *nng_opt_protocol = "protocol"; +const char *nng_opt_transport = "transport"; +const char *nng_opt_locaddr = "local-address"; +const char *nng_opt_remaddr = "remote-address"; // Well known protocol options. -const char *nng_opt_req_resendtime = "req:resend-time"; -const char *nng_opt_sub_subscribe = "sub:subscribe"; -const char *nng_opt_sub_unsubscribe = "sub:unsubscribe"; const char *nng_opt_surveyor_surveytime = "surveyor:survey-time"; - -int nng_optid_raw; -int nng_optid_linger; -int nng_optid_recvbuf; -int nng_optid_sendbuf; -int nng_optid_recvtimeo; -int nng_optid_sendtimeo; -int nng_optid_recvmaxsz; -int nng_optid_reconnmint; -int nng_optid_reconnmaxt; -int nng_optid_maxttl; -int nng_optid_protocol; -int nng_optid_transport; -int nng_optid_recvfd; -int nng_optid_sendfd; -int nng_optid_locaddr; -int nng_optid_remaddr; -int nng_optid_url; -int nng_optid_req_resendtime; -int nng_optid_sub_subscribe; -int nng_optid_sub_unsubscribe; -int nng_optid_surveyor_surveytime; @@ -86,16 +86,16 @@ NNG_DECL uint16_t nng_protocol(nng_socket); NNG_DECL uint16_t nng_peer(nng_socket); // nng_setopt sets an option for a specific socket. -NNG_DECL int nng_setopt(nng_socket, int, const void *, size_t); -NNG_DECL int nng_setopt_int(nng_socket, int, int); -NNG_DECL int nng_setopt_usec(nng_socket, int, uint64_t); -NNG_DECL int nng_setopt_size(nng_socket, int, size_t); +NNG_DECL int nng_setopt(nng_socket, const char *, const void *, size_t); +NNG_DECL int nng_setopt_int(nng_socket, const char *, int); +NNG_DECL int nng_setopt_usec(nng_socket, const char *, uint64_t); +NNG_DECL int nng_setopt_size(nng_socket, const char *, size_t); // nng_socket_getopt obtains the option for a socket. -NNG_DECL int nng_getopt(nng_socket, int, void *, size_t *); -NNG_DECL int nng_getopt_int(nng_socket, int, int *); -NNG_DECL int nng_getopt_usec(nng_socket, int, uint64_t *); -NNG_DECL int nng_getopt_size(nng_socket, int, size_t *); +NNG_DECL int nng_getopt(nng_socket, const char *, void *, size_t *); +NNG_DECL int nng_getopt_int(nng_socket, const char *, int *); +NNG_DECL int nng_getopt_usec(nng_socket, const char *, uint64_t *); +NNG_DECL int nng_getopt_size(nng_socket, const char *, size_t *); // nng_notify_func is a user function that is executed upon certain // events. See below. @@ -199,35 +199,36 @@ NNG_DECL int nng_listener_close(nng_listener); // nng_dialer_setopt sets an option for a specific dialer. Note // dialer options may not be altered on a running dialer. -NNG_DECL int nng_dialer_setopt(nng_dialer, int, const void *, size_t); -NNG_DECL int nng_dialer_setopt_int(nng_dialer, int, int); -NNG_DECL int nng_dialer_setopt_usec(nng_dialer, int, uint64_t); -NNG_DECL int nng_dialer_setopt_size(nng_dialer, int, size_t); +NNG_DECL int nng_dialer_setopt(nng_dialer, const char *, const void *, size_t); +NNG_DECL int nng_dialer_setopt_int(nng_dialer, const char *, int); +NNG_DECL int nng_dialer_setopt_usec(nng_dialer, const char *, uint64_t); +NNG_DECL int nng_dialer_setopt_size(nng_dialer, const char *, size_t); // nng_dialer_getopt obtains the option for a dialer. This will // fail for options that a particular dialer is not interested in, // even if they were set on the socket. -NNG_DECL int nng_dialer_getopt(nng_dialer, int, void *, size_t *); -NNG_DECL int nng_dialer_getopt_int(nng_dialer, int, int *); -NNG_DECL int nng_dialer_getopt_usec(nng_dialer, int, uint64_t *); -NNG_DECL int nng_dialer_getopt_size(nng_dialer, int, size_t *); +NNG_DECL int nng_dialer_getopt(nng_dialer, const char *, void *, size_t *); +NNG_DECL int nng_dialer_getopt_int(nng_dialer, const char *, int *); +NNG_DECL int nng_dialer_getopt_usec(nng_dialer, const char *, uint64_t *); +NNG_DECL int nng_dialer_getopt_size(nng_dialer, const char *, size_t *); // nng_listener_setopt sets an option for a dialer. This value is // not stored in the socket. Subsequent setopts on the socket may // override these value however. Note listener options may not be altered // on a running listener. -NNG_DECL int nng_listener_setopt(nng_dialer, int, const void *, size_t); -NNG_DECL int nng_listener_setopt_int(nng_dialer, int, int); -NNG_DECL int nng_listener_setopt_usec(nng_dialer, int, uint64_t); -NNG_DECL int nng_listener_setopt_size(nng_dialer, int, size_t); +NNG_DECL int nng_listener_setopt( + nng_listener, const char *, const void *, size_t); +NNG_DECL int nng_listener_setopt_int(nng_listener, const char *, int); +NNG_DECL int nng_listener_setopt_usec(nng_listener, const char *, uint64_t); +NNG_DECL int nng_listener_setopt_size(nng_listener, const char *, size_t); // nng_listener_getopt obtains the option for a listener. This will // fail for options that a particular listener is not interested in, // even if they were set on the socket. -NNG_DECL int nng_listener_getopt(nng_listener, int, void *, size_t *); -NNG_DECL int nng_listener_getopt_int(nng_listener, int, int *); -NNG_DECL int nng_listener_getopt_usec(nng_listener, int, uint64_t *); -NNG_DECL int nng_listener_getopt_size(nng_listener, int, size_t *); +NNG_DECL int nng_listener_getopt(nng_listener, const char *, void *, size_t *); +NNG_DECL int nng_listener_getopt_int(nng_listener, const char *, int *); +NNG_DECL int nng_listener_getopt_usec(nng_listener, const char *, uint64_t *); +NNG_DECL int nng_listener_getopt_size(nng_listener, const char *, size_t *); // nng_strerror returns a human readable string associated with the error // code supplied. @@ -320,7 +321,7 @@ NNG_DECL const char *nng_option_name(int); // we do permit an application to close a pipe. This can be useful, for // example during a connection notification, to disconnect a pipe that // is associated with an invalid or untrusted remote peer. -NNG_DECL int nng_pipe_getopt(nng_pipe, int, void *, size_t *); +NNG_DECL int nng_pipe_getopt(nng_pipe, const char *, void *, size_t *); NNG_DECL int nng_pipe_close(nng_pipe); // Flags. @@ -395,60 +396,41 @@ NNG_DECL int nng_respondent0_open(nng_socket *); #define nng_surveyor_open nng_surveyor0_open #define nng_respondent_open nng_respondent0_open -// Options. We encode option numbers as follows: -// -// <level> - 0: socket, 1: transport -// <type> - zero (socket), or transport (8 bits) -// <code> - specific value (16 bits) -#define NNG_OPT_SOCKET(c) (c) -#define NNG_OPT_TRANSPORT_OPT(t, c) (0x10000 | ((t) << 16) | (c)) +// Options. +#define NNG_OPT_RAW "raw" +#define NNG_OPT_LINGER "linger" +#define NNG_OPT_RECVBUF "recv-buffer" +#define NNG_OPT_SENDBUF "send-buffer" +#define NNG_OPT_RECVFD "recv-fd" +#define NNG_OPT_SENDFD "send-fd" +#define NNG_OPT_RECVTIMEO "recv-timeout" +#define NNG_OPT_SENDTIMEO "send-timeout" +#define NNG_OPT_LOCADDR "local-address" +#define NNG_OPT_REMADDR "remote-address" +#define NNG_OPT_URL "url" +#define NNG_OPT_MAXTTL "ttl-max" +#define NNG_OPT_PROTOCOL "protocol" +#define NNG_OPT_TRANSPORT "transport" +#define NNG_OPT_RECVMAXSZ "recv-size-max" +#define NNG_OPT_RECONNMINT "reconnect-time-min" +#define NNG_OPT_RECONNMAXT "reconnect-time-max" + +#define NNG_OPT_SUB_SUBSCRIBE "sub:subscribe" +#define NNG_OPT_SUB_UNSUBSCRIBE "sub:unsubscribe" + +#define NNG_OPT_REQ_RESENDTIME "req:resend-time" + +#define NNG_OPT_SURVEYOR_SURVEYTIME "surveyor:survey-time" NNG_DECL const char *nng_opt_raw; -NNG_DECL const char *nng_opt_linger; -NNG_DECL const char *nng_opt_recvbuf; -NNG_DECL const char *nng_opt_sendbuf; -NNG_DECL const char *nng_opt_recvtimeo; -NNG_DECL const char *nng_opt_sendtimeo; NNG_DECL const char *nng_opt_recvmaxsz; -NNG_DECL const char *nng_opt_reconnmint; -NNG_DECL const char *nng_opt_reconnmaxt; NNG_DECL const char *nng_opt_maxttl; NNG_DECL const char *nng_opt_protocol; NNG_DECL const char *nng_opt_transport; -NNG_DECL const char *nng_opt_recvfd; -NNG_DECL const char *nng_opt_sendfd; NNG_DECL const char *nng_opt_locaddr; NNG_DECL const char *nng_opt_remaddr; -NNG_DECL const char *nng_opt_url; -NNG_DECL const char *nng_opt_req_resendtime; -NNG_DECL const char *nng_opt_sub_subscribe; -NNG_DECL const char *nng_opt_sub_unsubscribe; NNG_DECL const char *nng_opt_surveyor_surveytime; -NNG_DECL int nng_optid_raw; -NNG_DECL int nng_optid_linger; -NNG_DECL int nng_optid_recvbuf; -NNG_DECL int nng_optid_sendbuf; -NNG_DECL int nng_optid_recvtimeo; -NNG_DECL int nng_optid_sendtimeo; -NNG_DECL int nng_optid_recvmaxsz; -NNG_DECL int nng_optid_reconnmint; -NNG_DECL int nng_optid_reconnmaxt; -NNG_DECL int nng_optid_maxttl; -NNG_DECL int nng_optid_protocol; -NNG_DECL int nng_optid_transport; -NNG_DECL int nng_optid_recvfd; -NNG_DECL int nng_optid_sendfd; -NNG_DECL int nng_optid_locaddr; -NNG_DECL int nng_optid_remaddr; -NNG_DECL int nng_optid_url; - -// These protocol specific options may not be valid until a socket of -// the given protocol is opened! -NNG_DECL int nng_optid_req_resendtime; -NNG_DECL int nng_optid_sub_subscribe; -NNG_DECL int nng_optid_sub_unsubscribe; -NNG_DECL int nng_optid_surveyor_surveytime; // XXX: TBD: priorities, socket names, ipv4only // Statistics. These are for informational purposes only, and subject @@ -598,8 +580,9 @@ enum nng_errno_enum { NNG_ENOFILES = 21, NNG_ENOSPC = 22, NNG_EEXIST = 23, - NNG_EINTERNAL = 24, - NNG_ETRANSPORT = 25, + NNG_EREADONLY = 24, + NNG_EWRITEONLY = 25, + NNG_EINTERNAL = 1000, NNG_ESYSERR = 0x10000000, NNG_ETRANERR = 0x20000000, }; @@ -648,11 +631,12 @@ typedef struct nng_sockaddr_zt nng_sockaddr_zt; typedef struct nng_sockaddr { union { - uint16_t s_family; - nng_sockaddr_path s_path; - nng_sockaddr_in6 s_in6; - nng_sockaddr_in s_in; - nng_sockaddr_zt s_zt; + uint16_t s_family; + nng_sockaddr_path s_path; + nng_sockaddr_inproc s_inproc; + nng_sockaddr_in6 s_in6; + nng_sockaddr_in s_in; + nng_sockaddr_zt s_zt; } s_un; } nng_sockaddr; diff --git a/src/nng_compat.c b/src/nng_compat.c index a6a558f5..bceabe61 100644 --- a/src/nng_compat.c +++ b/src/nng_compat.c @@ -133,7 +133,7 @@ nn_socket(int domain, int protocol) return (-1); } if (domain == AF_SP_RAW) { - if ((rv = nng_setopt_int(sock, nng_optid_raw, 1)) != 0) { + if ((rv = nng_setopt_int(sock, NNG_OPT_RAW, 1)) != 0) { nn_seterror(rv); nng_close(sock); return (-1); @@ -566,10 +566,10 @@ nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) // options which we convert -- most of the array is initialized at run time. static struct { - int nnlevel; - int nnopt; - int opt; - int mscvt; + int nnlevel; + int nnopt; + const char *opt; + int mscvt; } options[] = { // clang-format off { NN_SOL_SOCKET, NN_LINGER }, // review @@ -610,60 +610,60 @@ init_opts(void) case NN_SOL_SOCKET: switch (options[i].nnopt) { case NN_LINGER: - SETOPT(nng_optid_linger, 1); + SETOPT(NNG_OPT_LINGER, 1); break; case NN_SNDBUF: - SETOPT(nng_optid_sendbuf, 0); + SETOPT(NNG_OPT_SENDBUF, 0); break; case NN_RCVBUF: - SETOPT(nng_optid_recvbuf, 0); + SETOPT(NNG_OPT_RECVBUF, 0); break; case NN_RECONNECT_IVL: - SETOPT(nng_optid_reconnmint, 1); + SETOPT(NNG_OPT_RECONNMINT, 1); break; case NN_RECONNECT_IVL_MAX: - SETOPT(nng_optid_reconnmaxt, 1); + SETOPT(NNG_OPT_RECONNMAXT, 1); break; case NN_SNDFD: - SETOPT(nng_optid_sendfd, 0); + SETOPT(NNG_OPT_SENDFD, 0); break; case NN_RCVFD: - SETOPT(nng_optid_recvfd, 0); + SETOPT(NNG_OPT_RECVFD, 0); break; case NN_RCVMAXSIZE: - SETOPT(nng_optid_recvmaxsz, 0); + SETOPT(NNG_OPT_RECVMAXSZ, 0); break; case NN_MAXTTL: - SETOPT(nng_optid_maxttl, 0); + SETOPT(NNG_OPT_MAXTTL, 0); break; case NN_RCVTIMEO: - SETOPT(nng_optid_recvtimeo, 1); + SETOPT(NNG_OPT_RECVTIMEO, 1); break; case NN_SNDTIMEO: - SETOPT(nng_optid_sendtimeo, 1); + SETOPT(NNG_OPT_SENDTIMEO, 1); break; } break; case NN_REQ: switch (options[i].nnopt) { case NN_REQ_RESEND_IVL: - SETOPT(nng_optid_req_resendtime, 1); + SETOPT(NNG_OPT_REQ_RESENDTIME, 1); break; } break; case NN_SUB: switch (options[i].nnopt) { case NN_SUB_SUBSCRIBE: - SETOPT(nng_optid_sub_subscribe, 0); + SETOPT(NNG_OPT_SUB_SUBSCRIBE, 0); break; case NN_SUB_UNSUBSCRIBE: - SETOPT(nng_optid_sub_unsubscribe, 0); + SETOPT(NNG_OPT_SUB_UNSUBSCRIBE, 0); break; } case NN_SURVEYOR: switch (options[i].nnopt) { case NN_SURVEYOR_DEADLINE: - SETOPT(nng_optid_surveyor_surveytime, 1); + SETOPT(nng_opt_surveyor_surveytime, 1); break; } break; @@ -675,11 +675,11 @@ init_opts(void) int nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) { - int opt = -1; - int mscvt = 0; - uint64_t usec; - int * msecp; - int rv; + const char *name = NULL; + int mscvt = 0; + uint64_t usec; + int * msecp; + int rv; init_opts(); @@ -687,12 +687,12 @@ nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) if ((options[i].nnlevel == nnlevel) && (options[i].nnopt == nnopt)) { mscvt = options[i].mscvt; - opt = options[i].opt; + name = options[i].opt; break; } } - if (opt < 0) { + if (name == NULL) { return (ENOPROTOOPT); } @@ -707,7 +707,7 @@ nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) *szp = sizeof(uint64_t); } - if ((rv = nng_getopt((nng_socket) s, opt, valp, szp)) != 0) { + if ((rv = nng_getopt((nng_socket) s, name, valp, szp)) != 0) { nn_seterror(rv); return (-1); } @@ -724,10 +724,10 @@ nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) int nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) { - int opt = -1; - int mscvt = 0; - uint64_t usec; - int rv; + const char *name = NULL; + int mscvt = 0; + uint64_t usec; + int rv; init_opts(); @@ -735,11 +735,11 @@ nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) if ((options[i].nnlevel == nnlevel) && (options[i].nnopt == nnopt)) { mscvt = options[i].mscvt; - opt = options[i].opt; + name = options[i].opt; break; } } - if (opt < 0) { + if (name == NULL) { return (ENOPROTOOPT); } @@ -756,7 +756,7 @@ nn_setsockopt(int s, int nnlevel, int nnopt, const void *valp, size_t sz) sz = sizeof(usec); } - if ((rv = nng_setopt((nng_socket) s, opt, valp, sz)) != 0) { + if ((rv = nng_setopt((nng_socket) s, name, valp, sz)) != 0) { nn_seterror(rv); return (-1); } diff --git a/src/protocol/bus/bus.c b/src/protocol/bus/bus.c index d9189729..cad21989 100644 --- a/src/protocol/bus/bus.c +++ b/src/protocol/bus/bus.c @@ -325,27 +325,17 @@ bus_pipe_recv(bus_pipe *p) } static int -bus_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +bus_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - bus_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } - return (rv); + bus_sock *s = arg; + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -bus_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +bus_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - bus_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); + bus_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); } static nni_proto_pipe_ops bus_pipe_ops = { @@ -355,13 +345,22 @@ static nni_proto_pipe_ops bus_pipe_ops = { .pipe_stop = bus_pipe_stop, }; +static nni_proto_sock_option bus_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = bus_sock_getopt_raw, + .pso_setopt = bus_sock_setopt_raw, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops bus_sock_ops = { - .sock_init = bus_sock_init, - .sock_fini = bus_sock_fini, - .sock_open = bus_sock_open, - .sock_close = bus_sock_close, - .sock_setopt = bus_sock_setopt, - .sock_getopt = bus_sock_getopt, + .sock_init = bus_sock_init, + .sock_fini = bus_sock_fini, + .sock_open = bus_sock_open, + .sock_close = bus_sock_close, + .sock_options = bus_sock_options, }; static nni_proto bus_proto = { diff --git a/src/protocol/pair/pair_v0.c b/src/protocol/pair/pair_v0.c index 277d5cb1..9cabe3c7 100644 --- a/src/protocol/pair/pair_v0.c +++ b/src/protocol/pair/pair_v0.c @@ -230,31 +230,17 @@ pair0_sock_close(void *arg) } static int -pair0_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +pair0_sock_setopt_raw(void *arg, const void *buf, size_t sz) { pair0_sock *s = arg; - int rv; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } else { - rv = NNG_ENOTSUP; - } - return (rv); + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -pair0_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +pair0_sock_getopt_raw(void *arg, void *buf, size_t *szp) { pair0_sock *s = arg; - int rv; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } else { - rv = NNG_ENOTSUP; - } - return (rv); + return (nni_getopt_int(s->raw, buf, szp)); } static nni_proto_pipe_ops pair0_pipe_ops = { @@ -264,13 +250,22 @@ static nni_proto_pipe_ops pair0_pipe_ops = { .pipe_stop = pair0_pipe_stop, }; +static nni_proto_sock_option pair0_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = pair0_sock_getopt_raw, + .pso_setopt = pair0_sock_setopt_raw, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops pair0_sock_ops = { - .sock_init = pair0_sock_init, - .sock_fini = pair0_sock_fini, - .sock_open = pair0_sock_open, - .sock_close = pair0_sock_close, - .sock_setopt = pair0_sock_setopt, - .sock_getopt = pair0_sock_getopt, + .sock_init = pair0_sock_init, + .sock_fini = pair0_sock_fini, + .sock_open = pair0_sock_open, + .sock_close = pair0_sock_close, + .sock_options = pair0_sock_options, }; // Legacy protocol (v0) diff --git a/src/protocol/pair/pair_v1.c b/src/protocol/pair/pair_v1.c index 68dbc6f7..2cd5782b 100644 --- a/src/protocol/pair/pair_v1.c +++ b/src/protocol/pair/pair_v1.c @@ -25,9 +25,9 @@ static void pair1_pipe_getq_cb(void *); static void pair1_pipe_putq_cb(void *); static void pair1_pipe_fini(void *); -// These are exposed as external names for external consumers. -int nng_optid_pair1_poly; -const char *nng_opt_pair1_poly = "pair1-polyamorous"; +// This is exposed as an external name for external consumers. +#define NNG_OPT_PAIR1_POLY "pair1-polyamorous" +const char *nng_opt_pair1_poly = NNG_OPT_PAIR1_POLY; // pair1_sock is our per-socket protocol private structure. struct pair1_sock { @@ -394,74 +394,57 @@ pair1_sock_close(void *arg) } static int -pair1_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +pair1_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - pair1_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - nni_mtx_lock(&s->mtx); - if (s->started) { - rv = NNG_ESTATE; - } else { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } - nni_mtx_unlock(&s->mtx); - } else if (opt == nng_optid_maxttl) { - nni_mtx_lock(&s->mtx); - rv = nni_setopt_int(&s->ttl, buf, sz, 1, 255); - nni_mtx_unlock(&s->mtx); - } else if (opt == nng_optid_pair1_poly) { - nni_mtx_lock(&s->mtx); - if (s->started) { - rv = NNG_ESTATE; - } else { - rv = nni_setopt_int(&s->poly, buf, sz, 0, 1); - } - nni_mtx_unlock(&s->mtx); - } - + pair1_sock *s = arg; + int rv; + nni_mtx_lock(&s->mtx); + rv = s->started ? NNG_ESTATE : nni_setopt_int(&s->raw, buf, sz, 0, 1); + nni_mtx_unlock(&s->mtx); return (rv); } static int -pair1_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +pair1_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - pair1_sock *s = arg; - int rv = NNG_ENOTSUP; + pair1_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); +} - if (opt == nng_optid_raw) { - nni_mtx_lock(&s->mtx); - rv = nni_getopt_int(s->raw, buf, szp); - nni_mtx_unlock(&s->mtx); - } else if (opt == nng_optid_maxttl) { - nni_mtx_lock(&s->mtx); - rv = nni_getopt_int(s->ttl, buf, szp); - nni_mtx_unlock(&s->mtx); - } else if (opt == nng_optid_pair1_poly) { - nni_mtx_lock(&s->mtx); - rv = nni_getopt_int(s->poly, buf, szp); - nni_mtx_unlock(&s->mtx); - } +static int +pair1_sock_setopt_maxttl(void *arg, const void *buf, size_t sz) +{ + pair1_sock *s = arg; + int rv; + nni_mtx_lock(&s->mtx); // Have to be locked against recv cb. + rv = nni_setopt_int(&s->ttl, buf, sz, 1, 255); + nni_mtx_unlock(&s->mtx); return (rv); } -static void -pair1_fini(void) +static int +pair1_sock_getopt_maxttl(void *arg, void *buf, size_t *szp) { - nng_optid_pair1_poly = -1; + pair1_sock *s = arg; + return (nni_getopt_int(s->ttl, buf, szp)); } static int -pair1_init(void) +pair1_sock_setopt_poly(void *arg, const void *buf, size_t sz) { - int rv; - if ((rv = nni_option_register( - nng_opt_pair1_poly, &nng_optid_pair1_poly)) != 0) { - pair1_fini(); - return (rv); - } - return (0); + pair1_sock *s = arg; + int rv; + nni_mtx_lock(&s->mtx); + rv = s->started ? NNG_ESTATE : nni_setopt_int(&s->poly, buf, sz, 0, 1); + nni_mtx_unlock(&s->mtx); + return (rv); +} + +static int +pair1_sock_getopt_poly(void *arg, void *buf, size_t *szp) +{ + pair1_sock *s = arg; + return (nni_getopt_int(s->poly, buf, szp)); } static nni_proto_pipe_ops pair1_pipe_ops = { @@ -471,13 +454,32 @@ static nni_proto_pipe_ops pair1_pipe_ops = { .pipe_stop = pair1_pipe_stop, }; +static nni_proto_sock_option pair1_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = pair1_sock_getopt_raw, + .pso_setopt = pair1_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_MAXTTL, + .pso_getopt = pair1_sock_getopt_maxttl, + .pso_setopt = pair1_sock_setopt_maxttl, + }, + { + .pso_name = NNG_OPT_PAIR1_POLY, + .pso_getopt = pair1_sock_getopt_poly, + .pso_setopt = pair1_sock_setopt_poly, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops pair1_sock_ops = { - .sock_init = pair1_sock_init, - .sock_fini = pair1_sock_fini, - .sock_open = pair1_sock_open, - .sock_close = pair1_sock_close, - .sock_setopt = pair1_sock_setopt, - .sock_getopt = pair1_sock_getopt, + .sock_init = pair1_sock_init, + .sock_fini = pair1_sock_fini, + .sock_open = pair1_sock_open, + .sock_close = pair1_sock_close, + .sock_options = pair1_sock_options, }; static nni_proto pair1_proto = { @@ -487,8 +489,6 @@ static nni_proto pair1_proto = { .proto_flags = NNI_PROTO_FLAG_SNDRCV, .proto_sock_ops = &pair1_sock_ops, .proto_pipe_ops = &pair1_pipe_ops, - .proto_init = &pair1_init, - .proto_fini = &pair1_fini, }; int diff --git a/src/protocol/pipeline/pull.c b/src/protocol/pipeline/pull.c index 21c1613d..ba828763 100644 --- a/src/protocol/pipeline/pull.c +++ b/src/protocol/pipeline/pull.c @@ -171,27 +171,17 @@ pull_sock_close(void *arg) } static int -pull_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +pull_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - pull_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } - return (rv); + pull_sock *s = arg; + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -pull_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +pull_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - pull_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); + pull_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); } static nni_proto_pipe_ops pull_pipe_ops = { @@ -201,13 +191,22 @@ static nni_proto_pipe_ops pull_pipe_ops = { .pipe_stop = pull_pipe_stop, }; +static nni_proto_sock_option pull_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = pull_sock_getopt_raw, + .pso_setopt = pull_sock_setopt_raw, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops pull_sock_ops = { - .sock_init = pull_sock_init, - .sock_fini = pull_sock_fini, - .sock_open = pull_sock_open, - .sock_close = pull_sock_close, - .sock_setopt = pull_sock_setopt, - .sock_getopt = pull_sock_getopt, + .sock_init = pull_sock_init, + .sock_fini = pull_sock_fini, + .sock_open = pull_sock_open, + .sock_close = pull_sock_close, + .sock_options = pull_sock_options, }; static nni_proto pull_proto = { diff --git a/src/protocol/pipeline/push.c b/src/protocol/pipeline/push.c index b28f12c5..77db7fcb 100644 --- a/src/protocol/pipeline/push.c +++ b/src/protocol/pipeline/push.c @@ -192,27 +192,17 @@ push_getq_cb(void *arg) } static int -push_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +push_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - push_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } - return (rv); + push_sock *s = arg; + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -push_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +push_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - push_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); + push_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); } static nni_proto_pipe_ops push_pipe_ops = { @@ -222,13 +212,22 @@ static nni_proto_pipe_ops push_pipe_ops = { .pipe_stop = push_pipe_stop, }; +static nni_proto_sock_option push_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = push_sock_getopt_raw, + .pso_setopt = push_sock_setopt_raw, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops push_sock_ops = { - .sock_init = push_sock_init, - .sock_fini = push_sock_fini, - .sock_open = push_sock_open, - .sock_close = push_sock_close, - .sock_setopt = push_sock_setopt, - .sock_getopt = push_sock_getopt, + .sock_init = push_sock_init, + .sock_fini = push_sock_fini, + .sock_open = push_sock_open, + .sock_close = push_sock_close, + .sock_options = push_sock_options, }; static nni_proto push_proto = { diff --git a/src/protocol/pubsub/pub.c b/src/protocol/pubsub/pub.c index 10a9760f..03f4603a 100644 --- a/src/protocol/pubsub/pub.c +++ b/src/protocol/pubsub/pub.c @@ -268,27 +268,17 @@ pub_pipe_send_cb(void *arg) } static int -pub_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +pub_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - pub_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } - return (rv); + pub_sock *s = arg; + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -pub_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +pub_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - pub_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); + pub_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); } static nni_proto_pipe_ops pub_pipe_ops = { @@ -298,13 +288,22 @@ static nni_proto_pipe_ops pub_pipe_ops = { .pipe_stop = pub_pipe_stop, }; +static nni_proto_sock_option pub_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = pub_sock_getopt_raw, + .pso_setopt = pub_sock_setopt_raw, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops pub_sock_ops = { - .sock_init = pub_sock_init, - .sock_fini = pub_sock_fini, - .sock_open = pub_sock_open, - .sock_close = pub_sock_close, - .sock_setopt = pub_sock_setopt, - .sock_getopt = pub_sock_getopt, + .sock_init = pub_sock_init, + .sock_fini = pub_sock_fini, + .sock_open = pub_sock_open, + .sock_close = pub_sock_close, + .sock_options = pub_sock_options, }; static nni_proto pub_proto = { diff --git a/src/protocol/pubsub/sub.c b/src/protocol/pubsub/sub.c index 5f4b497d..7b6f4904 100644 --- a/src/protocol/pubsub/sub.c +++ b/src/protocol/pubsub/sub.c @@ -13,6 +13,9 @@ #include "core/nng_impl.h" +const char *nng_opt_sub_subscribe = NNG_OPT_SUB_SUBSCRIBE; +const char *nng_opt_sub_unsubscribe = NNG_OPT_SUB_UNSUBSCRIBE; + // Subscriber protocol. The SUB protocol receives messages sent to // it from publishers, and filters out those it is not interested in, // only passing up ones that match known subscriptions. @@ -178,8 +181,9 @@ sub_putq_cb(void *arg) // to replace this with a patricia trie, like old nanomsg had. static int -sub_subscribe(sub_sock *s, const void *buf, size_t sz) +sub_subscribe(void *arg, const void *buf, size_t sz) { + sub_sock * s = arg; sub_topic *topic; sub_topic *newtopic; @@ -222,8 +226,9 @@ sub_subscribe(sub_sock *s, const void *buf, size_t sz) } static int -sub_unsubscribe(sub_sock *s, const void *buf, size_t sz) +sub_unsubscribe(void *arg, const void *buf, size_t sz) { + sub_sock * s = arg; sub_topic *topic; int rv; @@ -252,31 +257,17 @@ sub_unsubscribe(sub_sock *s, const void *buf, size_t sz) } static int -sub_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +sub_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - sub_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - } else if (opt == nng_optid_sub_subscribe) { - rv = sub_subscribe(s, buf, sz); - } else if (opt == nng_optid_sub_unsubscribe) { - rv = sub_unsubscribe(s, buf, sz); - } - return (rv); + sub_sock *s = arg; + return (nni_setopt_int(&s->raw, buf, sz, 0, 1)); } static int -sub_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +sub_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - sub_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); + sub_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); } static nni_msg * @@ -330,13 +321,32 @@ static nni_proto_pipe_ops sub_pipe_ops = { .pipe_stop = sub_pipe_stop, }; +static nni_proto_sock_option sub_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = sub_sock_getopt_raw, + .pso_setopt = sub_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_SUB_SUBSCRIBE, + .pso_getopt = NULL, + .pso_setopt = sub_subscribe, + }, + { + .pso_name = NNG_OPT_SUB_UNSUBSCRIBE, + .pso_getopt = NULL, + .pso_setopt = sub_unsubscribe, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops sub_sock_ops = { .sock_init = sub_sock_init, .sock_fini = sub_sock_fini, .sock_open = sub_sock_open, .sock_close = sub_sock_close, - .sock_setopt = sub_sock_setopt, - .sock_getopt = sub_sock_getopt, + .sock_options = sub_sock_options, .sock_rfilter = sub_sock_rfilter, }; diff --git a/src/protocol/reqrep/rep.c b/src/protocol/reqrep/rep.c index 6641c58f..cd9411d9 100644 --- a/src/protocol/reqrep/rep.c +++ b/src/protocol/reqrep/rep.c @@ -343,32 +343,36 @@ rep_pipe_putq_cb(void *arg) } static int -rep_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +rep_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - rep_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_maxttl) { - rv = nni_setopt_int(&s->ttl, buf, sz, 1, 255); - } else if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); + rep_sock *s = arg; + int rv; + rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); + if (rv == 0) { nni_sock_senderr(s->sock, s->raw ? 0 : NNG_ESTATE); } return (rv); } static int -rep_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +rep_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - rep_sock *s = arg; - int rv = NNG_ENOTSUP; + rep_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); +} - if (opt == nng_optid_maxttl) { - rv = nni_getopt_int(s->ttl, buf, szp); - } else if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); +static int +rep_sock_setopt_maxttl(void *arg, const void *buf, size_t sz) +{ + rep_sock *s = arg; + return (nni_setopt_int(&s->ttl, buf, sz, 1, 255)); +} + +static int +rep_sock_getopt_maxttl(void *arg, void *buf, size_t *szp) +{ + rep_sock *s = arg; + return (nni_getopt_int(s->ttl, buf, szp)); } static nni_msg * @@ -445,13 +449,27 @@ static nni_proto_pipe_ops rep_pipe_ops = { .pipe_stop = rep_pipe_stop, }; +static nni_proto_sock_option rep_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = rep_sock_getopt_raw, + .pso_setopt = rep_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_MAXTTL, + .pso_getopt = rep_sock_getopt_maxttl, + .pso_setopt = rep_sock_setopt_maxttl, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops rep_sock_ops = { .sock_init = rep_sock_init, .sock_fini = rep_sock_fini, .sock_open = rep_sock_open, .sock_close = rep_sock_close, - .sock_setopt = rep_sock_setopt, - .sock_getopt = rep_sock_getopt, + .sock_options = rep_sock_options, .sock_rfilter = rep_sock_rfilter, .sock_sfilter = rep_sock_sfilter, }; diff --git a/src/protocol/reqrep/req.c b/src/protocol/reqrep/req.c index c2008a9a..7d47b0b3 100644 --- a/src/protocol/reqrep/req.c +++ b/src/protocol/reqrep/req.c @@ -15,8 +15,9 @@ #include "core/nng_impl.h" // Request protocol. The REQ protocol is the "request" side of a -// request-reply pair. This is useful for building RPC clients, for -// example. +// request-reply pair. This is useful for building RPC clients, for example. + +const char *nng_opt_req_resendtime = NNG_OPT_REQ_RESENDTIME; typedef struct req_pipe req_pipe; typedef struct req_sock req_sock; @@ -245,44 +246,50 @@ req_pipe_stop(void *arg) } static int -req_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +req_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - req_sock *s = arg; - int rv = NNG_ENOTSUP; - - if (opt == nng_optid_req_resendtime) { - rv = nni_setopt_usec(&s->retry, buf, sz); - - } else if (opt == nng_optid_raw) { - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - if (rv == 0) { - nni_sock_recverr(s->sock, s->raw ? 0 : NNG_ESTATE); - } - - } else if (opt == nng_optid_maxttl) { - rv = nni_setopt_int(&s->ttl, buf, sz, 1, 255); + req_sock *s = arg; + int rv; + rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); + if (rv == 0) { + nni_sock_recverr(s->sock, s->raw ? 0 : NNG_ESTATE); } - return (rv); } static int -req_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +req_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - req_sock *s = arg; - int rv = NNG_ENOTSUP; + req_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); +} - if (opt == nng_optid_req_resendtime) { - rv = nni_getopt_usec(s->retry, buf, szp); +static int +req_sock_setopt_maxttl(void *arg, const void *buf, size_t sz) +{ + req_sock *s = arg; + return (nni_setopt_int(&s->ttl, buf, sz, 1, 255)); +} - } else if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); +static int +req_sock_getopt_maxttl(void *arg, void *buf, size_t *szp) +{ + req_sock *s = arg; + return (nni_getopt_int(s->ttl, buf, szp)); +} - } else if (opt == nng_optid_maxttl) { - rv = nni_getopt_int(s->ttl, buf, szp); - } +static int +req_sock_setopt_resendtime(void *arg, const void *buf, size_t sz) +{ + req_sock *s = arg; + return (nni_setopt_usec(&s->retry, buf, sz)); +} - return (rv); +static int +req_sock_getopt_resendtime(void *arg, void *buf, size_t *szp) +{ + req_sock *s = arg; + return (nni_getopt_usec(s->retry, buf, szp)); } // Raw and cooked mode differ in the way they send messages out. @@ -597,13 +604,32 @@ static nni_proto_pipe_ops req_pipe_ops = { .pipe_stop = req_pipe_stop, }; +static nni_proto_sock_option req_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = req_sock_getopt_raw, + .pso_setopt = req_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_MAXTTL, + .pso_getopt = req_sock_getopt_maxttl, + .pso_setopt = req_sock_setopt_maxttl, + }, + { + .pso_name = NNG_OPT_REQ_RESENDTIME, + .pso_getopt = req_sock_getopt_resendtime, + .pso_setopt = req_sock_setopt_resendtime, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops req_sock_ops = { .sock_init = req_sock_init, .sock_fini = req_sock_fini, .sock_open = req_sock_open, .sock_close = req_sock_close, - .sock_setopt = req_sock_setopt, - .sock_getopt = req_sock_getopt, + .sock_options = req_sock_options, .sock_rfilter = req_sock_rfilter, .sock_sfilter = req_sock_sfilter, }; diff --git a/src/protocol/survey/respond.c b/src/protocol/survey/respond.c index 89e19e91..70dbd704 100644 --- a/src/protocol/survey/respond.c +++ b/src/protocol/survey/respond.c @@ -343,42 +343,36 @@ resp_putq_cb(void *arg) } static int -resp_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +resp_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - resp_sock *s = arg; - int rv = NNG_ENOTSUP; - int oldraw; - - if (opt == nng_optid_maxttl) { - rv = nni_setopt_int(&s->ttl, buf, sz, 1, 255); - - } else if (opt == nng_optid_raw) { - oldraw = s->raw; - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - if (oldraw != s->raw) { - if (!s->raw) { - nni_sock_senderr(s->nsock, 0); - } else { - nni_sock_senderr(s->nsock, NNG_ESTATE); - } - } - } + resp_sock *s = arg; + int rv; + if ((rv = nni_setopt_int(&s->raw, buf, sz, 0, 1)) == 0) { + nni_sock_senderr(s->nsock, s->raw ? 0 : NNG_ESTATE); + } return (rv); } static int -resp_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +resp_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - resp_sock *s = arg; - int rv = NNG_ENOTSUP; + resp_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); +} - if (opt == nng_optid_maxttl) { - rv = nni_getopt_int(s->ttl, buf, szp); - } else if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); +static int +resp_sock_setopt_maxttl(void *arg, const void *buf, size_t sz) +{ + resp_sock *s = arg; + return (nni_setopt_int(&s->ttl, buf, sz, 1, 255)); +} + +static int +resp_sock_getopt_maxttl(void *arg, void *buf, size_t *szp) +{ + resp_sock *s = arg; + return (nni_getopt_int(s->ttl, buf, szp)); } static nni_msg * @@ -453,13 +447,27 @@ static nni_proto_pipe_ops resp_pipe_ops = { .pipe_stop = resp_pipe_stop, }; +static nni_proto_sock_option resp_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = resp_sock_getopt_raw, + .pso_setopt = resp_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_MAXTTL, + .pso_getopt = resp_sock_getopt_maxttl, + .pso_setopt = resp_sock_setopt_maxttl, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops resp_sock_ops = { .sock_init = resp_sock_init, .sock_fini = resp_sock_fini, .sock_open = resp_sock_open, .sock_close = resp_sock_close, - .sock_setopt = resp_sock_setopt, - .sock_getopt = resp_sock_getopt, + .sock_options = resp_sock_options, .sock_rfilter = resp_sock_rfilter, .sock_sfilter = resp_sock_sfilter, }; diff --git a/src/protocol/survey/survey.c b/src/protocol/survey/survey.c index e90c7f57..361b9d37 100644 --- a/src/protocol/survey/survey.c +++ b/src/protocol/survey/survey.c @@ -267,44 +267,38 @@ failed: } static int -surv_sock_setopt(void *arg, int opt, const void *buf, size_t sz) +surv_sock_setopt_raw(void *arg, const void *buf, size_t sz) { - surv_sock *s = arg; - int rv = NNG_ENOTSUP; - int oldraw; - - if (opt == nng_optid_surveyor_surveytime) { - rv = nni_setopt_usec(&s->survtime, buf, sz); - - } else if (opt == nng_optid_raw) { - oldraw = s->raw; - rv = nni_setopt_int(&s->raw, buf, sz, 0, 1); - if (oldraw != s->raw) { - if (s->raw) { - nni_sock_recverr(s->nsock, 0); - } else { - nni_sock_recverr(s->nsock, NNG_ESTATE); - } - s->survid = 0; - nni_timer_cancel(&s->timer); - } - } + surv_sock *s = arg; + int rv; + if ((rv = nni_setopt_int(&s->raw, buf, sz, 0, 1)) == 0) { + nni_sock_recverr(s->nsock, s->raw ? 0 : NNG_ESTATE); + s->survid = 0; + nni_timer_cancel(&s->timer); + } return (rv); } static int -surv_sock_getopt(void *arg, int opt, void *buf, size_t *szp) +surv_sock_getopt_raw(void *arg, void *buf, size_t *szp) { - surv_sock *s = arg; - int rv = NNG_ENOTSUP; + surv_sock *s = arg; + return (nni_getopt_int(s->raw, buf, szp)); +} - if (opt == nng_optid_surveyor_surveytime) { - rv = nni_getopt_usec(s->survtime, buf, szp); - } else if (opt == nng_optid_raw) { - rv = nni_getopt_int(s->raw, buf, szp); - } - return (rv); +static int +surv_sock_setopt_surveytime(void *arg, const void *buf, size_t sz) +{ + surv_sock *s = arg; + return (nni_setopt_usec(&s->survtime, buf, sz)); +} + +static int +surv_sock_getopt_surveytime(void *arg, void *buf, size_t *szp) +{ + surv_sock *s = arg; + return (nni_getopt_usec(s->survtime, buf, szp)); } static void @@ -418,13 +412,27 @@ static nni_proto_pipe_ops surv_pipe_ops = { .pipe_stop = surv_pipe_stop, }; +static nni_proto_sock_option surv_sock_options[] = { + { + .pso_name = NNG_OPT_RAW, + .pso_getopt = surv_sock_getopt_raw, + .pso_setopt = surv_sock_setopt_raw, + }, + { + .pso_name = NNG_OPT_SURVEYOR_SURVEYTIME, + .pso_getopt = surv_sock_getopt_surveytime, + .pso_setopt = surv_sock_setopt_surveytime, + }, + // terminate list + { NULL, NULL, NULL }, +}; + static nni_proto_sock_ops surv_sock_ops = { .sock_init = surv_sock_init, .sock_fini = surv_sock_fini, .sock_open = surv_sock_open, .sock_close = surv_sock_close, - .sock_setopt = surv_sock_setopt, - .sock_getopt = surv_sock_getopt, + .sock_options = surv_sock_options, .sock_rfilter = surv_sock_rfilter, .sock_sfilter = surv_sock_sfilter, }; diff --git a/src/transport/inproc/inproc.c b/src/transport/inproc/inproc.c index e3cc5143..3f013f92 100644 --- a/src/transport/inproc/inproc.c +++ b/src/transport/inproc/inproc.c @@ -177,25 +177,15 @@ nni_inproc_pipe_peer(void *arg) } static int -nni_inproc_pipe_getopt(void *arg, int option, void *buf, size_t *szp) +nni_inproc_pipe_get_addr(void *arg, void *buf, size_t *szp) { -#if 0 - nni_inproc_pipe *pipe = arg; + nni_inproc_pipe *p = arg; + nni_sockaddr sa; - switch (option) { - case NNG_OPT_LOCALADDR: - case NNG_OPT_REMOTEADDR: - len = strlen(pipe->addr) + 1; - if (len > *szp) { - (void) memcpy(buf, pipe->addr, *szp); - } else { - (void) memcpy(buf, pipe->addr, len); - } - *szp = len; - return (0); - } -#endif - return (NNG_ENOTSUP); + sa.s_un.s_inproc.sa_family = NNG_AF_INPROC; + nni_strlcpy(sa.s_un.s_inproc.sa_path, p->addr, + sizeof(sa.s_un.s_inproc.sa_path)); + return (nni_getopt_sockaddr(&sa, buf, szp)); } static int @@ -442,13 +432,25 @@ nni_inproc_ep_accept(void *arg, nni_aio *aio) nni_mtx_unlock(&nni_inproc.mx); } +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 }, + // terminate list + { NULL, NULL }, +}; + static nni_tran_pipe nni_inproc_pipe_ops = { - .p_fini = nni_inproc_pipe_fini, - .p_send = nni_inproc_pipe_send, - .p_recv = nni_inproc_pipe_recv, - .p_close = nni_inproc_pipe_close, - .p_peer = nni_inproc_pipe_peer, - .p_getopt = nni_inproc_pipe_getopt, + .p_fini = nni_inproc_pipe_fini, + .p_send = nni_inproc_pipe_send, + .p_recv = nni_inproc_pipe_recv, + .p_close = nni_inproc_pipe_close, + .p_peer = nni_inproc_pipe_peer, + .p_options = nni_inproc_pipe_options, +}; + +static nni_tran_ep_option nni_inproc_ep_options[] = { + // terminate list + { NULL, NULL, NULL }, }; static nni_tran_ep nni_inproc_ep_ops = { @@ -458,8 +460,7 @@ static nni_tran_ep nni_inproc_ep_ops = { .ep_bind = nni_inproc_ep_bind, .ep_accept = nni_inproc_ep_accept, .ep_close = nni_inproc_ep_close, - .ep_setopt = NULL, - .ep_getopt = NULL, + .ep_options = nni_inproc_ep_options, }; // This is the inproc transport linkage, and should be the only global diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c index b65adfee..afe8afa8 100644 --- a/src/transport/ipc/ipc.c +++ b/src/transport/ipc/ipc.c @@ -16,14 +16,14 @@ // IPC transport. Platform specific IPC operations must be // supplied as well. Normally the IPC is UNIX domain sockets or -// Windows named pipes. Other platforms could use other mechanisms. +// Windows named pipes. Other platforms could use other mechanisms, +// but all implementations on the platform must use the same mechanism. typedef struct nni_ipc_pipe nni_ipc_pipe; typedef struct nni_ipc_ep nni_ipc_ep; // nni_ipc_pipe is one end of an IPC connection. struct nni_ipc_pipe { - const char * addr; nni_plat_ipc_pipe *ipp; uint16_t peer; uint16_t proto; @@ -48,7 +48,7 @@ struct nni_ipc_pipe { }; struct nni_ipc_ep { - char addr[NNG_MAXADDRLEN + 1]; + nni_sockaddr sa; nni_plat_ipc_ep *iep; uint16_t proto; size_t rcvmax; @@ -63,15 +63,6 @@ static void nni_ipc_pipe_nego_cb(void *); static void nni_ipc_ep_cb(void *); static int -nni_ipc_tran_chkopt(int o, const void *data, size_t sz) -{ - if (o == nng_optid_recvmaxsz) { - return (nni_chkopt_size(data, sz, 0, NNI_MAXSZ)); - } - return (NNG_ENOTSUP); -} - -static int nni_ipc_tran_init(void) { return (0); @@ -132,10 +123,8 @@ nni_ipc_pipe_init(nni_ipc_pipe **pipep, nni_ipc_ep *ep, void *ipp) p->proto = ep->proto; p->rcvmax = ep->rcvmax; p->ipp = ipp; - p->addr = ep->addr; p->sa.s_un.s_path.sa_family = NNG_AF_IPC; - nni_strlcpy(p->sa.s_un.s_path.sa_path, p->addr + strlen("ipc://"), - sizeof(p->sa.s_un.s_path.sa_path)); + p->sa = ep->sa; *pipep = p; return (0); @@ -463,22 +452,10 @@ nni_ipc_pipe_peer(void *arg) } static int -nni_ipc_pipe_getopt(void *arg, int option, void *buf, size_t *szp) +nni_ipc_pipe_get_addr(void *arg, void *buf, size_t *szp) { - - nni_ipc_pipe *pipe = arg; - size_t len; - int rv; - - if ((option == nng_optid_locaddr) || (option == nng_optid_remaddr)) { - rv = nni_getopt_sockaddr(&pipe->sa, buf, szp); - } else if (option == nng_optid_recvmaxsz) { - rv = nni_getopt_size(pipe->rcvmax, &buf, szp); - - } else { - rv = NNG_ENOTSUP; - } - return (rv); + nni_ipc_pipe *p = arg; + return (nni_getopt_sockaddr(&p->sa, buf, szp)); } static void @@ -496,33 +473,28 @@ nni_ipc_ep_fini(void *arg) static int nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode) { - nni_ipc_ep * ep; - int rv; - nni_sockaddr sa; - size_t sz; + nni_ipc_ep *ep; + int rv; + size_t sz; if (strncmp(url, "ipc://", strlen("ipc://")) != 0) { return (NNG_EADDRINVAL); } url += strlen("ipc://"); - sz = sizeof(sa.s_un.s_path.sa_path); - sa.s_un.s_path.sa_family = NNG_AF_IPC; - - if (nni_strlcpy(sa.s_un.s_path.sa_path, url, sz) >= sz) { - return (NNG_EADDRINVAL); - } - if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) { return (NNG_ENOMEM); } - if (nni_strlcpy(ep->addr, url, sizeof(ep->addr)) >= sizeof(ep->addr)) { + sz = sizeof(ep->sa.s_un.s_path.sa_path); + ep->sa.s_un.s_path.sa_family = NNG_AF_IPC; + + if (nni_strlcpy(ep->sa.s_un.s_path.sa_path, url, sz) >= sz) { NNI_FREE_STRUCT(ep); return (NNG_EADDRINVAL); } - if ((rv = nni_plat_ipc_ep_init(&ep->iep, &sa, mode)) != 0) { + if ((rv = nni_plat_ipc_ep_init(&ep->iep, &ep->sa, mode)) != 0) { NNI_FREE_STRUCT(ep); return (rv); } @@ -666,41 +638,60 @@ nni_ipc_ep_connect(void *arg, nni_aio *aio) } static int -nni_ipc_ep_setopt(void *arg, int opt, const void *v, size_t sz) +nni_ipc_ep_setopt_recvmaxsz(void *arg, const void *data, size_t sz) { - int rv = NNG_ENOTSUP; nni_ipc_ep *ep = arg; - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&ep->mtx); - rv = nni_setopt_size(&ep->rcvmax, v, sz, 0, NNI_MAXSZ); - nni_mtx_unlock(&ep->mtx); + if (ep == NULL) { + return (nni_chkopt_size(data, sz, 0, NNI_MAXSZ)); } - return (rv); + return (nni_setopt_size(&ep->rcvmax, data, sz, 0, NNI_MAXSZ)); } static int -nni_ipc_ep_getopt(void *arg, int opt, void *v, size_t *szp) +nni_ipc_ep_getopt_recvmaxsz(void *arg, void *data, size_t *szp) { - int rv = NNG_ENOTSUP; nni_ipc_ep *ep = arg; + return (nni_getopt_size(ep->rcvmax, data, szp)); +} - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&ep->mtx); - rv = nni_getopt_size(ep->rcvmax, v, szp); - nni_mtx_unlock(&ep->mtx); - } - return (rv); +static int +nni_ipc_ep_get_addr(void *arg, void *data, size_t *szp) +{ + nni_ipc_ep *ep = arg; + return (nni_getopt_sockaddr(&ep->sa, data, 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 }, + // terminate list + { NULL, NULL }, +}; + static nni_tran_pipe nni_ipc_pipe_ops = { - .p_fini = nni_ipc_pipe_fini, - .p_start = nni_ipc_pipe_start, - .p_send = nni_ipc_pipe_send, - .p_recv = nni_ipc_pipe_recv, - .p_close = nni_ipc_pipe_close, - .p_peer = nni_ipc_pipe_peer, - .p_getopt = nni_ipc_pipe_getopt, + .p_fini = nni_ipc_pipe_fini, + .p_start = nni_ipc_pipe_start, + .p_send = nni_ipc_pipe_send, + .p_recv = nni_ipc_pipe_recv, + .p_close = nni_ipc_pipe_close, + .p_peer = nni_ipc_pipe_peer, + .p_options = nni_ipc_pipe_options, +}; + +static nni_tran_ep_option nni_ipc_ep_options[] = { + { + .eo_name = NNG_OPT_RECVMAXSZ, + .eo_getopt = nni_ipc_ep_getopt_recvmaxsz, + .eo_setopt = nni_ipc_ep_setopt_recvmaxsz, + }, + { + .eo_name = NNG_OPT_LOCADDR, + .eo_getopt = nni_ipc_ep_get_addr, + .eo_setopt = NULL, + }, + // terminate list + { NULL, NULL, NULL }, }; static nni_tran_ep nni_ipc_ep_ops = { @@ -710,8 +701,7 @@ static nni_tran_ep nni_ipc_ep_ops = { .ep_bind = nni_ipc_ep_bind, .ep_accept = nni_ipc_ep_accept, .ep_close = nni_ipc_ep_close, - .ep_setopt = nni_ipc_ep_setopt, - .ep_getopt = nni_ipc_ep_getopt, + .ep_options = nni_ipc_ep_options, }; // This is the IPC transport linkage, and should be the only global diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c index 587c1af9..413d8fa5 100644 --- a/src/transport/tcp/tcp.c +++ b/src/transport/tcp/tcp.c @@ -63,18 +63,6 @@ static void nni_tcp_pipe_nego_cb(void *); static void nni_tcp_ep_cb(void *arg); static int -nni_tcp_tran_chkopt(int o, const void *data, size_t sz) -{ - if (o == nng_optid_recvmaxsz) { - return (nni_chkopt_size(data, sz, 0, NNI_MAXSZ)); - } - if (o == nng_optid_linger) { - return (nni_chkopt_usec(data, sz)); - } - return (NNG_ENOTSUP); -} - -static int nni_tcp_tran_init(void) { return (0); @@ -419,29 +407,6 @@ nni_tcp_pipe_peer(void *arg) } static int -nni_tcp_pipe_getopt(void *arg, int option, void *buf, size_t *szp) -{ -#if 0 - nni_inproc_pipe *pipe = arg; - size_t len; - - switch (option) { - case NNG_OPT_LOCALADDR: - case NNG_OPT_REMOTEADDR: - len = strlen(pipe->addr) + 1; - if (len > *szp) { - (void) memcpy(buf, pipe->addr, *szp); - } else { - (void) memcpy(buf, pipe->addr, len); - } - *szp = len; - return (0); - } -#endif - return (NNG_ENOTSUP); -} - -static int nni_tcp_parse_pair(char *pair, char **hostp, char **servp) { char *host, *serv, *end; @@ -786,52 +751,71 @@ nni_tcp_ep_connect(void *arg, nni_aio *aio) } static int -nni_tcp_ep_setopt(void *arg, int opt, const void *v, size_t sz) +nni_tcp_ep_setopt_recvmaxsz(void *arg, const void *v, size_t sz) { - int rv = NNG_ENOTSUP; nni_tcp_ep *ep = arg; - - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&ep->mtx); - rv = nni_setopt_size(&ep->rcvmax, v, sz, 0, NNI_MAXSZ); - nni_mtx_unlock(&ep->mtx); - - } else if (opt == nng_optid_linger) { - nni_mtx_lock(&ep->mtx); - rv = nni_setopt_usec(&ep->linger, v, sz); - nni_mtx_unlock(&ep->mtx); + if (ep == NULL) { + return (nni_chkopt_size(v, sz, 0, NNI_MAXSZ)); } - return (rv); + return (nni_setopt_size(&ep->rcvmax, v, sz, 0, NNI_MAXSZ)); } static int -nni_tcp_ep_getopt(void *arg, int opt, void *v, size_t *szp) +nni_tcp_ep_getopt_recvmaxsz(void *arg, void *v, size_t *szp) { - int rv = NNG_ENOTSUP; nni_tcp_ep *ep = arg; + return (nni_getopt_size(ep->rcvmax, v, szp)); +} - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&ep->mtx); - rv = nni_getopt_size(ep->rcvmax, v, szp); - nni_mtx_unlock(&ep->mtx); - - } else if (opt == nng_optid_linger) { - nni_mtx_lock(&ep->mtx); - rv = nni_getopt_usec(ep->linger, v, szp); - nni_mtx_unlock(&ep->mtx); +static int +nni_tcp_ep_setopt_linger(void *arg, const void *v, size_t sz) +{ + nni_tcp_ep *ep = arg; + if (ep == NULL) { + return (nni_chkopt_usec(v, sz)); } - // XXX: add address properties - return (rv); + return (nni_setopt_usec(&ep->linger, v, sz)); } +static int +nni_tcp_ep_getopt_linger(void *arg, void *v, size_t *szp) +{ + nni_tcp_ep *ep = arg; + return (nni_getopt_usec(ep->linger, v, szp)); +} + +static nni_tran_pipe_option nni_tcp_pipe_options[] = { +#if 0 + { NNG_OPT_LOCADDR, nni_tcp_pipe_get_locaddr }, + { NNG_OPT_REMADDR, nni_tcp_pipe_get_remaddr }, +#endif + // terminate list + { NULL, NULL } +}; + static nni_tran_pipe nni_tcp_pipe_ops = { - .p_fini = nni_tcp_pipe_fini, - .p_start = nni_tcp_pipe_start, - .p_send = nni_tcp_pipe_send, - .p_recv = nni_tcp_pipe_recv, - .p_close = nni_tcp_pipe_close, - .p_peer = nni_tcp_pipe_peer, - .p_getopt = nni_tcp_pipe_getopt, + .p_fini = nni_tcp_pipe_fini, + .p_start = nni_tcp_pipe_start, + .p_send = nni_tcp_pipe_send, + .p_recv = nni_tcp_pipe_recv, + .p_close = nni_tcp_pipe_close, + .p_peer = nni_tcp_pipe_peer, + .p_options = nni_tcp_pipe_options, +}; + +static nni_tran_ep_option nni_tcp_ep_options[] = { + { + .eo_name = NNG_OPT_RECVMAXSZ, + .eo_getopt = nni_tcp_ep_getopt_recvmaxsz, + .eo_setopt = nni_tcp_ep_setopt_recvmaxsz, + }, + { + .eo_name = NNG_OPT_LINGER, + .eo_getopt = nni_tcp_ep_getopt_linger, + .eo_setopt = nni_tcp_ep_setopt_linger, + }, + // terminate list + { NULL, NULL, NULL }, }; static nni_tran_ep nni_tcp_ep_ops = { @@ -841,8 +825,7 @@ static nni_tran_ep nni_tcp_ep_ops = { .ep_bind = nni_tcp_ep_bind, .ep_accept = nni_tcp_ep_accept, .ep_close = nni_tcp_ep_close, - .ep_setopt = nni_tcp_ep_setopt, - .ep_getopt = nni_tcp_ep_getopt, + .ep_options = nni_tcp_ep_options, }; // This is the TCP transport linkage, and should be the only global @@ -852,7 +835,6 @@ struct nni_tran nni_tcp_tran = { .tran_scheme = "tcp", .tran_ep = &nni_tcp_ep_ops, .tran_pipe = &nni_tcp_pipe_ops, - .tran_chkopt = nni_tcp_tran_chkopt, .tran_init = nni_tcp_tran_init, .tran_fini = nni_tcp_tran_fini, }; diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c index 40af6e54..9182ec1f 100644 --- a/src/transport/zerotier/zerotier.c +++ b/src/transport/zerotier/zerotier.c @@ -22,26 +22,32 @@ #include <ZeroTierOne.h> -const char *nng_opt_zt_home = "zt:home"; -const char *nng_opt_zt_nwid = "zt:nwid"; -const char *nng_opt_zt_node = "zt:node"; -const char *nng_opt_zt_status = "zt:status"; -const char *nng_opt_zt_network_name = "zt:network-name"; -const char *nng_opt_zt_local_port = "zt:local-port"; -const char *nng_opt_zt_ping_time = "zt:ping-time"; -const char *nng_opt_zt_ping_count = "zt:ping-count"; - -int nng_optid_zt_home = -1; -int nng_optid_zt_nwid = -1; -int nng_optid_zt_node = -1; -int nng_optid_zt_status = -1; -int nng_optid_zt_network_name = -1; -int nng_optid_zt_ping_time = -1; -int nng_optid_zt_ping_count = -1; -int nng_optid_zt_local_port = -1; +#define NNG_ZT_OPT_HOME "zt:home" +#define NNG_ZT_OPT_NWID "zt:nwid" +#define NNG_ZT_OPT_NODE "zt:node" +#define NNG_ZT_OPT_STATUS "zt:status" +#define NNG_ZT_OPT_NETWORK_NAME "zt:network-name" +#define NNG_ZT_OPT_PING_TIME "zt:ping-time" +#define NNG_ZT_OPT_PING_COUNT "zt:ping-count" + +const char *nng_opt_zt_home = NNG_ZT_OPT_HOME; +const char *nng_opt_zt_nwid = NNG_ZT_OPT_NWID; +const char *nng_opt_zt_node = NNG_ZT_OPT_NODE; +const char *nng_opt_zt_status = NNG_ZT_OPT_STATUS; +const char *nng_opt_zt_network_name = NNG_ZT_OPT_NETWORK_NAME; +const char *nng_opt_zt_ping_time = NNG_ZT_OPT_PING_TIME; +const char *nng_opt_zt_ping_count = NNG_ZT_OPT_PING_COUNT; + +int zt_optid_home = -1; +int zt_optid_nwid = -1; +int zt_optid_node = -1; +int zt_optid_status = -1; +int zt_optid_network_name = -1; +int zt_optid_ping_time = -1; +int zt_optid_ping_count = -1; // These values are supplied to help folks checking status. They are the -// return values from nng_optid_zt_status. +// return values from zt_optid_status. int nng_zt_status_configuring = ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION; int nng_zt_status_ok = ZT_NETWORK_STATUS_OK; int nng_zt_status_denied = ZT_NETWORK_STATUS_ACCESS_DENIED; @@ -1597,51 +1603,23 @@ done: } static int -zt_chkopt(int opt, const void *dat, size_t sz) -{ - if (opt == nng_optid_recvmaxsz) { - // We cannot deal with message sizes larger - // than 64k. - return (nni_chkopt_size(dat, sz, 0, 0xffffffffU)); - } - if (opt == nng_optid_zt_home) { - size_t l = nni_strnlen(dat, sz); - if ((l >= sz) || (l >= NNG_MAXADDRLEN)) { - return (NNG_EINVAL); - } - // XXX: should we apply additional security - // checks? home path is not null terminated - return (0); - } - if (opt == nng_optid_zt_ping_count) { - return (nni_chkopt_int(dat, sz, 0, 1000000)); - } - if (opt == nng_optid_zt_ping_time) { - return (nni_chkopt_usec(dat, sz)); - } - return (NNG_ENOTSUP); -} - -static int zt_tran_init(void) { int rv; - if (((rv = nni_option_register(nng_opt_zt_home, &nng_optid_zt_home)) != + if (((rv = nni_option_register(nng_opt_zt_home, &zt_optid_home)) != 0) || - ((rv = nni_option_register(nng_opt_zt_node, &nng_optid_zt_node)) != + ((rv = nni_option_register(nng_opt_zt_node, &zt_optid_node)) != 0) || - ((rv = nni_option_register(nng_opt_zt_nwid, &nng_optid_zt_nwid)) != + ((rv = nni_option_register(nng_opt_zt_nwid, &zt_optid_nwid)) != + 0) || + ((rv = nni_option_register(nng_opt_zt_status, &zt_optid_status)) != 0) || ((rv = nni_option_register( - nng_opt_zt_status, &nng_optid_zt_status)) != 0) || - ((rv = nni_option_register(nng_opt_zt_network_name, - &nng_optid_zt_network_name)) != 0) || - ((rv = nni_option_register( - nng_opt_zt_local_port, &nng_optid_zt_local_port)) != 0) || + nng_opt_zt_network_name, &zt_optid_network_name)) != 0) || ((rv = nni_option_register( - nng_opt_zt_ping_count, &nng_optid_zt_ping_count)) != 0) || + nng_opt_zt_ping_count, &zt_optid_ping_count)) != 0) || ((rv = nni_option_register( - nng_opt_zt_ping_time, &nng_optid_zt_ping_time)) != 0)) { + nng_opt_zt_ping_time, &zt_optid_ping_time)) != 0)) { return (rv); } nni_mtx_init(&zt_lk); @@ -1652,11 +1630,11 @@ zt_tran_init(void) static void zt_tran_fini(void) { - nng_optid_zt_home = -1; - nng_optid_zt_nwid = -1; - nng_optid_zt_node = -1; - nng_optid_zt_ping_count = -1; - nng_optid_zt_ping_time = -1; + zt_optid_home = -1; + zt_optid_nwid = -1; + zt_optid_node = -1; + zt_optid_ping_count = -1; + zt_optid_ping_time = -1; zt_node *ztn; nni_mtx_lock(&zt_lk); @@ -2014,25 +1992,31 @@ zt_getopt_network_name(zt_node *ztn, uint64_t nwid, void *buf, size_t *szp) } static int -zt_pipe_getopt(void *arg, int option, void *buf, size_t *szp) +zt_pipe_get_recvmaxsz(void *arg, void *buf, size_t *szp) { zt_pipe *p = arg; - int rv; + return (nni_getopt_size(p->zp_rcvmax, buf, szp)); +} - if (option == nng_optid_recvmaxsz) { - rv = nni_getopt_size(p->zp_rcvmax, buf, szp); - } else if (option == nng_optid_zt_nwid) { - rv = nni_getopt_u64(p->zp_nwid, buf, szp); - } else if (option == nng_optid_zt_node) { - rv = nni_getopt_u64(p->zp_laddr >> 24, buf, szp); - } else if (option == nng_optid_zt_status) { - rv = zt_getopt_status(p->zp_ztn, p->zp_nwid, buf, szp); - } else if (option == nng_optid_zt_network_name) { - rv = zt_getopt_network_name(p->zp_ztn, p->zp_nwid, buf, szp); - } else { - rv = NNG_ENOTSUP; - } - return (rv); +static int +zt_pipe_get_nwid(void *arg, void *buf, size_t *szp) +{ + zt_pipe *p = arg; + return (nni_getopt_u64(p->zp_nwid, buf, szp)); +} + +static int +zt_pipe_get_node(void *arg, void *buf, size_t *szp) +{ + zt_pipe *p = arg; + return (nni_getopt_u64(p->zp_laddr >> 24, buf, szp)); +} + +static int +zt_pipe_get_status(void *arg, void *buf, size_t *szp) +{ + zt_pipe *p = arg; + return (zt_getopt_status(p->zp_ztn, p->zp_nwid, buf, szp)); } static void @@ -2553,96 +2537,184 @@ zt_ep_connect(void *arg, nni_aio *aio) } static int -zt_ep_setopt(void *arg, int opt, const void *data, size_t size) +zt_ep_setopt_recvmaxsz(void *arg, const void *data, size_t sz) { zt_ep *ep = arg; - int i; - int rv = NNG_ENOTSUP; - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&zt_lk); - rv = nni_setopt_size( - &ep->ze_rcvmax, data, size, 0, 0xffffffffu); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_home) { - // XXX: check to make sure not started... - i = nni_strnlen((const char *) data, size); - if ((i >= size) || (i >= NNG_MAXADDRLEN)) { - return (NNG_EINVAL); - } + if (ep == NULL) { + return (nni_chkopt_size(data, sz, 0, 0xffffffffu)); + } + return (nni_setopt_size(&ep->ze_rcvmax, data, sz, 0, 0xffffffffu)); +} + +static int +zt_ep_getopt_recvmaxsz(void *arg, void *data, size_t *szp) +{ + zt_ep *ep = arg; + return (nni_getopt_size(ep->ze_rcvmax, data, szp)); +} + +static int +zt_ep_setopt_home(void *arg, const void *data, size_t sz) +{ + int len; + int rv; + zt_ep *ep = arg; + + len = nni_strnlen(data, sz); + if ((len >= sz) || (len >= NNG_MAXADDRLEN)) { + return (NNG_EINVAL); + } + if (ep != NULL) { nni_mtx_lock(&zt_lk); nni_strlcpy(ep->ze_home, data, sizeof(ep->ze_home)); - rv = zt_node_find(ep); - if (rv != 0) { + if ((rv = zt_node_find(ep)) != 0) { ep->ze_ztn = NULL; } nni_mtx_unlock(&zt_lk); + } else { rv = 0; - } else if (opt == nng_optid_zt_ping_count) { - nni_mtx_lock(&zt_lk); - rv = - nni_setopt_int(&ep->ze_ping_count, data, size, 0, 1000000); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_ping_time) { - nni_mtx_lock(&zt_lk); - rv = nni_setopt_usec(&ep->ze_ping_time, data, size); - nni_mtx_unlock(&zt_lk); } return (rv); } static int -zt_ep_getopt(void *arg, int opt, void *data, size_t *szp) +zt_ep_getopt_home(void *arg, void *data, size_t *szp) { zt_ep *ep = arg; - int rv = NNG_ENOTSUP; + return (nni_getopt_str(ep->ze_home, data, szp)); +} - if (opt == nng_optid_recvmaxsz) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_size(ep->ze_rcvmax, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_home) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_str(ep->ze_home, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_node) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_u64(ep->ze_ztn->zn_self, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_nwid) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_u64(ep->ze_nwid, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_ping_count) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_int(ep->ze_ping_count, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_ping_time) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_usec(ep->ze_ping_time, data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_local_port) { - nni_mtx_lock(&zt_lk); - rv = nni_getopt_int( - (int) (ep->ze_laddr & zt_port_mask), data, szp); - nni_mtx_unlock(&zt_lk); - } else if (opt == nng_optid_zt_network_name) { - rv = - zt_getopt_network_name(ep->ze_ztn, ep->ze_nwid, data, szp); - } else if (opt == nng_optid_zt_status) { - rv = zt_getopt_status(ep->ze_ztn, ep->ze_nwid, data, szp); +static int +zt_ep_getopt_node(void *arg, void *data, size_t *szp) +{ + zt_ep *ep = arg; + return (nni_getopt_u64(ep->ze_ztn->zn_self, data, szp)); +} + +static int +zt_ep_getopt_nwid(void *arg, void *data, size_t *szp) +{ + zt_ep *ep = arg; + return (nni_getopt_u64(ep->ze_nwid, data, szp)); +} + +static int +zt_ep_getopt_network_name(void *arg, void *buf, size_t *szp) +{ + zt_ep *ep = arg; + return (zt_getopt_network_name(ep->ze_ztn, ep->ze_nwid, buf, szp)); +} + +static int +zt_ep_getopt_status(void *arg, void *buf, size_t *szp) +{ + zt_ep *ep = arg; + return (zt_getopt_status(ep->ze_ztn, ep->ze_nwid, buf, szp)); +} + +static int +zt_ep_setopt_ping_time(void *arg, const void *data, size_t sz) +{ + zt_ep *ep = arg; + if (ep == NULL) { + return (nni_chkopt_usec(data, sz)); } - return (rv); + return (nni_setopt_usec(&ep->ze_ping_time, data, sz)); +} + +static int +zt_ep_getopt_ping_time(void *arg, void *data, size_t *szp) +{ + zt_ep *ep = arg; + return (nni_getopt_usec(ep->ze_ping_time, data, szp)); +} + +static int +zt_ep_setopt_ping_count(void *arg, const void *data, size_t sz) +{ + zt_ep *ep = arg; + if (ep == NULL) { + return (nni_chkopt_int(data, sz, 0, 1000000)); + } + return (nni_setopt_int(&ep->ze_ping_count, data, sz, 0, 1000000)); +} + +static int +zt_ep_getopt_ping_count(void *arg, void *data, size_t *szp) +{ + zt_ep *ep = arg; + return (nni_getopt_int(ep->ze_ping_count, data, szp)); } +static nni_tran_pipe_option zt_pipe_options[] = { +#if 0 + { NNG_OPT_RECVMAXSZ, zt_pipe_getopt_recvmaxsz }, + { NNG_ZT_OPT_NWID, zt_pipe_getopt_nwid }, + { NNG_ZT_OPT_NODE, zt_pipe_getopt_node }, + { NNG_ZT_OPT_STATUS, zt_pipe_getopt_status }, + { NNG_ZT_OPT_NETWORK_NAME, zt_pipe_getopt_network_name }, +#endif +#if 0 + { NNG_OPT_LOCADDR, zt_pipe_get_locaddr }, + { NNG_OPT_REMADDR, zt_pipe_get_remaddr } +#endif + // terminate list + { NULL, NULL }, +}; static nni_tran_pipe zt_pipe_ops = { - .p_fini = zt_pipe_fini, - .p_start = zt_pipe_start, - .p_send = zt_pipe_send, - .p_recv = zt_pipe_recv, - .p_close = zt_pipe_close, - .p_peer = zt_pipe_peer, - .p_getopt = zt_pipe_getopt, + .p_fini = zt_pipe_fini, + .p_start = zt_pipe_start, + .p_send = zt_pipe_send, + .p_recv = zt_pipe_recv, + .p_close = zt_pipe_close, + .p_peer = zt_pipe_peer, + .p_options = zt_pipe_options, +}; + +static nni_tran_ep_option zt_ep_options[] = { + { + .eo_name = NNG_OPT_RECVMAXSZ, + .eo_getopt = zt_ep_getopt_recvmaxsz, + .eo_setopt = zt_ep_setopt_recvmaxsz, + }, + { + .eo_name = NNG_ZT_OPT_HOME, + .eo_getopt = zt_ep_getopt_home, + .eo_setopt = zt_ep_setopt_home, + }, + { + .eo_name = NNG_ZT_OPT_NODE, + .eo_getopt = zt_ep_getopt_node, + .eo_setopt = NULL, + }, + { + .eo_name = NNG_ZT_OPT_NWID, + .eo_getopt = zt_ep_getopt_nwid, + .eo_setopt = NULL, + }, + { + .eo_name = NNG_ZT_OPT_STATUS, + .eo_getopt = zt_ep_getopt_status, + .eo_setopt = NULL, + }, + { + .eo_name = NNG_ZT_OPT_NETWORK_NAME, + .eo_getopt = zt_ep_getopt_network_name, + .eo_setopt = NULL, + }, + { + .eo_name = NNG_ZT_OPT_PING_TIME, + .eo_getopt = zt_ep_getopt_ping_time, + .eo_setopt = zt_ep_setopt_ping_time, + }, + { + .eo_name = NNG_ZT_OPT_PING_COUNT, + .eo_getopt = zt_ep_getopt_ping_count, + .eo_setopt = zt_ep_setopt_ping_count, + }, + // terminate list + { NULL, NULL, NULL }, }; static nni_tran_ep zt_ep_ops = { @@ -2652,8 +2724,7 @@ static nni_tran_ep zt_ep_ops = { .ep_bind = zt_ep_bind, .ep_accept = zt_ep_accept, .ep_close = zt_ep_close, - .ep_setopt = zt_ep_setopt, - .ep_getopt = zt_ep_getopt, + .ep_options = zt_ep_options, }; // This is the ZeroTier transport linkage, and should be the @@ -2663,7 +2734,6 @@ static struct nni_tran zt_tran = { .tran_scheme = "zt", .tran_ep = &zt_ep_ops, .tran_pipe = &zt_pipe_ops, - .tran_chkopt = zt_chkopt, .tran_init = zt_tran_init, .tran_fini = zt_tran_fini, }; |
