diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-05-17 20:20:17 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-05-17 20:20:17 -0700 |
| commit | 109a559590abfe3017dd317c3068e2457188541c (patch) | |
| tree | 103c9eba61c3d82956b677c78cc83ae040968c8f | |
| parent | 70d478f5d185e147ca8d3dcba4cbd8bb6da3719a (diff) | |
| download | nng-109a559590abfe3017dd317c3068e2457188541c.tar.gz nng-109a559590abfe3017dd317c3068e2457188541c.tar.bz2 nng-109a559590abfe3017dd317c3068e2457188541c.zip | |
fixes #452 Want tcp6:// and tcp4:// to constrain IP family
| -rw-r--r-- | docs/man/nng_tcp.7.adoc | 14 | ||||
| -rw-r--r-- | docs/man/nng_tls.7.adoc | 16 | ||||
| -rw-r--r-- | src/transport/tcp/tcp.c | 43 | ||||
| -rw-r--r-- | src/transport/tls/tls.c | 43 |
4 files changed, 107 insertions, 9 deletions
diff --git a/docs/man/nng_tcp.7.adoc b/docs/man/nng_tcp.7.adoc index aa90364e..7b9b6823 100644 --- a/docs/man/nng_tcp.7.adoc +++ b/docs/man/nng_tcp.7.adoc @@ -45,6 +45,20 @@ TCP port number.(((port number, TCP))) For example, to contact port 80 on the localhost either of the following URIs could be used: `tcp://127.0.0.1:80` or `tcp://localhost:80`. +A URI may be restricted to IPv6 using the scheme `tcp6://`, and may +be restricted to IPv4 using the scheme `tcp4://`. + +NOTE: Specifying `tcp6://` may not prevent IPv4 hosts from being used with +IPv4-in-IPv6 addresses, particularly when using a wildcard hostname with +listeners. +The details of varies across operating systems. + +NOTE: Both `tcp6://` and `tcp4://` are _nng_ extensions, and will not +be understood by other implementations such as _libnanomsg_. + +TIP: We recommend using either numeric IP addresses, or names that are +specific to either IPv4 or IPv6 to prevent confusion and surprises. + When specifying IPv6 addresses, the address must be enclosed in square brackets (`[]`) to avoid confusion with the final colon separating the port. diff --git a/docs/man/nng_tls.7.adoc b/docs/man/nng_tls.7.adoc index 249159b7..e2465377 100644 --- a/docs/man/nng_tls.7.adoc +++ b/docs/man/nng_tls.7.adoc @@ -26,7 +26,7 @@ int nng_tls_register(void); (((TLS)))(((Transport Layer Security)))(((transport, _tls_))) The ((_tls_ transport)) provides communication support between -_nng_ sockets across a TCP/IP network using +_nng_ sockets across a TCP/IP network using https://tools.ietf.org/html/rfc5246[TLS v1.2] on top of https://tools.ietf.org/html/rfc793[TCP]. Both IPv4 and IPv6 are supported when the underlying platform also supports it. @@ -67,6 +67,20 @@ For example, to contact port 4433 on the localhost either of the following URIs could be used: `tls+tcp://127.0.0.1:4433` or `tls+tcp://localhost:4433`. +A URI may be restricted to IPv6 using the scheme `tls+tcp6://`, and may +be restricted to IPv4 using the scheme `tls+tcp4://`. + +NOTE: Specifying `tls+tcp6://` may not prevent IPv4 hosts from being used with +IPv4-in-IPv6 addresses, particularly when using a wildcard hostname with +listeners. +The details of varies across operating systems. + +NOTE: Both `tls+tcp6://` and `tls+tcp4://` are _nng_ extensions, and will not +be understood by other implementations such as _mangos_. + +TIP: We recommend using either numeric IP addresses, or names that are +specific to either IPv4 or IPv6 to prevent confusion and surprises. + When specifying IPv6 addresses, the address must be enclosed in square brackets (`[]`) to avoid confusion with the final colon separating the port. diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c index 171cc8ee..419774e1 100644 --- a/src/transport/tcp/tcp.c +++ b/src/transport/tcp/tcp.c @@ -611,6 +611,17 @@ nni_tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) nni_sockaddr rsa, lsa; nni_aio * aio; int passive; + 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); + } // Check for invalid URL components. if ((strlen(url->u_path) != 0) && (strcmp(url->u_path, "/") != 0)) { @@ -640,7 +651,7 @@ nni_tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) // or connect! if (mode == NNI_EP_MODE_DIAL) { passive = 0; - lsa.s_family = NNG_AF_UNSPEC; + lsa.s_family = af; nni_aio_set_input(aio, 0, &rsa); if ((host == NULL) || (serv == NULL)) { nni_aio_fini(aio); @@ -648,11 +659,11 @@ nni_tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) } } else { passive = 1; - rsa.s_family = NNG_AF_UNSPEC; + rsa.s_family = af; nni_aio_set_input(aio, 0, &lsa); } - nni_plat_tcp_resolv(host, serv, NNG_AF_UNSPEC, passive, aio); + nni_plat_tcp_resolv(host, serv, af, passive, aio); nni_aio_wait(aio); if ((rv = nni_aio_result(aio)) != 0) { nni_aio_fini(aio); @@ -981,8 +992,32 @@ static nni_tran nni_tcp_tran = { .tran_fini = nni_tcp_tran_fini, }; +static nni_tran nni_tcp4_tran = { + .tran_version = NNI_TRANSPORT_VERSION, + .tran_scheme = "tcp4", + .tran_ep = &nni_tcp_ep_ops, + .tran_pipe = &nni_tcp_pipe_ops, + .tran_init = nni_tcp_tran_init, + .tran_fini = nni_tcp_tran_fini, +}; + +static nni_tran nni_tcp6_tran = { + .tran_version = NNI_TRANSPORT_VERSION, + .tran_scheme = "tcp6", + .tran_ep = &nni_tcp_ep_ops, + .tran_pipe = &nni_tcp_pipe_ops, + .tran_init = nni_tcp_tran_init, + .tran_fini = nni_tcp_tran_fini, +}; + int nng_tcp_register(void) { - return (nni_tran_register(&nni_tcp_tran)); + int rv; + if (((rv = nni_tran_register(&nni_tcp_tran)) != 0) || + ((rv = nni_tran_register(&nni_tcp4_tran)) != 0) || + ((rv = nni_tran_register(&nni_tcp6_tran)) != 0)) { + return (rv); + } + return (0); } diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c index f7e90303..385dd206 100644 --- a/src/transport/tls/tls.c +++ b/src/transport/tls/tls.c @@ -622,6 +622,17 @@ nni_tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) int passive; nng_tls_mode tlsmode; nng_tls_auth_mode authmode; + uint16_t af; + + 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)) { @@ -651,7 +662,7 @@ nni_tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) passive = 0; tlsmode = NNG_TLS_MODE_CLIENT; authmode = NNG_TLS_AUTH_MODE_REQUIRED; - lsa.s_family = NNG_AF_UNSPEC; + lsa.s_family = af; nni_aio_set_input(aio, 0, &rsa); if ((host == NULL) || (serv == NULL)) { nni_aio_fini(aio); @@ -661,13 +672,13 @@ nni_tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) passive = 1; tlsmode = NNG_TLS_MODE_SERVER; authmode = NNG_TLS_AUTH_MODE_NONE; - rsa.s_family = NNG_AF_UNSPEC; + rsa.s_family = af; nni_aio_set_input(aio, 0, &lsa); } // XXX: arguably we could defer this part to the point we do a bind // or connect! - nni_plat_tcp_resolv(host, serv, NNG_AF_UNSPEC, passive, aio); + nni_plat_tcp_resolv(host, serv, af, passive, aio); nni_aio_wait(aio); if ((rv = nni_aio_result(aio)) != 0) { nni_aio_fini(aio); @@ -1137,8 +1148,32 @@ static nni_tran nni_tls_tran = { .tran_fini = nni_tls_tran_fini, }; +static nni_tran nni_tls4_tran = { + .tran_version = NNI_TRANSPORT_VERSION, + .tran_scheme = "tls+tcp4", + .tran_ep = &nni_tls_ep_ops, + .tran_pipe = &nni_tls_pipe_ops, + .tran_init = nni_tls_tran_init, + .tran_fini = nni_tls_tran_fini, +}; + +static nni_tran nni_tls6_tran = { + .tran_version = NNI_TRANSPORT_VERSION, + .tran_scheme = "tls+tcp6", + .tran_ep = &nni_tls_ep_ops, + .tran_pipe = &nni_tls_pipe_ops, + .tran_init = nni_tls_tran_init, + .tran_fini = nni_tls_tran_fini, +}; + int nng_tls_register(void) { - return (nni_tran_register(&nni_tls_tran)); + int rv; + if (((rv = nni_tran_register(&nni_tls_tran)) != 0) || + ((rv = nni_tran_register(&nni_tls4_tran)) != 0) || + ((rv = nni_tran_register(&nni_tls6_tran)) != 0)) { + return (rv); + } + return (0); } |
