aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2019-01-05 16:09:10 -0800
committerGarrett D'Amore <garrett@damore.org>2019-01-06 12:12:27 -0800
commit68c6310ee83078d6ad6af0c9ccddef11b8f8b7c2 (patch)
treed03175dddb1142a5ac9fedf4a8643f27648db53e /src
parentf76f536742c7d0766244ff4b8d388586100384d5 (diff)
downloadnng-68c6310ee83078d6ad6af0c9ccddef11b8f8b7c2.tar.gz
nng-68c6310ee83078d6ad6af0c9ccddef11b8f8b7c2.tar.bz2
nng-68c6310ee83078d6ad6af0c9ccddef11b8f8b7c2.zip
fixes #847 Define public TLS API
Diffstat (limited to 'src')
-rw-r--r--src/supplemental/tls/CMakeLists.txt9
-rw-r--r--src/supplemental/tls/mbedtls/tls.c84
-rw-r--r--src/supplemental/tls/tls_api.h18
-rw-r--r--src/supplemental/tls/tls_common.c560
-rw-r--r--src/transport/tls/tls.c470
5 files changed, 750 insertions, 391 deletions
diff --git a/src/supplemental/tls/CMakeLists.txt b/src/supplemental/tls/CMakeLists.txt
index 8fed1df1..8f819ea8 100644
--- a/src/supplemental/tls/CMakeLists.txt
+++ b/src/supplemental/tls/CMakeLists.txt
@@ -1,6 +1,9 @@
#
# Copyright 2018 Capitar IT Group BV <info@capitar.com>
# Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+# Copyright 2019 Devolutions <info@devolutions.net>
+#
+
#
# This software is supplied under the terms of the MIT License, a
# copy of which should be located in the distribution where this
@@ -8,12 +11,14 @@
# found online at https://opensource.org/licenses/MIT.
#
+set(_SRCS ${PROJECT_SOURCE_DIR}/include/nng/supplemental/tls/tls.h)
+
if (NNG_SUPP_TLS)
set(NNG_SUPP_TLS_MBEDTLS ON)
set(_DEFS -DNNG_SUPP_TLS)
-endif()
-set(_SRCS ${PROJECT_SOURCE_DIR}/include/nng/supplemental/tls/tls.h)
+ list(APPEND _SRCS supplemental/tls/tls_common.c)
+endif()
# For now we only support the ARM mbedTLS library.
if (NNG_SUPP_TLS_MBEDTLS)
diff --git a/src/supplemental/tls/mbedtls/tls.c b/src/supplemental/tls/mbedtls/tls.c
index 29f1873e..9f1e8f83 100644
--- a/src/supplemental/tls/mbedtls/tls.c
+++ b/src/supplemental/tls/mbedtls/tls.c
@@ -1,7 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
-// Copyright 2018 Devolutions <info@devolutions.net>
+// Copyright 2019 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -158,32 +158,34 @@ nni_tls_config_fini(nng_tls_config *cfg)
{
nni_tls_certkey *ck;
- nni_mtx_lock(&cfg->lk);
- cfg->refcnt--;
- if (cfg->refcnt != 0) {
+ if (cfg != NULL) {
+ nni_mtx_lock(&cfg->lk);
+ cfg->refcnt--;
+ if (cfg->refcnt != 0) {
+ nni_mtx_unlock(&cfg->lk);
+ return;
+ }
nni_mtx_unlock(&cfg->lk);
- return;
- }
- nni_mtx_unlock(&cfg->lk);
- mbedtls_ssl_config_free(&cfg->cfg_ctx);
+ mbedtls_ssl_config_free(&cfg->cfg_ctx);
#ifdef NNG_TLS_USE_CTR_DRBG
- mbedtls_ctr_drbg_free(&cfg->rng_ctx);
+ mbedtls_ctr_drbg_free(&cfg->rng_ctx);
#endif
- mbedtls_x509_crt_free(&cfg->ca_certs);
- mbedtls_x509_crl_free(&cfg->crl);
- if (cfg->server_name) {
- nni_strfree(cfg->server_name);
- }
- while ((ck = nni_list_first(&cfg->certkeys))) {
- nni_list_remove(&cfg->certkeys, ck);
- mbedtls_x509_crt_free(&ck->crt);
- mbedtls_pk_free(&ck->key);
+ mbedtls_x509_crt_free(&cfg->ca_certs);
+ mbedtls_x509_crl_free(&cfg->crl);
+ if (cfg->server_name) {
+ nni_strfree(cfg->server_name);
+ }
+ while ((ck = nni_list_first(&cfg->certkeys))) {
+ nni_list_remove(&cfg->certkeys, ck);
+ mbedtls_x509_crt_free(&ck->crt);
+ mbedtls_pk_free(&ck->key);
- NNI_FREE_STRUCT(ck);
+ NNI_FREE_STRUCT(ck);
+ }
+ nni_mtx_fini(&cfg->lk);
+ NNI_FREE_STRUCT(cfg);
}
- nni_mtx_fini(&cfg->lk);
- NNI_FREE_STRUCT(cfg);
}
int
@@ -254,27 +256,29 @@ void
nni_tls_fini(nni_tls *tp)
{
// Shut it all down first.
- if (tp->tcp) {
- nni_tcp_conn_close(tp->tcp);
- }
- nni_aio_stop(tp->tcp_send);
- nni_aio_stop(tp->tcp_recv);
+ if (tp != NULL) {
+ if (tp->tcp) {
+ nni_tcp_conn_close(tp->tcp);
+ }
+ nni_aio_stop(tp->tcp_send);
+ nni_aio_stop(tp->tcp_recv);
- // And finalize / free everything.
- if (tp->tcp) {
- nni_tcp_conn_fini(tp->tcp);
- }
- nni_aio_fini(tp->tcp_send);
- nni_aio_fini(tp->tcp_recv);
- mbedtls_ssl_free(&tp->ctx);
- nni_mtx_fini(&tp->lk);
- nni_free(tp->recvbuf, NNG_TLS_MAX_RECV_SIZE);
- nni_free(tp->sendbuf, NNG_TLS_MAX_RECV_SIZE);
- if (tp->cfg != NULL) {
- // release the hold we got on it
- nni_tls_config_fini(tp->cfg);
+ // And finalize / free everything.
+ if (tp->tcp) {
+ nni_tcp_conn_fini(tp->tcp);
+ }
+ nni_aio_fini(tp->tcp_send);
+ nni_aio_fini(tp->tcp_recv);
+ mbedtls_ssl_free(&tp->ctx);
+ nni_mtx_fini(&tp->lk);
+ nni_free(tp->recvbuf, NNG_TLS_MAX_RECV_SIZE);
+ nni_free(tp->sendbuf, NNG_TLS_MAX_RECV_SIZE);
+ if (tp->cfg != NULL) {
+ // release the hold we got on it
+ nni_tls_config_fini(tp->cfg);
+ }
+ NNI_FREE_STRUCT(tp);
}
- NNI_FREE_STRUCT(tp);
}
// nni_tls_mkerr converts an mbed error to an NNG error. In all cases
diff --git a/src/supplemental/tls/tls_api.h b/src/supplemental/tls/tls_api.h
index 63424d5e..22dd68a0 100644
--- a/src/supplemental/tls/tls_api.h
+++ b/src/supplemental/tls/tls_api.h
@@ -1,7 +1,7 @@
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
-// Copyright 2018 Devolutions <info@devolutions.net>
+// Copyright 2019 Devolutions <info@devolutions.net>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
@@ -44,6 +44,20 @@ extern int nni_tls_setopt(
nni_tls *, const char *, const void *, size_t, nni_type);
extern int nni_tls_getopt(nni_tls *, const char *, void *, size_t *, nni_type);
-// TBD: getting additional peer certificate information...
+extern int nni_tls_set(
+ nng_tls *, const char *, const void *, size_t, nni_type);
+extern int nni_tls_get(nng_tls *, const char *, void *, size_t *, nni_type);
+
+extern int nni_tls_dialer_setopt(
+ nng_tls_dialer *, const char *, const void *, size_t, nni_type);
+
+extern int nni_tls_dialer_getopt(
+ nng_tls_dialer *, const char *, void *, size_t *, nni_type);
+
+extern int nni_tls_listener_setopt(
+ nng_tls_listener *, const char *, const void *, size_t, nni_type);
+
+extern int nni_tls_listener_getopt(
+ nng_tls_listener *, const char *, void *, size_t *, nni_type);
#endif // NNG_SUPPLEMENTAL_TLS_TLS_API_H
diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c
new file mode 100644
index 00000000..95466558
--- /dev/null
+++ b/src/supplemental/tls/tls_common.c
@@ -0,0 +1,560 @@
+//
+// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2018 Capitar IT Group BV <info@capitar.com>
+// Copyright 2019 Devolutions <info@devolutions.net>
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "core/nng_impl.h"
+#include "supplemental/tls/tls_api.h"
+
+#include <nng/supplemental/tcp/tcp.h>
+#include <nng/supplemental/tls/tls.h>
+
+// This file contains common code for TLS, and is only compiled if we
+// have TLS configured in the system. In particular, this provides the
+// parts of TLS support that are invariant relative to different TLS
+// libraries, such as dialer and listener support.
+
+struct nng_tls_s {
+ nni_tls * c;
+ nni_aio * aio; // system aio for connect/accept
+ nni_aio * uaio; // user aio for connect/accept
+ nng_tls_config *cfg;
+};
+
+// We use a union and share an "endpoint" for both dialers and listeners.
+// This allows us to reuse the bulk of the code for things like option
+// handlers for both dialers and listeners.
+typedef union tls_tcp_ep_u {
+ nni_tcp_dialer * d;
+ nni_tcp_listener *l;
+} tls_tcp_ep;
+
+typedef struct nng_tls_ep_s {
+ tls_tcp_ep tcp;
+ nng_tls_config *cfg;
+ nni_mtx lk;
+} tls_ep;
+
+void
+nng_tls_close(nng_tls *tls)
+{
+ nni_tls_close(tls->c);
+}
+
+void
+nng_tls_free(nng_tls *tls)
+{
+ if (tls != NULL) {
+ nni_tls_fini(tls->c);
+ nni_aio_fini(tls->aio);
+ nng_tls_config_free(tls->cfg);
+ NNI_FREE_STRUCT(tls);
+ }
+}
+
+void
+nng_tls_send(nng_tls *tls, nng_aio *aio)
+{
+ nni_tls_send(tls->c, aio);
+}
+
+void
+nng_tls_recv(nng_tls *tls, nng_aio *aio)
+{
+ nni_tls_recv(tls->c, aio);
+}
+
+int
+nni_tls_get(nng_tls *tls, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ return (nni_tls_getopt(tls->c, name, buf, szp, t));
+}
+
+int
+nni_tls_set(
+ nng_tls *tls, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ return (nni_tls_setopt(tls->c, name, buf, sz, t));
+}
+
+int
+nng_tls_getopt(nng_tls *tls, const char *name, void *buf, size_t *szp)
+{
+ return (nni_tls_getopt(tls->c, name, buf, szp, NNI_TYPE_OPAQUE));
+}
+
+int
+nng_tls_setopt(nng_tls *tls, const char *name, const void *buf, size_t sz)
+{
+ return (nni_tls_setopt(tls->c, name, buf, sz, NNI_TYPE_OPAQUE));
+}
+
+int
+nng_tls_dialer_alloc(nng_tls_dialer **dp)
+{
+ tls_ep *ep;
+ int rv;
+
+ if ((rv = nni_init()) != 0) {
+ return (rv);
+ }
+ if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ nni_mtx_init(&ep->lk);
+
+ if ((rv = nni_tcp_dialer_init(&ep->tcp.d)) != 0) {
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ return (rv);
+ }
+ if ((rv = nng_tls_config_alloc(&ep->cfg, NNG_TLS_MODE_CLIENT)) != 0) {
+ nni_tcp_dialer_fini(ep->tcp.d);
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ return (rv);
+ }
+ *dp = (void *) ep;
+ return (rv);
+}
+
+void
+nng_tls_dialer_close(nng_tls_dialer *d)
+{
+ tls_ep *ep = (void *) d;
+ nni_tcp_dialer_close(ep->tcp.d);
+}
+
+void
+nng_tls_dialer_free(nng_tls_dialer *d)
+{
+ tls_ep *ep = (void *) d;
+ if (ep != NULL) {
+ nni_tcp_dialer_fini(ep->tcp.d);
+ nng_tls_config_free(ep->cfg);
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ }
+}
+
+// For dialing, we need to have our own completion callback, instead of
+// the user's completion callback.
+
+static void
+tls_conn_cb(void *arg)
+{
+ nng_tls * tls = arg;
+ nni_tcp_conn *tcp;
+ int rv;
+
+ if ((rv = nni_aio_result(tls->aio)) != 0) {
+ nni_aio_finish_error(tls->uaio, rv);
+ nng_tls_free(tls);
+ return;
+ }
+
+ tcp = nni_aio_get_output(tls->aio, 0);
+
+ rv = nni_tls_init(&tls->c, tls->cfg, tcp);
+ if (rv != 0) {
+ nni_aio_finish_error(tls->uaio, rv);
+ nni_tcp_conn_fini(tcp);
+ nng_tls_free(tls);
+ return;
+ }
+
+ nni_aio_set_output(tls->uaio, 0, tls);
+ nni_aio_finish(tls->uaio, 0, 0);
+}
+
+// Dialer cancel is called when the user has indicated that they no longer
+// want to wait for the connection to establish.
+static void
+tls_conn_cancel(nni_aio *aio, void *arg, int rv)
+{
+ nng_tls *tls = arg;
+ NNI_ASSERT(tls->uaio == aio);
+ // Just pass this down. If the connection is already done, this
+ // will have no effect.
+ nni_aio_abort(tls->aio, rv);
+}
+
+void
+nng_tls_dialer_dial(nng_tls_dialer *d, const nng_sockaddr *sa, nng_aio *aio)
+{
+ int rv;
+ nng_tls *tls;
+ tls_ep * ep = (void *) d;
+
+ if (nni_aio_begin(aio) != 0) {
+ return;
+ }
+ if ((tls = NNI_ALLOC_STRUCT(tls)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ return;
+ }
+ if ((rv = nni_aio_init(&tls->aio, tls_conn_cb, tls)) != 0) {
+ nni_aio_finish_error(aio, rv);
+ NNI_FREE_STRUCT(tls);
+ return;
+ }
+ tls->uaio = aio;
+
+ // Save a copy of the TLS configuration. This way we don't have
+ // to ensure that the dialer outlives the connection, because the
+ // only shared data is the configuration which is reference counted.
+ nni_mtx_lock(&ep->lk);
+ tls->cfg = ep->cfg;
+ nng_tls_config_hold(tls->cfg);
+ nni_mtx_unlock(&ep->lk);
+
+ if ((rv = nni_aio_schedule(aio, tls_conn_cancel, tls)) != 0) {
+ nni_aio_finish_error(aio, rv);
+ nng_tls_free(tls);
+ return;
+ }
+
+ nni_tcp_dialer_dial(ep->tcp.d, sa, tls->aio);
+}
+
+static int
+tls_check_string(const void *v, size_t sz, nni_opt_type t)
+{
+ if ((t != NNI_TYPE_OPAQUE) && (t != NNI_TYPE_STRING)) {
+ return (NNG_EBADTYPE);
+ }
+ if (nni_strnlen(v, sz) >= sz) {
+ return (NNG_EINVAL);
+ }
+ return (0);
+}
+
+static int
+tls_ep_set_config(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ nng_tls_config *cfg;
+ tls_ep * ep;
+
+ if ((rv = nni_copyin_ptr((void **) &cfg, buf, sz, t)) != 0) {
+ return (rv);
+ }
+ if (cfg == NULL) {
+ return (NNG_EINVAL);
+ }
+ if ((ep = arg) != NULL) {
+ nng_tls_config *old;
+
+ nni_mtx_lock(&ep->lk);
+ old = ep->cfg;
+ nng_tls_config_hold(cfg);
+ ep->cfg = cfg;
+ nni_mtx_unlock(&ep->lk);
+ if (old != NULL) {
+ nng_tls_config_free(old);
+ }
+ }
+ return (0);
+}
+
+static int
+tls_ep_get_config(void *arg, void *buf, size_t *szp, nni_type t)
+{
+ tls_ep * ep = arg;
+ nng_tls_config *cfg;
+ int rv;
+ nni_mtx_lock(&ep->lk);
+ if ((cfg = ep->cfg) != NULL) {
+ nng_tls_config_hold(cfg);
+ }
+ if ((rv = nni_copyout_ptr(cfg, buf, szp, t)) != 0) {
+ nng_tls_config_free(cfg);
+ }
+ nni_mtx_unlock(&ep->lk);
+ return (rv);
+}
+
+static int
+tls_ep_set_server_name(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ tls_ep *ep = arg;
+ int rv;
+ if ((rv = tls_check_string(buf, sz, t)) != 0) {
+ return (rv);
+ }
+ if ((ep = arg) != NULL) {
+ nni_mtx_lock(&ep->lk);
+ rv = nng_tls_config_server_name(ep->cfg, buf);
+ nni_mtx_unlock(&ep->lk);
+ }
+ return (rv);
+}
+
+static int
+tls_ep_set_auth_mode(void *arg, const void *buf, size_t sz, nni_type t)
+{
+ int mode;
+ int rv;
+ tls_ep *ep;
+
+ rv = nni_copyin_int(&mode, buf, sz, NNG_TLS_AUTH_MODE_NONE,
+ NNG_TLS_AUTH_MODE_REQUIRED, t);
+ if ((rv == 0) && ((ep = arg) != NULL)) {
+ nni_mtx_lock(&ep->lk);
+ rv = nng_tls_config_auth_mode(ep->cfg, mode);
+ nni_mtx_unlock(&ep->lk);
+ }
+ return (rv);
+}
+
+static int
+tls_ep_set_ca_file(void *arg, const void *buf, size_t sz, nni_opt_type t)
+{
+ tls_ep *ep;
+ int rv;
+
+ if (((rv = tls_check_string(buf, sz, t)) == 0) &&
+ ((ep = arg) != NULL)) {
+ nni_mtx_lock(&ep->lk);
+ rv = nng_tls_config_ca_file(ep->cfg, buf);
+ nni_mtx_unlock(&ep->lk);
+ }
+ return (rv);
+}
+
+static int
+tls_ep_set_cert_key_file(void *arg, const void *buf, size_t sz, nni_opt_type t)
+{
+ tls_ep *ep;
+ int rv;
+
+ if (((rv = tls_check_string(buf, sz, t)) == 0) &&
+ ((ep = arg) != NULL)) {
+ nni_mtx_lock(&ep->lk);
+ rv = nng_tls_config_cert_key_file(ep->cfg, buf, NULL);
+ nni_mtx_unlock(&ep->lk);
+ }
+ return (rv);
+}
+
+static const nni_option tls_ep_opts[] = {
+ {
+ .o_name = NNG_OPT_TLS_CONFIG,
+ .o_get = tls_ep_get_config,
+ .o_set = tls_ep_set_config,
+ },
+ {
+ .o_name = NNG_OPT_TLS_SERVER_NAME,
+ .o_set = tls_ep_set_server_name,
+ },
+ {
+ .o_name = NNG_OPT_TLS_CA_FILE,
+ .o_set = tls_ep_set_ca_file,
+ },
+ {
+ .o_name = NNG_OPT_TLS_CERT_KEY_FILE,
+ .o_set = tls_ep_set_cert_key_file,
+ },
+ {
+ .o_name = NNG_OPT_TLS_AUTH_MODE,
+ .o_set = tls_ep_set_auth_mode,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+// private version of getopt and setopt take the type
+int
+nni_tls_dialer_getopt(
+ nng_tls_dialer *d, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ int rv;
+ tls_ep *ep = (void *) d;
+
+ rv = nni_tcp_dialer_getopt(ep->tcp.d, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tls_ep_opts, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+int
+nni_tls_dialer_setopt(nng_tls_dialer *d, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ int rv;
+ tls_ep *ep = (void *) d;
+
+ rv = nni_tcp_dialer_setopt(
+ ep != NULL ? ep->tcp.d : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tls_ep_opts, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
+
+// public versions of option handlers here
+
+int
+nng_tls_dialer_getopt(
+ nng_tls_dialer *d, const char *name, void *buf, size_t *szp)
+{
+ return (nni_tls_dialer_getopt(d, name, buf, szp, NNI_TYPE_OPAQUE));
+}
+
+int
+nng_tls_dialer_setopt(
+ nng_tls_dialer *d, const char *name, const void *buf, size_t sz)
+{
+ return (nni_tls_dialer_setopt(d, name, buf, sz, NNI_TYPE_OPAQUE));
+}
+
+void
+nng_tls_listener_close(nng_tls_listener *l)
+{
+ tls_ep *ep = (void *) l;
+ nni_tcp_listener_close(ep->tcp.l);
+}
+
+void
+nng_tls_listener_free(nng_tls_listener *l)
+{
+ tls_ep *ep = (void *) l;
+ if (ep != NULL) {
+ nng_tls_listener_close(l);
+ nng_tls_config_free(ep->cfg);
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ }
+}
+
+int
+nng_tls_listener_alloc(nng_tls_listener **lp)
+{
+ tls_ep *ep;
+ int rv;
+
+ if ((rv = nni_init()) != 0) {
+ return (rv);
+ }
+ if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ nni_mtx_init(&ep->lk);
+
+ if ((rv = nni_tcp_listener_init(&ep->tcp.l)) != 0) {
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ return (rv);
+ }
+ if ((rv = nng_tls_config_alloc(&ep->cfg, NNG_TLS_MODE_SERVER)) != 0) {
+ nni_tcp_listener_fini(ep->tcp.l);
+ nni_mtx_fini(&ep->lk);
+ NNI_FREE_STRUCT(ep);
+ return (rv);
+ }
+ *lp = (void *) ep;
+ return (0);
+}
+
+int
+nng_tls_listener_listen(nng_tls_listener *l, nng_sockaddr *sa)
+{
+ tls_ep *ep = (void *) l;
+ return (nni_tcp_listener_listen(ep->tcp.l, sa));
+}
+
+void
+nng_tls_listener_accept(nng_tls_listener *l, nng_aio *aio)
+{
+ int rv;
+ nng_tls *tls;
+ tls_ep * ep = (void *) l;
+
+ if (nni_aio_begin(aio) != 0) {
+ return;
+ }
+ if ((tls = NNI_ALLOC_STRUCT(tls)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ return;
+ }
+ if ((rv = nni_aio_init(&tls->aio, tls_conn_cb, tls)) != 0) {
+ nni_aio_finish_error(aio, rv);
+ NNI_FREE_STRUCT(tls);
+ return;
+ }
+ tls->uaio = aio;
+
+ // Save a copy of the TLS configuration. This way we don't have
+ // to ensure that the dialer outlives the connection, because the
+ // only shared data is the configuration which is reference counted.
+ nni_mtx_lock(&ep->lk);
+ tls->cfg = ep->cfg;
+ nng_tls_config_hold(tls->cfg);
+ nni_mtx_unlock(&ep->lk);
+
+ if ((rv = nni_aio_schedule(aio, tls_conn_cancel, tls)) != 0) {
+ nni_aio_finish_error(aio, rv);
+ nng_tls_free(tls);
+ return;
+ }
+
+ nni_tcp_listener_accept(ep->tcp.l, tls->aio);
+}
+
+int
+nni_tls_listener_getopt(
+ nng_tls_listener *l, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ int rv;
+ tls_ep *ep = (void *) l;
+
+ rv = nni_tcp_listener_getopt(ep->tcp.l, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tls_ep_opts, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+int
+nni_tls_listener_setopt(nng_tls_listener *l, const char *name, const void *buf,
+ size_t sz, nni_type t)
+{
+ int rv;
+ tls_ep *ep = (void *) l;
+
+ rv = nni_tcp_listener_setopt(
+ ep != NULL ? ep->tcp.l : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tls_ep_opts, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
+
+// public versions of option handlers here
+
+int
+nng_tls_listener_getopt(
+ nng_tls_listener *l, const char *name, void *buf, size_t *szp)
+{
+ return (nni_tls_listener_getopt(l, name, buf, szp, NNI_TYPE_OPAQUE));
+}
+
+int
+nng_tls_listener_setopt(
+ nng_tls_listener *l, const char *name, const void *buf, size_t sz)
+{
+ return (nni_tls_listener_setopt(l, name, buf, sz, NNI_TYPE_OPAQUE));
+}
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index dc198ebf..25bfb0dd 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -30,13 +30,11 @@ typedef struct tlstran_pipe tlstran_pipe;
// tlstran_pipe is one end of a TLS connection.
struct tlstran_pipe {
- nni_tls * tls;
+ nng_tls * tls;
nni_pipe * npipe;
uint16_t peer;
uint16_t proto;
size_t rcvmax;
- bool nodelay;
- bool keepalive;
bool closed;
nni_list_node node;
nni_list sendq;
@@ -67,20 +65,16 @@ struct tlstran_ep {
uint16_t af;
uint16_t proto;
size_t rcvmax;
- bool nodelay;
- bool keepalive;
bool fini;
int authmode;
- nng_tls_config * cfg;
nni_url * url;
nni_list pipes;
nni_reap_item reap;
- nni_tcp_dialer * dialer;
- nni_tcp_listener *listener;
+ nng_tls_dialer * dialer;
+ nng_tls_listener *listener;
const char * host;
nng_sockaddr src;
nng_sockaddr sa;
- nng_sockaddr bsa;
nni_dialer * ndialer;
nni_listener * nlistener;
};
@@ -116,7 +110,7 @@ tlstran_pipe_close(void *arg)
nni_aio_close(p->connaio);
nni_aio_close(p->rslvaio);
- nni_tls_close(p->tls);
+ nng_tls_close(p->tls);
}
static void
@@ -159,9 +153,7 @@ tlstran_pipe_fini(void *arg)
nni_aio_fini(p->negoaio);
nni_aio_fini(p->connaio);
nni_aio_fini(p->rslvaio);
- if (p->tls != NULL) {
- nni_tls_fini(p->tls);
- }
+ nng_tls_free(p->tls);
nni_msg_free(p->rxmsg);
NNI_FREE_STRUCT(p);
}
@@ -190,12 +182,10 @@ tlstran_pipe_alloc(tlstran_pipe **pipep, tlstran_ep *ep)
nni_atomic_flag_reset(&p->reaped);
nni_list_append(&ep->pipes, p);
- p->keepalive = ep->keepalive;
- p->nodelay = ep->nodelay;
- p->rcvmax = ep->rcvmax;
- p->proto = ep->proto;
- p->ep = ep;
- *pipep = p;
+ p->rcvmax = ep->rcvmax;
+ p->proto = ep->proto;
+ p->ep = ep;
+ *pipep = p;
return (0);
}
@@ -204,7 +194,7 @@ tlstran_pipe_reap(tlstran_pipe *p)
{
if (!nni_atomic_flag_test_and_set(&p->reaped)) {
if (p->tls != NULL) {
- nni_tls_close(p->tls);
+ nng_tls_close(p->tls);
}
nni_reap(&p->reap, tlstran_pipe_fini, p);
}
@@ -250,7 +240,7 @@ tlstran_pipe_rslv_cb(void *arg)
tlstran_pipe_reap(p);
return;
}
- nni_tcp_dialer_dial(ep->dialer, &p->sa, p->connaio);
+ nng_tls_dialer_dial(ep->dialer, &p->sa, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -262,31 +252,24 @@ tlstran_pipe_conn_cb(void *arg)
nni_aio * aio = p->connaio;
nni_aio * uaio;
nni_iov iov;
- nni_tcp_conn *conn;
int rv;
nni_mtx_lock(&ep->mtx);
if ((rv = nni_aio_result(aio)) == 0) {
- conn = nni_aio_get_output(aio, 0);
+ p->tls = nni_aio_get_output(aio, 0);
} else {
- conn = NULL;
+ p->tls = NULL;
}
if ((uaio = p->useraio) == NULL) {
- if (conn != NULL) {
- nni_tcp_conn_fini(conn);
- }
nni_mtx_unlock(&ep->mtx);
tlstran_pipe_reap(p);
return;
}
- if ((rv != 0) || ((rv = nni_tls_init(&p->tls, ep->cfg, conn)) != 0)) {
+ if (rv != 0) {
p->useraio = NULL;
nni_mtx_unlock(&ep->mtx);
- if (conn != NULL) {
- nni_tcp_conn_fini(conn);
- }
nni_aio_finish_error(uaio, rv);
tlstran_pipe_reap(p);
return;
@@ -305,7 +288,7 @@ tlstran_pipe_conn_cb(void *arg)
iov.iov_len = 8;
iov.iov_buf = &p->txlen[0];
nni_aio_set_iov(p->negoaio, 1, &iov);
- nni_tls_send(p->tls, p->negoaio);
+ nng_tls_send(p->tls, p->negoaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -342,7 +325,7 @@ tlstran_pipe_nego_cb(void *arg)
iov.iov_buf = &p->txlen[p->gottxhead];
nni_aio_set_iov(aio, 1, &iov);
// send it down...
- nni_tls_send(p->tls, aio);
+ nng_tls_send(p->tls, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -351,7 +334,7 @@ tlstran_pipe_nego_cb(void *arg)
iov.iov_len = p->wantrxhead - p->gotrxhead;
iov.iov_buf = &p->rxlen[p->gotrxhead];
nni_aio_set_iov(aio, 1, &iov);
- nni_tls_recv(p->tls, aio);
+ nng_tls_recv(p->tls, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -368,11 +351,6 @@ tlstran_pipe_nego_cb(void *arg)
p->useraio = NULL;
nni_mtx_unlock(&ep->mtx);
- (void) nni_tls_setopt(p->tls, NNG_OPT_TCP_NODELAY, &p->nodelay,
- sizeof(p->nodelay), NNI_TYPE_BOOL);
- (void) nni_tls_setopt(p->tls, NNG_OPT_TCP_KEEPALIVE, &p->keepalive,
- sizeof(p->keepalive), NNI_TYPE_BOOL);
-
nni_aio_set_output(uaio, 0, p);
nni_aio_finish(uaio, 0, 0);
return;
@@ -412,7 +390,7 @@ tlstran_pipe_send_cb(void *arg)
n = nni_aio_count(txaio);
nni_aio_iov_advance(txaio, n);
if (nni_aio_iov_count(txaio) > 0) {
- nni_tls_send(p->tls, txaio);
+ nng_tls_send(p->tls, txaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -448,7 +426,7 @@ tlstran_pipe_recv_cb(void *arg)
nni_aio_iov_advance(rxaio, n);
if (nni_aio_iov_count(rxaio) > 0) {
// Was this a partial read? If so then resubmit for the rest.
- nni_tls_recv(p->tls, rxaio);
+ nng_tls_recv(p->tls, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -480,7 +458,7 @@ tlstran_pipe_recv_cb(void *arg)
iov.iov_len = (size_t) len;
nni_aio_set_iov(rxaio, 1, &iov);
- nni_tls_recv(p->tls, rxaio);
+ nng_tls_recv(p->tls, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -570,7 +548,7 @@ tlstran_pipe_send_start(tlstran_pipe *p)
}
nni_aio_set_iov(txaio, niov, iov);
- nni_tls_send(p->tls, txaio);
+ nng_tls_send(p->tls, txaio);
}
static void
@@ -631,7 +609,7 @@ tlstran_pipe_recv_start(tlstran_pipe *p)
iov.iov_len = sizeof(p->rxlen);
nni_aio_set_iov(rxaio, 1, &iov);
- nni_tls_recv(p->tls, rxaio);
+ nng_tls_recv(p->tls, rxaio);
}
static void
@@ -676,17 +654,10 @@ tlstran_ep_fini(void *arg)
nni_mtx_unlock(&ep->mtx);
return;
}
- if (ep->dialer != NULL) {
- nni_tcp_dialer_fini(ep->dialer);
- }
- if (ep->listener != NULL) {
- nni_tcp_listener_fini(ep->listener);
- }
+ nng_tls_dialer_free(ep->dialer);
+ nng_tls_listener_free(ep->listener);
nni_mtx_unlock(&ep->mtx);
- if (ep->cfg != NULL) {
- nni_tls_config_fini(ep->cfg);
- }
nni_mtx_fini(&ep->mtx);
NNI_FREE_STRUCT(ep);
}
@@ -705,14 +676,14 @@ tlstran_ep_close(void *arg)
nni_aio_close(p->txaio);
nni_aio_close(p->rxaio);
if (p->tls != NULL) {
- nni_tls_close(p->tls);
+ nng_tls_close(p->tls);
}
}
if (ep->dialer != NULL) {
- nni_tcp_dialer_close(ep->dialer);
+ nng_tls_dialer_close(ep->dialer);
}
if (ep->listener != NULL) {
- nni_tcp_listener_close(ep->listener);
+ nng_tls_listener_close(ep->listener);
}
nni_mtx_unlock(&ep->mtx);
}
@@ -753,13 +724,11 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
nni_mtx_init(&ep->mtx);
NNI_LIST_INIT(&ep->pipes, tlstran_pipe, node);
- ep->authmode = NNG_TLS_AUTH_MODE_REQUIRED;
- ep->url = url;
- ep->af = af;
- ep->proto = nni_sock_proto_id(sock);
- ep->nodelay = true;
- ep->keepalive = false;
- ep->ndialer = ndialer;
+ ep->authmode = NNG_TLS_AUTH_MODE_REQUIRED;
+ ep->url = url;
+ ep->af = af;
+ ep->proto = nni_sock_proto_id(sock);
+ ep->ndialer = ndialer;
// Detect an embedded local interface name in the hostname. This
// syntax is only valid with dialers.
@@ -798,10 +767,11 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
rv = 0;
}
- if ((rv != 0) || ((rv = nni_tcp_dialer_init(&ep->dialer)) != 0) ||
- ((rv = nni_tls_config_init(&ep->cfg, NNG_TLS_MODE_CLIENT)) != 0) ||
- ((rv = nng_tls_config_auth_mode(ep->cfg, ep->authmode)) != 0) ||
- ((rv = nng_tls_config_server_name(ep->cfg, ep->host)) != 0)) {
+ if ((rv != 0) || ((rv = nng_tls_dialer_alloc(&ep->dialer)) != 0) ||
+ ((rv = nng_tls_dialer_setopt(ep->dialer, NNG_OPT_TLS_AUTH_MODE,
+ &ep->authmode, sizeof(ep->authmode))) != 0) ||
+ ((rv = nng_tls_dialer_setopt(ep->dialer, NNG_OPT_TLS_SERVER_NAME,
+ ep->host, strlen(ep->host) + 1)) != 0)) {
tlstran_ep_fini(ep);
return (rv);
}
@@ -849,8 +819,6 @@ tlstran_ep_init_listener(void **lp, nni_url *url, nni_listener *nlistener)
ep->url = url;
ep->af = af;
ep->proto = nni_sock_proto_id(sock);
- ep->nodelay = true;
- ep->keepalive = false;
ep->nlistener = nlistener;
if (strlen(host) == 0) {
@@ -873,10 +841,9 @@ tlstran_ep_init_listener(void **lp, nni_url *url, nni_listener *nlistener)
rv = nni_aio_result(aio);
nni_aio_fini(aio);
- ep->bsa = ep->sa;
- if (((rv = nni_tcp_listener_init(&ep->listener)) != 0) ||
- ((rv = nni_tls_config_init(&ep->cfg, NNG_TLS_MODE_SERVER)) != 0) ||
- ((rv = nng_tls_config_auth_mode(ep->cfg, ep->authmode)) != 0)) {
+ if ((rv != 0) || ((rv = nng_tls_listener_alloc(&ep->listener)) != 0) ||
+ ((rv = nng_tls_listener_setopt(ep->listener, NNG_OPT_TLS_AUTH_MODE,
+ &ep->authmode, sizeof(ep->authmode))) != 0)) {
tlstran_ep_fini(ep);
return (rv);
}
@@ -921,8 +888,7 @@ tlstran_ep_bind(void *arg)
int rv;
nni_mtx_lock(&ep->mtx);
- ep->bsa = ep->sa;
- rv = nni_tcp_listener_listen(ep->listener, &ep->bsa);
+ rv = nng_tls_listener_listen(ep->listener, &ep->sa);
nni_mtx_unlock(&ep->mtx);
return (rv);
@@ -953,36 +919,11 @@ tlstran_ep_accept(void *arg, nni_aio *aio)
}
p->useraio = aio;
- nni_tcp_listener_accept(ep->listener, p->connaio);
+ nng_tls_listener_accept(ep->listener, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
static int
-tlstran_ep_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- bool val;
- int rv;
- if (((rv = nni_copyin_bool(&val, v, sz, t)) == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- ep->nodelay = val;
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
-}
-
-static int
-tlstran_ep_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_bool(ep->nodelay, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
- return (rv);
-}
-
-static int
tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
{
tlstran_ep *ep = arg;
@@ -998,31 +939,6 @@ tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
}
static int
-tlstran_ep_set_keepalive(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- bool val;
- int rv;
- if (((rv = nni_copyin_bool(&val, v, sz, t)) == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- ep->keepalive = val;
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
-}
-
-static int
-tlstran_ep_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_bool(ep->keepalive, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
- return (rv);
-}
-
-static int
tlstran_ep_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
{
tlstran_ep *ep = arg;
@@ -1036,146 +952,28 @@ tlstran_ep_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
static int
tlstran_ep_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tlstran_ep *ep = arg;
- char ustr[128];
- char ipstr[48]; // max for IPv6 addresses including []
- char portstr[6]; // max for 16-bit port
+ tlstran_ep * ep = arg;
+ char ustr[128];
+ char ipstr[48]; // max for IPv6 addresses including []
+ char portstr[6]; // max for 16-bit port
+ nng_sockaddr sa;
+ size_t sz = sizeof(sa);
+ int rv;
if (ep->dialer != NULL) {
return (nni_copyout_str(ep->url->u_rawurl, v, szp, t));
}
- nni_mtx_lock(&ep->mtx);
- nni_ntop(&ep->bsa, ipstr, portstr);
- nni_mtx_unlock(&ep->mtx);
- snprintf(ustr, sizeof(ustr), "tls+tcp://%s:%s", ipstr, portstr);
- return (nni_copyout_str(ustr, v, szp, t));
-}
-
-static int
-tlstran_ep_get_locaddr(void *arg, void *buf, size_t *szp, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
-
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_sockaddr(&ep->bsa, buf, szp, t);
- nni_mtx_unlock(&ep->mtx);
- return (rv);
-}
-
-static int
-tlstran_ep_set_config(void *arg, const void *data, size_t sz, nni_opt_type t)
-{
- tlstran_ep * ep = arg;
- nng_tls_config *cfg;
- int rv;
-
- if ((rv = nni_copyin_ptr((void **) &cfg, data, sz, t)) != 0) {
+ rv = nni_tls_listener_getopt(
+ ep->listener, NNG_OPT_LOCADDR, &sa, &sz, NNI_TYPE_SOCKADDR);
+ if (rv != 0) {
return (rv);
}
- if (cfg == NULL) {
- return (NNG_EINVAL);
- }
- if (ep != NULL) {
- nng_tls_config *old;
- nni_mtx_lock(&ep->mtx);
- old = ep->cfg;
- nni_tls_config_hold(cfg);
- ep->cfg = cfg;
- nni_mtx_unlock(&ep->mtx);
- if (old != NULL) {
- nni_tls_config_fini(old);
- }
- }
- return (0);
-}
-
-static int
-tlstran_ep_get_config(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- tlstran_ep * ep = arg;
- nng_tls_config *cfg;
- int rv;
nni_mtx_lock(&ep->mtx);
- if ((cfg = ep->cfg) != NULL) {
- nni_tls_config_hold(cfg);
- }
- rv = nni_copyout_ptr(cfg, v, szp, t);
+ nni_ntop(&sa, ipstr, portstr);
nni_mtx_unlock(&ep->mtx);
- return (rv);
-}
-
-static int
-tlstran_check_string(const void *v, size_t sz, nni_opt_type t)
-{
- if ((t != NNI_TYPE_OPAQUE) && (t != NNI_TYPE_STRING)) {
- return (NNG_EBADTYPE);
- }
- if (nni_strnlen(v, sz) >= sz) {
- return (NNG_EINVAL);
- }
- return (0);
-}
-
-static int
-tlstran_ep_set_ca_file(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
-
- if (((rv = tlstran_check_string(v, sz, t)) == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- rv = nng_tls_config_ca_file(ep->cfg, v);
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
-}
-
-static int
-tlstran_ep_set_auth_mode(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int mode;
- int rv;
-
- rv = nni_copyin_int(&mode, v, sz, NNG_TLS_AUTH_MODE_NONE,
- NNG_TLS_AUTH_MODE_REQUIRED, t);
- if ((rv == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- rv = nng_tls_config_auth_mode(ep->cfg, mode);
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
-}
-
-static int
-tlstran_ep_set_server_name(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
-
- if (((rv = tlstran_check_string(v, sz, t)) == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- rv = nng_tls_config_server_name(ep->cfg, v);
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
-}
-
-static int
-tlstran_ep_set_cert_key_file(
- void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- tlstran_ep *ep = arg;
- int rv;
-
- if (((rv = tlstran_check_string(v, sz, t)) == 0) && (ep != NULL)) {
- nni_mtx_lock(&ep->mtx);
- rv = nng_tls_config_cert_key_file(ep->cfg, v, NULL);
- nni_mtx_unlock(&ep->mtx);
- }
- return (rv);
+ snprintf(ustr, sizeof(ustr), "tls+tcp://%s:%s", ipstr, portstr);
+ return (nni_copyout_str(ustr, v, szp, t));
}
static const nni_option tlstran_pipe_opts[] = {
@@ -1192,7 +990,7 @@ tlstran_pipe_getopt(
tlstran_pipe *p = arg;
int rv;
- if ((rv = nni_tls_getopt(p->tls, name, buf, szp, t)) == NNG_ENOTSUP) {
+ if ((rv = nni_tls_get(p->tls, name, buf, szp, t)) == NNG_ENOTSUP) {
rv = nni_getopt(tlstran_pipe_opts, name, p, buf, szp, t);
}
return (rv);
@@ -1209,7 +1007,7 @@ static nni_tran_pipe_ops tlstran_pipe_ops = {
.p_getopt = tlstran_pipe_getopt,
};
-static nni_option tlstran_dialer_options[] = {
+static nni_option tlstran_ep_options[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_get = tlstran_ep_get_recvmaxsz,
@@ -1219,109 +1017,87 @@ static nni_option tlstran_dialer_options[] = {
.o_name = NNG_OPT_URL,
.o_get = tlstran_ep_get_url,
},
- {
- .o_name = NNG_OPT_TLS_CONFIG,
- .o_get = tlstran_ep_get_config,
- .o_set = tlstran_ep_set_config,
- },
- {
- .o_name = NNG_OPT_TLS_CERT_KEY_FILE,
- .o_set = tlstran_ep_set_cert_key_file,
- },
- {
- .o_name = NNG_OPT_TLS_CA_FILE,
- .o_set = tlstran_ep_set_ca_file,
- },
- {
- .o_name = NNG_OPT_TLS_AUTH_MODE,
- .o_set = tlstran_ep_set_auth_mode,
- },
- {
- .o_name = NNG_OPT_TLS_SERVER_NAME,
- .o_set = tlstran_ep_set_server_name,
- },
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tlstran_ep_get_nodelay,
- .o_set = tlstran_ep_set_nodelay,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tlstran_ep_get_keepalive,
- .o_set = tlstran_ep_set_keepalive,
- },
// terminate list
{
.o_name = NULL,
},
};
-static nni_option tlstran_listener_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = tlstran_ep_get_recvmaxsz,
- .o_set = tlstran_ep_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_URL,
- .o_get = tlstran_ep_get_url,
- },
- {
- .o_name = NNG_OPT_LOCADDR,
- .o_get = tlstran_ep_get_locaddr,
- },
- {
- .o_name = NNG_OPT_TLS_CONFIG,
- .o_get = tlstran_ep_get_config,
- .o_set = tlstran_ep_set_config,
- },
- {
- .o_name = NNG_OPT_TLS_CERT_KEY_FILE,
- .o_set = tlstran_ep_set_cert_key_file,
- },
- {
- .o_name = NNG_OPT_TLS_CA_FILE,
- .o_set = tlstran_ep_set_ca_file,
- },
- {
- .o_name = NNG_OPT_TLS_AUTH_MODE,
- .o_set = tlstran_ep_set_auth_mode,
- },
- {
- .o_name = NNG_OPT_TLS_SERVER_NAME,
- .o_set = tlstran_ep_set_server_name,
- },
- {
- .o_name = NNG_OPT_TCP_NODELAY,
- .o_get = tlstran_ep_get_nodelay,
- .o_set = tlstran_ep_set_nodelay,
- },
- {
- .o_name = NNG_OPT_TCP_KEEPALIVE,
- .o_get = tlstran_ep_get_keepalive,
- .o_set = tlstran_ep_set_keepalive,
- },
- // terminate list
- {
- .o_name = NULL,
- },
-};
+static int
+tlstran_dialer_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ int rv;
+ tlstran_ep *ep = arg;
+
+ rv = nni_tls_dialer_getopt(ep->dialer, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tlstran_ep_options, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tlstran_dialer_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ tlstran_ep *ep = arg;
+
+ rv = nni_tls_dialer_setopt(
+ ep != NULL ? ep->dialer : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tlstran_ep_options, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
+
+static int
+tlstran_listener_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+{
+ int rv;
+ tlstran_ep *ep = arg;
+
+ rv = nni_tls_listener_getopt(ep->listener, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(tlstran_ep_options, name, ep, buf, szp, t);
+ }
+ return (rv);
+}
+
+static int
+tlstran_listener_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ tlstran_ep *ep = arg;
+
+ rv = nni_tls_listener_setopt(
+ ep != NULL ? ep->listener : NULL, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(tlstran_ep_options, name, ep, buf, sz, t);
+ }
+ return (rv);
+}
static nni_tran_dialer_ops tlstran_dialer_ops = {
.d_init = tlstran_ep_init_dialer,
.d_fini = tlstran_ep_fini,
.d_connect = tlstran_ep_connect,
.d_close = tlstran_ep_close,
- .d_options = tlstran_dialer_options,
+ .d_getopt = tlstran_dialer_getopt,
+ .d_setopt = tlstran_dialer_setopt,
};
static nni_tran_listener_ops tlstran_listener_ops = {
- .l_init = tlstran_ep_init_listener,
- .l_fini = tlstran_ep_fini,
- .l_bind = tlstran_ep_bind,
- .l_accept = tlstran_ep_accept,
- .l_close = tlstran_ep_close,
- .l_options = tlstran_listener_options,
+ .l_init = tlstran_ep_init_listener,
+ .l_fini = tlstran_ep_fini,
+ .l_bind = tlstran_ep_bind,
+ .l_accept = tlstran_ep_accept,
+ .l_close = tlstran_ep_close,
+ .l_getopt = tlstran_listener_getopt,
+ .l_setopt = tlstran_listener_setopt,
};
static nni_tran tls_tran = {