From: Marcin Siodelski Date: Mon, 10 Feb 2014 10:32:27 +0000 (+0100) Subject: [master] Merge branch 'trac3242' X-Git-Tag: bind10-1.2.0beta1-release~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9e571cc217d6b1a2fd6fdae1565fcc6fde6d08b1;p=thirdparty%2Fkea.git [master] Merge branch 'trac3242' Conflicts: src/bin/dhcp4/tests/fqdn_unittest.cc --- 9e571cc217d6b1a2fd6fdae1565fcc6fde6d08b1 diff --cc src/bin/dhcp4/tests/fqdn_unittest.cc index e17a7e3ac6,1c318f16c9..f1cb7b002b --- a/src/bin/dhcp4/tests/fqdn_unittest.cc +++ b/src/bin/dhcp4/tests/fqdn_unittest.cc @@@ -16,9 -16,9 +16,10 @@@ #include #include #include + #include #include #include +#include #include #include @@@ -31,21 -31,11 +32,20 @@@ using namespace isc::dhcp_ddns namespace { - class NameDhcpv4SrvTest : public Dhcpv4SrvFakeIfaceTest { + class NameDhcpv4SrvTest : public Dhcpv4SrvTest { public: - + // Bit Constants for turning on and off DDNS configuration options. + static const uint16_t ALWAYS_INCLUDE_FQDN = 1; + static const uint16_t OVERRIDE_NO_UPDATE = 2; + static const uint16_t OVERRIDE_CLIENT_UPDATE = 4; + static const uint16_t REPLACE_CLIENT_NAME = 8; + - NameDhcpv4SrvTest() : Dhcpv4SrvFakeIfaceTest() { + NameDhcpv4SrvTest() : Dhcpv4SrvTest() { srv_ = new NakedDhcpv4Srv(0); + // Config DDNS to be enabled, all controls off + enableD2(); } + virtual ~NameDhcpv4SrvTest() { delete srv_; } @@@ -343,50 -288,6 +343,54 @@@ srv_->name_change_reqs_.pop(); } + + /// @brief Tests processing a request with the given client flags + /// + /// This method creates a request with its FQDN flags set to the given + /// value and submits it to the server for processing. It then checks + /// the following: + /// 1. Did the server generate an ACK with the correct FQDN flags + /// 2. If the server should have generated an NCR, did it? and If + /// so was it correct? + /// + /// @param client_flags Mask of client FQDN flags which are true + /// @param response_flags Mask of expected FQDN flags in the response + void flagVsConfigScenario(const uint8_t client_flags, + const uint8_t response_flags) { ++ // Create fake interfaces and open fake sockets. ++ IfaceMgrTestConfig iface_config(true); ++ IfaceMgr::instance().openSockets4(); ++ + Pkt4Ptr req = generatePktWithFqdn(DHCPREQUEST, client_flags, + "myhost.example.com.", + Option4ClientFqdn::FULL, true); + + // Process the request. + Pkt4Ptr reply; + ASSERT_NO_THROW(reply = srv_->processRequest(req)); + + // Verify the response and flags. + checkResponse(reply, DHCPACK, 1234); + checkFqdnFlags(reply, response_flags); + + // There should be an NCR only if response S flag is 1. + /// @todo This logic will need to change if forward and reverse + /// updates are ever controlled independently. + if ((response_flags & Option4ClientFqdn::FLAG_S) == 0) { + ASSERT_EQ(0, srv_->name_change_reqs_.size()); + } else { + // Verify that there is one NameChangeRequest generated as expected. + ASSERT_EQ(1, srv_->name_change_reqs_.size()); + verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true, + reply->getYiaddr().toText(), + "myhost.example.com.", + "", // empty DHCID means don't check it + time(NULL) + subnet_->getValid(), + subnet_->getValid(), true); + } + } + + NakedDhcpv4Srv* srv_; }; @@@ -763,30 -618,6 +773,34 @@@ TEST_F(NameDhcpv4SrvTest, processReques subnet_->getValid(), true); } +// Test that server generates client's hostname from the IP address assigned +// to it when DHCPv4 Client FQDN option specifies an empty domain-name AND +// ddns updates are disabled. +TEST_F(NameDhcpv4SrvTest, processRequestEmptyDomainNameDisabled) { ++ // Create fake interfaces and open fake sockets. ++ IfaceMgrTestConfig test_config(true); ++ IfaceMgr::instance().openSockets4(); ++ + disableD2(); + Pkt4Ptr req = generatePktWithFqdn(DHCPREQUEST, Option4ClientFqdn::FLAG_S | + Option4ClientFqdn::FLAG_E, + "", Option4ClientFqdn::PARTIAL, true); + Pkt4Ptr reply; + ASSERT_NO_THROW(reply = srv_->processRequest(req)); + + checkResponse(reply, DHCPACK, 1234); + + Option4ClientFqdnPtr fqdn = getClientFqdnOption(reply); + ASSERT_TRUE(fqdn); + + // The hostname is generated from the IP address acquired (yiaddr). + std::string hostname = generatedNameFromAddress(reply->getYiaddr()); + + EXPECT_EQ(hostname, fqdn->getDomainName()); + EXPECT_EQ(Option4ClientFqdn::FULL, fqdn->getDomainNameType()); +} + + // Test that server generates client's hostname from the IP address assigned // to it when Hostname option carries the top level domain-name. TEST_F(NameDhcpv4SrvTest, processRequestEmptyHostname) { @@@ -919,14 -758,13 +942,17 @@@ TEST_F(NameDhcpv4SrvTest, processTwoReq time(NULL), subnet_->getValid(), true); } -// Test that when the Release message is sent for the previously acquired -// lease, then server genenerates a NameChangeRequest to remove the entries -// corresponding to the lease being released. +// Test that when a release message is sent for a previously acquired lease, +// DDNS updates are enabled that the server genenerates a NameChangeRequest +// to remove entries corresponding to the released lease. TEST_F(NameDhcpv4SrvTest, processRequestRelease) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + // Verify the updates are enabled. + ASSERT_TRUE(CfgMgr::instance().ddnsEnabled()); + + // Create and process a lease request so we have a lease to release. Pkt4Ptr req = generatePktWithFqdn(DHCPREQUEST, Option4ClientFqdn::FLAG_S | Option4ClientFqdn::FLAG_E, "myhost.example.com.", @@@ -954,46 -795,6 +980,50 @@@ // The lease has been removed, so there should be a NameChangeRequest to // remove corresponding DNS entries. ASSERT_EQ(1, srv_->name_change_reqs_.size()); + verifyNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, true, true, + reply->getYiaddr().toText(), "myhost.example.com.", + "00010132E91AA355CFBB753C0F0497A5A940436" + "965B68B6D438D98E680BF10B09F3BCF", + time(NULL), subnet_->getValid(), true); +} + +// Test that when the Release message is sent for a previously acquired lease +// and DDNS updates are disabled that server does NOT generate a +// NameChangeRequest to remove entries corresponding to the released lease. +TEST_F(NameDhcpv4SrvTest, processRequestReleaseUpdatesDisabled) { ++ // Create fake interfaces and open fake sockets. ++ IfaceMgrTestConfig test_config(true); ++ IfaceMgr::instance().openSockets4(); ++ + // Disable DDNS. + disableD2(); + ASSERT_FALSE(CfgMgr::instance().ddnsEnabled()); + + // Create and process a lease request so we have a lease to release. + Pkt4Ptr req = generatePktWithFqdn(DHCPREQUEST, Option4ClientFqdn::FLAG_S | + Option4ClientFqdn::FLAG_E, + "myhost.example.com.", + Option4ClientFqdn::FULL, true); + Pkt4Ptr reply; + ASSERT_NO_THROW(reply = srv_->processRequest(req)); + checkResponse(reply, DHCPACK, 1234); + + // With DDNS updates disabled, there should be not be a NameChangeRequest + // for the add. + ASSERT_EQ(0, srv_->name_change_reqs_.size()); + + // Create and process the Release message. + Pkt4Ptr rel = Pkt4Ptr(new Pkt4(DHCPRELEASE, 1234)); + rel->setCiaddr(reply->getYiaddr()); + rel->setRemoteAddr(IOAddress("192.0.2.3")); + rel->addOption(generateClientId()); + rel->addOption(srv_->getServerID()); + ASSERT_NO_THROW(srv_->processRelease(rel)); + + // With DDNS updates disabled, there should be not be a NameChangeRequest + // for the remove. + ASSERT_EQ(0, srv_->name_change_reqs_.size()); } + } // end of anonymous namespace