From: W.C.A. Wijngaards Date: Mon, 19 May 2025 11:17:21 +0000 (+0200) Subject: - Fix for cname chain length with qtype ANY and qname minimisation. X-Git-Tag: release-1.24.0rc1~91 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=32644937b07f802318c306b850e0801117400b8a;p=thirdparty%2Funbound.git - Fix for cname chain length with qtype ANY and qname minimisation. Thanks to Jim Greenwood from Nominet for the report. --- diff --git a/doc/Changelog b/doc/Changelog index 264a5fdd5..289372adc 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/iterator/iterator.c b/iterator/iterator.c index e64dfa61b..320faf734 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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 index 000000000..97fefaf95 --- /dev/null +++ b/testdata/iter_minimise_chain.rpl @@ -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