aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/tcp/tcp.c1016
-rw-r--r--src/transport/tls/tls.c1056
2 files changed, 1226 insertions, 846 deletions
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index e8aa04d0..c323da29 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.c
@@ -17,17 +17,18 @@
// TCP transport. Platform specific TCP operations must be
// supplied as well.
-typedef struct tcp_pipe tcp_pipe;
-typedef struct tcp_ep tcp_ep;
+typedef struct tcptran_pipe tcptran_pipe;
+typedef struct tcptran_dialer tcptran_dialer;
+typedef struct tcptran_listener tcptran_listener;
// tcp_pipe is one end of a TCP connection.
-struct tcp_pipe {
- nni_plat_tcp_pipe *tpp;
- uint16_t peer;
- uint16_t proto;
- size_t rcvmax;
- bool nodelay;
- bool keepalive;
+struct tcptran_pipe {
+ nni_tcp_conn *conn;
+ uint16_t peer;
+ uint16_t proto;
+ size_t rcvmax;
+ bool nodelay;
+ bool keepalive;
nni_list recvq;
nni_list sendq;
@@ -46,53 +47,70 @@ struct tcp_pipe {
nni_mtx mtx;
};
-struct tcp_ep {
- nni_plat_tcp_ep *tep;
- uint16_t proto;
- size_t rcvmax;
- bool nodelay;
- bool keepalive;
- nni_aio * aio;
- nni_aio * user_aio;
- nni_url * url;
- nng_sockaddr bsa; // bound addr
- nni_mtx mtx;
+struct tcptran_dialer {
+ nni_tcp_dialer *dialer;
+ uint16_t proto;
+ uint16_t af;
+ size_t rcvmax;
+ bool nodelay;
+ bool keepalive;
+ bool resolving;
+ nng_sockaddr sa;
+ nni_aio * aio;
+ nni_aio * user_aio;
+ nni_url * url;
+ nni_mtx mtx;
};
-static void tcp_pipe_dosend(tcp_pipe *, nni_aio *);
-static void tcp_pipe_dorecv(tcp_pipe *);
-static void tcp_pipe_send_cb(void *);
-static void tcp_pipe_recv_cb(void *);
-static void tcp_pipe_nego_cb(void *);
-static void tcp_ep_cb(void *arg);
+struct tcptran_listener {
+ nni_tcp_listener *listener;
+ uint16_t proto;
+ size_t rcvmax;
+ bool nodelay;
+ bool keepalive;
+ nni_aio * aio;
+ nni_aio * user_aio;
+ nni_url * url;
+ nng_sockaddr sa;
+ nng_sockaddr bsa; // bound addr
+ nni_mtx mtx;
+};
+
+static void tcptran_pipe_send_start(tcptran_pipe *);
+static void tcptran_pipe_recv_start(tcptran_pipe *);
+static void tcptran_pipe_send_cb(void *);
+static void tcptran_pipe_recv_cb(void *);
+static void tcptran_pipe_nego_cb(void *);
+static void tcptran_dialer_cb(void *arg);
+static void tcptran_listener_cb(void *arg);
static int
-tcp_tran_init(void)
+tcptran_init(void)
{
return (0);
}
static void
-tcp_tran_fini(void)
+tcptran_fini(void)
{
}
static void
-tcp_pipe_close(void *arg)
+tcptran_pipe_close(void *arg)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
nni_aio_close(p->rxaio);
nni_aio_close(p->txaio);
nni_aio_close(p->negaio);
- nni_plat_tcp_pipe_close(p->tpp);
+ nni_tcp_conn_close(p->conn);
}
static void
-tcp_pipe_stop(void *arg)
+tcptran_pipe_stop(void *arg)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
nni_aio_stop(p->rxaio);
nni_aio_stop(p->txaio);
@@ -100,62 +118,48 @@ tcp_pipe_stop(void *arg)
}
static void
-tcp_pipe_fini(void *arg)
+tcptran_pipe_fini(void *arg)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
nni_aio_fini(p->rxaio);
nni_aio_fini(p->txaio);
nni_aio_fini(p->negaio);
- if (p->tpp != NULL) {
- nni_plat_tcp_pipe_fini(p->tpp);
- }
- if (p->rxmsg) {
- nni_msg_free(p->rxmsg);
+ if (p->conn != NULL) {
+ nni_tcp_conn_fini(p->conn);
}
-
+ nni_msg_free(p->rxmsg);
NNI_FREE_STRUCT(p);
}
static int
-tcp_pipe_init(tcp_pipe **pipep, tcp_ep *ep, void *tpp)
+tcptran_pipe_init(tcptran_pipe **pipep, void *conn)
{
- tcp_pipe *p;
- int rv;
+ tcptran_pipe *p;
+ int rv;
if ((p = NNI_ALLOC_STRUCT(p)) == NULL) {
return (NNG_ENOMEM);
}
nni_mtx_init(&p->mtx);
- if (((rv = nni_aio_init(&p->txaio, tcp_pipe_send_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->rxaio, tcp_pipe_recv_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->negaio, tcp_pipe_nego_cb, p)) != 0)) {
- tcp_pipe_fini(p);
+ 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->negaio, tcptran_pipe_nego_cb, p)) != 0)) {
+ tcptran_pipe_fini(p);
return (rv);
}
nni_aio_list_init(&p->recvq);
nni_aio_list_init(&p->sendq);
- p->proto = ep->proto;
- p->rcvmax = ep->rcvmax;
- p->nodelay = ep->nodelay;
- p->keepalive = ep->keepalive;
- p->tpp = tpp;
-
- // We try to set the nodelay and keepalive, but if these fail for
- // some reason, its not really fatal to the communication channel.
- // So ignore the return values.
- (void) nni_plat_tcp_pipe_set_nodelay(tpp, p->nodelay);
- (void) nni_plat_tcp_pipe_set_keepalive(tpp, p->keepalive);
-
- *pipep = p;
+ p->conn = conn;
+ *pipep = p;
return (0);
}
static void
-tcp_cancel_nego(nni_aio *aio, int rv)
+tcptran_pipe_nego_cancel(nni_aio *aio, int rv)
{
- tcp_pipe *p = nni_aio_get_prov_data(aio);
+ tcptran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (p->user_negaio != aio) {
@@ -170,11 +174,11 @@ tcp_cancel_nego(nni_aio *aio, int rv)
}
static void
-tcp_pipe_nego_cb(void *arg)
+tcptran_pipe_nego_cb(void *arg)
{
- tcp_pipe *p = arg;
- nni_aio * aio = p->negaio;
- int rv;
+ tcptran_pipe *p = arg;
+ nni_aio * aio = p->negaio;
+ int rv;
nni_mtx_lock(&p->mtx);
if ((rv = nni_aio_result(aio)) != 0) {
@@ -194,7 +198,7 @@ tcp_pipe_nego_cb(void *arg)
iov.iov_buf = &p->txlen[p->gottxhead];
// send it down...
nni_aio_set_iov(aio, 1, &iov);
- nni_plat_tcp_pipe_send(p->tpp, aio);
+ nni_tcp_conn_send(p->conn, aio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -203,7 +207,7 @@ tcp_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_plat_tcp_pipe_recv(p->tpp, aio);
+ nni_tcp_conn_recv(p->conn, aio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -227,14 +231,14 @@ done:
}
static void
-tcp_pipe_send_cb(void *arg)
+tcptran_pipe_send_cb(void *arg)
{
- tcp_pipe *p = arg;
- int rv;
- nni_aio * aio;
- size_t n;
- nni_msg * msg;
- nni_aio * txaio = p->txaio;
+ tcptran_pipe *p = arg;
+ int rv;
+ nni_aio * aio;
+ size_t n;
+ nni_msg * msg;
+ nni_aio * txaio = p->txaio;
nni_mtx_lock(&p->mtx);
aio = nni_list_first(&p->sendq);
@@ -254,16 +258,14 @@ tcp_pipe_send_cb(void *arg)
n = nni_aio_count(txaio);
nni_aio_iov_advance(txaio, n);
if (nni_aio_iov_count(txaio) > 0) {
- nni_plat_tcp_pipe_send(p->tpp, txaio);
+ nni_tcp_conn_send(p->conn, txaio);
nni_mtx_unlock(&p->mtx);
return;
}
nni_aio_list_remove(aio);
- if (!nni_list_empty(&p->sendq)) {
- // schedule next send
- tcp_pipe_dosend(p, nni_list_first(&p->sendq));
- }
+ tcptran_pipe_send_start(p);
+
nni_mtx_unlock(&p->mtx);
msg = nni_aio_get_msg(aio);
@@ -274,14 +276,14 @@ tcp_pipe_send_cb(void *arg)
}
static void
-tcp_pipe_recv_cb(void *arg)
+tcptran_pipe_recv_cb(void *arg)
{
- tcp_pipe *p = arg;
- nni_aio * aio;
- int rv;
- size_t n;
- nni_msg * msg;
- nni_aio * rxaio = p->rxaio;
+ tcptran_pipe *p = arg;
+ nni_aio * aio;
+ int rv;
+ size_t n;
+ nni_msg * msg;
+ nni_aio * rxaio = p->rxaio;
nni_mtx_lock(&p->mtx);
aio = nni_list_first(&p->recvq);
@@ -293,7 +295,7 @@ tcp_pipe_recv_cb(void *arg)
n = nni_aio_count(rxaio);
nni_aio_iov_advance(rxaio, n);
if (nni_aio_iov_count(rxaio) > 0) {
- nni_plat_tcp_pipe_recv(p->tpp, rxaio);
+ nni_tcp_conn_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -325,7 +327,7 @@ tcp_pipe_recv_cb(void *arg)
iov.iov_len = (size_t) len;
nni_aio_set_iov(rxaio, 1, &iov);
- nni_plat_tcp_pipe_recv(p->tpp, rxaio);
+ nni_tcp_conn_recv(p->conn, rxaio);
nni_mtx_unlock(&p->mtx);
return;
}
@@ -336,7 +338,7 @@ tcp_pipe_recv_cb(void *arg)
msg = p->rxmsg;
p->rxmsg = NULL;
if (!nni_list_empty(&p->recvq)) {
- tcp_pipe_dorecv(p);
+ tcptran_pipe_recv_start(p);
}
nni_mtx_unlock(&p->mtx);
@@ -357,9 +359,9 @@ recv_error:
}
static void
-tcp_cancel_tx(nni_aio *aio, int rv)
+tcptran_pipe_send_cancel(nni_aio *aio, int rv)
{
- tcp_pipe *p = nni_aio_get_prov_data(aio);
+ tcptran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (!nni_aio_list_active(aio)) {
@@ -381,14 +383,19 @@ tcp_cancel_tx(nni_aio *aio, int rv)
}
static void
-tcp_pipe_dosend(tcp_pipe *p, nni_aio *aio)
+tcptran_pipe_send_start(tcptran_pipe *p)
{
+ nni_aio *aio;
nni_aio *txaio;
nni_msg *msg;
int niov;
nni_iov iov[3];
uint64_t len;
+ if ((aio = nni_list_first(&p->sendq)) == NULL) {
+ return;
+ }
+
// This runs to send the message.
msg = nni_aio_get_msg(aio);
len = nni_msg_len(msg) + nni_msg_header_len(msg);
@@ -411,35 +418,35 @@ tcp_pipe_dosend(tcp_pipe *p, nni_aio *aio)
niov++;
}
nni_aio_set_iov(txaio, niov, iov);
- nni_plat_tcp_pipe_send(p->tpp, txaio);
+ nni_tcp_conn_send(p->conn, txaio);
}
static void
-tcp_pipe_send(void *arg, nni_aio *aio)
+tcptran_pipe_send(void *arg, nni_aio *aio)
{
- tcp_pipe *p = arg;
- int rv;
+ tcptran_pipe *p = arg;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tcp_cancel_tx, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tcptran_pipe_send_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
}
nni_list_append(&p->sendq, aio);
if (nni_list_first(&p->sendq) == aio) {
- tcp_pipe_dosend(p, aio);
+ tcptran_pipe_send_start(p);
}
nni_mtx_unlock(&p->mtx);
}
static void
-tcp_cancel_rx(nni_aio *aio, int rv)
+tcptran_pipe_recv_cancel(nni_aio *aio, int rv)
{
- tcp_pipe *p = nni_aio_get_prov_data(aio);
+ tcptran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (!nni_aio_list_active(aio)) {
@@ -460,7 +467,7 @@ tcp_cancel_rx(nni_aio *aio, int rv)
}
static void
-tcp_pipe_dorecv(tcp_pipe *p)
+tcptran_pipe_recv_start(tcptran_pipe *p)
{
nni_aio *rxaio;
nni_iov iov;
@@ -472,20 +479,20 @@ tcp_pipe_dorecv(tcp_pipe *p)
iov.iov_len = sizeof(p->rxlen);
nni_aio_set_iov(rxaio, 1, &iov);
- nni_plat_tcp_pipe_recv(p->tpp, rxaio);
+ nni_tcp_conn_recv(p->conn, rxaio);
}
static void
-tcp_pipe_recv(void *arg, nni_aio *aio)
+tcptran_pipe_recv(void *arg, nni_aio *aio)
{
- tcp_pipe *p = arg;
- int rv;
+ tcptran_pipe *p = arg;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tcp_cancel_rx, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tcptran_pipe_recv_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -493,75 +500,74 @@ tcp_pipe_recv(void *arg, nni_aio *aio)
nni_list_append(&p->recvq, aio);
if (nni_list_first(&p->recvq) == aio) {
- tcp_pipe_dorecv(p);
+ tcptran_pipe_recv_start(p);
}
nni_mtx_unlock(&p->mtx);
}
static uint16_t
-tcp_pipe_peer(void *arg)
+tcptran_pipe_peer(void *arg)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
return (p->peer);
}
static int
-tcp_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
+ tcptran_pipe *p = arg;
+ int rv;
+ nni_sockaddr sa;
memset(&sa, 0, sizeof(sa));
- if ((rv = nni_plat_tcp_pipe_sockname(p->tpp, &sa)) == 0) {
+ if ((rv = nni_tcp_conn_sockname(p->conn, &sa)) == 0) {
rv = nni_copyout_sockaddr(&sa, v, szp, t);
}
return (rv);
}
static int
-tcp_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
+ tcptran_pipe *p = arg;
+ int rv;
+ nni_sockaddr sa;
memset(&sa, 0, sizeof(sa));
- if ((rv = nni_plat_tcp_pipe_peername(p->tpp, &sa)) == 0) {
+ if ((rv = nni_tcp_conn_peername(p->conn, &sa)) == 0) {
rv = nni_copyout_sockaddr(&sa, v, szp, t);
}
return (rv);
}
static int
-tcp_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
return (nni_copyout_bool(p->keepalive, v, szp, t));
}
static int
-tcp_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_pipe *p = arg;
+ tcptran_pipe *p = arg;
return (nni_copyout_bool(p->nodelay, v, szp, t));
}
-// Note that the url *must* be in a modifiable buffer.
static void
-tcp_pipe_start(void *arg, nni_aio *aio)
+tcptran_pipe_start(void *arg, nni_aio *aio)
{
- tcp_pipe *p = arg;
- nni_aio * negaio;
- nni_iov iov;
- int rv;
+ tcptran_pipe *p = arg;
+ nni_aio * negaio;
+ nni_iov iov;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tcp_cancel_nego, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tcptran_pipe_nego_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -582,35 +588,39 @@ tcp_pipe_start(void *arg, nni_aio *aio)
iov.iov_len = 8;
iov.iov_buf = &p->txlen[0];
nni_aio_set_iov(negaio, 1, &iov);
- nni_plat_tcp_pipe_send(p->tpp, negaio);
+ nni_tcp_conn_send(p->conn, negaio);
nni_mtx_unlock(&p->mtx);
}
static void
-tcp_ep_fini(void *arg)
+tcptran_dialer_fini(void *arg)
{
- tcp_ep *ep = arg;
+ tcptran_dialer *d = arg;
- nni_aio_stop(ep->aio);
- if (ep->tep != NULL) {
- nni_plat_tcp_ep_fini(ep->tep);
+ nni_aio_stop(d->aio);
+ if (d->dialer != NULL) {
+ nni_tcp_dialer_fini(d->dialer);
}
- nni_aio_fini(ep->aio);
- nni_mtx_fini(&ep->mtx);
- NNI_FREE_STRUCT(ep);
+ nni_aio_fini(d->aio);
+ nni_mtx_fini(&d->mtx);
+ NNI_FREE_STRUCT(d);
+}
+
+static void
+tcptran_dialer_close(void *arg)
+{
+ tcptran_dialer *d = arg;
+
+ nni_aio_close(d->aio);
+ nni_tcp_dialer_close(d->dialer);
}
static int
-tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode)
+tcptran_dialer_init(void **dp, nni_url *url, nni_sock *sock)
{
- tcp_ep * ep;
- int rv;
- char * host;
- char * serv;
- nni_sockaddr rsa, lsa;
- nni_aio * aio;
- int passive;
- uint16_t af;
+ tcptran_dialer *d;
+ int rv;
+ uint16_t af;
if (strcmp(url->u_scheme, "tcp") == 0) {
af = NNG_AF_UNSPEC;
@@ -627,345 +637,543 @@ tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode)
return (NNG_EADDRINVAL);
}
if ((url->u_fragment != NULL) || (url->u_userinfo != NULL) ||
- (url->u_query != NULL)) {
+ (url->u_query != NULL) || (strlen(url->u_hostname) == 0) ||
+ (strlen(url->u_port) == 0)) {
return (NNG_EADDRINVAL);
}
- if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
- return (rv);
+ if ((d = NNI_ALLOC_STRUCT(d)) == NULL) {
+ return (NNG_ENOMEM);
}
+ nni_mtx_init(&d->mtx);
- if (strlen(url->u_hostname) == 0) {
- host = NULL;
- } else {
- host = url->u_hostname;
+ if (((rv = nni_tcp_dialer_init(&d->dialer)) != 0) ||
+ ((rv = nni_aio_init(&d->aio, tcptran_dialer_cb, d)) != 0)) {
+ tcptran_dialer_fini(d);
+ return (rv);
}
- if (strlen(url->u_port) == 0) {
- serv = NULL;
- } else {
- serv = url->u_port;
- }
- // XXX: arguably we could defer this part to the point we do a bind
- // or connect!
- if (mode == NNI_EP_MODE_DIAL) {
- passive = 0;
- lsa.s_family = af;
- nni_aio_set_input(aio, 0, &rsa);
- if ((host == NULL) || (serv == NULL)) {
- nni_aio_fini(aio);
- return (NNG_EADDRINVAL);
+ d->url = url;
+ d->proto = nni_sock_proto_id(sock);
+ d->nodelay = true;
+ d->keepalive = false;
+ d->af = af;
+
+ *dp = d;
+ return (0);
+}
+
+static void
+tcptran_dialer_cb(void *arg)
+{
+ tcptran_dialer *d = arg;
+ tcptran_pipe * p;
+ nni_tcp_conn * conn;
+ nni_aio * aio;
+ int rv;
+
+ nni_mtx_lock(&d->mtx);
+ aio = d->user_aio;
+ rv = nni_aio_result(d->aio);
+
+ if (aio == NULL) {
+ nni_mtx_unlock(&d->mtx);
+ if ((rv == 0) && !d->resolving) {
+ conn = nni_aio_get_output(d->aio, 0);
+ nni_tcp_conn_fini(conn);
}
- } else {
- passive = 1;
- rsa.s_family = af;
- nni_aio_set_input(aio, 0, &lsa);
+ return;
}
- nni_plat_tcp_resolv(host, serv, af, passive, aio);
- nni_aio_wait(aio);
- if ((rv = nni_aio_result(aio)) != 0) {
- nni_aio_fini(aio);
- return (rv);
+ if (rv != 0) {
+ d->user_aio = NULL;
+ nni_mtx_unlock(&d->mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
}
- nni_aio_fini(aio);
+ if (d->resolving) {
+ // Name resolution complete. Now go to next step.
+ d->resolving = false;
+ nni_tcp_dialer_dial(d->dialer, &d->sa, d->aio);
+ nni_mtx_unlock(&d->mtx);
+ return;
+ }
- if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
- return (NNG_ENOMEM);
+ d->user_aio = NULL;
+ conn = nni_aio_get_output(d->aio, 0);
+ NNI_ASSERT(conn != NULL);
+ if ((rv = tcptran_pipe_init(&p, conn)) != 0) {
+ nni_mtx_unlock(&d->mtx);
+ nni_tcp_conn_fini(conn);
+ nni_aio_finish_error(aio, rv);
+ return;
}
- nni_mtx_init(&ep->mtx);
- ep->url = url;
- if ((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) {
- tcp_ep_fini(ep);
- return (rv);
+ p->proto = d->proto;
+ p->rcvmax = d->rcvmax;
+ p->nodelay = d->nodelay;
+ p->keepalive = d->keepalive;
+ nni_mtx_unlock(&d->mtx);
+
+ (void) nni_tcp_conn_set_nodelay(conn, p->nodelay);
+ (void) nni_tcp_conn_set_keepalive(conn, p->keepalive);
+
+ nni_aio_set_output(aio, 0, p);
+ nni_aio_finish(aio, 0, 0);
+}
+
+static void
+tcptran_dialer_cancel(nni_aio *aio, int rv)
+{
+ tcptran_dialer *d = nni_aio_get_prov_data(aio);
+
+ nni_mtx_lock(&d->mtx);
+ if (d->user_aio != aio) {
+ nni_mtx_unlock(&d->mtx);
+ return;
}
+ d->user_aio = NULL;
+ nni_mtx_unlock(&d->mtx);
- if ((rv = nni_aio_init(&ep->aio, tcp_ep_cb, ep)) != 0) {
- tcp_ep_fini(ep);
- return (rv);
+ nni_aio_abort(d->aio, rv);
+ nni_aio_finish_error(aio, rv);
+}
+
+static void
+tcptran_dialer_connect(void *arg, nni_aio *aio)
+{
+ tcptran_dialer *d = arg;
+ int rv;
+
+ if (nni_aio_begin(aio) != 0) {
+ return;
}
- ep->proto = nni_sock_proto_id(sock);
- ep->nodelay = true;
- ep->keepalive = false;
+ nni_mtx_lock(&d->mtx);
+ NNI_ASSERT(d->user_aio == NULL);
- *epp = ep;
- return (0);
+ if ((rv = nni_aio_schedule(aio, tcptran_dialer_cancel, d)) != 0) {
+ nni_mtx_unlock(&d->mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
+ d->user_aio = aio;
+
+ d->resolving = true;
+
+ // Start the name resolution. Callback will see resolving, and then
+ // switch to doing actual connect.
+ nni_aio_set_input(d->aio, 0, &d->sa);
+ nni_tcp_resolv(d->url->u_hostname, d->url->u_port, d->af, 0, d->aio);
+ nni_mtx_unlock(&d->mtx);
}
static int
-tcp_dialer_init(void **epp, nni_url *url, nni_sock *sock)
+tcptran_dialer_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- return (tcp_ep_init(epp, url, sock, NNI_EP_MODE_DIAL));
+ tcptran_dialer *d = arg;
+
+ return (nni_copyout_str(d->url->u_rawurl, v, szp, t));
}
static int
-tcp_listener_init(void **epp, nni_url *url, nni_sock *sock)
+tcptran_dialer_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- return (tcp_ep_init(epp, url, sock, NNI_EP_MODE_LISTEN));
+ tcptran_dialer *d = arg;
+ return (nni_copyout_size(d->rcvmax, v, szp, t));
}
-static void
-tcp_ep_close(void *arg)
+static int
+tcptran_dialer_set_recvmaxsz(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
-
- nni_aio_close(ep->aio);
+ tcptran_dialer *d = arg;
+ size_t val;
+ int rv;
+ if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {
+ nni_mtx_lock(&d->mtx);
+ d->rcvmax = val;
+ nni_mtx_unlock(&d->mtx);
+ }
+ return (rv);
+}
- nni_mtx_lock(&ep->mtx);
- nni_plat_tcp_ep_close(ep->tep);
- nni_mtx_unlock(&ep->mtx);
+static int
+tcptran_dialer_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
+{
+ tcptran_dialer *d = arg;
+ int rv;
+ nni_mtx_lock(&d->mtx);
+ rv = nni_copyout_bool(d->nodelay, v, szp, t);
+ nni_mtx_unlock(&d->mtx);
+ return (rv);
}
static int
-tcp_ep_bind(void *arg)
+tcptran_dialer_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
- int rv;
+ tcptran_dialer *d = arg;
+ bool val;
+ int rv;
+ if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
+ nni_mtx_lock(&d->mtx);
+ d->nodelay = val;
+ nni_mtx_unlock(&d->mtx);
+ }
+ return (rv);
+}
- nni_mtx_lock(&ep->mtx);
- rv = nni_plat_tcp_ep_listen(ep->tep, &ep->bsa);
- nni_mtx_unlock(&ep->mtx);
+static int
+tcptran_dialer_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
+{
+ tcptran_dialer *d = arg;
+ return (nni_copyout_bool(d->keepalive, v, szp, t));
+}
+static int
+tcptran_dialer_set_keepalive(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
+{
+ tcptran_dialer *d = arg;
+ bool val;
+ int rv;
+ if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
+ nni_mtx_lock(&d->mtx);
+ d->keepalive = val;
+ nni_mtx_unlock(&d->mtx);
+ }
return (rv);
}
static void
-tcp_ep_finish(tcp_ep *ep)
+tcptran_listener_fini(void *arg)
{
- nni_aio * aio;
- int rv;
- tcp_pipe *pipe = NULL;
+ tcptran_listener *l = arg;
- if ((rv = nni_aio_result(ep->aio)) != 0) {
- goto done;
+ nni_aio_stop(l->aio);
+ if (l->listener != NULL) {
+ nni_tcp_listener_fini(l->listener);
+ }
+ nni_aio_fini(l->aio);
+ nni_mtx_fini(&l->mtx);
+ NNI_FREE_STRUCT(l);
+}
+
+static int
+tcptran_listener_init(void **lp, nni_url *url, nni_sock *sock)
+{
+ tcptran_listener *l;
+ int rv;
+ char * host;
+ nni_aio * aio;
+ uint16_t af;
+
+ 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);
}
- NNI_ASSERT(nni_aio_get_output(ep->aio, 0) != NULL);
- // Attempt to allocate the parent pipe. If this fails we'll
- // drop the connection (ENOMEM probably).
- rv = tcp_pipe_init(&pipe, ep, nni_aio_get_output(ep->aio, 0));
+ // Check for invalid URL components.
+ if ((strlen(url->u_path) != 0) && (strcmp(url->u_path, "/") != 0)) {
+ return (NNG_EADDRINVAL);
+ }
+ if ((url->u_fragment != NULL) || (url->u_userinfo != NULL) ||
+ (url->u_query != NULL)) {
+ return (NNG_EADDRINVAL);
+ }
-done:
- aio = ep->user_aio;
- ep->user_aio = NULL;
+ if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ nni_mtx_init(&l->mtx);
+ l->url = url;
- if ((aio != NULL) && (rv == 0)) {
- nni_aio_set_output(aio, 0, pipe);
- nni_aio_finish(aio, 0, 0);
- return;
+ if (strlen(url->u_hostname) == 0) {
+ host = NULL;
+ } else {
+ host = url->u_hostname;
}
- if (pipe != NULL) {
- tcp_pipe_fini(pipe);
+
+ if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
+ tcptran_listener_fini(l);
+ return (rv);
}
- if (aio != NULL) {
- NNI_ASSERT(rv != 0);
- nni_aio_finish_error(aio, rv);
+
+ // 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.
+
+ nni_aio_set_input(aio, 0, &l->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_listener_fini(l);
+ return (rv);
+ }
+
+ if ((rv = nni_tcp_listener_init(&l->listener)) != 0) {
+ tcptran_listener_fini(l);
+ return (rv);
+ }
+
+ if ((rv = nni_aio_init(&l->aio, tcptran_listener_cb, l)) != 0) {
+ tcptran_listener_fini(l);
+ return (rv);
}
+ l->proto = nni_sock_proto_id(sock);
+ l->nodelay = true;
+ l->keepalive = false;
+ l->bsa = l->sa;
+
+ *lp = l;
+ return (0);
}
static void
-tcp_ep_cb(void *arg)
+tcptran_listener_close(void *arg)
{
- tcp_ep *ep = arg;
+ tcptran_listener *l = arg;
- nni_mtx_lock(&ep->mtx);
- tcp_ep_finish(ep);
- nni_mtx_unlock(&ep->mtx);
+ nni_aio_close(l->aio);
+ nni_tcp_listener_close(l->listener);
}
-static void
-tcp_cancel_ep(nni_aio *aio, int rv)
+static int
+tcptran_listener_bind(void *arg)
{
- tcp_ep *ep = nni_aio_get_prov_data(aio);
+ tcptran_listener *l = arg;
+ int rv;
- nni_mtx_lock(&ep->mtx);
- if (ep->user_aio != aio) {
- nni_mtx_unlock(&ep->mtx);
- return;
- }
- ep->user_aio = NULL;
- nni_mtx_unlock(&ep->mtx);
+ l->bsa = l->sa;
+ nni_mtx_lock(&l->mtx);
+ rv = nni_tcp_listener_listen(l->listener, &l->bsa);
+ nni_mtx_unlock(&l->mtx);
- nni_aio_abort(ep->aio, rv);
- nni_aio_finish_error(aio, rv);
+ return (rv);
}
static void
-tcp_ep_accept(void *arg, nni_aio *aio)
+tcptran_listener_cb(void *arg)
{
- tcp_ep *ep = arg;
- int rv;
+ tcptran_listener *l = arg;
+ nni_aio * aio;
+ int rv;
+ tcptran_pipe * p = NULL;
+ nni_tcp_conn * conn;
+
+ nni_mtx_lock(&l->mtx);
+ rv = nni_aio_result(l->aio);
+ aio = l->user_aio;
+ l->user_aio = NULL;
+
+ if (aio == NULL) {
+ nni_mtx_unlock(&l->mtx);
+ if (rv == 0) {
+ conn = nni_aio_get_output(l->aio, 0);
+ nni_tcp_conn_fini(conn);
+ }
+ return;
+ }
- if (nni_aio_begin(aio) != 0) {
+ if (rv != 0) {
+ nni_mtx_unlock(&l->mtx);
+ nni_aio_finish_error(aio, rv);
return;
}
- nni_mtx_lock(&ep->mtx);
- NNI_ASSERT(ep->user_aio == NULL);
- if ((rv = nni_aio_schedule(aio, tcp_cancel_ep, ep)) != 0) {
- nni_mtx_unlock(&ep->mtx);
+ conn = nni_aio_get_output(l->aio, 0);
+
+ NNI_ASSERT(conn != NULL);
+ if ((rv = tcptran_pipe_init(&p, conn)) != 0) {
+ nni_mtx_unlock(&l->mtx);
+ nni_tcp_conn_fini(conn);
nni_aio_finish_error(aio, rv);
return;
}
- ep->user_aio = aio;
- nni_plat_tcp_ep_accept(ep->tep, ep->aio);
- nni_mtx_unlock(&ep->mtx);
+ p->proto = l->proto;
+ p->rcvmax = l->rcvmax;
+ p->nodelay = l->nodelay;
+ p->keepalive = l->keepalive;
+ nni_mtx_unlock(&l->mtx);
+
+ (void) nni_tcp_conn_set_nodelay(conn, p->nodelay);
+ (void) nni_tcp_conn_set_keepalive(conn, p->keepalive);
+
+ nni_aio_set_output(aio, 0, p);
+ nni_aio_finish(aio, 0, 0);
}
static void
-tcp_ep_connect(void *arg, nni_aio *aio)
+tcptran_listener_cancel(nni_aio *aio, int rv)
{
- tcp_ep *ep = arg;
- int rv;
+ tcptran_listener *l = nni_aio_get_prov_data(aio);
- if (nni_aio_begin(aio) != 0) {
- return;
- }
- nni_mtx_lock(&ep->mtx);
- NNI_ASSERT(ep->user_aio == NULL);
-
- if ((rv = nni_aio_schedule(aio, tcp_cancel_ep, ep)) != 0) {
- nni_mtx_unlock(&ep->mtx);
- nni_aio_finish_error(aio, rv);
+ nni_mtx_lock(&l->mtx);
+ if (l->user_aio != aio) {
+ nni_mtx_unlock(&l->mtx);
return;
}
- ep->user_aio = aio;
+ l->user_aio = NULL;
+ nni_mtx_unlock(&l->mtx);
- nni_plat_tcp_ep_connect(ep->tep, ep->aio);
- nni_mtx_unlock(&ep->mtx);
+ nni_aio_abort(l->aio, rv);
+ nni_aio_finish_error(aio, rv);
}
-static int
-tcp_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
+static void
+tcptran_listener_accept(void *arg, nni_aio *aio)
{
- tcp_ep *ep = arg;
- size_t val;
- int rv;
- 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);
+ tcptran_listener *l = arg;
+ int rv;
+
+ if (nni_aio_begin(aio) != 0) {
+ return;
}
- return (rv);
-}
+ nni_mtx_lock(&l->mtx);
+ NNI_ASSERT(l->user_aio == NULL);
-static int
-tcp_ep_chk_recvmaxsz(const void *v, size_t sz, nni_opt_type t)
-{
- return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
+ if ((rv = nni_aio_schedule(aio, tcptran_listener_cancel, l)) != 0) {
+ nni_mtx_unlock(&l->mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
+ l->user_aio = aio;
+
+ nni_tcp_listener_accept(l->listener, l->aio);
+ nni_mtx_unlock(&l->mtx);
}
static int
-tcp_ep_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
+tcptran_listener_set_nodelay(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
- bool val;
- int rv;
+ tcptran_listener *l = arg;
+ bool val;
+ int rv;
if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
- nni_mtx_lock(&ep->mtx);
- ep->nodelay = val;
- nni_mtx_unlock(&ep->mtx);
+ nni_mtx_lock(&l->mtx);
+ l->nodelay = val;
+ nni_mtx_unlock(&l->mtx);
}
return (rv);
}
static int
-tcp_ep_chk_bool(const void *v, size_t sz, nni_opt_type t)
+tcptran_listener_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- return (nni_copyin_bool(NULL, v, sz, t));
+ tcptran_listener *l = arg;
+ int rv;
+ nni_mtx_lock(&l->mtx);
+ rv = nni_copyout_bool(l->nodelay, v, szp, t);
+ nni_mtx_unlock(&l->mtx);
+ return (rv);
}
static int
-tcp_ep_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_listener_set_recvmaxsz(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_bool(ep->nodelay, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
+ tcptran_listener *l = arg;
+ size_t val;
+ int rv;
+ if ((rv = nni_copyin_size(&val, v, sz, 0, NNI_MAXSZ, t)) == 0) {
+ nni_mtx_lock(&l->mtx);
+ l->rcvmax = val;
+ nni_mtx_unlock(&l->mtx);
+ }
return (rv);
}
static int
-tcp_ep_set_keepalive(void *arg, const void *v, size_t sz, nni_opt_type t)
+tcptran_listener_set_keepalive(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
- bool val;
- int rv;
+ tcptran_listener *l = arg;
+ bool val;
+ int rv;
if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
- nni_mtx_lock(&ep->mtx);
- ep->keepalive = val;
- nni_mtx_unlock(&ep->mtx);
+ nni_mtx_lock(&l->mtx);
+ l->keepalive = val;
+ nni_mtx_unlock(&l->mtx);
}
return (rv);
}
static int
-tcp_ep_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_listener_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_bool(ep->keepalive, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
+ tcptran_listener *l = arg;
+ int rv;
+ nni_mtx_lock(&l->mtx);
+ rv = nni_copyout_bool(l->keepalive, v, szp, t);
+ nni_mtx_unlock(&l->mtx);
return (rv);
}
static int
-tcp_dialer_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_listener_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_ep *ep = arg;
+ tcptran_listener *l = arg;
+ char ustr[128];
+ char ipstr[48]; // max for IPv6 addresses including []
+ char portstr[6]; // max for 16-bit port
- return (nni_copyout_str(ep->url->u_rawurl, v, szp, t));
+ nni_ntop(&l->bsa, ipstr, portstr);
+ snprintf(ustr, sizeof(ustr), "tcp://%s:%s", ipstr, portstr);
+ return (nni_copyout_str(ustr, v, szp, t));
}
static int
-tcp_listener_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_listener_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tcp_ep *ep = arg;
- char ustr[128];
- char ipstr[48]; // max for IPv6 addresses including []
- char portstr[6]; // max for 16-bit port
+ tcptran_listener *l = arg;
+ return (nni_copyout_size(l->rcvmax, v, szp, t));
+}
- nni_plat_tcp_ntop(&ep->bsa, ipstr, portstr);
- snprintf(ustr, sizeof(ustr), "tcp://%s:%s", ipstr, portstr);
- return (nni_copyout_str(ustr, v, szp, t));
+static int
+tcptran_check_bool(const void *v, size_t sz, nni_opt_type t)
+{
+ return (nni_copyin_bool(NULL, v, sz, t));
}
static int
-tcp_ep_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
+tcptran_check_recvmaxsz(const void *v, size_t sz, nni_opt_type t)
{
- tcp_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_size(ep->rcvmax, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
- return (rv);
+ return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
}
-static nni_tran_option tcp_pipe_options[] = {
+static nni_tran_option tcptran_pipe_options[] = {
{
.o_name = NNG_OPT_LOCADDR,
.o_type = NNI_TYPE_SOCKADDR,
- .o_get = tcp_pipe_get_locaddr,
+ .o_get = tcptran_pipe_get_locaddr,
},
{
.o_name = NNG_OPT_REMADDR,
.o_type = NNI_TYPE_SOCKADDR,
- .o_get = tcp_pipe_get_remaddr,
+ .o_get = tcptran_pipe_get_remaddr,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_pipe_get_keepalive,
+ .o_get = tcptran_pipe_get_keepalive,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_pipe_get_nodelay,
+ .o_get = tcptran_pipe_get_nodelay,
},
// terminate list
{
@@ -973,43 +1181,43 @@ static nni_tran_option tcp_pipe_options[] = {
},
};
-static nni_tran_pipe_ops tcp_pipe_ops = {
- .p_fini = tcp_pipe_fini,
- .p_start = tcp_pipe_start,
- .p_stop = tcp_pipe_stop,
- .p_send = tcp_pipe_send,
- .p_recv = tcp_pipe_recv,
- .p_close = tcp_pipe_close,
- .p_peer = tcp_pipe_peer,
- .p_options = tcp_pipe_options,
+static nni_tran_pipe_ops tcptran_pipe_ops = {
+ .p_fini = tcptran_pipe_fini,
+ .p_start = tcptran_pipe_start,
+ .p_stop = tcptran_pipe_stop,
+ .p_send = tcptran_pipe_send,
+ .p_recv = tcptran_pipe_recv,
+ .p_close = tcptran_pipe_close,
+ .p_peer = tcptran_pipe_peer,
+ .p_options = tcptran_pipe_options,
};
-static nni_tran_option tcp_dialer_options[] = {
+static nni_tran_option tcptran_dialer_options[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_type = NNI_TYPE_SIZE,
- .o_get = tcp_ep_get_recvmaxsz,
- .o_set = tcp_ep_set_recvmaxsz,
- .o_chk = tcp_ep_chk_recvmaxsz,
+ .o_get = tcptran_dialer_get_recvmaxsz,
+ .o_set = tcptran_dialer_set_recvmaxsz,
+ .o_chk = tcptran_check_recvmaxsz,
},
{
.o_name = NNG_OPT_URL,
.o_type = NNI_TYPE_STRING,
- .o_get = tcp_dialer_get_url,
+ .o_get = tcptran_dialer_get_url,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_ep_get_nodelay,
- .o_set = tcp_ep_set_nodelay,
- .o_chk = tcp_ep_chk_bool,
+ .o_get = tcptran_dialer_get_nodelay,
+ .o_set = tcptran_dialer_set_nodelay,
+ .o_chk = tcptran_check_bool,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_ep_get_keepalive,
- .o_set = tcp_ep_set_keepalive,
- .o_chk = tcp_ep_chk_bool,
+ .o_get = tcptran_dialer_get_keepalive,
+ .o_set = tcptran_dialer_set_keepalive,
+ .o_chk = tcptran_check_bool,
},
// terminate list
{
@@ -1017,32 +1225,32 @@ static nni_tran_option tcp_dialer_options[] = {
},
};
-static nni_tran_option tcp_listener_options[] = {
+static nni_tran_option tcptran_listener_options[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_type = NNI_TYPE_SIZE,
- .o_get = tcp_ep_get_recvmaxsz,
- .o_set = tcp_ep_set_recvmaxsz,
- .o_chk = tcp_ep_chk_recvmaxsz,
+ .o_get = tcptran_listener_get_recvmaxsz,
+ .o_set = tcptran_listener_set_recvmaxsz,
+ .o_chk = tcptran_check_recvmaxsz,
},
{
.o_name = NNG_OPT_URL,
.o_type = NNI_TYPE_STRING,
- .o_get = tcp_listener_get_url,
+ .o_get = tcptran_listener_get_url,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_ep_get_nodelay,
- .o_set = tcp_ep_set_nodelay,
- .o_chk = tcp_ep_chk_bool,
+ .o_get = tcptran_listener_get_nodelay,
+ .o_set = tcptran_listener_set_nodelay,
+ .o_chk = tcptran_check_bool,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tcp_ep_get_keepalive,
- .o_set = tcp_ep_set_keepalive,
- .o_chk = tcp_ep_chk_bool,
+ .o_get = tcptran_listener_get_keepalive,
+ .o_set = tcptran_listener_set_keepalive,
+ .o_chk = tcptran_check_bool,
},
// terminate list
{
@@ -1050,51 +1258,51 @@ static nni_tran_option tcp_listener_options[] = {
},
};
-static nni_tran_dialer_ops tcp_dialer_ops = {
- .d_init = tcp_dialer_init,
- .d_fini = tcp_ep_fini,
- .d_connect = tcp_ep_connect,
- .d_close = tcp_ep_close,
- .d_options = tcp_dialer_options,
+static nni_tran_dialer_ops tcptran_dialer_ops = {
+ .d_init = tcptran_dialer_init,
+ .d_fini = tcptran_dialer_fini,
+ .d_connect = tcptran_dialer_connect,
+ .d_close = tcptran_dialer_close,
+ .d_options = tcptran_dialer_options,
};
-static nni_tran_listener_ops tcp_listener_ops = {
- .l_init = tcp_listener_init,
- .l_fini = tcp_ep_fini,
- .l_bind = tcp_ep_bind,
- .l_accept = tcp_ep_accept,
- .l_close = tcp_ep_close,
- .l_options = tcp_listener_options,
+static nni_tran_listener_ops tcptran_listener_ops = {
+ .l_init = tcptran_listener_init,
+ .l_fini = tcptran_listener_fini,
+ .l_bind = tcptran_listener_bind,
+ .l_accept = tcptran_listener_accept,
+ .l_close = tcptran_listener_close,
+ .l_options = tcptran_listener_options,
};
static nni_tran tcp_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tcp",
- .tran_dialer = &tcp_dialer_ops,
- .tran_listener = &tcp_listener_ops,
- .tran_pipe = &tcp_pipe_ops,
- .tran_init = tcp_tran_init,
- .tran_fini = tcp_tran_fini,
+ .tran_dialer = &tcptran_dialer_ops,
+ .tran_listener = &tcptran_listener_ops,
+ .tran_pipe = &tcptran_pipe_ops,
+ .tran_init = tcptran_init,
+ .tran_fini = tcptran_fini,
};
static nni_tran tcp4_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tcp4",
- .tran_dialer = &tcp_dialer_ops,
- .tran_listener = &tcp_listener_ops,
- .tran_pipe = &tcp_pipe_ops,
- .tran_init = tcp_tran_init,
- .tran_fini = tcp_tran_fini,
+ .tran_dialer = &tcptran_dialer_ops,
+ .tran_listener = &tcptran_listener_ops,
+ .tran_pipe = &tcptran_pipe_ops,
+ .tran_init = tcptran_init,
+ .tran_fini = tcptran_fini,
};
static nni_tran tcp6_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tcp6",
- .tran_dialer = &tcp_dialer_ops,
- .tran_listener = &tcp_listener_ops,
- .tran_pipe = &tcp_pipe_ops,
- .tran_init = tcp_tran_init,
- .tran_fini = tcp_tran_fini,
+ .tran_dialer = &tcptran_dialer_ops,
+ .tran_listener = &tcptran_listener_ops,
+ .tran_pipe = &tcptran_pipe_ops,
+ .tran_init = tcptran_init,
+ .tran_fini = tcptran_fini,
};
int
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index 5e1a1e8d..b1bdddb8 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -22,17 +22,19 @@
// supplied as well, and uses the supplemental TLS v1.2 code. It is not
// an accident that this very closely resembles the TCP transport itself.
-typedef struct tls_pipe tls_pipe;
-typedef struct tls_ep tls_ep;
-
-// tls_pipe is one end of a TLS connection.
-struct tls_pipe {
- nni_plat_tcp_pipe *tcp;
- uint16_t peer;
- uint16_t proto;
- size_t rcvmax;
- bool nodelay;
- bool keepalive;
+typedef struct tlstran_ep tlstran_ep;
+typedef struct tlstran_dialer tlstran_dialer;
+typedef struct tlstran_listener tlstran_listener;
+typedef struct tlstran_pipe tlstran_pipe;
+
+// tlstran_pipe is one end of a TLS connection.
+struct tlstran_pipe {
+ nni_tls *tls;
+ uint16_t peer;
+ uint16_t proto;
+ size_t rcvmax;
+ bool nodelay;
+ bool keepalive;
nni_list sendq;
nni_list recvq;
@@ -49,47 +51,62 @@ struct tls_pipe {
nni_aio *negaio;
nni_msg *rxmsg;
nni_mtx mtx;
- nni_tls *tls;
};
-struct tls_ep {
- nni_plat_tcp_ep *tep;
- uint16_t proto;
- size_t rcvmax;
- int authmode;
- nni_aio * aio;
- nni_aio * user_aio;
- nni_mtx mtx;
- nng_tls_config * cfg;
- nng_sockaddr bsa;
- nni_url * url;
- int mode;
- bool nodelay;
- bool keepalive;
+// Stuff that is common to both dialers and listeners.
+struct tlstran_ep {
+ uint16_t proto;
+ size_t rcvmax;
+ bool nodelay;
+ bool keepalive;
+ int authmode;
+ nng_tls_config *cfg;
+ nni_url * url;
+ nni_mtx mtx;
+};
+
+struct tlstran_dialer {
+ tlstran_ep ep; // must be first
+ nni_tcp_dialer *dialer;
+ uint16_t af;
+ nni_aio * aio;
+ nni_aio * user_aio;
+ bool resolving;
+ nng_sockaddr sa;
+};
+
+struct tlstran_listener {
+ tlstran_ep ep; // must be first
+ nni_tcp_listener *listener;
+ nni_aio * aio;
+ nni_aio * user_aio;
+ nng_sockaddr sa;
+ nng_sockaddr bsa; // bound addr
};
-static void tls_pipe_dorecv(tls_pipe *);
-static void tls_pipe_dosend(tls_pipe *, nni_aio *);
-static void tls_pipe_send_cb(void *);
-static void tls_pipe_recv_cb(void *);
-static void tls_pipe_nego_cb(void *);
-static void tls_ep_cb(void *arg);
+static void tlstran_pipe_send_start(tlstran_pipe *);
+static void tlstran_pipe_recv_start(tlstran_pipe *);
+static void tlstran_pipe_send_cb(void *);
+static void tlstran_pipe_recv_cb(void *);
+static void tlstran_pipe_nego_cb(void *);
+static void tlstran_dialer_cb(void *);
+static void tlstran_listener_cb(void *);
static int
-tls_tran_init(void)
+tlstran_init(void)
{
return (0);
}
static void
-tls_tran_fini(void)
+tlstran_fini(void)
{
}
static void
-tls_pipe_close(void *arg)
+tlstran_pipe_close(void *arg)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
nni_aio_close(p->rxaio);
nni_aio_close(p->txaio);
@@ -99,9 +116,9 @@ tls_pipe_close(void *arg)
}
static void
-tls_pipe_stop(void *arg)
+tlstran_pipe_stop(void *arg)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
nni_aio_stop(p->rxaio);
nni_aio_stop(p->txaio);
@@ -109,14 +126,13 @@ tls_pipe_stop(void *arg)
}
static void
-tls_pipe_fini(void *arg)
+tlstran_pipe_fini(void *arg)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
nni_aio_fini(p->rxaio);
nni_aio_fini(p->txaio);
nni_aio_fini(p->negaio);
-
if (p->tls != NULL) {
nni_tls_fini(p->tls);
}
@@ -125,41 +141,34 @@ tls_pipe_fini(void *arg)
}
static int
-tls_pipe_init(tls_pipe **pipep, tls_ep *ep, void *tpp)
+tlstran_pipe_init(tlstran_pipe **pipep, nni_tls *tls)
{
- tls_pipe * p;
- nni_plat_tcp_pipe *tcp = tpp;
- int rv;
+ tlstran_pipe *p;
+ int rv;
if ((p = NNI_ALLOC_STRUCT(p)) == NULL) {
return (NNG_ENOMEM);
}
nni_mtx_init(&p->mtx);
- if (((rv = nni_tls_init(&p->tls, ep->cfg, tcp)) != 0) ||
- ((rv = nni_aio_init(&p->txaio, tls_pipe_send_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->rxaio, tls_pipe_recv_cb, p)) != 0) ||
- ((rv = nni_aio_init(&p->negaio, tls_pipe_nego_cb, p)) != 0)) {
- tls_pipe_fini(p);
+ 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->negaio, tlstran_pipe_nego_cb, p)) != 0)) {
+ tlstran_pipe_fini(p);
return (rv);
}
nni_aio_list_init(&p->recvq);
nni_aio_list_init(&p->sendq);
- p->proto = ep->proto;
- p->rcvmax = ep->rcvmax;
- p->tcp = tcp;
- p->keepalive = ep->keepalive;
- p->nodelay = ep->nodelay;
-
+ p->tls = tls;
*pipep = p;
return (0);
}
static void
-tls_cancel_nego(nni_aio *aio, int rv)
+tlstran_pipe_cancel_nego(nni_aio *aio, int rv)
{
- tls_pipe *p = nni_aio_get_prov_data(aio);
+ tlstran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (p->user_negaio != aio) {
@@ -174,11 +183,11 @@ tls_cancel_nego(nni_aio *aio, int rv)
}
static void
-tls_pipe_nego_cb(void *arg)
+tlstran_pipe_nego_cb(void *arg)
{
- tls_pipe *p = arg;
- nni_aio * aio = p->negaio;
- int rv;
+ tlstran_pipe *p = arg;
+ nni_aio * aio = p->negaio;
+ int rv;
nni_mtx_lock(&p->mtx);
if ((rv = nni_aio_result(aio)) != 0) {
@@ -237,14 +246,14 @@ done:
}
static void
-tls_pipe_send_cb(void *arg)
+tlstran_pipe_send_cb(void *arg)
{
- tls_pipe *p = arg;
- int rv;
- nni_aio * aio;
- size_t n;
- nni_msg * msg;
- nni_aio * txaio = p->txaio;
+ tlstran_pipe *p = arg;
+ int rv;
+ nni_aio * aio;
+ size_t n;
+ nni_msg * msg;
+ nni_aio * txaio = p->txaio;
nni_mtx_lock(&p->mtx);
aio = nni_list_first(&p->sendq);
@@ -269,9 +278,7 @@ tls_pipe_send_cb(void *arg)
return;
}
nni_aio_list_remove(aio);
- if (!nni_list_empty(&p->sendq)) {
- tls_pipe_dosend(p, nni_list_first(&p->sendq));
- }
+ tlstran_pipe_send_start(p);
nni_mtx_unlock(&p->mtx);
msg = nni_aio_get_msg(aio);
@@ -282,14 +289,14 @@ tls_pipe_send_cb(void *arg)
}
static void
-tls_pipe_recv_cb(void *arg)
+tlstran_pipe_recv_cb(void *arg)
{
- tls_pipe *p = arg;
- nni_aio * aio;
- int rv;
- size_t n;
- nni_msg * msg;
- nni_aio * rxaio = p->rxaio;
+ tlstran_pipe *p = arg;
+ nni_aio * aio;
+ int rv;
+ size_t n;
+ nni_msg * msg;
+ nni_aio * rxaio = p->rxaio;
nni_mtx_lock(&p->mtx);
aio = nni_list_first(&p->recvq);
@@ -345,7 +352,7 @@ tls_pipe_recv_cb(void *arg)
msg = p->rxmsg;
p->rxmsg = NULL;
if (!nni_list_empty(&p->recvq)) {
- tls_pipe_dorecv(p);
+ tlstran_pipe_recv_start(p);
}
nni_mtx_unlock(&p->mtx);
@@ -365,9 +372,9 @@ recv_error:
}
static void
-tls_cancel_tx(nni_aio *aio, int rv)
+tlstran_pipe_send_cancel(nni_aio *aio, int rv)
{
- tls_pipe *p = nni_aio_get_prov_data(aio);
+ tlstran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (!nni_aio_list_active(aio)) {
@@ -389,14 +396,19 @@ tls_cancel_tx(nni_aio *aio, int rv)
}
static void
-tls_pipe_dosend(tls_pipe *p, nni_aio *aio)
+tlstran_pipe_send_start(tlstran_pipe *p)
{
nni_aio *txaio;
+ nni_aio *aio;
nni_msg *msg;
int niov;
nni_iov iov[3];
uint64_t len;
+ if ((aio = nni_list_first(&p->sendq)) == NULL) {
+ return;
+ }
+
msg = nni_aio_get_msg(aio);
len = nni_msg_len(msg) + nni_msg_header_len(msg);
@@ -423,31 +435,31 @@ tls_pipe_dosend(tls_pipe *p, nni_aio *aio)
}
static void
-tls_pipe_send(void *arg, nni_aio *aio)
+tlstran_pipe_send(void *arg, nni_aio *aio)
{
- tls_pipe *p = arg;
- int rv;
+ tlstran_pipe *p = arg;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tls_cancel_tx, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tlstran_pipe_send_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
}
nni_list_append(&p->sendq, aio);
if (nni_list_first(&p->sendq) == aio) {
- tls_pipe_dosend(p, aio);
+ tlstran_pipe_send_start(p);
}
nni_mtx_unlock(&p->mtx);
}
static void
-tls_cancel_rx(nni_aio *aio, int rv)
+tlstran_pipe_recv_cancel(nni_aio *aio, int rv)
{
- tls_pipe *p = nni_aio_get_prov_data(aio);
+ tlstran_pipe *p = nni_aio_get_prov_data(aio);
nni_mtx_lock(&p->mtx);
if (!nni_aio_list_active(aio)) {
@@ -468,7 +480,7 @@ tls_cancel_rx(nni_aio *aio, int rv)
}
static void
-tls_pipe_dorecv(tls_pipe *p)
+tlstran_pipe_recv_start(tlstran_pipe *p)
{
nni_aio *rxaio;
nni_iov iov;
@@ -484,16 +496,16 @@ tls_pipe_dorecv(tls_pipe *p)
}
static void
-tls_pipe_recv(void *arg, nni_aio *aio)
+tlstran_pipe_recv(void *arg, nni_aio *aio)
{
- tls_pipe *p = arg;
- int rv;
+ tlstran_pipe *p = arg;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tls_cancel_rx, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tlstran_pipe_recv_cancel, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -501,25 +513,25 @@ tls_pipe_recv(void *arg, nni_aio *aio)
nni_aio_list_append(&p->recvq, aio);
if (nni_list_first(&p->recvq) == aio) {
- tls_pipe_dorecv(p);
+ tlstran_pipe_recv_start(p);
}
nni_mtx_unlock(&p->mtx);
}
static uint16_t
-tls_pipe_peer(void *arg)
+tlstran_pipe_peer(void *arg)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
return (p->peer);
}
static int
-tls_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
+ tlstran_pipe *p = arg;
+ int rv;
+ nni_sockaddr sa;
memset(&sa, 0, sizeof(sa));
if ((rv = nni_tls_sockname(p->tls, &sa)) == 0) {
@@ -529,11 +541,11 @@ tls_pipe_get_locaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
}
static int
-tls_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_pipe * p = arg;
- int rv;
- nni_sockaddr sa;
+ tlstran_pipe *p = arg;
+ int rv;
+ nni_sockaddr sa;
memset(&sa, 0, sizeof(sa));
if ((rv = nni_tls_peername(p->tls, &sa)) == 0) {
@@ -543,32 +555,32 @@ tls_pipe_get_remaddr(void *arg, void *v, size_t *szp, nni_opt_type t)
}
static int
-tls_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_pipe_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
return (nni_copyout_bool(p->keepalive, v, szp, t));
}
static int
-tls_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_pipe_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
return (nni_copyout_bool(p->nodelay, v, szp, t));
}
static void
-tls_pipe_start(void *arg, nni_aio *aio)
+tlstran_pipe_start(void *arg, nni_aio *aio)
{
- tls_pipe *p = arg;
- nni_aio * negaio;
- nni_iov iov;
- int rv;
+ tlstran_pipe *p = arg;
+ nni_aio * negaio;
+ nni_iov iov;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
nni_mtx_lock(&p->mtx);
- if ((rv = nni_aio_schedule(aio, tls_cancel_nego, p)) != 0) {
+ if ((rv = nni_aio_schedule(aio, tlstran_pipe_cancel_nego, p)) != 0) {
nni_mtx_unlock(&p->mtx);
nni_aio_finish_error(aio, rv);
return;
@@ -594,35 +606,39 @@ tls_pipe_start(void *arg, nni_aio *aio)
}
static void
-tls_ep_fini(void *arg)
+tlstran_dialer_fini(void *arg)
{
- tls_ep *ep = arg;
+ tlstran_dialer *d = arg;
- nni_aio_stop(ep->aio);
- if (ep->tep != NULL) {
- nni_plat_tcp_ep_fini(ep->tep);
+ nni_aio_stop(d->aio);
+ if (d->dialer != NULL) {
+ nni_tcp_dialer_fini(d->dialer);
}
- if (ep->cfg) {
- nni_tls_config_fini(ep->cfg);
+ nni_aio_fini(d->aio);
+ if (d->ep.cfg != NULL) {
+ nni_tls_config_fini(d->ep.cfg);
}
- nni_aio_fini(ep->aio);
- nni_mtx_fini(&ep->mtx);
- NNI_FREE_STRUCT(ep);
+ nni_mtx_fini(&d->ep.mtx);
+ NNI_FREE_STRUCT(d);
+}
+
+static void
+tlstran_dialer_close(void *arg)
+{
+ tlstran_dialer *d = arg;
+
+ nni_aio_close(d->aio);
+ nni_tcp_dialer_close(d->dialer);
}
static int
-tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode)
+tlstran_dialer_init(void **dp, nni_url *url, nni_sock *sock)
{
- tls_ep * ep;
- int rv;
- char * host;
- char * serv;
- nni_sockaddr rsa, lsa;
- nni_aio * aio;
- int passive;
- nng_tls_mode tlsmode;
- nng_tls_auth_mode authmode;
- uint16_t af;
+ tlstran_dialer *d;
+ int rv;
+ uint16_t af;
+ char * host = url->u_hostname;
+ char * port = url->u_port;
if (strcmp(url->u_scheme, "tls+tcp") == 0) {
af = NNG_AF_UNSPEC;
@@ -639,232 +655,374 @@ tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode)
return (NNG_EADDRINVAL);
}
if ((url->u_fragment != NULL) || (url->u_userinfo != NULL) ||
- (url->u_query != NULL)) {
+ (url->u_query != NULL) || (host == NULL) || (port == NULL) ||
+ (strlen(host) == 0) || (strlen(port) == 0)) {
return (NNG_EADDRINVAL);
}
+ if ((d = NNI_ALLOC_STRUCT(d)) == NULL) {
+ return (NNG_ENOMEM);
+ }
- if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
+ nni_mtx_init(&d->ep.mtx);
+ d->ep.authmode = NNG_TLS_AUTH_MODE_REQUIRED;
+ d->ep.url = url;
+ d->ep.proto = nni_sock_proto_id(sock);
+ d->ep.nodelay = true;
+ d->ep.keepalive = false;
+
+ if (((rv = nni_tcp_dialer_init(&d->dialer)) != 0) ||
+ ((rv = nni_tls_config_init(&d->ep.cfg, NNG_TLS_MODE_CLIENT)) !=
+ 0) ||
+ ((rv = nng_tls_config_auth_mode(d->ep.cfg, d->ep.authmode)) !=
+ 0) ||
+ ((rv = nng_tls_config_server_name(d->ep.cfg, host)) != 0) ||
+ ((rv = nni_aio_init(&d->aio, tlstran_dialer_cb, d)) != 0)) {
+ tlstran_dialer_fini(d);
return (rv);
}
+ d->af = af;
- if (strlen(url->u_hostname) == 0) {
- host = NULL;
- } else {
- host = url->u_hostname;
- }
- if (strlen(url->u_port) == 0) {
- serv = NULL;
- } else {
- serv = url->u_port;
- }
-
- if (mode == NNI_EP_MODE_DIAL) {
- passive = 0;
- tlsmode = NNG_TLS_MODE_CLIENT;
- authmode = NNG_TLS_AUTH_MODE_REQUIRED;
- lsa.s_family = af;
- nni_aio_set_input(aio, 0, &rsa);
- if ((host == NULL) || (serv == NULL)) {
- nni_aio_fini(aio);
- return (NNG_EADDRINVAL);
+ *dp = d;
+ return (0);
+}
+
+static void
+tlstran_dialer_cb(void *arg)
+{
+ tlstran_dialer *d = arg;
+ tlstran_pipe * p;
+ nni_tcp_conn * conn;
+ nni_tls * tls;
+ nni_aio * aio;
+ int rv;
+
+ nni_mtx_lock(&d->ep.mtx);
+ aio = d->user_aio;
+ rv = nni_aio_result(d->aio);
+
+ if (aio == NULL) {
+ nni_mtx_unlock(&d->ep.mtx);
+ if ((rv == 0) && !d->resolving) {
+ conn = nni_aio_get_output(d->aio, 0);
+ nni_tcp_conn_fini(conn);
}
- } else {
- passive = 1;
- tlsmode = NNG_TLS_MODE_SERVER;
- authmode = NNG_TLS_AUTH_MODE_NONE;
- rsa.s_family = af;
- nni_aio_set_input(aio, 0, &lsa);
+ return;
}
- // XXX: arguably we could defer this part to the point we do a bind
- // or connect!
- nni_plat_tcp_resolv(host, serv, af, passive, aio);
- nni_aio_wait(aio);
- if ((rv = nni_aio_result(aio)) != 0) {
- nni_aio_fini(aio);
- return (rv);
+ if (rv != 0) {
+ d->user_aio = NULL;
+ nni_mtx_unlock(&d->ep.mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
}
- nni_aio_fini(aio);
- if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
- return (NNG_ENOMEM);
+ if (d->resolving) {
+ // Name resolution complete. Now go to next step.
+ d->resolving = false;
+ nni_tcp_dialer_dial(d->dialer, &d->sa, d->aio);
+ nni_mtx_unlock(&d->ep.mtx);
+ return;
}
- nni_mtx_init(&ep->mtx);
- ep->url = url;
- ep->keepalive = false;
- ep->nodelay = true;
+ d->user_aio = NULL;
+ conn = nni_aio_get_output(d->aio, 0);
+ NNI_ASSERT(conn != NULL);
- if (((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) ||
- ((rv = nni_tls_config_init(&ep->cfg, tlsmode)) != 0) ||
- ((rv = nng_tls_config_auth_mode(ep->cfg, authmode)) != 0) ||
- ((rv = nni_aio_init(&ep->aio, tls_ep_cb, ep)) != 0)) {
- tls_ep_fini(ep);
- return (rv);
+ if ((rv = nni_tls_init(&tls, d->ep.cfg, conn)) != 0) {
+ nni_mtx_unlock(&d->ep.mtx);
+ nni_tcp_conn_fini(conn);
+ nni_aio_finish_error(aio, rv);
+ return;
}
- if ((tlsmode == NNG_TLS_MODE_CLIENT) && (host != NULL)) {
- if ((rv = nng_tls_config_server_name(ep->cfg, host)) != 0) {
- tls_ep_fini(ep);
- return (rv);
- }
+
+ if ((rv = tlstran_pipe_init(&p, tls)) != 0) {
+ nni_mtx_unlock(&d->ep.mtx);
+ nni_tls_fini(tls);
+ nni_aio_finish_error(aio, rv);
+ return;
}
- ep->proto = nni_sock_proto_id(sock);
- ep->authmode = authmode;
- *epp = ep;
- return (0);
-}
+ p->proto = d->ep.proto;
+ p->rcvmax = d->ep.rcvmax;
+ p->nodelay = d->ep.nodelay;
+ p->keepalive = d->ep.keepalive;
+ nni_mtx_unlock(&d->ep.mtx);
-static int
-tls_dialer_init(void **epp, nni_url *url, nni_sock *sock)
-{
- return (tls_ep_init(epp, url, sock, NNI_EP_MODE_DIAL));
+ (void) nni_tls_set_nodelay(tls, p->nodelay);
+ (void) nni_tls_set_keepalive(tls, p->keepalive);
+
+ nni_aio_set_output(aio, 0, p);
+ nni_aio_finish(aio, 0, 0);
}
-static int
-tls_listener_init(void **epp, nni_url *url, nni_sock *sock)
+static void
+tlstran_dialer_cancel(nni_aio *aio, int rv)
{
- return (tls_ep_init(epp, url, sock, NNI_EP_MODE_LISTEN));
+ tlstran_dialer *d = nni_aio_get_prov_data(aio);
+
+ nni_mtx_lock(&d->ep.mtx);
+ if (d->user_aio != aio) {
+ nni_mtx_unlock(&d->ep.mtx);
+ return;
+ }
+ d->user_aio = NULL;
+ nni_mtx_unlock(&d->ep.mtx);
+
+ nni_aio_abort(d->aio, rv);
+ nni_aio_finish_error(aio, rv);
}
static void
-tls_ep_close(void *arg)
+tlstran_dialer_connect(void *arg, nni_aio *aio)
{
- tls_ep *ep = arg;
+ tlstran_dialer *d = arg;
+ int rv;
- nni_aio_close(ep->aio);
+ if (nni_aio_begin(aio) != 0) {
+ return;
+ }
+ nni_mtx_lock(&d->ep.mtx);
+ NNI_ASSERT(d->user_aio == NULL);
- nni_mtx_lock(&ep->mtx);
- nni_plat_tcp_ep_close(ep->tep);
- nni_mtx_unlock(&ep->mtx);
+ if ((rv = nni_aio_schedule(aio, tlstran_dialer_cancel, d)) != 0) {
+ nni_mtx_unlock(&d->ep.mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
+ d->user_aio = aio;
+
+ d->resolving = true;
+
+ // Start the name resolution. Callback will see resolving, and then
+ // switch to doing actual connect.
+ nni_aio_set_input(d->aio, 0, &d->sa);
+ nni_tcp_resolv(
+ d->ep.url->u_hostname, d->ep.url->u_port, d->af, 0, d->aio);
+ nni_mtx_unlock(&d->ep.mtx);
}
-static int
-tls_ep_bind(void *arg)
+static void
+tlstran_listener_fini(void *arg)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_listener *l = arg;
- nni_mtx_lock(&ep->mtx);
- rv = nni_plat_tcp_ep_listen(ep->tep, &ep->bsa);
- nni_mtx_unlock(&ep->mtx);
-
- return (rv);
+ nni_aio_stop(l->aio);
+ if (l->listener != NULL) {
+ nni_tcp_listener_fini(l->listener);
+ }
+ nni_aio_fini(l->aio);
+ if (l->ep.cfg != NULL) {
+ nni_tls_config_fini(l->ep.cfg);
+ }
+ nni_mtx_fini(&l->ep.mtx);
+ NNI_FREE_STRUCT(l);
}
static void
-tls_ep_finish(tls_ep *ep)
+tlstran_listener_close(void *arg)
{
- nni_aio * aio;
- int rv;
- tls_pipe *pipe = NULL;
+ tlstran_listener *l = arg;
- if ((rv = nni_aio_result(ep->aio)) != 0) {
- goto done;
+ nni_aio_close(l->aio);
+ nni_tcp_listener_close(l->listener);
+}
+
+static int
+tlstran_listener_init(void **lp, nni_url *url, nni_sock *sock)
+{
+ tlstran_listener *l;
+ int rv;
+ nni_aio * aio;
+ uint16_t af;
+ char * host = url->u_hostname;
+ char * port = url->u_port;
+
+ if (strcmp(url->u_scheme, "tls+tcp") == 0) {
+ af = NNG_AF_UNSPEC;
+ } else if (strcmp(url->u_scheme, "tls+tcp4") == 0) {
+ af = NNG_AF_INET;
+ } else if (strcmp(url->u_scheme, "tls+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);
+ }
+ if ((url->u_fragment != NULL) || (url->u_userinfo != NULL) ||
+ (url->u_query != NULL)) {
+ return (NNG_EADDRINVAL);
}
- NNI_ASSERT(nni_aio_get_output(ep->aio, 0) != NULL);
- // Attempt to allocate the parent pipe. If this fails we'll
- // drop the connection (ENOMEM probably).
- rv = tls_pipe_init(&pipe, ep, nni_aio_get_output(ep->aio, 0));
+ if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ nni_mtx_init(&l->ep.mtx);
+ l->ep.url = url;
+ l->ep.authmode = NNG_TLS_AUTH_MODE_NONE;
+ l->ep.keepalive = false;
+ l->ep.nodelay = true;
+ l->ep.proto = nni_sock_proto_id(sock);
-done:
- aio = ep->user_aio;
- ep->user_aio = NULL;
+ if (strlen(host) == 0) {
+ host = NULL;
+ }
- if ((aio != NULL) && (rv == 0)) {
- nni_aio_set_output(aio, 0, pipe);
- nni_aio_finish(aio, 0, 0);
- return;
+ if ((rv = nni_aio_init(&aio, NULL, NULL)) != 0) {
+ tlstran_listener_fini(l);
+ return (rv);
}
- if (pipe != NULL) {
- tls_pipe_fini(pipe);
+
+ // 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.
+
+ nni_aio_set_input(aio, 0, &l->sa);
+
+ nni_tcp_resolv(host, port, af, 1, aio);
+ nni_aio_wait(aio);
+ rv = nni_aio_result(aio);
+ nni_aio_fini(aio);
+
+ if (rv != 0) {
+ tlstran_listener_fini(l);
+ return (rv);
}
- if (aio != NULL) {
- NNI_ASSERT(rv != 0);
- nni_aio_finish_error(aio, rv);
+
+ if (((rv = nni_tcp_listener_init(&l->listener)) != 0) ||
+ ((rv = nni_tls_config_init(&l->ep.cfg, NNG_TLS_MODE_SERVER)) !=
+ 0) ||
+ ((rv = nng_tls_config_auth_mode(l->ep.cfg, l->ep.authmode)) !=
+ 0) ||
+ ((rv = nni_aio_init(&l->aio, tlstran_listener_cb, l)) != 0)) {
+ tlstran_listener_fini(l);
+ return (rv);
}
+ l->bsa = l->sa;
+
+ *lp = l;
+ return (0);
}
-static void
-tls_ep_cb(void *arg)
+static int
+tlstran_listener_bind(void *arg)
{
- tls_ep *ep = arg;
+ tlstran_listener *l = arg;
+ int rv;
- nni_mtx_lock(&ep->mtx);
- tls_ep_finish(ep);
- nni_mtx_unlock(&ep->mtx);
+ l->bsa = l->sa;
+ nni_mtx_lock(&l->ep.mtx);
+ rv = nni_tcp_listener_listen(l->listener, &l->bsa);
+ nni_mtx_unlock(&l->ep.mtx);
+
+ return (rv);
}
static void
-tls_cancel_ep(nni_aio *aio, int rv)
+tlstran_listener_cb(void *arg)
{
- tls_ep *ep = nni_aio_get_prov_data(aio);
+ tlstran_listener *l = arg;
+ nni_aio * aio;
+ int rv;
+ tlstran_pipe * p = NULL;
+ nni_tcp_conn * conn;
+ nni_tls * tls;
+
+ nni_mtx_lock(&l->ep.mtx);
+ rv = nni_aio_result(l->aio);
+ aio = l->user_aio;
+ l->user_aio = NULL;
+
+ if (aio == NULL) {
+ nni_mtx_unlock(&l->ep.mtx);
+ if (rv == 0) {
+ conn = nni_aio_get_output(l->aio, 0);
+ nni_tcp_conn_fini(conn);
+ }
+ return;
+ }
+ if (rv != 0) {
+ nni_mtx_unlock(&l->ep.mtx);
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
- nni_mtx_lock(&ep->mtx);
- if (ep->user_aio != aio) {
- nni_mtx_unlock(&ep->mtx);
+ conn = nni_aio_get_output(l->aio, 0);
+ if ((rv = nni_tls_init(&tls, l->ep.cfg, conn)) != 0) {
+ nni_mtx_unlock(&l->ep.mtx);
+ nni_tcp_conn_fini(conn);
+ nni_aio_finish_error(aio, rv);
return;
}
- ep->user_aio = NULL;
- nni_mtx_unlock(&ep->mtx);
+ if ((rv = tlstran_pipe_init(&p, tls)) != 0) {
+ nni_mtx_unlock(&l->ep.mtx);
+ nni_tls_fini(tls);
+ nni_aio_finish_error(aio, rv);
+ return;
+ }
+ p->proto = l->ep.proto;
+ p->rcvmax = l->ep.rcvmax;
+ p->nodelay = l->ep.nodelay;
+ p->keepalive = l->ep.keepalive;
- nni_aio_abort(ep->aio, rv);
- nni_aio_finish_error(aio, rv);
+ (void) nni_tls_set_nodelay(tls, p->nodelay);
+ (void) nni_tls_set_keepalive(tls, p->keepalive);
+
+ nni_mtx_unlock(&l->ep.mtx);
+
+ nni_aio_set_output(aio, 0, p);
+ nni_aio_finish(aio, 0, 0);
}
static void
-tls_ep_accept(void *arg, nni_aio *aio)
+tlstran_listener_cancel(nni_aio *aio, int rv)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_listener *l = nni_aio_get_prov_data(aio);
- if (nni_aio_begin(aio) != 0) {
- return;
- }
- nni_mtx_lock(&ep->mtx);
- NNI_ASSERT(ep->user_aio == NULL);
- if ((rv = nni_aio_schedule(aio, tls_cancel_ep, ep)) != 0) {
- nni_mtx_unlock(&ep->mtx);
- nni_aio_finish_error(aio, rv);
+ nni_mtx_lock(&l->ep.mtx);
+ if (l->user_aio != aio) {
+ nni_mtx_unlock(&l->ep.mtx);
return;
}
- ep->user_aio = aio;
- nni_plat_tcp_ep_accept(ep->tep, ep->aio);
- nni_mtx_unlock(&ep->mtx);
+ l->user_aio = NULL;
+ nni_mtx_unlock(&l->ep.mtx);
+
+ nni_aio_abort(l->aio, rv);
+ nni_aio_finish_error(aio, rv);
}
static void
-tls_ep_connect(void *arg, nni_aio *aio)
+tlstran_listener_accept(void *arg, nni_aio *aio)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_listener *l = arg;
+ int rv;
if (nni_aio_begin(aio) != 0) {
return;
}
- nni_mtx_lock(&ep->mtx);
- NNI_ASSERT(ep->user_aio == NULL);
- if ((rv = nni_aio_schedule(aio, tls_cancel_ep, ep)) != 0) {
- nni_mtx_unlock(&ep->mtx);
+ nni_mtx_lock(&l->ep.mtx);
+ NNI_ASSERT(l->user_aio == NULL);
+
+ if ((rv = nni_aio_schedule(aio, tlstran_listener_cancel, l)) != 0) {
+ nni_mtx_unlock(&l->ep.mtx);
nni_aio_finish_error(aio, rv);
+ return;
}
- ep->user_aio = aio;
- nni_plat_tcp_ep_connect(ep->tep, ep->aio);
- nni_mtx_unlock(&ep->mtx);
-}
+ l->user_aio = aio;
-static int
-tls_ep_chk_bool(const void *v, size_t sz, nni_opt_type t)
-{
- return (nni_copyin_bool(NULL, v, sz, t));
+ nni_tcp_listener_accept(l->listener, l->aio);
+ nni_mtx_unlock(&l->ep.mtx);
}
static int
-tls_ep_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- bool val;
- int rv;
+ tlstran_ep *ep = arg;
+ bool val;
+ int rv;
if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
nni_mtx_lock(&ep->mtx);
ep->nodelay = val;
@@ -874,10 +1032,10 @@ tls_ep_set_nodelay(void *arg, const void *v, size_t sz, nni_opt_type t)
}
static int
-tls_ep_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_ep_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
nni_mtx_lock(&ep->mtx);
rv = nni_copyout_bool(ep->nodelay, v, szp, t);
nni_mtx_unlock(&ep->mtx);
@@ -885,11 +1043,25 @@ tls_ep_get_nodelay(void *arg, void *v, size_t *szp, nni_opt_type t)
}
static int
-tls_ep_set_keepalive(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- bool val;
- int rv;
+ tlstran_ep *ep = arg;
+ size_t val;
+ int rv;
+ 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);
+ }
+ return (rv);
+}
+
+static int
+tlstran_ep_set_keepalive(void *arg, const void *v, size_t sz, nni_opt_type t)
+{
+ tlstran_ep *ep = arg;
+ bool val;
+ int rv;
if ((rv = nni_copyin_bool(&val, v, sz, t)) == 0) {
nni_mtx_lock(&ep->mtx);
ep->keepalive = val;
@@ -899,10 +1071,10 @@ tls_ep_set_keepalive(void *arg, const void *v, size_t sz, nni_opt_type t)
}
static int
-tls_ep_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_ep_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
nni_mtx_lock(&ep->mtx);
rv = nni_copyout_bool(ep->keepalive, v, szp, t);
nni_mtx_unlock(&ep->mtx);
@@ -910,60 +1082,53 @@ tls_ep_get_keepalive(void *arg, void *v, size_t *szp, nni_opt_type t)
}
static int
-tls_dialer_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_ep_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_ep *ep = arg;
-
- return (nni_copyout_str(ep->url->u_rawurl, v, szp, t));
+ tlstran_ep *ep = arg;
+ int rv;
+ nni_mtx_lock(&ep->mtx);
+ rv = nni_copyout_size(ep->rcvmax, v, szp, t);
+ nni_mtx_unlock(&ep->mtx);
+ return (rv);
}
static int
-tls_listener_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_check_bool(const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- char ustr[128];
- char ipstr[48]; // max for IPv6 addresses including []
- char portstr[6]; // max for 16-bit port
-
- nni_plat_tcp_ntop(&ep->bsa, ipstr, portstr);
- snprintf(ustr, sizeof(ustr), "tls+tcp://%s:%s", ipstr, portstr);
- return (nni_copyout_str(ustr, v, szp, t));
+ return (nni_copyin_bool(NULL, v, sz, t));
}
static int
-tls_ep_set_recvmaxsz(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_dialer_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_ep *ep = arg;
- size_t val;
- int rv;
+ tlstran_dialer *d = arg;
- 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);
- }
- return (rv);
+ return (nni_copyout_str(d->ep.url->u_rawurl, v, szp, t));
}
static int
-tls_ep_chk_recvmaxsz(const void *v, size_t sz, nni_opt_type t)
+tlstran_listener_get_url(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
+ tlstran_listener *l = arg;
+ char ustr[128];
+ char ipstr[48]; // max for IPv6 addresses including []
+ char portstr[6]; // max for 16-bit port
+
+ nni_mtx_lock(&l->ep.mtx);
+ nni_ntop(&l->bsa, ipstr, portstr);
+ nni_mtx_unlock(&l->ep.mtx);
+ snprintf(ustr, sizeof(ustr), "tls+tcp://%s:%s", ipstr, portstr);
+ return (nni_copyout_str(ustr, v, szp, t));
}
static int
-tls_ep_get_recvmaxsz(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_check_recvmaxsz(const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
- nni_mtx_lock(&ep->mtx);
- rv = nni_copyout_size(ep->rcvmax, v, szp, t);
- nni_mtx_unlock(&ep->mtx);
- return (rv);
+ return (nni_copyin_size(NULL, v, sz, 0, NNI_MAXSZ, t));
}
static int
-tls_ep_chk_config(const void *data, size_t sz, nni_opt_type t)
+tlstran_check_config(const void *data, size_t sz, nni_opt_type t)
{
void *v;
int rv;
@@ -974,9 +1139,9 @@ tls_ep_chk_config(const void *data, size_t sz, nni_opt_type t)
}
static int
-tls_ep_set_config(void *arg, const void *data, size_t sz, nni_opt_type t)
+tlstran_ep_set_config(void *arg, const void *data, size_t sz, nni_opt_type t)
{
- tls_ep * ep = arg;
+ tlstran_ep * ep = arg;
nng_tls_config *cfg, *old;
int rv;
@@ -998,10 +1163,10 @@ tls_ep_set_config(void *arg, const void *data, size_t sz, nni_opt_type t)
}
static int
-tls_ep_get_config(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_ep_get_config(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
nni_mtx_lock(&ep->mtx);
rv = nni_copyout_ptr(ep->cfg, v, szp, t);
nni_mtx_unlock(&ep->mtx);
@@ -1009,7 +1174,7 @@ tls_ep_get_config(void *arg, void *v, size_t *szp, nni_opt_type t)
}
static int
-tls_ep_chk_string(const void *v, size_t sz, nni_opt_type t)
+tlstran_check_string(const void *v, size_t sz, nni_opt_type t)
{
if ((t != NNI_TYPE_OPAQUE) && (t != NNI_TYPE_STRING)) {
return (NNG_EBADTYPE);
@@ -1021,58 +1186,65 @@ tls_ep_chk_string(const void *v, size_t sz, nni_opt_type t)
}
static int
-tls_ep_set_ca_file(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_ca_file(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
- if ((rv = tls_ep_chk_string(v, sz, t)) == 0) {
+ if ((rv = tlstran_check_string(v, sz, t)) == 0) {
+ nni_mtx_lock(&ep->mtx);
rv = nng_tls_config_ca_file(ep->cfg, v);
+ nni_mtx_unlock(&ep->mtx);
}
return (rv);
}
static int
-tls_ep_chk_auth_mode(const void *v, size_t sz, nni_opt_type t)
+tlstran_check_auth_mode(const void *v, size_t sz, nni_opt_type t)
{
return (nni_copyin_int(NULL, v, sz, NNG_TLS_AUTH_MODE_NONE,
NNG_TLS_AUTH_MODE_REQUIRED, t));
}
static int
-tls_ep_set_auth_mode(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_auth_mode(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- int mode;
- int rv;
+ tlstran_ep *ep = arg;
+ int mode;
+ int rv;
rv = nni_copyin_int(&mode, v, sz, NNG_TLS_AUTH_MODE_NONE,
NNG_TLS_AUTH_MODE_REQUIRED, t);
if (rv == 0) {
+ nni_mtx_lock(&ep->mtx);
rv = nng_tls_config_auth_mode(ep->cfg, mode);
+ nni_mtx_unlock(&ep->mtx);
}
return (rv);
}
static int
-tls_ep_set_server_name(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_server_name(void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
- if ((rv = tls_ep_chk_string(v, sz, t)) == 0) {
+ if ((rv = tlstran_check_string(v, sz, t)) == 0) {
+ nni_mtx_lock(&ep->mtx);
rv = nng_tls_config_server_name(ep->cfg, v);
+ nni_mtx_unlock(&ep->mtx);
}
return (rv);
}
static int
-tls_ep_set_cert_key_file(void *arg, const void *v, size_t sz, nni_opt_type t)
+tlstran_ep_set_cert_key_file(
+ void *arg, const void *v, size_t sz, nni_opt_type t)
{
- tls_ep *ep = arg;
- int rv;
+ tlstran_ep *ep = arg;
+ int rv;
- if ((rv = tls_ep_chk_string(v, sz, t)) == 0) {
+ if ((rv = tlstran_check_string(v, sz, t)) == 0) {
nni_mtx_lock(&ep->mtx);
rv = nng_tls_config_cert_key_file(ep->cfg, v, NULL);
nni_mtx_unlock(&ep->mtx);
@@ -1081,38 +1253,38 @@ tls_ep_set_cert_key_file(void *arg, const void *v, size_t sz, nni_opt_type t)
}
static int
-tls_pipe_get_verified(void *arg, void *v, size_t *szp, nni_opt_type t)
+tlstran_pipe_get_verified(void *arg, void *v, size_t *szp, nni_opt_type t)
{
- tls_pipe *p = arg;
+ tlstran_pipe *p = arg;
return (nni_copyout_bool(nni_tls_verified(p->tls), v, szp, t));
}
-static nni_tran_option tls_pipe_options[] = {
+static nni_tran_option tlstran_pipe_options[] = {
{
.o_name = NNG_OPT_LOCADDR,
.o_type = NNI_TYPE_SOCKADDR,
- .o_get = tls_pipe_get_locaddr,
+ .o_get = tlstran_pipe_get_locaddr,
},
{
.o_name = NNG_OPT_REMADDR,
.o_type = NNI_TYPE_SOCKADDR,
- .o_get = tls_pipe_get_remaddr,
+ .o_get = tlstran_pipe_get_remaddr,
},
{
.o_name = NNG_OPT_TLS_VERIFIED,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_pipe_get_verified,
+ .o_get = tlstran_pipe_get_verified,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_pipe_get_keepalive,
+ .o_get = tlstran_pipe_get_keepalive,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_pipe_get_nodelay,
+ .o_get = tlstran_pipe_get_nodelay,
},
// terminate list
{
@@ -1120,74 +1292,74 @@ static nni_tran_option tls_pipe_options[] = {
},
};
-static nni_tran_pipe_ops tls_pipe_ops = {
- .p_fini = tls_pipe_fini,
- .p_start = tls_pipe_start,
- .p_stop = tls_pipe_stop,
- .p_send = tls_pipe_send,
- .p_recv = tls_pipe_recv,
- .p_close = tls_pipe_close,
- .p_peer = tls_pipe_peer,
- .p_options = tls_pipe_options,
+static nni_tran_pipe_ops tlstran_pipe_ops = {
+ .p_fini = tlstran_pipe_fini,
+ .p_start = tlstran_pipe_start,
+ .p_stop = tlstran_pipe_stop,
+ .p_send = tlstran_pipe_send,
+ .p_recv = tlstran_pipe_recv,
+ .p_close = tlstran_pipe_close,
+ .p_peer = tlstran_pipe_peer,
+ .p_options = tlstran_pipe_options,
};
-static nni_tran_option tls_dialer_options[] = {
+static nni_tran_option tlstran_dialer_options[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_type = NNI_TYPE_SIZE,
- .o_get = tls_ep_get_recvmaxsz,
- .o_set = tls_ep_set_recvmaxsz,
- .o_chk = tls_ep_chk_recvmaxsz,
+ .o_get = tlstran_ep_get_recvmaxsz,
+ .o_set = tlstran_ep_set_recvmaxsz,
+ .o_chk = tlstran_check_recvmaxsz,
},
{
.o_name = NNG_OPT_URL,
.o_type = NNI_TYPE_STRING,
- .o_get = tls_dialer_get_url,
+ .o_get = tlstran_dialer_get_url,
},
{
.o_name = NNG_OPT_TLS_CONFIG,
.o_type = NNI_TYPE_POINTER,
- .o_get = tls_ep_get_config,
- .o_set = tls_ep_set_config,
- .o_chk = tls_ep_chk_config,
+ .o_get = tlstran_ep_get_config,
+ .o_set = tlstran_ep_set_config,
+ .o_chk = tlstran_check_config,
},
{
.o_name = NNG_OPT_TLS_CERT_KEY_FILE,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_cert_key_file,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_cert_key_file,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TLS_CA_FILE,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_ca_file,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_ca_file,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TLS_AUTH_MODE,
.o_type = NNI_TYPE_INT32, // enum really
- .o_set = tls_ep_set_auth_mode,
- .o_chk = tls_ep_chk_auth_mode,
+ .o_set = tlstran_ep_set_auth_mode,
+ .o_chk = tlstran_check_auth_mode,
},
{
.o_name = NNG_OPT_TLS_SERVER_NAME,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_server_name,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_server_name,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_ep_get_nodelay,
- .o_set = tls_ep_set_nodelay,
- .o_chk = tls_ep_chk_bool,
+ .o_get = tlstran_ep_get_nodelay,
+ .o_set = tlstran_ep_set_nodelay,
+ .o_chk = tlstran_check_bool,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_ep_get_keepalive,
- .o_set = tls_ep_set_keepalive,
- .o_chk = tls_ep_chk_bool,
+ .o_get = tlstran_ep_get_keepalive,
+ .o_set = tlstran_ep_set_keepalive,
+ .o_chk = tlstran_check_bool,
},
// terminate list
{
@@ -1195,63 +1367,63 @@ static nni_tran_option tls_dialer_options[] = {
},
};
-static nni_tran_option tls_listener_options[] = {
+static nni_tran_option tlstran_listener_options[] = {
{
.o_name = NNG_OPT_RECVMAXSZ,
.o_type = NNI_TYPE_SIZE,
- .o_get = tls_ep_get_recvmaxsz,
- .o_set = tls_ep_set_recvmaxsz,
- .o_chk = tls_ep_chk_recvmaxsz,
+ .o_get = tlstran_ep_get_recvmaxsz,
+ .o_set = tlstran_ep_set_recvmaxsz,
+ .o_chk = tlstran_check_recvmaxsz,
},
{
.o_name = NNG_OPT_URL,
.o_type = NNI_TYPE_STRING,
- .o_get = tls_listener_get_url,
+ .o_get = tlstran_listener_get_url,
},
{
.o_name = NNG_OPT_TLS_CONFIG,
.o_type = NNI_TYPE_POINTER,
- .o_get = tls_ep_get_config,
- .o_set = tls_ep_set_config,
- .o_chk = tls_ep_chk_config,
+ .o_get = tlstran_ep_get_config,
+ .o_set = tlstran_ep_set_config,
+ .o_chk = tlstran_check_config,
},
{
.o_name = NNG_OPT_TLS_CERT_KEY_FILE,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_cert_key_file,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_cert_key_file,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TLS_CA_FILE,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_ca_file,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_ca_file,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TLS_AUTH_MODE,
.o_type = NNI_TYPE_INT32, // enum really
- .o_set = tls_ep_set_auth_mode,
- .o_chk = tls_ep_chk_auth_mode,
+ .o_set = tlstran_ep_set_auth_mode,
+ .o_chk = tlstran_check_auth_mode,
},
{
.o_name = NNG_OPT_TLS_SERVER_NAME,
.o_type = NNI_TYPE_STRING,
- .o_set = tls_ep_set_server_name,
- .o_chk = tls_ep_chk_string,
+ .o_set = tlstran_ep_set_server_name,
+ .o_chk = tlstran_check_string,
},
{
.o_name = NNG_OPT_TCP_NODELAY,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_ep_get_nodelay,
- .o_set = tls_ep_set_nodelay,
- .o_chk = tls_ep_chk_bool,
+ .o_get = tlstran_ep_get_nodelay,
+ .o_set = tlstran_ep_set_nodelay,
+ .o_chk = tlstran_check_bool,
},
{
.o_name = NNG_OPT_TCP_KEEPALIVE,
.o_type = NNI_TYPE_BOOL,
- .o_get = tls_ep_get_keepalive,
- .o_set = tls_ep_set_keepalive,
- .o_chk = tls_ep_chk_bool,
+ .o_get = tlstran_ep_get_keepalive,
+ .o_set = tlstran_ep_set_keepalive,
+ .o_chk = tlstran_check_bool,
},
// terminate list
{
@@ -1259,51 +1431,51 @@ static nni_tran_option tls_listener_options[] = {
},
};
-static nni_tran_dialer_ops tls_dialer_ops = {
- .d_init = tls_dialer_init,
- .d_fini = tls_ep_fini,
- .d_connect = tls_ep_connect,
- .d_close = tls_ep_close,
- .d_options = tls_dialer_options,
+static nni_tran_dialer_ops tlstran_dialer_ops = {
+ .d_init = tlstran_dialer_init,
+ .d_fini = tlstran_dialer_fini,
+ .d_connect = tlstran_dialer_connect,
+ .d_close = tlstran_dialer_close,
+ .d_options = tlstran_dialer_options,
};
-static nni_tran_listener_ops tls_listener_ops = {
- .l_init = tls_listener_init,
- .l_fini = tls_ep_fini,
- .l_bind = tls_ep_bind,
- .l_accept = tls_ep_accept,
- .l_close = tls_ep_close,
- .l_options = tls_listener_options,
+static nni_tran_listener_ops tlstran_listener_ops = {
+ .l_init = tlstran_listener_init,
+ .l_fini = tlstran_listener_fini,
+ .l_bind = tlstran_listener_bind,
+ .l_accept = tlstran_listener_accept,
+ .l_close = tlstran_listener_close,
+ .l_options = tlstran_listener_options,
};
static nni_tran tls_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tls+tcp",
- .tran_dialer = &tls_dialer_ops,
- .tran_listener = &tls_listener_ops,
- .tran_pipe = &tls_pipe_ops,
- .tran_init = tls_tran_init,
- .tran_fini = tls_tran_fini,
+ .tran_dialer = &tlstran_dialer_ops,
+ .tran_listener = &tlstran_listener_ops,
+ .tran_pipe = &tlstran_pipe_ops,
+ .tran_init = tlstran_init,
+ .tran_fini = tlstran_fini,
};
static nni_tran tls4_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tls+tcp4",
- .tran_dialer = &tls_dialer_ops,
- .tran_listener = &tls_listener_ops,
- .tran_pipe = &tls_pipe_ops,
- .tran_init = tls_tran_init,
- .tran_fini = tls_tran_fini,
+ .tran_dialer = &tlstran_dialer_ops,
+ .tran_listener = &tlstran_listener_ops,
+ .tran_pipe = &tlstran_pipe_ops,
+ .tran_init = tlstran_init,
+ .tran_fini = tlstran_fini,
};
static nni_tran tls6_tran = {
.tran_version = NNI_TRANSPORT_VERSION,
.tran_scheme = "tls+tcp6",
- .tran_dialer = &tls_dialer_ops,
- .tran_listener = &tls_listener_ops,
- .tran_pipe = &tls_pipe_ops,
- .tran_init = tls_tran_init,
- .tran_fini = tls_tran_fini,
+ .tran_dialer = &tlstran_dialer_ops,
+ .tran_listener = &tlstran_listener_ops,
+ .tran_pipe = &tlstran_pipe_ops,
+ .tran_init = tlstran_init,
+ .tran_fini = tlstran_fini,
};
int