summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniel Salzman <daniel.salzman@nic.cz>2025-01-18 19:07:49 +0100
committerDaniel Salzman <daniel.salzman@nic.cz>2025-01-20 12:38:41 +0100
commit0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2 (patch)
tree56bd4dcc5066b76468898327fa651c4e6f563653 /src
parentdoc: update network adapters in XDP pre-requisities (diff)
downloadknot-0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2.tar.xz
knot-0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2.zip
libknot: add EDNS ZONEVERSION support
Diffstat (limited to 'src')
-rw-r--r--src/libknot/codes.c3
-rw-r--r--src/libknot/rrset-dump.c5
-rw-r--r--src/libknot/rrtype/opt.c52
-rw-r--r--src/libknot/rrtype/opt.h46
4 files changed, 98 insertions, 8 deletions
diff --git a/src/libknot/codes.c b/src/libknot/codes.c
index b0b78faa6..cece38a85 100644
--- a/src/libknot/codes.c
+++ b/src/libknot/codes.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
@@ -142,5 +142,6 @@ const knot_lookup_t knot_edns_opt_names[] = {
{ KNOT_EDNS_OPTION_PADDING, "PADDING" },
{ KNOT_EDNS_OPTION_CHAIN, "CHAIN" },
{ KNOT_EDNS_OPTION_EDE, "EDE" },
+ { KNOT_EDNS_OPTION_ZONEVERSION, "ZONEVERSION" },
{ 0, NULL }
};
diff --git a/src/libknot/rrset-dump.c b/src/libknot/rrset-dump.c
index 9fac99dc6..f1f5b3762 100644
--- a/src/libknot/rrset-dump.c
+++ b/src/libknot/rrset-dump.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
@@ -1172,6 +1172,9 @@ static void wire_ednsoptval_to_str(rrset_dump_params_t *p, uint16_t opt, uint16_
CHECK_PRET
wire_text_to_str(p, len - sizeof(uint16_t), "", true, false);
break;
+ case KNOT_EDNS_OPTION_ZONEVERSION:
+ wire_data_to_hex(p, len); // not fully implemented, don't know QNAME
+ break;
default:
assert(0); // this should be handled in wire_ednsopt_to_str() by generic OPT##=hex
break;
diff --git a/src/libknot/rrtype/opt.c b/src/libknot/rrtype/opt.c
index 294689c2d..ebdf836b0 100644
--- a/src/libknot/rrtype/opt.c
+++ b/src/libknot/rrtype/opt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -685,3 +685,53 @@ int knot_edns_cookie_parse(knot_edns_cookie_t *cc, knot_edns_cookie_t *sc,
return KNOT_EOK;
}
+
+_public_
+int knot_edns_zoneversion_parse(knot_dname_storage_t zone, uint8_t *type,
+ uint32_t *version, const uint8_t *option,
+ uint16_t option_len, const knot_dname_t *qname)
+{
+ if (zone == NULL || type == NULL || version == NULL || option == NULL ||
+ qname == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ if (option_len == 0) {
+ return KNOT_ENOENT;
+ } else if (option_len != KNOT_EDNS_ZONEVERSION_LENGTH) {
+ return KNOT_EMALF;
+ }
+
+ wire_ctx_t wire = wire_ctx_init_const(option, option_len);
+ uint8_t labels = wire_ctx_read_u8(&wire);
+ *type = wire_ctx_read_u8(&wire);
+ *version = wire_ctx_read_u32(&wire);
+
+ size_t qname_labels = knot_dname_labels(qname, NULL);
+ if (labels > qname_labels) {
+ return KNOT_EMALF;
+ }
+ size_t prefix_size = knot_dname_prefixlen(qname, qname_labels - labels);
+ size_t qname_size = knot_dname_size(qname);
+ memcpy(zone, qname + prefix_size, qname_size - prefix_size);
+
+ return wire.error;
+}
+
+_public_
+int knot_edns_zoneversion_write(uint8_t *option, uint16_t option_len, uint8_t type,
+ const knot_dname_t *zone, uint32_t version)
+{
+ if (option == NULL || zone == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ size_t labels = knot_dname_labels(zone, NULL);
+
+ wire_ctx_t wire = wire_ctx_init(option, option_len);
+ wire_ctx_write_u8(&wire, labels);
+ wire_ctx_write_u8(&wire, type);
+ wire_ctx_write_u32(&wire, version);
+
+ return wire.error;
+}
diff --git a/src/libknot/rrtype/opt.h b/src/libknot/rrtype/opt.h
index bce87c20c..48285ed4a 100644
--- a/src/libknot/rrtype/opt.h
+++ b/src/libknot/rrtype/opt.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2022 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
@@ -71,6 +71,14 @@ enum {
/*! \brief EDNS maximum server cookie size. */
KNOT_EDNS_COOKIE_SRVR_MAX_SIZE = 32,
+ /*! \brief The minimal length for EDE option including option header. */
+ KNOT_EDNS_EDE_MIN_LENGTH = 6,
+
+ /*! \brief The SOA serial version type. */
+ KNOT_EDNS_ZONEVERSION_TYPE_SOA = 0,
+ /*! \brief The length of ZONEVERSION in a response. */
+ KNOT_EDNS_ZONEVERSION_LENGTH = 6,
+
/*! \brief NSID option code. */
KNOT_EDNS_OPTION_NSID = 3,
/*! \brief EDNS Client subnet option code. */
@@ -85,14 +93,13 @@ enum {
KNOT_EDNS_OPTION_PADDING = 12,
/*! \brief EDNS Chain query option code. */
KNOT_EDNS_OPTION_CHAIN = 13,
-
/*! \brief EDNS Extended error code. */
KNOT_EDNS_OPTION_EDE = 15,
- /*! \brief The minimal length for EDE option including option header. */
- KNOT_EDNS_EDE_MIN_LENGTH = 6,
+ /*! \brief EDNS Zone version option code. */
+ KNOT_EDNS_OPTION_ZONEVERSION = 19,
/*! \brief Maximal currently known option code. */
- KNOT_EDNS_MAX_OPTION_CODE = 17,
+ KNOT_EDNS_MAX_OPTION_CODE = 19,
};
/* Helpers for splitting extended RCODE. */
@@ -584,4 +591,33 @@ int knot_edns_cookie_write(uint8_t *option, uint16_t option_len,
int knot_edns_cookie_parse(knot_edns_cookie_t *cc, knot_edns_cookie_t *sc,
const uint8_t *option, uint16_t option_len);
+/*!
+ * \brief Writes EDNS Zone version wire data.
+ *
+ * \param[out] option EDNS option data buffer.
+ * \param[in] option_len EDNS option data buffer size.
+ * \param[in] type The version type.
+ * \param[in] zone Zone name.
+ * \param[in] version The zone version.
+ *
+ * \return Error code, KNOT_EOK if successful or KNOT_ENOENT if no data.
+ */
+int knot_edns_zoneversion_write(uint8_t *option, uint16_t option_len, uint8_t type,
+ const knot_dname_t *zone, uint32_t version);
+
+/*!
+ * \brief Parses EDNS Zone version wire data.
+ *
+ * \param[out] labels The QNAME labels.
+ * \param[out] type The version type.
+ * \param[out] version The zone version.
+ * \param[in] option EDNS option data.
+ * \param[in] option_len EDNS option size.
+ *
+ * \return Error code, KNOT_EOK if successful.
+ */
+int knot_edns_zoneversion_parse(knot_dname_storage_t zone, uint8_t *type,
+ uint32_t *version, const uint8_t *option,
+ uint16_t option_len, const knot_dname_t *qname);
+
/*! @} */