diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/core/endpt.c | 12 | ||||
| -rw-r--r-- | src/core/endpt.h | 1 | ||||
| -rw-r--r-- | src/nng.c | 118 | ||||
| -rw-r--r-- | src/nng.h | 11 | ||||
| -rw-r--r-- | src/transport/zerotier/zerotier.adoc | 4 | ||||
| -rw-r--r-- | src/transport/zerotier/zerotier.c | 71 | ||||
| -rw-r--r-- | src/transport/zerotier/zerotier.h | 110 |
8 files changed, 259 insertions, 75 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ffcb2b7b..2f2f54ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,7 +144,12 @@ if (NNG_PLATFORM_WINDOWS) endif() if (NNG_ENABLE_ZEROTIER) - set (NNG_SOURCES ${NNG_SOURCES} transport/zerotier/zerotier.c) + set (NNG_SOURCES ${NNG_SOURCES} + transport/zerotier/zerotier.c + transport/zerotier/zerotier.h + ) + install(FILES transport/zerotier/zerotier.h + DESTINATION include/nng/transport/zerotier) endif() include_directories(AFTER SYSTEM ${PROJECT_SOURCE_DIR}/src diff --git a/src/core/endpt.c b/src/core/endpt.c index e6216ba3..fa30bf77 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -605,21 +605,21 @@ nni_ep_setopt(nni_ep *ep, const char *name, const void *val, size_t sz) return (NNG_EREADONLY); } nni_mtx_lock(&ep->ep_mtx); - // XXX: Consider removing this test. - if (ep->ep_started) { - nni_mtx_unlock(&ep->ep_mtx); - return (NNG_ESTATE); - } rv = eo->eo_setopt(ep->ep_data, val, sz); nni_mtx_unlock(&ep->ep_mtx); return (rv); } - // XXX: socket fallback return (NNG_ENOTSUP); } int +nni_ep_mode(nni_ep *ep) +{ + return (ep->ep_mode); +} + +int nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) { nni_tran_ep_option *eo; diff --git a/src/core/endpt.h b/src/core/endpt.h index d12d661f..f5ad09ee 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -32,6 +32,7 @@ extern int nni_ep_getopt(nni_ep *, const char *, void *, size_t *); extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); extern const char *nni_ep_url(nni_ep *); +extern int nni_ep_mode(nni_ep *); // Endpoint modes. Currently used by transports. Remove this when we make // transport dialers and listeners explicit. @@ -328,7 +328,8 @@ nng_dialer_start(nng_dialer id, int flags) } static int -nng_ep_setopt(uint32_t id, const char *name, const void *val, size_t sz) +nng_ep_setopt( + uint32_t id, const char *name, const void *val, size_t sz, int mode) { nni_ep *ep; int rv; @@ -339,13 +340,17 @@ nng_ep_setopt(uint32_t id, const char *name, const void *val, size_t sz) if ((rv = nni_ep_find(&ep, id)) != 0) { return (rv); } - rv = nni_ep_setopt(ep, name, val, sz); + if (nni_ep_mode(ep) == mode) { + rv = nni_ep_setopt(ep, name, val, sz); + } else { + rv = NNG_ENOENT; + } nni_ep_rele(ep); return (rv); } static int -nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp) +nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp, int mode) { nni_ep *ep; int rv; @@ -356,7 +361,11 @@ nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp) if ((rv = nni_ep_find(&ep, id)) != 0) { return (rv); } - rv = nni_ep_getopt(ep, name, val, szp); + if (nni_ep_mode(ep) == mode) { + rv = nni_ep_getopt(ep, name, val, szp); + } else { + rv = NNG_ENOENT; + } nni_ep_rele(ep); return (rv); } @@ -364,104 +373,128 @@ nng_ep_getopt(uint32_t id, const char *name, void *val, size_t *szp) int nng_dialer_setopt(nng_dialer id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, name, v, sz)); + return (nng_ep_setopt(id, name, v, sz, NNI_EP_MODE_DIAL)); } int nng_dialer_setopt_int(nng_dialer id, const char *name, int val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setopt(id, name, &val, sizeof(val))); } int nng_dialer_setopt_size(nng_dialer id, const char *name, size_t val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setopt(id, name, &val, sizeof(val))); } int nng_dialer_setopt_usec(nng_dialer id, const char *name, uint64_t val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_dialer_setopt(id, name, &val, sizeof(val))); +} + +int +nng_dialer_setopt_uint64(nng_dialer id, const char *name, uint64_t val) +{ + return (nng_dialer_setopt(id, name, &val, sizeof(val))); } int nng_dialer_getopt(nng_dialer id, const char *name, void *val, size_t *szp) { - return (nng_ep_getopt(id, name, val, szp)); + return (nng_ep_getopt(id, name, val, szp, NNI_EP_MODE_DIAL)); } int nng_dialer_getopt_int(nng_dialer id, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_dialer_getopt(id, name, valp, &sz)); } int nng_dialer_getopt_size(nng_dialer id, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_dialer_getopt(id, name, valp, &sz)); } int -nng_dialer_getopt_usec(nng_dialer id, const char *name, uint64_t *valp) +nng_dialer_getopt_uint64(nng_dialer id, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_dialer_getopt(id, name, valp, &sz)); +} + +int +nng_dialer_getopt_usec(nng_dialer id, const char *name, uint64_t *valp) +{ + return (nng_dialer_getopt_uint64(id, name, valp)); } int nng_listener_setopt( nng_listener id, const char *name, const void *v, size_t sz) { - return (nng_ep_setopt(id, name, v, sz)); + return (nng_ep_setopt(id, name, v, sz, NNI_EP_MODE_LISTEN)); } int nng_listener_setopt_int(nng_listener id, const char *name, int val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setopt(id, name, &val, sizeof(val))); } int nng_listener_setopt_size(nng_listener id, const char *name, size_t val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setopt(id, name, &val, sizeof(val))); } int nng_listener_setopt_usec(nng_listener id, const char *name, uint64_t val) { - return (nng_ep_setopt(id, name, &val, sizeof(val))); + return (nng_listener_setopt(id, name, &val, sizeof(val))); +} + +int +nng_listener_setopt_uint64(nng_listener id, const char *name, uint64_t val) +{ + return (nng_listener_setopt(id, name, &val, sizeof(val))); } int nng_listener_getopt(nng_listener id, const char *name, void *val, size_t *szp) { - return (nng_ep_getopt(id, name, val, szp)); + return (nng_ep_getopt(id, name, val, szp, NNI_EP_MODE_LISTEN)); } int nng_listener_getopt_int(nng_listener id, const char *name, int *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_listener_getopt(id, name, valp, &sz)); } int nng_listener_getopt_size(nng_listener id, const char *name, size_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_listener_getopt(id, name, valp, &sz)); } int -nng_listener_getopt_usec(nng_listener id, const char *name, uint64_t *valp) +nng_listener_getopt_uint64(nng_listener id, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); - return (nng_ep_getopt(id, name, valp, &sz)); + return (nng_listener_getopt(id, name, valp, &sz)); +} + +int +nng_listener_getopt_usec(nng_listener id, const char *name, uint64_t *valp) +{ + return (nng_listener_getopt_uint64(id, name, valp)); } static int @@ -543,6 +576,12 @@ nng_setopt_usec(nng_socket sid, const char *name, uint64_t val) } int +nng_setopt_uint64(nng_socket sid, const char *name, uint64_t val) +{ + return (nng_setopt(sid, name, &val, sizeof(val))); +} + +int nng_getopt_int(nng_socket sid, const char *name, int *valp) { size_t sz = sizeof(*valp); @@ -557,12 +596,18 @@ nng_getopt_size(nng_socket sid, const char *name, size_t *valp) } int -nng_getopt_usec(nng_socket sid, const char *name, uint64_t *valp) +nng_getopt_uint64(nng_socket sid, const char *name, uint64_t *valp) { size_t sz = sizeof(*valp); return (nng_getopt(sid, name, valp, &sz)); } +int +nng_getopt_usec(nng_socket sid, const char *name, uint64_t *valp) +{ + return (nng_getopt_uint64(sid, name, valp)); +} + nng_notify * nng_setnotify(nng_socket sid, int mask, nng_notify_func fn, void *arg) { @@ -709,6 +754,33 @@ nng_pipe_getopt(nng_pipe id, const char *name, void *val, size_t *sizep) } int +nng_pipe_getopt_int(nng_pipe id, const char *name, int *valp) +{ + size_t sz = sizeof(*valp); + return (nng_pipe_getopt(id, name, valp, &sz)); +} + +int +nng_pipe_getopt_size(nng_pipe id, const char *name, size_t *valp) +{ + size_t sz = sizeof(*valp); + return (nng_pipe_getopt(id, name, valp, &sz)); +} + +int +nng_pipe_getopt_uint64(nng_pipe id, const char *name, uint64_t *valp) +{ + size_t sz = sizeof(*valp); + return (nng_pipe_getopt(id, name, valp, &sz)); +} + +int +nni_pipe_getopt_usec(nng_pipe id, const char *name, uint64_t *valp) +{ + return (nng_pipe_getopt_uint64(id, name, valp)); +} + +int nng_pipe_close(nng_pipe id) { int rv; @@ -90,12 +90,14 @@ NNG_DECL int nng_setopt(nng_socket, const char *, const void *, size_t); NNG_DECL int nng_setopt_int(nng_socket, const char *, int); NNG_DECL int nng_setopt_usec(nng_socket, const char *, uint64_t); NNG_DECL int nng_setopt_size(nng_socket, const char *, size_t); +NNG_DECL int nng_setopt_uint64(nng_socket, const char *, uint64_t); // nng_socket_getopt obtains the option for a socket. NNG_DECL int nng_getopt(nng_socket, const char *, void *, size_t *); NNG_DECL int nng_getopt_int(nng_socket, const char *, int *); NNG_DECL int nng_getopt_usec(nng_socket, const char *, uint64_t *); NNG_DECL int nng_getopt_size(nng_socket, const char *, size_t *); +NNG_DECL int nng_getopt_uint64(nng_socket, const char *, uint64_t *); // nng_notify_func is a user function that is executed upon certain // events. See below. @@ -203,6 +205,7 @@ NNG_DECL int nng_dialer_setopt(nng_dialer, const char *, const void *, size_t); NNG_DECL int nng_dialer_setopt_int(nng_dialer, const char *, int); NNG_DECL int nng_dialer_setopt_usec(nng_dialer, const char *, uint64_t); NNG_DECL int nng_dialer_setopt_size(nng_dialer, const char *, size_t); +NNG_DECL int nng_dialer_setopt_uint64(nng_dialer, const char *, uint64_t); // nng_dialer_getopt obtains the option for a dialer. This will // fail for options that a particular dialer is not interested in, @@ -211,6 +214,7 @@ NNG_DECL int nng_dialer_getopt(nng_dialer, const char *, void *, size_t *); NNG_DECL int nng_dialer_getopt_int(nng_dialer, const char *, int *); NNG_DECL int nng_dialer_getopt_usec(nng_dialer, const char *, uint64_t *); NNG_DECL int nng_dialer_getopt_size(nng_dialer, const char *, size_t *); +NNG_DECL int nng_dialer_getopt_uint64(nng_dialer, const char *, uint64_t *); // nng_listener_setopt sets an option for a dialer. This value is // not stored in the socket. Subsequent setopts on the socket may @@ -221,6 +225,7 @@ NNG_DECL int nng_listener_setopt( NNG_DECL int nng_listener_setopt_int(nng_listener, const char *, int); NNG_DECL int nng_listener_setopt_usec(nng_listener, const char *, uint64_t); NNG_DECL int nng_listener_setopt_size(nng_listener, const char *, size_t); +NNG_DECL int nng_listener_setopt_uint64(nng_listener, const char *, uint64_t); // nng_listener_getopt obtains the option for a listener. This will // fail for options that a particular listener is not interested in, @@ -229,6 +234,8 @@ NNG_DECL int nng_listener_getopt(nng_listener, const char *, void *, size_t *); NNG_DECL int nng_listener_getopt_int(nng_listener, const char *, int *); NNG_DECL int nng_listener_getopt_usec(nng_listener, const char *, uint64_t *); NNG_DECL int nng_listener_getopt_size(nng_listener, const char *, size_t *); +NNG_DECL int nng_listener_getopt_uint64( + nng_listener, const char *, uint64_t *); // nng_strerror returns a human readable string associated with the error // code supplied. @@ -322,6 +329,10 @@ NNG_DECL const char *nng_option_name(int); // example during a connection notification, to disconnect a pipe that // is associated with an invalid or untrusted remote peer. NNG_DECL int nng_pipe_getopt(nng_pipe, const char *, void *, size_t *); +NNG_DECL int nng_pipe_getopt_int(nng_pipe, const char *, int *); +NNG_DECL int nng_pipe_getopt_usec(nng_pipe, const char *, uint64_t *); +NNG_DECL int nng_pipe_getopt_size(nng_pipe, const char *, size_t *); +NNG_DECL int nng_pipe_getopt_uint64(nng_pipe, const char *, uint64_t *); NNG_DECL int nng_pipe_close(nng_pipe); // Flags. diff --git a/src/transport/zerotier/zerotier.adoc b/src/transport/zerotier/zerotier.adoc index dc838420..84501807 100644 --- a/src/transport/zerotier/zerotier.adoc +++ b/src/transport/zerotier/zerotier.adoc @@ -357,10 +357,10 @@ ZeroTier IDs, ZeroTier network IDs, and our own 24-bit ports. The format shall be `zt://<nwid>/<ztid>:<port>`, where the `<nwid>` component represents the 64-bit hexadecimal ZeroTier network ID, the `<ztid>` represents the 40-bit hexadecimal ZeroTier Device ID, -and the `<port>` is the 24-bit port number previously described. +and the `<port>` is the 24-bit port number (decimal) previously described. A responder may elide the `<ztid>/` portion, to just bind to itself, -in which case the format will be `zt://<nwid>/<ztid>:<port>`. +in which case the format will be `zt://<nwid>:<port>`. A port number of 0 may be used when listening to indicate that a random ephemeral port should be chosen. diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c index 46423b80..56acce03 100644 --- a/src/transport/zerotier/zerotier.c +++ b/src/transport/zerotier/zerotier.c @@ -15,6 +15,7 @@ #include <string.h> #include "core/nng_impl.h" +#include "zerotier.h" #ifndef _WIN32 #include <unistd.h> @@ -22,31 +23,16 @@ #include <ZeroTierOne.h> -#define NNG_ZT_OPT_HOME "zt:home" -#define NNG_ZT_OPT_NWID "zt:nwid" -#define NNG_ZT_OPT_NODE "zt:node" -#define NNG_ZT_OPT_STATUS "zt:status" -#define NNG_ZT_OPT_NETWORK_NAME "zt:network-name" -#define NNG_ZT_OPT_PING_TIME "zt:ping-time" -#define NNG_ZT_OPT_PING_COUNT "zt:ping-count" -#define NNG_ZT_OPT_MTU "zt:mtu" - -const char *nng_opt_zt_home = NNG_ZT_OPT_HOME; -const char *nng_opt_zt_nwid = NNG_ZT_OPT_NWID; -const char *nng_opt_zt_node = NNG_ZT_OPT_NODE; -const char *nng_opt_zt_status = NNG_ZT_OPT_STATUS; -const char *nng_opt_zt_network_name = NNG_ZT_OPT_NETWORK_NAME; -const char *nng_opt_zt_ping_time = NNG_ZT_OPT_PING_TIME; -const char *nng_opt_zt_ping_count = NNG_ZT_OPT_PING_COUNT; - // These values are supplied to help folks checking status. They are the -// return values from zt_opt_status. -int nng_zt_status_configuring = ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION; -int nng_zt_status_ok = ZT_NETWORK_STATUS_OK; -int nng_zt_status_denied = ZT_NETWORK_STATUS_ACCESS_DENIED; -int nng_zt_status_notfound = ZT_NETWORK_STATUS_NOT_FOUND; -int nng_zt_status_error = ZT_NETWORK_STATUS_PORT_ERROR; -int nng_zt_status_obsolete = ZT_NETWORK_STATUS_CLIENT_TOO_OLD; +// return values from zt_opt_status. It's important that the status values +// here match what the underlying ZeroTier core gives us. +int nng_zt_network_status_configuring = + ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION; +int nng_zt_network_status_ok = ZT_NETWORK_STATUS_OK; +int nng_zt_network_status_denied = ZT_NETWORK_STATUS_ACCESS_DENIED; +int nng_zt_network_status_notfound = ZT_NETWORK_STATUS_NOT_FOUND; +int nng_zt_network_status_error = ZT_NETWORK_STATUS_PORT_ERROR; +int nng_zt_network_status_obsolete = ZT_NETWORK_STATUS_CLIENT_TOO_OLD; // ZeroTier Transport. This sits on the ZeroTier L2 network, which itself // is implemented on top of UDP. This requires the 3rd party @@ -248,6 +234,7 @@ struct zt_ep { zt_node * ze_ztn; uint64_t ze_nwid; int ze_mode; + int ze_running; nni_sockaddr ze_addr; uint64_t ze_raddr; // remote node address uint64_t ze_laddr; // local node address @@ -1932,7 +1919,7 @@ zt_pipe_peer(void *arg) } static int -zt_getopt_status(zt_node *ztn, uint64_t nwid, void *buf, size_t *szp) +zt_getopt_network_status(zt_node *ztn, uint64_t nwid, void *buf, size_t *szp) { ZT_VirtualNetworkConfig *vcfg; int status; @@ -1990,13 +1977,6 @@ zt_pipe_get_node(void *arg, void *buf, size_t *szp) return (nni_getopt_u64(p->zp_laddr >> 24, buf, szp)); } -static int -zt_pipe_get_status(void *arg, void *buf, size_t *szp) -{ - zt_pipe *p = arg; - return (zt_getopt_status(p->zp_ztn, p->zp_nwid, buf, szp)); -} - static void zt_pipe_cancel_ping(nni_aio *aio, int rv) { @@ -2308,6 +2288,7 @@ zt_ep_bind_locked(zt_ep *ep) ep->ze_laddr = ztn->zn_self; ep->ze_laddr <<= 24; ep->ze_laddr |= port; + ep->ze_running = 1; if ((rv = nni_idhash_insert(ztn->zn_eps, ep->ze_laddr, ep)) != 0) { nni_idhash_remove(ztn->zn_ports, port); @@ -2498,6 +2479,7 @@ zt_ep_connect(void *arg, nni_aio *aio) nni_aio_list_append(&ep->ze_aios, aio); ep->ze_creq_try = 1; + ep->ze_running = 1; nni_aio_set_timeout(ep->ze_creq_aio, now + zt_conn_interval); // This can't fail -- the only way the ze_creq_aio gets @@ -2543,6 +2525,9 @@ zt_ep_setopt_home(void *arg, const void *data, size_t sz) return (NNG_EINVAL); } if (ep != NULL) { + if (ep->ze_running) { + return (NNG_ESTATE); + } nni_mtx_lock(&zt_lk); nni_strlcpy(ep->ze_home, data, sizeof(ep->ze_home)); if ((rv = zt_node_find(ep)) != 0) { @@ -2584,10 +2569,10 @@ zt_ep_getopt_network_name(void *arg, void *buf, size_t *szp) } static int -zt_ep_getopt_status(void *arg, void *buf, size_t *szp) +zt_ep_getopt_network_status(void *arg, void *buf, size_t *szp) { zt_ep *ep = arg; - return (zt_getopt_status(ep->ze_ztn, ep->ze_nwid, buf, szp)); + return (zt_getopt_network_status(ep->ze_ztn, ep->ze_nwid, buf, szp)); } static int @@ -2658,7 +2643,7 @@ zt_pipe_getopt_mtu(void *arg, void *data, size_t *szp) static nni_tran_pipe_option zt_pipe_options[] = { { NNG_OPT_LOCADDR, zt_pipe_getopt_locaddr }, { NNG_OPT_REMADDR, zt_pipe_getopt_remaddr }, - { NNG_ZT_OPT_MTU, zt_pipe_getopt_mtu }, + { NNG_OPT_ZT_MTU, zt_pipe_getopt_mtu }, // terminate list { NULL, NULL }, }; @@ -2680,37 +2665,37 @@ static nni_tran_ep_option zt_ep_options[] = { .eo_setopt = zt_ep_setopt_recvmaxsz, }, { - .eo_name = NNG_ZT_OPT_HOME, + .eo_name = NNG_OPT_ZT_HOME, .eo_getopt = zt_ep_getopt_home, .eo_setopt = zt_ep_setopt_home, }, { - .eo_name = NNG_ZT_OPT_NODE, + .eo_name = NNG_OPT_ZT_NODE, .eo_getopt = zt_ep_getopt_node, .eo_setopt = NULL, }, { - .eo_name = NNG_ZT_OPT_NWID, + .eo_name = NNG_OPT_ZT_NWID, .eo_getopt = zt_ep_getopt_nwid, .eo_setopt = NULL, }, { - .eo_name = NNG_ZT_OPT_STATUS, - .eo_getopt = zt_ep_getopt_status, + .eo_name = NNG_OPT_ZT_NETWORK_STATUS, + .eo_getopt = zt_ep_getopt_network_status, .eo_setopt = NULL, }, { - .eo_name = NNG_ZT_OPT_NETWORK_NAME, + .eo_name = NNG_OPT_ZT_NETWORK_NAME, .eo_getopt = zt_ep_getopt_network_name, .eo_setopt = NULL, }, { - .eo_name = NNG_ZT_OPT_PING_TIME, + .eo_name = NNG_OPT_ZT_PING_TIME, .eo_getopt = zt_ep_getopt_ping_time, .eo_setopt = zt_ep_setopt_ping_time, }, { - .eo_name = NNG_ZT_OPT_PING_COUNT, + .eo_name = NNG_OPT_ZT_PING_COUNT, .eo_getopt = zt_ep_getopt_ping_count, .eo_setopt = zt_ep_setopt_ping_count, }, diff --git a/src/transport/zerotier/zerotier.h b/src/transport/zerotier/zerotier.h new file mode 100644 index 00000000..ff33609e --- /dev/null +++ b/src/transport/zerotier/zerotier.h @@ -0,0 +1,110 @@ +// +// Copyright 2017 Garrett D'Amore <garrett@damore.org> +// Copyright 2017 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 +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#ifndef NNG_TRANSPORT_ZEROTIER_ZEROTIER_H +#define NNG_TRANSPORT_ZEROTIER_ZEROTIER_H + +// ZeroTier Transport. This sits on the ZeroTier L2 network, which itself +// is implemented on top of UDP. This requires the 3rd party +// libzerotiercore library (which is GPLv3!) and platform specific UDP +// functionality to be built in. Note that care must be taken to link +// dynamically if one wishes to avoid making your entire application GPL3. +// (Alternatively ZeroTier offers commercial licenses which may prevent +// this particular problem.) This implementation does not make use of +// certain advanced capabilities in ZeroTier such as more sophisticated +// route management and TCP fallback. You need to have connectivity +// to the Internet to use this. (Or at least to your Planetary root.) +// +// The ZeroTier URL format we support is zt://<nwid>/<ztid>:<port> where +// the <nwid> component represents the 64-bit hexadecimal ZeroTier +// network ID,the <ztid> represents the 40-bit hexadecimal ZeroTier +// node (device) ID, and the <port> is a 24-bit (decimal) port number. +// +// A listener may elide the <ztid>/ portion, to just bind to itself, +// in which case the format will be zt://<nwid>:<port> +// +// A listener may also use either 0 or * for the <port> to indicate that +// a random local ephemeral port should be used. +// +// Because ZeroTier takes a while to establish connectivity, it is even +// more important that applications using the ZeroTier transport not +// assume that a connection will be immediately available. It can take +// quite a few seconds for peer-to-peer connectivity to be established. +// +// The ZeroTier transport was funded by Capitar IT Group, BV. +// +// This transport is highly experimental. + +// ZeroTier transport-specific options. + +// NNG_OPT_ZT_HOME is a string containing a directory, where persistent +// state (key files, etc.) will be stored. It should be protected from +// unauthorized viewing and modification. This option must be set on an +// endpoint or socket before the endpoint(s) are started. If the unset, +// or an empty string, then no persistence is used and an ephemeral node +// will be created instead. Note that different endpoints may use different +// values for this option, and that will lead to each endpoint having a +// different ZeroTier identity -- however only one ephemeral node will +// be created for the application. +#define NNG_OPT_ZT_HOME "zt:home" + +// NNG_OPT_ZT_NWID is the 64-bit network ID, represented using a uint64_t in +// native byte order. This is a read-only option; it is derived automatically +// from the URL. +#define NNG_OPT_ZT_NWID "zt:nwid" + +// NNG_OPT_ZT_NODE is the 40-bit node ID, stored in native order in the low +// 40-bits of a uint64_t, of the node. This is a read-only option. +#define NNG_OPT_ZT_NODE "zt:node" + +// NNG_OPT_ZT_NETWORK_STATUS represents the status of the ZeroTier virtual +// network. The option is a read-only value, stored as an integer, which +// takes of the nng_zt_network_status_xxx values listed below. +#define NNG_OPT_ZT_NETWORK_STATUS "zt:network-status" + +// NNG_OPT_ZT_NETWORK_NAME is a human-readable name for the ZeroTier virtual +// network. This will only be set once the ZeroTier network has come up +// as the name comes from the network controller. This is read-only, and +// is presented as an ASCIIZ string. +#define NNG_OPT_ZT_NETWORK_NAME "zt:network-name" + +// NNG_OPT_ZT_PING_TIME and NNG_OPT_ZT_PING_COUNT are used to send ping +// requests when a connection appears to be idled. If a logical session +// has not received traffic from it's peer for ping-time, then a ping packet +// is sent. This will be done up to ping-count times. If no traffic from +// the remote peer is seen after all ping requests are sent, then the peer +// is assumed to be dead or offline, and the session is closed. The +// NNG_OPT_ZT_PING_TIME is a duration (usec, stored as an nng_duration, and +// NNG_OPT_ZT_PING_COUNT is an integer.) This ping process can be disabled +// by setting either ping-time or ping-count to zero. +#define NNG_OPT_ZT_PING_TIME "zt:ping-time" +#define NNG_OPT_ZT_PING_COUNT "zt:ping-count" + +// NNG_OPT_ZT_MTU is a read-only size_t and contains the ZeroTier virtual +// network MTU (i.e. the L2 payload MTU). Messages that are larger than this +// (including our 20-byte header data) will be fragmented into multiple +// virtual L2 frames. +#define NNG_OPT_ZT_MTU "zt:mtu" + +// Network status values. +// These values are supplied to help folks checking status. They are the +// return values from zt_opt_status. We avoid hard coding them as defines, +// to keep applications from baking in values that may change if the +// underlying ZeroTier transport changes. +extern int nng_zt_network_status_configuring; +extern int nng_zt_network_status_ok; +extern int nng_zt_network_status_denied; +extern int nng_zt_network_status_notfound; +extern int nng_zt_network_status_error; +extern int nng_zt_network_status_obsolete; + +extern int nng_zt_register(void); + +#endif // NNG_TRANSPORT_ZEROTIER_ZEROTIER_H |
