]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2011] Checkpoint: added code and updated tests
authorFrancis Dupont <fdupont@isc.org>
Tue, 3 Aug 2021 18:23:24 +0000 (20:23 +0200)
committerFrancis Dupont <fdupont@isc.org>
Mon, 9 Aug 2021 15:08:24 +0000 (17:08 +0200)
src/bin/d2/nc_trans.cc
src/bin/d2/tests/d2_simple_parser_unittest.cc
src/bin/d2/tests/nc_test_utils.cc
src/bin/d2/tests/nc_test_utils.h
src/bin/d2/tests/nc_trans_unittests.cc
src/bin/d2/tests/testdata/d2_cfg_tests.json
src/lib/d2srv/d2_config.cc
src/lib/d2srv/d2_config.h
src/lib/d2srv/d2_simple_parser.cc

index 371d8a90fde0049cf93ef8f2e652020b38cfe7cf..2321ee72e90d2a0e70c724d3011cbf6bab1cb47c 100644 (file)
@@ -430,14 +430,6 @@ NameChangeTransaction::initServerSelection(const DdnsDomainPtr& domain) {
                   "initServerSelection called with an empty domain");
     }
 
-    // Set the tsig_key to that of the DdnsDomain.
-    TSIGKeyInfoPtr tsig_key_info = domain->getTSIGKeyInfo();
-    if (tsig_key_info) {
-        tsig_key_ = tsig_key_info->getTSIGKey();
-    } else {
-        tsig_key_.reset();
-    }
-
     current_server_list_ = domain->getServers();
     next_server_pos_ = 0;
     current_server_.reset();
@@ -451,6 +443,14 @@ NameChangeTransaction::selectNextServer() {
         // Toss out any previous response.
         dns_update_response_.reset();
 
+        // Set the tsig_key to that of the current server..
+        TSIGKeyInfoPtr tsig_key_info = current_server_->getTSIGKeyInfo();
+        if (tsig_key_info) {
+            tsig_key_ = tsig_key_info->getTSIGKey();
+        } else {
+            tsig_key_.reset();
+        }
+
         // @todo  Protocol is set on DNSClient constructor.  We need
         // to propagate a configuration value downward, probably starting
         // at global, then domain, then server
index d792808d2d83e5eaa662720284fb14bdda25af16..57777ec3f31e7cba71b1f0019f63aa8a172b29da 100644 (file)
@@ -425,7 +425,8 @@ public:
     /// @param config element to parse
     virtual void parseElement(data::ConstElementPtr config) {
         DnsServerInfoParser parser;
-        server_ = parser.parse(config);
+        std::string domain = "{ \"key-name\": \"\" }";
+        server_ = parser.parse(config, Element::fromJSON(domain), {});
     }
 
     /// @brief Retains the DnsServerInfo created by a successful parsing
@@ -470,7 +471,8 @@ public:
     /// @param config element to parse
     virtual void parseElement(data::ConstElementPtr config) {
         DnsServerInfoListParser parser;
-        servers_ = parser.parse(config);
+        std::string domain = "{ \"key-name\": \"\" }";
+        servers_ = parser.parse(config, Element::fromJSON(domain), {});
     }
 
     /// @brief Retains the DnsServerInfos created by a successful parsing
@@ -977,7 +979,7 @@ TEST_F(DdnsDomainParserTest, invalidDomain) {
              "  \"dns-servers\" : [ "
              "  {  \"ip-address\": \"127.0.0.3\" , "
              "    \"port\": 300 } ] } ";
-    PARSE_FAIL(config, "DdnsDomain : example.com specifies"
+    PARSE_FAIL(config, "DdnsDomain : specifies"
                 " an undefined key: d2_key.example.com (<string>:1:41)");
 }
 
@@ -1006,30 +1008,34 @@ TEST_F(DdnsDomainParserTest, validDomain) {
     // Verify the name and key_name values.
     EXPECT_EQ("example.com", domain_->getName());
     EXPECT_EQ("d2_key.example.com", domain_->getKeyName());
-    ASSERT_TRUE(domain_->getTSIGKeyInfo());
-    ASSERT_TRUE(domain_->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify that the server list exists and contains the correct number of
     // servers.
     const DnsServerInfoStoragePtr& servers = domain_->getServers();
-    EXPECT_TRUE(servers);
+    ASSERT_TRUE(servers);
     EXPECT_EQ(3, servers->size());
 
     // Fetch each server and verify its contents.
     DnsServerInfoPtr server = (*servers)[0];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
 
     EXPECT_TRUE(checkServer(server, "", "127.0.0.1", 100));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     server = (*servers)[1];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
 
     EXPECT_TRUE(checkServer(server, "", "127.0.0.2", 200));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     server = (*servers)[2];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
 
     EXPECT_TRUE(checkServer(server, "", "127.0.0.3", 300));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify unparsing.
     ElementPtr json;
@@ -1094,27 +1100,36 @@ TEST_F(DdnsDomainListParserTest, validList) {
     EXPECT_EQ("example.com", domain->getName());
     EXPECT_EQ("d2_key.example.com", domain->getKeyName());
 
-    // Verify the TSIGKeyInfo name and that the actual key was created
-    ASSERT_TRUE(domain->getTSIGKeyInfo());
-    EXPECT_EQ(domain->getKeyName(), domain->getTSIGKeyInfo()->getName());
-    EXPECT_TRUE(domain->getTSIGKeyInfo()->getTSIGKey());
-
     // Verify the each of the first domain's servers
     DnsServerInfoStoragePtr servers = domain->getServers();
-    EXPECT_TRUE(servers);
+    ASSERT_TRUE(servers);
     EXPECT_EQ(3, servers->size());
 
     DnsServerInfoPtr server = (*servers)[0];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.1", 100));
 
+    // Verify the TSIGKeyInfo name and that the actual key was created
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
+
     server = (*servers)[1];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.2", 200));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     server = (*servers)[2];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.3", 300));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify second domain
     gotit = domains_->find("billcat.net");
@@ -1124,27 +1139,35 @@ TEST_F(DdnsDomainListParserTest, validList) {
     // Verify the name and key_name values of the second domain.
     EXPECT_EQ("billcat.net", domain->getName());
     EXPECT_EQ("d2_key.billcat.net", domain->getKeyName());
-    ASSERT_TRUE(domain->getTSIGKeyInfo());
-    EXPECT_EQ(domain->getKeyName(), domain->getTSIGKeyInfo()->getName());
-    EXPECT_TRUE(domain->getTSIGKeyInfo()->getTSIGKey());
 
     // Verify the each of second domain's servers
     servers = domain->getServers();
-    EXPECT_TRUE(servers);
-    servers->size();
+    ASSERT_TRUE(servers);
     EXPECT_EQ(3, servers->size());
 
     server = (*servers)[0];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.4", 400));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     server = (*servers)[1];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.5", 500));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 
     server = (*servers)[2];
-    EXPECT_TRUE(server);
+    ASSERT_TRUE(server);
     EXPECT_TRUE(checkServer(server, "", "127.0.0.6", 600));
+    ASSERT_TRUE(server->getTSIGKeyInfo());
+    EXPECT_EQ(domain->getKeyName(), server->getKeyName());
+    EXPECT_EQ(domain->getKeyName(), server->getTSIGKeyInfo()->getName());
+    EXPECT_TRUE(server->getTSIGKeyInfo()->getTSIGKey());
 }
 
 /// @brief Tests that a domain list configuration cannot contain duplicates.
@@ -1168,4 +1191,4 @@ TEST_F(DdnsDomainListParserTest, duplicateDomain) {
                "Duplicate domain specified:example.com (<string>:1:115)");
 }
 
-};
+}
index 87b60468e129c9d69276438033f3e05900aa4a43..8608182cb552a4c8466d483b5411f356e75a0ebd 100644 (file)
@@ -285,9 +285,9 @@ TransactionTest::setupForIPv4Transaction(dhcp_ddns::NameChangeType chg_type,
         // Create the forward domain and then its servers.
         forward_domain_ = makeDomain("example.com.", tsig_key_info);
         addDomainServer(forward_domain_, "forward.example.com",
-                        "127.0.0.1", 5301);
+                        "127.0.0.1", 5301, tsig_key_info);
         addDomainServer(forward_domain_, "forward2.example.com",
-                        "127.0.0.1", 5302);
+                        "127.0.0.1", 5302, tsig_key_info);
     }
 
     // If the change mask does not include a reverse change clear the
@@ -299,9 +299,9 @@ TransactionTest::setupForIPv4Transaction(dhcp_ddns::NameChangeType chg_type,
         // Create the reverse domain and its server.
         reverse_domain_ = makeDomain("2.168.192.in.addr.arpa.", tsig_key_info);
         addDomainServer(reverse_domain_, "reverse.example.com",
-                        "127.0.0.1", 5301);
+                        "127.0.0.1", 5301, tsig_key_info);
         addDomainServer(reverse_domain_, "reverse2.example.com",
-                        "127.0.0.1", 5302);
+                        "127.0.0.1", 5302, tsig_key_info);
     }
 }
 
@@ -344,9 +344,9 @@ TransactionTest::setupForIPv6Transaction(dhcp_ddns::NameChangeType chg_type,
         // Create the forward domain and then its servers.
         forward_domain_ = makeDomain("example.com.", tsig_key_info);
         addDomainServer(forward_domain_, "fwd6-server.example.com",
-                        "::1", 5301);
+                        "::1", 5301, tsig_key_info);
         addDomainServer(forward_domain_, "fwd6-server2.example.com",
-                        "::1", 5302);
+                        "::1", 5302, tsig_key_info);
     }
 
     // If the change mask does not include a reverse change clear the
@@ -358,9 +358,9 @@ TransactionTest::setupForIPv6Transaction(dhcp_ddns::NameChangeType chg_type,
         // Create the reverse domain and its server.
         reverse_domain_ = makeDomain("1.2001.ip6.arpa.", tsig_key_info);
         addDomainServer(reverse_domain_, "rev6-server.example.com",
-                        "::1", 5301);
+                        "::1", 5301, tsig_key_info);
         addDomainServer(reverse_domain_, "rev6-server2.example.com",
-                        "::1", 5302);
+                        "::1", 5302, tsig_key_info);
     }
 }
 
@@ -454,8 +454,7 @@ dhcp_ddns::NameChangeRequestPtr makeNcrFromString(const std::string& ncr_str) {
 DdnsDomainPtr makeDomain(const std::string& zone_name,
                          const std::string& key_name) {
     DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
-    DdnsDomainPtr domain(new DdnsDomain(zone_name, servers,
-                         makeTSIGKeyInfo(key_name)));
+    DdnsDomainPtr domain(new DdnsDomain(zone_name, servers, key_name));
     return (domain);
 }
 
@@ -463,7 +462,11 @@ DdnsDomainPtr makeDomain(const std::string& zone_name,
                          const TSIGKeyInfoPtr &tsig_key_info) {
     DdnsDomainPtr domain;
     DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
-    domain.reset(new DdnsDomain(zone_name, servers, tsig_key_info));
+    std::string key_name;
+    if (tsig_key_info) {
+        key_name = tsig_key_info->getName();
+    }
+    domain.reset(new DdnsDomain(zone_name, servers, key_name));
     return (domain);
 }
 
@@ -494,9 +497,10 @@ TSIGKeyInfoPtr makeTSIGKeyInfo(const std::string& key_name,
 }
 
 void addDomainServer(DdnsDomainPtr& domain, const std::string& name,
-                     const std::string& ip, const size_t port) {
+                     const std::string& ip, const size_t port,
+                     const TSIGKeyInfoPtr &tsig_key_info) {
     DnsServerInfoPtr server(new DnsServerInfo(name, asiolink::IOAddress(ip),
-                                              port));
+                                              port, true, tsig_key_info, true));
     domain->getServers()->push_back(server);
 }
 
index 26eacd82d05b15e745bf58c3cdac06347ff23921..543004b627c9df82d38269e7074fbff081f2fd62 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -451,11 +451,15 @@ TSIGKeyInfoPtr makeTSIGKeyInfo(const std::string& key_name,
 /// @param name new server's host name of the server
 /// @param ip new server's ip address
 /// @param port new server's port
+/// @param tsig_key_info pointer to the TSIGInfog key for this server.
+/// Defaults to an empty pointer, meaning this server has no key.
 ///
 /// @throw Underlying methods may throw.
 extern void addDomainServer(DdnsDomainPtr& domain, const std::string& name,
                             const std::string& ip = TEST_DNS_SERVER_IP,
-                            const size_t port = TEST_DNS_SERVER_PORT);
+                            const size_t port = TEST_DNS_SERVER_PORT,
+                            const TSIGKeyInfoPtr&
+                            tsig_key_info = TSIGKeyInfoPtr());
 
 /// @brief Creates a hex text dump of the given data buffer.
 ///
index 47444772305e6380c0b95e5be2610895eb1ecd87..1471006a14f15468c72d128e22673117319d89ca 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
index 487b82dd11bc8598991fcd785a0a4449dd1ab533..d0cd384657a9c2b7160b24cab07fd020b6331463 100644 (file)
 #------ "D2.forward-ddns.dhcp-ddns, key-name tests
 ,{
 "description" : "D2.forward-ddns, no matching key name",
-"logic-error" : "DdnsDomain : four.example.com. specifies an undefined key: no.such.key (<string>:1:104)",
+"logic-error" : "DdnsDomain : specifies an undefined key: no.such.key (<string>:1:104)",
 "data" :
     {
     "forward-ddns" :
 #------ "D2.reverse-ddns.dhcp-ddns, key-name tests
 ,{
 "description" : "D2.reverse-ddns, no matching key name",
-"logic-error" : "DdnsDomain : 2.0.192.in-addr.arpa. specifies an undefined key: no.such.key (<string>:1:126)",
+"logic-error" : "DdnsDomain : specifies an undefined key: no.such.key (<string>:1:126)",
 "data" :
     {
     "forward-ddns" : {},
index 68fd48e5afbcab10bb2d8bbcf2edfa8cb31aa4a9..a6c2d162e5311de9ba059a0f5e92e861ea4e4168 100644 (file)
@@ -201,15 +201,28 @@ TSIGKeyInfo::toElement() const {
 
 // *********************** DnsServerInfo  *************************
 DnsServerInfo::DnsServerInfo(const std::string& hostname,
-                             isc::asiolink::IOAddress ip_address, uint32_t port,
-                             bool enabled)
-    :hostname_(hostname), ip_address_(ip_address), port_(port),
-    enabled_(enabled) {
+                             isc::asiolink::IOAddress ip_address,
+                             uint32_t port,
+                             bool enabled,
+                             const TSIGKeyInfoPtr& tsig_key_info,
+                             bool inherited_key)
+    : hostname_(hostname), ip_address_(ip_address), port_(port),
+      enabled_(enabled), tsig_key_info_(tsig_key_info),
+      inherited_key_(inherited_key) {
 }
 
 DnsServerInfo::~DnsServerInfo() {
 }
 
+const std::string
+DnsServerInfo::getKeyName() const {
+    if (tsig_key_info_) {
+        return (tsig_key_info_->getName());
+    }
+
+    return ("");
+}
+
 std::string
 DnsServerInfo::toText() const {
     std::ostringstream stream;
@@ -228,11 +241,14 @@ DnsServerInfo::toElement() const {
     result->set("ip-address", Element::create(ip_address_.toText()));
     // Set port
     result->set("port", Element::create(static_cast<int64_t>(port_)));
+    // Set key-name
+    if (tsig_key_info_ && !inherited_key_) {
+        result->set("key-name", Element::create(tsig_key_info_->getName()));
+    }
 
     return (result);
 }
 
-
 std::ostream&
 operator<<(std::ostream& os, const DnsServerInfo& server) {
     os << server.toText();
@@ -243,23 +259,13 @@ operator<<(std::ostream& os, const DnsServerInfo& server) {
 
 DdnsDomain::DdnsDomain(const std::string& name,
                        DnsServerInfoStoragePtr servers,
-                       const TSIGKeyInfoPtr& tsig_key_info)
-    : name_(name), servers_(servers),
-      tsig_key_info_(tsig_key_info) {
+                       const std::string& key_name)
+    : name_(name), servers_(servers), key_name_(key_name) {
 }
 
 DdnsDomain::~DdnsDomain() {
 }
 
-const std::string
-DdnsDomain::getKeyName() const {
-    if (tsig_key_info_) {
-        return (tsig_key_info_->getName());
-    }
-
-    return ("");
-}
-
 ElementPtr
 DdnsDomain::toElement() const {
     ElementPtr result = Element::createMap();
@@ -279,8 +285,8 @@ DdnsDomain::toElement() const {
         result->set("dns-servers", servers);
     }
     // Set key-name
-    if (tsig_key_info_) {
-        result->set("key-name", Element::create(tsig_key_info_->getName()));
+    if (!key_name_.empty()) {
+        result->set("key-name", Element::create(key_name_));
     }
 
     return (result);
@@ -477,12 +483,47 @@ TSIGKeyInfoListParser::parse(ConstElementPtr key_list) {
 // *********************** DnsServerInfoParser  *************************
 
 DnsServerInfoPtr
-DnsServerInfoParser::parse(ConstElementPtr server_config) {
+DnsServerInfoParser::parse(ConstElementPtr server_config,
+                           ConstElementPtr domain_config,
+                           const TSIGKeyInfoMapPtr keys) {
     std::string hostname = getString(server_config, "hostname");
     std::string ip_address = getString(server_config, "ip-address");
     uint32_t port = getInteger(server_config, "port");
+    std::string key_name = getString(server_config, "key-name");
     ConstElementPtr user_context = server_config->get("user-context");
 
+    // Key name is optional. If it is not blank, then find the key in the
+    // list of defined keys.
+    TSIGKeyInfoPtr tsig_key_info;
+    bool inherited_key = false;
+    if (key_name.empty()) {
+        std::string domain_key_name = getString(domain_config, "key-name");
+        if (!domain_key_name.empty()) {
+            key_name = domain_key_name;
+            inherited_key = true;
+        }
+    }
+    if (!key_name.empty()) {
+        if (keys) {
+            TSIGKeyInfoMap::iterator kit = keys->find(key_name);
+            if (kit != keys->end()) {
+                tsig_key_info = kit->second;
+            }
+        }
+
+        if (!tsig_key_info) {
+            if (inherited_key) {
+                isc_throw(D2CfgError, "DdnsDomain : specifies an "
+                          << "undefined key: " << key_name << " ("
+                          << getPosition("key-name", domain_config) << ")");
+            } else {
+                isc_throw(D2CfgError, "Dns Server : specifies an "
+                          << "undefined key: " << key_name << " ("
+                          << getPosition("key-name", server_config) << ")");
+            }
+        }
+    }
+
     // The configuration must specify one or the other.
     if (hostname.empty() == ip_address.empty()) {
         isc_throw(D2CfgError, "Dns Server must specify one or the other"
@@ -512,7 +553,9 @@ DnsServerInfoParser::parse(ConstElementPtr server_config) {
             // Create an IOAddress from the IP address string given and then
             // create the DnsServerInfo.
             isc::asiolink::IOAddress io_addr(ip_address);
-            server_info.reset(new DnsServerInfo(hostname, io_addr, port));
+            server_info.reset(new DnsServerInfo(hostname, io_addr, port,
+                                                true, tsig_key_info,
+                                                inherited_key));
         } catch (const isc::asiolink::IOError& ex) {
             isc_throw(D2CfgError, "Dns Server : invalid IP address : "
                       << ip_address
@@ -531,12 +574,15 @@ DnsServerInfoParser::parse(ConstElementPtr server_config) {
 // *********************** DnsServerInfoListParser  *************************
 
 DnsServerInfoStoragePtr
-DnsServerInfoListParser::parse(ConstElementPtr server_list) {
+DnsServerInfoListParser::parse(ConstElementPtr server_list,
+                               ConstElementPtr domain_config,
+                               const TSIGKeyInfoMapPtr keys) {
     DnsServerInfoStoragePtr servers(new DnsServerInfoStorage());
     ConstElementPtr server_config;
     DnsServerInfoParser parser;
     BOOST_FOREACH(server_config, server_list->listValue()) {
-        DnsServerInfoPtr server = parser.parse(server_config);
+        DnsServerInfoPtr server =
+            parser.parse(server_config, domain_config, keys);
         servers->push_back(server);
     }
 
@@ -551,24 +597,6 @@ DdnsDomainPtr DdnsDomainParser::parse(ConstElementPtr domain_config,
     std::string key_name = getString(domain_config, "key-name");
     ConstElementPtr user_context = domain_config->get("user-context");
 
-    // Key name is optional. If it is not blank, then find the key in the
-    // list of defined keys.
-    TSIGKeyInfoPtr tsig_key_info;
-    if (!key_name.empty()) {
-        if (keys) {
-            TSIGKeyInfoMap::iterator kit = keys->find(key_name);
-            if (kit != keys->end()) {
-                tsig_key_info = kit->second;
-            }
-        }
-
-        if (!tsig_key_info) {
-            isc_throw(D2CfgError, "DdnsDomain : " << name
-                      << " specifies an undefined key: " << key_name
-                      << " (" << getPosition("key-name", domain_config) << ")");
-        }
-    }
-
     // Parse the list of DNS servers
     ConstElementPtr servers_config;
     try {
@@ -579,14 +607,15 @@ DdnsDomainPtr DdnsDomainParser::parse(ConstElementPtr domain_config,
     }
 
     DnsServerInfoListParser server_parser;
-    DnsServerInfoStoragePtr servers =  server_parser.parse(servers_config);
+    DnsServerInfoStoragePtr servers =
+        server_parser.parse(servers_config, domain_config, keys);
     if (servers->size() == 0) {
         isc_throw(D2CfgError, "DNS server list cannot be empty"
                     << servers_config->getPosition());
     }
 
     // Instantiate the new domain and add it to domain storage.
-    DdnsDomainPtr domain(new DdnsDomain(name, servers, tsig_key_info));
+    DdnsDomainPtr domain(new DdnsDomain(name, servers, key_name));
 
     // Add user-context
     if (user_context) {
@@ -640,5 +669,5 @@ DdnsDomainListMgrParser::parse(ConstElementPtr mgr_config,
     return(mgr);
 }
 
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
+} // end of isc::dhcp namespace
+} // end of isc namespace
index 2d7b5e10e2913d9a68a156333535bcd52fef59d4..d687695743a331311f031cbd7df687a1ece3a887 100644 (file)
@@ -122,7 +122,8 @@ namespace d2 {
 ///        "key-name": "d2_key.tmark.org" ,
 ///        "dns-servers" :
 ///        [
-///          { "ip-address": "127.0.0.101" , "port": 100 }
+///          { "ip-address": "127.0.0.101" , "port": 100 ,
+///            "key-name": "d2_key.tmark.org" }
 ///        ]
 ///      }
 ///    ]
@@ -434,10 +435,17 @@ public:
     /// the default.)
     /// @param enabled is a flag that indicates whether this server is
     /// enabled for use. It defaults to true.
+    /// @param tsig_key_info pointer to the TSIGKeyInfo for the server's key
+    /// It defaults to an empty pointer, signifying the server has no key.
+    /// @param inherited_key is a flag that indicates whether the key was
+    /// inherited from the domain or not. It defaults to false i.e. not
+    /// inherited.
     DnsServerInfo(const std::string& hostname,
                   isc::asiolink::IOAddress ip_address,
                   uint32_t port = STANDARD_DNS_PORT,
-                  bool enabled=true);
+                  bool enabled = true,
+                  const TSIGKeyInfoPtr& tsig_key_info = TSIGKeyInfoPtr(),
+                  bool inherited_key = false);
 
     /// @brief Destructor
     virtual ~DnsServerInfo();
@@ -481,6 +489,20 @@ public:
         enabled_ = false;
     }
 
+    /// @brief Convenience method which returns the server's TSIG key name.
+    ///
+    /// @return returns the key name in an std::string. If server has no
+    /// TSIG key, the string will empty.
+    const std::string getKeyName() const;
+
+    /// @brief Getter which returns the server's TSIGKey info
+    ///
+    /// @return returns the pointer to the server storage.  If the server
+    /// is not configured to use TSIG the pointer will be empty.
+    const TSIGKeyInfoPtr& getTSIGKeyInfo() {
+        return (tsig_key_info_);
+    }
+
     /// @brief Returns a text representation for the server.
     std::string toText() const;
 
@@ -505,6 +527,14 @@ private:
     /// @param enabled is a flag that indicates whether this server is
     /// enabled for use. It defaults to true.
     bool enabled_;
+
+    /// @brief Pointer to domain's the TSIGKeyInfo.
+    /// Value is empty if the domain is not configured for TSIG.
+    TSIGKeyInfoPtr tsig_key_info_;
+
+    /// @brief Inherited key. When true the key was inherited from the domain,
+    /// when false the key was not inherited from the domain.
+    bool inherited_key_;
 };
 
 std::ostream&
@@ -533,11 +563,9 @@ public:
     ///
     /// @param name is the domain name of the domain.
     /// @param servers is the list of server(s) supporting this domain.
-    /// @param tsig_key_info pointer to the TSIGKeyInfo for the domain's key
-    /// It defaults to an empty pointer, signifying the domain has no key.
-    DdnsDomain(const std::string& name,
-               DnsServerInfoStoragePtr servers,
-               const TSIGKeyInfoPtr& tsig_key_info = TSIGKeyInfoPtr());
+    /// @param key_name is the TSIG key name of the domain.
+    DdnsDomain(const std::string& name, DnsServerInfoStoragePtr servers,
+               const std::string& key_name = "");
 
     /// @brief Destructor
     virtual ~DdnsDomain();
@@ -549,11 +577,15 @@ public:
         return (name_);
     }
 
-    /// @brief Convenience method which returns the domain's TSIG key name.
+    /// @brief Getter which returns the domain's TSIG key name.
+    ///
+    /// @note: TSIG key infos are in servers.
     ///
     /// @return returns the key name in an std::string. If domain has no
     /// TSIG key, the string will empty.
-    const std::string getKeyName() const;
+    const std::string getKeyName() const {
+        return (key_name_);
+    }
 
     /// @brief Getter which returns the domain's list of servers.
     ///
@@ -562,14 +594,6 @@ public:
         return (servers_);
     }
 
-    /// @brief Getter which returns the domain's TSIGKey info
-    ///
-    /// @return returns the pointer to the server storage.  If the domain
-    /// is not configured to use TSIG the pointer will be empty.
-    const TSIGKeyInfoPtr& getTSIGKeyInfo() {
-        return (tsig_key_info_);
-    }
-
     /// @brief Unparse a configuration object
     ///
     /// @return a pointer to a configuration
@@ -582,9 +606,8 @@ private:
     /// @brief The list of server(s) supporting this domain.
     DnsServerInfoStoragePtr servers_;
 
-    /// @brief Pointer to domain's the TSIGKeyInfo.
-    /// Value is empty if the domain is not configured for TSIG.
-    TSIGKeyInfoPtr tsig_key_info_;
+    /// @brief The TSIG key name (empty when there is no key for the domain).
+    std::string key_name_;
 };
 
 /// @brief Defines a pointer for DdnsDomain instances.
@@ -778,6 +801,7 @@ public:
     ///   3. Add the new TSIGKeyInfo instance to the key map
     ///
     /// @param key_list_config is the list of "tsig_key" elements to parse.
+    /// @param keys map of defined TSIG keys
     ///
     /// @return a map containing the TSIGKeyInfo instances
     TSIGKeyInfoMapPtr parse(data::ConstElementPtr key_list_config);
@@ -796,6 +820,8 @@ public:
     /// and returns it.
     ///
     /// @param server_config is the "dns-server" configuration to parse
+    /// @param domain_config the parent domain's configuration
+    /// @param keys map of defined TSIG keys
     ///
     /// @return a pointer to the newly created server instance
     ///
@@ -803,7 +829,9 @@ public:
     /// -# hostname is not blank, hostname is not yet supported
     /// -# ip_address is invalid
     /// -# port is 0
-    DnsServerInfoPtr parse(data::ConstElementPtr server_config);
+    DnsServerInfoPtr parse(data::ConstElementPtr server_config,
+                           data::ConstElementPtr domain_config,
+                           const TSIGKeyInfoMapPtr keys);
 };
 
 /// @brief Parser for a list of DnsServerInfos
@@ -811,7 +839,7 @@ public:
 /// This class parses a list of "dns-server" configuration elements.
 /// The DnsServerInfo instances are added
 /// to the given storage upon commit.
-class DnsServerInfoListParser : public data::SimpleParser{
+class DnsServerInfoListParser : public data::SimpleParser {
 public:
     /// @brief Performs the actual parsing of the given list "dns-server"
     /// elements.
@@ -823,8 +851,12 @@ public:
     ///   2. Adds the server to the server list
     ///
     /// @param server_list_config is the list of "dns-server" elements to parse.
+    /// @param domain_config the parent domain's configuration
+    /// @param keys map of defined TSIG keys
     /// @return A pointer to the new, populated server list
-    DnsServerInfoStoragePtr parse(data::ConstElementPtr server_list_config);
+    DnsServerInfoStoragePtr parse(data::ConstElementPtr server_list_config,
+                                  data::ConstElementPtr domain_config,
+                                  const TSIGKeyInfoMapPtr keys);
 };
 
 /// @brief Parser for  DdnsDomain
@@ -891,8 +923,7 @@ public:
                                const TSIGKeyInfoMapPtr keys);
 };
 
-
-}; // end of isc::d2 namespace
-}; // end of isc namespace
+} // end of isc::d2 namespace
+} // end of isc namespace
 
 #endif // D2_CONFIG_H
index 15cfd67ab2150251f55b43c308dfffb8a8f4cbef..e6e8594551dba51771a9de619ff1ec7e7f189981 100644 (file)
@@ -110,6 +110,7 @@ const SimpleDefaults D2SimpleParser::DDNS_DOMAIN_DEFAULTS = {
 const SimpleDefaults D2SimpleParser::DNS_SERVER_DEFAULTS = {
     { "hostname", Element::string, "" },
     { "port",     Element::integer, "53" },
+    { "key-name", Element::string, "" }
 };
 
 /// @}