diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-08-28 23:00:53 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-08-28 23:00:53 -0700 |
| commit | ce9f0cb155ad0e97cfc7703d9d7c8e5bec3201bc (patch) | |
| tree | 01fc3b118dd74a2202ac794dce69f380c39a35f4 | |
| parent | 05852bc279a6d88722cff8e8399b5d08853b9c32 (diff) | |
| download | nng-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.c | 62 | ||||
| -rw-r--r-- | tests/tcp.c | 2 | ||||
| -rw-r--r-- | tests/tls.c | 43 |
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. |
