]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix for cname chain length with qtype ANY and qname minimisation.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 19 May 2025 11:17:21 +0000 (13:17 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 19 May 2025 11:17:21 +0000 (13:17 +0200)
  Thanks to Jim Greenwood from Nominet for the report.

doc/Changelog
iterator/iterator.c
testdata/iter_minimise_chain.rpl [new file with mode: 0644]

index 264a5fdd5fbf55d41f095ff535e37b4c14c2acc7..289372adc70a894424aaf27b826982b30149e777 100644 (file)
@@ -1,3 +1,7 @@
+19 May 2025: Wouter
+       - Fix for cname chain length with qtype ANY and qname minimisation.
+         Thanks to Jim Greenwood from Nominet for the report.
+
 15 May 2025: Wouter
        - Fix config of slab values when there is no config file.
 
index e64dfa61ba2dc8bca5ff458d47b40beb4562808e..320faf734c5805dbf1b39902836c41cd33d9ce28 100644 (file)
@@ -3247,13 +3247,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                }
        }
        if(type == RESPONSE_TYPE_CNAME &&
-               iq->qchase.qtype == LDNS_RR_TYPE_CNAME &&
+               (iq->qchase.qtype == LDNS_RR_TYPE_CNAME ||
+                 iq->qchase.qtype == LDNS_RR_TYPE_ANY) &&
                iq->minimisation_state == MINIMISE_STATE &&
                query_dname_compare(iq->qchase.qname, iq->qinfo_out.qname) == 0) {
                /* The minimised query for full QTYPE and hidden QTYPE can be
                 * classified as CNAME response type, even when the original
                 * QTYPE=CNAME. This should be treated as answer response type.
                 */
+               /* For QTYPE=ANY, it is also considered the response, that
+                * is what the classifier would say, if it saw qtype ANY,
+                * and this same response was returned for that. The response
+                * can already be treated as such an answer, without having
+                * to send another query with a new qtype. */
                type = RESPONSE_TYPE_ANSWER;
        }
 
@@ -3510,6 +3516,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                        iq->num_target_queries = 0;
                        return processDSNSFind(qstate, iq, id);
                }
+               if(iq->minimisation_state == MINIMISE_STATE &&
+                       query_dname_compare(iq->qchase.qname,
+                       iq->qinfo_out.qname) != 0) {
+                       verbose(VERB_ALGO, "continue query minimisation, "
+                               "downwards, after CNAME response for "
+                               "intermediate label");
+                       /* continue query minimisation, downwards */
+                       return next_state(iq, QUERYTARGETS_STATE);
+               }
                /* Process the CNAME response. */
                if(!handle_cname_response(qstate, iq, iq->response, 
                        &sname, &snamelen)) {
@@ -3572,10 +3587,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                iq->auth_zone_response = 0;
                iq->sent_count = 0;
                iq->dp_target_count = 0;
-               if(iq->minimisation_state != MINIMISE_STATE)
-                       /* Only count as query restart when it is not an extra
-                        * query as result of qname minimisation. */
-                       iq->query_restart_count++;
+               iq->query_restart_count++;
                if(qstate->env->cfg->qname_minimisation)
                        iq->minimisation_state = INIT_MINIMISE_STATE;
 
diff --git a/testdata/iter_minimise_chain.rpl b/testdata/iter_minimise_chain.rpl
new file mode 100644 (file)
index 0000000..97fefaf
--- /dev/null
@@ -0,0 +1,623 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+       qname-minimisation: yes
+       max-query-restarts: 11
+       max-global-quota: 120
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129
+CONFIG_END
+
+SCENARIO_BEGIN Test qname minimisation and long cname chain.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 1000
+        ADDRESS 193.0.14.129
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 1000
+        ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN A
+SECTION AUTHORITY
+com. IN NS a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 1000
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com. IN NS ns.example.com.
+SECTION ADDITIONAL
+ns.example.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain1.example.com. IN CNAME
+SECTION ANSWER
+chain1.example.com. IN CNAME chain2.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain2.example.com. IN CNAME
+SECTION ANSWER
+chain2.example.com. IN CNAME chain3.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain3.example.com. IN CNAME
+SECTION ANSWER
+chain3.example.com. IN CNAME chain4.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain4.example.com. IN CNAME
+SECTION ANSWER
+chain4.example.com. IN CNAME chain5.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain5.example.com. IN CNAME
+SECTION ANSWER
+chain5.example.com. IN CNAME chain6.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain6.example.com. IN CNAME
+SECTION ANSWER
+chain6.example.com. IN CNAME chain7.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain7.example.com. IN CNAME
+SECTION ANSWER
+chain7.example.com. IN CNAME chain8.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain8.example.com. IN CNAME
+SECTION ANSWER
+chain8.example.com. IN CNAME chain9.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain9.example.com. IN CNAME
+SECTION ANSWER
+chain9.example.com. IN CNAME chain10.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain10.example.com. IN CNAME
+SECTION ANSWER
+chain10.example.com. IN CNAME chain11.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain11.example.com. IN CNAME
+SECTION ANSWER
+chain11.example.com. IN CNAME chain12.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain12.example.com. IN CNAME
+SECTION ANSWER
+chain12.example.com. IN CNAME chain13.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain13.example.com. IN CNAME
+SECTION ANSWER
+chain13.example.com. IN CNAME chain14.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain14.example.com. IN CNAME
+SECTION ANSWER
+chain14.example.com. IN CNAME chain15.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain15.example.com. IN CNAME
+SECTION ANSWER
+chain15.example.com. IN CNAME chain16.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain16.example.com. IN CNAME
+SECTION ANSWER
+chain16.example.com. IN CNAME chain17.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain17.example.com. IN CNAME
+SECTION ANSWER
+chain17.example.com. IN CNAME chain18.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain18.example.com. IN CNAME
+SECTION ANSWER
+chain18.example.com. IN CNAME chain19.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain19.example.com. IN CNAME
+SECTION ANSWER
+chain19.example.com. IN CNAME chain20.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain20.example.com. IN CNAME
+SECTION ANSWER
+chain20.example.com. IN CNAME chain21.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain21.example.com. IN CNAME
+SECTION ANSWER
+chain21.example.com. IN CNAME chain22.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain22.example.com. IN CNAME
+SECTION ANSWER
+chain22.example.com. IN CNAME chain23.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain23.example.com. IN CNAME
+SECTION ANSWER
+chain23.example.com. IN CNAME chain24.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain24.example.com. IN CNAME
+SECTION ANSWER
+chain24.example.com. IN CNAME chain25.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain25.example.com. IN CNAME
+SECTION ANSWER
+chain25.example.com. IN CNAME chain26.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain26.example.com. IN CNAME
+SECTION ANSWER
+chain26.example.com. IN CNAME chain27.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain27.example.com. IN CNAME
+SECTION ANSWER
+chain27.example.com. IN CNAME chain28.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain28.example.com. IN CNAME
+SECTION ANSWER
+chain28.example.com. IN CNAME chain29.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain29.example.com. IN CNAME
+SECTION ANSWER
+chain29.example.com. IN CNAME chain30.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain30.example.com. IN CNAME
+SECTION ANSWER
+chain30.example.com. IN CNAME chain31.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain31.example.com. IN CNAME
+SECTION ANSWER
+chain31.example.com. IN CNAME chain32.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain32.example.com. IN CNAME
+SECTION ANSWER
+chain32.example.com. IN CNAME chain33.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain33.example.com. IN CNAME
+SECTION ANSWER
+chain33.example.com. IN CNAME chain34.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain34.example.com. IN CNAME
+SECTION ANSWER
+chain34.example.com. IN CNAME chain35.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain35.example.com. IN CNAME
+SECTION ANSWER
+chain35.example.com. IN CNAME chain36.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain36.example.com. IN CNAME
+SECTION ANSWER
+chain36.example.com. IN CNAME chain37.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain37.example.com. IN CNAME
+SECTION ANSWER
+chain37.example.com. IN CNAME chain38.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain38.example.com. IN CNAME
+SECTION ANSWER
+chain38.example.com. IN CNAME chain39.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain39.example.com. IN CNAME
+SECTION ANSWER
+chain39.example.com. IN CNAME chain40.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+chain40.example.com. IN CNAME
+SECTION ANSWER
+chain40.example.com. IN CNAME chain41.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub1.chain1.example.com. IN A
+SECTION ANSWER
+sub1.chain1.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub1.chain1.example.com. IN ANY
+SECTION ANSWER
+sub1.chain1.example.com. IN A 1.2.3.5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub2.chain2.example.com. IN A
+SECTION ANSWER
+sub2.chain2.example.com. IN CNAME sub2-2.chain2.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub2-2.chain2.example.com. IN A
+SECTION ANSWER
+sub2-2.chain2.example.com. IN CNAME sub2-3.chain2.example.com.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+sub2-3.chain1.example.com. IN ANY
+SECTION ANSWER
+sub2-3.chain1.example.com. IN A 1.2.3.6
+ENTRY_END
+RANGE_END
+
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+chain1.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+chain1.example.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+chain13.example.com. IN ANY
+ENTRY_END
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+chain13.example.com. IN ANY
+SECTION ANSWER
+chain13.example.com. IN CNAME chain14.example.com.
+ENTRY_END
+
+STEP 49 TIME_PASSES ELAPSE 7200 ; expire the previous records.
+STEP 50 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+chain1.example.com. IN ANY
+ENTRY_END
+
+STEP 60 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+chain1.example.com. IN ANY
+SECTION ANSWER
+chain1.example.com. IN CNAME chain2.example.com.
+ENTRY_END
+
+STEP 69 TIME_PASSES ELAPSE 7200 ; expire the previous records.
+STEP 70 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+sub1.chain1.example.com. IN ANY
+ENTRY_END
+
+STEP 80 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+sub1.chain1.example.com. IN ANY
+SECTION ANSWER
+sub1.chain1.example.com. IN A 1.2.3.5
+ENTRY_END
+
+STEP 90 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+sub2.chain2.example.com. IN ANY
+ENTRY_END
+
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+sub2.chain2.example.com. IN ANY
+SECTION ANSWER
+sub2.chain2.example.com. IN CNAME sub2-2.chain2.example.com.
+ENTRY_END
+
+SCENARIO_END