- Merge #1433 from jisakiel: Add new static zone type
block_aaaa to suppress AAAA queries.
- Unit test for block_a and block_aaaa.
+ - Fix #1477: respip + dns64: dns64 uses A records modified by
+ respip instead of original A records. Adds local-zone types
+ block_a_wdata and block_aaaa_wdata, that are like block_a
+ and block_aaaa, and uses local-data if present.
23 July 2026: Wouter
- Updated credits for Xuanchao Xie in 22 july changelog.
# NODATA for A queries and ignores local data for that name
# o block_aaaa similarly to block_a, resolves all records normally but
# returns NODATA for AAAA queries and ignores local data for that name
+ # o block_a_wdata like block_a but uses local data if present.
+ # o block_aaaa_wdata like block_aaaa but uses local data if present.
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
# o noview breaks out of that view towards global local-zones.
#
:ref:`always_transparent<unbound.conf.local-zone.type.always_transparent>`,
:ref:`block_a<unbound.conf.local-zone.type.block_a>`,
:ref:`block_aaaa<unbound.conf.local-zone.type.block_aaaa>`,
+ :ref:`block_a_wdata<unbound.conf.local-zone.type.block_a_wdata>`,
+ :ref:`block_aaaa_wdata<unbound.conf.local-zone.type.block_aaaa_wdata>`,
:ref:`always_refuse<unbound.conf.local-zone.type.always_refuse>`,
:ref:`always_nxdomain<unbound.conf.local-zone.type.always_nxdomain>`,
:ref:`always_null<unbound.conf.local-zone.type.always_null>`,
Useful in cases when there is a need to explicitly force all apps to
use IPv4 protocol and avoid any queries to IPv6.
+ @@UAHL@unbound.conf.local-zone.type@block_a_wdata@@
+ Like :ref:`block_a<unbound.conf.local-zone.type.block_a>`, but
+ uses local data if present.
+ If there is local data that is returned, and it acts like transparent.
+ For A queries it returns NODATA.
+
+ @@UAHL@unbound.conf.local-zone.type@block_aaaa_wdata@@
+ Like :ref:`block_aaaa<unbound.conf.local-zone.type.block_aaaa>`, but
+ uses local data if present.
+ If there is local data that is returned, and it acts like transparent.
+ For AAAA queries it returns NODATA.
+
@@UAHL@unbound.conf.local-zone.type@always_refuse@@
Like :ref:`refuse<unbound.conf.local-zone.type.refuse>`, but ignores
local data and refuses the query.
key.namelen = qinfo->qname_len;
key.namelabs = labs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
- if(z->type == local_zone_transparent || z->type == local_zone_inform)
+ if(z->type == local_zone_transparent || z->type == local_zone_inform
+ || z->type == local_zone_block_a_wdata
+ || z->type == local_zone_block_aaaa_wdata)
return (ld == NULL);
if(ld)
lr = local_data_find_type(ld, qinfo->qtype, 1);
|| lz_type == local_zone_always_transparent) {
/* no NODATA or NXDOMAINS for this zone type */
return 0;
- } else if(lz_type == local_zone_block_a) {
+ } else if(lz_type == local_zone_block_a ||
+ lz_type == local_zone_block_a_wdata) {
/* Return NODATA for all A queries */
if(qinfo->qtype == LDNS_RR_TYPE_A) {
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
}
return 0;
- } else if(lz_type == local_zone_block_aaaa) {
+ } else if(lz_type == local_zone_block_aaaa ||
+ lz_type == local_zone_block_aaaa_wdata) {
/* Return NODATA for all AAAA queries */
if(qinfo->qtype == LDNS_RR_TYPE_AAAA) {
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
lzt == local_zone_inform ||
lzt == local_zone_always_transparent ||
lzt == local_zone_block_a ||
- lzt == local_zone_block_aaaa) &&
+ lzt == local_zone_block_aaaa ||
+ lzt == local_zone_block_a_wdata ||
+ lzt == local_zone_block_aaaa_wdata) &&
local_zone_does_not_cover(z, qinfo, labs)) {
lock_rw_unlock(&z->lock);
z = NULL;
case local_zone_always_transparent: return "always_transparent";
case local_zone_block_a: return "block_a";
case local_zone_block_aaaa: return "block_aaaa";
+ case local_zone_block_a_wdata: return "block_a_wdata";
+ case local_zone_block_aaaa_wdata: return "block_aaaa_wdata";
case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain";
case local_zone_always_nodata: return "always_nodata";
*t = local_zone_block_a;
else if(strcmp(type, "block_aaaa") == 0)
*t = local_zone_block_aaaa;
+ else if(strcmp(type, "block_a_wdata") == 0)
+ *t = local_zone_block_a_wdata;
+ else if(strcmp(type, "block_aaaa_wdata") == 0)
+ *t = local_zone_block_aaaa_wdata;
else if(strcmp(type, "always_refuse") == 0)
*t = local_zone_always_refuse;
else if(strcmp(type, "always_nxdomain") == 0)
local_zone_block_a,
/** resolve normally, even when there is local data, but return NODATA for AAAA queries */
local_zone_block_aaaa,
+ /** resolve normally, use local data, else return NODATA for A queries */
+ local_zone_block_a_wdata,
+ /** resolve normally, use local data, else return NODATA for AAAA queries */
+ local_zone_block_aaaa_wdata,
/** answer with error, even when there is local data */
local_zone_always_refuse,
/** answer with nxdomain, even when there is local data */
qname-minimisation: no
local-zone: "example1.com." block_a
local-zone: "example2.com." block_aaaa
+ local-zone: "example3.com." block_a_wdata
+ local-data: "b.example3.com. A 1.2.3.5"
+ local-data: "b.example3.com. AAAA 1:2:3::5"
+ local-zone: "example4.com." block_aaaa_wdata
+ local-data: "b.example4.com. A 1.2.3.5"
+ local-data: "b.example4.com. AAAA 1:2:3::5"
stub-zone:
name: "."
SCENARIO_BEGIN test local data with block_a and block_aaaa
; K.ROOT-SERVERS.NET.
-RANGE_BEGIN 0 100
+RANGE_BEGIN 0 400
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
SECTION ANSWER
a.example2.com. IN AAAA 1:2:3::4
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example3.com. IN A
+SECTION ANSWER
+a.example3.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example3.com. IN AAAA
+SECTION ANSWER
+a.example3.com. IN AAAA 1:2:3::4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example4.com. IN A
+SECTION ANSWER
+a.example4.com. IN A 1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.example4.com. IN AAAA
+SECTION ANSWER
+a.example4.com. IN AAAA 1:2:3::4
+ENTRY_END
RANGE_END
; block_a for example1.com
SECTION ANSWER
ENTRY_END
+; block_a_wdata for example3.com
+STEP 80 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example3.com. IN A
+ENTRY_END
+
+; block_a_wdata blocks A
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+a.example3.com. IN A
+SECTION ANSWER
+ENTRY_END
+
+STEP 100 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example3.com. IN AAAA
+ENTRY_END
+
+; block_a_wdata allows AAAA from upstream
+STEP 110 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.example3.com. IN AAAA
+SECTION ANSWER
+a.example3.com. IN AAAA 1:2:3::4
+ENTRY_END
+
+STEP 120 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.example3.com. IN A
+ENTRY_END
+
+; block_a_wdata allows local-data A
+STEP 130 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+b.example3.com. IN A
+SECTION ANSWER
+b.example3.com. A 1.2.3.5
+ENTRY_END
+
+STEP 140 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.example3.com. IN AAAA
+ENTRY_END
+
+; block_a_wdata allows local-data AAAA
+STEP 150 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+b.example3.com. IN AAAA
+SECTION ANSWER
+b.example3.com. AAAA 1:2:3::5
+ENTRY_END
+
+; block_aaaa_wdata for example4.com
+STEP 160 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example4.com. IN A
+ENTRY_END
+
+; block_aaaa_wdata allows A from upstream
+STEP 170 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA DO NOERROR
+SECTION QUESTION
+a.example4.com. IN A
+SECTION ANSWER
+a.example4.com. IN A 1.2.3.4
+ENTRY_END
+
+STEP 180 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+a.example4.com. IN AAAA
+ENTRY_END
+
+; block_aaaa_wdata blocks AAAA
+STEP 190 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+a.example4.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
+STEP 200 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.example4.com. IN A
+ENTRY_END
+
+; block_aaaa_wdata allows local-data A
+STEP 210 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+b.example4.com. IN A
+SECTION ANSWER
+b.example4.com. A 1.2.3.5
+ENTRY_END
+
+STEP 220 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+b.example4.com. IN AAAA
+ENTRY_END
+
+; block_aaaa_wdata allows local-data AAAA
+STEP 230 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR AA RD RA DO NOERROR
+SECTION QUESTION
+b.example4.com. IN AAAA
+SECTION ANSWER
+b.example4.com. AAAA 1:2:3::5
+ENTRY_END
+
SCENARIO_END
&& strcmp($3, "always_transparent")!=0
&& strcmp($3, "block_a")!=0
&& strcmp($3, "block_aaaa")!=0
+ && strcmp($3, "block_a_wdata")!=0
+ && strcmp($3, "block_aaaa_wdata")!=0
&& strcmp($3, "always_refuse")!=0
&& strcmp($3, "always_nxdomain")!=0
&& strcmp($3, "always_nodata")!=0
"typetransparent, inform, inform_deny, "
"inform_redirect, always_transparent, "
"block_a, block_aaaa, "
+ "block_a_wdata, block_aaaa_wdata, "
"always_refuse, always_nxdomain, "
"always_nodata, always_deny, always_null, "
"noview, nodefault or ipset");