aboutsummaryrefslogtreecommitdiff
path: root/src/transport/tls
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2019-01-21 22:40:10 -0800
committerGarrett D'Amore <garrett@damore.org>2019-02-16 19:22:27 -0800
commit5cf750697624d4fd63cfe26921209d7c30e1a2d2 (patch)
treebf11695e5f1ec5e400c87da0cc6ff23935a2eeff /src/transport/tls
parentca655b9db689ee0e655248b1a9f166b8db6cc984 (diff)
downloadnng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.tar.gz
nng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.tar.bz2
nng-5cf750697624d4fd63cfe26921209d7c30e1a2d2.zip
fixes #872 create unified nng_stream API
This is a major change, and includes changes to use a polymorphic stream API for all transports. There have been related bugs fixed along the way. Additionally the man pages have changed. The old non-polymorphic APIs are removed now. This is a breaking change, but the old APIs were never part of any released public API.
Diffstat (limited to 'src/transport/tls')
-rw-r--r--src/transport/tls/tls.c289
1 files changed, 151 insertions, 138 deletions
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index 25bfb0dd..d68cb8b1 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -1,7 +1,7 @@
//
-// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2019 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
@@ -30,7 +30,7 @@ typedef struct tlstran_pipe tlstran_pipe;
// tlstran_pipe is one end of a TLS connection.
struct tlstran_pipe {
- nng_tls * tls;
+ nng_stream * tls;
nni_pipe * npipe;
uint16_t peer;
uint16_t proto;
@@ -54,29 +54,28 @@ struct tlstran_pipe {
nni_aio * rxaio;
nni_aio * negoaio;
nni_aio * connaio;
- nni_aio * rslvaio;
nni_msg * rxmsg;
nni_mtx mtx;
};
// Stuff that is common to both dialers and listeners.
struct tlstran_ep {
- nni_mtx mtx;
- uint16_t af;
- uint16_t proto;
- size_t rcvmax;
- bool fini;
- int authmode;
- nni_url * url;
- nni_list pipes;
- nni_reap_item reap;
- nng_tls_dialer * dialer;
- nng_tls_listener *listener;
- const char * host;
- nng_sockaddr src;
- nng_sockaddr sa;
- nni_dialer * ndialer;
- nni_listener * nlistener;
+ nni_mtx mtx;
+ uint16_t af;
+ uint16_t proto;
+ size_t rcvmax;
+ bool fini;
+ int authmode;
+ nni_url * url;
+ nni_list pipes;
+ nni_reap_item reap;
+ nng_stream_dialer * dialer;
+ nng_stream_listener *listener;
+ const char * host;
+ nng_sockaddr src;
+ nng_sockaddr sa;
+ nni_dialer * ndialer;
+ nni_listener * nlistener;
};
static void tlstran_pipe_send_start(tlstran_pipe *);
@@ -85,7 +84,6 @@ static void tlstran_pipe_send_cb(void *);
static void tlstran_pipe_recv_cb(void *);
static void tlstran_pipe_conn_cb(void *);
static void tlstran_pipe_nego_cb(void *);
-static void tlstran_pipe_rslv_cb(void *);
static void tlstran_ep_fini(void *);
static int
@@ -108,9 +106,8 @@ tlstran_pipe_close(void *arg)
nni_aio_close(p->txaio);
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_aio_close(p->rslvaio);
- nng_tls_close(p->tls);
+ nng_stream_close(p->tls);
}
static void
@@ -122,7 +119,6 @@ tlstran_pipe_stop(void *arg)
nni_aio_stop(p->txaio);
nni_aio_stop(p->negoaio);
nni_aio_stop(p->connaio);
- nni_aio_stop(p->rslvaio);
}
static int
@@ -152,8 +148,7 @@ tlstran_pipe_fini(void *arg)
nni_aio_fini(p->txaio);
nni_aio_fini(p->negoaio);
nni_aio_fini(p->connaio);
- nni_aio_fini(p->rslvaio);
- nng_tls_free(p->tls);
+ nng_stream_free(p->tls);
nni_msg_free(p->rxmsg);
NNI_FREE_STRUCT(p);
}
@@ -171,7 +166,6 @@ tlstran_pipe_alloc(tlstran_pipe **pipep, tlstran_ep *ep)
if (((rv = nni_aio_init(&p->txaio, tlstran_pipe_send_cb, p)) != 0) ||
((rv = nni_aio_init(&p->rxaio, tlstran_pipe_recv_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->rslvaio, tlstran_pipe_rslv_cb, p)) != 0) ||
((rv = nni_aio_init(&p->connaio, tlstran_pipe_conn_cb, p)) != 0) ||
((rv = nni_aio_init(&p->negoaio, tlstran_pipe_nego_cb, p)) != 0)) {
tlstran_pipe_fini(p);
@@ -194,7 +188,7 @@ tlstran_pipe_reap(tlstran_pipe *p)
{
if (!nni_atomic_flag_test_and_set(&p->reaped)) {
if (p->tls != NULL) {
- nng_tls_close(p->tls);
+ nng_stream_close(p->tls);
}
nni_reap(&p->reap, tlstran_pipe_fini, p);
}
@@ -210,7 +204,6 @@ tlstran_pipe_conn_cancel(nni_aio *aio, void *arg, int rv)
p->useraio = NULL;
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_aio_close(p->rslvaio);
nni_aio_finish_error(aio, rv);
tlstran_pipe_reap(p);
}
@@ -218,33 +211,6 @@ tlstran_pipe_conn_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-tlstran_pipe_rslv_cb(void *arg)
-{
- tlstran_pipe *p = arg;
- tlstran_ep * ep = p->ep;
- nni_aio * aio = p->rslvaio;
- nni_aio * uaio;
- int rv;
-
- nni_mtx_lock(&ep->mtx);
- if ((uaio = p->useraio) == NULL) {
- nni_mtx_unlock(&ep->mtx);
- tlstran_pipe_reap(p);
- return;
- }
-
- if ((rv = nni_aio_result(aio)) != 0) {
- p->useraio = NULL;
- nni_mtx_unlock(&ep->mtx);
- nni_aio_finish_error(uaio, rv);
- tlstran_pipe_reap(p);
- return;
- }
- nng_tls_dialer_dial(ep->dialer, &p->sa, p->connaio);
- nni_mtx_unlock(&ep->mtx);
-}
-
-static void
tlstran_pipe_conn_cb(void *arg)
{
tlstran_pipe *p = arg;
@@ -288,7 +254,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);
- nng_tls_send(p->tls, p->negoaio);
+ nng_stream_send(p->tls, p->negoaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -325,7 +291,7 @@ tlstran_pipe_nego_cb(void *arg)
iov.iov_buf = &p->txlen[p->gottxhead];
nni_aio_set_iov(aio, 1, &iov);
// send it down...
- nng_tls_send(p->tls, aio);
+ nng_stream_send(p->tls, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -334,7 +300,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);
- nng_tls_recv(p->tls, aio);
+ nng_stream_recv(p->tls, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -390,7 +356,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) {
- nng_tls_send(p->tls, txaio);
+ nng_stream_send(p->tls, txaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -426,7 +392,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.
- nng_tls_recv(p->tls, rxaio);
+ nng_stream_recv(p->tls, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -458,7 +424,7 @@ tlstran_pipe_recv_cb(void *arg)
iov.iov_len = (size_t) len;
nni_aio_set_iov(rxaio, 1, &iov);
- nng_tls_recv(p->tls, rxaio);
+ nng_stream_recv(p->tls, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -548,7 +514,7 @@ tlstran_pipe_send_start(tlstran_pipe *p)
}
nni_aio_set_iov(txaio, niov, iov);
- nng_tls_send(p->tls, txaio);
+ nng_stream_send(p->tls, txaio);
}
static void
@@ -609,7 +575,7 @@ tlstran_pipe_recv_start(tlstran_pipe *p)
iov.iov_len = sizeof(p->rxlen);
nni_aio_set_iov(rxaio, 1, &iov);
- nng_tls_recv(p->tls, rxaio);
+ nng_stream_recv(p->tls, rxaio);
}
static void
@@ -654,8 +620,8 @@ tlstran_ep_fini(void *arg)
nni_mtx_unlock(&ep->mtx);
return;
}
- nng_tls_dialer_free(ep->dialer);
- nng_tls_listener_free(ep->listener);
+ nng_stream_dialer_free(ep->dialer);
+ nng_stream_listener_free(ep->listener);
nni_mtx_unlock(&ep->mtx);
nni_mtx_fini(&ep->mtx);
@@ -672,42 +638,89 @@ tlstran_ep_close(void *arg)
NNI_LIST_FOREACH (&ep->pipes, p) {
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_aio_close(p->rslvaio);
nni_aio_close(p->txaio);
nni_aio_close(p->rxaio);
if (p->tls != NULL) {
- nng_tls_close(p->tls);
+ nng_stream_close(p->tls);
}
}
if (ep->dialer != NULL) {
- nng_tls_dialer_close(ep->dialer);
+ nng_stream_dialer_close(ep->dialer);
}
if (ep->listener != NULL) {
- nng_tls_listener_close(ep->listener);
+ nng_stream_listener_close(ep->listener);
}
nni_mtx_unlock(&ep->mtx);
}
+// This parses off the optional source address that this transport uses.
+// The special handling of this URL format is quite honestly an historical
+// mistake, which we would remove if we could.
static int
-tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
+tlstran_url_parse_source(nni_url *url, nng_sockaddr *sa, const nni_url *surl)
{
- tlstran_ep * ep;
- int rv;
- uint16_t af;
- char * host;
- nng_sockaddr srcsa;
- nni_sock * sock = nni_dialer_sock(ndialer);
+ int af;
+ char * semi;
+ char * src;
+ size_t len;
+ int rv;
+ nni_aio *aio;
- if (strcmp(url->u_scheme, "tls+tcp") == 0) {
+ // We modify the URL. This relies on the fact that the underlying
+ // transport does not free this, so we can just use references.
+
+ url->u_scheme = surl->u_scheme;
+ url->u_port = surl->u_port;
+ url->u_hostname = surl->u_hostname;
+
+ if ((semi = strchr(url->u_hostname, ';')) == NULL) {
+ memset(sa, 0, sizeof(*sa));
+ return (0);
+ }
+
+ len = (size_t)(semi - url->u_hostname);
+ url->u_hostname = semi + 1;
+
+ if (strcmp(surl->u_scheme, "tls+tcp") == 0) {
af = NNG_AF_UNSPEC;
- } else if (strcmp(url->u_scheme, "tls+tcp4") == 0) {
+ } else if (strcmp(surl->u_scheme, "tls+tcp4") == 0) {
af = NNG_AF_INET;
- } else if (strcmp(url->u_scheme, "tls+tcp6") == 0) {
+ } else if (strcmp(surl->u_scheme, "tls+tcp6") == 0) {
af = NNG_AF_INET6;
} else {
return (NNG_EADDRINVAL);
}
+ if ((src = nni_alloc(len + 1)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ memcpy(src, surl->u_hostname, len);
+ src[len] = '\0';
+
+ if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
+ nni_free(src, len + 1);
+ return (rv);
+ }
+
+ nni_tcp_resolv(src, 0, af, 1, aio);
+ nni_aio_wait(aio);
+ if ((rv = nni_aio_result(aio)) == 0) {
+ nni_aio_get_sockaddr(aio, sa);
+ }
+ nni_aio_fini(aio);
+ nni_free(src, len + 1);
+ return (rv);
+}
+
+static int
+tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
+{
+ tlstran_ep * ep;
+ int rv;
+ nng_sockaddr srcsa;
+ nni_sock * sock = nni_dialer_sock(ndialer);
+ nni_url myurl;
+
// Check for invalid URL components.
if ((strlen(url->u_path) != 0) && (strcmp(url->u_path, "/") != 0)) {
return (NNG_EADDRINVAL);
@@ -717,6 +730,11 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
(strlen(url->u_port) == 0)) {
return (NNG_EADDRINVAL);
}
+
+ if ((rv = tlstran_url_parse_source(&myurl, &srcsa, url)) != 0) {
+ return (NNG_EADDRINVAL);
+ }
+
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
@@ -726,56 +744,20 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *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.
- if ((host = strchr(url->u_hostname, ';')) != NULL) {
- size_t len;
- char * src = NULL;
- nni_aio *aio;
- len = (uintptr_t) host - (uintptr_t) url->u_hostname;
- host++;
- if ((len < 2) || (strlen(host) == 0)) {
- tlstran_ep_fini(ep);
- return (NNG_EADDRINVAL);
- }
- if ((src = nni_alloc(len + 1)) == NULL) {
- tlstran_ep_fini(ep);
- return (NNG_ENOMEM);
- }
- memcpy(src, url->u_hostname, len);
- src[len] = 0;
-
- if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
- tlstran_ep_fini(ep);
- nni_strfree(src);
- return (rv);
- }
- nni_aio_set_input(aio, 0, &srcsa);
- nni_tcp_resolv(src, 0, af, 1, aio);
- nni_aio_wait(aio);
- rv = nni_aio_result(aio);
- nni_aio_fini(aio);
- nni_strfree(src);
- ep->host = host;
- } else {
- srcsa.s_family = NNG_AF_UNSPEC;
- ep->host = url->u_hostname;
- rv = 0;
+ if ((rv != 0) ||
+ ((rv = nng_stream_dialer_alloc_url(&ep->dialer, &myurl)) != 0)) {
+ tlstran_ep_fini(ep);
+ return (rv);
}
-
- 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)) {
+ if ((srcsa.s_family != NNG_AF_UNSPEC) &&
+ ((rv = nni_stream_dialer_setx(ep->dialer, NNG_OPT_LOCADDR, &srcsa,
+ sizeof(srcsa), NNI_TYPE_SOCKADDR)) != 0)) {
tlstran_ep_fini(ep);
return (rv);
}
-
*dp = ep;
return (0);
}
@@ -841,9 +823,11 @@ tlstran_ep_init_listener(void **lp, nni_url *url, nni_listener *nlistener)
rv = nni_aio_result(aio);
nni_aio_fini(aio);
- 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)) {
+ if ((rv != 0) ||
+ ((rv = nng_stream_listener_alloc_url(&ep->listener, url)) != 0) ||
+ ((rv = nni_stream_listener_setx(ep->listener,
+ NNG_OPT_TLS_AUTH_MODE, &ep->authmode, sizeof(ep->authmode),
+ NNI_TYPE_INT32)) != 0)) {
tlstran_ep_fini(ep);
return (rv);
}
@@ -876,8 +860,7 @@ tlstran_ep_connect(void *arg, nni_aio *aio)
return;
}
p->useraio = aio;
- nni_aio_set_input(p->rslvaio, 0, &p->sa);
- nni_tcp_resolv(ep->host, ep->url->u_port, ep->af, 0, p->rslvaio);
+ nng_stream_dialer_dial(ep->dialer, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -888,7 +871,7 @@ tlstran_ep_bind(void *arg)
int rv;
nni_mtx_lock(&ep->mtx);
- rv = nng_tls_listener_listen(ep->listener, &ep->sa);
+ rv = nng_stream_listener_listen(ep->listener);
nni_mtx_unlock(&ep->mtx);
return (rv);
@@ -919,7 +902,7 @@ tlstran_ep_accept(void *arg, nni_aio *aio)
}
p->useraio = aio;
- nng_tls_listener_accept(ep->listener, p->connaio);
+ nng_stream_listener_accept(ep->listener, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -929,8 +912,7 @@ tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
tlstran_ep *ep = arg;
size_t val;
int rv;
- if (((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) &&
- (ep != NULL)) {
+ if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {
nni_mtx_lock(&ep->mtx);
ep->rcvmax = val;
nni_mtx_unlock(&ep->mtx);
@@ -963,7 +945,7 @@ tlstran_ep_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
if (ep->dialer != NULL) {
return (nni_copyout_str(ep->url->u_rawurl, v, szp, t));
}
- rv = nni_tls_listener_getopt(
+ rv = nni_stream_listener_getx(
ep->listener, NNG_OPT_LOCADDR, &sa, &sz, NNI_TYPE_SOCKADDR);
if (rv != 0) {
return (rv);
@@ -990,12 +972,19 @@ tlstran_pipe_getopt(
tlstran_pipe *p = arg;
int rv;
- if ((rv = nni_tls_get(p->tls, name, buf, szp, t)) == NNG_ENOTSUP) {
+ if ((rv = nni_stream_getx(p->tls, name, buf, szp, t)) == NNG_ENOTSUP) {
rv = nni_getopt(tlstran_pipe_opts, name, p, buf, szp, t);
}
return (rv);
}
+static int
+tlstran_check_recvmaxsz(const void *v, size_t sz, nni_type t)
+{
+ size_t val;
+ return (nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t));
+}
+
static nni_tran_pipe_ops tlstran_pipe_ops = {
.p_init = tlstran_pipe_init,
.p_fini = tlstran_pipe_fini,
@@ -1023,6 +1012,16 @@ static nni_option tlstran_ep_options[] = {
},
};
+static nni_chkoption tlstran_checkopts[] = {
+ {
+ .o_name = NNG_OPT_RECVMAXSZ,
+ .o_check = tlstran_check_recvmaxsz,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
static int
tlstran_dialer_getopt(
void *arg, const char *name, void *buf, size_t *szp, nni_type t)
@@ -1030,7 +1029,7 @@ tlstran_dialer_getopt(
int rv;
tlstran_ep *ep = arg;
- rv = nni_tls_dialer_getopt(ep->dialer, name, buf, szp, t);
+ rv = nni_stream_dialer_getx(ep->dialer, name, buf, szp, t);
if (rv == NNG_ENOTSUP) {
rv = nni_getopt(tlstran_ep_options, name, ep, buf, szp, t);
}
@@ -1044,7 +1043,7 @@ tlstran_dialer_setopt(
int rv;
tlstran_ep *ep = arg;
- rv = nni_tls_dialer_setopt(
+ rv = nni_stream_dialer_setx(
ep != NULL ? ep->dialer : NULL, name, buf, sz, t);
if (rv == NNG_ENOTSUP) {
rv = nni_setopt(tlstran_ep_options, name, ep, buf, sz, t);
@@ -1059,7 +1058,7 @@ tlstran_listener_getopt(
int rv;
tlstran_ep *ep = arg;
- rv = nni_tls_listener_getopt(ep->listener, name, buf, szp, t);
+ rv = nni_stream_listener_getx(ep->listener, name, buf, szp, t);
if (rv == NNG_ENOTSUP) {
rv = nni_getopt(tlstran_ep_options, name, ep, buf, szp, t);
}
@@ -1073,7 +1072,7 @@ tlstran_listener_setopt(
int rv;
tlstran_ep *ep = arg;
- rv = nni_tls_listener_setopt(
+ rv = nni_stream_listener_setx(
ep != NULL ? ep->listener : NULL, name, buf, sz, t);
if (rv == NNG_ENOTSUP) {
rv = nni_setopt(tlstran_ep_options, name, ep, buf, sz, t);
@@ -1081,6 +1080,17 @@ tlstran_listener_setopt(
return (rv);
}
+static int
+tlstran_checkopt(const char *name, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ rv = nni_chkopt(tlstran_checkopts, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_stream_checkopt("tls+tcp", name, buf, sz, t);
+ }
+ return (rv);
+}
+
static nni_tran_dialer_ops tlstran_dialer_ops = {
.d_init = tlstran_ep_init_dialer,
.d_fini = tlstran_ep_fini,
@@ -1108,6 +1118,7 @@ static nni_tran tls_tran = {
.tran_pipe = &tlstran_pipe_ops,
.tran_init = tlstran_init,
.tran_fini = tlstran_fini,
+ .tran_checkopt = tlstran_checkopt,
};
static nni_tran tls4_tran = {
@@ -1118,6 +1129,7 @@ static nni_tran tls4_tran = {
.tran_pipe = &tlstran_pipe_ops,
.tran_init = tlstran_init,
.tran_fini = tlstran_fini,
+ .tran_checkopt = tlstran_checkopt,
};
static nni_tran tls6_tran = {
@@ -1128,6 +1140,7 @@ static nni_tran tls6_tran = {
.tran_pipe = &tlstran_pipe_ops,
.tran_init = tlstran_init,
.tran_fini = tlstran_fini,
+ .tran_checkopt = tlstran_checkopt,
};
int