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:
parent
75be45f1e4
commit
36578f463e
1 changed files with 8 additions and 0 deletions
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue