From ba594cfec0408c9103ca12f004c69eeba32f700a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 15 Oct 2008 07:20:53 +0200 Subject: 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(). --- src/listen.c | 53 ++++++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) (limited to 'src/listen.c') 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 */ -- cgit v1.2.3