aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-15 07:20:53 +0200
committerMax Kellermann <max@duempel.org>2008-10-15 07:20:53 +0200
commitba594cfec0408c9103ca12f004c69eeba32f700a (patch)
tree3c31ae0d7b3cc793479727228650ddc5ea9b5a21
parenta3e3d2c9506d17b3e19e205535ec263ee75178c9 (diff)
downloadmpd-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 '')
-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 */