]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix that dns64 does not ignore the `forward-no-cache` and
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 16 Jun 2026 07:52:46 +0000 (09:52 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 16 Jun 2026 07:52:46 +0000 (09:52 +0200)
  `stub-no-cache` options. Thanks to Qifan Zhang, Palo Alto
  Networks, for the report.

dns64/dns64.c
doc/Changelog
iterator/iterator.c
testdata/dns64_fwd_nocache.rpl [new file with mode: 0644]
util/module.h

index 314dc46398f29a437a0d4a7d1431ddbc69ca06d1..ca39bd96416232fc6749c4a1a1fe88ff4e02135b 100644 (file)
@@ -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,
index 2ab026031172f882d6df662cff0693adee6b1a73..5c3b091c9c81e21fd983e22617103c5cd0a0399f 100644 (file)
@@ -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
index 723590955355a7334dd1231864ba2d2a69baa9dd..3b81b1385fede45c19ea3810aded31d9e2166847 100644 (file)
@@ -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 (file)
index 0000000..51ab744
--- /dev/null
@@ -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
index d093c2aeca0bf58cf652c1b571c4ef522a0fdff7..46eb7c31efc74915f89c93750a71b4fe3aa4f69a 100644 (file)
@@ -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