Browse Source

[3328] Added additional validation in D2ClientCfg

Added checks in D2ClientCfg to make user server and
sender ip values are the same family, and that
the server ip/port is not exactly the same as the
sender ip/port.
Thomas Markwalder 11 years ago
parent
commit
c1203657a7

+ 6 - 2
src/bin/dhcp4/tests/d2_unittest.cc

@@ -89,7 +89,8 @@ Dhcp4SrvD2Test::reset() {
 void
 Dhcp4SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
                             const std::string& ip_address,
-                            const uint32_t port) {
+                            const uint32_t port,
+                            const uint32_t sender_port) {
     std::ostringstream config;
     config <<
         "{ \"interfaces\": [ \"*\" ],"
@@ -102,6 +103,7 @@ Dhcp4SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
         "     \"enable-updates\" : " << (enable_d2 ? "true" : "false") <<  ", "
         "     \"server-ip\" : \"" << ip_address << "\", "
         "     \"server-port\" : " << port << ", "
+        "     \"sender-port\" : " << sender_port << ", "
         "     \"ncr-protocol\" : \"UDP\", "
         "     \"ncr-format\" : \"JSON\", "
         "     \"always-include-fqdn\" : true, "
@@ -293,7 +295,9 @@ TEST_F(Dhcp4SrvD2Test, forceUDPSendFailure) {
 
     // Configure it enabled and start it.
     // Using server address of 0.0.0.0/0 should induce failure on send.
-    ASSERT_NO_FATAL_FAILURE(configureD2(true, SHOULD_PASS, "0.0.0.0", 0));
+    // Pass in a non-zero sender port to avoid validation error when
+    // server-ip/port are same as sender-ip/port
+    ASSERT_NO_FATAL_FAILURE(configureD2(true, SHOULD_PASS, "0.0.0.0", 0, 53001));
     ASSERT_TRUE(mgr.ddnsEnabled());
     ASSERT_NO_THROW(srv_.startD2());
     ASSERT_TRUE(mgr.amSending());

+ 3 - 1
src/bin/dhcp4/tests/d2_unittest.h

@@ -79,9 +79,11 @@ public:
     /// @param exp_result indicates if configuration should pass or fail
     /// @param ip_address IP address for the D2 server
     /// @param port  port for the D2 server
+    /// @param sender_port NCR sender port
     void configureD2(bool enable_updates, bool exp_result = SHOULD_PASS,
                      const std::string& ip_address = "127.0.0.1",
-                     const uint32_t port = 53001);
+                     const uint32_t port = 53001,
+                     const uint32_t sender_port = 0);
 
     /// @brief Configures the server with the given configuration
     ///

+ 6 - 2
src/bin/dhcp6/tests/d2_unittest.cc

@@ -91,7 +91,8 @@ Dhcp6SrvD2Test::reset() {
 void
 Dhcp6SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
                             const std::string& ip_address,
-                            const uint32_t port) {
+                            const uint32_t port,
+                            const uint32_t sender_port) {
     std::ostringstream config;
     config <<
         "{ \"interfaces\": [ \"*\" ],"
@@ -106,6 +107,7 @@ Dhcp6SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
         "     \"enable-updates\" : " << (enable_d2 ? "true" : "false") <<  ", "
         "     \"server-ip\" : \"" << ip_address << "\", "
         "     \"server-port\" : " << port << ", "
+        "     \"sender-port\" : " << sender_port << ", "
         "     \"ncr-protocol\" : \"UDP\", "
         "     \"ncr-format\" : \"JSON\", "
         "     \"always-include-fqdn\" : true, "
@@ -297,7 +299,9 @@ TEST_F(Dhcp6SrvD2Test, forceUDPSendFailure) {
 
     // Configure it enabled and start it.
     // Using server address of 0.0.0.0/0 should induce failure on send.
-    ASSERT_NO_FATAL_FAILURE(configureD2(true, SHOULD_PASS, "0.0.0.0", 0));
+    // Pass in a non-zero sender port to avoid validation error when
+    // server-ip/port are same as sender-ip/port
+    ASSERT_NO_FATAL_FAILURE(configureD2(true, SHOULD_PASS, "0.0.0.0", 0, 53001));
     ASSERT_TRUE(mgr.ddnsEnabled());
     ASSERT_NO_THROW(srv_.startD2());
     ASSERT_TRUE(mgr.amSending());

+ 3 - 1
src/bin/dhcp6/tests/d2_unittest.h

@@ -79,9 +79,11 @@ public:
     /// @param exp_result indicates if configuration should pass or fail
     /// @param ip_address IP address for the D2 server
     /// @param port  port for the D2 server
+    /// @param sender_port NCR sender port
     void configureD2(bool enable_updates, bool exp_result = SHOULD_PASS,
                      const std::string& ip_address = "127.0.0.1",
-                     const uint32_t port = 53001);
+                     const uint32_t port = 53001,
+                     const uint32_t sender_port = 0);
 
     /// @brief Configures the server with the given configuration
     ///

+ 18 - 4
src/lib/dhcpsrv/d2_client_cfg.cc

@@ -73,8 +73,8 @@ D2ClientConfig::D2ClientConfig(const  bool enable_updates,
 
 D2ClientConfig::D2ClientConfig()
     : enable_updates_(false),
-      server_ip_(isc::asiolink::IOAddress("0.0.0.0")),
-      server_port_(0),
+      server_ip_(isc::asiolink::IOAddress(DFT_SERVER_IP)),
+      server_port_(DFT_SERVER_PORT),
       sender_ip_(isc::asiolink::IOAddress("0.0.0.0")),
       sender_port_(0),
       max_queue_size_(0),
@@ -106,8 +106,22 @@ D2ClientConfig::validateContents() {
 
     if (ncr_protocol_ != dhcp_ddns::NCR_UDP) {
         isc_throw(D2ClientError, "D2ClientConfig: NCR Protocol:"
-                    << dhcp_ddns::ncrProtocolToString(ncr_protocol_)
-                    << " is not yet supported");
+                  << dhcp_ddns::ncrProtocolToString(ncr_protocol_)
+                  << " is not yet supported");
+    }
+
+    if (sender_ip_.getFamily() != server_ip_.getFamily()) {
+        isc_throw(D2ClientError, "D2ClientConfig: address family mismatch: "
+                  << "server-ip: " << server_ip_.toText()
+                  << " is: " << (server_ip_.isV4() ? "IPv4" : "IPv6")
+                  << " while sender-ip: "  << sender_ip_.toText()
+                  << " is: " << (sender_ip_.isV4() ? "IPv4" : "IPv6"));
+    }
+
+    if (server_ip_ == sender_ip_ && server_port_ == sender_port_) {
+        isc_throw(D2ClientError, "D2ClientConfig: server and sender cannot"
+                  " share the exact same IP address/port: "
+                  << server_ip_.toText() << "/" << server_port_);
     }
 
     /// @todo perhaps more validation we should do yet?

+ 38 - 0
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

@@ -962,6 +962,44 @@ TEST_F(ParseConfigTest, invalidD2Config) {
         "     \"qualifying-suffix\" : \"test.suffix.\" "
         "    }"
         "}",
+        // Mismatched server and sender IPs
+        "{ \"dhcp-ddns\" :"
+        "    {"
+        "     \"enable-updates\" : true, "
+        "     \"server-ip\" : \"192.0.2.0\", "
+        "     \"server-port\" : 3432, "
+        "     \"sender-ip\" : \"3001::5\", "
+        "     \"sender-port\" : 3433, "
+        "     \"max-queue-size\" : 2048, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\", "
+        "     \"always-include-fqdn\" : true, "
+        "     \"override-no-update\" : true, "
+        "     \"override-client-update\" : true, "
+        "     \"replace-client-name\" : true, "
+        "     \"generated-prefix\" : \"test.prefix\", "
+        "     \"qualifying-suffix\" : \"test.suffix.\" "
+        "    }"
+        "}",
+        // Identical server and sender IP/port
+        "{ \"dhcp-ddns\" :"
+        "    {"
+        "     \"enable-updates\" : true, "
+        "     \"server-ip\" : \"3001::5\", "
+        "     \"server-port\" : 3433, "
+        "     \"sender-ip\" : \"3001::5\", "
+        "     \"sender-port\" : 3433, "
+        "     \"max-queue-size\" : 2048, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\", "
+        "     \"always-include-fqdn\" : true, "
+        "     \"override-no-update\" : true, "
+        "     \"override-client-update\" : true, "
+        "     \"replace-client-name\" : true, "
+        "     \"generated-prefix\" : \"test.prefix\", "
+        "     \"qualifying-suffix\" : \"test.suffix.\" "
+        "    }"
+        "}",
         // stop
         ""
     };