]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2011] Checkpoint: added callout
authorFrancis Dupont <fdupont@isc.org>
Wed, 4 Aug 2021 12:56:35 +0000 (14:56 +0200)
committerFrancis Dupont <fdupont@isc.org>
Mon, 9 Aug 2021 15:08:24 +0000 (17:08 +0200)
doc/devel/Doxyfile
src/bin/d2/d2_hooks.dox
src/bin/d2/d2_process.cc
src/bin/d2/nc_trans.cc
src/bin/d2/nc_trans.h
src/bin/d2/simple_add.cc
src/bin/d2/tests/nc_test_utils.cc
src/lib/d2srv/d2_config.cc
src/lib/d2srv/d2_config.h

index 3c41f8aa7c1a59882eb9a4c4b93c0071abd28506..e190a0fada58880b667c95f0b2c826d24336cf43 100644 (file)
@@ -898,7 +898,6 @@ INPUT                  = ../../src/bin/agent \
                          ../../src/lib/util \
                          ../../src/lib/util/encode \
                          ../../src/lib/util/io \
-                         ../../src/lib/util/random \
                          ../../src/lib/util/unittests \
                          ../../src/lib/yang \
                          .
index 7cf4ee38a78cc2695a07f712aa346a0832a1ed06..e1bde28c5719375895c1a6e3368033ade9b06967 100644 (file)
@@ -66,4 +66,17 @@ to the end of this list.
    considers the configuration is incorrect and rejects it using the error
    string as an error message.
 
+ @subsection d2HooksSelectKey select_key
+ - @b Arguments:
+   - name: @b current_server, type: isc::d2::DnsServerInfoPtr, direction: <b>in</b>
+   - name: @b tsig_key, type: isc::dns::TSIGKeyPtr, direction: <b>in/out</b>
+
+ - @b Description: this callout is executed when the DNS server to send the
+   next DNS update was selected and a TSIG key to protect the DNS update
+   is looking for. Pointers to the selected DNS server and the current TSIG
+   key are provided. If a hook library wants to use another TSIG key the
+   pointer must be updated.
+
+ - <b>Next step status</b>: IF any callout sets the status to value different
+   from CONTINUE the selected server is skipped.
 */
index f6f2a32cb585a0075769ea0d8f829848845de726..973e98e24838107d1af7d6733f19dd6fb919466d 100644 (file)
@@ -24,7 +24,7 @@ namespace {
 struct D2ProcessHooks {
     int hooks_index_d2_srv_configured_;
 
-    /// Constructor that registers hook points for the DHCPv4 server.
+    /// Constructor that registers hook points for the D2 server.
     D2ProcessHooks() {
         hooks_index_d2_srv_configured_ = HooksManager::registerHook("d2_srv_configured");
     }
index 2321ee72e90d2a0e70c724d3011cbf6bab1cb47c..bca27aa70e20cab3119ffca34b10d4067f609355 100644 (file)
 #include <d2srv/d2_log.h>
 #include <dns/qid_gen.h>
 #include <dns/rdata.h>
+#include <hooks/hooks.h>
+#include <hooks/hooks_manager.h>
 
 #include <sstream>
 
+using namespace isc::hooks;
 using namespace isc::util;
 
+namespace {
+
+/// Structure that holds registered hook indexes.
+struct NcTransHooks {
+    int hooks_index_select_key_;
+
+    /// Constructor that registers hook points for the D2 server.
+    NcTransHooks() {
+        hooks_index_select_key_ = HooksManager::registerHook("select_key");
+    }
+};
+
+// Declare a Hooks object. As this is outside any function or method, it
+// will be instantiated (and the constructor run) when the module is loaded.
+// As a result, the hook indexes will be defined before any method in this
+// module is called.
+
+NcTransHooks Hooks;
+
+}
+
 namespace isc {
 namespace d2 {
 
@@ -437,33 +461,65 @@ NameChangeTransaction::initServerSelection(const DdnsDomainPtr& domain) {
 
 bool
 NameChangeTransaction::selectNextServer() {
-    if ((current_server_list_) &&
-        (next_server_pos_ < current_server_list_->size())) {
-        current_server_  = (*current_server_list_)[next_server_pos_];
-        // 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();
+    for (;;) {
+        if ((current_server_list_) &&
+            (next_server_pos_ < current_server_list_->size())) {
+            current_server_  = (*current_server_list_)[next_server_pos_];
+            // Toss out any previous response.
+            dns_update_response_.reset();
+
+            // Set the tsig_key to that of the current server..
+            if (!selectTSIGKey()) {
+                ++next_server_pos_;
+                continue;
+            }
+
+            // @todo  Protocol is set on DNSClient constructor.  We need
+            // to propagate a configuration value downward, probably starting
+            // at global, then domain, then server
+            // Once that is supported we need to add it here.
+            dns_client_.reset(new DNSClient(dns_update_response_ , this,
+                                            DNSClient::UDP));
+            ++next_server_pos_;
+            return (true);
         }
 
-        // @todo  Protocol is set on DNSClient constructor.  We need
-        // to propagate a configuration value downward, probably starting
-        // at global, then domain, then server
-        // Once that is supported we need to add it here.
-        dns_client_.reset(new DNSClient(dns_update_response_ , this,
-                                        DNSClient::UDP));
-        ++next_server_pos_;
-        return (true);
+        return (false);
     }
+}
 
-    return (false);
+bool
+NameChangeTransaction::selectTSIGKey() {
+    TSIGKeyInfoPtr tsig_key_info = current_server_->getTSIGKeyInfo();
+    if (tsig_key_info) {
+        tsig_key_ = tsig_key_info->getTSIGKey();
+    } else {
+        tsig_key_.reset();
+    }
+
+    // This hook point allows hooks libraries to overwrite the TSIG key.
+    if (HooksManager::calloutsPresent(Hooks.hooks_index_select_key_)) {
+        CalloutHandlePtr callout_handle = HooksManager::createCalloutHandle();
+
+        callout_handle->setArgument("current_server", current_server_);
+        callout_handle->setArgument("tsig_key", tsig_key_);
+
+        HooksManager::callCallouts(Hooks.hooks_index_select_key_,
+                                   *callout_handle);
+
+        // This server is skipped not NEXT_STEP_CONTINUE status.
+        if (callout_handle->getStatus() != CalloutHandle::NEXT_STEP_CONTINUE) {
+            return (false);
+        }
+
+        // Reread the TSIG key.
+        callout_handle->getArgument("tsig_key", tsig_key_);
+    }
+
+    return (true);
 }
 
+
 const DNSClientPtr&
 NameChangeTransaction::getDNSClient() const {
     return (dns_client_);
index ba8ddad76007f740fab8a92074f1cfc832db91de..a25b5da57f3364f3f767a3ed904b95fcfd4e9f47 100644 (file)
@@ -343,6 +343,14 @@ protected:
     /// servers from which to select.
     bool selectNextServer();
 
+    /// @brief Selects the TSIG key.
+    ///
+    /// This method uses the current server and the select_key callout.
+    /// When no TSIG key is selected the tsig_key_ pointer is null.
+    ///
+    /// @return False when the current server should be skipped.
+    bool selectTSIGKey();
+
     /// @brief Sets the update attempt count to the given value.
     ///
     /// @param value is the new value to assign.
index 957e67bc1ee9817c3a34045b1490f3fd58842d52..7c7b0cf2c426a28953e180f118a05eb86cf6f50c 100644 (file)
@@ -511,7 +511,7 @@ SimpleAddTransaction::buildReplaceRevPtrsRequest() {
 
     // There are no prerequisites.
 
-    // Create the FQDN/IP PTR 'delete' RR for this IP and add it to 
+    // Create the FQDN/IP PTR 'delete' RR for this IP and add it to
     // the update section.
     dns::RRsetPtr update(new dns::RRset(rev_ip, dns::RRClass::ANY(),
                          dns::RRType::PTR(), dns::RRTTL(0)));
index 8608182cb552a4c8466d483b5411f356e75a0ebd..f4888d492a336457fd0533a0a92d49acc5fa4905 100644 (file)
@@ -500,7 +500,7 @@ void addDomainServer(DdnsDomainPtr& domain, const std::string& name,
                      const std::string& ip, const size_t port,
                      const TSIGKeyInfoPtr &tsig_key_info) {
     DnsServerInfoPtr server(new DnsServerInfo(name, asiolink::IOAddress(ip),
-                                              port, true, tsig_key_info, true));
+                                              port, true, tsig_key_info));
     domain->getServers()->push_back(server);
 }
 
index a6c2d162e5311de9ba059a0f5e92e861ea4e4168..40baf5f60974c80baa73b9498742dd1d65ad9fa5 100644 (file)
@@ -495,13 +495,14 @@ DnsServerInfoParser::parse(ConstElementPtr server_config,
     // 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;
+    bool inherited_key = true;
     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;
         }
+    } else {
+        inherited_key = false;
     }
     if (!key_name.empty()) {
         if (keys) {
index d687695743a331311f031cbd7df687a1ece3a887..9faf097f17bc51a9145fbfc89b61fc97f8252879 100644 (file)
@@ -438,14 +438,13 @@ public:
     /// @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.
+    /// inherited from the domain or not. It defaults to true i.e. inherited.
     DnsServerInfo(const std::string& hostname,
                   isc::asiolink::IOAddress ip_address,
                   uint32_t port = STANDARD_DNS_PORT,
                   bool enabled = true,
                   const TSIGKeyInfoPtr& tsig_key_info = TSIGKeyInfoPtr(),
-                  bool inherited_key = false);
+                  bool inherited_key = true);
 
     /// @brief Destructor
     virtual ~DnsServerInfo();
@@ -801,7 +800,6 @@ 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);