aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-05-21 16:49:31 -0700
committerGarrett D'Amore <garrett@damore.org>2018-05-21 21:27:16 -0700
commita3cf238a431e6a454f43a66f3c02a2f17d6dfc61 (patch)
treee66560b9d5422420c4af86b8589324690160fb20 /src/platform/windows
parentd0cf8ce6f43daf6882037dbdcdaa7f2169dd1e6a (diff)
downloadnng-a3cf238a431e6a454f43a66f3c02a2f17d6dfc61.tar.gz
nng-a3cf238a431e6a454f43a66f3c02a2f17d6dfc61.tar.bz2
nng-a3cf238a431e6a454f43a66f3c02a2f17d6dfc61.zip
fixes #471 Linux resolver truncates port number silently
Diffstat (limited to 'src/platform/windows')
-rw-r--r--src/platform/windows/win_resolv.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c
index c0fa1e0a..fb9d6751 100644
--- a/src/platform/windows/win_resolv.c
+++ b/src/platform/windows/win_resolv.c
@@ -10,6 +10,9 @@
#include "core/nng_impl.h"
+#include <ctype.h>
+#include <string.h>
+
#ifdef NNG_PLATFORM_WINDOWS
// Modern Windows has an asynchronous resolver, but there are problems
@@ -33,8 +36,8 @@ struct resolv_item {
int family;
int passive;
const char * name;
- const char * serv;
int proto;
+ uint16_t port;
nni_aio * aio;
nng_sockaddr sa;
};
@@ -112,8 +115,7 @@ resolv_task(resolv_item *item)
hints.ai_protocol = item->proto;
hints.ai_family = item->family;
- rv = getaddrinfo(item->name, item->serv, &hints, &results);
- if (rv != 0) {
+ if ((rv = getaddrinfo(item->name, "80", &hints, &results)) != 0) {
rv = resolv_gai_errno(rv);
goto done;
}
@@ -139,14 +141,14 @@ resolv_task(resolv_item *item)
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_port = item->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 = sin6->sin6_port;
+ sa->s_in6.sa_port = item->port;
memcpy(sa->s_in6.sa_addr, sin6->sin6_addr.s6_addr, 16);
break;
}
@@ -167,6 +169,7 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
resolv_item *item;
int fam;
int rv;
+ int port;
if (nni_aio_begin(aio) != 0) {
return;
@@ -186,17 +189,44 @@ 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;
}
-
+ memset(&item->sa, 0, sizeof(item->sa));
item->passive = passive;
item->name = host;
- item->serv = serv;
item->proto = proto;
item->aio = aio;
item->family = fam;
+ item->port = htons((uint16_t) port);
nni_mtx_lock(&resolv_mtx);
if (resolv_fini) {