From 6c9387a9385dea83447a093b35f97e5fcfd39a5d Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Thu, 2 Oct 2025 15:25:49 -0400 Subject: [PATCH] [#4142] dhcpsrv and v4 UTs modified: src/bin/dhcp4/tests/fqdn_unittest.cc modified: src/lib/dhcpsrv/tests/d2_client_unittest.cc --- src/bin/dhcp4/tests/fqdn_unittest.cc | 60 ++++++++++++++++++++- src/lib/dhcpsrv/tests/d2_client_unittest.cc | 40 ++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/bin/dhcp4/tests/fqdn_unittest.cc b/src/bin/dhcp4/tests/fqdn_unittest.cc index a5d3e4c21a..4bb5dc18d4 100644 --- a/src/bin/dhcp4/tests/fqdn_unittest.cc +++ b/src/bin/dhcp4/tests/fqdn_unittest.cc @@ -2253,7 +2253,7 @@ TEST_F(NameDhcpv4SrvTest, sanitizeHostDefault) { }, { "qualified host name with nuls", - std::string("four-ok-host\000.other.org",23), + std::string("four-ok-host\000.other.org", 23), "four-ok-host.other.org" } }; @@ -3203,4 +3203,62 @@ TEST_F(NameDhcpv4SrvTest, poolDdnsParametersTest) { } } +// Verifies that when the FQDN option is scrubbed empty it is logged +// and ignored. +TEST_F(NameDhcpv4SrvTest, hostnameScrubbedEmpty) { + Dhcp4Client client(srv_, Dhcp4Client::SELECTING); + + // Configure DHCP server. + configure(CONFIGS[2], *client.getServer()); + + // Set the hostname option. + ASSERT_NO_THROW(client.includeHostname("___")); + + // Send the DHCPDISCOVER and make sure that the server responded. + ASSERT_NO_THROW(client.doDiscover()); + auto resp = client.getContext().response_; + ASSERT_TRUE(resp); + ASSERT_EQ(DHCPOFFER, static_cast(resp->getType())); + + // Should have logged that it was scrubbed empty. + std::string log = "DHCP4_CLIENT_HOSTNAME_SCRUBBED_EMPTY" + " [hwtype=1 67:c6:69:73:51:ff], cid=[no info], tid=0x0:" + " sanitiziing client's Hostname option '___'" + " yielded an empty string"; + EXPECT_EQ(1, countFile(log)); + + // Hostname should not be in the response. + ASSERT_FALSE(resp->getOption(DHO_HOST_NAME)); +} + +// Verifies that when the FQDN option is scrubbed empty it is logged +// and ignored. +TEST_F(NameDhcpv4SrvTest, fqdnScrubbedEmpty) { + Dhcp4Client client(srv_, Dhcp4Client::SELECTING); + + // Configure DHCP server. + configure(CONFIGS[2], *client.getServer()); + + // Include the Client FQDN option. + ASSERT_NO_THROW(client.includeFQDN(Option4ClientFqdn::FLAG_S | Option4ClientFqdn::FLAG_E, + "___", Option4ClientFqdn::PARTIAL)); + + // Send the DHCPDISCOVER and make sure that the server responded. + ASSERT_NO_THROW(client.doDiscover()); + auto resp = client.getContext().response_; + ASSERT_TRUE(resp); + ASSERT_EQ(DHCPOFFER, static_cast(resp->getType())); + + // Should have logged that it was scrubbed empty. + std::string log = "DHCP4_CLIENT_FQDN_SCRUBBED_EMPTY" + " [hwtype=1 67:c6:69:73:51:ff], cid=[no info], tid=0x0:" + " sanitiziing client's FQDN option '___'" + " yielded an empty string"; + EXPECT_EQ(1, countFile(log)); + + // Hostname should not be in the response. + ASSERT_FALSE(resp->getOption(DHO_FQDN)); +} + + } // end of anonymous namespace diff --git a/src/lib/dhcpsrv/tests/d2_client_unittest.cc b/src/lib/dhcpsrv/tests/d2_client_unittest.cc index 68ad2189d6..520acbbb88 100644 --- a/src/lib/dhcpsrv/tests/d2_client_unittest.cc +++ b/src/lib/dhcpsrv/tests/d2_client_unittest.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -1257,4 +1258,43 @@ TEST_F(D2ClientMgrParamsTest, sanitizeFqdnV6) { } } +/// @brief Tests adjustDomainName template method with Option4ClientFqdn +/// when sanitizing scrubs input name empty. +TEST_F(D2ClientMgrParamsTest, adjustDomainNameV4ScrubbedEmpty) { + D2ClientMgr mgr; + + // Create enabled configuration + subnet_->setDdnsSendUpdates(false); + subnet_->setDdnsQualifyingSuffix("suffix.com"); + subnet_->setHostnameCharSet("[^A-Za-z0-9.-]"); + subnet_->setHostnameCharReplacement(""); + + Option4ClientFqdn request(0, Option4ClientFqdn::RCODE_CLIENT(), + "___", Option4ClientFqdn::FULL); + + Option4ClientFqdn response(request); + ASSERT_THROW_MSG(mgr.adjustDomainName(request, response, *ddns_params_), + FQDNScrubbedEmpty, "___."); +} + +/// @brief Tests adjustDomainName template method with Option4ClientFqdn +/// when sanitizing scrubs input name empty. +TEST_F(D2ClientMgrParamsTest, adjustDomainNameV6ScrubbedEmpty) { + D2ClientMgr mgr; + + // Create enabled configuration + subnet_->setDdnsSendUpdates(false); + subnet_->setDdnsQualifyingSuffix("suffix.com"); + subnet_->setHostnameCharSet("[^A-Za-z0-9.-]"); + subnet_->setHostnameCharReplacement(""); + + Option6ClientFqdn request(0, "___", Option6ClientFqdn::FULL); + + Option6ClientFqdn response(request); + ASSERT_THROW_MSG(mgr.adjustDomainName(request, response, *ddns_params_), + FQDNScrubbedEmpty, "___."); +} + + + } // end of anonymous namespace -- 2.47.3