diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/options.c | 34 | ||||
| -rw-r--r-- | src/core/options.h | 180 | ||||
| -rw-r--r-- | src/core/platform.h | 29 | ||||
| -rw-r--r-- | src/core/socket.c | 85 | ||||
| -rw-r--r-- | src/core/stream.c | 428 | ||||
| -rw-r--r-- | src/core/stream.h | 29 | ||||
| -rw-r--r-- | src/core/tcp.h | 5 | ||||
| -rw-r--r-- | src/core/transport.c | 67 | ||||
| -rw-r--r-- | src/core/transport.h | 12 |
9 files changed, 474 insertions, 395 deletions
diff --git a/src/core/options.c b/src/core/options.c index 82735369..5de87c61 100644 --- a/src/core/options.c +++ b/src/core/options.c @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // Copyright 2018 Devolutions <info@devolutions.net> // @@ -55,6 +55,7 @@ nni_copyin_bool(bool *bp, const void *v, size_t sz, nni_type t) if (sz != sizeof(bool)) { return (NNG_EINVAL); } + // NB: C99 does not require that sizeof (bool) == 1. if (bp != NULL) { memcpy(bp, v, sz); } @@ -158,15 +159,18 @@ nni_copyin_str(char *s, const void *v, size_t sz, size_t maxsz, nni_type t) switch (t) { case NNI_TYPE_STRING: + z = v == NULL ? 0 : strlen(v); + break; case NNI_TYPE_OPAQUE: - if ((z = nni_strnlen(v, sz)) >= sz) { + z = v == NULL ? 0 : nni_strnlen(v, sz); + if (z >= sz) { return (NNG_EINVAL); // missing terminator } break; default: return (NNG_EBADTYPE); } - if (z > maxsz) { + if (z >= maxsz) { return (NNG_EINVAL); // too long } if (s != NULL) { @@ -245,7 +249,6 @@ nni_copyout_bool(bool b, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_BOOL: - NNI_ASSERT(*szp == sizeof(b)); *(bool *) dst = b; return (0); case NNI_TYPE_OPAQUE: @@ -260,7 +263,6 @@ nni_copyout_int(int i, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_INT32: - NNI_ASSERT(*szp == sizeof(i)); *(int *) dst = i; return (0); case NNI_TYPE_OPAQUE: @@ -275,7 +277,6 @@ nni_copyout_ms(nng_duration d, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_DURATION: - NNI_ASSERT(*szp == sizeof(d)); *(nng_duration *) dst = d; return (0); case NNI_TYPE_OPAQUE: @@ -290,7 +291,6 @@ nni_copyout_ptr(void *p, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_POINTER: - NNI_ASSERT(*szp == sizeof(p)); *(void **) dst = p; return (0); case NNI_TYPE_OPAQUE: @@ -305,7 +305,6 @@ nni_copyout_size(size_t s, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_SIZE: - NNI_ASSERT(*szp == sizeof(s)); *(size_t *) dst = s; return (0); case NNI_TYPE_OPAQUE: @@ -321,7 +320,6 @@ nni_copyout_sockaddr( { switch (t) { case NNI_TYPE_SOCKADDR: - NNI_ASSERT(*szp == sizeof(*sap)); *(nng_sockaddr *) dst = *sap; return (0); case NNI_TYPE_OPAQUE: @@ -336,7 +334,6 @@ nni_copyout_u64(uint64_t u, void *dst, size_t *szp, nni_type t) { switch (t) { case NNI_TYPE_UINT64: - NNI_ASSERT(*szp == sizeof(u)); *(uint64_t *) dst = u; return (0); case NNI_TYPE_OPAQUE: @@ -353,7 +350,6 @@ nni_copyout_str(const char *str, void *dst, size_t *szp, nni_type t) switch (t) { case NNI_TYPE_STRING: - NNI_ASSERT(*szp == sizeof(char *)); if ((s = nni_strdup(str)) == NULL) { return (NNG_ENOMEM); } @@ -399,19 +395,3 @@ nni_setopt(const nni_option *opts, const char *nm, void *arg, const void *buf, } return (NNG_ENOTSUP); } - -int -nni_chkopt(const nni_chkoption *opts, const char *nm, const void *buf, - size_t sz, nni_type t) -{ - while (opts->o_name != NULL) { - if (strcmp(opts->o_name, nm) == 0) { - if (opts->o_check == NULL) { - return (NNG_EREADONLY); - } - return (opts->o_check(buf, sz, t)); - } - opts++; - } - return (NNG_ENOTSUP); -}
\ No newline at end of file diff --git a/src/core/options.h b/src/core/options.h index 41d10365..9c5d4817 100644 --- a/src/core/options.h +++ b/src/core/options.h @@ -74,191 +74,11 @@ struct nni_option_s { int (*o_set)(void *, const void *, size_t, nni_type); }; -typedef struct nni_chkoption_s nni_chkoption; -struct nni_chkoption_s { - const char *o_name; - // o_check can be NULL for read-only options - int (*o_check)(const void *, size_t, nni_type); -}; - // nni_getopt and nni_setopt are helper functions to implement options // based on arrays of nni_option structures. extern int nni_getopt( const nni_option *, const char *, void *, void *, size_t *, nni_type); extern int nni_setopt( const nni_option *, const char *, void *, const void *, size_t, nni_type); -extern int nni_chkopt( - const nni_chkoption *, const char *, const void *, size_t, nni_type); - -// -// This next block sets up to define the various typed option functions. -// To make it easier to cover them all at once, we use macros. -// - -#define NNI_DEFGET(base, pointer) \ - int nng_##base##_get( \ - nng_##base pointer s, const char *nm, void *vp, size_t *szp) \ - { \ - return (nni_##base##_getx(s, nm, vp, szp, NNI_TYPE_OPAQUE)); \ - } - -#define NNI_DEFTYPEDGET(base, suffix, pointer, type, nnitype) \ - int nng_##base##_get_##suffix( \ - nng_##base pointer s, const char *nm, type *vp) \ - { \ - size_t sz = sizeof(*vp); \ - return (nni_##base##_getx(s, nm, vp, &sz, nnitype)); \ - } - -#define NNI_DEFGETALL(base) \ - NNI_DEFGET(base, ) \ - NNI_DEFTYPEDGET(base, int, , int, NNI_TYPE_INT32) \ - NNI_DEFTYPEDGET(base, bool, , bool, NNI_TYPE_BOOL) \ - NNI_DEFTYPEDGET(base, size, , size_t, NNI_TYPE_SIZE) \ - NNI_DEFTYPEDGET(base, uint64, , uint64_t, NNI_TYPE_UINT64) \ - NNI_DEFTYPEDGET(base, string, , char *, NNI_TYPE_STRING) \ - NNI_DEFTYPEDGET(base, ptr, , void *, NNI_TYPE_POINTER) \ - NNI_DEFTYPEDGET(base, ms, , nng_duration, NNI_TYPE_DURATION) \ - NNI_DEFTYPEDGET(base, addr, , nng_sockaddr, NNI_TYPE_SOCKADDR) - -#define NNI_DEFGETALL_PTR(base) \ - NNI_DEFGET(base, *) \ - NNI_DEFTYPEDGET(base, int, *, int, NNI_TYPE_INT32) \ - NNI_DEFTYPEDGET(base, bool, *, bool, NNI_TYPE_BOOL) \ - NNI_DEFTYPEDGET(base, size, *, size_t, NNI_TYPE_SIZE) \ - NNI_DEFTYPEDGET(base, uint64, *, uint64_t, NNI_TYPE_UINT64) \ - NNI_DEFTYPEDGET(base, string, *, char *, NNI_TYPE_STRING) \ - NNI_DEFTYPEDGET(base, ptr, *, void *, NNI_TYPE_POINTER) \ - NNI_DEFTYPEDGET(base, ms, *, nng_duration, NNI_TYPE_DURATION) \ - NNI_DEFTYPEDGET(base, addr, *, nng_sockaddr, NNI_TYPE_SOCKADDR) - -#define NNI_DEFSET(base, pointer) \ - int nng_##base##_set( \ - nng_##base pointer s, const char *nm, const void *vp, size_t sz) \ - { \ - return (nni_##base##_setx(s, nm, vp, sz, NNI_TYPE_OPAQUE)); \ - } - -#define NNI_DEFTYPEDSETEX(base, suffix, pointer, type, len, nnitype) \ - int nng_##base##_set_##suffix( \ - nng_##base pointer s, const char *nm, type v) \ - { \ - return (nni_##base##_setx(s, nm, &v, len, nnitype)); \ - } - -#define NNI_DEFTYPEDSET(base, suffix, pointer, type, nnitype) \ - int nng_##base##_set_##suffix( \ - nng_##base pointer s, const char *nm, type v) \ - { \ - return (nni_##base##_setx(s, nm, &v, sizeof(v), nnitype)); \ - } - -#define NNI_DEFSTRINGSET(base, pointer) \ - int nng_##base##_set_string( \ - nng_##base pointer s, const char *nm, const char *v) \ - { \ - return (nni_##base##_setx(s, nm, v, \ - v != NULL ? strlen(v) + 1 : 0, NNI_TYPE_STRING)); \ - } - -#define NNI_DEFSOCKADDRSET(base, pointer) \ - int nng_##base##_set_addr( \ - nng_##base pointer s, const char *nm, const nng_sockaddr *v) \ - { \ - return (nni_##base##_setx( \ - s, nm, v, sizeof(*v), NNI_TYPE_SOCKADDR)); \ - } - -#define NNI_DEFSETALL(base) \ - NNI_DEFSET(base, ) \ - NNI_DEFTYPEDSET(base, int, , int, NNI_TYPE_INT32) \ - NNI_DEFTYPEDSET(base, bool, , bool, NNI_TYPE_BOOL) \ - NNI_DEFTYPEDSET(base, size, , size_t, NNI_TYPE_SIZE) \ - NNI_DEFTYPEDSET(base, uint64, , uint64_t, NNI_TYPE_UINT64) \ - NNI_DEFTYPEDSET(base, ms, , nng_duration, NNI_TYPE_DURATION) \ - NNI_DEFTYPEDSET(base, ptr, , void *, NNI_TYPE_POINTER) \ - NNI_DEFSTRINGSET(base, ) \ - NNI_DEFSOCKADDRSET(base, ) - -#define NNI_DEFSETALL_PTR(base) \ - NNI_DEFSET(base, *) \ - NNI_DEFTYPEDSET(base, int, *, int, NNI_TYPE_INT32) \ - NNI_DEFTYPEDSET(base, bool, *, bool, NNI_TYPE_BOOL) \ - NNI_DEFTYPEDSET(base, size, *, size_t, NNI_TYPE_SIZE) \ - NNI_DEFTYPEDSET(base, uint64, *, uint64_t, NNI_TYPE_UINT64) \ - NNI_DEFTYPEDSET(base, ms, *, nng_duration, NNI_TYPE_DURATION) \ - NNI_DEFTYPEDSET(base, ptr, *, void *, NNI_TYPE_POINTER) \ - NNI_DEFSTRINGSET(base, *) \ - NNI_DEFSOCKADDRSET(base, *) - -#define NNI_LEGACY_DEFGET(base) \ - int nng_##base##_getopt( \ - nng_##base s, const char *nm, void *vp, size_t *szp) \ - { \ - return (nng_##base##_get(s, nm, vp, szp)); \ - } - -#define NNI_LEGACY_DEFTYPEDGET(base, suffix, type) \ - int nng_##base##_getopt_##suffix( \ - nng_##base s, const char *nm, type *vp) \ - { \ - return (nng_##base##_get_##suffix(s, nm, vp)); \ - } - -#define NNI_LEGACY_DEFSOCKADDRGET(base) \ - int nng_##base##_getopt_sockaddr( \ - nng_##base s, const char *nm, nng_sockaddr *vp) \ - { \ - return (nng_##base##_get_addr(s, nm, vp)); \ - } - -#define NNI_LEGACY_DEFGETALL(base) \ - NNI_LEGACY_DEFGET(base) \ - NNI_LEGACY_DEFTYPEDGET(base, int, int) \ - NNI_LEGACY_DEFTYPEDGET(base, bool, bool) \ - NNI_LEGACY_DEFTYPEDGET(base, size, size_t) \ - NNI_LEGACY_DEFTYPEDGET(base, uint64, uint64_t) \ - NNI_LEGACY_DEFTYPEDGET(base, string, char *) \ - NNI_LEGACY_DEFTYPEDGET(base, ptr, void *) \ - NNI_LEGACY_DEFTYPEDGET(base, ms, nng_duration) \ - NNI_LEGACY_DEFSOCKADDRGET(base) - -#define NNI_LEGACY_DEFSET(base) \ - int nng_##base##_setopt( \ - nng_##base s, const char *nm, const void *vp, size_t sz) \ - { \ - return (nng_##base##_set(s, nm, vp, sz)); \ - } - -#define NNI_LEGACY_DEFTYPEDSET(base, suffix, type) \ - int nng_##base##_setopt_##suffix(nng_##base s, const char *nm, type v) \ - { \ - return (nng_##base##_set_##suffix(s, nm, v)); \ - } - -#define NNI_LEGACY_DEFSTRINGSET(base) \ - int nng_##base##_setopt_string( \ - nng_##base s, const char *nm, const char *v) \ - { \ - return (nng_##base##_set_string(s, nm, v)); \ - } - -#define NNI_LEGACY_DEFSOCKADDRSET(base) \ - int nng_##base##_setopt_sockaddr( \ - nng_##base s, const char *nm, const nng_sockaddr *v) \ - { \ - return (nng_##base##_set_addr(s, nm, v)); \ - } - -#define NNI_LEGACY_DEFSETALL(base) \ - NNI_LEGACY_DEFSET(base) \ - NNI_LEGACY_DEFTYPEDSET(base, int, int) \ - NNI_LEGACY_DEFTYPEDSET(base, bool, bool) \ - NNI_LEGACY_DEFTYPEDSET(base, size, size_t) \ - NNI_LEGACY_DEFTYPEDSET(base, uint64, uint64_t) \ - NNI_LEGACY_DEFTYPEDSET(base, ms, nng_duration) \ - NNI_LEGACY_DEFTYPEDSET(base, ptr, void*) \ - NNI_LEGACY_DEFSTRINGSET(base) \ - NNI_LEGACY_DEFSOCKADDRSET(base) #endif // CORE_OPTIONS_H diff --git a/src/core/platform.h b/src/core/platform.h index 704e338d..35d42339 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -280,8 +280,8 @@ extern int nni_tcp_dialer_init(nni_tcp_dialer **); extern void nni_tcp_dialer_fini(nni_tcp_dialer *); // nni_tcp_dialer_close closes the dialer. -// Further operations on it should return NNG_ECLOSED. Any in-progress -// connection will be aborted. +// Further operations on it should return NNG_ECLOSED. +// Any in-progress connection will be aborted. extern void nni_tcp_dialer_close(nni_tcp_dialer *); // nni_tcp_dial attempts to create an outgoing connection, @@ -289,16 +289,12 @@ extern void nni_tcp_dialer_close(nni_tcp_dialer *); // output will be an nni_tcp_conn * associated with the remote server. extern void nni_tcp_dial(nni_tcp_dialer *, const nng_sockaddr *, nni_aio *); -// nni_tcp_dialer_getopt gets an option from the dialer. -extern int nni_tcp_dialer_setopt( +// nni_tcp_dialer_set sets an option on the dialer. +extern int nni_tcp_dialer_set( nni_tcp_dialer *, const char *, const void *, size_t, nni_type); -// nni_tcp_dialer_setopt sets an option on the dialer. There is special -// support for NNG_OPT_LOCADDR, which will be the source address (if legal) -// for new connections, except that the port will be ignored. The -// NNG_OPT_TCP_NODELAY and NNG_OPT_TCP_KEEPALIVE options work to set the -// initial values of those options on newly created connections. -extern int nni_tcp_dialer_getopt( +// nni_tcp_dialer_get gets an option on the dialer. +extern int nni_tcp_dialer_get( nni_tcp_dialer *, const char *, void *, size_t *, nni_type); // nni_tcp_listener_init creates a new listener object, unbound. @@ -321,14 +317,14 @@ extern int nni_tcp_listener_listen(nni_tcp_listener *, const nni_sockaddr *); // associated with the remote peer. extern void nni_tcp_listener_accept(nni_tcp_listener *, nni_aio *); -// nni_tcp_listener_getopt gets an option from the listener. -extern int nni_tcp_listener_setopt( +// nni_tcp_listener_set sets an option on the listener. +extern int nni_tcp_listener_set( nni_tcp_listener *, const char *, const void *, size_t, nni_type); -// nni_tcp_listener_setopt sets an option on the listener. The most common +// nni_tcp_listener_get gets an option from the listener. The most common // use for this is to retrieve the setting of the NNG_OPT_TCP_LOCADDR // address after binding to wild card port (0). -extern int nni_tcp_listener_getopt( +extern int nni_tcp_listener_get( nni_tcp_listener *, const char *, void *, size_t *, nni_type); // nni_resolv_ip resolves a DNS host and service name asynchronously. @@ -339,8 +335,8 @@ extern int nni_tcp_listener_getopt( // connect(). The host part may be NULL only if passive is true. // Symbolic service names will be looked up assuming SOCK_STREAM, so // they may not work with UDP. -extern void nni_resolv_ip(const char *, const char *, int, bool, - nng_sockaddr *sa, nni_aio *); +extern void nni_resolv_ip( + const char *, const char *, int, bool, nng_sockaddr *sa, nni_aio *); // nni_parse_ip parses an IP address, without a port. extern int nni_parse_ip(const char *, nng_sockaddr *); @@ -361,7 +357,6 @@ typedef struct nni_ipc_listener nni_ipc_listener; // be stubs that just return NNG_ENOTSUP. extern int nni_ipc_dialer_alloc(nng_stream_dialer **, const nng_url *); extern int nni_ipc_listener_alloc(nng_stream_listener **, const nng_url *); -extern int nni_ipc_checkopt(const char *, const void *, size_t, nni_type); // // UDP support. UDP is not connection oriented, and only has the notion diff --git a/src/core/socket.c b/src/core/socket.c index 72c55c7a..f741b6f0 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -983,11 +983,9 @@ int nni_sock_setopt( nni_sock *s, const char *name, const void *v, size_t sz, nni_type t) { - int rv; - nni_dialer * d; - nni_listener *l; - nni_sockopt * optv; - nni_sockopt * oldv = NULL; + int rv; + nni_sockopt *optv; + nni_sockopt *oldv = NULL; nni_mtx_lock(&s->s_mx); if (s->s_closing) { @@ -1012,17 +1010,67 @@ nni_sock_setopt( } nni_mtx_unlock(&s->s_mx); - // Validation of generic and transport options. This is stateless, so - // transports should not fail to set an option later if they - // passed it here. + // Validation of generic and transport options. + // NOTE: Setting transport options via socket is deprecated. + // These options should be set on the endpoint to which they apply. if ((strcmp(name, NNG_OPT_RECONNMINT) == 0) || (strcmp(name, NNG_OPT_RECONNMAXT) == 0)) { - nng_duration ms; - if ((rv = nni_copyin_ms(&ms, v, sz, t)) != 0) { + if ((rv = nni_copyin_ms(NULL, v, sz, t)) != 0) { return (rv); } - } else if ((rv = nni_tran_chkopt(name, v, sz, t)) != 0) { - return (rv); + + } else if (strcmp(name, NNG_OPT_RECVMAXSZ) == 0) { + if ((rv = nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t)) != + 0) { + return (rv); + } + +#if !defined(NNG_ELIDE_DEPRECATED) + // TCP options, set via socket is deprecated. + } else if ((strcmp(name, NNG_OPT_TCP_KEEPALIVE) == 0) || + (strcmp(name, NNG_OPT_TCP_NODELAY)) == 0) { + if ((rv = nni_copyin_bool(NULL, v, sz, t)) != 0) { + return (rv); + } +#endif + +#if defined(NNG_SUPP_TLS) && !defined(NNG_ELIDE_DEPRECATED) + // TLS options may not be supported if TLS is not + // compiled in. Supporting all these is deprecated. + } else if (strcmp(name, NNG_OPT_TLS_CONFIG) == 0) { + if ((rv = nni_copyin_ptr(NULL, v, sz, t)) != 0) { + return (rv); + } + } else if ((strcmp(name, NNG_OPT_TLS_SERVER_NAME) == 0) || + (strcmp(name, NNG_OPT_TLS_CA_FILE) == 0) || + (strcmp(name, NNG_OPT_TLS_CERT_KEY_FILE) == 0)) { + if ((t != NNI_TYPE_OPAQUE) && (t != NNI_TYPE_STRING)) { + return (NNG_EBADTYPE); + } + if (nni_strnlen(v, sz) >= sz) { + return (NNG_EINVAL); + } + } else if ((strcmp(name, NNG_OPT_TLS_AUTH_MODE) == 0)) { + // 0, 1, or 2 (none, optional, required) + if ((rv = nni_copyin_int(NULL, v, sz, 0, 2, t)) != 0) { + return (rv); + } +#endif + +#if defined(NNG_PLATFORM_POSIX) && !defined(NNG_SUPPRESS_DEPRECATED) + } else if (strcmp(name, NNG_OPT_IPC_PERMISSIONS) == 0) { + // UNIX mode bits are 0777, but allow set id and sticky bits + if ((rv = nni_copyin_int(NULL, v, sz, 0, 07777, t)) != 0) { + return (rv); + } +#endif + +#if defined(NNG_PLATFORM_WINDOWS) && !defined(NNG_SUPPRESS_DEPRECATED) + } else if (strcmp(name, NNG_OPT_IPC_SECURITY_DESCRIPTOR) == 0) { + if ((rv = nni_copyin_ptr(NULL, v, sz, t)) == 0) { + return (rv); + } +#endif } // Prepare a copy of the socket option. @@ -1058,6 +1106,10 @@ nni_sock_setopt( } } +#ifndef NNG_ELIDE_DEPRCATED + nni_dialer * d; + nni_listener *l; + // Apply the options. Failure to set any option on any // transport (other than ENOTSUP) stops the operation // altogether. Its important that transport wide checks @@ -1084,6 +1136,7 @@ nni_sock_setopt( } } } +#endif if (rv == 0) { // Remove and toss the old value; we are using a new one. @@ -1151,10 +1204,12 @@ nni_sock_getopt( } } - if (sopt->sz > *szp) { - sz = *szp; + if (szp != NULL) { + if (sopt->sz > *szp) { + sz = *szp; + } + *szp = sopt->sz; } - *szp = sopt->sz; memcpy(val, sopt->data, sz); rv = 0; break; diff --git a/src/core/stream.c b/src/core/stream.c index 9309a3a0..418bfb15 100644 --- a/src/core/stream.c +++ b/src/core/stream.c @@ -23,90 +23,76 @@ static struct { const char *scheme; int (*dialer_alloc)(nng_stream_dialer **, const nng_url *); int (*listener_alloc)(nng_stream_listener **, const nng_url *); - int (*checkopt)(const char *, const void *, size_t, nni_type); } stream_drivers[] = { { .scheme = "ipc", .dialer_alloc = nni_ipc_dialer_alloc, .listener_alloc = nni_ipc_listener_alloc, - .checkopt = nni_ipc_checkopt, }, #ifdef NNG_PLATFORM_POSIX { .scheme = "unix", .dialer_alloc = nni_ipc_dialer_alloc, .listener_alloc = nni_ipc_listener_alloc, - .checkopt = nni_ipc_checkopt, }, #endif #ifdef NNG_HAVE_ABSTRACT_SOCKETS { - .scheme = "abstract", - .dialer_alloc = nni_ipc_dialer_alloc, - .listener_alloc = nni_ipc_listener_alloc, - .checkopt = nni_ipc_checkopt, - }, + .scheme = "abstract", + .dialer_alloc = nni_ipc_dialer_alloc, + .listener_alloc = nni_ipc_listener_alloc, + }, #endif - { + { .scheme = "tcp", .dialer_alloc = nni_tcp_dialer_alloc, .listener_alloc = nni_tcp_listener_alloc, - .checkopt = nni_tcp_checkopt, }, { .scheme = "tcp4", .dialer_alloc = nni_tcp_dialer_alloc, .listener_alloc = nni_tcp_listener_alloc, - .checkopt = nni_tcp_checkopt, }, { .scheme = "tcp6", .dialer_alloc = nni_tcp_dialer_alloc, .listener_alloc = nni_tcp_listener_alloc, - .checkopt = nni_tcp_checkopt, }, { .scheme = "tls+tcp", .dialer_alloc = nni_tls_dialer_alloc, .listener_alloc = nni_tls_listener_alloc, - .checkopt = nni_tls_checkopt, }, { .scheme = "tls+tcp4", .dialer_alloc = nni_tls_dialer_alloc, .listener_alloc = nni_tls_listener_alloc, - .checkopt = nni_tls_checkopt, }, { .scheme = "tls+tcp6", .dialer_alloc = nni_tls_dialer_alloc, .listener_alloc = nni_tls_listener_alloc, - .checkopt = nni_tls_checkopt, }, { .scheme = "ws", .dialer_alloc = nni_ws_dialer_alloc, .listener_alloc = nni_ws_listener_alloc, - .checkopt = nni_ws_checkopt, }, - { - .scheme = "ws4", - .dialer_alloc = nni_ws_dialer_alloc, - .listener_alloc = nni_ws_listener_alloc, - .checkopt = nni_ws_checkopt, - }, - { - .scheme = "ws6", - .dialer_alloc = nni_ws_dialer_alloc, - .listener_alloc = nni_ws_listener_alloc, - .checkopt = nni_ws_checkopt, - }, - { + { + .scheme = "ws4", + .dialer_alloc = nni_ws_dialer_alloc, + .listener_alloc = nni_ws_listener_alloc, + }, + { + .scheme = "ws6", + .dialer_alloc = nni_ws_dialer_alloc, + .listener_alloc = nni_ws_listener_alloc, + }, + { .scheme = "wss", .dialer_alloc = nni_ws_dialer_alloc, .listener_alloc = nni_ws_listener_alloc, - .checkopt = nni_ws_checkopt, }, { .scheme = NULL, @@ -140,17 +126,17 @@ nng_stream_recv(nng_stream *s, nng_aio *aio) } int -nni_stream_getx( +nni_stream_get( nng_stream *s, const char *nm, void *data, size_t *szp, nni_type t) { - return (s->s_getx(s, nm, data, szp, t)); + return (s->s_get(s, nm, data, szp, t)); } int -nni_stream_setx( +nni_stream_set( nng_stream *s, const char *nm, const void *data, size_t sz, nni_type t) { - return (s->s_setx(s, nm, data, sz, t)); + return (s->s_set(s, nm, data, sz, t)); } void @@ -208,17 +194,17 @@ nng_stream_dialer_alloc(nng_stream_dialer **dp, const char *uri) } int -nni_stream_dialer_getx( +nni_stream_dialer_get( nng_stream_dialer *d, const char *nm, void *data, size_t *szp, nni_type t) { - return (d->sd_getx(d, nm, data, szp, t)); + return (d->sd_get(d, nm, data, szp, t)); } int -nni_stream_dialer_setx(nng_stream_dialer *d, const char *nm, const void *data, +nni_stream_dialer_set(nng_stream_dialer *d, const char *nm, const void *data, size_t sz, nni_type t) { - return (d->sd_setx(d, nm, data, sz, t)); + return (d->sd_set(d, nm, data, sz, t)); } void @@ -246,17 +232,17 @@ nng_stream_listener_accept(nng_stream_listener *l, nng_aio *aio) } int -nni_stream_listener_getx(nng_stream_listener *l, const char *nm, void *data, +nni_stream_listener_get(nng_stream_listener *l, const char *nm, void *data, size_t *szp, nni_type t) { - return (l->sl_getx(l, nm, data, szp, t)); + return (l->sl_get(l, nm, data, szp, t)); } int -nni_stream_listener_setx(nng_stream_listener *l, const char *nm, +nni_stream_listener_set(nng_stream_listener *l, const char *nm, const void *data, size_t sz, nni_type t) { - return (l->sl_setx(l, nm, data, sz, t)); + return (l->sl_set(l, nm, data, sz, t)); } int @@ -294,26 +280,348 @@ nng_stream_listener_alloc(nng_stream_listener **lp, const char *uri) return (rv); } +// Public stream options. + int -nni_stream_checkopt(const char *scheme, const char *name, const void *data, - size_t sz, nni_type t) +nng_stream_get(nng_stream *s, const char *n, void *v, size_t *szp) { - for (int i = 0; stream_drivers[i].scheme != NULL; i++) { - if (strcmp(stream_drivers[i].scheme, scheme) != 0) { - continue; - } - if (stream_drivers[i].checkopt == NULL) { - return (NNG_ENOTSUP); - } - return (stream_drivers[i].checkopt(name, data, sz, t)); - } - return (NNG_ENOTSUP); + return (nni_stream_get(s, n, v, szp, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_get_int(nng_stream *s, const char *n, int *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_INT32)); +} + +int +nng_stream_get_bool(nng_stream *s, const char *n, bool *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_BOOL)); +} + +int +nng_stream_get_size(nng_stream *s, const char *n, size_t *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_SIZE)); +} + +int +nng_stream_get_uint64(nng_stream *s, const char *n, uint64_t *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_UINT64)); +} + +int +nng_stream_get_string(nng_stream *s, const char *n, char **v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_STRING)); +} + +int +nng_stream_get_ptr(nng_stream *s, const char *n, void **v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_POINTER)); +} + +int +nng_stream_get_ms(nng_stream *s, const char *n, nng_duration *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_DURATION)); +} + +int +nng_stream_get_addr(nng_stream *s, const char *n, nng_sockaddr *v) +{ + return (nni_stream_get(s, n, v, NULL, NNI_TYPE_SOCKADDR)); +} + +int +nng_stream_dialer_get( + nng_stream_dialer *d, const char *n, void *v, size_t *szp) +{ + return (nni_stream_dialer_get(d, n, v, szp, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_dialer_get_int(nng_stream_dialer *d, const char *n, int *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_INT32)); +} + +int +nng_stream_dialer_get_bool(nng_stream_dialer *d, const char *n, bool *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_BOOL)); +} + +int +nng_stream_dialer_get_size(nng_stream_dialer *d, const char *n, size_t *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_SIZE)); +} + +int +nng_stream_dialer_get_uint64(nng_stream_dialer *d, const char *n, uint64_t *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_UINT64)); +} + +int +nng_stream_dialer_get_string(nng_stream_dialer *d, const char *n, char **v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_STRING)); +} + +int +nng_stream_dialer_get_ptr(nng_stream_dialer *d, const char *n, void **v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_POINTER)); +} + +int +nng_stream_dialer_get_ms(nng_stream_dialer *d, const char *n, nng_duration *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_DURATION)); +} + +int +nng_stream_dialer_get_addr( + nng_stream_dialer *d, const char *n, nng_sockaddr *v) +{ + return (nni_stream_dialer_get(d, n, v, NULL, NNI_TYPE_SOCKADDR)); +} + +int +nng_stream_listener_get( + nng_stream_listener *l, const char *n, void *v, size_t *szp) +{ + return (nni_stream_listener_get(l, n, v, szp, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_listener_get_int(nng_stream_listener *l, const char *n, int *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_INT32)); +} + +int +nng_stream_listener_get_bool(nng_stream_listener *l, const char *n, bool *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_BOOL)); +} + +int +nng_stream_listener_get_size(nng_stream_listener *l, const char *n, size_t *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_SIZE)); +} + +int +nng_stream_listener_get_uint64( + nng_stream_listener *l, const char *n, uint64_t *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_UINT64)); +} + +int +nng_stream_listener_get_string(nng_stream_listener *l, const char *n, char **v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_STRING)); +} + +int +nng_stream_listener_get_ptr(nng_stream_listener *l, const char *n, void **v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_POINTER)); +} + +int +nng_stream_listener_get_ms( + nng_stream_listener *l, const char *n, nng_duration *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_DURATION)); +} + +int +nng_stream_listener_get_addr( + nng_stream_listener *l, const char *n, nng_sockaddr *v) +{ + return (nni_stream_listener_get(l, n, v, NULL, NNI_TYPE_SOCKADDR)); +} + +int +nng_stream_set(nng_stream *s, const char *n, const void *v, size_t sz) +{ + return (nni_stream_set(s, n, v, sz, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_set_int(nng_stream *s, const char *n, int v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_INT32)); +} + +int +nng_stream_set_bool(nng_stream *s, const char *n, bool v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_BOOL)); +} + +int +nng_stream_set_size(nng_stream *s, const char *n, size_t v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_SIZE)); +} + +int +nng_stream_set_uint64(nng_stream *s, const char *n, uint64_t v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_UINT64)); } -NNI_DEFGETALL_PTR(stream) -NNI_DEFGETALL_PTR(stream_dialer) -NNI_DEFGETALL_PTR(stream_listener) +int +nng_stream_set_ms(nng_stream *s, const char *n, nng_duration v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_DURATION)); +} + +int +nng_stream_set_ptr(nng_stream *s, const char *n, void *v) +{ + return (nni_stream_set(s, n, &v, sizeof(v), NNI_TYPE_POINTER)); +} + +int +nng_stream_set_string(nng_stream *s, const char *n, const char *v) +{ + return (nni_stream_set( + s, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING)); +} + +int +nng_stream_set_addr(nng_stream *s, const char *n, const nng_sockaddr *v) +{ + return (nni_stream_set(s, n, v, sizeof(*v), NNI_TYPE_SOCKADDR)); +} -NNI_DEFSETALL_PTR(stream) -NNI_DEFSETALL_PTR(stream_dialer) -NNI_DEFSETALL_PTR(stream_listener)
\ No newline at end of file +int +nng_stream_dialer_set( + nng_stream_dialer *d, const char *n, const void *v, size_t sz) +{ + return (nni_stream_dialer_set(d, n, v, sz, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_dialer_set_int(nng_stream_dialer *d, const char *n, int v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_INT32)); +} + +int +nng_stream_dialer_set_bool(nng_stream_dialer *d, const char *n, bool v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_BOOL)); +} + +int +nng_stream_dialer_set_size(nng_stream_dialer *d, const char *n, size_t v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_SIZE)); +} + +int +nng_stream_dialer_set_uint64(nng_stream_dialer *d, const char *n, uint64_t v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_UINT64)); +} + +int +nng_stream_dialer_set_ms(nng_stream_dialer *d, const char *n, nng_duration v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_DURATION)); +} + +int +nng_stream_dialer_set_ptr(nng_stream_dialer *d, const char *n, void *v) +{ + return (nni_stream_dialer_set(d, n, &v, sizeof(v), NNI_TYPE_POINTER)); +} + +int +nng_stream_dialer_set_string( + nng_stream_dialer *d, const char *n, const char *v) +{ + return (nni_stream_dialer_set( + d, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING)); +} + +int +nng_stream_dialer_set_addr( + nng_stream_dialer *d, const char *n, const nng_sockaddr *v) +{ + return (nni_stream_dialer_set(d, n, v, sizeof(*v), NNI_TYPE_SOCKADDR)); +} + +int +nng_stream_listener_set( + nng_stream_listener *l, const char *n, const void *v, size_t sz) +{ + return (nni_stream_listener_set(l, n, v, sz, NNI_TYPE_OPAQUE)); +} + +int +nng_stream_listener_set_int(nng_stream_listener *l, const char *n, int v) +{ + return (nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_INT32)); +} + +int +nng_stream_listener_set_bool(nng_stream_listener *l, const char *n, bool v) +{ + return (nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_BOOL)); +} + +int +nng_stream_listener_set_size(nng_stream_listener *l, const char *n, size_t v) +{ + return (nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_SIZE)); +} + +int +nng_stream_listener_set_uint64( + nng_stream_listener *l, const char *n, uint64_t v) +{ + return (nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_UINT64)); +} + +int +nng_stream_listener_set_ms( + nng_stream_listener *l, const char *n, nng_duration v) +{ + return ( + nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_DURATION)); +} + +int +nng_stream_listener_set_ptr(nng_stream_listener *l, const char *n, void *v) +{ + return ( + nni_stream_listener_set(l, n, &v, sizeof(v), NNI_TYPE_POINTER)); +} + +int +nng_stream_listener_set_string( + nng_stream_listener *l, const char *n, const char *v) +{ + return (nni_stream_listener_set( + l, n, v, v == NULL ? 0 : strlen(v) + 1, NNI_TYPE_STRING)); +} + +int +nng_stream_listener_set_addr( + nng_stream_listener *l, const char *n, const nng_sockaddr *v) +{ + return ( + nni_stream_listener_set(l, n, v, sizeof(*v), NNI_TYPE_SOCKADDR)); +} diff --git a/src/core/stream.h b/src/core/stream.h index 18914979..eb3cb93b 100644 --- a/src/core/stream.h +++ b/src/core/stream.h @@ -1,5 +1,5 @@ // -// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -16,24 +16,21 @@ #include "core/nng_impl.h" // Private property operations (these include the types.) -extern int nni_stream_getx( +extern int nni_stream_get( nng_stream *, const char *, void *, size_t *, nni_type); -extern int nni_stream_setx( +extern int nni_stream_set( nng_stream *, const char *, const void *, size_t, nni_type); -extern int nni_stream_dialer_getx( +extern int nni_stream_dialer_get( nng_stream_dialer *, const char *, void *, size_t *, nni_type); -extern int nni_stream_dialer_setx( +extern int nni_stream_dialer_set( nng_stream_dialer *, const char *, const void *, size_t, nni_type); -extern int nni_stream_listener_getx( +extern int nni_stream_listener_get( nng_stream_listener *, const char *, void *, size_t *, nni_type); -extern int nni_stream_listener_setx( +extern int nni_stream_listener_set( nng_stream_listener *, const char *, const void *, size_t, nni_type); -extern int nni_stream_checkopt( - const char *, const char *, const void *, size_t, nni_type); - // This is the common implementation of a connected byte stream. It should be // the first element of any implementation. Applications are not permitted to // access it directly. @@ -42,8 +39,8 @@ struct nng_stream { void (*s_close)(void *); void (*s_recv)(void *, nng_aio *); void (*s_send)(void *, nng_aio *); - int (*s_getx)(void *, const char *, void *, size_t *, nni_type); - int (*s_setx)(void *, const char *, const void *, size_t, nni_type); + int (*s_get)(void *, const char *, void *, size_t *, nni_type); + int (*s_set)(void *, const char *, const void *, size_t, nni_type); }; // Dialer implementation. Stream dialers create streams. @@ -51,8 +48,8 @@ struct nng_stream_dialer { void (*sd_free)(void *); void (*sd_close)(void *); void (*sd_dial)(void *, nng_aio *); - int (*sd_getx)(void *, const char *, void *, size_t *, nni_type); - int (*sd_setx)(void *, const char *, const void *, size_t, nni_type); + int (*sd_get)(void *, const char *, void *, size_t *, nni_type); + int (*sd_set)(void *, const char *, const void *, size_t, nni_type); }; // Listener implementation. Stream listeners accept connections and create @@ -62,8 +59,8 @@ struct nng_stream_listener { void (*sl_close)(void *); int (*sl_listen)(void *); void (*sl_accept)(void *, nng_aio *); - int (*sl_getx)(void *, const char *, void *, size_t *, nni_type); - int (*sl_setx)(void *, const char *, const void *, size_t, nni_type); + int (*sl_get)(void *, const char *, void *, size_t *, nni_type); + int (*sl_set)(void *, const char *, const void *, size_t, nni_type); }; #endif // CORE_STREAM_H diff --git a/src/core/tcp.h b/src/core/tcp.h index ac4398d0..6e1829dc 100644 --- a/src/core/tcp.h +++ b/src/core/tcp.h @@ -1,5 +1,5 @@ // -// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -18,7 +18,4 @@ extern int nni_tcp_dialer_alloc(nng_stream_dialer **, const nng_url *); extern int nni_tcp_listener_alloc(nng_stream_listener **, const nng_url *); -// nni_tcp_checkopt is used to validate (generically) options. -extern int nni_tcp_checkopt(const char *, const void *, size_t, nni_type); - #endif // CORE_TCP_H diff --git a/src/core/transport.c b/src/core/transport.c index 071ea0c7..78859078 100644 --- a/src/core/transport.c +++ b/src/core/transport.c @@ -111,73 +111,6 @@ nni_tran_find(nni_url *url) return (NULL); } -int -nni_tran_chkopt(const char *name, const void *v, size_t sz, int typ) -{ - nni_transport *t; - int rv = NNG_ENOTSUP; - - nni_mtx_lock(&nni_tran_lk); - NNI_LIST_FOREACH (&nni_tran_list, t) { - const nni_tran_dialer_ops * dops; - const nni_tran_listener_ops *lops; - const nni_option * o; - - // Check option entry point is cleaner than endpoint hacks. - if (t->t_tran.tran_checkopt != NULL) { - rv = t->t_tran.tran_checkopt(name, v, sz, typ); - if (rv != NNG_ENOTSUP) { - nni_mtx_unlock(&nni_tran_lk); - return (rv); - } - continue; - } - - // Generally we look for endpoint options. We check both - // dialers and listeners. - dops = t->t_tran.tran_dialer; - if ((dops->d_setopt != NULL) && - ((rv = dops->d_setopt(NULL, name, v, sz, typ)) != - NNG_ENOTSUP)) { - nni_mtx_unlock(&nni_tran_lk); - return (rv); - } - for (o = dops->d_options; o && o->o_name != NULL; o++) { - if (strcmp(name, o->o_name) != 0) { - continue; - } - if (o->o_set == NULL) { - nni_mtx_unlock(&nni_tran_lk); - return (NNG_EREADONLY); - } - nni_mtx_unlock(&nni_tran_lk); - rv = o->o_set(NULL, v, sz, typ); - return (rv); - } - lops = t->t_tran.tran_listener; - if ((lops->l_setopt != NULL) && - ((rv = lops->l_setopt(NULL, name, v, sz, typ)) != - NNG_ENOTSUP)) { - nni_mtx_unlock(&nni_tran_lk); - return (rv); - } - for (o = lops->l_options; o && o->o_name != NULL; o++) { - if (strcmp(name, o->o_name) != 0) { - continue; - } - if (o->o_set == NULL) { - nni_mtx_unlock(&nni_tran_lk); - return (NNG_EREADONLY); - } - nni_mtx_unlock(&nni_tran_lk); - rv = o->o_set(NULL, v, sz, typ); - return (rv); - } - } - nni_mtx_unlock(&nni_tran_lk); - return (rv); -} - // nni_tran_sys_init initializes the entire transport subsystem, including // each individual transport. diff --git a/src/core/transport.h b/src/core/transport.h index 84d9c1d9..b2da2c7a 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // Copyright 2018 Devolutions <info@devolutions.net> // @@ -29,7 +29,8 @@ #define NNI_TRANSPORT_V4 0x54520004 #define NNI_TRANSPORT_V5 0x54520005 #define NNI_TRANSPORT_V6 0x54220006 -#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V6 +#define NNI_TRANSPORT_V7 0x54220006 +#define NNI_TRANSPORT_VERSION NNI_TRANSPORT_V7 // Endpoint operations are called by the socket in a // protocol-independent fashion. The socket makes individual calls, @@ -183,18 +184,11 @@ struct nni_tran { // tran_fini, if not NULL, is called during library deinitialization. // It should release any global resources, close any open files, etc. void (*tran_fini)(void); - - // tran_chkopt is used to check option validity; this is used as - // an initial filter on the data, without actually setting anything. - // This can be useful, for example, before any transports are - // configured on the socket. - int (*tran_checkopt)(const char *, const void *, size_t, nni_type); }; // These APIs are used by the framework internally, and not for use by // transport implementations. extern nni_tran *nni_tran_find(nni_url *); -extern int nni_tran_chkopt(const char *, const void *, size_t, int); extern int nni_tran_sys_init(void); extern void nni_tran_sys_fini(void); extern int nni_tran_register(const nni_tran *); |
