Browse Source

[master] Merge branch 'trac3779'

Thomas Markwalder 10 years ago
parent
commit
f318b7e799
2 changed files with 128 additions and 6 deletions
  1. 7 4
      src/bin/dhcp4/dhcp4_srv.cc
  2. 121 2
      src/bin/dhcp4/tests/fqdn_unittest.cc

+ 7 - 4
src/bin/dhcp4/dhcp4_srv.cc

@@ -1233,10 +1233,13 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) {
             // any potential exceptions (e.g. invalid lease database backend
             // implementation) and log an error.
             try {
-                // The lease update should be safe, because the lease should
-                // be already in the database. In most cases the exception
-                // would be thrown if the lease was missing.
-                LeaseMgrFactory::instance().updateLease4(lease);
+                if (!fake_allocation) {
+                    // The lease update should be safe, because the lease should
+                    // be already in the database. In most cases the exception
+                    // would be thrown if the lease was missing.
+                    LeaseMgrFactory::instance().updateLease4(lease);
+                }
+
                 // The name update in the option should be also safe,
                 // because the generated name is well formed.
                 if (fqdn) {

+ 121 - 2
src/bin/dhcp4/tests/fqdn_unittest.cc

@@ -90,6 +90,38 @@ const char* CONFIGS[] = {
             "\"enable-updates\": true,"
             "\"qualifying-suffix\": \"fake-suffix.isc.org.\""
         "}"
+    "}",
+    // Simple config with DDNS updates disabled.  Note pool is one address
+    // large to ensure we get a specific address back.
+    "{ \"interfaces-config\": {"
+        "      \"interfaces\": [ \"*\" ]"
+        "},"
+        "\"valid-lifetime\": 3000,"
+        "\"subnet4\": [ { "
+        "    \"subnet\": \"10.0.0.0/24\", "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.10\" } ]"
+        " }],"
+        "\"dhcp-ddns\": {"
+            "\"enable-updates\": false,"
+            "\"qualifying-suffix\": \"fake-suffix.isc.org.\""
+        "}"
+    "}",
+    // Simple config with DDNS updates enabled.  Note pool is one address
+    // large to ensure we get a specific address back.
+    "{ \"interfaces-config\": {"
+        "      \"interfaces\": [ \"*\" ]"
+        "},"
+        "\"valid-lifetime\": 3000,"
+        "\"subnet4\": [ { "
+        "    \"subnet\": \"10.0.0.0/24\", "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.10\" } ]"
+        " }],"
+        "\"dhcp-ddns\": {"
+            "\"enable-updates\": true,"
+            "\"qualifying-suffix\": \"fake-suffix.isc.org.\""
+        "}"
     "}"
 };
 
@@ -1129,7 +1161,7 @@ TEST_F(NameDhcpv4SrvTest, fqdnReservation) {
                                 "0D280858B1ED7696E174C4479E3372",
                                 time(NULL), subnet_->getValid(), true);
     }
-    
+
     // And that this FQDN has been stored in the lease database.
     Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(client.config_.lease_.addr_);
     ASSERT_TRUE(lease);
@@ -1211,7 +1243,7 @@ TEST_F(NameDhcpv4SrvTest, hostnameReservation) {
 
     // Obtain the Hostname option sent in the response and make sure that the server
     // has used the hostname reserved for this client.
-    OptionStringPtr hostname; 
+    OptionStringPtr hostname;
     hostname = boost::dynamic_pointer_cast<OptionString>(resp->getOption(DHO_HOST_NAME));
     ASSERT_TRUE(hostname);
     EXPECT_EQ("unique-host.example.org", hostname->getValue());
@@ -1298,5 +1330,92 @@ TEST_F(NameDhcpv4SrvTest, hostnameReservation) {
     }
 }
 
+// Test verifies that the server properly generates a FQDN when the client
+// FQDN name is blank, whether or not DDNS updates are enabled.  It also
+// verifies that the lease is only in the database following a DHCPREQUEST and
+// that the lesae contains the generated FQDN.
+TEST_F(NameDhcpv4SrvTest, emptyFqdn) {
+    Dhcp4Client client(Dhcp4Client::SELECTING);
+    isc::asiolink::IOAddress expected_address("10.0.0.10");
+    std::string expected_fqdn("myhost-10-0-0-10.fake-suffix.isc.org.");
+
+    // Load a configuration with DDNS updates disabled
+    configure(CONFIGS[2], *client.getServer());
+    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
+
+    // Include the Client FQDN option.
+    ASSERT_NO_THROW(client.includeFQDN((Option4ClientFqdn::FLAG_S
+                                        | Option4ClientFqdn::FLAG_E),
+                                       "", Option4ClientFqdn::PARTIAL));
+
+    // Send the DHCPDISCOVER
+    ASSERT_NO_THROW(client.doDiscover());
+
+    // Make sure that the server responded.
+    Pkt4Ptr resp = client.getContext().response_;
+    ASSERT_TRUE(resp);
+    ASSERT_EQ(DHCPOFFER, static_cast<int>(resp->getType()));
+
+    // Make sure the response FQDN has the generated name and FQDN flags are
+    // correct for updated disabled.
+    Option4ClientFqdnPtr fqdn;
+    fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(DHO_FQDN));
+    ASSERT_TRUE(fqdn);
+    EXPECT_EQ(expected_fqdn, fqdn->getDomainName());
+    checkFqdnFlags(resp, (Option4ClientFqdn::FLAG_N |
+                          Option4ClientFqdn::FLAG_E |
+                          Option4ClientFqdn::FLAG_O));
+
+    // Make sure the lease is NOT in the database.
+    Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(IOAddress(expected_address));
+    ASSERT_FALSE(lease);
+
+    // Now test with updates enabled
+    configure(CONFIGS[3], *client.getServer());
+    ASSERT_TRUE(CfgMgr::instance().ddnsEnabled());
+    ASSERT_NO_THROW(client.getServer()->startD2());
+
+    // Send the DHCPDISCOVER
+    ASSERT_NO_THROW(client.doDiscover());
+
+    // Make sure that the server responded.
+    resp = client.getContext().response_;
+    ASSERT_TRUE(resp);
+    ASSERT_EQ(DHCPOFFER, static_cast<int>(resp->getType()));
+
+    // Make sure the response FQDN has the generated name and FQDN flags are
+    // correct for updates enabled.
+    fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(DHO_FQDN));
+    ASSERT_TRUE(fqdn);
+    EXPECT_EQ(expected_fqdn, fqdn->getDomainName());
+    checkFqdnFlags(resp, (Option4ClientFqdn::FLAG_E |
+                          Option4ClientFqdn::FLAG_S));
+
+    // Make sure the lease is NOT in the database.
+    lease = LeaseMgrFactory::instance().getLease4(IOAddress(expected_address));
+    ASSERT_FALSE(lease);
+
+    // Do a DORA and verify that the lease exists and the name is correct.
+    ASSERT_NO_THROW(client.doDORA());
+
+    // Make sure that the server responded.
+    resp = client.getContext().response_;
+    ASSERT_TRUE(resp);
+    ASSERT_EQ(DHCPACK, static_cast<int>(resp->getType()));
+
+    // Make sure the response FQDN has the generated name and FQDN flags are
+    // correct for updates enabled.
+    fqdn = boost::dynamic_pointer_cast<Option4ClientFqdn>(resp->getOption(DHO_FQDN));
+    ASSERT_TRUE(fqdn);
+    EXPECT_EQ(expected_fqdn, fqdn->getDomainName());
+    checkFqdnFlags(resp, (Option4ClientFqdn::FLAG_E |
+                          Option4ClientFqdn::FLAG_S));
+
+    // Make sure the lease is in the database and hostname is correct.
+    lease = LeaseMgrFactory::instance().getLease4(IOAddress(expected_address));
+    ASSERT_TRUE(lease);
+    EXPECT_EQ(expected_fqdn, lease->hostname_);
+
+}
 
 } // end of anonymous namespace