1
1

Fix a problem with binding to the wildcard address.

On CentOS 6 and MacOS, if no address family was specified, we'd
get back an IPv4 address from getaddrinfo(3), with the result that
we couldn't accept IPv6 connections in the default server configuration.

There was an earlier attempt at fixing this problem that caused
Issue #193.  This change is a follow-up fix to that issue.

While here, put lots of comments around the fix so we remember
why we're doing these shenanigans.
Этот коммит содержится в:
Bruce A. Mah 2014-07-17 17:14:20 -07:00
родитель 5b760eef47
Коммит 76b5942f6f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4984910A8CAAEE8A

Просмотреть файл

@ -107,7 +107,24 @@ netannounce(int domain, int proto, char *local, int port)
snprintf(portstr, 6, "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = domain;
/*
* If binding to the wildcard address with no explicit address
* family specified, then force us to get an AF_INET6 socket. On
* CentOS 6 and MacOS, getaddrinfo(3) with AF_UNSPEC in ai_family,
* and ai_flags containing AI_PASSIVE returns a result structure
* with ai_family set to AF_INET, with the result that we create
* and bind an IPv4 address wildcard address and by default, we
* can't accept IPv6 connections.
*
* On FreeBSD, under the above circumstances, ai_family in the
* result structure is set to AF_INET6.
*/
if (domain == AF_UNSPEC && !local) {
hints.ai_family = AF_INET6;
}
else {
hints.ai_family = domain;
}
hints.ai_socktype = proto;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(local, portstr, &hints, &res) != 0)
@ -126,6 +143,12 @@ netannounce(int domain, int proto, char *local, int port)
freeaddrinfo(res);
return -1;
}
/*
* If we got an IPv6 socket, figure out if it should accept IPv4
* connections as well. We do that if and only if no address
* family was specified explicitly.
*/
if (res->ai_family == AF_INET6 && (domain == AF_UNSPEC || domain == AF_INET6)) {
if (domain == AF_UNSPEC)
opt = 0;