diff options
| -rw-r--r-- | src/platform/windows/win_impl.h | 1 | ||||
| -rw-r--r-- | src/platform/windows/win_net.c | 41 | ||||
| -rw-r--r-- | tests/survey.c | 11 | ||||
| -rw-r--r-- | tests/tcp.c | 7 |
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(); |
