Browse Source

[3252] Install handler function for socket errors in DHCPv6 server.

Marcin Siodelski 11 years ago
parent
commit
4ff150488b
3 changed files with 29 additions and 2 deletions
  1. 4 0
      src/bin/dhcp6/dhcp6_messages.mes
  2. 15 2
      src/bin/dhcp6/dhcp6_srv.cc
  3. 10 0
      src/bin/dhcp6/dhcp6_srv.h

+ 4 - 0
src/bin/dhcp6/dhcp6_messages.mes

@@ -250,6 +250,10 @@ configured to receive the traffic.
 A debug message issued during startup, this indicates that the IPv6 DHCP
 server is about to open sockets on the specified port.
 
+% DHCP6_OPEN_SOCKET_FAIL failed to create socket: %1
+A warning message issued when IfaceMgr fails to open and bind a socket. The reason
+for the failure is appended as an argument of the log message.
+
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 The IPv6 DHCP server has received a packet that it is unable to interpret.
 

+ 15 - 2
src/bin/dhcp6/dhcp6_srv.cc

@@ -45,6 +45,7 @@
 #include <util/io_utilities.h>
 #include <util/range_utilities.h>
 
+#include <boost/bind.hpp>
 #include <boost/foreach.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/algorithm/string/erase.hpp>
@@ -152,7 +153,12 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 return;
             }
-            IfaceMgr::instance().openSockets6(port_);
+            // Create error handler. This handler will be called every time
+            // the socket opening operation fails. We use this handler to
+            // log a warning.
+            isc::dhcp::IfaceMgrErrorMsgCallback error_handler =
+                boost::bind(&Dhcpv6Srv::ifaceMgrSocket6ErrorHandler, _1);
+            IfaceMgr::instance().openSockets6(port_, error_handler);
         }
 
         string duid_file = CfgMgr::instance().getDataDir() + "/" + string(SERVER_DUID_FILE);
@@ -2311,7 +2317,9 @@ Dhcpv6Srv::openActiveSockets(const uint16_t port) {
     // sockets are marked active or inactive.
     // @todo Optimization: we should not reopen all sockets but rather select
     // those that have been affected by the new configuration.
-    if (!IfaceMgr::instance().openSockets6(port)) {
+    isc::dhcp::IfaceMgrErrorMsgCallback error_handler =
+        boost::bind(&Dhcpv6Srv::ifaceMgrSocket6ErrorHandler, _1);
+    if (!IfaceMgr::instance().openSockets6(port, error_handler)) {
         LOG_WARN(dhcp6_logger, DHCP6_NO_SOCKETS_OPEN);
     }
 }
@@ -2409,6 +2417,11 @@ Dhcpv6Srv::unpackOptions(const OptionBuffer& buf,
     return (offset);
 }
 
+void
+Dhcpv6Srv::ifaceMgrSocket6ErrorHandler(const std::string& errmsg) {
+    // Log the reason for socket opening failure and return.
+    LOG_WARN(dhcp6_logger, DHCP6_OPEN_SOCKET_FAIL).arg(errmsg);
+}
 
 };
 };

+ 10 - 0
src/bin/dhcp6/dhcp6_srv.h

@@ -534,6 +534,16 @@ protected:
                          size_t* relay_msg_len);
 
 private:
+
+    /// @brief Implements the error handler for socket open failure.
+    ///
+    /// This callback function is installed on the @c isc::dhcp::IfaceMgr
+    /// when IPv6 sockets are being open. When socket fails to open for
+    /// any reason, this function is called. It simply logs the error message.
+    ///
+    /// @param errmsg An error message containing a cause of the failure.
+    static void ifaceMgrSocket6ErrorHandler(const std::string& errmsg);
+
     /// @brief Allocation Engine.
     /// Pointer to the allocation engine that we are currently using
     /// It must be a pointer, because we will support changing engines