From: Piotrek Zadroga Date: Wed, 12 Apr 2023 15:32:38 +0000 (+0200) Subject: [#2536] Adding some docs for DNRv6 Option X-Git-Tag: Kea-2.3.8~181 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9ccdca02dc35fd0ef6db7db4510504060fe33ef;p=thirdparty%2Fkea.git [#2536] Adding some docs for DNRv6 Option --- diff --git a/src/lib/dhcp/option_dnr.cc b/src/lib/dhcp/option_dnr.cc index 545026641f..0ed9d6c047 100644 --- a/src/lib/dhcp/option_dnr.cc +++ b/src/lib/dhcp/option_dnr.cc @@ -95,8 +95,8 @@ OptionDnr6::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) { // Encrypted DNS options are designed to always include an authentication domain name, // so when there is no FQDN included, we shall throw an exception. if (adn_length_ == 0) { - isc_throw(InvalidOptionDnr6DomainName, "Mandatory Authentication Domain Name fully " - "qualified domain-name is missing"); + isc_throw(InvalidOptionDnrDomainName, "Mandatory Authentication Domain Name fully " + "qualified domain-name is missing"); } // Let's try to extract ADN FQDN data. @@ -104,9 +104,9 @@ OptionDnr6::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) { try { adn_.reset(new isc::dns::Name(name_buf, true)); } catch (const Exception& ex) { - isc_throw(InvalidOptionDnr6DomainName, "failed to parse " - "fully qualified domain-name from wire format " - "- " << ex.what()); + isc_throw(InvalidOptionDnrDomainName, "failed to parse " + "fully qualified domain-name from wire format " + "- " << ex.what()); } begin += adn_tuple.getTotalLength(); @@ -153,10 +153,11 @@ OptionDnr6::toText(int indent) const { uint16_t OptionDnr6::len() const { - return adn_only_mode_ ? - (OPTION6_HDR_LEN + SERVICE_PRIORITY_SIZE + adn_length_ + ADN_LENGTH_SIZE) : - (OPTION6_HDR_LEN + SERVICE_PRIORITY_SIZE + adn_length_ + ADN_LENGTH_SIZE + - addr_length_ + ADDR_LENGTH_SIZE + svc_params_length_); + uint16_t len = OPTION6_HDR_LEN + SERVICE_PRIORITY_SIZE + adn_length_ + ADN_LENGTH_SIZE; + if (!adn_only_mode_) { + len += addr_length_ + ADDR_LENGTH_SIZE + svc_params_length_; + } + return (len); } std::string diff --git a/src/lib/dhcp/option_dnr.h b/src/lib/dhcp/option_dnr.h index ea4f70e27d..54a46556bf 100644 --- a/src/lib/dhcp/option_dnr.h +++ b/src/lib/dhcp/option_dnr.h @@ -15,42 +15,63 @@ namespace isc { namespace dhcp { /// @brief Exception thrown when invalid domain name is specified. -class InvalidOptionDnr6DomainName : public Exception { +class InvalidOptionDnrDomainName : public Exception { public: - InvalidOptionDnr6DomainName(const char* file, size_t line, const char* what) + InvalidOptionDnrDomainName(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { } }; +/// @brief Represents DHCPv6 Encrypted DNS %Option (code 144). +/// +/// This option has been defined in the draft-ietf-add-dnr-15 (to be replaced +/// with published RFC) and it has a following structure: +/// - option-code = 144 (2 octets) +/// - option-len (2 octets) +/// - Service Priority (2 octets) +/// - ADN Length (2 octets) +/// - Authentication Domain Name (variable length) +/// - Addr Length (2 octets) +/// - IPv6 Address(es) (variable length) +/// - Service Parameters (variable length). class OptionDnr6 : public Option { public: - /// a container for (IPv6) addresses + /// @brief A container for (IPv6) addresses. typedef std::vector AddressContainer; - /// @brief Size in octets of Service Priority field + /// @brief Size in octets of Service Priority field. static const uint8_t SERVICE_PRIORITY_SIZE = 2; - /// @brief Size in octets of ADN Length field + /// @brief Size in octets of ADN Length field. static const uint8_t ADN_LENGTH_SIZE = 2; - /// @brief Size in octets of Addr Length field + /// @brief Size in octets of Addr Length field. static const uint8_t ADDR_LENGTH_SIZE = 2; + /// @brief Constructor of the %Option from on-wire data. + /// + /// This constructor creates an instance of the option using a buffer with + /// on-wire data. It may throw an exception if the @c unpack method throws. + /// + /// @param begin Iterator pointing to the beginning of the buffer holding an + /// option. + /// @param end Iterator pointing to the end of the buffer holding an option. OptionDnr6(OptionBufferConstIter begin, OptionBufferConstIter end); + virtual OptionPtr clone() const; virtual void pack(util::OutputBuffer& buf, bool check) const; virtual void unpack(OptionBufferConstIter begin, OptionBufferConstIter end); virtual std::string toText(int indent) const; virtual uint16_t len() const; - /// @brief Getter of the @c service_priority_ + /// @brief Getter of the @c service_priority_. /// /// @return The priority of this OPTION_V6_DNR instance compared to other instances. uint16_t getServicePriority() const { return (service_priority_); } - /// @brief Getter of the @c adn_length_ + /// @brief Getter of the @c adn_length_. /// /// @return Length of the authentication-domain-name data in octets. uint16_t getAdnLength() const { @@ -64,14 +85,14 @@ public: /// @return Authentication domain name in the text format. std::string getAdn() const; - /// @brief Getter of the @c addr_length_ + /// @brief Getter of the @c addr_length_. /// /// @return Length of enclosed IPv6 addresses in octets. uint16_t getAddrLength() const { return (addr_length_); } - /// @brief Getter of the @c svc_params_length_ + /// @brief Getter of the @c svc_params_length_. /// /// @return Length of Service Parameters field in octets. uint16_t getSvcParamsLength() const { @@ -85,12 +106,12 @@ public: /// is no longer available. As options are expected to hold only /// a few (1-3) addresses, the overhead is not that big. /// - /// @return address container with addresses + /// @return Address container with addresses. AddressContainer getAddresses() const { return (ipv6_addresses_); } -private: +protected: /// @brief The priority of this OPTION_V6_DNR instance compared to other instances. uint16_t service_priority_; @@ -107,7 +128,7 @@ private: /// @brief Length of enclosed IPv6 addresses in octets. uint16_t addr_length_ = 0; - /// @brief Vector container holding one or more IPv6 addresses + /// @brief Vector container holding one or more IPv6 addresses. /// /// One or more IPv6 addresses to reach the encrypted DNS resolver. /// An address can be link-local, ULA, or GUA. @@ -128,6 +149,7 @@ private: /// following the rules in Section 2.1 of [I-D.ietf-dnsop-svcb-https]. std::vector svc_params_; +private: /// @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)", @@ -137,13 +159,31 @@ private: /// /// @return Minimal length of the option data (without headers) in octets. static uint8_t getMinimalLength() { - return SERVICE_PRIORITY_SIZE + ADN_LENGTH_SIZE; + return (SERVICE_PRIORITY_SIZE + ADN_LENGTH_SIZE); }; + /// @brief Writes the ADN FQDN in the wire format into a buffer. + /// + /// The Authentication Domain Name - fully qualified domain name of the encrypted + /// DNS resolver data is appended at the end of the buffer. + /// + /// @param [out] buf buffer where ADN FQDN will be written. void packAdn(isc::util::OutputBuffer& buf) const; + /// @brief Writes the IPv6 address(es) in the wire format into a buffer. + /// + /// The IPv6 address(es) (@c ipv6_addresses_) data is appended at the end + /// of the buffer. + /// + /// @param [out] buf buffer where IPv6 address(es) will be written. void packAddresses(isc::util::OutputBuffer& buf) const; + /// @brief Writes the Service Parameters in the wire format into a buffer. + /// + /// The Service Parameters (@c svc_params_) data is appended at the end + /// of the buffer. + /// + /// @param [out] buf buffer where SvcParams will be written. void packSvcParams(isc::util::OutputBuffer& buf) const; }; diff --git a/src/lib/dhcp/tests/option_dnr_unittest.cc b/src/lib/dhcp/tests/option_dnr_unittest.cc index b405d011a5..dc3d4e96a1 100644 --- a/src/lib/dhcp/tests/option_dnr_unittest.cc +++ b/src/lib/dhcp/tests/option_dnr_unittest.cc @@ -74,9 +74,9 @@ TEST(OptionDnr6Test, onlyWhitespaceFqdn) { }; OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); - // Create option instance. Check that constructor throws InvalidOptionDnr6DomainName exception. + // Create option instance. Check that constructor throws InvalidOptionDnrDomainName exception. scoped_ptr option; - EXPECT_THROW(option.reset(new OptionDnr6(buf.begin(), buf.end())), InvalidOptionDnr6DomainName); + EXPECT_THROW(option.reset(new OptionDnr6(buf.begin(), buf.end())), InvalidOptionDnrDomainName); ASSERT_FALSE(option); } @@ -90,9 +90,9 @@ TEST(OptionDnr6Test, noAdnFqdn) { OptionBuffer buf(buf_data, buf_data + sizeof(buf_data)); // Create option instance. Encrypted DNS options are designed to ALWAYS include // an authentication domain name, so check that constructor throws - // InvalidOptionDnr6DomainName exception. + // InvalidOptionDnrDomainName exception. scoped_ptr option; - EXPECT_THROW(option.reset(new OptionDnr6(buf.begin(), buf.end())), InvalidOptionDnr6DomainName); + EXPECT_THROW(option.reset(new OptionDnr6(buf.begin(), buf.end())), InvalidOptionDnrDomainName); ASSERT_FALSE(option); }