summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcp/option4_dnr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcp/option4_dnr.h')
-rw-r--r--src/lib/dhcp/option4_dnr.h146
1 files changed, 131 insertions, 15 deletions
diff --git a/src/lib/dhcp/option4_dnr.h b/src/lib/dhcp/option4_dnr.h
index 3062f69c23..ae8e43c620 100644
--- a/src/lib/dhcp/option4_dnr.h
+++ b/src/lib/dhcp/option4_dnr.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2023 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2023 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -14,6 +14,8 @@
#include <dhcp/option_data_types.h>
#include <dns/name.h>
+#include <unordered_set>
+
namespace isc {
namespace dhcp {
@@ -53,10 +55,17 @@ public:
/// @brief Size in octets of Service Priority field.
static const uint8_t SERVICE_PRIORITY_SIZE = 2;
+ /// @brief Set of forbidden SvcParams.
+ ///
+ /// The service parameters MUST NOT include
+ /// "ipv4hint" or "ipv6hint" SvcParams as they are superseded by the
+ /// included IP addresses.
+ static const std::unordered_set<std::string> FORBIDDEN_SVC_PARAMS;
+
/// @brief Constructor of the empty DNR Instance.
///
/// @param universe either V4 or V6 Option universe
- explicit DnrInstance(Option::Universe universe) : universe_(universe) {}
+ explicit DnrInstance(Option::Universe universe);
/// @brief Constructor of the DNR Instance with all fields from params.
///
@@ -157,27 +166,32 @@ public:
/// @brief Returns minimal length of the DNR instance data (without headers) in octets.
///
- /// If the ADN-only mode is used, then "Addr Length", "ip(v4/v6)-address(es)",
- /// and "Service Parameters (SvcParams)" fields are not present.
- /// So minimal length of data is calculated by adding 2 octets for Service Priority,
- /// octets needed for ADN Length and octets needed for DNR Instance Data Length
- /// (only in case of DHCPv4).
- ///
/// @return Minimal length of the DNR instance data (without headers) in octets.
- uint8_t getMinimalLength() const;
+ uint8_t getMinimalLength() const {
+ return (minimal_length_);
+ }
/// @brief Returns size in octets of Addr Length field.
- uint8_t getAddrLengthSize() const;
+ uint8_t getAddrLengthSize() const {
+ return (addr_length_size_);
+ }
/// @brief Returns size in octets of DNR Instance Data Length field.
- uint8_t getDnrInstanceDataLengthSize() const;
+ uint8_t getDnrInstanceDataLengthSize() const {
+ return (dnr_instance_data_length_size_);
+ }
/// @brief Returns size in octets of ADN Length field.
- uint8_t getAdnLengthSize() const;
+ uint8_t getAdnLengthSize() const {
+ return (adn_length_size_);
+ }
- /// @brief Constructs Log prefix depending on V4/V6 Option universe.
+ /// @brief Returns Log prefix depending on V4/V6 Option universe.
+ ///
/// @return Log prefix as a string which can be used for prints when throwing an exception.
- std::string getLogPrefix() const;
+ std::string getLogPrefix() const {
+ return (log_prefix_);
+ }
/// @brief Returns whether ADN only mode is enabled or disabled.
bool isAdnOnlyMode() const {
@@ -192,9 +206,13 @@ public:
/// It also calculates and sets value of Addr length field.
///
/// @param adn string representation of ADN FQDN
+ ///
+ /// @throw InvalidOptionDnrDomainName Thrown in case of any issue with parsing ADN
+ /// from given string.
void setAdn(const std::string& adn);
/// @brief Setter of the @c adn_only_mode_ field.
+ ///
/// @param adn_only_mode enabled/disabled setting
void setAdnOnlyMode(bool adn_only_mode) {
adn_only_mode_ = adn_only_mode;
@@ -206,6 +224,8 @@ public:
/// DNS resolver data is appended at the end of the buffer.
///
/// @param [out] buf buffer where ADN FQDN will be written.
+ ///
+ /// @throw InvalidOptionDnrDomainName Thrown when mandatory field ADN is empty.
void packAdn(isc::util::OutputBuffer& buf) const;
/// @brief Writes the IP address(es) in the wire format into a buffer.
@@ -231,9 +251,12 @@ public:
///
/// @param begin beginning of the buffer from which the field will be read
/// @param end end of the buffer from which the field will be read
+ ///
+ /// @throw OutOfRange Thrown in case of truncated data detected.
void unpackDnrInstanceDataLength(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks Service Priority from wire data buffer and stores it in @c service_priority_.
+ ///
/// @param begin beginning of the buffer from which the field will be read
void unpackServicePriority(OptionBufferConstIter& begin);
@@ -243,6 +266,10 @@ public:
///
/// @param begin beginning of the buffer from which the ADN will be read
/// @param end end of the buffer from which the ADN will be read
+ ///
+ /// @throw BadValue Thrown in case of any issue with unpacking opaque data of the ADN.
+ /// @throw InvalidOptionDnrDomainName Thrown in case of any issue with parsing ADN
+ /// from given wire data.
void unpackAdn(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks IP address(es) from wire data and stores it/them in @c ip_addresses_.
@@ -251,6 +278,10 @@ public:
///
/// @param begin beginning of the buffer from which the field will be read
/// @param end end of the buffer from which the field will be read
+ ///
+ /// @throw BadValue Thrown in case of any issue with unpacking opaque data of the IP addresses.
+ /// @throw OutOfRange Thrown in case of malformed data detected during parsing e.g.
+ /// Addr Len not divisible by 4, Addr Len is 0.
virtual void unpackAddresses(OptionBufferConstIter& begin, OptionBufferConstIter end);
/// @brief Unpacks Service Parameters from wire data buffer and stores it in @c svc_params_.
@@ -264,15 +295,33 @@ public:
/// @brief Checks SvcParams field if encoded correctly and throws in case of issue found.
///
/// The field should be encoded following the rules in
- /// Section 2.1 of [I-D.ietf-dnsop-svcb-https].
+ /// Section 2.1 of [I-D.ietf-dnsop-svcb-https]. SvcParams are
+ /// a whitespace-separated list, with each SvcParam consisting of
+ /// a SvcParamKey=SvcParamValue pair or a standalone SvcParamKey.
+ ///
+ /// @note It is user's responsibility to provide correct configuration
+ /// of @c SvcParams as described in Section 2.1 of [I-D.ietf-dnsop-svcb-https].
+ /// Currently, SvcParamValue is not verified. Proper syntax of SvcParamValue
+ /// is described in Appendix A of [I-D.ietf-dnsop-svcb-https].
+ ///
+ /// @param from_wire_data used to determine whether SvcParams data comes
+ /// from unpacked wire data or from ctor param
+ ///
+ /// @throw InvalidOptionDnrSvcParams Thrown in case of any issue found when checking
+ /// @c ServiceParams field syntax
void checkSvcParams(bool from_wire_data = true);
/// @brief Checks IP address(es) field if data is correct and throws in case of issue found.
///
/// Fields lengths are also calculated and saved to member variables.
+ ///
+ /// @throw OutOfRange Thrown in case of no IP addresses found or when IP addresses length
+ /// is too big
+ /// @throw InvalidOptionDnrSvcParams Thrown when @c checkSvcParams(from_wire_data) throws
void checkFields();
/// @brief Adds IP address to @c ip_addresses_ container.
+ ///
/// @param ip_address IP address to be added
void addIpAddress(const asiolink::IOAddress& ip_address);
@@ -327,6 +376,35 @@ protected:
/// @brief Calculates and returns length of DNR Instance data in octets.
/// @return length of DNR Instance data in octets.
uint16_t dnrInstanceLen() const;
+
+private:
+ /// @brief Size in octets of DNR Instance Data Length field.
+ ///
+ /// @note This field is used only in case of V4 DNR option.
+ uint8_t dnr_instance_data_length_size_;
+
+ /// @brief Size in octets of ADN Length field.
+ uint8_t adn_length_size_;
+
+ /// @brief Size in octets of Addr Length field.
+ uint8_t addr_length_size_;
+
+ /// @brief Minimal length of the DNR instance data (without headers) in octets.
+ ///
+ /// @note If the ADN-only mode is used, then "Addr Length", "ip(v4/v6)-address(es)",
+ /// and "Service Parameters (SvcParams)" fields are not present.
+ /// So minimal length of data is calculated by adding 2 octets for Service Priority,
+ /// octets needed for ADN Length and octets needed for DNR Instance Data Length
+ /// (only in case of DHCPv4).
+ uint8_t minimal_length_;
+
+ /// @brief Log prefix as a string which can be used for prints when throwing an exception.
+ std::string log_prefix_;
+
+ /// @brief Initializes private member variables basing on option's V4/V6 Universe.
+ ///
+ /// @note It must be called in all types of constructors of class @c DnrInstance .
+ void initMembers();
};
/// @brief Represents DHCPv4 Encrypted DNS %Option (code 162).
@@ -378,10 +456,48 @@ public:
return (dnr_instances_);
}
+ /// @brief Copies this option and returns a pointer to the copy.
+ ///
+ /// @return Pointer to the copy of the option.
OptionPtr clone() const override;
+
+ /// @brief Writes option in wire-format to a buffer.
+ ///
+ /// Writes option in wire-format to buffer, returns pointer to first unused
+ /// byte after stored option (that is useful for writing options one after
+ /// another).
+ ///
+ /// @param buf pointer to a buffer
+ /// @param check flag which indicates if checking the option length is
+ /// required (used only in V4)
+ ///
+ /// @throw InvalidOptionDnrDomainName Thrown when Option's mandatory field ADN is empty.
+ /// @throw OutOfRange Thrown when @c check param set to @c true and
+ /// @c Option::packHeader(buf,check) throws.
void pack(util::OutputBuffer& buf, bool check = true) const override;
+
+ /// @brief Parses received wire data buffer.
+ ///
+ /// @param begin iterator to first byte of option data
+ /// @param end iterator to end of option data (first byte after option end)
+ ///
+ /// @throw OutOfRange Thrown in case of truncated data. May be also thrown when
+ /// @c DnrInstance::unpackDnrInstanceDataLength(begin,end) throws.
+ /// @throw BadValue Thrown when @c DnrInstance::unpackAdn(begin,end) throws.
+ /// @throw InvalidOptionDnrDomainName Thrown when @c DnrInstance::unpackAdn(begin,end) throws.
void unpack(OptionBufferConstIter begin, OptionBufferConstIter end) override;
+
+ /// @brief Returns string representation of the option.
+ ///
+ /// @param indent number of spaces before printing text
+ ///
+ /// @return string with text representation.
std::string toText(int indent = 0) const override;
+
+ /// @brief Returns length of the complete option (data length + DHCPv4/DHCPv6
+ /// option header)
+ ///
+ /// @return length of the option
uint16_t len() const override;
protected: