]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix to not count cached NXDOMAIN for MAX_TARGET_NX.
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 29 Jun 2022 15:26:09 +0000 (17:26 +0200)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Wed, 29 Jun 2022 15:26:09 +0000 (17:26 +0200)
doc/Changelog
iterator/iterator.c
testdata/iter_nxns_cached.rpl [new file with mode: 0644]

index 60909ddedfb9ca78500a18e0d196ce1ee4a5cdbe..4695802e9c8c0cb7c3e5475b5016dedc43529402 100644 (file)
@@ -6,6 +6,7 @@
        - Fix #704: [FR] Statistics counter for number of outgoing UDP queries
          sent; introduces 'num.query.udpout' to the 'unbound-control stats'
          command.
+       - Fix to not count cached NXDOMAIN for MAX_TARGET_NX.
 
 28 June 2022: George
        - Show the output of the exact .rpl run that failed with 'make test'.
index 3cfb286f44914a0f1bf10b08e2b3107b8c53dd8c..2e64c3945201fc4913c64ed7ab7e9b18001f5dbd 100644 (file)
@@ -3383,8 +3383,11 @@ processTargetResponse(struct module_qstate* qstate, int id,
                delegpt_mark_neg(dpns, qstate->qinfo.qtype);
                dpns->resolved = 1; /* fail the target */
                if((dpns->got4 == 2 || !ie->supports_ipv4) &&
-                       (dpns->got6 == 2 || !ie->supports_ipv6))
+                       (dpns->got6 == 2 || !ie->supports_ipv6) &&
+                       /* do not count cached answers */
+                       (qstate->reply_origin && qstate->reply_origin->len != 0)) {
                        target_count_increase_nx(foriq, 1);
+               }
        }
 }
 
diff --git a/testdata/iter_nxns_cached.rpl b/testdata/iter_nxns_cached.rpl
new file mode 100644 (file)
index 0000000..7671df6
--- /dev/null
@@ -0,0 +1,384 @@
+; Check that cached NXDOMAIN replies for nameservers do not count towards the
+; MAX_TARGET_NX limit.
+
+server:
+       module-config: "iterator"
+       trust-anchor-signaling: no
+       target-fetch-policy: "0 0 0 0 0"
+       verbosity: 3
+       access-control: 127.0.0.1 allow_snoop
+       do-not-query-localhost: no
+       qname-minimisation: no
+       minimal-responses: no
+       rrset-roundrobin: no
+stub-zone:
+       name: "example.com"
+       stub-addr: 127.0.0.2
+stub-zone:
+       name: "nameservers.com"
+       stub-addr: 127.0.0.3
+CONFIG_END
+
+SCENARIO_BEGIN Test that the NXNS countermeasure is not triggered for cached NXDOMAIN
+
+RANGE_BEGIN 0 100
+       ADDRESS 127.0.0.1
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       b.a.example.com. IN A
+               SECTION ANSWER
+                       b.a.example.com. IN A 127.0.0.0
+       ENTRY_END
+RANGE_END
+
+RANGE_BEGIN 31 100
+       ADDRESS 127.0.0.3
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns1.nameservers.com. IN A
+               SECTION ANSWER
+                       ns1.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns2.nameservers.com. IN A
+               SECTION ANSWER
+                       ns2.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns3.nameservers.com. IN A
+               SECTION ANSWER
+                       ns3.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns4.nameservers.com. IN A
+               SECTION ANSWER
+                       ns4.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns5.nameservers.com. IN A
+               SECTION ANSWER
+                       ns5.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns6.nameservers.com. IN A
+               SECTION ANSWER
+                       ns6.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns7.nameservers.com. IN A
+               SECTION ANSWER
+                       ns7.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns8.nameservers.com. IN A
+               SECTION ANSWER
+                       ns8.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns9.nameservers.com. IN A
+               SECTION ANSWER
+                       ns9.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns10.nameservers.com. IN A
+               SECTION ANSWER
+                       ns10.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns11.nameservers.com. IN A
+               SECTION ANSWER
+                       ns11.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+       ENTRY_BEGIN
+               MATCH opcode qtype qname
+               ADJUST copy_id
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       ns12.nameservers.com. IN A
+               SECTION ANSWER
+                       ns12.nameservers.com. IN A 127.0.0.1
+       ENTRY_END
+
+       ; Reply no-data to AAAA queries
+       ENTRY_BEGIN
+               MATCH opcode subdomain
+               ADJUST copy_id copy_query
+               REPLY QR NOERROR
+               SECTION QUESTION
+                       nameservers.com. IN A
+       ENTRY_END
+RANGE_END
+
+; Query for a domain
+STEP 0 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.example.com. IN A
+ENTRY_END
+
+; Answer with delegation
+STEP 1 REPLY
+ENTRY_BEGIN
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+a.example.com. IN A
+SECTION AUTHORITY
+a.example.com. IN NS ns1.nameservers.com.
+a.example.com. IN NS ns2.nameservers.com.
+a.example.com. IN NS ns3.nameservers.com.
+a.example.com. IN NS ns4.nameservers.com.
+a.example.com. IN NS ns5.nameservers.com.
+a.example.com. IN NS ns6.nameservers.com.
+a.example.com. IN NS ns7.nameservers.com.
+a.example.com. IN NS ns8.nameservers.com.
+a.example.com. IN NS ns9.nameservers.com.
+a.example.com. IN NS ns10.nameservers.com.
+a.example.com. IN NS ns11.nameservers.com.
+a.example.com. IN NS ns12.nameservers.com.
+ENTRY_END
+
+; Reply NXDOMAIN to MAX_TARGET_NX queries(6) x2 (A+AAAA)
+STEP 2 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+SECTION AUTHORITY
+example.com. IN SOA ns.example.com email.example.com 1 2 3 4 60
+ENTRY_END
+STEP 3 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+SECTION AUTHORITY
+example.com. IN SOA ns.ns email.email 1 2 3 4 60
+ENTRY_END
+STEP 4 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 5 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 6 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 7 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 8 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 9 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 10 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 11 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 12 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 13 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+
+; We should receive SERVFAIL because MAX_TARGET_NX was reached
+STEP 14 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.example.com. IN A
+ENTRY_END
+
+; Query for another domain in the same delegation
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+b.a.example.com. IN A
+ENTRY_END
+
+; We still have 6 NSes that Unbound didn't try to resolve
+; Reply with NXDOMAIN for 5 of them
+STEP 21 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 22 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 23 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 24 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 25 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 26 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 27 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 28 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 29 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+STEP 30 REPLY
+ENTRY_BEGIN
+ADJUST copy_id copy_query
+REPLY QR NXDOMAIN
+SECTION QUESTION
+a.query. IN A
+ENTRY_END
+
+; Unbound will reach the upstream and get the answer for the final NS
+; which has the answer for the client query.
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+b.a.example.com. IN A
+SECTION ANSWER
+b.a.example.com. IN A 127.0.0.0
+ENTRY_END
+
+; Allow for possible pending NS query (AAAA) to get answered
+STEP 41 TRAFFIC
+
+SCENARIO_END