Fix wildcard bind to bind both IPv6 and IPv4 on Windows & BSD

We rely on AF_INET6 wildcard bind() binding the AF_INET port, too,
i.e. IPV6_V6ONLY off.  This should be the default according to RFC
3493 section 5.3, but isn't on Windows and BSD.  RFC 4038 recognizes
this fact in section 4.2.

When IPV6_V6ONLY is on, an AF_INET6 wildcard bind only accepts
connections from IPv6 addresses.  Thus, IPv4 doesn't work when
getaddrinfo() returns an AF_INET6 address first (which it should do
when the system has an IPv6 address configured).

Switch off IPV6_V6ONLY explicitly instead of relying on the default.
This makes IPv6 work on systems where IPV6_V6ONLY is on by default,
such as Windows and BSD.

Except for OpenBSD, which does not support switching it off.  To be
addressed in the next commit.
This commit is contained in:
Markus Armbruster 2013-04-07 19:16:09 +02:00
parent 75be45f1e4
commit 36578f463e

View file

@ -81,6 +81,14 @@ tcp_listen(char *host, char *serv, size_t *addrlenp)
if (fd < 0)
continue; /* error, try next one */
#ifdef IPV6_V6ONLY
if (ai->ai_family == AF_INET6) {
int off = 0;
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off));
}
#endif
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (bind(fd, ai->ai_addr, ai->ai_addrlen) == 0)
break; /* success */