From 36578f463ecac00e6a109a7784b0038ab10ad939 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 7 Apr 2013 19:16:09 +0200 Subject: [PATCH] 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. --- src/lib/gen/tcp_listen.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/gen/tcp_listen.c b/src/lib/gen/tcp_listen.c index 41df7ac0d..f2ec86d09 100644 --- a/src/lib/gen/tcp_listen.c +++ b/src/lib/gen/tcp_listen.c @@ -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 */ -- 2.43.0