listen: use getaddrinfo() instead of gethostbyname()
getaddrinfo() is more robust and has proper IPv6 support. The new code tries to bind to all IP addresses returned by getaddrinfo().
This commit is contained in:
parent
a3e3d2c950
commit
ba594cfec0
55
src/listen.c
55
src/listen.c
@ -192,39 +192,30 @@ static void parseListenConfigParam(unsigned int port, ConfigParam * param)
|
|||||||
#endif /* HAVE_UN */
|
#endif /* HAVE_UN */
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_TCP
|
#ifdef HAVE_TCP
|
||||||
struct hostent *he;
|
struct addrinfo hints, *ai, *i;
|
||||||
DEBUG("binding to address for %s\n", param->value);
|
char service[20];
|
||||||
if (!(he = gethostbyname(param->value))) {
|
int ret;
|
||||||
FATAL("can't lookup host \"%s\" at line %i\n",
|
|
||||||
param->value, param->line);
|
|
||||||
}
|
|
||||||
switch (he->h_addrtype) {
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
case AF_INET6:
|
|
||||||
if (!useIpv6) {
|
|
||||||
FATAL("no IPv6 support, but a IPv6 address "
|
|
||||||
"found for \"%s\" at line %i\n",
|
|
||||||
param->value, param->line);
|
|
||||||
}
|
|
||||||
memcpy((char *)&sin6.sin6_addr.s6_addr,
|
|
||||||
(const char *)he->h_addr, he->h_length);
|
|
||||||
addrp = (const struct sockaddr *)&sin6;
|
|
||||||
addrlen = sizeof(struct sockaddr_in6);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case AF_INET:
|
|
||||||
memcpy((char *)&sin4.sin_addr.s_addr,
|
|
||||||
(const char *)he->h_addr, he->h_length);
|
|
||||||
addrp = (struct sockaddr *)&sin4;
|
|
||||||
addrlen = sizeof(struct sockaddr_in);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FATAL("address type for \"%s\" is not IPv4 or IPv6 "
|
|
||||||
"at line %i\n", param->value, param->line);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (establishListen(addrp, addrlen) < 0)
|
DEBUG("binding to address for %s\n", param->value);
|
||||||
BINDERROR();
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
snprintf(service, sizeof(service), "%u", port);
|
||||||
|
|
||||||
|
ret = getaddrinfo(param->value, service, &hints, &ai);
|
||||||
|
if (ret != 0)
|
||||||
|
FATAL("can't lookup host \"%s\" at line %i: %s\n",
|
||||||
|
param->value, param->line, gai_strerror(ret));
|
||||||
|
|
||||||
|
for (i = ai; i != NULL; i = i->ai_next)
|
||||||
|
if (establishListen(i->ai_addr, i->ai_addrlen) < 0)
|
||||||
|
BINDERROR();
|
||||||
|
|
||||||
|
freeaddrinfo(ai);
|
||||||
#else /* HAVE_TCP */
|
#else /* HAVE_TCP */
|
||||||
FATAL("TCP support is disabled\n");
|
FATAL("TCP support is disabled\n");
|
||||||
#endif /* HAVE_TCP */
|
#endif /* HAVE_TCP */
|
||||||
|
Loading…
Reference in New Issue
Block a user