diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/defs.h | 4 | ||||
| -rw-r--r-- | src/core/endpt.c | 11 | ||||
| -rw-r--r-- | src/core/platform.h | 8 | ||||
| -rw-r--r-- | src/platform/posix/posix_aio.h | 1 | ||||
| -rw-r--r-- | src/platform/posix/posix_epdesc.c | 12 | ||||
| -rw-r--r-- | src/platform/posix/posix_tcp.c | 51 | ||||
| -rw-r--r-- | src/platform/windows/win_tcp.c | 58 | ||||
| -rw-r--r-- | src/supplemental/http/http_server.c | 2 | ||||
| -rw-r--r-- | src/transport/tcp/tcp.c | 26 | ||||
| -rw-r--r-- | src/transport/tls/tls.c | 28 | ||||
| -rw-r--r-- | src/transport/zerotier/zerotier.c | 21 |
11 files changed, 205 insertions, 17 deletions
diff --git a/src/core/defs.h b/src/core/defs.h index b08ce838..c449aa32 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -111,8 +111,8 @@ typedef struct { } while (0) #define NNI_GET16(ptr, v) \ - v = (((uint32_t)((uint8_t)(ptr)[0])) << 8) + \ - (((uint32_t)(uint8_t)(ptr)[1])) + v = (((uint16_t)((uint8_t)(ptr)[0])) << 8) + \ + (((uint16_t)(uint8_t)(ptr)[1])) #define NNI_GET32(ptr, v) \ v = (((uint32_t)((uint8_t)(ptr)[0])) << 24) + \ diff --git a/src/core/endpt.c b/src/core/endpt.c index 4d3727bc..4d3d9031 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -618,10 +618,6 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) { nni_tran_ep_option *eo; - if (strcmp(name, NNG_OPT_URL) == 0) { - return (nni_getopt_str(ep->ep_url->u_rawurl, valp, szp)); - } - for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { int rv; if (strcmp(eo->eo_name, name) != 0) { @@ -636,6 +632,13 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) return (rv); } + // We provide a fallback on the URL, but let the implementation + // override. This allows the URL to be created with wildcards, + // that are resolved later. + if (strcmp(name, NNG_OPT_URL) == 0) { + return (nni_getopt_str(ep->ep_url->u_rawurl, valp, szp)); + } + return (nni_sock_getopt(ep->ep_sock, name, valp, szp)); } diff --git a/src/core/platform.h b/src/core/platform.h index cf635f4a..3f336f11 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -207,7 +207,7 @@ extern void nni_plat_tcp_ep_close(nni_plat_tcp_ep *); // nni_plat_tcp_listen creates an TCP socket in listening mode, bound // to the specified path. -extern int nni_plat_tcp_ep_listen(nni_plat_tcp_ep *); +extern int nni_plat_tcp_ep_listen(nni_plat_tcp_ep *, nni_sockaddr *); // nni_plat_tcp_ep_accept starts an accept to receive an incoming connection. // An accepted connection will be passed back in the a_pipe member. @@ -248,6 +248,12 @@ extern int nni_plat_tcp_pipe_peername(nni_plat_tcp_pipe *, nni_sockaddr *); // nni_plat_tcp_pipe_sockname gets the local name. extern int nni_plat_tcp_pipe_sockname(nni_plat_tcp_pipe *, nni_sockaddr *); +// nni_plat_tcp_ntop obtains the IP address for the socket (enclosing it +// in brackets if it is IPv6) and port. Enough space for both must +// be present (48 bytes and 6 bytes each), although if either is NULL then +// those components are skipped. +extern int nni_plat_tcp_ntop(const nni_sockaddr *, char *, char *); + // nni_plat_tcp_resolv resolves a TCP name asynchronously. The family // should be one of NNG_AF_INET, NNG_AF_INET6, or NNG_AF_UNSPEC. The // first two constrain the name to those families, while the third will diff --git a/src/platform/posix/posix_aio.h b/src/platform/posix/posix_aio.h index 71656391..2073f6d6 100644 --- a/src/platform/posix/posix_aio.h +++ b/src/platform/posix/posix_aio.h @@ -40,5 +40,6 @@ extern void nni_posix_epdesc_close(nni_posix_epdesc *); extern void nni_posix_epdesc_connect(nni_posix_epdesc *, nni_aio *); extern int nni_posix_epdesc_listen(nni_posix_epdesc *); extern void nni_posix_epdesc_accept(nni_posix_epdesc *, nni_aio *); +extern int nni_posix_epdesc_sockname(nni_posix_epdesc *, nni_sockaddr *); #endif // PLATFORM_POSIX_AIO_H diff --git a/src/platform/posix/posix_epdesc.c b/src/platform/posix/posix_epdesc.c index 3da36fa2..16c0d09f 100644 --- a/src/platform/posix/posix_epdesc.c +++ b/src/platform/posix/posix_epdesc.c @@ -343,6 +343,18 @@ nni_posix_epdesc_accept(nni_posix_epdesc *ed, nni_aio *aio) nni_mtx_unlock(&ed->mtx); } +int +nni_posix_epdesc_sockname(nni_posix_epdesc *ed, nni_sockaddr *sa) +{ + struct sockaddr_storage ss; + socklen_t sslen = sizeof(ss); + + if (getsockname(ed->node.fd, (void *) &ss, &sslen) != 0) { + return (nni_plat_errno(errno)); + } + return (nni_posix_sockaddr2nn(sa, &ss)); +} + void nni_posix_epdesc_connect(nni_posix_epdesc *ed, nni_aio *aio) { diff --git a/src/platform/posix/posix_tcp.c b/src/platform/posix/posix_tcp.c index 79e241a3..8a6fe9d1 100644 --- a/src/platform/posix/posix_tcp.c +++ b/src/platform/posix/posix_tcp.c @@ -13,6 +13,7 @@ #ifdef NNG_PLATFORM_POSIX #include "platform/posix/posix_aio.h" +#include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <netinet/in.h> @@ -65,9 +66,14 @@ nni_plat_tcp_ep_close(nni_plat_tcp_ep *ep) } int -nni_plat_tcp_ep_listen(nni_plat_tcp_ep *ep) +nni_plat_tcp_ep_listen(nni_plat_tcp_ep *ep, nng_sockaddr *bsa) { - return (nni_posix_epdesc_listen((void *) ep)); + int rv; + rv = nni_posix_epdesc_listen((void *) ep); + if ((rv == 0) && (bsa != NULL)) { + rv = nni_posix_epdesc_sockname((void *) ep, bsa); + } + return (rv); } void @@ -118,4 +124,45 @@ nni_plat_tcp_pipe_sockname(nni_plat_tcp_pipe *p, nni_sockaddr *sa) return (nni_posix_pipedesc_sockname((void *) p, sa)); } +int +nni_plat_tcp_ntop(const nni_sockaddr *sa, char *ipstr, char *portstr) +{ + const void *ap; + uint16_t port; + int af; + switch (sa->s_un.s_family) { + case NNG_AF_INET: + ap = &sa->s_un.s_in.sa_addr; + port = sa->s_un.s_in.sa_port; + af = AF_INET; + break; + case NNG_AF_INET6: + ap = &sa->s_un.s_in6.sa_addr; + port = sa->s_un.s_in6.sa_port; + af = AF_INET6; + break; + default: + return (NNG_EINVAL); + } + if (ipstr != NULL) { + if (af == AF_INET6) { + size_t l; + ipstr[0] = '['; + inet_ntop(af, ap, ipstr + 1, INET6_ADDRSTRLEN); + l = strlen(ipstr); + ipstr[l++] = ']'; + ipstr[l++] = '\0'; + } else { + inet_ntop(af, ap, ipstr, INET6_ADDRSTRLEN); + } + } + if (portstr != NULL) { +#ifdef NNG_LITTLE_ENDIAN + port = ((port >> 8) & 0xff) | ((port & 0xff) << 8); +#endif + snprintf(portstr, 6, "%u", port); + } + return (0); +} + #endif // NNG_PLATFORM_POSIX diff --git a/src/platform/windows/win_tcp.c b/src/platform/windows/win_tcp.c index 20f324b3..da661588 100644 --- a/src/platform/windows/win_tcp.c +++ b/src/platform/windows/win_tcp.c @@ -355,7 +355,7 @@ nni_plat_tcp_ep_fini(nni_plat_tcp_ep *ep) } static int -nni_win_tcp_listen(nni_plat_tcp_ep *ep) +nni_win_tcp_listen(nni_plat_tcp_ep *ep, nni_sockaddr *bsa) { int rv; BOOL yes; @@ -392,6 +392,17 @@ nni_win_tcp_listen(nni_plat_tcp_ep *ep) goto fail; } + if (bsa != NULL) { + SOCKADDR_STORAGE bound; + int len = sizeof(bound); + rv = getsockname(s, (SOCKADDR *) &bound, &len); + if (rv != 0) { + rv = nni_win_error(GetLastError()); + goto fail; + } + nni_win_sockaddr2nn(bsa, &bound); + } + if (listen(s, SOMAXCONN) != 0) { rv = nni_win_error(GetLastError()); goto fail; @@ -410,12 +421,12 @@ fail: } int -nni_plat_tcp_ep_listen(nni_plat_tcp_ep *ep) +nni_plat_tcp_ep_listen(nni_plat_tcp_ep *ep, nng_sockaddr *bsa) { int rv; nni_mtx_lock(&ep->acc_ev.mtx); - rv = nni_win_tcp_listen(ep); + rv = nni_win_tcp_listen(ep, bsa); nni_mtx_unlock(&ep->acc_ev.mtx); return (rv); } @@ -643,6 +654,47 @@ nni_plat_tcp_ep_connect(nni_plat_tcp_ep *ep, nni_aio *aio) } int +nni_plat_tcp_ntop(const nni_sockaddr *sa, char *ipstr, char *portstr) +{ + const void *ap; + uint16_t port; + int af; + switch (sa->s_un.s_family) { + case NNG_AF_INET: + ap = &sa->s_un.s_in.sa_addr; + port = sa->s_un.s_in.sa_port; + af = AF_INET; + break; + case NNG_AF_INET6: + ap = &sa->s_un.s_in6.sa_addr; + port = sa->s_un.s_in6.sa_port; + af = AF_INET6; + break; + default: + return (NNG_EINVAL); + } + if (ipstr != NULL) { + if (af == AF_INET6) { + size_t l; + ipstr[0] = '['; + InetNtopA(af, ap, ipstr + 1, INET6_ADDRSTRLEN); + l = strlen(ipstr); + ipstr[l++] = ']'; + ipstr[l++] = '\0'; + } else { + InetNtopA(af, ap, ipstr, INET6_ADDRSTRLEN); + } + } + if (portstr != NULL) { +#ifdef NNG_LITTLE_ENDIAN + port = ((port >> 8) & 0xff) | ((port & 0xff) << 8); +#endif + snprintf(portstr, 6, "%u", port); + } + return (0); +} + +int nni_win_tcp_sysinit(void) { WSADATA data; diff --git a/src/supplemental/http/http_server.c b/src/supplemental/http/http_server.c index 503ab1dd..7feadc96 100644 --- a/src/supplemental/http/http_server.c +++ b/src/supplemental/http/http_server.c @@ -895,7 +895,7 @@ http_server_start(nni_http_server *s) if (rv != 0) { return (rv); } - if ((rv = nni_plat_tcp_ep_listen(s->tep)) != 0) { + if ((rv = nni_plat_tcp_ep_listen(s->tep, NULL)) != 0) { nni_plat_tcp_ep_fini(s->tep); s->tep = NULL; return (rv); diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c index 475a77ff..2a23b88b 100644 --- a/src/transport/tcp/tcp.c +++ b/src/transport/tcp/tcp.c @@ -53,6 +53,8 @@ struct nni_tcp_ep { nni_aio * aio; nni_aio * user_aio; nni_url * url; + nng_sockaddr bsa; // bound addr + int mode; nni_mtx mtx; }; @@ -591,6 +593,7 @@ nni_tcp_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) return (rv); } ep->proto = nni_sock_proto(sock); + ep->mode = mode; *epp = ep; return (0); @@ -615,7 +618,7 @@ nni_tcp_ep_bind(void *arg) int rv; nni_mtx_lock(&ep->mtx); - rv = nni_plat_tcp_ep_listen(ep->tep); + rv = nni_plat_tcp_ep_listen(ep->tep, &ep->bsa); nni_mtx_unlock(&ep->mtx); return (rv); @@ -734,6 +737,22 @@ nni_tcp_ep_setopt_recvmaxsz(void *arg, const void *v, size_t sz) } static int +nni_tcp_ep_getopt_url(void *arg, void *v, size_t *szp) +{ + nni_tcp_ep *ep = arg; + char ustr[128]; + char ipstr[48]; // max for IPv6 addresses including [] + char portstr[6]; // max for 16-bit port + + if (ep->mode == NNI_EP_MODE_DIAL) { + return (nni_getopt_str(ep->url->u_rawurl, v, szp)); + } + nni_plat_tcp_ntop(&ep->bsa, ipstr, portstr); + snprintf(ustr, sizeof(ustr), "tcp://%s:%s", ipstr, portstr); + return (nni_getopt_str(ustr, v, szp)); +} + +static int nni_tcp_ep_getopt_recvmaxsz(void *arg, void *v, size_t *szp) { nni_tcp_ep *ep = arg; @@ -781,6 +800,11 @@ static nni_tran_ep_option nni_tcp_ep_options[] = { .eo_setopt = nni_tcp_ep_setopt_recvmaxsz, }, { + .eo_name = NNG_OPT_URL, + .eo_getopt = nni_tcp_ep_getopt_url, + .eo_setopt = NULL, + }, + { .eo_name = NNG_OPT_LINGER, .eo_getopt = nni_tcp_ep_getopt_linger, .eo_setopt = nni_tcp_ep_setopt_linger, diff --git a/src/transport/tls/tls.c b/src/transport/tls/tls.c index f9de3367..cf849373 100644 --- a/src/transport/tls/tls.c +++ b/src/transport/tls/tls.c @@ -61,7 +61,9 @@ struct nni_tls_ep { nni_aio * user_aio; nni_mtx mtx; nng_tls_config * cfg; + nng_sockaddr bsa; nni_url * url; + int mode; }; static void nni_tls_pipe_send_cb(void *); @@ -597,7 +599,8 @@ nni_tls_ep_init(void **epp, nni_url *url, nni_sock *sock, int mode) return (NNG_ENOMEM); } nni_mtx_init(&ep->mtx); - ep->url = url; + ep->url = url; + ep->mode = mode; if (((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) || ((rv = nni_tls_config_init(&ep->cfg, tlsmode)) != 0) || @@ -638,7 +641,7 @@ nni_tls_ep_bind(void *arg) int rv; nni_mtx_lock(&ep->mtx); - rv = nni_plat_tcp_ep_listen(ep->tep); + rv = nni_plat_tcp_ep_listen(ep->tep, &ep->bsa); nni_mtx_unlock(&ep->mtx); return (rv); @@ -747,6 +750,22 @@ nni_tls_ep_connect(void *arg, nni_aio *aio) } static int +nni_tls_ep_getopt_url(void *arg, void *v, size_t *szp) +{ + nni_tls_ep *ep = arg; + char ustr[128]; + char ipstr[48]; // max for IPv6 addresses including [] + char portstr[6]; // max for 16-bit port + + if (ep->mode == NNI_EP_MODE_DIAL) { + return (nni_getopt_str(ep->url->u_rawurl, v, szp)); + } + nni_plat_tcp_ntop(&ep->bsa, ipstr, portstr); + snprintf(ustr, sizeof(ustr), "tls+tcp://%s:%s", ipstr, portstr); + return (nni_getopt_str(ustr, v, szp)); +} + +static int nni_tls_ep_setopt_recvmaxsz(void *arg, const void *v, size_t sz) { nni_tls_ep *ep = arg; @@ -907,6 +926,11 @@ static nni_tran_ep_option nni_tls_ep_options[] = { .eo_setopt = nni_tls_ep_setopt_linger, }, { + .eo_name = NNG_OPT_URL, + .eo_getopt = nni_tls_ep_getopt_url, + .eo_setopt = NULL, + }, + { .eo_name = NNG_OPT_TLS_CONFIG, .eo_getopt = tls_getopt_config, .eo_setopt = tls_setopt_config, diff --git a/src/transport/zerotier/zerotier.c b/src/transport/zerotier/zerotier.c index f8ed4626..4a846301 100644 --- a/src/transport/zerotier/zerotier.c +++ b/src/transport/zerotier/zerotier.c @@ -230,7 +230,6 @@ struct zt_ep { 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 uint16_t ze_proto; @@ -2557,6 +2556,21 @@ zt_ep_getopt_home(void *arg, void *data, size_t *szp) } static int +zt_ep_getopt_url(void *arg, void *data, size_t *szp) +{ + char ustr[64]; // more than plenty + zt_ep * ep = arg; + uint64_t addr; + + addr = ep->ze_mode == NNI_EP_MODE_DIAL ? ep->ze_raddr : ep->ze_laddr; + snprintf(ustr, sizeof(ustr), "zt://%llx.%llx:%u", + (unsigned long long) addr >> zt_port_shift, + (unsigned long long) ep->ze_nwid, + (unsigned) (addr & zt_port_mask)); + return (nni_getopt_str(ustr, data, szp)); +} + +static int zt_ep_setopt_orbit(void *arg, const void *data, size_t sz) { uint64_t moonid; @@ -2725,6 +2739,11 @@ static nni_tran_ep_option zt_ep_options[] = { .eo_setopt = zt_ep_setopt_recvmaxsz, }, { + .eo_name = NNG_OPT_URL, + .eo_getopt = zt_ep_getopt_url, + .eo_setopt = NULL, + }, + { .eo_name = NNG_OPT_ZT_HOME, .eo_getopt = zt_ep_getopt_home, .eo_setopt = zt_ep_setopt_home, |
