aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-05-17 20:20:17 -0700
committerGarrett D'Amore <garrett@damore.org>2018-05-17 20:20:17 -0700
commit109a559590abfe3017dd317c3068e2457188541c (patch)
tree103c9eba61c3d82956b677c78cc83ae040968c8f
parent70d478f5d185e147ca8d3dcba4cbd8bb6da3719a (diff)
downloadnng-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.adoc14
-rw-r--r--docs/man/nng_tls.7.adoc16
-rw-r--r--src/transport/tcp/tcp.c43
-rw-r--r--src/transport/tls/tls.c43
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);
}