summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibor Peltan <libor.peltan@nic.cz>2025-01-16 16:04:23 +0100
committerLibor Peltan <libor.peltan@nic.cz>2025-01-16 16:04:23 +0100
commita3a772b57508cbb77009b2af72c7b7671b79aa7b (patch)
tree87ea9d75c7b0ad69dcc2ba742c9d3d599d0da4b1
parentdoc: update year to 2025 (diff)
parentadjust: refactor structure initializations to be more descriptive (diff)
downloadknot-a3a772b57508cbb77009b2af72c7b7671b79aa7b.tar.xz
knot-a3a772b57508cbb77009b2af72c7b7671b79aa7b.zip
Merge branch 'dname_apex' into 'master'
Fix DNAME at the zone apex check if active NSEC3 See merge request knot/knot-dns!1740
-rw-r--r--src/knot/zone/adjust.c20
-rw-r--r--src/knot/zone/semantic-check.c4
-rw-r--r--tests-extra/tests/zone/dname_apex/data/test.zone6
-rw-r--r--tests-extra/tests/zone/dname_apex/test.py48
4 files changed, 72 insertions, 6 deletions
diff --git a/src/knot/zone/adjust.c b/src/knot/zone/adjust.c
index fb96e0a83..0c2b82ff1 100644
--- a/src/knot/zone/adjust.c
+++ b/src/knot/zone/adjust.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2025 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -492,7 +492,11 @@ int zone_adjust_contents(zone_contents_t *zone, adjust_cb_t nodes_cb, adjust_cb_
zone->dnssec = node_rrtype_is_signed(zone->apex, KNOT_RRTYPE_SOA);
measure_t m = knot_measure_init(measure_zone, false);
- adjust_ctx_t ctx = { zone, add_changed, true };
+ adjust_ctx_t ctx = {
+ .zone = zone,
+ .changed_nodes = add_changed,
+ .nsec3_param_changed = true
+ };
if (threads > 1) {
assert(nodes_cb != adjust_cb_flags); // This cb demands parent to be adjusted before child
@@ -525,7 +529,11 @@ int zone_adjust_update(zone_update_t *update, adjust_cb_t nodes_cb, adjust_cb_t
{
int ret = KNOT_EOK;
measure_t m = knot_measure_init(false, measure_diff);
- adjust_ctx_t ctx = { update->new_cont, update->a_ctx->adjust_ptrs, zone_update_changed_nsec3param(update) };
+ adjust_ctx_t ctx = {
+ .zone = update->new_cont,
+ .changed_nodes = update->a_ctx->adjust_ptrs,
+ .nsec3_param_changed = zone_update_changed_nsec3param(update)
+ };
if (nsec3_cb != NULL) {
ret = zone_adjust_tree(update->a_ctx->nsec3_ptrs, &ctx, nsec3_cb, false, &m);
@@ -575,7 +583,11 @@ int zone_adjust_incremental_update(zone_update_t *update, unsigned threads)
return ret;
}
bool nsec3change = zone_update_changed_nsec3param(update);
- adjust_ctx_t ctx = { update->new_cont, update->a_ctx->adjust_ptrs, nsec3change };
+ adjust_ctx_t ctx = {
+ .zone = update->new_cont,
+ .changed_nodes = update->a_ctx->adjust_ptrs,
+ .nsec3_param_changed = nsec3change
+ };
ret = zone_adjust_contents(update->new_cont, adjust_cb_flags, adjust_cb_nsec3_flags,
false, true, 1, update->a_ctx->adjust_ptrs);
diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c
index d449c5f77..76155ed94 100644
--- a/src/knot/zone/semantic-check.c
+++ b/src/knot/zone/semantic-check.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2025 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -427,7 +427,7 @@ static int check_dname(const zone_node_t *node, semchecks_data_t *data)
}
/* RFC 6672 Section 2.4 Paragraph 1 */
/* If the NSEC3 node of the apex is present, it is counted as apex's child. */
- unsigned allowed_children = (is_apex && node_nsec3_get(node) != NULL) ? 1 : 0;
+ unsigned allowed_children = (is_apex && !zone_tree_is_empty(data->zone->nsec3_nodes)) ? 1 : 0;
if (node->children > allowed_children) {
data->handler->error = true;
data->handler->cb(data->handler, data->zone, node->owner,
diff --git a/tests-extra/tests/zone/dname_apex/data/test.zone b/tests-extra/tests/zone/dname_apex/data/test.zone
new file mode 100644
index 000000000..a63ab998a
--- /dev/null
+++ b/tests-extra/tests/zone/dname_apex/data/test.zone
@@ -0,0 +1,6 @@
+$ORIGIN test.
+$TTL 3600
+
+@ SOA dns1 hostmaster 2010111201 10800 3600 1209600 7200
+ NS ns.example.com.
+ DNAME example.com.
diff --git a/tests-extra/tests/zone/dname_apex/test.py b/tests-extra/tests/zone/dname_apex/test.py
new file mode 100644
index 000000000..d8d9dc851
--- /dev/null
+++ b/tests-extra/tests/zone/dname_apex/test.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+
+'''Test for DNAME check at the zone apex'''
+
+import random
+from dnstest.test import Test
+
+t = Test()
+
+master = t.server("knot")
+slave = t.server("knot")
+ZONE = "test."
+zones = t.zone(ZONE, storage=".")
+
+t.link(zones, master, slave)
+
+master.zonefile_sync = 0
+master.zonefile_load = "difference-no-serial"
+master.zones[ZONE].journal_content = "all"
+
+if random.choice([False, True]):
+ master.dnssec(zones[0]).enable = True
+ if random.choice([False, True]):
+ master.dnssec(zones[0]).nsec3 = True
+
+t.start()
+
+# Check if the zone was accepted via AXFR
+serial = master.zones_wait(zones)
+slave.zones_wait(zones)
+t.xfr_diff(master, slave, zones)
+resp = slave.dig(ZONE, "DNAME")
+resp.check(rcode="NOERROR", rdata="example.com.")
+
+# Check if possibly signed zone (upon flush) can be parsed
+master.stop()
+t.sleep(1)
+master.zones[ZONE].zfile.append_rndTXT(ZONE)
+master.start()
+
+# Check if the zone was accepted via IXFR
+master.zones_wait(zones, serial)
+slave.zones_wait(zones, serial)
+t.xfr_diff(master, slave, zones)
+resp = slave.dig(ZONE, "DNAME")
+resp.check(rcode="NOERROR", rdata="example.com.")
+
+t.end()