diff options
author | Max Kellermann <max@duempel.org> | 2008-10-15 07:20:53 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2008-10-15 07:20:53 +0200 |
commit | ba594cfec0408c9103ca12f004c69eeba32f700a (patch) | |
tree | 3c31ae0d7b3cc793479727228650ddc5ea9b5a21 | |
parent | a3e3d2c9506d17b3e19e205535ec263ee75178c9 (diff) | |
download | mpd-ba594cfec0408c9103ca12f004c69eeba32f700a.tar.gz mpd-ba594cfec0408c9103ca12f004c69eeba32f700a.tar.xz mpd-ba594cfec0408c9103ca12f004c69eeba32f700a.zip |
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().
-rw-r--r-- | src/listen.c | 53 |
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 */ |