diff options
Diffstat (limited to 'src/transport')
| -rw-r--r-- | src/transport/ipc/ipc.c | 142 | ||||
| -rw-r--r-- | src/transport/tcp/tcp.c | 363 | ||||
| -rw-r--r-- | src/transport/tls/tls.c | 289 | ||||
| -rw-r--r-- | src/transport/ws/websocket.c | 910 |
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 |
