aboutsummaryrefslogtreecommitdiff
path: root/src/platform/posix
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2020-10-31 18:47:07 -0700
committerGarrett D'Amore <garrett@damore.org>2020-10-31 23:10:12 -0700
commit452ecf5ae83adc9ae77518746f4f81171c42248c (patch)
treed81730eef3c19775abf0715831dc18e3f9885d21 /src/platform/posix
parent587bc765ee69acfabf3bc8b88a70806c07b61f87 (diff)
downloadnng-452ecf5ae83adc9ae77518746f4f81171c42248c.tar.gz
nng-452ecf5ae83adc9ae77518746f4f81171c42248c.tar.bz2
nng-452ecf5ae83adc9ae77518746f4f81171c42248c.zip
fixes #1311 reduce wasted use for nni_aio
fixes #1317 IPv6 listener get port is incorrect fixes #1319 Want symbolic service names This is phase 1 of reducing the memory foot-print of aios, and also of pipes. This removes the largest consumer the socket address information, from the aio, which was only used by a few consumers.
Diffstat (limited to 'src/platform/posix')
-rw-r--r--src/platform/posix/posix_resolv_gai.c154
-rw-r--r--src/platform/posix/posix_tcpdial.c6
2 files changed, 68 insertions, 92 deletions
diff --git a/src/platform/posix/posix_resolv_gai.c b/src/platform/posix/posix_resolv_gai.c
index c6732a12..888cc9b7 100644
--- a/src/platform/posix/posix_resolv_gai.c
+++ b/src/platform/posix/posix_resolv_gai.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -40,18 +41,23 @@ static nni_thr resolv_thrs[NNG_RESOLV_CONCURRENCY];
typedef struct resolv_item resolv_item;
struct resolv_item {
- int family;
- int passive;
- char name_buf[256];
- char * name;
- int proto;
- int socktype;
- uint16_t port;
- nni_aio * aio;
- nng_sockaddr sa;
+ int family;
+ bool passive;
+ char * host;
+ char * serv;
+ nni_aio * aio;
+ nng_sockaddr *sa;
};
static void
+resolv_free_item(resolv_item *item)
+{
+ nni_strfree(item->serv);
+ nni_strfree(item->host);
+ NNI_FREE_STRUCT(item);
+}
+
+static void
resolv_cancel(nni_aio *aio, void *arg, int rv)
{
resolv_item *item = arg;
@@ -68,13 +74,14 @@ resolv_cancel(nni_aio *aio, void *arg, int rv)
// so we can just discard everything.
nni_aio_list_remove(aio);
nni_mtx_unlock(&resolv_mtx);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
} else {
// This case indicates the resolver is still processing our
// node. We can discard our interest in the result, but we
// can't interrupt the resolver itself. (Too bad, name
// resolution is utterly synchronous for now.)
item->aio = NULL;
+ item->sa = NULL;
nni_mtx_unlock(&resolv_mtx);
}
nni_aio_finish_error(aio, rv);
@@ -135,20 +142,36 @@ resolv_task(resolv_item *item)
// host part are split.
memset(&hints, 0, sizeof(hints));
#ifdef AI_ADDRCONFIG
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
-#else
- hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_flags = AI_ADDRCONFIG;
#endif
if (item->passive) {
hints.ai_flags |= AI_PASSIVE;
}
- hints.ai_protocol = item->proto;
hints.ai_family = item->family;
- hints.ai_socktype = item->socktype;
+ hints.ai_socktype = SOCK_STREAM;
+
+ // Check to see if this is a numeric port number, and if it is
+ // make sure that it's in the valid range (because Windows may
+ // incorrectly simple do a conversion and mask off upper bits.
+ if (item->serv != NULL) {
+ long port;
+ char *end;
+ port = strtol(item->serv, &end, 10);
+ if (*end == '\0') { // we fully converted it as a number...
+ hints.ai_flags |= AI_NUMERICSERV;
+
+ // Not a valid port number. Fail.
+ if ((port < 0) || (port > 0xffff)) {
+ rv = NNG_EADDRINVAL;
+ goto done;
+ }
+ }
+ }
// We can pass any non-zero service number, but we have to pass
// *something*, in case we are using a NULL hostname.
- if ((rv = getaddrinfo(item->name, "80", &hints, &results)) != 0) {
+ if ((rv = getaddrinfo(item->host, item->serv, &hints, &results)) !=
+ 0) {
rv = posix_gai_errno(rv);
goto done;
}
@@ -164,29 +187,31 @@ resolv_task(resolv_item *item)
}
}
- if (probe != NULL) {
+ nni_mtx_lock(&resolv_mtx);
+ if ((probe != NULL) && (item->aio != NULL)) {
struct sockaddr_in * sin;
struct sockaddr_in6 *sin6;
- nng_sockaddr * sa = &item->sa;
+ nng_sockaddr * sa = item->sa;
switch (probe->ai_addr->sa_family) {
case AF_INET:
rv = 0;
sin = (void *) probe->ai_addr;
sa->s_in.sa_family = NNG_AF_INET;
- sa->s_in.sa_port = item->port;
+ sa->s_in.sa_port = sin->sin_port;
sa->s_in.sa_addr = sin->sin_addr.s_addr;
break;
case AF_INET6:
rv = 0;
sin6 = (void *) probe->ai_addr;
sa->s_in6.sa_family = NNG_AF_INET6;
- sa->s_in6.sa_port = item->port;
+ sa->s_in6.sa_port = sin6->sin6_port;
sa->s_in6.sa_scope = sin6->sin6_scope_id;
memcpy(sa->s_in6.sa_addr, sin6->sin6_addr.s6_addr, 16);
break;
}
}
+ nni_mtx_unlock(&resolv_mtx);
done:
@@ -197,19 +222,18 @@ done:
return (rv);
}
-static void
-resolv_ip(const char *host, const char *serv, int passive, int family,
- int proto, int socktype, nni_aio *aio)
+void
+nni_resolv_ip(const char *host, const char *serv, int af, bool passive,
+ nng_sockaddr *sa, nni_aio *aio)
{
resolv_item *item;
sa_family_t fam;
int rv;
- int port;
if (nni_aio_begin(aio) != 0) {
return;
}
- switch (family) {
+ switch (af) {
case NNG_AF_INET:
fam = AF_INET;
break;
@@ -224,62 +248,30 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
return;
}
- // We can't use the resolver to look up up ports with AI_NUMERICSERV,
- // because some resolver(s) is(are?) broken. For example, the
- // systemd resolver takes a port number of 1000000 and just rips off
- // the high order bits and lets it through!
- port = 0;
- if (serv != NULL) {
- while (isdigit(*serv)) {
- port *= 10;
- port += (*serv - '0');
- if (port > 0xffff) {
- // Port number out of range.
- nni_aio_finish_error(aio, NNG_EADDRINVAL);
- return;
- }
- serv++;
- }
- if (*serv != '\0') {
- nni_aio_finish_error(aio, NNG_EADDRINVAL);
- return;
- }
- }
- if ((port == 0) && (!passive)) {
- nni_aio_finish_error(aio, NNG_EADDRINVAL);
- return;
- }
-
if ((item = NNI_ALLOC_STRUCT(item)) == NULL) {
nni_aio_finish_error(aio, NNG_ENOMEM);
return;
}
- // NB: must remain valid until this is completed. So we have to
- // keep our own copy.
-
- if (host != NULL &&
- nni_strnlen(host, sizeof(item->name_buf)) >=
- sizeof(item->name_buf)) {
- NNI_FREE_STRUCT(item);
- nni_aio_finish_error(aio, NNG_EADDRINVAL);
+ if (serv == NULL) {
+ item->serv = NULL;
+ } else if ((item->serv = nni_strdup(serv)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ resolv_free_item(item);
return;
}
-
if (host == NULL) {
- item->name = NULL;
- } else {
- nni_strlcpy(item->name_buf, host, sizeof(item->name_buf));
- item->name = item->name_buf;
+ item->host = NULL;
+ } else if ((item->host = nni_strdup(host)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ resolv_free_item(item);
+ return;
}
- memset(&item->sa, 0, sizeof(item->sa));
- item->proto = proto;
- item->aio = aio;
- item->family = fam;
- item->passive = passive;
- item->socktype = socktype;
- item->port = htons((uint16_t) port);
+ item->aio = aio;
+ item->family = fam;
+ item->passive = passive;
+ item->sa = sa;
nni_mtx_lock(&resolv_mtx);
if (resolv_fini) {
@@ -290,7 +282,7 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
}
if (rv != 0) {
nni_mtx_unlock(&resolv_mtx);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
nni_aio_finish_error(aio, rv);
return;
}
@@ -300,20 +292,6 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
}
void
-nni_tcp_resolv(
- const char *host, const char *serv, int family, int passive, nni_aio *aio)
-{
- resolv_ip(host, serv, passive, family, IPPROTO_TCP, SOCK_STREAM, aio);
-}
-
-void
-nni_udp_resolv(
- const char *host, const char *serv, int family, int passive, nni_aio *aio)
-{
- resolv_ip(host, serv, passive, family, IPPROTO_UDP, SOCK_DGRAM, aio);
-}
-
-void
resolv_worker(void *unused)
{
@@ -348,11 +326,11 @@ resolv_worker(void *unused)
nni_aio_set_prov_extra(aio, 0, NULL);
item->aio = NULL;
+ item->sa = NULL;
- nni_aio_set_sockaddr(aio, &item->sa);
nni_aio_finish(aio, rv, 0);
}
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
}
nni_mtx_unlock(&resolv_mtx);
}
diff --git a/src/platform/posix/posix_tcpdial.c b/src/platform/posix/posix_tcpdial.c
index 3fabc28a..9b3a91f5 100644
--- a/src/platform/posix/posix_tcpdial.c
+++ b/src/platform/posix/posix_tcpdial.c
@@ -169,7 +169,7 @@ tcp_dialer_cb(nni_posix_pfd *pfd, unsigned ev, void *arg)
// We don't give local address binding support. Outbound dialers always
// get an ephemeral port.
void
-nni_tcp_dial(nni_tcp_dialer *d, nni_aio *aio)
+nni_tcp_dial(nni_tcp_dialer *d, const nni_sockaddr *sa, nni_aio *aio)
{
nni_tcp_conn * c;
nni_posix_pfd * pfd = NULL;
@@ -179,14 +179,12 @@ nni_tcp_dial(nni_tcp_dialer *d, nni_aio *aio)
int rv;
int ka;
int nd;
- nng_sockaddr sa;
if (nni_aio_begin(aio) != 0) {
return;
}
- nni_aio_get_sockaddr(aio, &sa);
- if (((sslen = nni_posix_nn2sockaddr(&ss, &sa)) == 0) ||
+ if (((sslen = nni_posix_nn2sockaddr(&ss, sa)) == 0) ||
((ss.ss_family != AF_INET) && (ss.ss_family != AF_INET6))) {
nni_aio_finish_error(aio, NNG_EADDRINVAL);
return;