diff --git a/bin/tests/system/synthfromdnssec/ns1/named.conf.in b/bin/tests/system/synthfromdnssec/ns1/named.conf.in index 6a5086e4b2..e0ff8da1c5 100644 --- a/bin/tests/system/synthfromdnssec/ns1/named.conf.in +++ b/bin/tests/system/synthfromdnssec/ns1/named.conf.in @@ -62,6 +62,11 @@ zone "minimal" { file "minimal.db.signed"; }; +zone "no-apex-covering" { + type primary; + file "no-apex-covering.db.signed"; +}; + zone "soa-without-dnskey" { type primary; file "soa-without-dnskey.db.signed"; diff --git a/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in b/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in new file mode 100644 index 0000000000..baa525925c --- /dev/null +++ b/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in @@ -0,0 +1,28 @@ +; 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 3600 +@ SOA ns1 hostmaster 1 3600 1200 604800 3600 +@ NS ns1 +ns1 A 10.53.0.1 +; \007 sorts before * so the covering NSEC for the wildcard is not +; the apex NSEC. +\007 HINFO "" "" +nodata TXT nodata +*.wild-a A 1.2.3.4 +*.wild-cname CNAME ns1 +*.wild-1-nsec A 1.2.3.4 +*.wild-2-nsec A 1.2.3.4 +_x.wild-2-nsec TXT a name beween wild-2-nsec and a.wild-2-nsec +*.wild-2-nsec-afterdata A 1.2.3.4 +*.wild-2-nsec-afterdata AAAA 2002::1 +_x.wild-2-nsec-afterdata TXT a name beween wild-2-nsec-afterdata and a.wild-2-nsec-afterdata +dnamed DNAME dnamed. diff --git a/bin/tests/system/synthfromdnssec/ns1/root.db.in b/bin/tests/system/synthfromdnssec/ns1/root.db.in index bade656f67..4b3813edcc 100644 --- a/bin/tests/system/synthfromdnssec/ns1/root.db.in +++ b/bin/tests/system/synthfromdnssec/ns1/root.db.in @@ -16,6 +16,8 @@ ns1 A 10.53.0.1 example NS ns1.example fun NS ns1.example ns1.example A 10.53.0.1 +no-apex-covering NS ns1.no-apex-covering +ns1.no-apex-covering A 10.53.0.1 dnamed NS ns1.dnamed ns1.dnamed A 10.53.0.1 minimal NS ns1.minimal diff --git a/bin/tests/system/synthfromdnssec/ns1/sign.sh b/bin/tests/system/synthfromdnssec/ns1/sign.sh index 7d37d867ab..bdc1cdebd2 100644 --- a/bin/tests/system/synthfromdnssec/ns1/sign.sh +++ b/bin/tests/system/synthfromdnssec/ns1/sign.sh @@ -25,6 +25,17 @@ echo ns1.insecure A 10.53.0.1 >>"$zonefile" $SIGNER -P -o $zone $zonefile >/dev/null +zone=no-apex-covering +infile=no-apex-covering.db.in +zonefile=no-apex-covering.db + +keyname=$($KEYGEN -q -a ${DEFAULT_ALGORITHM} $zone) +cat "$infile" "$keyname.key" >"$zonefile" +echo insecure NS ns1.insecure >>"$zonefile" +echo ns1.insecure A 10.53.0.1 >>"$zonefile" + +$SIGNER -P -o $zone $zonefile >/dev/null + zone=insecure.example infile=example.db.in zonefile=insecure.example.db diff --git a/bin/tests/system/synthfromdnssec/tests.sh b/bin/tests/system/synthfromdnssec/tests.sh index dac6a2cc9e..b2427ec09d 100644 --- a/bin/tests/system/synthfromdnssec/tests.sh +++ b/bin/tests/system/synthfromdnssec/tests.sh @@ -132,6 +132,17 @@ for ns in 2 4 5 6; do if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) + echo_i "prime negative NXDOMAIN response no-apex-covering (synth-from-dnssec ${description};) ($n)" + ret=0 + dig_with_opts a.no-apex-covering. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 + check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1 + check_status NXDOMAIN dig.out.ns${ns}.test$n || ret=1 + check_nosynth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + [ $ns -eq 2 ] && cp dig.out.ns${ns}.test$n no-apex-covering.out + n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + echo_i "prime negative NODATA response (synth-from-dnssec ${description};) ($n)" ret=0 dig_with_opts nodata.example. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 @@ -370,6 +381,24 @@ for ns in 2 4 5 6; do if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) + echo_i "check synthesized NXDOMAIN response no-apex-covering (synth-from-dnssec ${description};) ($n)" + ret=0 + nextpart ns1/named.run >/dev/null + dig_with_opts b.no-apex-covering. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 + check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1 + check_status NXDOMAIN dig.out.ns${ns}.test$n || ret=1 + if [ ${synth} = yes ]; then + check_synth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + nextpart ns1/named.run | grep b.no-apex-covering/A >/dev/null && ret=1 + else + check_nosynth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + nextpart ns1/named.run | grep b.no-apex-covering/A >/dev/null || ret=1 + fi + digcomp no-apex-covering.out dig.out.ns${ns}.test$n || ret=1 + n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + echo_i "check synthesized NODATA response (synth-from-dnssec ${description};) ($n)" ret=0 nextpart ns1/named.run >/dev/null @@ -671,7 +700,7 @@ for ns in 2 4 5 6; do for synthesized in NXDOMAIN no-data wildcard; do case $synthesized in - NXDOMAIN) count=1 ;; + NXDOMAIN) count=2 ;; no-data) count=4 ;; wildcard) count=2 ;; esac @@ -728,7 +757,7 @@ for ns in 2 4 5 6; do for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do case $synthesized in - SynthNXDOMAIN) count=1 ;; + SynthNXDOMAIN) count=2 ;; SynthNODATA) count=4 ;; SynthWILDCARD) count=2 ;; esac @@ -787,7 +816,7 @@ for ns in 2 4 5 6; do for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do case $synthesized in - SynthNXDOMAIN) count=1 ;; + SynthNXDOMAIN) count=2 ;; SynthNODATA) count=4 ;; SynthWILDCARD) count=2 ;; esac diff --git a/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py b/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py index 4a2918e27b..2bb852d844 100644 --- a/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py +++ b/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py @@ -24,6 +24,7 @@ pytestmark = pytest.mark.extra_artifacts( "insecure.wildnodata2nsecafterdata.out", "json.out*", "minimal.nxdomain.out", + "no-apex-covering.out", "nodata.out", "nxdomain.out", "wild.out", @@ -45,6 +46,8 @@ pytestmark = pytest.mark.extra_artifacts( "ns1/insecure.example.db.signed", "ns1/minimal.db", "ns1/minimal.db.signed", + "ns1/no-apex-covering.db", + "ns1/no-apex-covering.db.signed", "ns1/root.db", "ns1/root.db.signed", "ns1/soa-without-dnskey.db", diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index 7e685318b8..eaafdfcf5d 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -1397,7 +1397,13 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name, */ result = dns_qp_lookup(search->qpdb->nsec, name, DNS_DBNAMESPACE_NSEC, NULL, &iter, NULL, (void **)&node, NULL); - if (result != DNS_R_PARTIALMATCH) { + /* + * When DNS_R_PARTIALMATCH or ISC_R_NOTFOUND is returned from + * dns_qp_lookup there is potentially a covering NSEC present + * in the cache so we need to search for it. Otherwise we are + * done here. + */ + if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) { return ISC_R_NOTFOUND; }