From 91494039090a62b09c416f844ba6e79ac5bc5b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Kugland?= Date: Sat, 16 May 2026 21:45:04 -0300 Subject: [PATCH 1/2] test: regression test for IPv6 accept() debug log address Verify that --ipv6 mode prints the correct [::1]:PORT in the accept() debug log, not garbage from the uninitialized IPv4 addrin struct. --- devel/run-tests | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/devel/run-tests b/devel/run-tests index 0b4bc08..d23daa0 100755 --- a/devel/run-tests +++ b/devel/run-tests @@ -59,6 +59,38 @@ runtests() { # 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 IPv6 accept() debug log test (regression: was printing garbage IPv4 address)" + ./a.out $DIR --port $PORT --ipv6 --addr ::1 \ + >test.out.ipv6debug 2>>test.out.stderr & + PID=$! + kill -0 $PID || exit 1 + $PYTHON -c " +import socket, sys, time +for _ in range(50): + try: + s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + s.settimeout(2) + s.connect(('::1', $PORT, 0, 0)) + s.send(b'GET / HTTP/1.0\r\nConnection: close\r\n\r\n') + try: s.recv(65536) + except: pass + s.close() + sys.exit(0) + except OSError: + s.close() + time.sleep(0.05) +print('FAIL: could not connect to IPv6 server', file=sys.stderr) +sys.exit(1) + " || { kill $PID; exit 1; } + kill $PID + wait $PID + grep -qF "accepted connection from [::1]:" test.out.ipv6debug || { + echo "FAIL: IPv6 debug accept log should contain [::1]:PORT but got:" + cat test.out.ipv6debug + exit 1 + } + rm -f test.out.ipv6debug + echo "===> run tests against a basic instance (generates darkhttpd.gcda)" ./a.out $DIR --port $PORT --addr $ADDR --log test.out.log \ >>test.out.stdout 2>>test.out.stderr & From 9902c5c36d6a20f0a603a34b5134247283b450d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Kugland?= Date: Wed, 13 May 2026 16:52:11 -0300 Subject: [PATCH 2/2] fix: print correct address in accept() debug log for IPv6 In IPv6 mode, accept() populates addrin6 but the debug printf always read from the uninitialized addrin (IPv4) struct, printing garbage. Gate on inet6 and use get_address_text() with bracketed IPv6 form. --- darkhttpd.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/darkhttpd.c b/darkhttpd.c index bcfb248..36d064f 100644 --- a/darkhttpd.c +++ b/darkhttpd.c @@ -1360,11 +1360,22 @@ static void accept_connection(void) { } LIST_INSERT_HEAD(&connlist, conn, entries); - if (debug) - printf("accepted connection from %s:%u (fd %d)\n", - inet_ntoa(addrin.sin_addr), - ntohs(addrin.sin_port), - conn->socket); + if (debug) { +#ifdef HAVE_INET6 + if (inet6) { + printf("accepted connection from [%s]:%u (fd %d)\n", + get_address_text(&addrin6.sin6_addr), + ntohs(addrin6.sin6_port), + conn->socket); + } else +#endif + { + printf("accepted connection from %s:%u (fd %d)\n", + inet_ntoa(addrin.sin_addr), + ntohs(addrin.sin_port), + conn->socket); + } + } /* Try to read straight away rather than going through another iteration * of the select() loop.