diff options
| author | Garrett D'Amore <garrett@damore.org> | 2020-10-31 18:47:07 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-10-31 23:10:12 -0700 |
| commit | 452ecf5ae83adc9ae77518746f4f81171c42248c (patch) | |
| tree | d81730eef3c19775abf0715831dc18e3f9885d21 /src/platform/posix | |
| parent | 587bc765ee69acfabf3bc8b88a70806c07b61f87 (diff) | |
| download | nng-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.c | 154 | ||||
| -rw-r--r-- | src/platform/posix/posix_tcpdial.c | 6 |
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; |
