From: W.C.A. Wijngaards Date: Tue, 16 Jun 2026 07:52:46 +0000 (+0200) Subject: - Fix that dns64 does not ignore the `forward-no-cache` and X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=299df5ec7704c7f4209a1d8d04f1365de19a8b76;p=thirdparty%2Funbound.git - Fix that dns64 does not ignore the `forward-no-cache` and `stub-no-cache` options. Thanks to Qifan Zhang, Palo Alto Networks, for the report. --- diff --git a/dns64/dns64.c b/dns64/dns64.c index 314dc4639..ca39bd964 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -664,6 +664,7 @@ handle_event_moddone(struct module_qstate* qstate, int id) !qstate->is_subnet_answer && qstate->return_msg && qstate->return_msg->rep && + !qstate->fwd_stub_no_cache && !dns_cache_store( qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, @@ -725,8 +726,15 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id, } if(qstate->ext_state[id] == module_finished) { iq = (struct dns64_qstate*)qstate->minfo[id]; - if(iq && iq->state != DNS64_INTERNAL_QUERY) - qstate->no_cache_store = iq->started_no_cache_store; + if(iq && iq->state != DNS64_INTERNAL_QUERY) { + if(qstate->fwd_stub_no_cache) { + /* If the forward/stub has no cache, then + * continue with the query with no cache. */ + qstate->no_cache_store = qstate->fwd_stub_no_cache; + } else { + qstate->no_cache_store = iq->started_no_cache_store; + } + } } } @@ -1040,10 +1048,14 @@ dns64_inform_super(struct module_qstate* qstate, int id, log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR); dns64_adjust_ptr(qstate, super); } + /* If the sub-query has no cache store, then also the super query. */ + if(qstate->fwd_stub_no_cache) + super->fwd_stub_no_cache = 1; /* Store the generated response in cache. */ if ( super->return_msg && super->return_msg->rep && (!super_dq || !super_dq->started_no_cache_store) && + !qstate->fwd_stub_no_cache && !super->rpz_applied && !super->rpz_passthru && !super->is_subnet_answer && !dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, diff --git a/doc/Changelog b/doc/Changelog index 2ab026031..5c3b091c9 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -15,6 +15,9 @@ records. These are records that are not under the zone apex. The out-of-zone records are dropped from the zone contents. Thanks to Qifan Zhang, Palo Alto Networks, for the report. + - Fix that dns64 does not ignore the `forward-no-cache` and + `stub-no-cache` options. Thanks to Qifan Zhang, Palo Alto + Networks, for the report. 15 June 2026: Wouter - Fix to add `max-transfer-size` and `max-transfer-time` that diff --git a/iterator/iterator.c b/iterator/iterator.c index 723590955..3b81b1385 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1486,6 +1486,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, verbose(VERB_ALGO, "no-cache set, going to the network"); qstate->no_cache_lookup = 1; qstate->no_cache_store = 1; + qstate->fwd_stub_no_cache = 1; msg = NULL; } else if(qstate->blacklist) { /* if cache, or anything else, was blacklisted then diff --git a/testdata/dns64_fwd_nocache.rpl b/testdata/dns64_fwd_nocache.rpl new file mode 100644 index 000000000..51ab74401 --- /dev/null +++ b/testdata/dns64_fwd_nocache.rpl @@ -0,0 +1,209 @@ +; config options go here. +server: + target-fetch-policy: "0 0 0 0 0" + qname-minimisation: no + minimal-responses: yes + module-config: "dns64 iterator" + dns64-prefix: 64:ff9b::0/96 +forward-zone: name: "." forward-addr: 216.0.0.1 + forward-no-cache: yes +CONFIG_END + +SCENARIO_BEGIN Test DNS64 with forward zone with forward-no-cache set. +RANGE_BEGIN 0 15 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +RANGE_BEGIN 15 25 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.41 +ENTRY_END +RANGE_END + +RANGE_BEGIN 25 35 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www2.example.com. IN A +SECTION ANSWER +www2.example.com. IN A 10.20.30.42 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www2.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. 300 IN SOA ns.example.com. host.example.com. 5 86400 7200 604800 300 +ENTRY_END +RANGE_END + +RANGE_BEGIN 35 45 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www2.example.com. IN A +SECTION ANSWER +www2.example.com. IN A 10.20.30.43 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www2.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. 300 IN SOA ns.example.com. host.example.com. 5 86400 7200 604800 300 +ENTRY_END +RANGE_END + +RANGE_BEGIN 45 55 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www3.example.com. IN AAAA +SECTION ANSWER +www3.example.com. 3600 IN AAAA 2001:db8::5 +ENTRY_END +RANGE_END + +RANGE_BEGIN 55 65 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR RD RA NOERROR +SECTION QUESTION +www3.example.com. IN AAAA +SECTION ANSWER +www3.example.com. 3600 IN AAAA 2001:db8::6 +ENTRY_END +RANGE_END + +; query for A record +STEP 10 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END +STEP 11 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END + +; the upstream has changed, ask for A record again +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.com. IN A +ENTRY_END +STEP 21 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.41 +ENTRY_END + +; query for synthesized AAAA record +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www2.example.com. IN AAAA +ENTRY_END +STEP 31 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www2.example.com. IN AAAA +SECTION ANSWER +www2.example.com. 3600 IN AAAA 64:ff9b::a14:1e2a +ENTRY_END + +; the upstream has changed, query for synthesized AAAA again. +STEP 40 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www2.example.com. IN AAAA +ENTRY_END +STEP 41 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www2.example.com. IN AAAA +SECTION ANSWER +www2.example.com. 3600 IN AAAA 64:ff9b::a14:1e2b +ENTRY_END + +; query for AAAA record, that is present, no synthesis. +STEP 50 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www3.example.com. IN AAAA +ENTRY_END +STEP 51 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www3.example.com. IN AAAA +SECTION ANSWER +www3.example.com. 3600 IN AAAA 2001:db8::5 +ENTRY_END + +; the upstream has changed, query for AAAA record again (no synthesis). +STEP 60 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www3.example.com. IN AAAA +ENTRY_END +STEP 61 CHECK_ANSWER +ENTRY_BEGIN +REPLY QR RD RA +MATCH opcode qname qtype all +SECTION QUESTION +www3.example.com. IN AAAA +SECTION ANSWER +www3.example.com. 3600 IN AAAA 2001:db8::6 +ENTRY_END + +SCENARIO_END diff --git a/util/module.h b/util/module.h index d093c2aec..46eb7c31e 100644 --- a/util/module.h +++ b/util/module.h @@ -707,6 +707,10 @@ struct module_qstate { * suitable for caching (briefly) the error response. Set by the * iterator when no_cache_store is enabled, and there is an error. */ int error_response_cache; + /** if the iterator sees that the forward/stub has no_cache set. + * to signal to calling modules that their setting of no_cache for + * other reasons, has to take into account the fwd/stub no_cache. */ + int fwd_stub_no_cache; /** * Attributes of clients that share the qstate that may affect IP-based