summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Salzman <daniel.salzman@nic.cz>2025-01-19 19:16:41 +0100
committerDaniel Salzman <daniel.salzman@nic.cz>2025-01-20 12:38:41 +0100
commit7c526754aec3001403d5621604a0ddf508c50445 (patch)
tree0960941faf1ea7e26a2470a3bca8e798b1d4dd4c /src
parentlibknot: add EDNS ZONEVERSION support (diff)
downloadknot-7c526754aec3001403d5621604a0ddf508c50445.tar.xz
knot-7c526754aec3001403d5621604a0ddf508c50445.zip
nameserver: add EDNS ZONEVERSION support
Diffstat (limited to 'src')
-rw-r--r--src/knot/nameserver/process_query.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/knot/nameserver/process_query.c b/src/knot/nameserver/process_query.c
index 2a3324dae..81625b82e 100644
--- a/src/knot/nameserver/process_query.c
+++ b/src/knot/nameserver/process_query.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
@@ -387,6 +387,33 @@ static int answer_edns_put(knot_pkt_t *resp, knotd_qdata_t *qdata)
}
}
+ /* Add ZONEVERSION if space and zone contents. */
+ uint8_t *zone_version = knot_pkt_edns_option(qdata->query, KNOT_EDNS_OPTION_ZONEVERSION);
+ if (zone_version != NULL) {
+ if (knot_edns_opt_get_length(zone_version) != 0) {
+ return KNOT_EMALF;
+ }
+ if (qdata->extra->contents != NULL &&
+ knot_pkt_reserve(resp, KNOT_EDNS_ZONEVERSION_LENGTH) == KNOT_EOK) {
+ ret = knot_pkt_reclaim(resp, KNOT_EDNS_ZONEVERSION_LENGTH);
+ assert(ret == KNOT_EOK);
+
+ uint8_t data[KNOT_EDNS_ZONEVERSION_LENGTH];
+ ret = knot_edns_zoneversion_write(data, sizeof(data),
+ KNOT_EDNS_ZONEVERSION_TYPE_SOA,
+ qdata->extra->zone->name,
+ zone_contents_serial(qdata->extra->contents));
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+ ret = knot_edns_add_option(&qdata->opt_rr, KNOT_EDNS_OPTION_ZONEVERSION,
+ sizeof(data), data, qdata->mm);
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+ }
+ }
+
/* Reclaim reserved OPT size. Should remain reserved space just for TSIG. */
ret = knot_pkt_reclaim(resp, opt_wire_size);
if (ret != KNOT_EOK) {