From: W.C.A. Wijngaards Date: Fri, 24 Jul 2026 07:29:17 +0000 (+0200) Subject: - Fix #1477: respip + dns64: dns64 uses A records modified by X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=79e100a7fbb45bee3a409f2add927dbee563d35d;p=thirdparty%2Funbound.git - 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. --- diff --git a/doc/Changelog b/doc/Changelog index 57296b331..25fd018e0 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,10 @@ - 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. diff --git a/doc/example.conf.in b/doc/example.conf.in index f1e1e412b..c5e4e242e 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -901,6 +901,8 @@ server: # 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. # diff --git a/doc/unbound.conf.rst b/doc/unbound.conf.rst index 71259afd9..e341c516f 100644 --- a/doc/unbound.conf.rst +++ b/doc/unbound.conf.rst @@ -2593,6 +2593,8 @@ These options are part of the ``server:`` section. :ref:`always_transparent`, :ref:`block_a`, :ref:`block_aaaa`, + :ref:`block_a_wdata`, + :ref:`block_aaaa_wdata`, :ref:`always_refuse`, :ref:`always_nxdomain`, :ref:`always_null`, @@ -2750,6 +2752,18 @@ These options are part of the ``server:`` section. 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`, 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`, 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`, but ignores local data and refuses the query. diff --git a/services/localzone.c b/services/localzone.c index 5d376cb15..5de780127 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -1679,7 +1679,9 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo, 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); @@ -1745,7 +1747,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env, || 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, @@ -1755,7 +1758,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env, } 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, @@ -1933,7 +1937,9 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, 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; @@ -2015,6 +2021,8 @@ const char* local_zone_type2str(enum localzone_type t) 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"; @@ -2053,6 +2061,10 @@ int local_zone_str2type(const char* type, enum localzone_type* t) *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) diff --git a/services/localzone.h b/services/localzone.h index de2633486..436874e0f 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -95,6 +95,10 @@ enum localzone_type { 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 */ diff --git a/testdata/local_block_a.rpl b/testdata/local_block_a.rpl index 4e3c9c3ab..6db5cb200 100644 --- a/testdata/local_block_a.rpl +++ b/testdata/local_block_a.rpl @@ -4,6 +4,12 @@ server: 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: "." @@ -13,7 +19,7 @@ CONFIG_END 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 @@ -66,6 +72,46 @@ a.example2.com. IN AAAA 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 @@ -141,4 +187,148 @@ a.example2.com. IN AAAA 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 diff --git a/util/configparser.y b/util/configparser.y index 64fdfc41e..490bba0ff 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -2396,6 +2396,8 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG && 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 @@ -2410,6 +2412,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG "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");