aboutsummaryrefslogtreecommitdiff
path: root/src/transport
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
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')
-rw-r--r--src/transport/ipc/ipc.c142
-rw-r--r--src/transport/tcp/tcp.c363
-rw-r--r--src/transport/tls/tls.c289
-rw-r--r--src/transport/ws/websocket.c910
4 files changed, 569 insertions, 1135 deletions
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 609b1811..e0d83be0 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.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
@@ -27,7 +27,7 @@ typedef struct ipctran_ep ipctran_ep;
// ipc_pipe is one end of an IPC connection.
struct ipctran_pipe {
- nni_ipc_conn * conn;
+ nng_stream * conn;
uint16_t peer;
uint16_t proto;
size_t rcvmax;
@@ -58,17 +58,17 @@ struct ipctran_pipe {
};
struct ipctran_ep {
- nni_mtx mtx;
- nni_sockaddr sa;
- size_t rcvmax;
- uint16_t proto;
- nni_list pipes;
- bool fini;
- nni_ipc_dialer * dialer;
- nni_ipc_listener *listener;
- nni_reap_item reap;
- nni_dialer * ndialer;
- nni_listener * nlistener;
+ nni_mtx mtx;
+ nni_sockaddr sa;
+ size_t rcvmax;
+ uint16_t proto;
+ nni_list pipes;
+ bool fini;
+ nng_stream_dialer * dialer;
+ nng_stream_listener *listener;
+ nni_reap_item reap;
+ nni_dialer * ndialer;
+ nni_listener * nlistener;
};
static void ipctran_pipe_send_start(ipctran_pipe *);
@@ -104,7 +104,7 @@ ipctran_pipe_close(void *arg)
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_ipc_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
static void
@@ -145,9 +145,7 @@ ipctran_pipe_fini(void *arg)
nni_aio_fini(p->txaio);
nni_aio_fini(p->negoaio);
nni_aio_fini(p->connaio);
- if (p->conn != NULL) {
- nni_ipc_conn_fini(p->conn);
- }
+ nng_stream_free(p->conn);
if (p->rxmsg) {
nni_msg_free(p->rxmsg);
}
@@ -160,7 +158,7 @@ ipctran_pipe_reap(ipctran_pipe *p)
{
if (!nni_atomic_flag_test_and_set(&p->reaped)) {
if (p->conn != NULL) {
- nni_ipc_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
nni_reap(&p->reap, ipctran_pipe_fini, p);
}
@@ -195,7 +193,6 @@ ipctran_pipe_alloc(ipctran_pipe **pipep, ipctran_ep *ep)
p->proto = ep->proto;
p->rcvmax = ep->rcvmax;
- p->sa = ep->sa;
p->ep = ep;
*pipep = p;
@@ -244,7 +241,7 @@ ipctran_pipe_conn_cb(void *arg)
iov.iov_len = 8;
iov.iov_buf = &p->txhead[0];
nni_aio_set_iov(p->negoaio, 1, &iov);
- nni_ipc_conn_send(p->conn, p->negoaio);
+ nng_stream_send(p->conn, p->negoaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -278,7 +275,7 @@ ipctran_pipe_nego_cb(void *arg)
iov.iov_buf = &p->txhead[p->gottxhead];
nni_aio_set_iov(aio, 1, &iov);
// send it down...
- nni_ipc_conn_send(p->conn, aio);
+ nng_stream_send(p->conn, aio);
nni_mtx_unlock(&p->ep->mtx);
return;
}
@@ -287,7 +284,7 @@ ipctran_pipe_nego_cb(void *arg)
iov.iov_len = p->wantrxhead - p->gotrxhead;
iov.iov_buf = &p->rxhead[p->gotrxhead];
nni_aio_set_iov(aio, 1, &iov);
- nni_ipc_conn_recv(p->conn, aio);
+ nng_stream_recv(p->conn, aio);
nni_mtx_unlock(&p->ep->mtx);
return;
}
@@ -343,7 +340,7 @@ ipctran_pipe_send_cb(void *arg)
n = nni_aio_count(txaio);
nni_aio_iov_advance(txaio, n);
if (nni_aio_iov_count(txaio) != 0) {
- nni_ipc_conn_send(p->conn, txaio);
+ nng_stream_send(p->conn, txaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -385,7 +382,7 @@ ipctran_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_ipc_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -429,7 +426,7 @@ ipctran_pipe_recv_cb(void *arg)
iov.iov_len = (size_t) len;
nni_aio_set_iov(rxaio, 1, &iov);
- nni_ipc_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -531,7 +528,7 @@ ipctran_pipe_send_start(ipctran_pipe *p)
niov++;
}
nni_aio_set_iov(txaio, niov, iov);
- nni_ipc_conn_send(p->conn, txaio);
+ nng_stream_send(p->conn, txaio);
}
static void
@@ -604,7 +601,7 @@ ipctran_pipe_recv_start(ipctran_pipe *p)
iov.iov_len = sizeof(p->rxhead);
nni_aio_set_iov(rxaio, 1, &iov);
- nni_ipc_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
}
static void
@@ -670,12 +667,8 @@ ipctran_ep_fini(void *arg)
nni_mtx_unlock(&ep->mtx);
return;
}
- if (ep->dialer != NULL) {
- nni_ipc_dialer_fini(ep->dialer);
- }
- if (ep->listener != NULL) {
- nni_ipc_listener_fini(ep->listener);
- }
+ nng_stream_dialer_free(ep->dialer);
+ nng_stream_listener_free(ep->listener);
nni_mtx_unlock(&ep->mtx);
nni_mtx_fini(&ep->mtx);
NNI_FREE_STRUCT(ep);
@@ -694,14 +687,14 @@ ipctran_ep_close(void *arg)
nni_aio_close(p->txaio);
nni_aio_close(p->rxaio);
if (p->conn != NULL) {
- nni_ipc_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
}
if (ep->dialer != NULL) {
- nni_ipc_dialer_close(ep->dialer);
+ nng_stream_dialer_close(ep->dialer);
}
if (ep->listener != NULL) {
- nni_ipc_listener_close(ep->listener);
+ nng_stream_listener_close(ep->listener);
}
nni_mtx_unlock(&ep->mtx);
}
@@ -711,7 +704,6 @@ ipctran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
{
ipctran_ep *ep;
int rv;
- size_t sz;
nni_sock * sock = nni_dialer_sock(ndialer);
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
@@ -720,17 +712,10 @@ ipctran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
nni_mtx_init(&ep->mtx);
NNI_LIST_INIT(&ep->pipes, ipctran_pipe, node);
- sz = sizeof(ep->sa.s_ipc.sa_path);
- ep->sa.s_ipc.sa_family = NNG_AF_IPC;
- ep->proto = nni_sock_proto_id(sock);
- ep->ndialer = ndialer;
-
- if (nni_strlcpy(ep->sa.s_ipc.sa_path, url->u_path, sz) >= sz) {
- ipctran_ep_fini(ep);
- return (NNG_EADDRINVAL);
- }
+ ep->proto = nni_sock_proto_id(sock);
+ ep->ndialer = ndialer;
- if ((rv = nni_ipc_dialer_init(&ep->dialer)) != 0) {
+ if ((rv = nng_stream_dialer_alloc_url(&ep->dialer, url)) != 0) {
ipctran_ep_fini(ep);
return (rv);
}
@@ -744,7 +729,6 @@ ipctran_ep_init_listener(void **dp, nni_url *url, nni_listener *nlistener)
{
ipctran_ep *ep;
int rv;
- size_t sz;
nni_sock * sock = nni_listener_sock(nlistener);
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
@@ -753,17 +737,10 @@ ipctran_ep_init_listener(void **dp, nni_url *url, nni_listener *nlistener)
nni_mtx_init(&ep->mtx);
NNI_LIST_INIT(&ep->pipes, ipctran_pipe, node);
- sz = sizeof(ep->sa.s_ipc.sa_path);
- ep->sa.s_ipc.sa_family = NNG_AF_IPC;
- ep->proto = nni_sock_proto_id(sock);
- ep->nlistener = nlistener;
+ ep->proto = nni_sock_proto_id(sock);
+ ep->nlistener = nlistener;
- if (nni_strlcpy(ep->sa.s_ipc.sa_path, url->u_path, sz) >= sz) {
- ipctran_ep_fini(ep);
- return (NNG_EADDRINVAL);
- }
-
- if ((rv = nni_ipc_listener_init(&ep->listener)) != 0) {
+ if ((rv = nng_stream_listener_alloc_url(&ep->listener, url)) != 0) {
ipctran_ep_fini(ep);
return (rv);
}
@@ -797,7 +774,7 @@ ipctran_ep_connect(void *arg, nni_aio *aio)
return;
}
p->useraio = aio;
- nni_ipc_dialer_dial(ep->dialer, &p->sa, p->connaio);
+ nng_stream_dialer_dial(ep->dialer, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -839,7 +816,7 @@ ipctran_ep_bind(void *arg)
int rv;
nni_mtx_lock(&ep->mtx);
- rv = nni_ipc_listener_listen(ep->listener, &ep->sa);
+ rv = nng_stream_listener_listen(ep->listener);
nni_mtx_unlock(&ep->mtx);
return (rv);
}
@@ -869,7 +846,7 @@ ipctran_ep_accept(void *arg, nni_aio *aio)
return;
}
p->useraio = aio;
- nni_ipc_listener_accept(ep->listener, p->connaio);
+ nng_stream_listener_accept(ep->listener, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -879,8 +856,7 @@ ipctran_pipe_getopt(
{
ipctran_pipe *p = arg;
- // We defer to the platform getopt code for IPC connections.
- return (nni_ipc_conn_getopt(p->conn, name, buf, szp, t));
+ return (nni_stream_getx(p->conn, name, buf, szp, t));
}
static nni_tran_pipe_ops ipctran_pipe_ops = {
@@ -915,7 +891,7 @@ ipctran_dialer_getopt(
rv = nni_getopt(ipctran_ep_options, name, ep, buf, szp, t);
if (rv == NNG_ENOTSUP) {
- rv = nni_ipc_dialer_getopt(ep->dialer, name, buf, szp, t);
+ rv = nni_stream_dialer_getx(ep->dialer, name, buf, szp, t);
}
return (rv);
}
@@ -929,8 +905,7 @@ ipctran_dialer_setopt(
rv = nni_setopt(ipctran_ep_options, name, ep, buf, sz, t);
if (rv == NNG_ENOTSUP) {
- rv = nni_ipc_dialer_setopt(
- ep != NULL ? ep->dialer : NULL, name, buf, sz, t);
+ rv = nni_stream_dialer_setx(ep->dialer, name, buf, sz, t);
}
return (rv);
}
@@ -944,7 +919,7 @@ ipctran_listener_getopt(
rv = nni_getopt(ipctran_ep_options, name, ep, buf, szp, t);
if (rv == NNG_ENOTSUP) {
- rv = nni_ipc_listener_getopt(ep->listener, name, buf, szp, t);
+ rv = nni_stream_listener_getx(ep->listener, name, buf, szp, t);
}
return (rv);
}
@@ -958,8 +933,34 @@ ipctran_listener_setopt(
rv = nni_setopt(ipctran_ep_options, name, ep, buf, sz, t);
if (rv == NNG_ENOTSUP) {
- rv = nni_ipc_listener_setopt(
- ep != NULL ? ep->listener : NULL, name, buf, sz, t);
+ rv = nni_stream_listener_setx(ep->listener, name, buf, sz, t);
+ }
+ return (rv);
+}
+
+static int
+ipctran_check_recvmaxsz(const void *v, size_t sz, nni_type t)
+{
+ return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
+}
+
+static nni_chkoption ipctran_checkopts[] = {
+ {
+ .o_name = NNG_OPT_RECVMAXSZ,
+ .o_check = ipctran_check_recvmaxsz,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+static int
+ipctran_checkopt(const char *name, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ rv = nni_chkopt(ipctran_checkopts, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_stream_checkopt("ipc", name, buf, sz, t);
}
return (rv);
}
@@ -991,6 +992,7 @@ static nni_tran ipc_tran = {
.tran_pipe = &ipctran_pipe_ops,
.tran_init = ipctran_init,
.tran_fini = ipctran_fini,
+ .tran_checkopt = ipctran_checkopt,
};
int
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index 30695918..3d757ee7 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.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
@@ -14,6 +14,7 @@
#include <string.h>
#include "core/nng_impl.h"
+#include "core/tcp.h"
// TCP transport. Platform specific TCP operations must be
// supplied as well.
@@ -23,19 +24,16 @@ typedef struct tcptran_ep tcptran_ep;
// tcp_pipe is one end of a TCP connection.
struct tcptran_pipe {
- nni_tcp_conn * conn;
+ nng_stream * conn;
nni_pipe * npipe;
uint16_t peer;
uint16_t proto;
size_t rcvmax;
- bool nodelay;
- bool keepalive;
bool closed;
nni_list_node node;
tcptran_ep * ep;
nni_atomic_flag reaped;
nni_reap_item reap;
- nni_sockaddr sa;
uint8_t txlen[sizeof(uint64_t)];
uint8_t rxlen[sizeof(uint64_t)];
size_t gottxhead;
@@ -49,30 +47,25 @@ struct tcptran_pipe {
nni_aio * rxaio;
nni_aio * negoaio;
nni_aio * connaio;
- nni_aio * rslvaio;
nni_msg * rxmsg;
nni_mtx mtx;
};
struct tcptran_ep {
- nni_mtx mtx;
- uint16_t af;
- uint16_t proto;
- size_t rcvmax;
- bool nodelay;
- bool keepalive;
- bool fini;
- nni_url * url;
- const char * host; // for dialers
- nng_sockaddr src;
- nng_sockaddr sa;
- nng_sockaddr bsa;
- nni_list pipes;
- nni_reap_item reap;
- nni_tcp_dialer * dialer;
- nni_tcp_listener *listener;
- nni_dialer * ndialer;
- nni_listener * nlistener;
+ nni_mtx mtx;
+ uint16_t af;
+ uint16_t proto;
+ size_t rcvmax;
+ bool fini;
+ nni_url * url;
+ const char * host; // for dialers
+ nng_sockaddr src;
+ nni_list pipes;
+ nni_reap_item reap;
+ nng_stream_dialer * dialer;
+ nng_stream_listener *listener;
+ nni_dialer * ndialer;
+ nni_listener * nlistener;
};
static void tcptran_pipe_send_start(tcptran_pipe *);
@@ -81,7 +74,6 @@ static void tcptran_pipe_send_cb(void *);
static void tcptran_pipe_recv_cb(void *);
static void tcptran_pipe_conn_cb(void *);
static void tcptran_pipe_nego_cb(void *);
-static void tcptran_pipe_rslv_cb(void *);
static void tcptran_ep_fini(void *);
static int
@@ -108,9 +100,8 @@ tcptran_pipe_close(void *arg)
nni_aio_close(p->txaio);
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_aio_close(p->rslvaio);
- nni_tcp_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
static void
@@ -122,7 +113,6 @@ tcptran_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
@@ -153,10 +143,7 @@ tcptran_pipe_fini(void *arg)
nni_aio_fini(p->txaio);
nni_aio_fini(p->negoaio);
nni_aio_fini(p->connaio);
- nni_aio_fini(p->rslvaio);
- if (p->conn != NULL) {
- nni_tcp_conn_fini(p->conn);
- }
+ nng_stream_free(p->conn);
nni_msg_free(p->rxmsg);
nni_mtx_fini(&p->mtx);
NNI_FREE_STRUCT(p);
@@ -167,7 +154,7 @@ tcptran_pipe_reap(tcptran_pipe *p)
{
if (!nni_atomic_flag_test_and_set(&p->reaped)) {
if (p->conn != NULL) {
- nni_tcp_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
nni_reap(&p->reap, tcptran_pipe_fini, p);
}
@@ -185,7 +172,6 @@ tcptran_pipe_alloc(tcptran_pipe **pipep, tcptran_ep *ep)
nni_mtx_init(&p->mtx);
if (((rv = nni_aio_init(&p->txaio, tcptran_pipe_send_cb, p)) != 0) ||
((rv = nni_aio_init(&p->rxaio, tcptran_pipe_recv_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->rslvaio, tcptran_pipe_rslv_cb, p)) != 0) ||
((rv = nni_aio_init(&p->connaio, tcptran_pipe_conn_cb, p)) != 0) ||
((rv = nni_aio_init(&p->negoaio, tcptran_pipe_nego_cb, p)) != 0)) {
tcptran_pipe_fini(p);
@@ -196,12 +182,10 @@ tcptran_pipe_alloc(tcptran_pipe **pipep, tcptran_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);
}
@@ -215,7 +199,6 @@ tcptran_pipe_conn_cancel(nni_aio *aio, void *arg, int rv)
if (aio == p->useraio) {
nni_aio_close(p->negoaio);
nni_aio_close(p->connaio);
- nni_aio_close(p->rslvaio);
p->useraio = NULL;
nni_aio_finish_error(aio, rv);
tcptran_pipe_reap(p);
@@ -224,33 +207,6 @@ tcptran_pipe_conn_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-tcptran_pipe_rslv_cb(void *arg)
-{
- tcptran_pipe *p = arg;
- tcptran_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);
- tcptran_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);
- tcptran_pipe_reap(p);
- return;
- }
-
- nni_tcp_dialer_dial(ep->dialer, &p->sa, p->connaio);
- nni_mtx_unlock(&ep->mtx);
-}
-
-static void
tcptran_pipe_conn_cb(void *arg)
{
tcptran_pipe *p = arg;
@@ -293,7 +249,7 @@ tcptran_pipe_conn_cb(void *arg)
iov.iov_len = 8;
iov.iov_buf = &p->txlen[0];
nni_aio_set_iov(p->negoaio, 1, &iov);
- nni_tcp_conn_send(p->conn, p->negoaio);
+ nng_stream_send(p->conn, p->negoaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -330,7 +286,7 @@ tcptran_pipe_nego_cb(void *arg)
iov.iov_buf = &p->txlen[p->gottxhead];
// send it down...
nni_aio_set_iov(aio, 1, &iov);
- nni_tcp_conn_send(p->conn, aio);
+ nng_stream_send(p->conn, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -339,7 +295,7 @@ tcptran_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_tcp_conn_recv(p->conn, aio);
+ nng_stream_recv(p->conn, aio);
nni_mtx_unlock(&ep->mtx);
return;
}
@@ -354,10 +310,6 @@ tcptran_pipe_nego_cb(void *arg)
NNI_GET16(&p->rxlen[4], p->peer);
p->useraio = NULL;
- (void) nni_tcp_conn_setopt(p->conn, NNG_OPT_TCP_NODELAY, &p->nodelay,
- sizeof(p->nodelay), NNI_TYPE_BOOL);
- (void) nni_tcp_conn_setopt(p->conn, NNG_OPT_TCP_KEEPALIVE,
- &p->keepalive, sizeof(p->keepalive), NNI_TYPE_BOOL);
nni_mtx_unlock(&ep->mtx);
@@ -400,7 +352,7 @@ tcptran_pipe_send_cb(void *arg)
n = nni_aio_count(txaio);
nni_aio_iov_advance(txaio, n);
if (nni_aio_iov_count(txaio) > 0) {
- nni_tcp_conn_send(p->conn, txaio);
+ nng_stream_send(p->conn, txaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -437,7 +389,7 @@ tcptran_pipe_recv_cb(void *arg)
n = nni_aio_count(rxaio);
nni_aio_iov_advance(rxaio, n);
if (nni_aio_iov_count(rxaio) > 0) {
- nni_tcp_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -469,7 +421,7 @@ tcptran_pipe_recv_cb(void *arg)
iov.iov_len = (size_t) len;
nni_aio_set_iov(rxaio, 1, &iov);
- nni_tcp_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -566,7 +518,7 @@ tcptran_pipe_send_start(tcptran_pipe *p)
niov++;
}
nni_aio_set_iov(txaio, niov, iov);
- nni_tcp_conn_send(p->conn, txaio);
+ nng_stream_send(p->conn, txaio);
}
static void
@@ -639,7 +591,7 @@ tcptran_pipe_recv_start(tcptran_pipe *p)
iov.iov_len = sizeof(p->rxlen);
nni_aio_set_iov(rxaio, 1, &iov);
- nni_tcp_conn_recv(p->conn, rxaio);
+ nng_stream_recv(p->conn, rxaio);
}
static void
@@ -678,7 +630,7 @@ tcptran_pipe_getopt(
void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
tcptran_pipe *p = arg;
- return (nni_tcp_conn_getopt(p->conn, name, buf, szp, t));
+ return (nni_stream_getx(p->conn, name, buf, szp, t));
}
static void
@@ -692,12 +644,8 @@ tcptran_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_stream_dialer_free(ep->dialer);
+ nng_stream_listener_free(ep->listener);
nni_mtx_unlock(&ep->mtx);
nni_mtx_fini(&ep->mtx);
NNI_FREE_STRUCT(ep);
@@ -713,41 +661,89 @@ tcptran_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->conn != NULL) {
- nni_tcp_conn_close(p->conn);
+ nng_stream_close(p->conn);
}
}
if (ep->dialer != NULL) {
- nni_tcp_dialer_close(ep->dialer);
+ nng_stream_dialer_close(ep->dialer);
}
if (ep->listener != NULL) {
- nni_tcp_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
-tcptran_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
+tcptran_url_parse_source(nni_url *url, nng_sockaddr *sa, const nni_url *surl)
{
- tcptran_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;
+
+ // 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);
+ }
- if (strcmp(url->u_scheme, "tcp") == 0) {
+ len = (size_t)(semi - url->u_hostname);
+ url->u_hostname = semi + 1;
+
+ if (strcmp(surl->u_scheme, "tcp") == 0) {
af = NNG_AF_UNSPEC;
- } else if (strcmp(url->u_scheme, "tcp4") == 0) {
+ } else if (strcmp(surl->u_scheme, "tcp4") == 0) {
af = NNG_AF_INET;
- } else if (strcmp(url->u_scheme, "tcp6") == 0) {
+ } else if (strcmp(surl->u_scheme, "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
+tcptran_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
+{
+ tcptran_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);
@@ -758,62 +754,27 @@ tcptran_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
return (NNG_EADDRINVAL);
}
+ if ((rv = tcptran_url_parse_source(&myurl, &srcsa, url)) != 0) {
+ return (NNG_EADDRINVAL);
+ }
+
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
nni_mtx_init(&ep->mtx);
NNI_LIST_INIT(&ep->pipes, tcptran_pipe, node);
- ep->af = af;
- ep->proto = nni_sock_proto_id(sock);
- ep->nodelay = true;
- ep->keepalive = false;
- ep->url = url;
- 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)) {
- tcptran_ep_fini(ep);
- return (NNG_EADDRINVAL);
- }
- if ((src = nni_alloc(len + 1)) == NULL) {
- tcptran_ep_fini(ep);
- return (NNG_ENOMEM);
- }
- memcpy(src, url->u_hostname, len);
- src[len] = 0;
-
- if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
- tcptran_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;
- }
+ ep->proto = nni_sock_proto_id(sock);
+ ep->url = url;
+ ep->ndialer = ndialer;
- if ((rv != 0) || ((rv = nni_tcp_dialer_init(&ep->dialer)) != 0)) {
+ if ((rv != 0) ||
+ ((rv = nng_stream_dialer_alloc_url(&ep->dialer, &myurl)) != 0)) {
tcptran_ep_fini(ep);
return (rv);
}
if ((srcsa.s_family != NNG_AF_UNSPEC) &&
- ((rv = nni_tcp_dialer_setopt(ep->dialer, NNG_OPT_LOCADDR, &srcsa,
+ ((rv = nni_stream_dialer_setx(ep->dialer, NNG_OPT_LOCADDR, &srcsa,
sizeof(srcsa), NNI_TYPE_SOCKADDR)) != 0)) {
tcptran_ep_fini(ep);
return (rv);
@@ -826,21 +787,8 @@ tcptran_listener_init(void **lp, nni_url *url, nni_listener *nlistener)
{
tcptran_ep *ep;
int rv;
- char * host;
- nni_aio * aio;
- uint16_t af;
nni_sock * sock = nni_listener_sock(nlistener);
- if (strcmp(url->u_scheme, "tcp") == 0) {
- af = NNG_AF_UNSPEC;
- } else if (strcmp(url->u_scheme, "tcp4") == 0) {
- af = NNG_AF_INET;
- } else if (strcmp(url->u_scheme, "tcp6") == 0) {
- af = NNG_AF_INET6;
- } else {
- return (NNG_EADDRINVAL);
- }
-
// Check for invalid URL components.
if ((strlen(url->u_path) != 0) && (strcmp(url->u_path, "/") != 0)) {
return (NNG_EADDRINVAL);
@@ -855,46 +803,14 @@ tcptran_listener_init(void **lp, nni_url *url, nni_listener *nlistener)
}
nni_mtx_init(&ep->mtx);
NNI_LIST_INIT(&ep->pipes, tcptran_pipe, node);
- ep->af = af;
ep->proto = nni_sock_proto_id(sock);
- ep->nodelay = true;
- ep->keepalive = false;
ep->url = url;
ep->nlistener = nlistener;
- if (strlen(url->u_hostname) == 0) {
- host = NULL;
- } else {
- host = url->u_hostname;
- }
-
- // XXX: We are doing lookup at listener initialization. There is
- // a valid argument that this should be done at bind time, but that
- // would require making bind asynchronous. In some ways this would
- // be worse than the cost of just waiting here. We always recommend
- // using local IP addresses rather than names when possible.
-
- if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
+ if ((rv = nng_stream_listener_alloc_url(&ep->listener, url)) != 0) {
tcptran_ep_fini(ep);
return (rv);
}
- nni_aio_set_input(aio, 0, &ep->sa);
- nni_tcp_resolv(host, url->u_port, af, 1, aio);
- nni_aio_wait(aio);
- rv = nni_aio_result(aio);
- nni_aio_fini(aio);
-
- if (rv != 0) {
- tcptran_ep_fini(ep);
- return (rv);
- }
-
- if ((rv = nni_tcp_listener_init(&ep->listener)) != 0) {
- tcptran_ep_fini(ep);
- return (rv);
- }
-
- ep->bsa = ep->sa;
*lp = ep;
return (0);
@@ -917,17 +833,13 @@ tcptran_ep_connect(void *arg, nni_aio *aio)
return;
}
if ((rv = nni_aio_schedule(aio, tcptran_pipe_conn_cancel, p)) != 0) {
- nni_list_remove(&ep->pipes, p);
- p->ep = NULL;
nni_mtx_unlock(&ep->mtx);
nni_aio_finish_error(aio, rv);
tcptran_pipe_reap(p);
return;
}
p->useraio = aio;
- // Start the name resolution before we try connecting.
- 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);
}
@@ -941,16 +853,18 @@ tcptran_ep_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
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;
- rv = nni_tcp_listener_getopt(ep->listener, NNG_OPT_LOCADDR,
- &sa, &sz, NNI_TYPE_SOCKADDR);
+ rv = nng_stream_listener_get_addr(
+ ep->listener, NNG_OPT_LOCADDR, &sa);
if (rv != 0) {
return (rv);
}
nni_ntop(&sa, ipstr, portstr);
- snprintf(ustr, sizeof(ustr), "tcp://%s:%s", ipstr, portstr);
+ snprintf(ustr, sizeof(ustr),
+ sa.s_family == NNG_AF_INET6 ? "tcp://[%s]:%s"
+ : "tcp://%s:%s",
+ ipstr, portstr);
return (nni_copyout_str(ustr, v, szp, t));
}
@@ -995,8 +909,7 @@ tcptran_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_stream_listener_listen(ep->listener);
nni_mtx_unlock(&ep->mtx);
return (rv);
@@ -1027,7 +940,7 @@ tcptran_ep_accept(void *arg, nni_aio *aio)
return;
}
p->useraio = aio;
- nni_tcp_listener_accept(ep->listener, p->connaio);
+ nng_stream_listener_accept(ep->listener, p->connaio);
nni_mtx_unlock(&ep->mtx);
}
@@ -1065,7 +978,7 @@ tcptran_dialer_getopt(
tcptran_ep *ep = arg;
int rv;
- rv = nni_tcp_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(tcptran_ep_opts, name, ep, buf, szp, t);
}
@@ -1079,8 +992,7 @@ tcptran_dialer_setopt(
tcptran_ep *ep = arg;
int rv;
- rv = nni_tcp_dialer_setopt(
- ep != NULL ? ep->dialer : NULL, name, buf, sz, t);
+ rv = nni_stream_dialer_setx(ep->dialer, name, buf, sz, t);
if (rv == NNG_ENOTSUP) {
rv = nni_setopt(tcptran_ep_opts, name, ep, buf, sz, t);
}
@@ -1094,7 +1006,7 @@ tcptran_listener_getopt(
tcptran_ep *ep = arg;
int rv;
- rv = nni_tcp_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(tcptran_ep_opts, name, ep, buf, szp, t);
}
@@ -1108,14 +1020,40 @@ tcptran_listener_setopt(
tcptran_ep *ep = arg;
int rv;
- rv = nni_tcp_listener_setopt(
- ep != NULL ? ep->listener : NULL, name, buf, sz, t);
+ rv = nni_stream_listener_setx(ep->listener, name, buf, sz, t);
if (rv == NNG_ENOTSUP) {
rv = nni_setopt(tcptran_ep_opts, name, ep, buf, sz, t);
}
return (rv);
}
+static int
+tcptran_check_recvmaxsz(const void *v, size_t sz, nni_type t)
+{
+ return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
+}
+
+static nni_chkoption tcptran_checkopts[] = {
+ {
+ .o_name = NNG_OPT_RECVMAXSZ,
+ .o_check = tcptran_check_recvmaxsz,
+ },
+ {
+ .o_name = NULL,
+ },
+};
+
+static int
+tcptran_checkopt(const char *name, const void *buf, size_t sz, nni_type t)
+{
+ int rv;
+ rv = nni_chkopt(tcptran_checkopts, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_stream_checkopt("tcp", name, buf, sz, t);
+ }
+ return (rv);
+}
+
static nni_tran_dialer_ops tcptran_dialer_ops = {
.d_init = tcptran_dialer_init,
.d_fini = tcptran_ep_fini,
@@ -1143,6 +1081,7 @@ static nni_tran tcp_tran = {
.tran_pipe = &tcptran_pipe_ops,
.tran_init = tcptran_init,
.tran_fini = tcptran_fini,
+ .tran_checkopt = tcptran_checkopt,
};
static nni_tran tcp4_tran = {
@@ -1153,6 +1092,7 @@ static nni_tran tcp4_tran = {
.tran_pipe = &tcptran_pipe_ops,
.tran_init = tcptran_init,
.tran_fini = tcptran_fini,
+ .tran_checkopt = tcptran_checkopt,
};
static nni_tran tcp6_tran = {
@@ -1163,6 +1103,7 @@ static nni_tran tcp6_tran = {
.tran_pipe = &tcptran_pipe_ops,
.tran_init = tcptran_init,
.tran_fini = tcptran_fini,
+ .tran_checkopt = tcptran_checkopt,
};
int
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
diff --git a/src/transport/ws/websocket.c b/src/transport/ws/websocket.c
index bf10f7e0..3424480a 100644
--- a/src/transport/ws/websocket.c
+++ b/src/transport/ws/websocket.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
@@ -26,56 +26,43 @@ typedef struct ws_dialer ws_dialer;
typedef struct ws_listener ws_listener;
typedef struct ws_pipe ws_pipe;
-typedef struct ws_hdr {
- nni_list_node node;
- char * name;
- char * value;
-} ws_hdr;
-
struct ws_dialer {
- uint16_t lproto; // local protocol
- uint16_t rproto; // remote protocol
- size_t rcvmax;
- char * prname;
- nni_list aios;
- nni_mtx mtx;
- nni_aio * connaio;
- nni_ws_dialer *dialer;
- nni_list headers; // req headers
- bool started;
- nni_dialer * ndialer;
+ uint16_t lproto; // local protocol
+ uint16_t rproto; // remote protocol
+ nni_list aios;
+ nni_mtx mtx;
+ nni_aio * connaio;
+ nng_stream_dialer *dialer;
+ bool started;
+ nni_dialer * ndialer;
};
struct ws_listener {
- uint16_t lproto; // local protocol
- uint16_t rproto; // remote protocol
- size_t rcvmax;
- char * prname;
- nni_list aios;
- nni_mtx mtx;
- nni_aio * accaio;
- nni_ws_listener *listener;
- nni_list headers; // res headers
- bool started;
- nni_listener * nlistener;
+ uint16_t lproto; // local protocol
+ uint16_t rproto; // remote protocol
+ nni_list aios;
+ nni_mtx mtx;
+ nni_aio * accaio;
+ nng_stream_listener *listener;
+ bool started;
+ nni_listener * nlistener;
};
struct ws_pipe {
- nni_mtx mtx;
- nni_pipe *npipe;
- size_t rcvmax;
- bool closed;
- uint16_t rproto;
- uint16_t lproto;
- nni_aio * user_txaio;
- nni_aio * user_rxaio;
- nni_aio * txaio;
- nni_aio * rxaio;
- nni_ws * ws;
+ nni_mtx mtx;
+ nni_pipe * npipe;
+ bool closed;
+ uint16_t rproto;
+ uint16_t lproto;
+ nni_aio * user_txaio;
+ nni_aio * user_rxaio;
+ nni_aio * txaio;
+ nni_aio * rxaio;
+ nng_stream *ws;
};
static void
-ws_pipe_send_cb(void *arg)
+wstran_pipe_send_cb(void *arg)
{
ws_pipe *p = arg;
nni_aio *taio;
@@ -98,7 +85,7 @@ ws_pipe_send_cb(void *arg)
}
static void
-ws_pipe_recv_cb(void *arg)
+wstran_pipe_recv_cb(void *arg)
{
ws_pipe *p = arg;
nni_aio *raio = p->rxaio;
@@ -124,7 +111,7 @@ ws_pipe_recv_cb(void *arg)
}
static void
-ws_pipe_recv_cancel(nni_aio *aio, void *arg, int rv)
+wstran_pipe_recv_cancel(nni_aio *aio, void *arg, int rv)
{
ws_pipe *p = arg;
nni_mtx_lock(&p->mtx);
@@ -139,7 +126,7 @@ ws_pipe_recv_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-ws_pipe_recv(void *arg, nni_aio *aio)
+wstran_pipe_recv(void *arg, nni_aio *aio)
{
ws_pipe *p = arg;
int rv;
@@ -148,18 +135,18 @@ ws_pipe_recv(void *arg, nni_aio *aio)
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, ws_pipe_recv_cancel, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, wstran_pipe_recv_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
}
p->user_rxaio = aio;
- nni_ws_recv_msg(p->ws, p->rxaio);
+ nng_stream_recv(p->ws, p->rxaio);
nni_mtx_unlock(&p->mtx);
}
static void
-ws_pipe_send_cancel(nni_aio *aio, void *arg, int rv)
+wstran_pipe_send_cancel(nni_aio *aio, void *arg, int rv)
{
ws_pipe *p = arg;
nni_mtx_lock(&p->mtx);
@@ -174,7 +161,7 @@ ws_pipe_send_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-ws_pipe_send(void *arg, nni_aio *aio)
+wstran_pipe_send(void *arg, nni_aio *aio)
{
ws_pipe *p = arg;
int rv;
@@ -183,7 +170,7 @@ ws_pipe_send(void *arg, nni_aio *aio)
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, ws_pipe_send_cancel, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, wstran_pipe_send_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -192,12 +179,12 @@ ws_pipe_send(void *arg, nni_aio *aio)
nni_aio_set_msg(p->txaio, nni_aio_get_msg(aio));
nni_aio_set_msg(aio, NULL);
- nni_ws_send_msg(p->ws, p->txaio);
+ nng_stream_send(p->ws, p->txaio);
nni_mtx_unlock(&p->mtx);
}
static void
-ws_pipe_stop(void *arg)
+wstran_pipe_stop(void *arg)
{
ws_pipe *p = arg;
@@ -206,7 +193,7 @@ ws_pipe_stop(void *arg)
}
static int
-ws_pipe_init(void *arg, nni_pipe *npipe)
+wstran_pipe_init(void *arg, nni_pipe *npipe)
{
ws_pipe *p = arg;
p->npipe = npipe;
@@ -214,22 +201,20 @@ ws_pipe_init(void *arg, nni_pipe *npipe)
}
static void
-ws_pipe_fini(void *arg)
+wstran_pipe_fini(void *arg)
{
ws_pipe *p = arg;
nni_aio_fini(p->rxaio);
nni_aio_fini(p->txaio);
- if (p->ws) {
- nni_ws_fini(p->ws);
- }
+ nng_stream_free(p->ws);
nni_mtx_fini(&p->mtx);
NNI_FREE_STRUCT(p);
}
static void
-ws_pipe_close(void *arg)
+wstran_pipe_close(void *arg)
{
ws_pipe *p = arg;
@@ -237,12 +222,12 @@ ws_pipe_close(void *arg)
nni_aio_close(p->txaio);
nni_mtx_lock(&p->mtx);
- nni_ws_close(p->ws);
+ nng_stream_close(p->ws);
nni_mtx_unlock(&p->mtx);
}
static int
-ws_pipe_alloc(ws_pipe **pipep, void *ws)
+wstran_pipe_alloc(ws_pipe **pipep, void *ws)
{
ws_pipe *p;
int rv;
@@ -253,9 +238,9 @@ ws_pipe_alloc(ws_pipe **pipep, void *ws)
nni_mtx_init(&p->mtx);
// Initialize AIOs.
- if (((rv = nni_aio_init(&p->txaio, ws_pipe_send_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->rxaio, ws_pipe_recv_cb, p)) != 0)) {
- ws_pipe_fini(p);
+ if (((rv = nni_aio_init(&p->txaio, wstran_pipe_send_cb, p)) != 0) ||
+ ((rv = nni_aio_init(&p->rxaio, wstran_pipe_recv_cb, p)) != 0)) {
+ wstran_pipe_fini(p);
return (rv);
}
p->ws = ws;
@@ -265,46 +250,20 @@ ws_pipe_alloc(ws_pipe **pipep, void *ws)
}
static uint16_t
-ws_pipe_peer(void *arg)
+wstran_pipe_peer(void *arg)
{
ws_pipe *p = arg;
return (p->rproto);
}
-// We have very different approaches for server and client.
-// Servers use the HTTP server framework, and a request methodology.
-
-static int
-ws_hook(void *arg, nni_http_req *req, nni_http_res *res)
-{
- ws_listener *l = arg;
- ws_hdr * h;
- NNI_ARG_UNUSED(req);
-
- // Eventually we'll want user customizable hooks.
- // For now we just set the headers we want.
-
- NNI_LIST_FOREACH (&l->headers, h) {
- int rv;
- rv = nng_http_res_set_header(res, h->name, h->value);
- if (rv != 0) {
- return (rv);
- }
- }
- return (0);
-}
-
static int
ws_listener_bind(void *arg)
{
ws_listener *l = arg;
int rv;
- nni_ws_listener_set_maxframe(l->listener, l->rcvmax);
- nni_ws_listener_hook(l->listener, ws_hook, l);
-
- if ((rv = nni_ws_listener_listen(l->listener)) == 0) {
+ if ((rv = nng_stream_listener_listen(l->listener)) == 0) {
l->started = true;
}
return (rv);
@@ -324,7 +283,7 @@ ws_listener_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-ws_listener_accept(void *arg, nni_aio *aio)
+wstran_listener_accept(void *arg, nni_aio *aio)
{
ws_listener *l = arg;
int rv;
@@ -343,13 +302,13 @@ ws_listener_accept(void *arg, nni_aio *aio)
}
nni_list_append(&l->aios, aio);
if (aio == nni_list_first(&l->aios)) {
- nni_ws_listener_accept(l->listener, l->accaio);
+ nng_stream_listener_accept(l->listener, l->accaio);
}
nni_mtx_unlock(&l->mtx);
}
static void
-ws_dialer_cancel(nni_aio *aio, void *arg, int rv)
+wstran_dialer_cancel(nni_aio *aio, void *arg, int rv)
{
ws_dialer *d = arg;
@@ -362,7 +321,7 @@ ws_dialer_cancel(nni_aio *aio, void *arg, int rv)
}
static void
-ws_dialer_connect(void *arg, nni_aio *aio)
+wstran_dialer_connect(void *arg, nni_aio *aio)
{
ws_dialer *d = arg;
int rv;
@@ -370,20 +329,9 @@ ws_dialer_connect(void *arg, nni_aio *aio)
if (nni_aio_begin(aio) != 0) {
return;
}
- if (!d->started) {
- ws_hdr *h;
- NNI_LIST_FOREACH (&d->headers, h) {
- int rv =
- nni_ws_dialer_header(d->dialer, h->name, h->value);
- if (rv != 0) {
- nni_aio_finish_error(aio, rv);
- return;
- }
- }
- }
nni_mtx_lock(&d->mtx);
- if ((rv = nni_aio_schedule(aio, ws_dialer_cancel, d)) != 0) {
+ if ((rv = nni_aio_schedule(aio, wstran_dialer_cancel, d)) != 0) {
nni_mtx_unlock(&d->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -391,225 +339,11 @@ ws_dialer_connect(void *arg, nni_aio *aio)
NNI_ASSERT(nni_list_empty(&d->aios));
d->started = true;
nni_list_append(&d->aios, aio);
- nni_ws_dialer_set_maxframe(d->dialer, d->rcvmax);
- nni_ws_dialer_dial(d->dialer, d->connaio);
- nni_mtx_unlock(&d->mtx);
-}
-
-static int
-ws_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
-ws_dialer_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_dialer *d = arg;
- size_t val;
- int rv;
-
- if (((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) &&
- (d != NULL)) {
- nni_mtx_lock(&d->mtx);
- d->rcvmax = val;
- nni_mtx_unlock(&d->mtx);
- nni_ws_dialer_set_maxframe(d->dialer, val);
- }
- return (rv);
-}
-
-static int
-ws_dialer_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_dialer *d = arg;
- int rv;
- nni_mtx_lock(&d->mtx);
- rv = nni_copyout_size(d->rcvmax, v, szp, t);
+ nng_stream_dialer_dial(d->dialer, d->connaio);
nni_mtx_unlock(&d->mtx);
- return (rv);
-}
-
-static int
-ws_listener_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_listener *l = arg;
- size_t val;
- int rv;
-
- if (((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) &&
- (l != NULL)) {
- nni_mtx_lock(&l->mtx);
- l->rcvmax = val;
- nni_mtx_unlock(&l->mtx);
- nni_ws_listener_set_maxframe(l->listener, val);
- }
- return (rv);
-}
-
-static int
-ws_listener_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_listener *l = arg;
- int rv;
- nni_mtx_lock(&l->mtx);
- rv = nni_copyout_size(l->rcvmax, v, szp, t);
- nni_mtx_unlock(&l->mtx);
- return (rv);
-}
-
-static int
-ws_set_headers(nni_list *headers, const char *v)
-{
- char * dupstr;
- size_t duplen;
- char * name;
- char * value;
- char * nl;
- nni_list l;
- ws_hdr * h;
- int rv;
-
- NNI_LIST_INIT(&l, ws_hdr, node);
- if ((dupstr = nni_strdup(v)) == NULL) {
- return (NNG_ENOMEM);
- }
- duplen = strlen(dupstr) + 1; // so we can free it later
- name = dupstr;
- for (;;) {
- if ((value = strchr(name, ':')) == NULL) {
- // Note that this also means that if
- // a bare word is present, we ignore it.
- break;
- }
- *value = '\0';
- value++;
- while (*value == ' ') {
- // Skip leading whitespace. Not strictly
- // necessary, but still a good idea.
- value++;
- }
- nl = value;
- // Find the end of the line -- should be CRLF, but can
- // also be unterminated or just LF if user
- while ((*nl != '\0') && (*nl != '\r') && (*nl != '\n')) {
- nl++;
- }
- while ((*nl == '\r') || (*nl == '\n')) {
- *nl = '\0';
- nl++;
- }
-
- if ((h = NNI_ALLOC_STRUCT(h)) == NULL) {
- rv = NNG_ENOMEM;
- goto done;
- }
- nni_list_append(&l, h);
- if (((h->name = nni_strdup(name)) == NULL) ||
- ((h->value = nni_strdup(value)) == NULL)) {
- rv = NNG_ENOMEM;
- goto done;
- }
-
- name = nl;
- }
-
- while ((h = nni_list_first(headers)) != NULL) {
- nni_list_remove(headers, h);
- nni_strfree(h->name);
- nni_strfree(h->value);
- NNI_FREE_STRUCT(h);
- }
- while ((h = nni_list_first(&l)) != NULL) {
- nni_list_remove(&l, h);
- nni_list_append(headers, h);
- }
- rv = 0;
-
-done:
- while ((h = nni_list_first(&l)) != NULL) {
- nni_list_remove(&l, h);
- nni_strfree(h->name);
- nni_strfree(h->value);
- NNI_FREE_STRUCT(h);
- }
- nni_free(dupstr, duplen);
- return (rv);
-}
-
-static int
-ws_dialer_set_reqhdrs(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_dialer *d = arg;
- int rv;
-
- if (((rv = ws_check_string(v, sz, t)) == 0) && (d != NULL)) {
- if (d->started) {
- return (NNG_EBUSY);
- }
- nni_mtx_lock(&d->mtx);
- rv = ws_set_headers(&d->headers, v);
- nni_mtx_unlock(&d->mtx);
- }
- return (rv);
-}
-
-static int
-ws_listener_set_reshdrs(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_listener *l = arg;
- int rv;
-
- if (((rv = ws_check_string(v, sz, t)) == 0) && (l != NULL)) {
- if (l->started) {
- return (NNG_EBUSY);
- }
- nni_mtx_lock(&l->mtx);
- rv = ws_set_headers(&l->headers, v);
- nni_mtx_unlock(&l->mtx);
- }
- return (rv);
-}
-
-static int
-ws_pipe_get_reshdrs(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_pipe * p = arg;
- const char *s;
-
- if ((s = nni_ws_response_headers(p->ws)) == NULL) {
- return (NNG_ENOMEM);
- }
- return (nni_copyout_str(s, v, szp, t));
-}
-
-static int
-ws_pipe_get_reqhdrs(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_pipe * p = arg;
- const char *s;
-
- if ((s = nni_ws_request_headers(p->ws)) == NULL) {
- return (NNG_ENOMEM);
- }
- return (nni_copyout_str(s, v, szp, t));
}
static const nni_option ws_pipe_options[] = {
- {
- .o_name = NNG_OPT_WS_REQUEST_HEADERS,
- .o_get = ws_pipe_get_reqhdrs,
- },
- {
- .o_name = NNG_OPT_WS_RESPONSE_HEADERS,
- .o_get = ws_pipe_get_reshdrs,
- },
// terminate list
{
.o_name = NULL,
@@ -617,113 +351,62 @@ static const nni_option ws_pipe_options[] = {
};
static int
-ws_pipe_getopt(void *arg, const char *name, void *buf, size_t *szp, nni_type t)
+wstran_pipe_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
ws_pipe *p = arg;
int rv;
- if ((rv = nni_ws_getopt(p->ws, name, buf, szp, t)) == NNG_ENOTSUP) {
+ if ((rv = nni_stream_getx(p->ws, name, buf, szp, t)) == NNG_ENOTSUP) {
rv = nni_getopt(ws_pipe_options, name, p, buf, szp, t);
}
return (rv);
}
static nni_tran_pipe_ops ws_pipe_ops = {
- .p_init = ws_pipe_init,
- .p_fini = ws_pipe_fini,
- .p_stop = ws_pipe_stop,
- .p_send = ws_pipe_send,
- .p_recv = ws_pipe_recv,
- .p_close = ws_pipe_close,
- .p_peer = ws_pipe_peer,
- .p_getopt = ws_pipe_getopt,
-};
-
-static nni_option ws_dialer_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = ws_dialer_get_recvmaxsz,
- .o_set = ws_dialer_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_WS_REQUEST_HEADERS,
- .o_set = ws_dialer_set_reqhdrs,
- },
- // terminate list
- {
- .o_name = NULL,
- },
-};
-
-static nni_option ws_listener_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = ws_listener_get_recvmaxsz,
- .o_set = ws_listener_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_WS_RESPONSE_HEADERS,
- .o_set = ws_listener_set_reshdrs,
- },
- // terminate list
- {
- .o_name = NULL,
- },
+ .p_init = wstran_pipe_init,
+ .p_fini = wstran_pipe_fini,
+ .p_stop = wstran_pipe_stop,
+ .p_send = wstran_pipe_send,
+ .p_recv = wstran_pipe_recv,
+ .p_close = wstran_pipe_close,
+ .p_peer = wstran_pipe_peer,
+ .p_getopt = wstran_pipe_getopt,
};
static void
-ws_dialer_fini(void *arg)
+wstran_dialer_fini(void *arg)
{
ws_dialer *d = arg;
- ws_hdr * hdr;
nni_aio_stop(d->connaio);
- if (d->dialer != NULL) {
- nni_ws_dialer_fini(d->dialer);
- }
+ nng_stream_dialer_free(d->dialer);
nni_aio_fini(d->connaio);
- while ((hdr = nni_list_first(&d->headers)) != NULL) {
- nni_list_remove(&d->headers, hdr);
- nni_strfree(hdr->name);
- nni_strfree(hdr->value);
- NNI_FREE_STRUCT(hdr);
- }
- nni_strfree(d->prname);
nni_mtx_fini(&d->mtx);
NNI_FREE_STRUCT(d);
}
static void
-ws_listener_fini(void *arg)
+wstran_listener_fini(void *arg)
{
ws_listener *l = arg;
- ws_hdr * hdr;
nni_aio_stop(l->accaio);
- if (l->listener != NULL) {
- nni_ws_listener_fini(l->listener);
- }
+ nng_stream_listener_free(l->listener);
nni_aio_fini(l->accaio);
- while ((hdr = nni_list_first(&l->headers)) != NULL) {
- nni_list_remove(&l->headers, hdr);
- nni_strfree(hdr->name);
- nni_strfree(hdr->value);
- NNI_FREE_STRUCT(hdr);
- }
- nni_strfree(l->prname);
nni_mtx_fini(&l->mtx);
NNI_FREE_STRUCT(l);
}
static void
-ws_connect_cb(void *arg)
+wstran_connect_cb(void *arg)
{
- ws_dialer *d = arg;
- ws_pipe * p;
- nni_aio * caio = d->connaio;
- nni_aio * uaio;
- int rv;
- nni_ws * ws = NULL;
+ ws_dialer * d = arg;
+ ws_pipe * p;
+ nni_aio * caio = d->connaio;
+ nni_aio * uaio;
+ int rv;
+ nng_stream *ws = NULL;
nni_mtx_lock(&d->mtx);
if (nni_aio_result(caio) == 0) {
@@ -731,9 +414,7 @@ ws_connect_cb(void *arg)
}
if ((uaio = nni_list_first(&d->aios)) == NULL) {
// The client stopped caring about this!
- if (ws != NULL) {
- nni_ws_fini(ws);
- }
+ nng_stream_free(ws);
nni_mtx_unlock(&d->mtx);
return;
}
@@ -741,11 +422,10 @@ ws_connect_cb(void *arg)
NNI_ASSERT(nni_list_empty(&d->aios));
if ((rv = nni_aio_result(caio)) != 0) {
nni_aio_finish_error(uaio, rv);
- } else if ((rv = ws_pipe_alloc(&p, ws)) != 0) {
- nni_ws_fini(ws);
+ } else if ((rv = wstran_pipe_alloc(&p, ws)) != 0) {
+ nng_stream_free(ws);
nni_aio_finish_error(uaio, rv);
} else {
- p->rcvmax = d->rcvmax;
p->rproto = d->rproto;
p->lproto = d->lproto;
@@ -756,25 +436,25 @@ ws_connect_cb(void *arg)
}
static void
-ws_dialer_close(void *arg)
+wstran_dialer_close(void *arg)
{
ws_dialer *d = arg;
nni_aio_close(d->connaio);
- nni_ws_dialer_close(d->dialer);
+ nng_stream_dialer_close(d->dialer);
}
static void
-ws_listener_close(void *arg)
+wstran_listener_close(void *arg)
{
ws_listener *l = arg;
nni_aio_close(l->accaio);
- nni_ws_listener_close(l->listener);
+ nng_stream_listener_close(l->listener);
}
static void
-ws_accept_cb(void *arg)
+wstran_accept_cb(void *arg)
{
ws_listener *l = arg;
nni_aio * aaio = l->accaio;
@@ -789,16 +469,15 @@ ws_accept_cb(void *arg)
nni_aio_finish_error(uaio, rv);
}
} else {
- nni_ws *ws = nni_aio_get_output(aaio, 0);
+ nng_stream *ws = nni_aio_get_output(aaio, 0);
if (uaio != NULL) {
ws_pipe *p;
// Make a pipe
nni_aio_list_remove(uaio);
- if ((rv = ws_pipe_alloc(&p, ws)) != 0) {
- nni_ws_close(ws);
+ if ((rv = wstran_pipe_alloc(&p, ws)) != 0) {
+ nng_stream_close(ws);
nni_aio_finish_error(uaio, rv);
} else {
- p->rcvmax = l->rcvmax;
p->rproto = l->rproto;
p->lproto = l->lproto;
@@ -808,37 +487,40 @@ ws_accept_cb(void *arg)
}
}
if (!nni_list_empty(&l->aios)) {
- nni_ws_listener_accept(l->listener, aaio);
+ nng_stream_listener_accept(l->listener, aaio);
}
nni_mtx_unlock(&l->mtx);
}
static int
-ws_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
+wstran_dialer_init(void **dp, nng_url *url, nni_dialer *ndialer)
{
- ws_dialer * d;
- nni_sock * s = nni_dialer_sock(ndialer);
- const char *n;
- int rv;
+ ws_dialer *d;
+ nni_sock * s = nni_dialer_sock(ndialer);
+ int rv;
+ char prname[64];
if ((d = NNI_ALLOC_STRUCT(d)) == NULL) {
return (NNG_ENOMEM);
}
nni_mtx_init(&d->mtx);
- NNI_LIST_INIT(&d->headers, ws_hdr, node);
nni_aio_list_init(&d->aios);
d->lproto = nni_sock_proto_id(s);
d->rproto = nni_sock_peer_id(s);
d->ndialer = ndialer;
- n = nni_sock_peer_name(s);
- if (((rv = nni_ws_dialer_init(&d->dialer, url)) != 0) ||
- ((rv = nni_aio_init(&d->connaio, ws_connect_cb, d)) != 0) ||
- ((rv = nni_asprintf(&d->prname, "%s.sp.nanomsg.org", n)) != 0) ||
- ((rv = nni_ws_dialer_proto(d->dialer, d->prname)) != 0)) {
- ws_dialer_fini(d);
+ snprintf(prname, sizeof(prname), "%s.sp.nanomsg.org",
+ nni_sock_peer_name(s));
+
+ if (((rv = nni_ws_dialer_alloc(&d->dialer, url)) != 0) ||
+ ((rv = nni_aio_init(&d->connaio, wstran_connect_cb, d)) != 0) ||
+ ((rv = nng_stream_dialer_set_bool(
+ d->dialer, NNI_OPT_WS_MSGMODE, true)) != 0) ||
+ ((rv = nng_stream_dialer_set_string(
+ d->dialer, NNG_OPT_WS_PROTOCOL, prname)) != 0)) {
+ wstran_dialer_fini(d);
return (rv);
}
@@ -847,31 +529,34 @@ ws_dialer_init(void **dp, nni_url *url, nni_dialer *ndialer)
}
static int
-ws_listener_init(void **lp, nni_url *url, nni_listener *nlistener)
+wstran_listener_init(void **lp, nng_url *url, nni_listener *nlistener)
{
ws_listener *l;
- const char * n;
int rv;
- nni_sock * sock = nni_listener_sock(nlistener);
+ nni_sock * s = nni_listener_sock(nlistener);
+ char prname[64];
if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
return (NNG_ENOMEM);
}
nni_mtx_init(&l->mtx);
- NNI_LIST_INIT(&l->headers, ws_hdr, node);
nni_aio_list_init(&l->aios);
- l->lproto = nni_sock_proto_id(sock);
- l->rproto = nni_sock_peer_id(sock);
- n = nni_sock_proto_name(sock);
+ l->lproto = nni_sock_proto_id(s);
+ l->rproto = nni_sock_peer_id(s);
l->nlistener = nlistener;
- if (((rv = nni_ws_listener_init(&l->listener, url)) != 0) ||
- ((rv = nni_aio_init(&l->accaio, ws_accept_cb, l)) != 0) ||
- ((rv = nni_asprintf(&l->prname, "%s.sp.nanomsg.org", n)) != 0) ||
- ((rv = nni_ws_listener_proto(l->listener, l->prname)) != 0)) {
- ws_listener_fini(l);
+ snprintf(prname, sizeof(prname), "%s.sp.nanomsg.org",
+ nni_sock_proto_name(s));
+
+ if (((rv = nni_ws_listener_alloc(&l->listener, url)) != 0) ||
+ ((rv = nni_aio_init(&l->accaio, wstran_accept_cb, l)) != 0) ||
+ ((rv = nng_stream_listener_set_bool(
+ l->listener, NNI_OPT_WS_MSGMODE, true)) != 0) ||
+ ((rv = nng_stream_listener_set_string(
+ l->listener, NNG_OPT_WS_PROTOCOL, prname)) != 0)) {
+ wstran_listener_fini(l);
return (rv);
}
*lp = l;
@@ -879,350 +564,143 @@ ws_listener_init(void **lp, nni_url *url, nni_listener *nlistener)
}
static int
-ws_tran_init(void)
+wstran_init(void)
{
return (0);
}
static void
-ws_tran_fini(void)
+wstran_fini(void)
{
}
-static nni_tran_dialer_ops ws_dialer_ops = {
- .d_init = ws_dialer_init,
- .d_fini = ws_dialer_fini,
- .d_connect = ws_dialer_connect,
- .d_close = ws_dialer_close,
- .d_options = ws_dialer_options,
-};
-
-static nni_tran_listener_ops ws_listener_ops = {
- .l_init = ws_listener_init,
- .l_fini = ws_listener_fini,
- .l_bind = ws_listener_bind,
- .l_accept = ws_listener_accept,
- .l_close = ws_listener_close,
- .l_options = ws_listener_options,
-};
-
-static nni_tran ws_tran = {
- .tran_version = NNI_TRANSPORT_VERSION,
- .tran_scheme = "ws",
- .tran_dialer = &ws_dialer_ops,
- .tran_listener = &ws_listener_ops,
- .tran_pipe = &ws_pipe_ops,
- .tran_init = ws_tran_init,
- .tran_fini = ws_tran_fini,
+static const nni_option wstran_ep_opts[] = {
+ // terminate list
+ {
+ .o_name = NULL,
+ },
};
-int
-nng_ws_register(void)
-{
- return (nni_tran_register(&ws_tran));
-}
-
-#ifdef NNG_TRANSPORT_WSS
-
-static int
-wss_dialer_get_tlsconfig(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_dialer * d = arg;
- nng_tls_config *tls;
- int rv;
-
- if (((rv = nni_ws_dialer_get_tls(d->dialer, &tls)) != 0) ||
- ((rv = nni_copyout_ptr(tls, v, szp, t)) != 0)) {
- return (rv);
- }
- return (0);
-}
-
-static int
-wss_listener_get_tlsconfig(void *arg, void *v, size_t *szp, nni_opt_type t)
-{
- ws_listener * l = arg;
- nng_tls_config *tls;
- int rv;
-
- if (((rv = nni_ws_listener_get_tls(l->listener, &tls)) != 0) ||
- ((rv = nni_copyout_ptr(tls, v, szp, t)) != 0)) {
- return (rv);
- }
- return (0);
-}
-
-static int
-wss_dialer_set_tlsconfig(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_dialer * d = arg;
- nng_tls_config *cfg;
- int rv;
-
- if ((rv = nni_copyin_ptr((void **) &cfg, v, sz, t)) != 0) {
- return (rv);
- }
- if (cfg == NULL) {
- return (NNG_EINVAL);
- }
- if (d != NULL) {
- rv = nni_ws_dialer_set_tls(d->dialer, cfg);
- }
- return (rv);
-}
-
static int
-wss_listener_set_tlsconfig(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_listener * l = arg;
- nng_tls_config *cfg;
- int rv;
-
- if ((rv = nni_copyin_ptr((void **) &cfg, v, sz, t)) != 0) {
- return (rv);
- }
- if (cfg == NULL) {
- return (NNG_EINVAL);
- }
- if (l != NULL) {
- rv = nni_ws_listener_set_tls(l->listener, cfg);
- }
- return (rv);
-}
-
-static int
-wss_dialer_set_cert_key_file(
- void *arg, const void *v, size_t sz, nni_opt_type t)
+wstran_dialer_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
ws_dialer *d = arg;
int rv;
- if (((rv = ws_check_string(v, sz, t)) == 0) && (d != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_dialer_get_tls(d->dialer, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_cert_key_file(tls, v, NULL);
- nni_tls_config_fini(tls);
+ rv = nni_stream_dialer_getx(d->dialer, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(wstran_ep_opts, name, d, buf, szp, t);
}
return (rv);
}
static int
-wss_listener_set_cert_key_file(
- void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_listener *l = arg;
- int rv;
-
- if (((rv = ws_check_string(v, sz, t)) == 0) && (l != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_listener_get_tls(l->listener, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_cert_key_file(tls, v, NULL);
- nni_tls_config_fini(tls);
- }
- return (rv);
-}
-
-static int
-wss_dialer_set_ca_file(void *arg, const void *v, size_t sz, nni_opt_type t)
+wstran_dialer_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
{
ws_dialer *d = arg;
int rv;
- if (((rv = ws_check_string(v, sz, t)) == 0) && (d != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_dialer_get_tls(d->dialer, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_ca_file(tls, v);
- nni_tls_config_fini(tls);
+ rv = nni_stream_dialer_setx(d->dialer, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(wstran_ep_opts, name, d, buf, sz, t);
}
return (rv);
}
static int
-wss_listener_set_ca_file(void *arg, const void *v, size_t sz, nni_opt_type t)
+wstran_listener_getopt(
+ void *arg, const char *name, void *buf, size_t *szp, nni_type t)
{
ws_listener *l = arg;
int rv;
- if (((rv = ws_check_string(v, sz, t)) == 0) && (l != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_listener_get_tls(l->listener, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_ca_file(tls, v);
- nni_tls_config_fini(tls);
- }
- return (rv);
-}
-
-static int
-wss_dialer_set_auth_mode(void *arg, const void *v, size_t sz, nni_opt_type t)
-{
- ws_dialer *d = arg;
- int rv;
- int mode;
-
- rv = nni_copyin_int(&mode, v, sz, NNG_TLS_AUTH_MODE_NONE,
- NNG_TLS_AUTH_MODE_REQUIRED, t);
-
- if ((rv == 0) && (d != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_dialer_get_tls(d->dialer, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_auth_mode(tls, mode);
- nni_tls_config_fini(tls);
+ rv = nni_stream_listener_getx(l->listener, name, buf, szp, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_getopt(wstran_ep_opts, name, l, buf, szp, t);
}
return (rv);
}
static int
-wss_listener_set_auth_mode(void *arg, const void *v, size_t sz, nni_opt_type t)
+wstran_listener_setopt(
+ void *arg, const char *name, const void *buf, size_t sz, nni_type t)
{
ws_listener *l = arg;
int rv;
- int mode;
-
- rv = nni_copyin_int(&mode, v, sz, NNG_TLS_AUTH_MODE_NONE,
- NNG_TLS_AUTH_MODE_REQUIRED, t);
- if ((rv == 0) && (l != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_listener_get_tls(l->listener, &tls)) != 0) {
- return (rv);
- }
- rv = nng_tls_config_auth_mode(tls, mode);
- nni_tls_config_fini(tls);
+ rv = nni_stream_listener_setx(l->listener, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_setopt(wstran_ep_opts, name, l, buf, sz, t);
}
return (rv);
}
+static nni_chkoption wstran_checkopts[] = {
+ {
+ .o_name = NULL,
+ },
+};
+
static int
-wss_dialer_set_tls_server_name(
- void *arg, const void *v, size_t sz, nni_opt_type t)
+wstran_checkopt(const char *name, const void *buf, size_t sz, nni_type t)
{
- ws_dialer *d = arg;
- int rv;
-
- if (((rv = ws_check_string(v, sz, t)) == 0) && (d != NULL)) {
- nng_tls_config *tls;
-
- if ((rv = nni_ws_dialer_get_tls(d->dialer, &tls)) != 0) {
- return (rv);
- }
-
- rv = nng_tls_config_server_name(tls, v);
- nni_tls_config_fini(tls);
+ int rv;
+ rv = nni_chkopt(wstran_checkopts, name, buf, sz, t);
+ if (rv == NNG_ENOTSUP) {
+ rv = nni_stream_checkopt("ws", name, buf, sz, t);
}
return (rv);
}
-static nni_option wss_dialer_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = ws_dialer_get_recvmaxsz,
- .o_set = ws_dialer_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_WS_REQUEST_HEADERS,
- .o_set = ws_dialer_set_reqhdrs,
- },
- {
- .o_name = NNG_OPT_TLS_CONFIG,
- .o_get = wss_dialer_get_tlsconfig,
- .o_set = wss_dialer_set_tlsconfig,
- },
- {
- .o_name = NNG_OPT_TLS_CERT_KEY_FILE,
- .o_set = wss_dialer_set_cert_key_file,
- },
- {
- .o_name = NNG_OPT_TLS_CA_FILE,
- .o_set = wss_dialer_set_ca_file,
- },
- {
- .o_name = NNG_OPT_TLS_AUTH_MODE,
- .o_set = wss_dialer_set_auth_mode,
- },
- {
- .o_name = NNG_OPT_TLS_SERVER_NAME,
- .o_set = wss_dialer_set_tls_server_name,
- },
- // terminate list
- {
- .o_name = NULL,
- },
+static nni_tran_dialer_ops ws_dialer_ops = {
+ .d_init = wstran_dialer_init,
+ .d_fini = wstran_dialer_fini,
+ .d_connect = wstran_dialer_connect,
+ .d_close = wstran_dialer_close,
+ .d_setopt = wstran_dialer_setopt,
+ .d_getopt = wstran_dialer_getopt,
};
-static nni_option wss_listener_options[] = {
- {
- .o_name = NNG_OPT_RECVMAXSZ,
- .o_get = ws_listener_get_recvmaxsz,
- .o_set = ws_listener_set_recvmaxsz,
- },
- {
- .o_name = NNG_OPT_WS_RESPONSE_HEADERS,
- .o_set = ws_listener_set_reshdrs,
- },
- {
- .o_name = NNG_OPT_TLS_CONFIG,
- .o_get = wss_listener_get_tlsconfig,
- .o_set = wss_listener_set_tlsconfig,
- },
- {
- .o_name = NNG_OPT_TLS_CERT_KEY_FILE,
- .o_set = wss_listener_set_cert_key_file,
- },
- {
- .o_name = NNG_OPT_TLS_CA_FILE,
- .o_set = wss_listener_set_ca_file,
- },
- {
- .o_name = NNG_OPT_TLS_AUTH_MODE,
- .o_set = wss_listener_set_auth_mode,
- },
- // terminate list
- {
- .o_name = NULL,
- },
+static nni_tran_listener_ops ws_listener_ops = {
+ .l_init = wstran_listener_init,
+ .l_fini = wstran_listener_fini,
+ .l_bind = ws_listener_bind,
+ .l_accept = wstran_listener_accept,
+ .l_close = wstran_listener_close,
+ .l_setopt = wstran_listener_setopt,
+ .l_getopt = wstran_listener_getopt,
};
-static nni_tran_dialer_ops wss_dialer_ops = {
- .d_init = ws_dialer_init,
- .d_fini = ws_dialer_fini,
- .d_connect = ws_dialer_connect,
- .d_close = ws_dialer_close,
- .d_options = wss_dialer_options,
+static nni_tran ws_tran = {
+ .tran_version = NNI_TRANSPORT_VERSION,
+ .tran_scheme = "ws",
+ .tran_dialer = &ws_dialer_ops,
+ .tran_listener = &ws_listener_ops,
+ .tran_pipe = &ws_pipe_ops,
+ .tran_init = wstran_init,
+ .tran_fini = wstran_fini,
+ .tran_checkopt = wstran_checkopt,
};
-static nni_tran_listener_ops wss_listener_ops = {
- .l_init = ws_listener_init,
- .l_fini = ws_listener_fini,
- .l_bind = ws_listener_bind,
- .l_accept = ws_listener_accept,
- .l_close = ws_listener_close,
- .l_options = wss_listener_options,
-};
+int
+nng_ws_register(void)
+{
+ return (nni_tran_register(&ws_tran));
+}
+
+#ifdef NNG_TRANSPORT_WSS
static nni_tran wss_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "wss",
- .tran_dialer = &wss_dialer_ops,
- .tran_listener = &wss_listener_ops,
+ .tran_dialer = &ws_dialer_ops,
+ .tran_listener = &ws_listener_ops,
.tran_pipe = &ws_pipe_ops,
- .tran_init = ws_tran_init,
- .tran_fini = ws_tran_fini,
+ .tran_init = wstran_init,
+ .tran_fini = wstran_fini,
+ .tran_checkopt = wstran_checkopt,
};
int