aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows
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/windows
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/windows')
-rw-r--r--src/platform/windows/win_resolv.c166
-rw-r--r--src/platform/windows/win_tcpdial.c7
2 files changed, 78 insertions, 95 deletions
diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c
index d810ecac..8628719f 100644
--- a/src/platform/windows/win_resolv.c
+++ b/src/platform/windows/win_resolv.c
@@ -11,7 +11,7 @@
#include "core/nng_impl.h"
#include <ctype.h>
-#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#ifdef NNG_PLATFORM_WINDOWS
@@ -34,17 +34,23 @@ static nni_thr resolv_thrs[NNG_RESOLV_CONCURRENCY];
typedef struct resolv_item resolv_item;
struct resolv_item {
- int family;
- int passive;
- 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;
@@ -60,12 +66,12 @@ 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_strfree(item->name);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
} else {
// Resolver still working, so just unlink our AIO to
// discard our interest in the results.
item->aio = NULL;
+ item->sa = NULL;
nni_mtx_unlock(&resolv_mtx);
}
nni_aio_finish_error(aio, rv);
@@ -108,18 +114,34 @@ resolv_task(resolv_item *item)
results = NULL;
- // We treat these all as IP addresses. The service and the
- // host part are split.
memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+ hints.ai_flags = AI_ADDRCONFIG;
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;
+ }
+ }
+ }
- if ((rv = getaddrinfo(item->name, "80", &hints, &results)) != 0) {
+ if ((rv = getaddrinfo(item->host, item->serv, &hints, &results)) !=
+ 0) {
rv = resolv_errno(rv);
goto done;
}
@@ -135,31 +157,33 @@ resolv_task(resolv_item *item)
}
}
+ nni_mtx_lock(&resolv_mtx);
if ((probe != NULL) && (item->aio != NULL)) {
struct sockaddr_in * sin;
struct sockaddr_in6 *sin6;
- nni_sockaddr sa;
+ nni_sockaddr * sa;
+
+ 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_addr = sin->sin_addr.s_addr;
- nni_aio_set_sockaddr(item->aio, &sa);
+ rv = 0;
+ sin = (void *) probe->ai_addr;
+ sa->s_in.sa_family = NNG_AF_INET;
+ 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_scope = sin6->sin6_scope_id;
- memcpy(sa.s_in6.sa_addr, sin6->sin6_addr.s6_addr, 16);
- nni_aio_set_sockaddr(item->aio, &sa);
+ rv = 0;
+ sin6 = (void *) probe->ai_addr;
+ sa->s_in6.sa_family = NNG_AF_INET6;
+ 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:
@@ -169,14 +193,13 @@ 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 family, bool passive,
+ nng_sockaddr *sa, nni_aio *aio)
{
resolv_item *item;
int fam;
int rv;
- int port;
if (nni_aio_begin(aio) != 0) {
return;
@@ -196,52 +219,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 Windows' resolver is broken. For example, the resolver
- // takes a port number of 1000000 and just rips off the high order
- // bits and lets it through! (It seems to time out though, so
- // maybe it is ignoring AI_NUMERICSERV.)
- 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;
}
if (host == NULL) {
- item->name = NULL;
- } else if ((item->name = nni_strdup(host)) == NULL) {
+ item->host = NULL;
+ } else if ((item->host = nni_strdup(host)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ resolv_free_item(item);
+ return;
+ }
+
+ if (serv == NULL) {
+ item->serv = NULL;
+ } else if ((item->serv = nni_strdup(serv)) == NULL) {
nni_aio_finish_error(aio, NNG_ENOMEM);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
return;
}
- memset(&item->sa, 0, sizeof(item->sa));
- item->passive = passive;
- item->proto = proto;
- item->aio = aio;
- item->family = fam;
- item->socktype = socktype;
- item->port = htons((uint16_t) port);
+ item->sa = sa;
+ item->passive = passive;
+ item->aio = aio;
+ item->family = fam;
nni_mtx_lock(&resolv_mtx);
if (resolv_fini) {
@@ -252,8 +253,7 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
}
if (rv != 0) {
nni_mtx_unlock(&resolv_mtx);
- nni_strfree(item->name);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
nni_aio_finish_error(aio, rv);
return;
}
@@ -263,20 +263,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 *notused)
{
@@ -308,11 +294,11 @@ resolv_worker(void *notused)
if ((aio = item->aio) != NULL) {
nni_aio_set_prov_extra(aio, 0, NULL);
item->aio = NULL;
+ item->sa = NULL;
nni_aio_finish(aio, rv, 0);
}
- nni_strfree(item->name);
- NNI_FREE_STRUCT(item);
+ resolv_free_item(item);
}
nni_mtx_unlock(&resolv_mtx);
}
diff --git a/src/platform/windows/win_tcpdial.c b/src/platform/windows/win_tcpdial.c
index 3d470ca1..89c5bf6a 100644
--- a/src/platform/windows/win_tcpdial.c
+++ b/src/platform/windows/win_tcpdial.c
@@ -173,22 +173,19 @@ tcp_dial_cb(nni_win_io *io, int rv, size_t cnt)
}
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)
{
SOCKET s;
SOCKADDR_STORAGE ss;
int len;
nni_tcp_conn * c;
int rv;
- nng_sockaddr sa;
-
- nni_aio_get_sockaddr(aio, &sa);
if (nni_aio_begin(aio) != 0) {
return;
}
- if ((len = nni_win_nn2sockaddr(&ss, &sa)) <= 0) {
+ if ((len = nni_win_nn2sockaddr(&ss, sa)) <= 0) {
nni_aio_finish_error(aio, NNG_EADDRINVAL);
return;
}