aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/listen.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/src/listen.c b/src/listen.c
index c40035279..70f2e962c 100644
--- a/src/listen.c
+++ b/src/listen.c
@@ -192,39 +192,30 @@ static void parseListenConfigParam(unsigned int port, ConfigParam * param)
#endif /* HAVE_UN */
} else {
#ifdef HAVE_TCP
- struct hostent *he;
+ struct addrinfo hints, *ai, *i;
+ char service[20];
+ int ret;
+
DEBUG("binding to address for %s\n", param->value);
- if (!(he = gethostbyname(param->value))) {
- 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)
- 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 */
FATAL("TCP support is disabled\n");
#endif /* HAVE_TCP */