aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-08-28 23:00:53 -0700
committerGarrett D'Amore <garrett@damore.org>2018-08-28 23:00:53 -0700
commitce9f0cb155ad0e97cfc7703d9d7c8e5bec3201bc (patch)
tree01fc3b118dd74a2202ac794dce69f380c39a35f4
parent05852bc279a6d88722cff8e8399b5d08853b9c32 (diff)
downloadnng-ce9f0cb155ad0e97cfc7703d9d7c8e5bec3201bc.tar.gz
nng-ce9f0cb155ad0e97cfc7703d9d7c8e5bec3201bc.tar.bz2
nng-ce9f0cb155ad0e97cfc7703d9d7c8e5bec3201bc.zip
fixes #678 local binding for TLS+TCP sockets
-rw-r--r--src/transport/tls/tls.c62
-rw-r--r--tests/tcp.c2
-rw-r--r--tests/tls.c43
3 files changed, 94 insertions, 13 deletions
diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c
index cf478796..8fd59fd7 100644
--- a/src/transport/tls/tls.c
+++ b/src/transport/tls/tls.c
@@ -76,6 +76,8 @@ struct tlstran_ep {
nni_reap_item reap;
nni_tcp_dialer * dialer;
nni_tcp_listener *listener;
+ const char * host;
+ nng_sockaddr src;
nng_sockaddr sa;
nng_sockaddr bsa;
nni_dialer * ndialer;
@@ -755,12 +757,12 @@ tlstran_ep_close(void *arg)
static int
tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
{
- tlstran_ep *ep;
- int rv;
- uint16_t af;
- char * host = url->u_hostname;
- char * port = url->u_port;
- nni_sock * sock = nni_dialer_sock(ndialer);
+ tlstran_ep * ep;
+ int rv;
+ uint16_t af;
+ char * host;
+ nng_sockaddr srcsa;
+ nni_sock * sock = nni_dialer_sock(ndialer);
if (strcmp(url->u_scheme, "tls+tcp") == 0) {
af = NNG_AF_UNSPEC;
@@ -777,8 +779,8 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
return (NNG_EADDRINVAL);
}
if ((url->u_fragment != NULL) || (url->u_userinfo != NULL) ||
- (url->u_query != NULL) || (host == NULL) || (port == NULL) ||
- (strlen(host) == 0) || (strlen(port) == 0)) {
+ (url->u_query != NULL) || (strlen(url->u_hostname) == 0) ||
+ (strlen(url->u_port) == 0)) {
return (NNG_EADDRINVAL);
}
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
@@ -796,10 +798,47 @@ tlstran_ep_init_dialer(void **dp, nni_url *url, nni_dialer *ndialer)
ep->keepalive = false;
ep->ndialer = ndialer;
- if (((rv = nni_tcp_dialer_init(&ep->dialer)) != 0) ||
+ // 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 = nni_tcp_dialer_init(&ep->dialer)) != 0) ||
((rv = nni_tls_config_init(&ep->cfg, NNG_TLS_MODE_CLIENT)) != 0) ||
((rv = nng_tls_config_auth_mode(ep->cfg, ep->authmode)) != 0) ||
- ((rv = nng_tls_config_server_name(ep->cfg, host)) != 0)) {
+ ((rv = nng_tls_config_server_name(ep->cfg, ep->host)) != 0)) {
tlstran_ep_fini(ep);
return (rv);
}
@@ -908,8 +947,7 @@ tlstran_ep_connect(void *arg, nni_aio *aio)
}
p->useraio = aio;
nni_aio_set_input(p->rslvaio, 0, &p->sa);
- nni_tcp_resolv(
- ep->url->u_hostname, ep->url->u_port, ep->af, 0, p->rslvaio);
+ nni_tcp_resolv(ep->host, ep->url->u_port, ep->af, 0, p->rslvaio);
nni_mtx_unlock(&ep->mtx);
}
diff --git a/tests/tcp.c b/tests/tcp.c
index d13cc83d..2c49f509 100644
--- a/tests/tcp.c
+++ b/tests/tcp.c
@@ -108,7 +108,7 @@ TestMain("TCP Transport", {
nng_strfree(addr);
});
- Convey("We can use local interface to connet", {
+ Convey("We can use local interface to connect", {
nng_socket s1;
nng_socket s2;
char addr[NNG_MAXADDRLEN];
diff --git a/tests/tls.c b/tests/tls.c
index 84c939e8..8915b265 100644
--- a/tests/tls.c
+++ b/tests/tls.c
@@ -368,6 +368,49 @@ TestMain("TLS Transport", {
NNG_EADDRINVAL);
});
+ Convey("We can use local interface to connect", {
+ nng_socket s1;
+ nng_socket s2;
+ nng_listener l;
+ nng_dialer d;
+ char addr[NNG_MAXADDRLEN];
+
+ So(nng_pair_open(&s1) == 0);
+ So(nng_pair_open(&s2) == 0);
+ Reset({
+ nng_close(s2);
+ nng_close(s1);
+ });
+ trantest_next_address(addr, "tls+tcp://127.0.0.1:%u");
+ So(nng_listener_create(&l, s1, addr) == 0);
+ So(init_listener_tls(l) == 0);
+ So(nng_listener_start(l, 0) == 0);
+ // reset port back one
+ trantest_prev_address(
+ addr, "tls+tcp://127.0.0.1;127.0.0.1:%u");
+ So(nng_dialer_create(&d, s2, addr) == 0);
+ So(init_dialer_tls(d) == 0);
+ So(nng_dialer_start(d, 0) == 0);
+ });
+
+ Convey("Botched local interfaces fail resonably", {
+ nng_socket s1;
+
+ So(nng_pair_open(&s1) == 0);
+ Reset({ nng_close(s1); });
+ So(nng_dial(s1, "tcp://1x.2;127.0.0.1:80", NULL, 0) ==
+ NNG_EADDRINVAL);
+ });
+
+ Convey("Can't specify address that isn't ours", {
+ nng_socket s1;
+
+ So(nng_pair_open(&s1) == 0);
+ Reset({ nng_close(s1); });
+ So(nng_dial(s1, "tcp://8.8.8.8;127.0.0.1:80", NULL, 0) ==
+ NNG_EADDRINVAL);
+ });
+
#if 0
// We really need to have pipe start/negotiate as one of the key steps during
// connect establish. Until that happens, we cannot verify the peer.