]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3289] Added v6 part
authorFrancis Dupont <fdupont@isc.org>
Sat, 6 Apr 2024 22:03:01 +0000 (00:03 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sat, 6 Apr 2024 22:03:01 +0000 (00:03 +0200)
ChangeLog
doc/sphinx/arm/dhcp6-srv.rst
src/lib/dhcp/option6_client_fqdn.cc
src/lib/dhcp/tests/option6_client_fqdn_unittest.cc

index d63eb3a33e60b4323c40fa5072053407402bc3b8..f362c674fe367f4ae855fd943314d661ae870db6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,8 @@
 2217.  [func]          fdupont
        Extended the lenient-option-parsing compatibility
-       flag to ignore DHCPv4 fqdn (81) option with some
-       invalid domain names (e.g. beginning with an empty label).
+       flag to ignore DHCPv4 fqdn (81) and DHCPv6 client-fqdn
+       (39) options with some invalid domain names (e.g.
+       beginning with an empty label).
        (Gitlab 3289)
 
 2216.  [func]          tmark
index f2f64de053c125031b6668acbc97d228d02a4f9d..14ee63a6daa6273e02f02b6a9274a299900ee2eb 100644 (file)
@@ -7996,6 +7996,9 @@ MiNID.
       }
     }
 
+Starting with Kea version 2.5.8 this is extended to silently ignore
+client-fqdn (39) options with some invalid domain names.
+
 .. _dhcp6_allocation_strategies:
 
 Allocation Strategies in DHCPv6
index 9aa9c13a6791308532fa0a8b988207b9f967074a..bc754f5e3f2b31da140d78bb59e082760c2d8568 100644 (file)
@@ -243,8 +243,13 @@ Option6ClientFqdnImpl::parseWireData(OptionBufferConstIter first,
             try {
                 domain_name_.reset(new isc::dns::Name(name_buf, true));
             } catch (const Exception&) {
-                isc_throw(InvalidOption6FqdnDomainName, "failed to parse "
-                          "partial domain-name from wire format");
+                if (Option::lenient_parsing_) {
+                    isc_throw(SkipThisOptionError, "failed to parse "
+                              "partial domain-name from wire format");
+                } else {
+                    isc_throw(InvalidOption6FqdnDomainName, "failed to parse "
+                              "partial domain-name from wire format");
+                }
             }
             // Terminating zero was missing, so set the domain-name type
             // to partial.
@@ -258,8 +263,13 @@ Option6ClientFqdnImpl::parseWireData(OptionBufferConstIter first,
             try {
                 domain_name_.reset(new isc::dns::Name(name_buf, true));
             } catch (const Exception&) {
-                isc_throw(InvalidOption6FqdnDomainName, "failed to parse "
-                          "fully qualified domain-name from wire format");
+                if (Option::lenient_parsing_) {
+                    isc_throw(SkipThisOptionError, "failed to parse "
+                              "fully qualified domain-name from wire format");
+                } else {
+                    isc_throw(InvalidOption6FqdnDomainName, "failed to parse "
+                              "fully qualified domain-name from wire format");
+                }
             }
             // Set the domain-type to fully qualified domain name.
             domain_name_type_ = Option6ClientFqdn::FULL;
index c2934899ccb379ed6498a0342673b45d6dee3709..2eadd6b7ee9c53505fd744933fbaa0c138a2c90b 100644 (file)
@@ -16,6 +16,18 @@ namespace {
 using namespace isc;
 using namespace isc::dhcp;
 
+// RAII device to make sure that lenient parsing flag is reset to false on exit.
+class LenientOptionParsing {
+public:
+    LenientOptionParsing(bool value) {
+        Option::lenient_parsing_ = value;
+    }
+
+    ~LenientOptionParsing() {
+        Option::lenient_parsing_ = false;
+    }
+};
+
 // This test verifies that constructor accepts empty partial domain-name but
 // does not accept empty fully qualified domain name.
 TEST(Option6ClientFqdnTest, constructEmptyName) {
@@ -173,10 +185,14 @@ TEST(Option6ClientFqdnTest, constructFromWireTooLongLabel) {
     OptionBuffer in_buf(Option6ClientFqdn::FLAG_S);
     in_buf.push_back(70);
     in_buf.insert(in_buf.end(), 70, 109);
-    in_buf.push_back(0);
+    // Don't add a 0 i.e. use a partial name (vs fully qualified).
 
+    LenientOptionParsing(false);
     EXPECT_THROW(Option6ClientFqdn(in_buf.begin(), in_buf.end()),
                  InvalidOption6FqdnDomainName);
+    Option::lenient_parsing_ = true;
+    EXPECT_THROW(Option6ClientFqdn(in_buf.begin(), in_buf.end()),
+                 SkipThisOptionError);
 }
 
 // Verify that exception is thrown if the overall length of the domain-name
@@ -193,8 +209,12 @@ TEST(Option6ClientFqdnTest, constructFromWireTooLongDomainName) {
     // Terminate FQDN with a dot.
     in_buf.push_back(0);
 
+    LenientOptionParsing(false);
     EXPECT_THROW(Option6ClientFqdn(in_buf.begin(), in_buf.end()),
                  InvalidOption6FqdnDomainName);
+    Option::lenient_parsing_ = true;
+    EXPECT_THROW(Option6ClientFqdn(in_buf.begin(), in_buf.end()),
+                 SkipThisOptionError);
 }
 
 // This test verifies that truncated option is rejected.
@@ -403,6 +423,8 @@ TEST(Option6ClientFqdnTest, constructInvalidName) {
     ASSERT_NO_THROW(Option6ClientFqdn(0, "myhost.example.com"));
 
     // Specify invalid domain name and expect that exception is thrown.
+    // Note in v6 the domain name is always encoded so this is not
+    // covered by lenient-option-parsing.
     EXPECT_THROW(Option6ClientFqdn(0, "my...host.example.com"),
                  InvalidOption6FqdnDomainName);
 }