From 70ce3136bd533b2c3caa8e2f81dd631c85e2eab9 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 5 Jun 2025 11:41:17 -0700 Subject: [PATCH 1/2] Use ipv6 queries in delv +ns `delv +ns` invokes the same code to perform name resolution as `named`, but it neglected to set up an IPv6 dispatch object first. Consequently, it was behaving more like `named -4`. It now sets up dispatch objects for both address families, and performs resolver queries to both v4 and v6 addresses, except when one of the address families has been suppressed by using `delv -4` or `delv -6`. --- bin/delv/delv.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/bin/delv/delv.c b/bin/delv/delv.c index d8c7966c33..262f83cdb2 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -101,7 +101,8 @@ static isc_mem_t *mctx = NULL; static dns_view_t *view = NULL; static ns_server_t *sctx = NULL; static ns_interface_t *ifp = NULL; -static dns_dispatch_t *dispatch = NULL; +static dns_dispatch_t *dispatch4 = NULL; +static dns_dispatch_t *dispatch6 = NULL; static dns_db_t *roothints = NULL; static isc_stats_t *resstats = NULL; static dns_stats_t *resquerystats = NULL; @@ -1927,8 +1928,11 @@ shutdown_server(void) { ns_interfacemgr_shutdown(interfacemgr); ns_interfacemgr_detach(&interfacemgr); } - if (dispatch != NULL) { - dns_dispatch_detach(&dispatch); + if (dispatch4 != NULL) { + dns_dispatch_detach(&dispatch4); + } + if (dispatch6 != NULL) { + dns_dispatch_detach(&dispatch6); } if (dispatchmgr != NULL) { dns_dispatchmgr_detach(&dispatchmgr); @@ -2128,7 +2132,7 @@ static void run_server(void *arg) { isc_result_t result; dns_cache_t *cache = NULL; - isc_sockaddr_t addr, any; + isc_sockaddr_t addr, any, any6; struct in_addr in; UNUSED(arg); @@ -2139,8 +2143,19 @@ run_server(void *arg) { ns_server_create(mctx, matchview, &sctx); CHECK(dns_dispatchmgr_create(mctx, loopmgr, netmgr, &dispatchmgr)); - isc_sockaddr_any(&any); - CHECK(dns_dispatch_createudp(dispatchmgr, &any, &dispatch)); + + if (use_ipv4) { + isc_sockaddr_any(&any); + isc_sockaddr_t *a = (srcaddr4 == NULL) ? &any : srcaddr4; + CHECK(dns_dispatch_createudp(dispatchmgr, a, &dispatch4)); + } + + if (use_ipv6) { + isc_sockaddr_any6(&any6); + isc_sockaddr_t *a = (srcaddr6 == NULL) ? &any6 : srcaddr6; + CHECK(dns_dispatch_createudp(dispatchmgr, a, &dispatch6)); + } + CHECK(ns_interfacemgr_create(mctx, sctx, loopmgr, netmgr, dispatchmgr, NULL, &interfacemgr)); @@ -2164,7 +2179,7 @@ run_server(void *arg) { CHECK(setup_dnsseckeys(NULL, view)); CHECK(dns_view_createresolver(view, netmgr, 0, tlsctx_client_cache, - dispatch, NULL)); + dispatch4, dispatch6)); dns_resolver_setmaxqueries(view->resolver, maxqueries); isc_stats_create(mctx, &resstats, dns_resstatscounter_max); From d29f1d171050580fde7e1ff3bc70f4c8157a4c1f Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 5 Jun 2025 14:10:21 -0700 Subject: [PATCH 2/2] add tests for 'delv +ns -4' and '-6' check that `delv +ns` sends iterative queries over both address families when -4 and -6 are not used, and suppresses queries appropriately when they are. --- bin/tests/system/digdelv/root.hint | 15 ++++++++++++ bin/tests/system/digdelv/tests.sh | 39 ++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 bin/tests/system/digdelv/root.hint diff --git a/bin/tests/system/digdelv/root.hint b/bin/tests/system/digdelv/root.hint new file mode 100644 index 0000000000..26bb7a6f7c --- /dev/null +++ b/bin/tests/system/digdelv/root.hint @@ -0,0 +1,15 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 999999 +. IN NS a.root-servers.nil. +a.root-servers.nil. IN A 10.53.0.1 +a.root-servers.nil. AAAA fd92:7065:b8e:ffff::1 diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh index 4807826fff..591c0a3d54 100644 --- a/bin/tests/system/digdelv/tests.sh +++ b/bin/tests/system/digdelv/tests.sh @@ -1766,7 +1766,7 @@ if [ -x "$DELV" ]; then n=$((n + 1)) echo_i "check NS output from delv +ns ($n)" ret=0 - delv_with_opts -i +ns +nortrace +nostrace +nomtrace +novtrace +hint=../_common/root.hint ns example >delv.out.test$n || ret=1 + delv_with_opts -i +ns +nortrace +nostrace +nomtrace +novtrace +hint=root.hint ns example >delv.out.test$n || ret=1 lines=$(awk '$1 == "example." && $4 == "NS" {print}' delv.out.test$n | wc -l) [ $lines -eq 2 ] || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi @@ -1775,7 +1775,7 @@ if [ -x "$DELV" ]; then n=$((n + 1)) echo_i "checking delv +ns (no validation) ($n)" ret=0 - delv_with_opts -i +ns +hint=../_common/root.hint a a.example >delv.out.test$n || ret=1 + delv_with_opts -i +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 grep -q '; authoritative' delv.out.test$n || ret=1 grep -q '_.example' delv.out.test$n && ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi @@ -1784,7 +1784,7 @@ if [ -x "$DELV" ]; then n=$((n + 1)) echo_i "checking delv +ns +qmin (no validation) ($n)" ret=0 - delv_with_opts -i +ns +qmin +hint=../_common/root.hint a a.example >delv.out.test$n || ret=1 + delv_with_opts -i +ns +qmin +hint=root.hint a a.example >delv.out.test$n || ret=1 grep -q '; authoritative' delv.out.test$n || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) @@ -1792,7 +1792,7 @@ if [ -x "$DELV" ]; then n=$((n + 1)) echo_i "checking delv +ns (with validation) ($n)" ret=0 - delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=../_common/root.hint a a.example >delv.out.test$n || ret=1 + delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 grep -q '; fully validated' delv.out.test$n || ret=1 grep -q '_.example' delv.out.test$n && ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi @@ -1801,11 +1801,40 @@ if [ -x "$DELV" ]; then n=$((n + 1)) echo_i "checking delv +ns +qmin (with validation) ($n)" ret=0 - delv_with_opts -a ns1/anchor.dnskey +root +ns +qmin +hint=../_common/root.hint a a.example >delv.out.test$n || ret=1 + delv_with_opts -a ns1/anchor.dnskey +root +ns +qmin +hint=root.hint a a.example >delv.out.test$n || ret=1 grep -q '; fully validated' delv.out.test$n || ret=1 if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) + if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then + n=$((n + 1)) + echo_i "checking delv +ns uses both address families ($n)" + ret=0 + delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 + grep -qF 'sending packet from 10.53' delv.out.test$n >/dev/null || ret=1 + grep -qF 'sending packet from fd92:7065' delv.out.test$n >/dev/null || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + + n=$((n + 1)) + echo_i "checking delv -4 +ns uses only IPv4 ($n)" + ret=0 + delv_with_opts -a ns1/anchor.dnskey +root -4 +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 + grep -qF 'sending packet from 10.53' delv.out.test$n >/dev/null || ret=1 + grep -qF 'sending packet from fd92:7065' delv.out.test$n >/dev/null && ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + + n=$((n + 1)) + echo_i "checking delv -6 +ns uses only IPv6 ($n)" + ret=0 + delv_with_opts -a ns1/anchor.dnskey +root -6 +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 + grep -qF 'sending packet from 10.53' delv.out.test$n >/dev/null && ret=1 + grep -qF 'sending packet from fd92:7065' delv.out.test$n >/dev/null || ret=1 + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + fi + else echo_i "$DELV is needed, so skipping these delv tests" fi