BIND 10 master, updated. 76ace0c46a5fe0e53a29dad093b817ad6c891f1b [master] Merge branch 'trac3288'

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jan 22 08:54:41 UTC 2014


The branch, master has been updated
       via  76ace0c46a5fe0e53a29dad093b817ad6c891f1b (commit)
       via  9f52928a3543fb3cd39c26a8242e7e49c3fe3baf (commit)
       via  d3f792e43cf9bacf108ad21ec58fa87d64422c7d (commit)
       via  85ceb8b8c5fe2e586f512ade653dcd722330c24e (commit)
      from  904601920fec509d9d28759fa03e1f8108ee4079 (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 76ace0c46a5fe0e53a29dad093b817ad6c891f1b
Merge: 9046019 9f52928
Author: Marcin Siodelski <marcin at isc.org>
Date:   Wed Jan 22 09:42:22 2014 +0100

    [master] Merge branch 'trac3288'
    
    Conflicts:
    	src/lib/dhcp/iface_mgr.cc

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

Summary of changes:
 src/lib/dhcp/Makefile.am               |    1 +
 src/lib/dhcp/iface_mgr.cc              |   95 +++-----------------------------
 src/lib/dhcp/iface_mgr.h               |   24 ++++++++
 src/lib/dhcp/iface_mgr_bsd.cc          |   25 ++++++++-
 src/lib/dhcp/iface_mgr_error_handler.h |   52 +++++++++++++++++
 src/lib/dhcp/iface_mgr_linux.cc        |   57 ++++++++++++++++++-
 src/lib/dhcp/iface_mgr_sun.cc          |   25 ++++++++-
 7 files changed, 188 insertions(+), 91 deletions(-)
 create mode 100644 src/lib/dhcp/iface_mgr_error_handler.h

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am
index 1748927..640bac1 100644
--- a/src/lib/dhcp/Makefile.am
+++ b/src/lib/dhcp/Makefile.am
@@ -19,6 +19,7 @@ libb10_dhcp___la_SOURCES += duid.cc duid.h
 libb10_dhcp___la_SOURCES += hwaddr.cc hwaddr.h
 libb10_dhcp___la_SOURCES += iface_mgr.cc iface_mgr.h
 libb10_dhcp___la_SOURCES += iface_mgr_bsd.cc
+libb10_dhcp___la_SOURCES += iface_mgr_error_handler.h
 libb10_dhcp___la_SOURCES += iface_mgr_linux.cc
 libb10_dhcp___la_SOURCES += iface_mgr_sun.cc
 libb10_dhcp___la_SOURCES += libdhcp++.cc libdhcp++.h
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index e3ffe48..9338006 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -22,6 +22,7 @@
 #include <dhcp/dhcp4.h>
 #include <dhcp/dhcp6.h>
 #include <dhcp/iface_mgr.h>
+#include <dhcp/iface_mgr_error_handler.h>
 #include <dhcp/pkt_filter_inet.h>
 #include <dhcp/pkt_filter_inet6.h>
 #include <exceptions/exceptions.h>
@@ -37,40 +38,6 @@
 #include <string.h>
 #include <sys/select.h>
 
-/// @brief A macro which handles an error in IfaceMgr.
-///
-/// There are certain cases when IfaceMgr may hit an error which shouldn't
-/// result in interruption of the function processing. A typical case is
-/// the function which opens sockets on available interfaces for a DHCP
-/// server. If this function fails to open a socket on a specific interface
-/// (for example, there is another socket already open on this interface
-/// and bound to the same address and port), it is desired that the server
-/// logs a warning but will try to open sockets on other interfaces. In order
-/// to log an error, the IfaceMgr will use the error handler function provided
-/// by the server and pass an error string to it. When the handler function
-/// returns, the IfaceMgr will proceed to open other sockets. It is allowed
-/// that the error handler function is not installed (is NULL). In these
-/// cases it is expected that the exception is thrown instead. A possible
-/// solution would be to enclose this conditional behavior in a function.
-/// However, despite the hate for macros, the macro seems to be a bit
-/// better solution in this case as it allows to convenietly pass an
-/// error string in a stream (not as a string).
-///
-/// @param ex_type Exception to be thrown if error_handler is NULL.
-/// @param handler Error handler function to be called or NULL to indicate
-/// that exception should be thrown instead.
-/// @param stream stream object holding an error string.
-#define IFACEMGR_ERROR(ex_type, handler, stream) \
-{ \
-    std::ostringstream oss__; \
-    oss__ << stream; \
-    if (handler) { \
-        handler(oss__.str()); \
-    } else { \
-        isc_throw(ex_type, oss__); \
-    } \
-} \
-
 using namespace std;
 using namespace isc::asiolink;
 using namespace isc::util::io::internal;
@@ -183,7 +150,7 @@ bool Iface::delAddress(const isc::asiolink::IOAddress& addr) {
     return (false);
 }
 
-bool Iface::delSocket(uint16_t sockfd) {
+bool Iface::delSocket(const uint16_t sockfd) {
     list<SocketInfo>::iterator sock = sockets_.begin();
     while (sock!=sockets_.end()) {
         if (sock->sockfd_ == sockfd) {
@@ -530,59 +497,13 @@ IfaceMgr::openSockets6(const uint16_t port,
                 continue;
             }
 
-            // Open socket and join multicast group only if the interface
-            // is multicast-capable.
-            // @todo The DHCPv6 requires multicast so we may want to think
-            // whether we want to open the socket on a multicast-incapable
-            // interface or not. For now, we prefer to be liberal and allow
-            // it for some odd use cases which may utilize non-multicast
-            // interfaces. Perhaps a warning should be emitted if the
-            // interface is not a multicast one.
-
-            // The sock variable will hold a socket descriptor. It may be
-            // used to close a socket if the function fails to bind to
-            // multicast address on Linux systems. Because we only bind
-            // a socket to multicast address on Linux, on other systems
-            // the sock variable will be initialized but unused. We have
-            // to suppress the cppcheck warning which shows up on non-Linux
-            // systems.
-            // cppcheck-suppress variableScope
-            int sock;
-            try {
-                // cppcheck-suppress unreadVariable
-                sock = openSocket(iface->getName(), *addr, port,
-                                  iface->flag_multicast_);
-
-            } catch (const Exception& ex) {
-                IFACEMGR_ERROR(SocketConfigError, error_handler,
-                               "Failed to open link-local socket on "
-                               " interface " << iface->getName() << ": "
-                               << ex.what());
-                continue;
+            // Run OS-specific function to open a socket on link-local address
+            // and join multicast group (non-Linux OSes), or open two sockets and
+            // bind one to link-local, another one to multicast address.
+            if (openMulticastSocket(*iface, *addr, port, error_handler)) {
+                ++count;
             }
 
-            count++;
-
-            /// @todo: Remove this ifdef once we start supporting BSD systems.
-#if defined(OS_LINUX)
-            // To receive multicast traffic, Linux requires binding socket to
-            // a multicast group. That in turn doesn't work on NetBSD.
-            if (iface->flag_multicast_) {
-                try {
-                    openSocket(iface->getName(),
-                               IOAddress(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
-                               port);
-                } catch (const Exception& ex) {
-                    // Delete previously opened socket.
-                    iface->delSocket(sock);
-                    IFACEMGR_ERROR(SocketConfigError, error_handler,
-                                   "Failed to open multicast socket on"
-                                   " interface " << iface->getName()
-                                   << ", reason: " << ex.what());
-                    continue;
-                }
-            }
-#endif
         }
     }
     return (count > 0);
@@ -807,7 +728,6 @@ IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
     return IOAddress(local_address);
 }
 
-
 int
 IfaceMgr::openSocket6(Iface& iface, const IOAddress& addr, uint16_t port,
                       const bool join_multicast) {
@@ -1129,6 +1049,5 @@ IfaceMgr::getSocket(isc::dhcp::Pkt4 const& pkt) {
               << " does not have any suitable IPv4 sockets open.");
 }
 
-
 } // end of namespace isc::dhcp
 } // end of namespace isc
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index 3fde867..5a26c5d 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -34,6 +34,7 @@ namespace isc {
 
 namespace dhcp {
 
+
 /// @brief IfaceMgr exception thrown thrown when interface detection fails.
 class IfaceDetectError : public Exception {
 public:
@@ -1002,6 +1003,29 @@ private:
                     const uint16_t port);
 
 
+    /// @brief Open an IPv6 socket with multicast support.
+    ///
+    /// This function opens socket(s) to allow reception of the DHCPv6 sent
+    /// to multicast address. It opens an IPv6 socket, binds it to link-local
+    /// address and joins multicast group (on non-Linux systems) or opens two
+    /// IPv6 sockets and binds one of them to link-local address and another
+    /// one to multicast address (on Linux systems).
+    ///
+    /// @note This function is intended to be called internally by the
+    /// @c IfaceMgr::openSockets6. It is not intended to be called from any
+    /// other function.
+    ///
+    /// @param iface Interface on which socket should be open.
+    /// @param addr Link-local address to bind the socket to.
+    /// @param port Port number to bind socket to.
+    /// @param error_handler Error handler function to be called when an
+    /// error occurs during opening a socket, or NULL if exception should
+    /// be thrown upon error.
+    bool openMulticastSocket(Iface& iface,
+                             const isc::asiolink::IOAddress addr,
+                             const uint16_t port,
+                             IfaceMgrErrorMsgCallback error_handler = NULL);
+
     /// Holds instance of a class derived from PktFilter, used by the
     /// IfaceMgr to open sockets and send/receive packets through these
     /// sockets. It is possible to supply custom object using
diff --git a/src/lib/dhcp/iface_mgr_bsd.cc b/src/lib/dhcp/iface_mgr_bsd.cc
index be73bcf..cf6c3e2 100644
--- a/src/lib/dhcp/iface_mgr_bsd.cc
+++ b/src/lib/dhcp/iface_mgr_bsd.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011, 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,7 @@
 #if defined(OS_BSD)
 
 #include <dhcp/iface_mgr.h>
+#include <dhcp/iface_mgr_error_handler.h>
 #include <dhcp/pkt_filter_inet.h>
 #include <exceptions/exceptions.h>
 
@@ -149,6 +150,28 @@ IfaceMgr::setMatchingPacketFilter(const bool /* direct_response_desired */) {
     setPacketFilter(PktFilterPtr(new PktFilterInet()));
 }
 
+bool
+IfaceMgr::openMulticastSocket(Iface& iface,
+                              const isc::asiolink::IOAddress addr,
+                              const uint16_t port,
+                              IfaceMgrErrorMsgCallback error_handler) {
+    try {
+        // This should open a socket, bound it to link-local address
+        // and join multicast group.
+        openSocket(iface.getName(), addr, port,
+                   iface.flag_multicast_);
+
+    } catch (const Exception& ex) {
+        IFACEMGR_ERROR(SocketConfigError, error_handler,
+                       "Failed to open link-local socket on "
+                       " interface " << iface.getName() << ": "
+                       << ex.what());
+        return (false);
+
+    }
+    return (true);
+}
+
 
 } // end of isc::dhcp namespace
 } // end of dhcp namespace
diff --git a/src/lib/dhcp/iface_mgr_error_handler.h b/src/lib/dhcp/iface_mgr_error_handler.h
new file mode 100644
index 0000000..c5ef5b4
--- /dev/null
+++ b/src/lib/dhcp/iface_mgr_error_handler.h
@@ -0,0 +1,52 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef IFACE_MGR_ERROR_HANDLER_H
+#define IFACE_MGR_ERROR_HANDLER_H
+
+/// @brief A macro which handles an error in IfaceMgr.
+///
+/// There are certain cases when IfaceMgr may hit an error which shouldn't
+/// result in interruption of the function processing. A typical case is
+/// the function which opens sockets on available interfaces for a DHCP
+/// server. If this function fails to open a socket on a specific interface
+/// (for example, there is another socket already open on this interface
+/// and bound to the same address and port), it is desired that the server
+/// logs a warning but will try to open sockets on other interfaces. In order
+/// to log an error, the IfaceMgr will use the error handler function provided
+/// by the server and pass an error string to it. When the handler function
+/// returns, the IfaceMgr will proceed to open other sockets. It is allowed
+/// that the error handler function is not installed (is NULL). In these
+/// cases it is expected that the exception is thrown instead. A possible
+/// solution would be to enclose this conditional behavior in a function.
+/// However, despite the hate for macros, the macro seems to be a bit
+/// better solution in this case as it allows to convenietly pass an
+/// error string in a stream (not as a string).
+///
+/// @param ex_type Exception to be thrown if error_handler is NULL.
+/// @param handler Error handler function to be called or NULL to indicate
+/// that exception should be thrown instead.
+/// @param stream stream object holding an error string.
+#define IFACEMGR_ERROR(ex_type, handler, stream) \
+{ \
+    std::ostringstream oss__; \
+    oss__ << stream; \
+    if (handler) { \
+        handler(oss__.str()); \
+    } else { \
+        isc_throw(ex_type, oss__); \
+    } \
+} \
+
+#endif // IFACE_MGR_ERROR_HANDLER_H
diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc
index dddeb52..eaa625e 100644
--- a/src/lib/dhcp/iface_mgr_linux.cc
+++ b/src/lib/dhcp/iface_mgr_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -33,6 +33,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcp/iface_mgr.h>
+#include <dhcp/iface_mgr_error_handler.h>
 #include <dhcp/pkt_filter_inet.h>
 #include <dhcp/pkt_filter_lpf.h>
 #include <exceptions/exceptions.h>
@@ -533,6 +534,60 @@ bool IfaceMgr::os_receive4(struct msghdr&, Pkt4Ptr&) {
     return (true);
 }
 
+bool
+IfaceMgr::openMulticastSocket(Iface& iface,
+                              const isc::asiolink::IOAddress addr,
+                              const uint16_t port,
+                              IfaceMgrErrorMsgCallback error_handler) {
+    // This variable will hold a descriptor of the socket bound to
+    // link-local address. It may be required for us to close this
+    // socket if an attempt to open and bind a socket to multicast
+    // address fails.
+    int sock;
+    try {
+        sock = openSocket(iface.getName(), addr, port,
+                          iface.flag_multicast_);
+
+    } catch (const Exception& ex) {
+        IFACEMGR_ERROR(SocketConfigError, error_handler,
+                       "Failed to open link-local socket on "
+                       " interface " << iface.getName() << ": "
+                       << ex.what());
+        return (false);
+
+    }
+
+    // To receive multicast traffic, Linux requires binding socket to
+    // the multicast address.
+
+    /// @todo The DHCPv6 requires multicast so we may want to think
+    /// whether we want to open the socket on a multicast-incapable
+    /// interface or not. For now, we prefer to be liberal and allow
+    /// it for some odd use cases which may utilize non-multicast
+    /// interfaces. Perhaps a warning should be emitted if the
+    /// interface is not a multicast one.
+    if (iface.flag_multicast_) {
+        try {
+            openSocket(iface.getName(),
+                       IOAddress(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
+                       port);
+        } catch (const Exception& ex) {
+            // An attempt to open and bind a socket to multicast addres
+            // has failed. We have to close the socket we previously
+            // bound to link-local address - this is everything or
+            // nothing strategy.
+            iface.delSocket(sock);
+            IFACEMGR_ERROR(SocketConfigError, error_handler,
+                           "Failed to open multicast socket on"
+                           " interface " << iface.getName()
+                           << ", reason: " << ex.what());
+            return (false);
+        }
+    }
+    // Both sockets have opened successfully.
+    return (true);
+}
+
 } // end of isc::dhcp namespace
 } // end of isc namespace
 
diff --git a/src/lib/dhcp/iface_mgr_sun.cc b/src/lib/dhcp/iface_mgr_sun.cc
index fe2b0b3..0a9f9b4 100644
--- a/src/lib/dhcp/iface_mgr_sun.cc
+++ b/src/lib/dhcp/iface_mgr_sun.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011, 2013-2014 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,7 @@
 #if defined(OS_SUN)
 
 #include <dhcp/iface_mgr.h>
+#include <dhcp/iface_mgr_error_handler.h>
 #include <dhcp/pkt_filter_inet.h>
 #include <exceptions/exceptions.h>
 
@@ -153,6 +154,28 @@ IfaceMgr::setMatchingPacketFilter(const bool /* direct_response_desired */) {
     setPacketFilter(PktFilterPtr(new PktFilterInet()));
 }
 
+bool
+IfaceMgr::openMulticastSocket(Iface& iface,
+                              const isc::asiolink::IOAddress addr,
+                              const uint16_t port,
+                              IfaceMgrErrorMsgCallback error_handler) {
+    try {
+        // This should open a socket, bound it to link-local address
+        // and join multicast group.
+        openSocket(iface.getName(), addr, port,
+                   iface.flag_multicast_);
+
+    } catch (const Exception& ex) {
+        IFACEMGR_ERROR(SocketConfigError, error_handler,
+                       "Failed to open link-local socket on "
+                       " interface " << iface.getName() << ": "
+                       << ex.what());
+        return (false);
+
+    }
+    return (true);
+}
+
 } // end of isc::dhcp namespace
 } // end of dhcp namespace
 



More information about the bind10-changes mailing list