diff options
| author | Garrett D'Amore <garrett@damore.org> | 2018-01-22 20:38:20 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2018-01-22 20:41:24 -0800 |
| commit | edced7d757bc3bfb98961e0d78695e4bedbb4561 (patch) | |
| tree | 7f67764d6618ecd2841e0b40077a851fa24a483e | |
| parent | 3d075fad7496ec126c5087d1c36ab7a4af73ce16 (diff) | |
| download | nng-edced7d757bc3bfb98961e0d78695e4bedbb4561.tar.gz nng-edced7d757bc3bfb98961e0d78695e4bedbb4561.tar.bz2 nng-edced7d757bc3bfb98961e0d78695e4bedbb4561.zip | |
fixes #221 zerotier URL format changes
We are adopting a more standard URL format for zerotier, and making
more use of the URL parsing common layer. While here we updated
the docs to reflect correctly the URI syntax we are using everywhere.
| -rw-r--r-- | docs/nng_inproc.adoc | 3 | ||||
| -rw-r--r-- | docs/nng_ipc.adoc | 9 | ||||
| -rw-r--r-- | docs/nng_zerotier.adoc | 26 | ||||
| -rw-r--r-- | src/transport/zerotier/zerotier.c | 66 | ||||
| -rw-r--r-- | tests/zt.c | 18 |
5 files changed, 50 insertions, 72 deletions
diff --git a/docs/nng_inproc.adoc b/docs/nng_inproc.adoc index 9ba30fae..47a088a5 100644 --- a/docs/nng_inproc.adoc +++ b/docs/nng_inproc.adoc @@ -46,8 +46,7 @@ URI Format ~~~~~~~~~~ This transport uses URIs using the scheme `inproc://`, followed by -an arbitrary string of text, terminated by a `NUL` byte. The -entire URI must be less than `NNG_MAXADDRLEN` bytes long. +an arbitrary string of text, terminated by a `NUL` byte. Multiple URIs can be used within the same application, and they will not interfere with one another. diff --git a/docs/nng_ipc.adoc b/docs/nng_ipc.adoc index 6367a681..c1fcd5c4 100644 --- a/docs/nng_ipc.adoc +++ b/docs/nng_ipc.adoc @@ -47,17 +47,12 @@ URI Format ~~~~~~~~~~ This transport uses URIs using the scheme `ipc://`, followed by -a path name in the file system where the socket or named pipe +a an absolute path name in the file system where the socket or named pipe should be created. TIP: On Windows, all names are prefixed by `\.\pipe\` and do not occupy the normal file system. On POSIX platforms, the path is -taken literally, and is relative to the current directory, unless -an extra leading `/` is provided. For example, `ipc://myname` refers -to the name `myname` in the current directory, whereas `ipc:///tmp/myname` -refers to `myname` located in `/tmp`. - -The entire URI must be less than `NNG_MAXADDRLEN` bytes long. +taken literally, and is relative to the root directory. Socket Address ~~~~~~~~~~~~~~ diff --git a/docs/nng_zerotier.adoc b/docs/nng_zerotier.adoc index 40ebabff..16bb647c 100644 --- a/docs/nng_zerotier.adoc +++ b/docs/nng_zerotier.adoc @@ -64,19 +64,19 @@ cannot be initialized for any reason. URI Format ~~~~~~~~~~ -This transport uses URIs using the scheme `zt://`, followed by a network -address (sixteen hexadecimal digits), followed by a `/` delimiter, -followed by the node number (ten hexadecimal digits) of the listening -node, followed by a service or port number (decimal value, up to 24-bits). -For example, the URI `zt://0123456789abdef/fedcba9876:999` indicates -that node fedcba9876 on network 0123456789abcdef listening on port 999. - -Listening nodes may use port 0, or `*`, to indicate that a suitable port -number be selected automatically. Applications using this must get the -selected port address using the `nng_listener_getopt` function. - -Listening nodes may also elide their own node number, as well as the -delimiter separating the node number. +This transport uses URIs using the scheme `zt://`, followed by a node +number (ten hexadecimal digits) followed by a `.` delimited, and then +a network address (sixteen hexadecimal digits), followed by a colon (`.`) +and service or port number (decimal value, up to 24-bits). +For example, the URI `zt://fedcba9876.0123456789abdef:999` indicates +that node fedcba9876 on network 0123456789abcdef is listening on port 999. + +The special value `*` can be used in lieu of a node number to represent +the node's own node number. + +Listeners may use port 0 to indicate that a suitable port +number be selected automatically. Applications using this must determine the +selected port number using the `nng_listener_getopt` function. Socket Address ~~~~~~~~~~~~~~ diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c index 2522138f..a5ca739c 100644 --- a/src/transport/zerotier/zerotier.c +++ b/src/transport/zerotier/zerotier.c @@ -2053,7 +2053,7 @@ zt_ep_fini(void *arg) } static int -zt_parsehex(const char **sp, uint64_t *valp, int wildok) +zt_parsehex(const char **sp, uint64_t *valp, bool wildok) { int n; const char *s = *sp; @@ -2109,17 +2109,12 @@ zt_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) int n; int rv; char c; - const char *u; + const char *h; if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) { return (NNG_ENOMEM); } - // URL parsing... - // URL is form zt://<nwid>[/<remoteaddr>]:<port> - // The <remoteaddr> part is required for remote dialers, but is - // not used at all for listeners. (We have no notion of binding - // to different node addresses.) ep->ze_mode = mode; ep->ze_mtu = ZT_MIN_MTU; ep->ze_aio = NULL; @@ -2135,20 +2130,33 @@ zt_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) return (rv); } - u = url->u_rawurl + strlen("zt://"); + // Our URL format is: + // + // zt://<nodeid>.<nwid>:<port> + // + // The port must be specified, but may be zero. The nodeid + // may be '*' to refer to ourself. There may be a trailing slash + // which will be ignored. + + h = url->u_hostname; + if (((strlen(url->u_path) == 1) && (url->u_path[0] != '/')) || + (strlen(url->u_path) > 1) || (url->u_fragment != NULL) || + (url->u_query != NULL) || (url->u_userinfo != NULL) || + (zt_parsehex(&h, &node, true) != 0) || (*h++ != '.') || + (zt_parsehex(&h, &ep->ze_nwid, false) != 0) || + (node > 0xffffffffffull)) { + return (NNG_EADDRINVAL); + } + h = url->u_port; + if ((zt_parsedec(&h, &port) != 0) || (port > zt_max_port)) { + return (NNG_EADDRINVAL); + } // Parse the URL. switch (mode) { case NNI_EP_MODE_DIAL: - // We require zt://<nwid>/<remotenode>:<port> - // The remote node must be a 40 bit address - // (max), and we require a non-zero port to - // connect to. - if ((zt_parsehex(&u, &nwid, 0) != 0) || (*u++ != '/') || - (zt_parsehex(&u, &node, 1) != 0) || - (node > 0xffffffffffull) || (*u++ != ':') || - (zt_parsedec(&u, &port) != 0) || (*u != '\0') || - (port > zt_max_port) || (port == 0)) { + /// We have to have a non-zero port number to connect to. + if (port == 0) { return (NNG_EADDRINVAL); } ep->ze_raddr = node; @@ -2157,28 +2165,6 @@ zt_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) ep->ze_laddr = 0; break; case NNI_EP_MODE_LISTEN: - // Listen mode is just zt://<nwid>:<port>. The - // port may be zero in this case, to indicate - // that the server should allocate an ephemeral - // port. We do allow the same form of URL including - // the node address, but that must be zero, a wild - // card, - // or our own node address. - if (zt_parsehex(&u, &nwid, 0) != 0) { - return (NNG_EADDRINVAL); - } - node = 0; - // Look for optional node address. - if (*u == '/') { - u++; - if (zt_parsehex(&u, &node, 1) != 0) { - return (NNG_EADDRINVAL); - } - } - if ((*u++ != ':') || (zt_parsedec(&u, &port) != 0) || - (*u != '\0') || (port > zt_max_port)) { - return (NNG_EADDRINVAL); - } ep->ze_laddr = node; ep->ze_laddr <<= 24; ep->ze_laddr |= port; @@ -2189,8 +2175,6 @@ zt_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) break; } - ep->ze_nwid = nwid; - nni_mtx_lock(&zt_lk); rv = zt_node_find(ep); nni_mtx_unlock(&zt_lk); @@ -1,6 +1,6 @@ // -// Copyright 2017 Garrett D'Amore <garrett@damore.org> -// Copyright 2017 Capitar IT Group BV <info@capitar.com> +// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -206,7 +206,7 @@ TestMain("ZeroTier Transport", { So(nng_zt_register() == 0); - snprintf(addr, sizeof(addr), "zt://" NWID ":%u", port); + snprintf(addr, sizeof(addr), "zt://*." NWID ":%u", port); So(nng_pair_open(&s) == 0); Reset({ nng_close(s); }); @@ -250,7 +250,7 @@ TestMain("ZeroTier Transport", { So(nng_zt_register() == 0); - snprintf(addr, sizeof(addr), "zt://" NWID "/%llx:%u", + snprintf(addr, sizeof(addr), "zt://%llx." NWID ":%u", (unsigned long long) node, port); So(nng_pair_open(&s) == 0); @@ -269,7 +269,7 @@ TestMain("ZeroTier Transport", { So(nng_zt_register() == 0); - snprintf(addr, sizeof(addr), "zt://" NWID ":%u", port); + snprintf(addr, sizeof(addr), "zt://*." NWID ":%u", port); So(nng_pair_open(&s) == 0); Reset({ nng_close(s); }); @@ -295,7 +295,7 @@ TestMain("ZeroTier Transport", { So(status == nng_zt_network_status_ok); }); Convey("Connection refused works", { - snprintf(addr, sizeof(addr), "zt://" NWID "/%llx:%u", + snprintf(addr, sizeof(addr), "zt://%llx." NWID ":%u", (unsigned long long) node1, 42u); So(nng_dialer_create(&d, s, addr) == 0); So(nng_dialer_getopt_uint64( @@ -318,7 +318,7 @@ TestMain("ZeroTier Transport", { // uint64_t node = 0xb000072fa6ull; // my personal host So(nng_zt_register() == 0); - snprintf(addr1, sizeof(addr1), "zt://" NWID ":%u", port); + snprintf(addr1, sizeof(addr1), "zt://*." NWID ":%u", port); So(nng_pair_open(&s1) == 0); So(nng_pair_open(&s2) == 0); @@ -339,7 +339,7 @@ TestMain("ZeroTier Transport", { So(nng_listener_getopt_uint64(l, NNG_OPT_ZT_NODE, &node) == 0); So(node != 0); nng_msleep(40); - snprintf(addr2, sizeof(addr2), "zt://" NWID "/%llx:%u", + snprintf(addr2, sizeof(addr2), "zt://%llx." NWID ":%u", (unsigned long long) node, port); So(nng_dialer_create(&d, s2, addr2) == 0); So(nng_dialer_setopt( @@ -348,6 +348,6 @@ TestMain("ZeroTier Transport", { nng_msleep(2000); }); - trantest_test_extended("zt://" NWID "/*:%u", check_props); + trantest_test_extended("zt://*." NWID ":%u", check_props); }) |
