BIND 10 trac1555, updated. 9f8d746079cad652e014d482327b6a73d5ee2f12 [1555] Open active V6 sockets when configuration is changed.

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 11 12:03:38 UTC 2013


The branch, trac1555 has been updated
       via  9f8d746079cad652e014d482327b6a73d5ee2f12 (commit)
      from  0a5d26dfc2ee6a4a84d596cbcb39e894e7432f3c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9f8d746079cad652e014d482327b6a73d5ee2f12
Author: Marcin Siodelski <marcin at isc.org>
Date:   Thu Jul 11 14:03:21 2013 +0200

    [1555] Open active V6 sockets when configuration is changed.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/dhcp4/ctrl_dhcp4_srv.cc |    1 -
 src/bin/dhcp6/ctrl_dhcp6_srv.cc |   41 ++++++++++++++++++++++++++++++++++++++-
 src/bin/dhcp6/ctrl_dhcp6_srv.h  |   11 +++++++++++
 src/bin/dhcp6/dhcp6_srv.cc      |    4 ++--
 src/bin/dhcp6/dhcp6_srv.h       |   15 ++++++++++++++
 src/lib/dhcp/iface_mgr.cc       |    2 +-
 6 files changed, 69 insertions(+), 5 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
index 9050a16..78cfb9b 100644
--- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc
+++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
@@ -26,7 +26,6 @@
 #include <dhcp4/spec_config.h>
 #include <dhcp4/config_parser.h>
 #include <exceptions/exceptions.h>
-#include <boost/bind.hpp>
 #include <util/buffer.h>
 
 #include <cassert>
diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
index c3488e5..cbd29b9 100644
--- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc
+++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
@@ -20,6 +20,7 @@
 #include <config/ccsession.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcpsrv/dhcp_config_parser.h>
+#include <dhcpsrv/cfgmgr.h>
 #include <dhcp6/config_parser.h>
 #include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_log.h>
@@ -100,7 +101,27 @@ ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) {
     }
 
     // Configure the server.
-    return (configureDhcp6Server(*server_, merged_config));
+    ConstElementPtr answer = configureDhcp6Server(*server_, merged_config);
+
+    // Check that configuration was successful. If not, do not reopen sockets.
+    int rcode = 0;
+    parseAnswer(rcode, answer);
+    if (rcode != 0) {
+        return (answer);
+    }
+
+    // Configuration may change active interfaces. Therefore, we have to reopen
+    // sockets according to new configuration. This operation is not exception
+    // safe and we really don't want to emit exceptions to the callback caller.
+    // Instead, catch an exception and create appropriate answer.
+    try {
+        server_->openActiveSockets(server_->getPort());
+    } catch (const std::exception& ex) {
+        std::ostringstream err;
+        err << "failed to open sockets after server reconfiguration: " << ex.what();
+        answer = isc::config::createAnswer(1, err.str());
+    }
+    return (answer);
 }
 
 ConstElementPtr
@@ -228,6 +249,24 @@ ControlledDhcpv6Srv::execDhcpv6ServerCommand(const std::string& command_id,
     }
 }
 
+void
+ControlledDhcpv6Srv::openActiveSockets(const uint16_t port) {
+    IfaceMgr::instance().closeSockets();
+
+    // Get the reference to the collection of interfaces. This reference should be
+    // valid as long as the program is run because IfaceMgr is a singleton.
+    // Therefore we can safely iterate over instances of all interfaces and modify
+    // their flags. Here we modify flags which indicate wheter socket should be
+    // open for a particular interface or not.
+    IfaceMgr::IfaceCollection ifaces = IfaceMgr::instance().getIfaces();
+    for (IfaceMgr::IfaceCollection::iterator iface = ifaces.begin();
+         iface != ifaces.end(); ++iface) {
+        iface->inactive_ = !CfgMgr::instance().isActiveIface(iface->getName());
+    }
+    // Let's reopen active sockets. openSockets6 will check internally whether
+    // sockets are marked active or inactive.
+    IfaceMgr::instance().openSockets6(port);
+}
 
 };
 };
diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.h b/src/bin/dhcp6/ctrl_dhcp6_srv.h
index ffd43c3..d1599f8 100644
--- a/src/bin/dhcp6/ctrl_dhcp6_srv.h
+++ b/src/bin/dhcp6/ctrl_dhcp6_srv.h
@@ -128,6 +128,17 @@ protected:
     /// when there is a new command or configuration sent over msgq.
     static void sessionReader(void);
 
+    /// @brief Open sockets which are marked as active in @c CfgMgr.
+    ///
+    /// This function reopens sockets according to the current settings in the
+    /// Configuration Manager. It holds the list of the interfaces which server
+    /// should listen on. This function will open sockets on these interfaces
+    /// only. This function is not exception safe.
+    ///
+    /// @param port UDP port on which server should listen.
+    /// @param use_bcast should broadcast flags be set on the sockets.
+    static void openActiveSockets(const uint16_t port);
+
     /// @brief IOService object, used for all ASIO operations.
     isc::asiolink::IOService io_service_;
 
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index ef69a94..f0e4a21 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -67,7 +67,7 @@ namespace dhcp {
 static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
 
 Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
-    : alloc_engine_(), serverid_(), shutdown_(true) {
+    : alloc_engine_(), serverid_(), shutdown_(true), port_(port) {
 
     LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_OPEN_SOCKET).arg(port);
 
@@ -82,7 +82,7 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 return;
             }
-            IfaceMgr::instance().openSockets6(port);
+            IfaceMgr::instance().openSockets6(port_);
         }
 
         string duid_file = CfgMgr::instance().getDataDir() + "/" + string(SERVER_DUID_FILE);
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index c7b1f0f..4c45b01 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -87,6 +87,19 @@ public:
     /// @brief Instructs the server to shut down.
     void shutdown();
 
+    /// @brief Get UDP port on which server should listen.
+    ///
+    /// This accessor must be public because sockets are reopened from the
+    /// static configuration callback handler. This callback handler invokes
+    /// @c ControlledDhcpv4Srv::openActiveSockets which requires port parameter
+    /// which has to be retrieved from the @c ControlledDhcpv4Srv object.
+    /// They are retrieved using this public function.
+    ///
+    /// @return UDP port on which server should listen.
+    uint16_t getPort() const {
+        return (port_);
+    }
+
 protected:
 
     /// @brief verifies if specified packet meets RFC requirements
@@ -334,6 +347,8 @@ private:
     /// Indicates if shutdown is in progress. Setting it to true will
     /// initiate server shutdown procedure.
     volatile bool shutdown_;
+
+    uint16_t port_;  ///< UDP port number on which server listens.
 };
 
 }; // namespace isc::dhcp
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index dfe0f36..0209326 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -364,7 +364,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
         if (iface->flag_loopback_ ||
             !iface->flag_up_ ||
             !iface->flag_running_,
-            !iface->inactive_) {
+            iface->inactive_) {
             continue;
         }
 



More information about the bind10-changes mailing list