BIND 10 trac1957, updated. 66d9922628755b55d297c03e02d5c7fb2614f8ac [trac1957] Throwing exception if unable to find address to create socket.

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Jul 6 09:52:09 UTC 2012


The branch, trac1957 has been updated
       via  66d9922628755b55d297c03e02d5c7fb2614f8ac (commit)
      from  61667bcc9c013ce7d105609404c32cd5d83fa02c (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 66d9922628755b55d297c03e02d5c7fb2614f8ac
Author: Marcin Siodelski <marcin at isc.org>
Date:   Fri Jul 6 11:51:17 2012 +0200

    [trac1957] Throwing exception if unable to find address to create socket.

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

Summary of changes:
 src/lib/dhcp/iface_mgr.cc                |   56 ++++++++++++++++--------------
 src/lib/dhcp/iface_mgr.h                 |    4 +++
 src/lib/dhcp/tests/iface_mgr_unittest.cc |   30 ++++++++--------
 3 files changed, 50 insertions(+), 40 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index b57a24f..578cdb2 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -397,7 +397,6 @@ int IfaceMgr::openSocket(const std::string& ifname, const IOAddress& addr,
 int IfaceMgr::openSocketFromIface(const std::string& ifname,
                                   const uint16_t port,
                                   const uint8_t family) {
-    int sock = 0;
     // Search for specified interface among detected interfaces.
     for (IfaceCollection::iterator iface = ifaces_.begin();
          iface != ifaces_.end();
@@ -411,28 +410,36 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
         // Interface is now detected. Search for address on interface
         // that matches address family (v6 or v4).
         AddressCollection addrs = iface->getAddresses();
-        for (AddressCollection::iterator addr_it = addrs.begin();
-             addr_it != addrs.end();
-             ++addr_it) {
-
-            if (addr_it->getFamily() != family) {
-                continue;
+        AddressCollection::iterator addr_it = addrs.begin();
+        while (addr_it != addrs.end()) {
+            if (addr_it->getFamily() == family) {
+                // We have interface and address so let's open socket.
+                // This may cause isc::Unexpected exception.
+                return (openSocket(iface->getName(), *addr_it, port));
             }
-
-            // We have interface and address so let's open socket.
-            sock = openSocket(iface->getName(), *addr_it, port);
-            if (sock < 0) {
-                isc_throw(Unexpected, "Failed to open socket.");
+            ++addr_it;
+        }
+        // If we are at the end of address collection it means that we found
+        // interface but there is no address for family specified.
+        if (addr_it == addrs.end()) {
+            // Stringify the family value to append it to exception string.
+            std::string family_name("AF_INET");
+            if (family == AF_INET6) {
+                family_name = "AF_INET6";
             }
-            return (sock);
+            // We did not find address on the interface.
+            isc_throw(BadValue, "There is no address for interface: "
+                      << ifname << ", port: " << port << ", address "
+                      " family: " << family_name);
         }
     }
-    return (sock);
+    // If we got here it means that we had not found the specified interface.
+    // Otherwise we would have returned from previous exist points.
+    isc_throw(BadValue, "There is no " << ifname << " interface present.");
 }
 
 int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
                                     const uint16_t port) {
-    int sock = 0;
     // Search through detected interfaces and addresses to match
     // local address we got.
     for (IfaceCollection::iterator iface = ifaces_.begin();
@@ -449,19 +456,16 @@ int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
             // on detected interfaces. If it does, we have
             // address and interface detected so we can open
             // socket.
-            if (*addr_it != addr) {
-                continue;
+            if (*addr_it == addr) {
+                // Open socket using local interface, address and port.
+                // This may cause isc::Unexpected exception.
+                return (openSocket(iface->getName(), *addr_it, port));
             }
-
-            // Open socket using local interface, address and port.
-            sock = openSocket(iface->getName(), *addr_it, port);
-            if (sock < 0) {
-                isc_throw(Unexpected, "Failed to open unicast socket.");
-            }
-            return (sock);
         }
     }
-    return (sock);
+    // If we got here it means that we did not find specified address
+    // on any available interface.
+    isc_throw(BadValue, "There is no such address " << addr.toText());
 }
 
 int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
@@ -474,7 +478,7 @@ int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
 isc::asiolink::IOAddress
 IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
     // Create remote endpoint, we will be connecting to it.
-    boost::shared_ptr<const UDPEndpoint>
+    boost::scoped_ptr<const UDPEndpoint>
         remote_endpoint(static_cast<const UDPEndpoint*>
                         (UDPEndpoint::create(IPPROTO_UDP, remote_addr, port)));
     if (!remote_endpoint) {
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index 4517bdf..c191caa 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -389,6 +389,8 @@ public:
     /// @return socket descriptor, if socket creation, binding and multicast
     /// group join were all successful.
     /// @throw isc::Unexpected if failed to create and bind socket.
+    /// @throw isc::BadValue if there is no address on specified interface
+    /// that belongs to given family.
     int openSocketFromIface(const std::string& ifname,
                             const uint16_t port,
                             const uint8_t family);
@@ -403,6 +405,8 @@ public:
     /// @return socket descriptor, if socket creation, binding and multicast
     /// group join were all successful.
     /// @throw isc::Unexpected if failed to create and bind socket
+    /// @throw isc::BadValue if specified address is not available on
+    /// any interface
     int openSocketFromAddress(const isc::asiolink::IOAddress& addr,
                               const uint16_t port);
 
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index 5b97674..eb00632 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc
@@ -18,6 +18,7 @@
 #include <sstream>
 
 #include <arpa/inet.h>
+#include <boost/scoped_ptr.hpp>
 #include <gtest/gtest.h>
 
 #include <asiolink/io_address.h>
@@ -241,12 +242,13 @@ TEST_F(IfaceMgrTest, sockets6) {
 }
 
 TEST_F(IfaceMgrTest, socketsFromIface) {
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
     // open v6 socket on loopback interface and bind to 10547 port
     int socket1 = 0;
+    const uint16_t port1 = 10547;
     EXPECT_NO_THROW(
-        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, 10547, AF_INET6);
+        socket1 = ifacemgr->openSocketFromIface(LOOPBACK, port1, AF_INET6);
     );
     // socket descriptor must be positive integer
     EXPECT_GT(socket1, 0);
@@ -254,25 +256,26 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
 
     // open v4 sicket on loopback interface and bind to 10548 port
     int socket2 = 0;
+    const uint16_t port2 = 10548;
     EXPECT_NO_THROW(
-        socket2 = ifacemgr->openSocketFromIface(LOOPBACK, 10547, AF_INET);
+        socket2 = ifacemgr->openSocketFromIface(LOOPBACK, port2, AF_INET);
     );
     // socket descriptor must be positive integer
     EXPECT_GT(socket2, 0);
     close(socket2);
 
-    delete ifacemgr;
 }
 
 
 TEST_F(IfaceMgrTest, socketsFromAddress) {
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
     // open v6 socket on loopback address and bind to 10547 port
     int socket1 = 0;
+    const uint16_t port1 = 10547;
     IOAddress loAddr6("::1");
     EXPECT_NO_THROW(
-        socket1 = ifacemgr->openSocketFromAddress(loAddr6, 10547);
+        socket1 = ifacemgr->openSocketFromAddress(loAddr6, port1);
     );
     // socket descriptor must be positive integer
     EXPECT_GT(socket1, 0);
@@ -280,41 +283,40 @@ TEST_F(IfaceMgrTest, socketsFromAddress) {
 
     // open v4 socket on loopback address and bind to 10548 port
     int socket2 = 0;
+    const uint16_t port2 = 10548;
     IOAddress loAddr("127.0.0.1");
     EXPECT_NO_THROW(
-        socket2 = ifacemgr->openSocketFromAddress(loAddr, 10548);
+        socket2 = ifacemgr->openSocketFromAddress(loAddr, port2);
     );
     // socket descriptor must be positive integer
     EXPECT_GT(socket2, 0);
     close(socket2);
-
-    delete ifacemgr;
 }
 
 TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
-    NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
+    boost::scoped_ptr<NakedIfaceMgr> ifacemgr(new NakedIfaceMgr());
 
     // Open v6 socket to connect to remote address.
     // Loopback address is the only one that we know
     // so let's treat it as remote address.
     int socket1 = 0;
+    const uint16_t port1 = 10547;
     IOAddress loAddr6("::1");
     EXPECT_NO_THROW(
-        socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, 10547);
+        socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, port1);
     );
     EXPECT_GT(socket1, 0);
     close(socket1);
 
     // Open v4 socket to connect to remote address.
     int socket2 = 0;
+    const uint16_t port2 = 10548;
     IOAddress loAddr("127.0.0.1");
     EXPECT_NO_THROW(
-        socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, 10548);
+        socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, port2);
     );
     EXPECT_GT(socket2, 0);
     close(socket2);
-
-    delete ifacemgr;
 }
 
 // TODO: disabled due to other naming on various systems



More information about the bind10-changes mailing list