aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/platform/windows/win_impl.h1
-rw-r--r--src/platform/windows/win_net.c41
-rw-r--r--tests/survey.c11
-rw-r--r--tests/tcp.c7
4 files changed, 40 insertions, 20 deletions
diff --git a/src/platform/windows/win_impl.h b/src/platform/windows/win_impl.h
index c6a68142..e63553a5 100644
--- a/src/platform/windows/win_impl.h
+++ b/src/platform/windows/win_impl.h
@@ -32,6 +32,7 @@ struct nni_plat_tcpsock {
WSAOVERLAPPED recv_olpd;
WSAOVERLAPPED send_olpd;
WSAOVERLAPPED conn_olpd; // Use for both connect and accept
+ int family;
// We have to lookup some function pointers using ioctls. Winsock,
// gotta love it.
diff --git a/src/platform/windows/win_net.c b/src/platform/windows/win_net.c
index bc237d0f..cd5862ff 100644
--- a/src/platform/windows/win_net.c
+++ b/src/platform/windows/win_net.c
@@ -120,7 +120,7 @@ nni_plat_to_sockaddr(SOCKADDR_STORAGE *ss, const nni_sockaddr *sa)
case NNG_AF_INET6:
sin6 = (void *) ss;
- memset(&sin6, 0, sizeof (sin6));
+ memset(sin6, 0, sizeof (*sin6));
sin6->sin6_family = PF_INET6;
sin6->sin6_port = sa->s_un.s_in6.sa_port;
memcpy(sin6->sin6_addr.s6_addr, sa->s_un.s_in6.sa_addr, 16);
@@ -162,19 +162,31 @@ nni_plat_lookup_host(const char *host, nni_sockaddr *addr, int flags)
ADDRINFO hint;
ADDRINFO *ai;
- memset(&hint, 0, sizeof (hint));
- hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG | AI_NUMERICSERV;
- hint.ai_family = PF_UNSPEC;
+ ZeroMemory(&hint, sizeof (hint));
+ hint.ai_flags = AI_PASSIVE | AI_ALL;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
+
+ // XXX: For some reason, using IPv6 (AF_INET6) leads to surprising
+ // results, particularly for the AI_PASSIVE NULL host, where the
+ // documented behavior is that a single zeroed address works. That
+ // does not seem to be what we get back, and attempts to bind to that
+ // specifically also seem to fail. Investigation is called for.
+ // For now we juse use AF_INET if HOST == NULL.
if (flags & NNI_FLAG_IPV4ONLY) {
- hint.ai_family = PF_INET;
+ hint.ai_family = AF_INET;
+ } else {
+ hint.ai_family = AF_UNSPEC;
+ }
+ if (host == NULL) {
+ // See above about why we had to do this terrible thing.
+ // We need to remove this before 1.0.
+ hint.ai_family = AF_INET;
}
if (getaddrinfo(host, "1", &hint, &ai) != 0) {
return (NNG_EADDRINVAL);
}
-
if (nni_plat_from_sockaddr(addr, ai->ai_addr) < 0) {
freeaddrinfo(ai);
return (NNG_EADDRINVAL);
@@ -300,10 +312,15 @@ static void
nni_plat_tcp_setopts(SOCKET fd)
{
BOOL yes;
+ DWORD no;
// Don't inherit the handle (CLOEXEC really).
SetHandleInformation((HANDLE) fd, HANDLE_FLAG_INHERIT, 0);
+ no = 0;
+ (void) setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &no,
+ sizeof (no));
+
// Also disable Nagle. We are careful to group data with WSASend,
// and latency is king for most of our users. (Consider adding
// a method to enable this later.)
@@ -343,14 +360,14 @@ nni_plat_tcp_init(nni_plat_tcpsock *s)
static int
-nni_plat_tcp_open(nni_plat_tcpsock *s)
+nni_plat_tcp_open(nni_plat_tcpsock *s, int fam)
{
int rv;
DWORD nbytes;
GUID guid1 = WSAID_CONNECTEX;
GUID guid2 = WSAID_ACCEPTEX;
- s->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ s->s = socket(fam, SOCK_STREAM, IPPROTO_TCP);
if (s->s == INVALID_SOCKET) {
rv = WSAGetLastError();
return (nni_winsock_error(rv));
@@ -368,6 +385,7 @@ nni_plat_tcp_open(nni_plat_tcpsock *s)
}
nni_plat_tcp_setopts(s->s);
+ s->family = fam;
return (0);
}
@@ -433,7 +451,7 @@ nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr)
return (NNG_EADDRINVAL);
}
- if ((rv = nni_plat_tcp_open(s)) != 0) {
+ if ((rv = nni_plat_tcp_open(s, ss.ss_family)) != 0) {
return (rv);
}
@@ -452,6 +470,7 @@ nni_plat_tcp_listen(nni_plat_tcpsock *s, const nni_sockaddr *addr)
return (nni_winsock_error(rv));
}
+
// Listen -- 128 depth is probably sufficient. If it isn't, other
// bad things are going to happen.
if (listen(s->s, 128) != 0) {
@@ -496,7 +515,7 @@ nni_plat_tcp_connect(nni_plat_tcpsock *s, const nni_sockaddr *addr,
bss.ss_family = ss.ss_family;
}
- if ((rv = nni_plat_tcp_open(s)) != 0) {
+ if ((rv = nni_plat_tcp_open(s, ss.ss_family)) != 0) {
return (rv);
}
@@ -533,7 +552,7 @@ nni_plat_tcp_accept(nni_plat_tcpsock *s, nni_plat_tcpsock *server)
char ainfo[512];
int rv;
- if ((rv = nni_plat_tcp_open(s)) != 0) {
+ if ((rv = nni_plat_tcp_open(s, server->family)) != 0) {
return (rv);
}
diff --git a/tests/survey.c b/tests/survey.c
index 7a5929ba..a749b0b1 100644
--- a/tests/survey.c
+++ b/tests/survey.c
@@ -18,7 +18,6 @@
So(memcmp(nng_msg_body(m), s, strlen(s)) == 0)
Main({
- int rv;
const char *addr = "inproc://test";
nni_init();
@@ -47,7 +46,6 @@ Main({
Convey("Survey without responder times out", {
uint64_t expire = 50000;
nng_msg *msg;
- int rv;
So(nng_setopt(surv, NNG_OPT_SURVEYTIME, &expire, sizeof (expire)) == 0);
So(nng_msg_alloc(&msg, 0) == 0);
@@ -84,10 +82,10 @@ Main({
nng_socket *sock;
uint64_t expire;
- So((rv = nng_open(&surv, NNG_PROTO_SURVEYOR)) == 0);
+ So(nng_open(&surv, NNG_PROTO_SURVEYOR) == 0);
So(surv != NULL);
- So((rv = nng_open(&resp, NNG_PROTO_RESPONDENT)) == 0);
+ So(nng_open(&resp, NNG_PROTO_RESPONDENT) == 0);
So(resp != NULL);
@@ -106,7 +104,7 @@ Main({
// earlier dial to have completed *fully*. This is a
// hack that only works because our listen logic is
// single threaded.
- So((rv = nng_open(&sock, NNG_PROTO_RESPONDENT)) == 0);
+ So(nng_open(&sock, NNG_PROTO_RESPONDENT) == 0);
So(nng_dial(sock, addr, NULL, NNG_FLAG_SYNCH) == 0);
nng_close(sock);
@@ -133,8 +131,7 @@ Main({
Convey("And goes to non-survey state", {
rtimeo = 200000;
So(nng_setopt(surv, NNG_OPT_RCVTIMEO, &rtimeo, sizeof (rtimeo)) == 0);
- rv = nng_recvmsg(surv, &msg, 0);
- So(rv== NNG_ESTATE);
+ So(nng_recvmsg(surv, &msg, 0) == NNG_ESTATE);
})
})
})
diff --git a/tests/tcp.c b/tests/tcp.c
index ea97454e..4cc9070e 100644
--- a/tests/tcp.c
+++ b/tests/tcp.c
@@ -14,6 +14,8 @@
// Inproc tests.
TestMain("TCP Transport", {
+ int rv;
+
nni_init();
trantest_test_all("tcp://127.0.0.1:4450");
@@ -37,8 +39,9 @@ TestMain("TCP Transport", {
nng_close(s2);
nng_close(s1);
})
- So(nng_listen(s1, "tcp://*:5599", NULL, NNG_FLAG_SYNCH) == 0);
- So(nng_dial(s2, "tcp://127.0.0.1:5599", NULL, NNG_FLAG_SYNCH) == 0);
+ So(nng_listen(s1, "tcp://*:5771", NULL, NNG_FLAG_SYNCH) == 0);
+ So(nng_dial(s2, "tcp://127.0.0.1:5771", NULL, NNG_FLAG_SYNCH) == 0);
+ fflush(stdout);
})
nni_fini();