]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2536] Implementing DNRv6 Option with TDD
authorPiotrek Zadroga <piotrek@isc.org>
Fri, 7 Apr 2023 15:38:25 +0000 (17:38 +0200)
committerPiotrek Zadroga <piotrek@isc.org>
Thu, 4 May 2023 21:17:18 +0000 (23:17 +0200)
src/lib/dhcp/option_dnr.cc
src/lib/dhcp/option_dnr.h
src/lib/dhcp/tests/option_dnr_unittest.cc

index 83fe76fef190dd871f07a0564aed1b91e8e2e72c..ef6d762e4f696ecfb272e13dcb25b6e2fee497a7 100644 (file)
@@ -75,6 +75,7 @@ OptionDnr6::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
         // ADN only mode, other fields are not included.
         return;
     }
+    adn_only_mode_ = false;
     if (std::distance(begin, end) < ADDR_LENGTH_SIZE) {
         isc_throw(OutOfRange, "DHCPv6 Encrypted DNS Option (" << type_ << ") malformed: after"
                               " ADN field, there should be at least "
@@ -99,6 +100,7 @@ OptionDnr6::unpack(OptionBufferConstIter begin, OptionBufferConstIter end) {
 
     // SvcParams (variable length) field is last
     svc_params_length_ = std::distance(begin, end);
+    // TBD svcParams unpack
 }
 
 std::string
@@ -108,15 +110,18 @@ OptionDnr6::toText(int indent) const {
 
 uint16_t
 OptionDnr6::len() const {
-    return Option::len();
+    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_);
 }
 
 std::string
 OptionDnr6::getAdn() const {
     if (adn_) {
-        return adn_->toText();
+        return (adn_->toText());
     }
-    return "";
+    return ("");
 }
 
 OptionDnr4::OptionDnr4() : Option(V4, DHO_V4_DNR) {
index a1b3e2896b1699353c0ec53dbcf175fbbbccf558..d95fa4a10c5cd4838b06141b98c89d37fc1c5c76 100644 (file)
@@ -47,14 +47,14 @@ public:
     ///
     /// @return The priority of this OPTION_V6_DNR instance compared to other instances.
     uint16_t getServicePriority() const {
-        return service_priority_;
+        return (service_priority_);
     }
 
     /// @brief Getter of the @c adn_length_
     ///
     /// @return Length of the authentication-domain-name data in octets.
     uint16_t getAdnLength() const {
-        return adn_length_;
+        return (adn_length_);
     }
 
     /// @brief Returns the Authentication domain name in the text format.
@@ -68,14 +68,14 @@ public:
     ///
     /// @return  Length of enclosed IPv6 addresses in octets.
     uint16_t getAddrLength() const {
-        return addr_length_;
+        return (addr_length_);
     }
 
     /// @brief Getter of the @c svc_params_length_
     ///
     /// @return Length of Service Parameters field in octets.
     uint16_t getSvcParamsLength() const {
-        return svc_params_length_;
+        return (svc_params_length_);
     }
 
     /// @brief Returns vector with addresses.
@@ -87,7 +87,7 @@ public:
     ///
     /// @return address container with addresses
     AddressContainer getAddresses() const {
-        return ipv6_addresses_;
+        return (ipv6_addresses_);
     }
 
 private:
@@ -116,6 +116,8 @@ private:
     /// @brief Length of Service Parameters field in octets.
     uint16_t svc_params_length_ = 0;
 
+    bool adn_only_mode_ = true;
+
     /// @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)",
index e8d69cd1c5bd5ef1a99c08add32d75c0b44c4bba..d7d2a8603b72615966e44926af207facf54706d8 100644 (file)
@@ -49,6 +49,7 @@ TEST(OptionDnr6Test, constructorAdnOnlyMode) {
     EXPECT_EQ("myhost.example.com.", option->getAdn());
     EXPECT_EQ(0, option->getAddrLength());
     EXPECT_EQ(0, option->getSvcParamsLength());
+    EXPECT_EQ(28, option->len());
 }
 
 TEST(OptionDnr6Test, constructorDataTruncated) {
@@ -155,6 +156,7 @@ TEST(OptionDnr6Test, addrLenZero) {
     EXPECT_EQ("myhost.example.com.", option->getAdn());
     EXPECT_EQ(0, option->getAddrLength());
     EXPECT_EQ(0, option->getSvcParamsLength());
+    EXPECT_EQ(30, option->len());
 }
 
 TEST(OptionDnr6Test, addrLenNot16Modulo) {
@@ -214,6 +216,43 @@ TEST(OptionDnr6Test, validIpV6Addresses) {
     EXPECT_EQ("ff02::face:b00c", addresses[1].toText());
     EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", addresses[2].toText());
     EXPECT_EQ(0, option->getSvcParamsLength());
+    EXPECT_EQ(78, option->len());
+}
+
+TEST(OptionDnr6Test, svcParamsIncluded) {
+    // Prepare data to decode
+    const uint8_t buf_data[] = {
+        0x80, 0x01,                                      // Service priority is 32769 dec
+        0x00, 0x14,                                      // ADN Length is 20 dec
+        0x06, 0x4D, 0x79, 0x68, 0x6F, 0x73, 0x74,        // FQDN: Myhost.
+        0x07, 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65,  // Example.
+        0x03, 0x43, 0x6F, 0x6D, 0x00,                    // Com.
+        0x00, 0x10,                                      // Addr Len field value = 48 dec
+        0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,  // 2001:db8:1::dead:beef
+        0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef,
+        0xff, 0xff                                       // example SvcParams data
+    };
+
+    OptionBuffer buf(buf_data, buf_data + sizeof(buf_data));
+    // Create option instance. Check that constructor doesn't throw.
+    scoped_ptr<OptionDnr6> option;
+    EXPECT_NO_THROW(option.reset(new OptionDnr6(buf.begin(), buf.end())));
+    ASSERT_TRUE(option);
+
+    // Check if member variables were correctly set by ctor.
+    EXPECT_EQ(Option::V6, option->getUniverse());
+    EXPECT_EQ(D6O_V6_DNR, option->getType());
+
+    // Check if data was unpacked correctly from wire data.
+    EXPECT_EQ(0x8001, option->getServicePriority());
+    EXPECT_EQ(20, option->getAdnLength());
+    EXPECT_EQ("myhost.example.com.", option->getAdn());
+    EXPECT_EQ(16, option->getAddrLength());
+    const OptionDnr6::AddressContainer& addresses = option->getAddresses();
+    EXPECT_EQ(1, addresses.size());
+    EXPECT_EQ("2001:db8:1::dead:beef", addresses[0].toText());
+    EXPECT_EQ(2, option->getSvcParamsLength());
+    EXPECT_EQ(48, option->len());
 }
 
 }  // namespace
\ No newline at end of file