From: Piotrek Zadroga Date: Tue, 11 Apr 2023 18:46:46 +0000 (+0200) Subject: [#2536] Working on packing DNRv6 Option X-Git-Tag: Kea-2.3.8~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f44d63c36bcc1e49ad49666224b4dcae3686ff9b;p=thirdparty%2Fkea.git [#2536] Working on packing DNRv6 Option --- diff --git a/src/lib/dhcp/option_dnr.cc b/src/lib/dhcp/option_dnr.cc index ef6d762e4f..545026641f 100644 --- a/src/lib/dhcp/option_dnr.cc +++ b/src/lib/dhcp/option_dnr.cc @@ -11,6 +11,7 @@ #include #include #include +#include using namespace isc::asiolink; @@ -24,7 +25,7 @@ OptionDnr6::OptionDnr6(OptionBufferConstIter begin, OptionBufferConstIter end) OptionPtr OptionDnr6::clone() const { - return Option::clone(); + return (cloneInternal()); } void @@ -32,7 +33,46 @@ OptionDnr6::pack(util::OutputBuffer& buf, bool check) const { packHeader(buf, check); buf.writeUint16(service_priority_); - // TBD + buf.writeUint16(adn_length_); + packAdn(buf); + if (adn_only_mode_) { + return; + } + buf.writeUint16(addr_length_); + packAddresses(buf); + packSvcParams(buf); +} + +void +OptionDnr6::packAdn(util::OutputBuffer& buf) const { + if (!adn_) { + // This should not happen since Encrypted DNS options are designed + // to always include an authentication domain name. + return; + } + isc::dns::LabelSequence label_sequence(*adn_); + if (label_sequence.getDataLength() > 0) { + size_t data_length = 0; + const uint8_t* data = label_sequence.getData(&data_length); + buf.writeData(data, data_length); + } +} + +void +OptionDnr6::packAddresses(util::OutputBuffer& buf) const { + for (auto address = ipv6_addresses_.begin(); address != ipv6_addresses_.end(); ++address) { + if (!address->isV6()) { + isc_throw(isc::BadValue, address->toText() << " is not an IPv6 address"); + } + buf.writeData(&address->toBytes()[0], V6ADDRESS_LEN); + } +} + +void +OptionDnr6::packSvcParams(util::OutputBuffer& buf) const { + if (svc_params_length_ > 0) { + buf.writeData(&*svc_params_.begin(), svc_params_length_); + } } void @@ -100,7 +140,10 @@ OptionDnr6::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) { // SvcParams (variable length) field is last svc_params_length_ = std::distance(begin, end); - // TBD svcParams unpack + if (svc_params_length_ > 0) { + // for now let's keep SvcParams as binary data in buffer + svc_params_.assign(begin, end); + } } std::string diff --git a/src/lib/dhcp/option_dnr.h b/src/lib/dhcp/option_dnr.h index d95fa4a10c..ea4f70e27d 100644 --- a/src/lib/dhcp/option_dnr.h +++ b/src/lib/dhcp/option_dnr.h @@ -116,8 +116,18 @@ private: /// @brief Length of Service Parameters field in octets. uint16_t svc_params_length_ = 0; + /// @brief Flag stating whether ADN only mode is used or not. + /// + /// "Addr Length", "ipv6-address(es)", and "Service Parameters (SvcParams)" + /// fields are not present if the ADN-only mode is used. bool adn_only_mode_ = true; + /// @brief Service Parameters (SvcParams) (variable length). + /// + /// Specifies a set of service parameters that are encoded + /// following the rules in Section 2.1 of [I-D.ietf-dnsop-svcb-https]. + std::vector svc_params_; + /// @brief Returns minimal length of the option data (without headers) in octets. /// /// If the ADN-only mode is used, then "Addr Length", "ipv6-address(es)", @@ -129,6 +139,12 @@ private: static uint8_t getMinimalLength() { return SERVICE_PRIORITY_SIZE + ADN_LENGTH_SIZE; }; + + void packAdn(isc::util::OutputBuffer& buf) const; + + void packAddresses(isc::util::OutputBuffer& buf) const; + + void packSvcParams(isc::util::OutputBuffer& buf) const; }; class OptionDnr4 : public Option { diff --git a/src/lib/dhcp/tests/option_dnr_unittest.cc b/src/lib/dhcp/tests/option_dnr_unittest.cc index d7d2a8603b..b405d011a5 100644 --- a/src/lib/dhcp/tests/option_dnr_unittest.cc +++ b/src/lib/dhcp/tests/option_dnr_unittest.cc @@ -190,8 +190,7 @@ TEST(OptionDnr6Test, validIpV6Addresses) { 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ff02::face:b00c 0x00, 0x00, 0x00, 0x00, 0xfa, 0xce, 0xb0, 0x0c, - // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };