aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/defs.h4
-rw-r--r--src/core/endpt.c11
-rw-r--r--src/core/platform.h8
-rw-r--r--src/platform/posix/posix_aio.h1
-rw-r--r--src/platform/posix/posix_epdesc.c12
-rw-r--r--src/platform/posix/posix_tcp.c51
-rw-r--r--src/platform/windows/win_tcp.c58
-rw-r--r--src/supplemental/http/http_server.c2
-rw-r--r--src/transport/tcp/tcp.c26
-rw-r--r--src/transport/tls/tls.c28
-rw-r--r--src/transport/zerotier/zerotier.c21
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,