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
 A debug message issued during startup, this indicates that the IPv6 DHCP
 server is about to open sockets on the specified port.
 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
 % DHCP6_PACKET_PARSE_FAIL failed to parse incoming packet
 The IPv6 DHCP server has received a packet that it is unable to interpret.
 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/io_utilities.h>
 #include <util/range_utilities.h>
 #include <util/range_utilities.h>
 
 
+#include <boost/bind.hpp>
 #include <boost/foreach.hpp>
 #include <boost/foreach.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/algorithm/string/erase.hpp>
 #include <boost/algorithm/string/erase.hpp>
@@ -152,7 +153,12 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 LOG_ERROR(dhcp6_logger, DHCP6_NO_INTERFACES);
                 return;
                 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);
         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.
     // sockets are marked active or inactive.
     // @todo Optimization: we should not reopen all sockets but rather select
     // @todo Optimization: we should not reopen all sockets but rather select
     // those that have been affected by the new configuration.
     // 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);
         LOG_WARN(dhcp6_logger, DHCP6_NO_SOCKETS_OPEN);
     }
     }
 }
 }
@@ -2409,6 +2417,11 @@ Dhcpv6Srv::unpackOptions(const OptionBuffer& buf,
     return (offset);
     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);
                          size_t* relay_msg_len);
 
 
 private:
 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.
     /// @brief Allocation Engine.
     /// Pointer to the allocation engine that we are currently using
     /// Pointer to the allocation engine that we are currently using
     /// It must be a pointer, because we will support changing engines
     /// It must be a pointer, because we will support changing engines