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 /src | |
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().
Diffstat (limited to 'src')
-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 */ |