diff --git a/darkhttpd.c b/darkhttpd.c index 4a22ae2..cd16708 100644 --- a/darkhttpd.c +++ b/darkhttpd.c @@ -794,7 +794,7 @@ static const char *get_address_text(const void *addr) { } } -/* Initialize the sockin global. This is the socket that we accept +/* Initialize the sockin global. This is the socket that we accept * connections from. */ static void init_sockin(void) { @@ -809,7 +809,7 @@ static void init_sockin(void) { if (inet6) { memset(&addrin6, 0, sizeof(addrin6)); if (inet_pton(AF_INET6, bindaddr ? bindaddr : "::", - &addrin6.sin6_addr) == -1) { + &addrin6.sin6_addr) != 1) { errx(1, "malformed --addr argument"); } sockin = socket(PF_INET6, SOCK_STREAM, 0); @@ -838,6 +838,18 @@ static void init_sockin(void) { &sockopt, sizeof(sockopt)) == -1) err(1, "setsockopt(TCP_NODELAY)"); +#ifdef HAVE_INET6 + if (inet6) { + /* Listen on IPv4 and IPv6 on the same socket. */ + /* Only relevant if listening on ::, but behaves normally if */ + /* listening on a specific address. */ + sockopt = 0; + if (setsockopt(sockin, IPPROTO_IPV6, IPV6_V6ONLY, + &sockopt, sizeof (sockopt)) < 0) + err(1, "setsockopt (IPV6_V6ONLY)"); + } +#endif + #ifdef TORTURE /* torture: cripple the kernel-side send buffer so we can only squeeze out * one byte at a time (this is for debugging) diff --git a/devel/run-tests b/devel/run-tests index 5cc6e40..412c549 100755 --- a/devel/run-tests +++ b/devel/run-tests @@ -44,6 +44,20 @@ runtests() { # Early exit if we can't even survive usage. ./a.out >/dev/null 2>>test.out.stderr || exit 1 + echo "===> run test for binding to bogus address (IPv4)" + # Should exit immediately. + # Error is "Can't assign requested adddress" on FreeBSD and "Cannot assign requested address" on Linux. + ./a.out $DIR --port $PORT --addr 8.8.8.8 2>&1 | grep -F "t assign requested address" > /dev/null || exit 1 + + echo "===> run test for binding to bogus address (IPv6)" + # Should exit immediately. + # Error is "Can't assign requested adddress" on FreeBSD and "Cannot assign requested address" on Linux. + ./a.out $DIR --port $PORT --ipv6 --addr ::8888 2>&1 | grep -F "t assign requested address" > /dev/null || exit 1 + + echo "===> run test for binding to IPv4 when IPv6 requested" + # Should exit immediately. + ./a.out $DIR --port $PORT --ipv6 --addr 127.0.0.1 2>&1 | grep -F "malformed --addr argument" > /dev/null || exit 1 + echo "===> run tests against a basic instance (generates darkhttpd.gcda)" ./a.out $DIR --port $PORT --log test.out.log \ >>test.out.stdout 2>>test.out.stderr &