Skip to content

Commit

Permalink
Listen to IPv4 and IPv6 at the same time when --ipv6 is passed
Browse files Browse the repository at this point in the history
This could have already been the default behavior on your OS, but
now it will be consistently utilized. Prior to this, to support IPv4
and IPv6 you would have to run two servers or set the relevant sysctl.

Also fixes incorrect inet_pton() usage.

Closes: #37
  • Loading branch information
hhartzer committed Feb 28, 2024
1 parent b6c1b0c commit 7d35683
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
16 changes: 14 additions & 2 deletions darkhttpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 14 additions & 0 deletions devel/run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -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 &
Expand Down

0 comments on commit 7d35683

Please sign in to comment.