]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Allow local-data for classes other than IN to inherit a configured
authorGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 10 Dec 2021 16:35:36 +0000 (17:35 +0100)
committerGeorge Thessalonikefs <george@nlnetlabs.nl>
Fri, 10 Dec 2021 16:35:36 +0000 (17:35 +0100)
  local-zone's type if possible, instead of defaulting to type
  transparent as per the implicit rule.

doc/Changelog
services/localzone.c
testdata/localdata.rpl

index 8a5a3231719374b79c8e0e1501ab500cf0a060df..9df23b322d3f111db909993336c7360d132bafd9 100644 (file)
@@ -1,3 +1,8 @@
+10 December 2021: George
+       - Allow local-data for classes other than IN to inherit a configured
+         local-zone's type if possible, instead of defaulting to type
+         transparent as per the implicit rule.
+
 10 December 2021: Wouter
        - Add code similar to fix for ldns for tab between strings, for
          consistency, the test case was not broken.
index 77d0107f9f6fb71e246077833b4d98b66153951c..beaefbdc83d8c09f21a34cac71c49eb46aff57bf 100644 (file)
  * with 16 bytes for an A record, a 64K packet has about 4000 max */
 #define LOCALZONE_RRSET_COUNT_MAX 4096
 
+/** print all RRsets in local zone */
+static void
+local_zone_out(struct local_zone* z)
+{
+       struct local_data* d;
+       struct local_rrset* p;
+       RBTREE_FOR(d, struct local_data*, &z->data) {
+               for(p = d->rrsets; p; p = p->next) {
+                       log_nametypeclass(NO_VERBOSE, "rrset", d->name,
+                               ntohs(p->rrset->rk.type),
+                               ntohs(p->rrset->rk.rrset_class));
+               }
+       }
+}
+
+static void
+local_zone_print(struct local_zone* z)
+{
+       char buf[64];
+       lock_rw_rdlock(&z->lock);
+       snprintf(buf, sizeof(buf), "%s zone",
+               local_zone_type2str(z->type));
+       log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
+       local_zone_out(z);
+       lock_rw_unlock(&z->lock);
+}
+
+void local_zones_print(struct local_zones* zones)
+{
+       struct local_zone* z;
+       lock_rw_rdlock(&zones->lock);
+       log_info("number of auth zones %u", (unsigned)zones->ztree.count);
+       RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
+               local_zone_print(z);
+       }
+       lock_rw_unlock(&zones->lock);
+}
+
 struct local_zones* 
 local_zones_create(void)
 {
@@ -1010,6 +1048,35 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
                lock_rw_rdlock(&zones->lock);
                if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
                        rr_type)) {
+                       /* Check if there is a zone that this could go
+                        * under but for different class; created zones are
+                        * always for LDNS_RR_CLASS_IN. Create the zone with
+                        * a different class but the same configured
+                        * local_zone_type. */
+                       struct local_zone* z = local_zones_lookup(zones,
+                               rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
+                       if(z) {
+                               uint8_t* name = memdup(z->name, z->namelen);
+                               lock_rw_unlock(&zones->lock);
+                               if(!name) {
+                                       log_err("out of memory");
+                                       free(rr_name);
+                                       return 0;
+                               }
+                               if(!(
+#ifndef THREADS_DISABLED
+                                       z =
+#endif
+                                       lz_enter_zone_dname(zones, name,
+                                               z->namelen, z->namelabs,
+                                               z->type, rr_class))) {
+                                       free(rr_name);
+                                       return 0;
+                               }
+                               lock_rw_unlock(&z->lock);
+                               free(rr_name);
+                               continue;
+                       }
                        if(!have_name) {
                                dclass = rr_class;
                                nm = rr_name;
@@ -1220,38 +1287,6 @@ local_zones_find_le(struct local_zones* zones,
        return (struct local_zone*)node;
 }
 
-/** print all RRsets in local zone */
-static void 
-local_zone_out(struct local_zone* z)
-{
-       struct local_data* d;
-       struct local_rrset* p;
-       RBTREE_FOR(d, struct local_data*, &z->data) {
-               for(p = d->rrsets; p; p = p->next) {
-                       log_nametypeclass(NO_VERBOSE, "rrset", d->name,
-                               ntohs(p->rrset->rk.type),
-                               ntohs(p->rrset->rk.rrset_class));
-               }
-       }
-}
-
-void local_zones_print(struct local_zones* zones)
-{
-       struct local_zone* z;
-       lock_rw_rdlock(&zones->lock);
-       log_info("number of auth zones %u", (unsigned)zones->ztree.count);
-       RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
-               char buf[64];
-               lock_rw_rdlock(&z->lock);
-               snprintf(buf, sizeof(buf), "%s zone",
-                       local_zone_type2str(z->type));
-               log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
-               local_zone_out(z);
-               lock_rw_unlock(&z->lock);
-       }
-       lock_rw_unlock(&zones->lock);
-}
-
 /** encode answer consisting of 1 rrset */
 static int
 local_encode(struct query_info* qinfo, struct module_env* env,
index 047fbeebadd41c9c88f1b7d58932ec92b3da3dd6..e54de2b616624c704156b81d7f2cecc068b149c4 100644 (file)
@@ -45,9 +45,32 @@ server:
        local-data: "b.c.implicit. A 20.30.45.50"
        local-data: "c.c.implicit. A 20.30.44.50"
 
+        ; create implicit data in the ANY domain
+        ; this should inherit the local_zone_type of the already configured
+        ; zone 'refuse.top.' and not be transparent
+        local-data: "refuse.top. ANY TXT implicit_non_transparent"
+
+stub-zone:
+        name: "refuse.top"
+        stub-addr: 1.2.3.4
+
 CONFIG_END
 SCENARIO_BEGIN Test local data queries
 
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+; This entry should never be queried
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.refuse.top. IN A
+SECTION ANSWER
+www.refuse.top. IN A 5.5.5.5
+ENTRY_END
+RANGE_END
+
 ; id.server.
 STEP 1 QUERY
 ENTRY_BEGIN
@@ -390,4 +413,35 @@ SECTION ANSWER
 foo.null.top. IN AAAA ::0
 ENTRY_END
 
+; refuse zone for implicit local-data with CLASS != IN
+STEP 64 QUERY
+ENTRY_BEGIN
+SECTION QUESTION
+refuse.top. ANY TXT
+ENTRY_END
+STEP 65 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RA AA NOERROR
+SECTION QUESTION
+refuse.top. ANY TXT
+SECTION ANSWER
+refuse.top. ANY TXT implicit_non_transparent
+ENTRY_END
+
+; refuse zone for implicit local-data with CLASS != IN
+STEP 66 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.refuse.top. ANY A
+ENTRY_END
+STEP 67 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RA RD AA REFUSED
+SECTION QUESTION
+www.refuse.top. ANY A
+ENTRY_END
+
 SCENARIO_END