]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
deleg: DELEG-aware answering depends on ADT presence
authorLibor Peltan <libor.peltan@nic.cz>
Fri, 6 Feb 2026 10:45:38 +0000 (11:45 +0100)
committerLibor Peltan <libor.peltan@nic.cz>
Wed, 6 May 2026 10:14:06 +0000 (12:14 +0200)
src/knot/dnssec/zone-events.c
src/knot/dnssec/zone-events.h
src/knot/nameserver/internet.c
src/knot/updates/zone-update.c
src/knot/zone/adjust.c
src/knot/zone/zone-tree.h

index 32e528ea243dca5e22926ca4fb9b2e438b009c7b..67c8761510819b417dd154d564a1cef0d39245f5 100644 (file)
@@ -550,3 +550,20 @@ end:
 
        return ret;
 }
+
+bool knot_dnssec_has_adt(const zone_contents_t *zone)
+{
+       const knot_rdataset_t *dk = node_rdataset(zone->apex, KNOT_RRTYPE_DNSKEY);
+       if (dk == NULL) {
+               return false;
+       }
+       knot_rdata_t *rd = dk->rdata;
+       for (int i = 0; i < dk->count; i++) {
+               if ((knot_dnskey_flags(rd) & KNOT_DNSKEY_FLAG_ADT)) {
+                       return true;
+               }
+               rd = knot_rdataset_next(rd);
+       }
+
+       return false;
+}
index 6bad0b7169802d734d425a95e23720a12b7d71dc..8b0fa1222d022fc6a7a644d56a91b92b2f593016 100644 (file)
@@ -115,3 +115,8 @@ knot_time_t knot_dnssec_failover_delay(const kdnssec_ctx_t *ctx);
  * \return KNOT_E*
  */
 int knot_dnssec_validate_zone(zone_update_t *update, validation_conf_t *val_conf);
+
+/*!
+ * \brief Check if any DNSKEY in the apex has ADT bit set.
+ */
+bool knot_dnssec_has_adt(const zone_contents_t *zone);
index d49d2b0006f9a0a8cda9ac0d15383222905d2431..e7757f81f94219b89bcaf587d50adb6a9eb2d9bb 100644 (file)
@@ -741,7 +741,8 @@ knot_layer_state_t internet_process_query(knot_pkt_t *pkt, knotd_qdata_t *qdata)
 
        /* Get answer to QNAME. */
        qdata->name = knot_pkt_qname(qdata->query);
-       qdata->deleg_aware = ((qdata->extra->contents->nodes->flags & ZONE_TREE_CONTAINS_DELEG) && knot_pkt_has_deleg_aware(qdata->query));
+       qdata->deleg_aware = knot_pkt_has_deleg_aware(qdata->query) &&
+                            (qdata->extra->contents->nodes->flags & ZONE_TREE_DELEG_AWARE);
        if (qdata->deleg_aware) {
                knot_edns_set_de(&qdata->opt_rr);
        }
index ecaafcd758265c4a6f57f10b4716b3ebc01e2e84..931631e1e50c66bf5587fdcbe7b636dee5e36bfc 100644 (file)
@@ -1191,6 +1191,11 @@ int zone_update_commit(conf_t *conf, zone_update_t *update)
                return KNOT_EZONESIZE;
        }
 
+       if ((update->new_cont->nodes->flags & ZONE_TREE_CONTAINS_DELEG) &&
+           node_rrtype_exists(update->new_cont->apex, KNOT_RRTYPE_DNSKEY) && !knot_dnssec_has_adt(update->new_cont)) {
+               log_zone_warning(update->zone->name, "contains DELEG record but no DNSKEY with ADT bit");
+       }
+
        val = conf_zone_get(conf, C_DNSSEC_VALIDATION, update->zone->name);
        if (conf_bool(&val)) {
                validation_conf_t val_conf = {
index 26acfd6ac20577166dba724ed63ea0383e2fd65a..c4bbf09c73318404009831f22d02a6fd1e26d9b2 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "knot/zone/adjust.h"
 #include "knot/common/log.h"
+#include "knot/dnssec/zone-events.h"
 #include "knot/dnssec/zone-nsec.h"
 #include "knot/zone/adds_tree.h"
 #include "knot/zone/measure.h"
@@ -36,6 +37,10 @@ int adjust_cb_flags(zone_node_t *node, adjust_ctx_t *ctx)
 
        assert(!(node->flags & NODE_FLAGS_DELETED));
 
+       if (parent == NULL && knot_dnssec_has_adt(ctx->zone)) {
+                ctx->zone->nodes->flags |= ZONE_TREE_DELEG_AWARE;
+       }
+
        node->flags &= ~(NODE_FLAGS_DELEG | NODE_FLAGS_NONAUTH | NODE_FLAGS_SUBTREE_AUTH |
                         NODE_FLAGS_SUBTREE_DATA | NODE_FLAGS_NONAUTH_DELEG);
 
index 7e8cf2dc027608bc2dbfb26a38172f73791a36fa..6aa6def22b427e8127586a6f42cbc180121210d1 100644 (file)
@@ -14,8 +14,10 @@ enum {
        ZONE_TREE_USE_BINODES = (1 << 0),
        /*! If set, from each bi-node in the zone tree, the second zone_node_t is valid. */
        ZONE_TREE_BINO_SECOND = (1 << 1),
-       /*! Indication of presence of a DELEG record anywhere in the tree -- Knot only behaves as DELEG-aware if there is any. */
+       /*! Indication of presence of a DELEG record anywhere in the tree. */
        ZONE_TREE_CONTAINS_DELEG = (1 << 2),
+       /*! DELEG-awareness of the zone. */
+       ZONE_TREE_DELEG_AWARE    = (1 << 3),
 };
 
 typedef struct {