diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/defs.h | 34 | ||||
| -rw-r--r-- | src/core/endpt.c | 44 | ||||
| -rw-r--r-- | src/core/endpt.h | 14 | ||||
| -rw-r--r-- | src/core/options.c | 96 | ||||
| -rw-r--r-- | src/core/options.h | 31 | ||||
| -rw-r--r-- | src/core/pipe.c | 13 | ||||
| -rw-r--r-- | src/core/pipe.h | 3 | ||||
| -rw-r--r-- | src/core/protocol.h | 25 | ||||
| -rw-r--r-- | src/core/socket.c | 466 | ||||
| -rw-r--r-- | src/core/socket.h | 19 | ||||
| -rw-r--r-- | src/core/transport.c | 18 | ||||
| -rw-r--r-- | src/core/transport.h | 134 |
12 files changed, 431 insertions, 466 deletions
diff --git a/src/core/defs.h b/src/core/defs.h index 29d1b826..77078a7a 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -40,22 +40,20 @@ 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_ctx nni_ctx; -typedef struct nni_ep nni_ep; -typedef struct nni_pipe nni_pipe; -typedef struct nni_tran nni_tran; -typedef struct nni_tran_ep_ops nni_tran_ep_ops; -typedef struct nni_tran_ep_option nni_tran_ep_option; -typedef struct nni_tran_pipe_ops nni_tran_pipe_ops; -typedef struct nni_tran_pipe_option nni_tran_pipe_option; - -typedef struct nni_proto_ctx_option nni_proto_ctx_option; -typedef struct nni_proto_ctx_ops nni_proto_ctx_ops; -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_socket nni_sock; +typedef struct nni_ctx nni_ctx; +typedef struct nni_ep nni_ep; +typedef struct nni_pipe nni_pipe; +typedef struct nni_tran nni_tran; +typedef struct nni_tran_option nni_tran_option; +typedef struct nni_tran_ep_ops nni_tran_ep_ops; +typedef struct nni_tran_pipe_ops nni_tran_pipe_ops; + +typedef struct nni_proto_option nni_proto_option; +typedef struct nni_proto_ctx_ops nni_proto_ctx_ops; +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_plat_mtx nni_mtx; typedef struct nni_plat_cv nni_cv; @@ -140,7 +138,7 @@ typedef struct { // Types. These are used to provide more structured access to options // (and maybe later statistics). For now these are internal only. -enum nni_type { +typedef enum nni_opt_type { NNI_TYPE_OPAQUE, NNI_TYPE_BOOL, NNI_TYPE_INT32, @@ -152,6 +150,6 @@ enum nni_type { NNI_TYPE_STRING, NNI_TYPE_SOCKADDR, NNI_TYPE_POINTER, -}; +} nni_opt_type; #endif // CORE_DEFS_H diff --git a/src/core/endpt.c b/src/core/endpt.c index 9fc26cf3..8e678fb0 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -582,26 +582,27 @@ nni_ep_pipe_remove(nni_ep *ep, nni_pipe *pipe) } int -nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz, int t) +nni_ep_setopt( + nni_ep *ep, const char *name, const void *val, size_t sz, nni_opt_type t) { - nni_tran_ep_option *eo; + nni_tran_option *o; if (strcmp(name, NNG_OPT_URL) == 0) { return (NNG_EREADONLY); } - for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { + for (o = ep->ep_ops.ep_options; o && o->o_name; o++) { int rv; - if (strcmp(eo->eo_name, name) != 0) { + if (strcmp(o->o_name, name) != 0) { continue; } - if (eo->eo_setopt == NULL) { + if (o->o_set == NULL) { return (NNG_EREADONLY); } nni_mtx_lock(&ep->ep_mtx); - rv = eo->eo_setopt(ep->ep_data, val, sz, t); + rv = o->o_set(ep->ep_data, val, sz, t); nni_mtx_unlock(&ep->ep_mtx); return (rv); } @@ -616,38 +617,21 @@ nni_ep_mode(nni_ep *ep) } int -nni_ep_opttype(nni_ep *ep, const char *name, int *tp) +nni_ep_getopt( + nni_ep *ep, const char *name, void *valp, size_t *szp, nni_opt_type t) { - nni_tran_ep_option *eo; + nni_tran_option *o; - for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { - if (strcmp(eo->eo_name, name) == 0) { - *tp = eo->eo_type; - return (0); - } - } - if (strcmp(name, NNG_OPT_URL) == 0) { - *tp = NNI_TYPE_STRING; - return (0); - } - return (NNG_ENOTSUP); -} - -int -nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp, int t) -{ - nni_tran_ep_option *eo; - - for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { + for (o = ep->ep_ops.ep_options; o && o->o_name; o++) { int rv; - if (strcmp(eo->eo_name, name) != 0) { + if (strcmp(o->o_name, name) != 0) { continue; } - if (eo->eo_getopt == NULL) { + if (o->o_get == NULL) { return (NNG_EWRITEONLY); } nni_mtx_lock(&ep->ep_mtx); - rv = eo->eo_getopt(ep->ep_data, valp, szp, t); + rv = o->o_get(ep->ep_data, valp, szp, t); nni_mtx_unlock(&ep->ep_mtx); return (rv); } diff --git a/src/core/endpt.h b/src/core/endpt.h index 2511c1ff..bf251d41 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -26,12 +26,14 @@ 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, int); -extern int nni_ep_getopt(nni_ep *, const char *, void *, size_t *, int); -extern int nni_ep_opttype(nni_ep *, const char *, int *); -extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); -extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); -extern int nni_ep_mode(nni_ep *); +extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); +extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); +extern int nni_ep_mode(nni_ep *); + +extern int nni_ep_setopt( + nni_ep *, const char *, const void *, size_t, nni_opt_type); +extern int nni_ep_getopt( + nni_ep *, const char *, void *, size_t *, nni_opt_type); // Endpoint modes. Currently used by transports. Remove this when we make // transport dialers and listeners explicit. diff --git a/src/core/options.c b/src/core/options.c index e0c72d25..3e35f44c 100644 --- a/src/core/options.c +++ b/src/core/options.c @@ -14,11 +14,11 @@ #include <string.h> int -nni_copyin_ms(nni_duration *dp, const void *v, size_t sz, int typ) +nni_copyin_ms(nni_duration *dp, const void *v, size_t sz, nni_opt_type t) { nni_duration dur; - switch (typ) { + switch (t) { case NNI_TYPE_DURATION: dur = *(nng_duration *) v; break; @@ -35,22 +35,28 @@ nni_copyin_ms(nni_duration *dp, const void *v, size_t sz, int typ) if (dur < -1) { return (NNG_EINVAL); } - *dp = dur; + if (dp != NULL) { + *dp = dur; + } return (0); } int -nni_copyin_bool(bool *bp, const void *v, size_t sz, int typ) +nni_copyin_bool(bool *bp, const void *v, size_t sz, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_BOOL: - *bp = *(bool *) v; + if (bp != NULL) { + *bp = *(bool *) v; + } break; case NNI_TYPE_OPAQUE: if (sz != sizeof(bool)) { return (NNG_EINVAL); } - memcpy(bp, v, sz); + if (bp != NULL) { + memcpy(bp, v, sz); + } break; default: return (NNG_EBADTYPE); @@ -60,11 +66,12 @@ nni_copyin_bool(bool *bp, const void *v, size_t sz, int typ) } int -nni_copyin_int(int *ip, const void *v, size_t sz, int minv, int maxv, int typ) +nni_copyin_int( + int *ip, const void *v, size_t sz, int minv, int maxv, nni_opt_type t) { int i; - switch (typ) { + switch (t) { case NNI_TYPE_INT32: i = *(int *) v; break; @@ -83,17 +90,19 @@ nni_copyin_int(int *ip, const void *v, size_t sz, int minv, int maxv, int typ) if (i < minv) { return (NNG_EINVAL); } - *ip = i; + if (ip != NULL) { + *ip = i; + } return (0); } int -nni_copyin_size( - size_t *sp, const void *v, size_t sz, size_t minv, size_t maxv, int typ) +nni_copyin_size(size_t *sp, const void *v, size_t sz, size_t minv, size_t maxv, + nni_opt_type t) { size_t val; - switch (typ) { + switch (t) { case NNI_TYPE_SIZE: val = *(size_t *) v; break; @@ -111,16 +120,18 @@ nni_copyin_size( if ((val > maxv) || (val < minv)) { return (NNG_EINVAL); } - *sp = val; + if (sp != NULL) { + *sp = val; + } return (0); } int -nni_copyin_ptr(void **pp, const void *v, size_t sz, int typ) +nni_copyin_ptr(void **pp, const void *v, size_t sz, nni_opt_type t) { void *p; - switch (typ) { + switch (t) { case NNI_TYPE_POINTER: p = *(void **) v; break; @@ -133,16 +144,18 @@ nni_copyin_ptr(void **pp, const void *v, size_t sz, int typ) default: return (NNG_EBADTYPE); } - *pp = p; + if (pp != NULL) { + *pp = p; + } return (0); } int -nni_copyin_str(char *s, const void *v, size_t sz, size_t maxsz, int typ) +nni_copyin_str(char *s, const void *v, size_t sz, size_t maxsz, nni_opt_type t) { size_t z; - switch (typ) { + switch (t) { case NNI_TYPE_STRING: z = strlen(v) + 1; NNI_ASSERT(sz == z); @@ -158,16 +171,18 @@ nni_copyin_str(char *s, const void *v, size_t sz, size_t maxsz, int typ) if (z > maxsz) { return (NNG_EINVAL); // too long } - memcpy(s, v, z); + if (s != NULL) { + memcpy(s, v, z); + } return (0); } int -nni_copyin_u64(uint64_t *up, const void *v, size_t sz, int typ) +nni_copyin_u64(uint64_t *up, const void *v, size_t sz, nni_opt_type t) { uint64_t u; - switch (typ) { + switch (t) { case NNI_TYPE_UINT64: u = *(uint64_t *) v; break; @@ -180,7 +195,9 @@ nni_copyin_u64(uint64_t *up, const void *v, size_t sz, int typ) default: return (NNG_EBADTYPE); } - *up = u; + if (up != NULL) { + *up = u; + } return (0); } @@ -202,9 +219,9 @@ nni_copyout(const void *src, size_t srcsz, void *dst, size_t *dstszp) } int -nni_copyout_bool(bool b, void *dst, size_t *szp, int typ) +nni_copyout_bool(bool b, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_BOOL: NNI_ASSERT(*szp == sizeof(b)); *(bool *) dst = b; @@ -217,9 +234,9 @@ nni_copyout_bool(bool b, void *dst, size_t *szp, int typ) } int -nni_copyout_int(int i, void *dst, size_t *szp, int typ) +nni_copyout_int(int i, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_INT32: NNI_ASSERT(*szp == sizeof(i)); *(int *) dst = i; @@ -232,9 +249,9 @@ nni_copyout_int(int i, void *dst, size_t *szp, int typ) } int -nni_copyout_ms(nng_duration d, void *dst, size_t *szp, int typ) +nni_copyout_ms(nng_duration d, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_DURATION: NNI_ASSERT(*szp == sizeof(d)); *(nng_duration *) dst = d; @@ -247,9 +264,9 @@ nni_copyout_ms(nng_duration d, void *dst, size_t *szp, int typ) } int -nni_copyout_ptr(void *p, void *dst, size_t *szp, int typ) +nni_copyout_ptr(void *p, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_POINTER: NNI_ASSERT(*szp == sizeof(p)); *(void **) dst = p; @@ -262,9 +279,9 @@ nni_copyout_ptr(void *p, void *dst, size_t *szp, int typ) } int -nni_copyout_size(size_t s, void *dst, size_t *szp, int typ) +nni_copyout_size(size_t s, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_SIZE: NNI_ASSERT(*szp == sizeof(s)); *(size_t *) dst = s; @@ -277,9 +294,10 @@ nni_copyout_size(size_t s, void *dst, size_t *szp, int typ) } int -nni_copyout_sockaddr(const nng_sockaddr *sap, void *dst, size_t *szp, int typ) +nni_copyout_sockaddr( + const nng_sockaddr *sap, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_SOCKADDR: NNI_ASSERT(*szp == sizeof(*sap)); *(nng_sockaddr *) dst = *sap; @@ -292,9 +310,9 @@ nni_copyout_sockaddr(const nng_sockaddr *sap, void *dst, size_t *szp, int typ) } int -nni_copyout_u64(uint64_t u, void *dst, size_t *szp, int typ) +nni_copyout_u64(uint64_t u, void *dst, size_t *szp, nni_opt_type t) { - switch (typ) { + switch (t) { case NNI_TYPE_UINT64: NNI_ASSERT(*szp == sizeof(u)); *(uint64_t *) dst = u; @@ -307,11 +325,11 @@ nni_copyout_u64(uint64_t u, void *dst, size_t *szp, int typ) } int -nni_copyout_str(const char *str, void *dst, size_t *szp, int typ) +nni_copyout_str(const char *str, void *dst, size_t *szp, nni_opt_type t) { char *s; - switch (typ) { + switch (t) { case NNI_TYPE_STRING: NNI_ASSERT(*szp == sizeof(char *)); if ((s = nni_strdup(str)) == NULL) { diff --git a/src/core/options.h b/src/core/options.h index dfc15d31..2a21a039 100644 --- a/src/core/options.h +++ b/src/core/options.h @@ -24,28 +24,29 @@ // in their own option handling, centralizing the logic for dealing with // variable sized options. -extern int nni_copyin_ms(nni_duration *, const void *, size_t, int); -extern int nni_copyin_bool(bool *, const void *, size_t, int); -extern int nni_copyin_int(int *, const void *, size_t, int, int, int); +extern int nni_copyin_ms(nni_duration *, const void *, size_t, nni_opt_type); +extern int nni_copyin_bool(bool *, const void *, size_t, nni_opt_type); +extern int nni_copyin_int(int *, const void *, size_t, int, int, nni_opt_type); extern int nni_copyin_size( - size_t *, const void *, size_t, size_t, size_t, int); -extern int nni_copyin_str(char *, const void *, size_t, size_t, int); -extern int nni_copyin_ptr(void **, const void *, size_t, int); -extern int nni_copyin_u64(uint64_t *, const void *, size_t, int); + size_t *, const void *, size_t, size_t, size_t, nni_opt_type); +extern int nni_copyin_str(char *, const void *, size_t, size_t, nni_opt_type); +extern int nni_copyin_ptr(void **, const void *, size_t, nni_opt_type); +extern int nni_copyin_u64(uint64_t *, const void *, size_t, nni_opt_type); // nni_copyout_xxx copies out a type of the named value. It assumes that // the type is aligned and the size correct, unless NNI_TYPE_OPAQUE is passed. extern int nni_copyout(const void *, size_t, void *, size_t *); -extern int nni_copyout_bool(bool, void *, size_t *, int); -extern int nni_copyout_int(int, void *, size_t *, int); -extern int nni_copyout_ms(nng_duration, void *, size_t *, int); -extern int nni_copyout_ptr(void *, void *, size_t *, int); -extern int nni_copyout_size(size_t, void *, size_t *, int); -extern int nni_copyout_sockaddr(const nng_sockaddr *, void *, size_t *, int); -extern int nni_copyout_u64(uint64_t, void *, size_t *, int); +extern int nni_copyout_bool(bool, void *, size_t *, nni_opt_type); +extern int nni_copyout_int(int, void *, size_t *, nni_opt_type); +extern int nni_copyout_ms(nng_duration, void *, size_t *, nni_opt_type); +extern int nni_copyout_ptr(void *, void *, size_t *, nni_opt_type); +extern int nni_copyout_size(size_t, void *, size_t *, nni_opt_type); +extern int nni_copyout_sockaddr( + const nng_sockaddr *, void *, size_t *, nni_opt_type); +extern int nni_copyout_u64(uint64_t, void *, size_t *, nni_opt_type); // nni_copyout_str copies out a string. If the type is NNI_TYPE_STRING, // then it passes through a pointer, created by nni_strdup(). -extern int nni_copyout_str(const char *, void *, size_t *, int); +extern int nni_copyout_str(const char *, void *, size_t *, nni_opt_type); #endif // CORE_OPTIONS_H diff --git a/src/core/pipe.c b/src/core/pipe.c index ccd0dbe7..93fbae99 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -359,18 +359,19 @@ nni_pipe_create(nni_ep *ep, void *tdata) } int -nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp, int typ) +nni_pipe_getopt( + nni_pipe *p, const char *name, void *val, size_t *szp, nni_opt_type t) { - nni_tran_pipe_option *po; + nni_tran_option *o; - for (po = p->p_tran_ops.p_options; po && po->po_name; po++) { - if (strcmp(po->po_name, name) != 0) { + for (o = p->p_tran_ops.p_options; o && o->o_name; o++) { + if (strcmp(o->o_name, name) != 0) { continue; } - return (po->po_getopt(p->p_tran_data, val, szp, typ)); + return (o->o_get(p->p_tran_data, val, szp, t)); } // Maybe the endpoint knows? - return (nni_ep_getopt(p->p_ep, name, val, szp, typ)); + return (nni_ep_getopt(p->p_ep, name, val, szp, t)); } void diff --git a/src/core/pipe.h b/src/core/pipe.h index 4ccbeae2..bd66d4ed 100644 --- a/src/core/pipe.h +++ b/src/core/pipe.h @@ -60,7 +60,8 @@ extern uint16_t nni_pipe_peer(nni_pipe *); // nni_pipe_getopt looks up the option. The last argument is the type, // which. If the type is NNI_TYPE_OPAQUE, then no format check is performed. -extern int nni_pipe_getopt(nni_pipe *, const char *, void *, size_t *, int); +extern int nni_pipe_getopt( + nni_pipe *, const char *, void *, size_t *, nni_opt_type); // 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 9c3b4d33..12ca7e71 100644 --- a/src/core/protocol.h +++ b/src/core/protocol.h @@ -21,6 +21,13 @@ // As a consequence, most of the concurrency in nng exists in the protocol // implementations. +struct nni_proto_option { + const char *o_name; + int o_type; + int (*o_get)(void *, void *, size_t *, nni_opt_type); + int (*o_set)(void *, const void *, size_t, nni_opt_type); +}; + // nni_proto_pipe contains protocol-specific per-pipe operations. struct nni_proto_pipe_ops { // pipe_init creates the protocol-specific per pipe data structure. @@ -50,13 +57,6 @@ struct nni_proto_pipe_ops { void (*pipe_stop)(void *); }; -struct nni_proto_ctx_option { - const char *co_name; - int co_type; - int (*co_getopt)(void *, void *, size_t *, int); - int (*co_setopt)(void *, const void *, size_t, int); -}; - struct nni_proto_ctx_ops { // ctx_init creates a new context. The second argument is the // protocol specific socket structure. @@ -80,14 +80,7 @@ struct nni_proto_ctx_ops { void (*ctx_drain)(void *, nni_aio *); // ctx_options array. - nni_proto_ctx_option *ctx_options; -}; - -struct nni_proto_sock_option { - const char *pso_name; - int pso_type; - int (*pso_getopt)(void *, void *, size_t *, int); - int (*pso_setopt)(void *, const void *, size_t, int); + nni_proto_option *ctx_options; }; struct nni_proto_sock_ops { @@ -130,7 +123,7 @@ struct nni_proto_sock_ops { void (*sock_drain)(void *, nni_aio *); // Options. Must not be NULL. Final entry should have NULL name. - nni_proto_sock_option *sock_options; + nni_proto_option *sock_options; }; typedef struct nni_proto_id { diff --git a/src/core/socket.c b/src/core/socket.c index bc94056f..4cf624e2 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -15,10 +15,10 @@ // Socket implementation. -static nni_list nni_sock_list; -static nni_idhash *nni_sock_hash; -static nni_mtx nni_sock_lk; -static nni_idhash *nni_ctx_hash; +static nni_list sock_list; +static nni_idhash *sock_hash; +static nni_mtx sock_lk; +static nni_idhash *ctx_hash; struct nni_ctx { nni_list_node c_node; @@ -32,12 +32,12 @@ struct nni_ctx { nng_duration c_rcvtimeo; }; -typedef struct nni_socket_option { - const char *so_name; - int so_type; - int (*so_getopt)(nni_sock *, void *, size_t *, int); - int (*so_setopt)(nni_sock *, const void *, size_t, int); -} nni_socket_option; +typedef struct sock_option { + const char *o_name; + int o_type; + int (*o_get)(nni_sock *, void *, size_t *, nni_opt_type); + int (*o_set)(nni_sock *, const void *, size_t, nni_opt_type); +} sock_option; typedef struct nni_sockopt { nni_list_node node; @@ -84,7 +84,7 @@ struct nni_socket { nni_list s_eps; // active endpoints nni_list s_pipes; // active pipes - nni_list s_ctxs; // active contexts (protected by global nni_sock_lk) + nni_list s_ctxs; // active contexts (protected by global sock_lk) bool s_closing; // Socket is closing bool s_closed; // Socket closed, protected by global lock @@ -97,7 +97,7 @@ struct nni_socket { static void nni_ctx_destroy(nni_ctx *); static int -nni_sock_get_fd(nni_sock *s, int flag, int *fdp) +sock_get_fd(nni_sock *s, int flag, int *fdp) { int rv; nni_pollable *p; @@ -126,248 +126,241 @@ nni_sock_get_fd(nni_sock *s, int flag, int *fdp) } static int -nni_sock_getopt_sendfd(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_sendfd(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { int fd; int rv; - if ((rv = nni_sock_get_fd(s, NNI_PROTO_FLAG_SND, &fd)) != 0) { + if ((rv = sock_get_fd(s, NNI_PROTO_FLAG_SND, &fd)) != 0) { return (rv); } - return (nni_copyout_int(fd, buf, szp, typ)); + return (nni_copyout_int(fd, buf, szp, t)); } static int -nni_sock_getopt_recvfd(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_recvfd(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { int fd; int rv; - if ((rv = nni_sock_get_fd(s, NNI_PROTO_FLAG_RCV, &fd)) != 0) { + if ((rv = sock_get_fd(s, NNI_PROTO_FLAG_RCV, &fd)) != 0) { return (rv); } - return (nni_copyout_int(fd, buf, szp, typ)); + return (nni_copyout_int(fd, buf, szp, t)); } static int -nni_sock_getopt_raw(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_raw(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { bool raw = ((nni_sock_flags(s) & NNI_PROTO_FLAG_RAW) != 0); - return (nni_copyout_bool(raw, buf, szp, typ)); + return (nni_copyout_bool(raw, buf, szp, t)); } static int -nni_sock_setopt_recvtimeo(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_recvtimeo(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { - return (nni_copyin_ms(&s->s_rcvtimeo, buf, sz, typ)); + return (nni_copyin_ms(&s->s_rcvtimeo, buf, sz, t)); } static int -nni_sock_getopt_recvtimeo(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_recvtimeo(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_ms(s->s_rcvtimeo, buf, szp, typ)); + return (nni_copyout_ms(s->s_rcvtimeo, buf, szp, t)); } static int -nni_sock_setopt_sendtimeo(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_sendtimeo(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { - return (nni_copyin_ms(&s->s_sndtimeo, buf, sz, typ)); + return (nni_copyin_ms(&s->s_sndtimeo, buf, sz, t)); } static int -nni_sock_getopt_sendtimeo(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_sendtimeo(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_ms(s->s_sndtimeo, buf, szp, typ)); + return (nni_copyout_ms(s->s_sndtimeo, buf, szp, t)); } static int -nni_sock_setopt_reconnmint(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_reconnmint(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { - return (nni_copyin_ms(&s->s_reconn, buf, sz, typ)); + return (nni_copyin_ms(&s->s_reconn, buf, sz, t)); } static int -nni_sock_getopt_reconnmint(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_reconnmint(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_ms(s->s_reconn, buf, szp, typ)); + return (nni_copyout_ms(s->s_reconn, buf, szp, t)); } static int -nni_sock_setopt_reconnmaxt(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_reconnmaxt(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { - return (nni_copyin_ms(&s->s_reconnmax, buf, sz, typ)); + return (nni_copyin_ms(&s->s_reconnmax, buf, sz, t)); } static int -nni_sock_getopt_reconnmaxt(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_reconnmaxt(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_ms(s->s_reconnmax, buf, szp, typ)); + return (nni_copyout_ms(s->s_reconnmax, buf, szp, t)); } static int -nni_sock_setopt_recvbuf(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_recvbuf(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { int len; int rv; - if ((rv = nni_copyin_int(&len, buf, sz, 0, 8192, typ)) != 0) { + if ((rv = nni_copyin_int(&len, buf, sz, 0, 8192, t)) != 0) { return (rv); } return (nni_msgq_resize(s->s_urq, len)); } static int -nni_sock_getopt_recvbuf(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_recvbuf(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { int len = nni_msgq_cap(s->s_urq); - return (nni_copyout_int(len, buf, szp, typ)); + return (nni_copyout_int(len, buf, szp, t)); } static int -nni_sock_setopt_sendbuf(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_sendbuf(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { int len; int rv; - if ((rv = nni_copyin_int(&len, buf, sz, 0, 8192, typ)) != 0) { + if ((rv = nni_copyin_int(&len, buf, sz, 0, 8192, t)) != 0) { return (rv); } return (nni_msgq_resize(s->s_uwq, len)); } static int -nni_sock_getopt_sendbuf(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_sendbuf(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { int len = nni_msgq_cap(s->s_uwq); - return (nni_copyout_int(len, buf, szp, typ)); + return (nni_copyout_int(len, buf, szp, t)); } static int -nni_sock_getopt_sockname(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_sockname(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_str(s->s_name, buf, szp, typ)); + return (nni_copyout_str(s->s_name, buf, szp, t)); } static int -nni_sock_setopt_sockname(nni_sock *s, const void *buf, size_t sz, int typ) +sock_set_sockname(nni_sock *s, const void *buf, size_t sz, nni_opt_type t) { - return (nni_copyin_str(s->s_name, buf, sizeof(s->s_name), sz, typ)); + return (nni_copyin_str(s->s_name, buf, sizeof(s->s_name), sz, t)); } static int -nni_sock_getopt_proto(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_proto(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_int(nni_sock_proto_id(s), buf, szp, typ)); + return (nni_copyout_int(nni_sock_proto_id(s), buf, szp, t)); } static int -nni_sock_getopt_peer(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_peer(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_int(nni_sock_peer_id(s), buf, szp, typ)); + return (nni_copyout_int(nni_sock_peer_id(s), buf, szp, t)); } static int -nni_sock_getopt_protoname(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_protoname(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_str(nni_sock_proto_name(s), buf, szp, typ)); + return (nni_copyout_str(nni_sock_proto_name(s), buf, szp, t)); } static int -nni_sock_getopt_peername(nni_sock *s, void *buf, size_t *szp, int typ) +sock_get_peername(nni_sock *s, void *buf, size_t *szp, nni_opt_type t) { - return (nni_copyout_str(nni_sock_peer_name(s), buf, szp, typ)); + return (nni_copyout_str(nni_sock_peer_name(s), buf, szp, t)); } -static const nni_socket_option nni_sock_options[] = { +static const sock_option sock_options[] = { { - .so_name = NNG_OPT_RECVTIMEO, - .so_type = NNI_TYPE_DURATION, - .so_getopt = nni_sock_getopt_recvtimeo, - .so_setopt = nni_sock_setopt_recvtimeo, + .o_name = NNG_OPT_RECVTIMEO, + .o_type = NNI_TYPE_DURATION, + .o_get = sock_get_recvtimeo, + .o_set = sock_set_recvtimeo, }, { - .so_name = NNG_OPT_SENDTIMEO, - .so_type = NNI_TYPE_DURATION, - .so_getopt = nni_sock_getopt_sendtimeo, - .so_setopt = nni_sock_setopt_sendtimeo, + .o_name = NNG_OPT_SENDTIMEO, + .o_type = NNI_TYPE_DURATION, + .o_get = sock_get_sendtimeo, + .o_set = sock_set_sendtimeo, }, { - .so_name = NNG_OPT_RECVFD, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_recvfd, - .so_setopt = NULL, + .o_name = NNG_OPT_RECVFD, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_recvfd, }, { - .so_name = NNG_OPT_SENDFD, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_sendfd, - .so_setopt = NULL, + .o_name = NNG_OPT_SENDFD, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_sendfd, }, { - .so_name = NNG_OPT_RECVBUF, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_recvbuf, - .so_setopt = nni_sock_setopt_recvbuf, + .o_name = NNG_OPT_RECVBUF, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_recvbuf, + .o_set = sock_set_recvbuf, }, { - .so_name = NNG_OPT_SENDBUF, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_sendbuf, - .so_setopt = nni_sock_setopt_sendbuf, + .o_name = NNG_OPT_SENDBUF, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_sendbuf, + .o_set = sock_set_sendbuf, }, { - .so_name = NNG_OPT_RECONNMINT, - .so_type = NNI_TYPE_DURATION, - .so_getopt = nni_sock_getopt_reconnmint, - .so_setopt = nni_sock_setopt_reconnmint, + .o_name = NNG_OPT_RECONNMINT, + .o_type = NNI_TYPE_DURATION, + .o_get = sock_get_reconnmint, + .o_set = sock_set_reconnmint, }, { - .so_name = NNG_OPT_RECONNMAXT, - .so_type = NNI_TYPE_DURATION, - .so_getopt = nni_sock_getopt_reconnmaxt, - .so_setopt = nni_sock_setopt_reconnmaxt, + .o_name = NNG_OPT_RECONNMAXT, + .o_type = NNI_TYPE_DURATION, + .o_get = sock_get_reconnmaxt, + .o_set = sock_set_reconnmaxt, }, { - .so_name = NNG_OPT_SOCKNAME, - .so_type = NNI_TYPE_STRING, - .so_getopt = nni_sock_getopt_sockname, - .so_setopt = nni_sock_setopt_sockname, + .o_name = NNG_OPT_SOCKNAME, + .o_type = NNI_TYPE_STRING, + .o_get = sock_get_sockname, + .o_set = sock_set_sockname, }, { - .so_name = NNG_OPT_RAW, - .so_type = NNI_TYPE_BOOL, - .so_getopt = nni_sock_getopt_raw, - .so_setopt = NULL, + .o_name = NNG_OPT_RAW, + .o_type = NNI_TYPE_BOOL, + .o_get = sock_get_raw, }, { - .so_name = NNG_OPT_PROTO, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_proto, - .so_setopt = NULL, + .o_name = NNG_OPT_PROTO, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_proto, }, { - .so_name = NNG_OPT_PEER, - .so_type = NNI_TYPE_INT32, - .so_getopt = nni_sock_getopt_peer, - .so_setopt = NULL, + .o_name = NNG_OPT_PEER, + .o_type = NNI_TYPE_INT32, + .o_get = sock_get_peer, }, { - .so_name = NNG_OPT_PROTONAME, - .so_type = NNI_TYPE_STRING, - .so_getopt = nni_sock_getopt_protoname, - .so_setopt = NULL, + .o_name = NNG_OPT_PROTONAME, + .o_type = NNI_TYPE_STRING, + .o_get = sock_get_protoname, }, { - .so_name = NNG_OPT_PEERNAME, - .so_type = NNI_TYPE_STRING, - .so_getopt = nni_sock_getopt_peername, - .so_setopt = NULL, + .o_name = NNG_OPT_PEERNAME, + .o_type = NNI_TYPE_STRING, + .o_get = sock_get_peername, }, // terminate list { - .so_name = NULL, + .o_name = NULL, }, }; @@ -408,8 +401,8 @@ nni_sock_find(nni_sock **sockp, uint32_t id) if ((rv = nni_init()) != 0) { return (rv); } - nni_mtx_lock(&nni_sock_lk); - if ((rv = nni_idhash_find(nni_sock_hash, id, (void **) &s)) == 0) { + nni_mtx_lock(&sock_lk); + if ((rv = nni_idhash_find(sock_hash, id, (void **) &s)) == 0) { if (s->s_closed) { rv = NNG_ECLOSED; } else { @@ -417,7 +410,7 @@ nni_sock_find(nni_sock **sockp, uint32_t id) *sockp = s; } } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); if (rv == NNG_ENOENT) { rv = NNG_ECLOSED; @@ -429,12 +422,12 @@ nni_sock_find(nni_sock **sockp, uint32_t id) void nni_sock_rele(nni_sock *s) { - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); s->s_refcnt--; if (s->s_closed && (s->s_refcnt < 2)) { nni_cv_wake(&s->s_close_cv); } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); } bool @@ -500,7 +493,7 @@ nni_sock_pipe_remove(nni_sock *s, nni_pipe *p) } static void -nni_sock_destroy(nni_sock *s) +sock_destroy(nni_sock *s) { nni_sockopt *sopt; @@ -569,7 +562,7 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto) nni_mtx_init(&s->s_mx); nni_mtx_init(&s->s_pipe_cbs_mtx); nni_cv_init(&s->s_cv, &s->s_mx); - nni_cv_init(&s->s_close_cv, &nni_sock_lk); + nni_cv_init(&s->s_close_cv, &sock_lk); if (((rv = nni_msgq_init(&s->s_uwq, 0)) != 0) || ((rv = nni_msgq_init(&s->s_urq, 1)) != 0) || @@ -584,7 +577,7 @@ nni_sock_create(nni_sock **sp, const nni_proto *proto) sizeof(nni_duration), NNI_TYPE_DURATION)) != 0) || ((rv = nni_sock_setopt(s, NNG_OPT_RECVMAXSZ, &s->s_rcvmaxsz, sizeof(size_t), NNI_TYPE_SIZE)) != 0)) { - nni_sock_destroy(s); + sock_destroy(s); return (rv); } @@ -612,31 +605,31 @@ nni_sock_sys_init(void) { int rv; - NNI_LIST_INIT(&nni_sock_list, nni_sock, s_node); - nni_mtx_init(&nni_sock_lk); + NNI_LIST_INIT(&sock_list, nni_sock, s_node); + nni_mtx_init(&sock_lk); - if (((rv = nni_idhash_init(&nni_sock_hash)) != 0) || - ((rv = nni_idhash_init(&nni_ctx_hash)) != 0)) { + if (((rv = nni_idhash_init(&sock_hash)) != 0) || + ((rv = nni_idhash_init(&ctx_hash)) != 0)) { nni_sock_sys_fini(); return (rv); } - nni_idhash_set_limits(nni_sock_hash, 1, 0x7fffffff, 1); - nni_idhash_set_limits(nni_ctx_hash, 1, 0x7fffffff, 1); + nni_idhash_set_limits(sock_hash, 1, 0x7fffffff, 1); + nni_idhash_set_limits(ctx_hash, 1, 0x7fffffff, 1); return (0); } void nni_sock_sys_fini(void) { - if (nni_sock_hash != NULL) { - nni_idhash_fini(nni_sock_hash); - nni_sock_hash = NULL; + if (sock_hash != NULL) { + nni_idhash_fini(sock_hash); + sock_hash = NULL; } - if (nni_ctx_hash != NULL) { - nni_idhash_fini(nni_ctx_hash); - nni_ctx_hash = NULL; + if (ctx_hash != NULL) { + nni_idhash_fini(ctx_hash); + ctx_hash = NULL; } - nni_mtx_fini(&nni_sock_lk); + nni_mtx_fini(&sock_lk); } int @@ -655,15 +648,15 @@ nni_sock_open(nni_sock **sockp, const nni_proto *proto) return (rv); } - nni_mtx_lock(&nni_sock_lk); - if ((rv = nni_idhash_alloc(nni_sock_hash, &s->s_id, s)) != 0) { - nni_sock_destroy(s); + nni_mtx_lock(&sock_lk); + if ((rv = nni_idhash_alloc(sock_hash, &s->s_id, s)) != 0) { + sock_destroy(s); } else { - nni_list_append(&nni_sock_list, s); + nni_list_append(&sock_list, s); s->s_sock_ops.sock_open(s->s_data); *sockp = s; } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); // Set the sockname. (void) snprintf( @@ -702,33 +695,33 @@ nni_sock_shutdown(nni_sock *sock) // We now mark any owned contexts as closing. // XXX: Add context draining support here! - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); nctx = nni_list_first(&sock->s_ctxs); while ((ctx = nctx) != NULL) { nctx = nni_list_next(&sock->s_ctxs, ctx); ctx->c_closed = true; if (ctx->c_refcnt == 0) { // No open operations. So close it. - nni_idhash_remove(nni_ctx_hash, ctx->c_id); + nni_idhash_remove(ctx_hash, ctx->c_id); nni_list_remove(&sock->s_ctxs, ctx); nni_ctx_destroy(ctx); } // If still has a reference count, then wait for last // reference to close before nuking it. } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); // Generally, unless the protocol is blocked trying to perform // writes (e.g. a slow reader on the other side), it should be // trying to shut things down. We wait to give it // a chance to do so gracefully. - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); while (!nni_list_empty(&sock->s_ctxs)) { sock->s_ctxwait = true; nni_cv_wait(&sock->s_close_cv); } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); nni_mtx_lock(&sock->s_mx); @@ -792,16 +785,16 @@ nni_sock_close(nni_sock *s) // is idempotent. nni_sock_shutdown(s); - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); if (s->s_closed) { // Some other thread called close. All we need to do // is drop our reference count. - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); nni_sock_rele(s); return; } s->s_closed = true; - nni_idhash_remove(nni_sock_hash, s->s_id); + nni_idhash_remove(sock_hash, s->s_id); // We might have been removed from the list already, e.g. by // nni_sock_closeall. This is idempotent. @@ -813,7 +806,7 @@ nni_sock_close(nni_sock *s) while ((s->s_refcnt > 1) || (!nni_list_empty(&s->s_ctxs))) { nni_cv_wait(&s->s_close_cv); } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); // Wait for pipes, eps, and contexts to finish closing. nni_mtx_lock(&s->s_mx); @@ -823,7 +816,7 @@ nni_sock_close(nni_sock *s) } nni_mtx_unlock(&s->s_mx); - nni_sock_destroy(s); + sock_destroy(s); } void @@ -831,20 +824,20 @@ nni_sock_closeall(void) { nni_sock *s; - if (nni_sock_hash == NULL) { + if (sock_hash == NULL) { return; } for (;;) { - nni_mtx_lock(&nni_sock_lk); - if ((s = nni_list_first(&nni_sock_list)) == NULL) { - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); + if ((s = nni_list_first(&sock_list)) == NULL) { + nni_mtx_unlock(&sock_lk); return; } // Bump the reference count. The close call below // will drop it. s->s_refcnt++; nni_list_node_remove(&s->s_node); - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); nni_sock_close(s); } } @@ -925,7 +918,7 @@ nni_sock_ep_add(nni_sock *s, nni_ep *ep) NNI_LIST_FOREACH (&s->s_options, sopt) { int rv; rv = nni_ep_setopt( - ep, sopt->name, sopt->data, sopt->sz, NNI_TYPE_OPAQUE); + ep, sopt->name, sopt->data, sopt->sz, sopt->typ); if ((rv != 0) && (rv != NNG_ENOTSUP)) { nni_mtx_unlock(&s->s_mx); return (rv); @@ -951,14 +944,15 @@ nni_sock_ep_remove(nni_sock *sock, nni_ep *ep) } int -nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) +nni_sock_setopt( + nni_sock *s, const char *name, const void *v, size_t sz, nni_opt_type t) { - int rv = NNG_ENOTSUP; - nni_ep * ep; - nni_sockopt * optv; - nni_sockopt * oldv = NULL; - const nni_socket_option * sso; - const nni_proto_sock_option *pso; + int rv = NNG_ENOTSUP; + nni_ep * ep; + nni_sockopt * optv; + nni_sockopt * oldv = NULL; + const sock_option * sso; + const nni_proto_option *pso; nni_mtx_lock(&s->s_mx); if (s->s_closing) { @@ -969,30 +963,30 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) // Protocol options. The protocol can override options that // the socket framework would otherwise supply, like buffer // sizes. - for (pso = s->s_sock_ops.sock_options; pso->pso_name != NULL; pso++) { - if (strcmp(pso->pso_name, name) != 0) { + for (pso = s->s_sock_ops.sock_options; pso->o_name != NULL; pso++) { + if (strcmp(pso->o_name, name) != 0) { continue; } - if (pso->pso_setopt == NULL) { + if (pso->o_set == NULL) { nni_mtx_unlock(&s->s_mx); return (NNG_EREADONLY); } - rv = pso->pso_setopt(s->s_data, v, sz, t); + rv = pso->o_set(s->s_data, v, sz, t); nni_mtx_unlock(&s->s_mx); return (rv); } // 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) { + for (sso = sock_options; sso->o_name != NULL; sso++) { + if (strcmp(sso->o_name, name) != 0) { continue; } - if (sso->so_setopt == NULL) { + if (sso->o_set == NULL) { nni_mtx_unlock(&s->s_mx); return (NNG_EREADONLY); } - rv = sso->so_setopt(s, v, sz, t); + rv = sso->o_set(s, v, sz, t); nni_mtx_unlock(&s->s_mx); return (rv); } @@ -1007,22 +1001,7 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) // 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, v, sz, t); - - // Also check a few generic things. We do this if no - // transport was found, or even if a transport rejected one of - // the settings. - if ((rv == NNG_ENOTSUP) || (rv == 0)) { - if (strcmp(name, NNG_OPT_RECVMAXSZ) == 0) { - size_t z; - // just a sanity test on the size; it also - // ensures that a size can be set even with no - // transport configured. - rv = nni_copyin_size(&z, v, sz, 0, NNI_MAXSZ, t); - } - } - - if (rv != 0) { + if ((rv = nni_tran_chkopt(name, v, sz, t)) != 0) { return (rv); } @@ -1065,16 +1044,6 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) // properly pre-validate. NNI_LIST_FOREACH (&s->s_eps, ep) { int x; - if (optv->typ == NNI_TYPE_OPAQUE) { - int t2; - if (nni_ep_opttype(ep, optv->name, &t2) == - NNG_ENOTSUP) { - continue; - } - // This allows us to determine what the type - // *should* be. - optv->typ = t2; - } x = nni_ep_setopt(ep, optv->name, optv->data, sz, t); if (x != NNG_ENOTSUP) { if ((rv = x) != 0) { @@ -1086,8 +1055,7 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) } if (rv == 0) { - // Remove and toss the old value, we are using a new - // one. + // Remove and toss the old value; we are using a new one. if (oldv != NULL) { nni_list_remove(&s->s_options, oldv); nni_free_opt(oldv); @@ -1106,12 +1074,13 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *v, size_t sz, int t) } int -nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp, int t) +nni_sock_getopt( + nni_sock *s, const char *name, void *val, size_t *szp, nni_opt_type t) { - int rv = NNG_ENOTSUP; - nni_sockopt * sopt; - const nni_socket_option * sso; - const nni_proto_sock_option *pso; + int rv = NNG_ENOTSUP; + nni_sockopt * sopt; + const sock_option * sso; + const nni_proto_option *pso; nni_mtx_lock(&s->s_mx); if (s->s_closing) { @@ -1122,29 +1091,29 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp, int t) // Protocol specific options. The protocol can override // options like the send buffer or notification descriptors // this way. - for (pso = s->s_sock_ops.sock_options; pso->pso_name != NULL; pso++) { - if (strcmp(name, pso->pso_name) != 0) { + for (pso = s->s_sock_ops.sock_options; pso->o_name != NULL; pso++) { + if (strcmp(name, pso->o_name) != 0) { continue; } - if (pso->pso_getopt == NULL) { + if (pso->o_get == NULL) { nni_mtx_unlock(&s->s_mx); return (NNG_EWRITEONLY); } - rv = pso->pso_getopt(s->s_data, val, szp, t); + rv = pso->o_get(s->s_data, val, szp, t); nni_mtx_unlock(&s->s_mx); return (rv); } // Socket generic options. - for (sso = nni_sock_options; sso->so_name != NULL; sso++) { - if (strcmp(name, sso->so_name) != 0) { + for (sso = sock_options; sso->o_name != NULL; sso++) { + if (strcmp(name, sso->o_name) != 0) { continue; } - if (sso->so_getopt == NULL) { + if (sso->o_get == NULL) { nni_mtx_unlock(&s->s_mx); return (NNG_EWRITEONLY); } - rv = sso->so_getopt(s, val, szp, t); + rv = sso->o_get(s, val, szp, t); nni_mtx_unlock(&s->s_mx); return (rv); } @@ -1198,8 +1167,8 @@ nni_ctx_find(nni_ctx **ctxp, uint32_t id, bool closing) if ((rv = nni_init()) != 0) { return (rv); } - nni_mtx_lock(&nni_sock_lk); - if ((rv = nni_idhash_find(nni_ctx_hash, id, (void **) &ctx)) == 0) { + nni_mtx_lock(&sock_lk); + if ((rv = nni_idhash_find(ctx_hash, id, (void **) &ctx)) == 0) { // We refuse a reference if either the socket is // closed, or the context is closed. (If the socket // is closed, and we are only getting the reference so @@ -1213,7 +1182,7 @@ nni_ctx_find(nni_ctx **ctxp, uint32_t id, bool closing) *ctxp = ctx; } } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); if (rv == NNG_ENOENT) { rv = NNG_ECLOSED; @@ -1237,24 +1206,24 @@ void nni_ctx_rele(nni_ctx *ctx) { nni_sock *sock = ctx->c_sock; - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); ctx->c_refcnt--; if ((ctx->c_refcnt > 0) || (!ctx->c_closed)) { // Either still have an active reference, or not // actually closing yet. - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); return; } // Remove us from the hash, so we can't be found any more. // This allows our ID to be reused later, although the system // tries to avoid ID reuse. - nni_idhash_remove(nni_ctx_hash, ctx->c_id); + nni_idhash_remove(ctx_hash, ctx->c_id); nni_list_remove(&sock->s_ctxs, ctx); if (sock->s_closed || sock->s_ctxwait) { nni_cv_wake(&sock->s_close_cv); } - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); nni_ctx_destroy(ctx); } @@ -1273,22 +1242,22 @@ nni_ctx_open(nni_ctx **ctxp, nni_sock *sock) return (NNG_ENOMEM); } - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); if (sock->s_closed) { - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); NNI_FREE_STRUCT(ctx); return (NNG_ECLOSED); } - if ((rv = nni_idhash_alloc(nni_ctx_hash, &id, ctx)) != 0) { - nni_mtx_unlock(&nni_sock_lk); + if ((rv = nni_idhash_alloc(ctx_hash, &id, ctx)) != 0) { + nni_mtx_unlock(&sock_lk); NNI_FREE_STRUCT(ctx); return (rv); } ctx->c_id = (uint32_t) id; if ((rv = sock->s_ctx_ops.ctx_init(&ctx->c_data, sock->s_data)) != 0) { - nni_idhash_remove(nni_ctx_hash, ctx->c_id); - nni_mtx_unlock(&nni_sock_lk); + nni_idhash_remove(ctx_hash, ctx->c_id); + nni_mtx_unlock(&sock_lk); NNI_FREE_STRUCT(ctx); return (rv); } @@ -1301,7 +1270,7 @@ nni_ctx_open(nni_ctx **ctxp, nni_sock *sock) ctx->c_sndtimeo = sock->s_sndtimeo; nni_list_append(&sock->s_ctxs, ctx); - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); // Paranoia, fixing a possible race in close. Don't let us // give back a context if the socket is being shutdown (it @@ -1321,9 +1290,9 @@ nni_ctx_open(nni_ctx **ctxp, nni_sock *sock) void nni_ctx_close(nni_ctx *ctx) { - nni_mtx_lock(&nni_sock_lk); + nni_mtx_lock(&sock_lk); ctx->c_closed = true; - nni_mtx_unlock(&nni_sock_lk); + nni_mtx_unlock(&sock_lk); nni_ctx_rele(ctx); } @@ -1349,27 +1318,28 @@ nni_ctx_recv(nni_ctx *ctx, nni_aio *aio) } int -nni_ctx_getopt(nni_ctx *ctx, const char *opt, void *v, size_t *szp, int typ) +nni_ctx_getopt( + nni_ctx *ctx, const char *opt, void *v, size_t *szp, nni_opt_type t) { - nni_sock * sock = ctx->c_sock; - nni_proto_ctx_option *co; - int rv = NNG_ENOTSUP; + nni_sock * sock = ctx->c_sock; + nni_proto_option *o; + int rv = NNG_ENOTSUP; nni_mtx_lock(&sock->s_mx); if (strcmp(opt, NNG_OPT_RECVTIMEO) == 0) { - rv = nni_copyout_ms(ctx->c_rcvtimeo, v, szp, typ); + rv = nni_copyout_ms(ctx->c_rcvtimeo, v, szp, t); } else if (strcmp(opt, NNG_OPT_SENDTIMEO) == 0) { - rv = nni_copyout_ms(ctx->c_sndtimeo, v, szp, typ); + rv = nni_copyout_ms(ctx->c_sndtimeo, v, szp, t); } else if (ctx->c_ops.ctx_options != NULL) { - for (co = ctx->c_ops.ctx_options; co->co_name != NULL; co++) { - if (strcmp(opt, co->co_name) != 0) { + for (o = ctx->c_ops.ctx_options; o->o_name != NULL; o++) { + if (strcmp(opt, o->o_name) != 0) { continue; } - if (co->co_getopt == NULL) { + if (o->o_get == NULL) { rv = NNG_EWRITEONLY; break; } - rv = co->co_getopt(ctx->c_data, v, szp, typ); + rv = o->o_get(ctx->c_data, v, szp, t); break; } } @@ -1379,27 +1349,27 @@ nni_ctx_getopt(nni_ctx *ctx, const char *opt, void *v, size_t *szp, int typ) int nni_ctx_setopt( - nni_ctx *ctx, const char *opt, const void *v, size_t sz, int typ) + nni_ctx *ctx, const char *opt, const void *v, size_t sz, nni_opt_type t) { - nni_sock * sock = ctx->c_sock; - nni_proto_ctx_option *co; - int rv = NNG_ENOTSUP; + nni_sock * sock = ctx->c_sock; + nni_proto_option *o; + int rv = NNG_ENOTSUP; nni_mtx_lock(&sock->s_mx); if (strcmp(opt, NNG_OPT_RECVTIMEO) == 0) { - rv = nni_copyin_ms(&ctx->c_rcvtimeo, v, sz, typ); + rv = nni_copyin_ms(&ctx->c_rcvtimeo, v, sz, t); } else if (strcmp(opt, NNG_OPT_SENDTIMEO) == 0) { - rv = nni_copyin_ms(&ctx->c_sndtimeo, v, sz, typ); + rv = nni_copyin_ms(&ctx->c_sndtimeo, v, sz, t); } else if (ctx->c_ops.ctx_options != NULL) { - for (co = ctx->c_ops.ctx_options; co->co_name != NULL; co++) { - if (strcmp(opt, co->co_name) != 0) { + for (o = ctx->c_ops.ctx_options; o->o_name != NULL; o++) { + if (strcmp(opt, o->o_name) != 0) { continue; } - if (co->co_setopt == NULL) { + if (o->o_set == NULL) { rv = NNG_EREADONLY; break; } - rv = co->co_setopt(ctx->c_data, v, sz, typ); + rv = o->o_set(ctx->c_data, v, sz, t); break; } } diff --git a/src/core/socket.h b/src/core/socket.h index 833129fa..7c10b195 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -29,12 +29,13 @@ extern void * nni_sock_proto_data(nni_sock *); extern struct nni_proto_pipe_ops *nni_sock_proto_pipe_ops(nni_sock *); extern int nni_sock_setopt( - nni_sock *, const char *, const void *, size_t, int); -extern int nni_sock_getopt(nni_sock *, const char *, void *, size_t *, int); -extern int nni_sock_recvmsg(nni_sock *, nni_msg **, int); -extern int nni_sock_sendmsg(nni_sock *, nni_msg *, int); -extern void nni_sock_send(nni_sock *, nni_aio *); -extern void nni_sock_recv(nni_sock *, nni_aio *); + nni_sock *, const char *, const void *, size_t, nni_opt_type); +extern int nni_sock_getopt( + nni_sock *, const char *, void *, size_t *, nni_opt_type); +extern int nni_sock_recvmsg(nni_sock *, nni_msg **, int); +extern int nni_sock_sendmsg(nni_sock *, nni_msg *, int); +extern void nni_sock_send(nni_sock *, nni_aio *); +extern void nni_sock_recv(nni_sock *, nni_aio *); extern uint32_t nni_sock_id(nni_sock *); // nni_sock_pipe_add adds the pipe to the socket. It is called by @@ -114,9 +115,11 @@ extern void nni_ctx_recv(nni_ctx *, nni_aio *); extern void nni_ctx_send(nni_ctx *, nni_aio *); // nni_ctx_getopt is used to get a context option. -extern int nni_ctx_getopt(nni_ctx *, const char *, void *, size_t *, int); +extern int nni_ctx_getopt( + nni_ctx *, const char *, void *, size_t *, nni_opt_type); // nni_ctx_setopt is used to set a context option. -extern int nni_ctx_setopt(nni_ctx *, const char *, const void *, size_t, int); +extern int nni_ctx_setopt( + nni_ctx *, const char *, const void *, size_t, nni_opt_type); #endif // CORE_SOCKET_H diff --git a/src/core/transport.c b/src/core/transport.c index 0cd84461..4733b6bd 100644 --- a/src/core/transport.c +++ b/src/core/transport.c @@ -118,23 +118,23 @@ nni_tran_chkopt(const char *name, const void *v, size_t sz, int typ) nni_mtx_lock(&nni_tran_lk); NNI_LIST_FOREACH (&nni_tran_list, t) { - const nni_tran_ep_ops * ep; - const nni_tran_ep_option *eo; + const nni_tran_ep_ops *ep; + const nni_tran_option *o; // 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) { + for (o = ep->ep_options; o && o->o_name != NULL; o++) { + if (strcmp(name, o->o_name) != 0) { continue; } - if (eo->eo_setopt == NULL) { + if (o->o_set == NULL) { nni_mtx_unlock(&nni_tran_lk); return (NNG_EREADONLY); } - if ((rv = eo->eo_setopt(NULL, v, sz, typ)) != 0) { - nni_mtx_unlock(&nni_tran_lk); - return (rv); - } + + rv = (o->o_chk != NULL) ? o->o_chk(v, sz, typ) : 0; + nni_mtx_unlock(&nni_tran_lk); + return (rv); } } nni_mtx_unlock(&nni_tran_lk); diff --git a/src/core/transport.h b/src/core/transport.h index 1046901c..e45aa7ec 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -47,39 +47,44 @@ struct nni_tran { // older versions in the future. #define NNI_TRANSPORT_V0 0x54520000 #define NNI_TRANSPORT_V1 0x54520001 -#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V1 +#define NNI_TRANSPORT_V2 0x54520002 +#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V2 -// Endpoint option handlers. -struct nni_tran_ep_option { - // eo_name is the name of the option. - const char *eo_name; +// Option handlers. +struct nni_tran_option { + // o_name is the name of the option. + const char *o_name; - // eo_type is the type of the option. - int eo_type; + // o_type is the type of the option. + nni_opt_type o_type; - // eo_getopt retrieves the value of the option. - int (*eo_getopt)(void *, void *, size_t *, int); + // o_get retrieves the value of the option. The first argument is the + // dialer, listener, or pipe where the request is being made. + int (*o_get)(void *, void *, size_t *, nni_opt_type); - // 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, int); + // o_set sets the value of the option. The first argument is the + // dialer, listener, or pipe where the request is being made. + int (*o_set)(void *, const void *, size_t, nni_opt_type); + + // o_chk checks to see if the proposed value is legal -- this is + // checks only the type, size, and generic range validation. This + // function can be called before any transport objects are created. + int (*o_chk)(const void *, size_t, nni_opt_type); }; -// 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), or run asynchronously if an aio -// is provided. Endpoints are unable to call back into the socket, to prevent -// recusive entry and deadlock. +// 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), 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_ops { // ep_init creates a vanilla endpoint. The value created is - // used for the first argument for all other endpoint functions. + // used for the first argument for all other endpoint + // functions. int (*ep_init)(void **, nni_url *, nni_sock *, int); // ep_fini frees the resources associated with the endpoint. @@ -87,8 +92,8 @@ struct nni_tran_ep_ops { void (*ep_fini)(void *); // ep_connect establishes a connection. It can return errors - // NNG_EACCESS, NNG_ECONNREFUSED, NNG_EBADADDR, NNG_ECONNFAILED, - // NNG_ETIMEDOUT, and NNG_EPROTO. + // NNG_EACCESS, NNG_ECONNREFUSED, NNG_EBADADDR, + // NNG_ECONNFAILED, NNG_ETIMEDOUT, and NNG_EPROTO. void (*ep_connect)(void *, nni_aio *); // ep_bind just does the bind() and listen() work, @@ -101,45 +106,34 @@ struct nni_tran_ep_ops { // ep_accept accepts an inbound connection. void (*ep_accept)(void *, nni_aio *); - // ep_close stops the endpoint from operating altogether. It does - // not affect pipes that have already been created. It is nonblocking. + // ep_close stops the endpoint from operating altogether. It + // does not affect pipes that have already been created. It is + // nonblocking. void (*ep_close)(void *); - // 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; - - // po_type is the type of the option. - int po_type; - - // po_getopt retrieves the value of the option. - int (*po_getopt)(void *, void *, size_t *, int); + // 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_option *ep_options; }; -// Pipe operations are entry points called by the socket. These may be called -// with socket locks held, so it is forbidden for the transport to call -// back into the socket at this point. (Which is one reason pointers back -// to socket or even enclosing pipe state, are not provided.) +// Pipe operations are entry points called by the socket. These may be +// called with socket locks held, so it is forbidden for the transport +// to call back into the socket at this point. (Which is one reason +// pointers back to socket or even enclosing pipe state, are not +// provided.) struct nni_tran_pipe_ops { // p_fini destroys the pipe. This should clean up all local - // resources, including closing files and freeing memory, used by - // the pipe. After this call returns, the system will not make - // further calls on the same pipe. + // resources, including closing files and freeing memory, used + // by the pipe. After this call returns, the system will not + // make further calls on the same pipe. void (*p_fini)(void *); // p_start starts the pipe running. This gives the transport a - // chance to hook into any transport specific negotiation phase. - // The pipe will not have its p_send or p_recv calls started, and - // will not be access by the "socket" until the pipe has indicated - // its readiness by finishing the aio. + // chance to hook into any transport specific negotiation + // phase. The pipe will not have its p_send or p_recv calls + // started, and will not be access by the "socket" until the + // pipe has indicated its readiness by finishing the aio. void (*p_start)(void *, nni_aio *); // p_stop stops the pipe, waiting for any callbacks that are @@ -147,31 +141,31 @@ struct nni_tran_pipe_ops { // resources with p_fini. void (*p_stop)(void *); - // p_aio_send queues the message for transmit. If this fails, then - // the caller may try again with the same message (or free it). If - // the call succeeds, then the transport has taken ownership of the - // message, and the caller may not use it again. The transport will - // have the responsibility to free the message (nng_msg_free()) when - // it is finished with it. + // p_aio_send queues the message for transmit. If this fails, + // then the caller may try again with the same message (or free + // it). If the call succeeds, then the transport has taken + // ownership of the message, and the caller may not use it + // again. The transport will have the responsibility to free + // the message (nng_msg_free()) when it is finished with it. void (*p_send)(void *, nni_aio *); - // p_recv schedules a message receive. This will be performed even for - // cases where no data is expected, to allow detection of a remote - // disconnect. + // p_recv schedules a message receive. This will be performed + // even for cases where no data is expected, to allow detection + // of a remote disconnect. void (*p_recv)(void *, nni_aio *); - // p_close closes the pipe. Further recv or send operations should - // return back NNG_ECLOSED. + // p_close closes the pipe. Further recv or send operations + // should return back NNG_ECLOSED. void (*p_close)(void *); - // p_peer returns the peer protocol. This may arrive in whatever - // transport specific manner is appropriate. + // p_peer returns the peer protocol. This may arrive in + // whatever transport specific manner is appropriate. uint16_t (*p_peer)(void *); - // 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; + // 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_option *p_options; }; // These APIs are used by the framework internally, and not for use by |
