diff options
author | Daniel Salzman <daniel.salzman@nic.cz> | 2025-01-19 19:16:41 +0100 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2025-01-20 12:38:41 +0100 |
commit | 7c526754aec3001403d5621604a0ddf508c50445 (patch) | |
tree | 0960941faf1ea7e26a2470a3bca8e798b1d4dd4c /src | |
parent | libknot: add EDNS ZONEVERSION support (diff) | |
download | knot-7c526754aec3001403d5621604a0ddf508c50445.tar.xz knot-7c526754aec3001403d5621604a0ddf508c50445.zip |
nameserver: add EDNS ZONEVERSION support
Diffstat (limited to 'src')
-rw-r--r-- | src/knot/nameserver/process_query.c | 29 |
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) { |