- Fix #1403: Inconsistency between do-nat64 and do-not-query-address
Some checks failed
ci / build (push) Has been cancelled

during retries.
This commit is contained in:
W.C.A. Wijngaards 2026-02-11 16:01:30 +01:00
parent f7f638e18f
commit 1a9a4e4ca1
4 changed files with 231 additions and 3 deletions

View file

@ -1,3 +1,7 @@
11 February 2026: Wouter
- Fix #1403: Inconsistency between do-nat64 and do-not-query-address
during retries.
9 February 2026: Wouter
- Merge #1401: Add a new build-time option for system TLS.
The --enable-system-tls flag enables the

View file

@ -4164,6 +4164,17 @@ servers.
Use a specific NAT64 prefix to reach IPv4-only servers.
The prefix length must be one of /32, /40, /48, /56, /64 or /96.
The NAT64 prefix is allowed by the
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
so that there is a clear outcome of addresses in both; the NAT64 prefix
is allowed.
The IPv4 address could be filtered by the
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
if needed.
Allowing the NAT64 prefix is useful when using do-not-query-address
for a cluster of machines that is IPv6-only and uses NAT64, but does
not have internet access.
Default: 64:ff9b::/96 (same as :ref:`dns64-prefix<unbound.conf.dns64.dns64-prefix>`)
.. _unbound.conf.dnscrypt:

View file

@ -308,9 +308,30 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
if(a->bogus)
return -1; /* address of server is bogus */
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
log_addr(VERB_ALGO, "skip addr on the donotquery list",
&a->addr, a->addrlen);
return -1; /* server is on the donotquery list */
if(iter_env->nat64.use_nat64 &&
addr_is_ip6(&a->addr, a->addrlen) &&
a->addrlen == iter_env->nat64.nat64_prefix_addrlen &&
addr_in_common(&a->addr, 128,
&iter_env->nat64.nat64_prefix_addr,
iter_env->nat64.nat64_prefix_net,
iter_env->nat64.nat64_prefix_addrlen) ==
iter_env->nat64.nat64_prefix_net) {
/* The NAT64 is enabled, and address is IPv6, it is
* in the NAT64 prefix. It is allowed.
* So that in an IPv6-only cluster without internet
* access, that makes the NAT64 translation continue
* to work. The NAT64 prefix is allowed. */
/* Otherwise, after a timeout, the already NAT64
* translated address would be treated differently,
* and that causes confusion. */
log_addr(VERB_ALGO, "the addr is on the donotquery "
"list, but allowed because it is NAT64",
&a->addr, a->addrlen);
} else {
log_addr(VERB_ALGO, "skip addr on the donotquery list",
&a->addr, a->addrlen);
return -1; /* server is on the donotquery list */
}
}
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip6 available */

192
testdata/iter_nat64_donotq.rpl vendored Normal file
View file

@ -0,0 +1,192 @@
; config options
server:
do-nat64: yes
nat64-prefix: 2001:db8:1234::/96
target-fetch-policy: "0 0 0 0 0"
; This is like a machine that is part of a cluster of hosts that
; is IPv6-only, and uses NAT64. The cluster has no internet access.
do-not-query-address: ::0/0
qname-minimisation: no
stub-zone:
name: "."
; Pick an address in the NAT64 prefix, so it is allowed.
; other addresses would not be allowed. Or without the bugfix,
; allowed depending on state machine activation sequence.
stub-addr: 2001:db8:1234::1
CONFIG_END
SCENARIO_BEGIN Test NAT64 transport for v4-only with do-not-query-addresses.
RANGE_BEGIN 0 100
ADDRESS 2001:db8:1234::1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS FAKE.ROOT.
SECTION ADDITIONAL
FAKE.ROOT. IN AAAA 2001:db8:1234::1
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
v4only. IN NS
SECTION AUTHORITY
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
RANGE_END
; replies from NS over "NAT64"
RANGE_BEGIN 0 20
ADDRESS 2001:db8:1234::c000:0201
; A over NAT64
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN A
SECTION ANSWER
ns.v4only. IN A 192.0.2.1
SECTION AUTHORITY
v4only. IN NS ns.v4only.
ENTRY_END
; no AAAA
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN AAAA
SECTION AUTHORITY
v4only. IN SOA ns.v4only. host. 1 3600 300 48000 3600
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
v4only. IN NS
SECTION ANSWER
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
test.v4only. IN A
SECTION ANSWER
test.v4only. IN A 192.0.2.2
SECTION AUTHORITY
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
RANGE_END
RANGE_BEGIN 50 100
ADDRESS 2001:db8:1234::c000:0201
; no AAAA
; The last resort lookup of the AAAA is blocked here,
; the last resort processing is not desired, it should resolve test2
; straight away.
;ENTRY_BEGIN
;MATCH opcode qtype qname
;ADJUST copy_id
;REPLY AA QR NOERROR
;SECTION QUESTION
;ns.v4only. IN AAAA
;SECTION AUTHORITY
;v4only. IN SOA ns.v4only. host. 1 3600 300 48000 3600
;v4only. IN NS ns.v4only.
;SECTION ADDITIONAL
;ns.v4only. IN A 192.0.2.1
;ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN A
SECTION ANSWER
ns.v4only. IN A 192.0.2.1
SECTION AUTHORITY
v4only. IN NS ns.v4only.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
test2.v4only. IN A
SECTION ANSWER
test2.v4only. IN A 192.0.2.3
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
test.v4only. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
test.v4only. IN A
SECTION ANSWER
test.v4only. IN A 192.0.2.2
ENTRY_END
; for a query where the upstream nameserver has a timeout.
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
test2.v4only. IN A
ENTRY_END
; Only the test2 query is there, and it has a timeout.
; The address is already NAT64 translated, so now that it is
; attempted again, it is looked up in dotnotq as the ipv6 address.
STEP 40 TIMEOUT
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
test2.v4only. IN A
SECTION ANSWER
test2.v4only. IN A 192.0.2.3
ENTRY_END
SCENARIO_END