BIND 10 trac1957, updated. 6df91c2dc854f8068a7f8aceb6b28ce380267ac1 [1957] Implemented openSocketFromRemoteAddress method.

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jun 14 19:01:16 UTC 2012


The branch, trac1957 has been updated
       via  6df91c2dc854f8068a7f8aceb6b28ce380267ac1 (commit)
      from  b8306189256e5bceeb3017817681ecb9c39b5736 (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 6df91c2dc854f8068a7f8aceb6b28ce380267ac1
Author: Marcin Siodelski <marcin at isc.org>
Date:   Thu Jun 14 20:48:44 2012 +0200

    [1957] Implemented openSocketFromRemoteAddress method.

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

Summary of changes:
 src/lib/dhcp/iface_mgr.cc                |   75 ++++++++++++++++++++++--------
 src/lib/dhcp/iface_mgr.h                 |   63 ++++++++++++++++++++++---
 src/lib/dhcp/tests/iface_mgr_unittest.cc |   24 +++++++---
 3 files changed, 131 insertions(+), 31 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc
index 345acc7..7a7e54c 100644
--- a/src/lib/dhcp/iface_mgr.cc
+++ b/src/lib/dhcp/iface_mgr.cc
@@ -23,6 +23,9 @@
 #include <dhcp/dhcp6.h>
 #include <dhcp/iface_mgr.h>
 #include <exceptions/exceptions.h>
+#include <asio.hpp>
+#include <asiolink/udp_endpoint.h>
+#include <asio/error.hpp>
 #include <asiolink/io_error.h>
 #include <util/io/pktinfo_utilities.h>
 
@@ -279,7 +282,7 @@ bool IfaceMgr::openSockets6(const uint16_t port) {
 
         AddressCollection addrs = iface->getAddresses();
 
-        for (AddressCollection::iterator addr= addrs.begin();
+        for (AddressCollection::iterator addr = addrs.begin();
              addr != addrs.end();
              ++addr) {
 
@@ -413,7 +416,6 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
              addr != addrs.end();
              ++addr) {
 
-            // skip IPv4 addresses
             if (addr->getFamily() != family) {
                 continue;
             }
@@ -428,8 +430,8 @@ int IfaceMgr::openSocketFromIface(const std::string& ifname,
     return (sock);
 }
 
-int IfaceMgr::openSocketFromAddr(const std::string& addr_name,
-                                 const uint16_t port) {
+int IfaceMgr::openSocketFromAddress(const IOAddress& addr,
+                                    const uint16_t port) {
     int sock = 0;
     for (IfaceCollection::iterator iface=ifaces_.begin();
          iface!=ifaces_.end();
@@ -437,13 +439,12 @@ int IfaceMgr::openSocketFromAddr(const std::string& addr_name,
 
         AddressCollection addrs = iface->getAddresses();
 
-        for (AddressCollection::iterator addr = addrs.begin();
-             addr != addrs.end();
-             ++addr) {
+        for (AddressCollection::iterator addr_it = addrs.begin();
+             addr_it != addrs.end();
+             ++addr_it) {
 
             try {
-                IOAddress searched_addr(addr_name);
-                if (addr->getAddress() != searched_addr.getAddress()) {
+                if (addr_it->getAddress() != addr.getAddress()) {
                     continue;
                 }
             } catch (const isc::asiolink::IOError& e) {
@@ -452,26 +453,62 @@ int IfaceMgr::openSocketFromAddr(const std::string& addr_name,
                 return (sock);
             }
 
-            sock = openSocket(iface->getName(), *addr, port);
-            if (sock<0) {
+            sock = openSocket(iface->getName(), *addr_it, port);
+            if (sock < 0) {
                 cout << "Failed to open unicast socket." << endl;
             }
             return (sock);
         }
     }
     return (sock);
+}
+
+int IfaceMgr::openSocketFromRemoteAddress(const IOAddress& remote_addr,
+                                          const uint16_t port) {
+    int sock = 0;
+    IOAddress local_address(getLocalAddress(remote_addr, port).getAddress());
+
+    for (IfaceCollection::iterator iface=ifaces_.begin();
+         iface!=ifaces_.end();
+         ++iface) {
+
+        AddressCollection addrs = iface->getAddresses();
 
+        for (AddressCollection::iterator addr = addrs.begin();
+             addr != addrs.end();
+             ++addr) {
+
+            if (addr->getAddress() != local_address.getAddress()) {
+                continue;
+            }
+
+            sock = openSocket(iface->getName(), *addr, port);
+            if (sock < 0) {
+                cout << "Failed to open unicast socket." << endl;
+            }
+            return (sock);
+        }
+    }
+    return (sock);
 }
 
-int IfaceMgr::openSocketFromRemoteAddr(const std::string&,
-                                       const uint16_t,
-                                       const uint8_t) {
-    /*
-int IfaceMgr::openSocketFromRemoteAddr(const std::string& remote_addr_name,
-                                       const uint16_t port,
-                                       const uint8_t family) {*/
+isc::asiolink::IOAddress
+IfaceMgr::getLocalAddress(const IOAddress& remote_addr, const uint16_t port) {
+    boost::shared_ptr<const UDPEndpoint>
+        remote_endpoint(static_cast<const UDPEndpoint*>
+                        (UDPEndpoint::create(IPPROTO_UDP, remote_addr, port)));
+    asio::io_service io_service;
+    asio::ip::udp::socket sock(io_service);
+    asio::error_code err_code;
+    sock.connect(remote_endpoint->getASIOEndpoint(), err_code);
+    if (err_code) {
+        isc_throw(Unexpected,"Failed to connect to remote address.");
+    }
+
+    asio::ip::udp::socket::endpoint_type local_endpoint =  sock.local_endpoint();
+    asio::ip::address local_address(local_endpoint.address());
 
-    return 0;
+    return IOAddress(local_address);
 }
 
 int IfaceMgr::openSocket4(Iface& iface, const IOAddress& addr, uint16_t port) {
diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h
index 17e4b79..d6af42c 100644
--- a/src/lib/dhcp/iface_mgr.h
+++ b/src/lib/dhcp/iface_mgr.h
@@ -373,16 +373,51 @@ public:
     /// @return socket descriptor, if socket creation, binding and multicast
     /// group join were all successful.
     int openSocket(const std::string& ifname,
-                   const isc::asiolink::IOAddress& addr, const uint16_t port);
+                   const isc::asiolink::IOAddress& addr,
+                   const uint16_t port);
 
-    int openSocketFromIface(const std::string& ifname, const uint16_t port,
+    /// @brief Opens UDP/IP socket and binds it to interface specified.
+    ///
+    /// This method differs from \ref openSocket such that it allows
+    /// not to specify local address to which socket will be bound.
+    /// Instead, method searches through addresses on specified
+    /// interface and selects one that matches address family.
+    ///
+    /// @param ifname name of the interface
+    /// @param addr address to be bound
+    /// @param port UDP port
+    /// @return socket descriptor, if socket creation, binding and multicast
+    /// group join were all successful.
+    int openSocketFromIface(const std::string& ifname,
+                            const uint16_t port,
                             const uint8_t family);
 
-    int openSocketFromAddr(const std::string& addr_name, const uint16_t port);
+    /// @brief Opens UDP/IP socket and binds to address specified
+    ///
+    /// This methods differs from \ref openSocket such that it allows
+    /// not to specify interface to which socket will be bound.
+    ///
+    /// @param addr address to be bound
+    /// @param port UDP port
+    /// @return socket descriptor, if socket creation, binding and multicast
+    /// group join were all successful.
+    int openSocketFromAddress(const isc::asiolink::IOAddress& addr,
+                              const uint16_t port);
+
+    /// @brief Opens UDP/IP socket to be used to connect to remote address
+    ///
+    /// This method identifies local address to be used to connect
+    /// to remote address specified as argument.
+    /// Once local address is idetified \ref openSocket is called
+    /// to open socket and bind it to interface, address and port.
+    ///
+    /// @param remote_addr remote address to connect to
+    /// @param port UDP port
+    /// @return socket descriptor, if socket creation, binding and multicast
+    /// group join were all successful.
+    int openSocketFromRemoteAddress(const isc::asiolink::IOAddress& remote_addr,
+                                    const uint16_t port);
 
-    int openSocketFromRemoteAddr(const std::string& remote_addr_name,
-                                 const uint16_t port,
-                                 const uint8_t family);
 
     /// Opens IPv6 sockets on detected interfaces.
     ///
@@ -537,6 +572,22 @@ private:
     joinMulticast(int sock, const std::string& ifname,
                   const std::string& mcast);
 
+    /// @brief Identifies local network address to be used to
+    /// connect to remote address.
+    ///
+    /// This method identifies local network address that can be used
+    /// to connect to remote address specified.
+    /// This method creates socket and makes attempt to connect
+    /// to remote location via this socket. If connection
+    /// is established successfully, the local address to which
+    /// socket is bound is returned.
+    ///
+    /// @param remote_addr remote address to connect to
+    /// @param port port to be used
+    /// @return local address to be used to connect to remote address
+    isc::asiolink::IOAddress
+    getLocalAddress(const isc::asiolink::IOAddress& remote_addr,
+                    const uint16_t port);
 };
 
 }; // namespace isc::dhcp
diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc
index e5ce2ef..7864ccd 100644
--- a/src/lib/dhcp/tests/iface_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc
@@ -258,15 +258,17 @@ TEST_F(IfaceMgrTest, socketsFromIface) {
 }
 
 
-TEST_F(IfaceMgrTest, socketsFromAddr) {
+TEST_F(IfaceMgrTest, socketsFromAddress) {
     NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
 
     // open v6 socket on loopback address and bind to 10547 port
-    int socket1 = ifacemgr->openSocketFromAddr("::1", 10547);
+    IOAddress loAddr6("::1");
+    int socket1 = ifacemgr->openSocketFromAddress(loAddr6, 10547);
     EXPECT_GT(socket1, 0);
 
-    // open v4 socket on loopback address and bind to 10548 port
-    int socket2 = ifacemgr->openSocketFromAddr("127.0.0.1", 10548);
+    // open v4 socket on loopip::udp::socketback address and bind to 10548 port
+    IOAddress loAddr("127.0.0.1");
+    int socket2 = ifacemgr->openSocketFromAddress(loAddr, 10548);
     EXPECT_GT(socket2, 0);
 
     close(socket1);
@@ -275,13 +277,23 @@ TEST_F(IfaceMgrTest, socketsFromAddr) {
     delete ifacemgr;
 }
 
-TEST_F(IfaceMgrTest, socketsFromRemoteAddr) {
+TEST_F(IfaceMgrTest, socketsFromRemoteAddress) {
     NakedIfaceMgr* ifacemgr = new NakedIfaceMgr();
 
-    int socket1 = ifacemgr->openSocketFromRemoteAddr("::1", 10547, AF_INET6);
+    // 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.
+    IOAddress loAddr6("::1");
+    int socket1 = ifacemgr->openSocketFromRemoteAddress(loAddr6, 10547);
     EXPECT_GT(socket1, 0);
 
+    // Open v4 socket to connect to remote address.
+    IOAddress loAddr("127.0.0.1");
+    int socket2 = ifacemgr->openSocketFromRemoteAddress(loAddr, 10548);
+    EXPECT_GT(socket2, 0);
+
     close(socket1);
+    close(socket2);
 
     delete ifacemgr;
 }



More information about the bind10-changes mailing list