diff options
author | Daniel Salzman <daniel.salzman@nic.cz> | 2025-01-18 19:07:49 +0100 |
---|---|---|
committer | Daniel Salzman <daniel.salzman@nic.cz> | 2025-01-20 12:38:41 +0100 |
commit | 0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2 (patch) | |
tree | 56bd4dcc5066b76468898327fa651c4e6f563653 /src | |
parent | doc: update network adapters in XDP pre-requisities (diff) | |
download | knot-0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2.tar.xz knot-0f34c44d3f14c6efab0d67d6e8f4e7e36a48a8b2.zip |
libknot: add EDNS ZONEVERSION support
Diffstat (limited to 'src')
-rw-r--r-- | src/libknot/codes.c | 3 | ||||
-rw-r--r-- | src/libknot/rrset-dump.c | 5 | ||||
-rw-r--r-- | src/libknot/rrtype/opt.c | 52 | ||||
-rw-r--r-- | src/libknot/rrtype/opt.h | 46 |
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); + /*! @} */ |