BIND 10 trac575, updated. 2a66d3aaac4754cf1c91204a4b2da244bfa269bd [trac575] Test and interface to listen addresses

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Feb 18 20:38:53 UTC 2011


The branch, trac575 has been updated
       via  2a66d3aaac4754cf1c91204a4b2da244bfa269bd (commit)
       via  319a4f17b34706ccb023fe571c27e7843bb93bf8 (commit)
       via  9cbeddff8102fd9411417a94449e4933a767084f (commit)
       via  73cb54ee37f9de1c5daf4359e209eae696ff6108 (commit)
       via  a8acfae7e9bd6e453bb0a4e2f225c0858d6807ea (commit)
       via  1f569da203364723a3b78152b127b05075f0b9f0 (commit)
       via  59d88e0db46955ed083426327b1b467366ea352d (commit)
      from  8f77709804055982134db51383ee1455e7905692 (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 2a66d3aaac4754cf1c91204a4b2da244bfa269bd
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 21:37:46 2011 +0100

    [trac575] Test and interface to listen addresses
    
    Getting works, setting needs to propagate DNSService inside.

commit 319a4f17b34706ccb023fe571c27e7843bb93bf8
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 21:16:21 2011 +0100

    [trac575] Specification of config Auth.listen_on

commit 9cbeddff8102fd9411417a94449e4933a767084f
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 21:12:21 2011 +0100

    [trac575] Move the setting up of addresses
    
    Taken out from resolver and put into the server_common library.

commit 73cb54ee37f9de1c5daf4359e209eae696ff6108
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 20:54:38 2011 +0100

    [trac575] Test for installing of addresses

commit a8acfae7e9bd6e453bb0a4e2f225c0858d6807ea
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 19:56:10 2011 +0100

    [trac575] AddressList

commit 1f569da203364723a3b78152b127b05075f0b9f0
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 19:50:56 2011 +0100

    [trac575] Rename addr_t to AddressPair
    
    It's better name, both more descriptive and follows capitalization
    rules.

commit 59d88e0db46955ed083426327b1b467366ea352d
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Fri Feb 18 19:47:03 2011 +0100

    [trac575] Editorial fix
    
    Spaces around comma

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

Summary of changes:
 src/bin/auth/auth.spec.pre.in           |   35 +++++++++++++++
 src/bin/auth/auth_srv.cc                |   14 ++++++
 src/bin/auth/auth_srv.h                 |    9 ++++
 src/bin/auth/tests/auth_srv_unittest.cc |   24 ++++++++++
 src/bin/resolver/resolver.cc            |   73 +++++++-----------------------
 src/lib/server_common/Makefile.am       |    1 +
 src/lib/server_common/portconfig.cc     |   59 +++++++++++++++++++++++-
 src/lib/server_common/portconfig.h      |   42 +++++++++++++++++-
 8 files changed, 196 insertions(+), 61 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in
index 8a77455..869051e 100644
--- a/src/bin/auth/auth.spec.pre.in
+++ b/src/bin/auth/auth.spec.pre.in
@@ -57,6 +57,41 @@
         "item_type": "integer",
         "item_optional": true,
         "item_default": 60
+      },
+      {
+        "item_name": "listen_on",
+        "item_type": "list",
+        "item_optional": False,
+        "item_default": [
+          {
+            "address": "::1",
+            "port": 5300
+          },
+          {
+            "address": "127.0.0.1",
+            "port": 5300
+          },
+        ],
+        "list_item_spec": {
+          "item_name": "address",
+          "item_type": "map",
+          "item_optional": False,
+          "item_default": {},
+          "map_item_spec": [
+            {
+              "item_name": "address",
+              "item_type": "string",
+              "item_optional": False,
+              "item_default": "::1"
+            },
+            {
+              "item_name": "port",
+              "item_type": "integer",
+              "item_optional": False,
+              "item_default": 5300
+            }
+          ]
+        }
       }
     ],
     "commands": [
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 045fe7f..cd3d01f 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -69,6 +69,7 @@ using namespace isc::data;
 using namespace isc::config;
 using namespace isc::xfr;
 using namespace asiolink;
+using namespace isc::server_common::portconfig;
 
 class AuthSrvImpl {
 private:
@@ -109,6 +110,9 @@ public:
 
     /// Query counters for statistics
     AuthCounters counters_;
+
+    /// Addresses we listen on
+    AddressList listen_addresses_;
 private:
     std::string db_file_;
 
@@ -750,3 +754,13 @@ uint64_t
 AuthSrv::getCounter(const AuthCounters::CounterType type) const {
     return (impl_->counters_.getCounter(type));
 }
+
+const AddressList&
+AuthSrv::getListenAddresses() const {
+    return (impl_->listen_addresses_);
+}
+
+void
+AuthSrv::setListenAddresses(const AddressList& ) {
+    // TODO Implement
+}
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 4772a02..b23fc67 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -25,6 +25,7 @@
 #include <config/ccsession.h>
 
 #include <asiolink/asiolink.h>
+#include <server_common/portconfig.h>
 #include <auth/statistics.h>
 
 namespace isc {
@@ -353,6 +354,14 @@ public:
     /// \return the value of the counter.
     uint64_t getCounter(const AuthCounters::CounterType type) const;
 
+    /**
+     * \brief Set and get the addresses we listen on.
+     */
+    void setListenAddresses(const isc::server_common::portconfig::AddressList&
+                            addreses);
+    const isc::server_common::portconfig::AddressList& getListenAddresses()
+        const;
+
 private:
     AuthSrvImpl* impl_;
     asiolink::SimpleCallback* checkin_;
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 576799c..7a92dc4 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -26,6 +26,8 @@
 #include <dns/rrttl.h>
 #include <dns/rdataclass.h>
 
+#include <server_common/portconfig.h>
+
 #include <datasrc/memory_datasrc.h>
 #include <auth/auth_srv.h>
 #include <auth/common.h>
@@ -43,6 +45,7 @@ using namespace isc::data;
 using namespace isc::xfr;
 using namespace asiolink;
 using namespace isc::testutils;
+using namespace isc::server_common::portconfig;
 using isc::UnitTestUtil;
 
 namespace {
@@ -650,4 +653,25 @@ TEST_F(AuthSrvTest, stop) {
     // If/when the interval timer has finer granularity we'll probably add
     // our own tests here, so we keep this empty test case.
 }
+
+TEST_F(AuthSrvTest, listenAddresses) {
+    // Default value should be not listening to anything
+    EXPECT_TRUE(server.getListenAddresses().empty());
+
+    // Try putting there some addresses
+    AddressList addresses;
+    addresses.push_back(AddressPair("127.0.0.1", 5321));
+    addresses.push_back(AddressPair("::1", 5321));
+    server.setListenAddresses(addresses);
+    ASSERT_EQ(2, server.getListenAddresses().size());
+    EXPECT_EQ("::1", server.getListenAddresses()[1].first);
+
+    // Is it independent from what we do with the vector later?
+    addresses.clear();
+    EXPECT_EQ(2, server.getListenAddresses().size());
+
+    // Did it return to empty list if we ask it to?
+    server.setListenAddresses(addresses);
+    EXPECT_TRUE(server.getListenAddresses().empty());
+}
 }
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index efdb1be..39a28d4 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -96,14 +96,14 @@ public:
         }
     }
 
-    void setForwardAddresses(const vector<addr_t>& upstream,
+    void setForwardAddresses(const vector<AddressPair>& upstream,
         DNSService *dnss)
     {
         upstream_ = upstream;
         if (dnss) {
             if (!upstream_.empty()) {
                 dlog("Setting forward addresses:");
-                BOOST_FOREACH(const addr_t& address, upstream) {
+                BOOST_FOREACH(const AddressPair& address, upstream) {
                     dlog(" " + address.first + ":" +
                         boost::lexical_cast<string>(address.second));
                 }
@@ -113,14 +113,14 @@ public:
         }
     }
 
-    void setRootAddresses(const vector<addr_t>& upstream_root,
+    void setRootAddresses(const vector<AddressPair>& upstream_root,
                           DNSService *dnss)
     {
         upstream_root_ = upstream_root;
         if (dnss) {
             if (!upstream_root_.empty()) {
                 dlog("Setting root addresses:");
-                BOOST_FOREACH(const addr_t& address, upstream_root) {
+                BOOST_FOREACH(const AddressPair& address, upstream_root) {
                     dlog(" " + address.first + ":" +
                         boost::lexical_cast<string>(address.second));
                 }
@@ -144,11 +144,11 @@ public:
     /// These members are public because Resolver accesses them directly.
     ModuleCCSession* config_session_;
     /// Addresses of the root nameserver(s)
-    vector<addr_t> upstream_root_;
+    vector<AddressPair> upstream_root_;
     /// Addresses of the forward nameserver
-    vector<addr_t> upstream_;
+    vector<AddressPair> upstream_;
     /// Addresses we listen on
-    vector<addr_t> listen_;
+    vector<AddressPair> listen_;
 
     /// Timeout for outgoing queries in milliseconds
     int query_timeout_;
@@ -467,13 +467,13 @@ Resolver::updateConfig(ConstElementPtr config) {
     try {
         // Parse forward_addresses
         ConstElementPtr rootAddressesE(config->get("root_addresses"));
-        vector<addr_t> rootAddresses(parseAddresses(rootAddressesE,
+        vector<AddressPair> rootAddresses(parseAddresses(rootAddressesE,
                                                     "root_addresses"));
         ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
-        vector<addr_t> forwardAddresses(parseAddresses(forwardAddressesE,
+        vector<AddressPair> forwardAddresses(parseAddresses(forwardAddressesE,
                                                        "forward_addresse"));
         ConstElementPtr listenAddressesE(config->get("listen_on"));
-        vector<addr_t> listenAddresses(parseAddresses(listenAddressesE,
+        vector<AddressPair> listenAddresses(parseAddresses(listenAddressesE,
                                                       "listen_on"));
         bool set_timeouts(false);
         int qtimeout = impl_->query_timeout_;
@@ -547,13 +547,13 @@ Resolver::updateConfig(ConstElementPtr config) {
 }
 
 void
-Resolver::setForwardAddresses(const vector<addr_t>& addresses)
+Resolver::setForwardAddresses(const vector<AddressPair>& addresses)
 {
     impl_->setForwardAddresses(addresses, dnss_);
 }
 
 void
-Resolver::setRootAddresses(const vector<addr_t>& addresses)
+Resolver::setRootAddresses(const vector<AddressPair>& addresses)
 {
     impl_->setRootAddresses(addresses, dnss_);
 }
@@ -563,58 +563,19 @@ Resolver::isForwarding() const {
     return (!impl_->upstream_.empty());
 }
 
-vector<addr_t>
+vector<AddressPair>
 Resolver::getForwardAddresses() const {
     return (impl_->upstream_);
 }
 
-vector<addr_t>
+vector<AddressPair>
 Resolver::getRootAddresses() const {
     return (impl_->upstream_root_);
 }
 
-namespace {
-
-void
-setAddresses(DNSService *service, const vector<addr_t>& addresses) {
-    service->clearServers();
-    BOOST_FOREACH(const addr_t &address, addresses) {
-        service->addServer(address.second, address.first);
-    }
-}
-
-}
-
 void
-Resolver::setListenAddresses(const vector<addr_t>& addresses) {
-    try {
-        dlog("Setting listen addresses:");
-        BOOST_FOREACH(const addr_t& addr, addresses) {
-            dlog(" " + addr.first + ":" +
-                        boost::lexical_cast<string>(addr.second));
-        }
-        setAddresses(dnss_, addresses);
-        impl_->listen_ = addresses;
-    }
-    catch (const exception& e) {
-        /*
-         * We couldn't set it. So return it back. If that fails as well,
-         * we have a problem.
-         *
-         * If that fails, bad luck, but we are useless anyway, so just die
-         * and let boss start us again.
-         */
-        dlog(string("Unable to set new address: ") + e.what(),true);
-        try {
-            setAddresses(dnss_, impl_->listen_);
-        }
-        catch (const exception& e2) {
-            dlog(string("Unable to recover from error;"),true);
-            dlog(string("Rollback failed with: ") + e2.what(),true);
-            abort();
-        }
-        throw e; // Let it fly a little bit further
-    }
+Resolver::setListenAddresses(const vector<AddressPair>& addresses) {
+    installListenAddresses(addresses, impl_->listen_, *dnss_);
 }
 
 void
@@ -650,7 +611,7 @@ Resolver::getRetries() const {
     return impl_->retries_;
 }
 
-vector<addr_t>
+vector<AddressPair>
 Resolver::getListenAddresses() const {
     return (impl_->listen_);
 }
diff --git a/src/lib/server_common/Makefile.am b/src/lib/server_common/Makefile.am
index 9ba3d77..dfb3014 100644
--- a/src/lib/server_common/Makefile.am
+++ b/src/lib/server_common/Makefile.am
@@ -21,5 +21,6 @@ libserver_common_la_SOURCES = portconfig.h portconfig.cc
 libserver_common_la_LIBADD = $(top_builddir)/src/lib/exceptions/libexceptions.la
 libserver_common_la_LIBADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 libserver_common_la_LIBADD += $(top_builddir)/src/lib/cc/libcc.la
+libserver_common_la_LIBADD += $(top_builddir)/src/lib/log/liblog.la
 
 CLEANFILES = *.gcno *.gcda
diff --git a/src/lib/server_common/portconfig.cc b/src/lib/server_common/portconfig.cc
index 2957c69..4b632e9 100644
--- a/src/lib/server_common/portconfig.cc
+++ b/src/lib/server_common/portconfig.cc
@@ -15,20 +15,26 @@
 #include "portconfig.h"
 
 #include <asiolink/io_address.h>
+#include <asiolink/dns_service.h>
+#include <log/dummylog.h>
+
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
 
 using namespace std;
 using namespace isc::data;
 using namespace asiolink;
+using isc::log::dlog;
 
 namespace isc {
 namespace server_common {
 namespace portconfig {
 
-std::vector<addr_t>
+AddressList
 parseAddresses(isc::data::ConstElementPtr addresses,
                const std::string& elemName)
 {
-    vector<addr_t> result;
+    AddressList result;
     if (addresses) {
         if (addresses->getType() == Element::list) {
             for (size_t i(0); i < addresses->size(); ++ i) {
@@ -46,7 +52,7 @@ parseAddresses(isc::data::ConstElementPtr addresses,
                         isc_throw(BadValue, "Bad port value (" <<
                             port->intValue() << ")");
                     }
-                    result.push_back(addr_t(addr->stringValue(),
+                    result.push_back(AddressPair(addr->stringValue(),
                         port->intValue()));
                 }
                 catch (const TypeError &e) { // Better error message
@@ -61,6 +67,53 @@ parseAddresses(isc::data::ConstElementPtr addresses,
     return (result);
 }
 
+namespace {
+
+void
+setAddresses(DNSService& service, const AddressList& addresses) {
+    service.clearServers();
+    BOOST_FOREACH(const AddressPair &address, addresses) {
+        service.addServer(address.second, address.first);
+    }
+}
+
+}
+
+void
+installListenAddresses(const AddressList& newAddresses,
+                       AddressList& addressStore,
+                       asiolink::DNSService& service)
+{
+    try {
+        dlog("Setting listen addresses:");
+        BOOST_FOREACH(const AddressPair& addr, newAddresses) {
+            dlog(" " + addr.first + ":" +
+                        boost::lexical_cast<string>(addr.second));
+        }
+        setAddresses(service, newAddresses);
+        addressStore = newAddresses;
+    }
+    catch (const exception& e) {
+        /*
+         * We couldn't set it. So return it back. If that fails as well,
+         * we have a problem.
+         *
+         * If that fails, bad luck, but we are useless anyway, so just die
+         * and let boss start us again.
+         */
+        dlog(string("Unable to set new address: ") + e.what(), true);
+        try {
+            setAddresses(service, addressStore);
+        }
+        catch (const exception& e2) {
+            dlog("Unable to recover from error;", true);
+            dlog(string("Rollback failed with: ") + e2.what(), true);
+            abort();
+        }
+        throw e; // Let it fly a little bit further
+    }
+}
+
 }
 }
 }
diff --git a/src/lib/server_common/portconfig.h b/src/lib/server_common/portconfig.h
index 6d8c2fb..bcb8528 100644
--- a/src/lib/server_common/portconfig.h
+++ b/src/lib/server_common/portconfig.h
@@ -22,6 +22,13 @@
 
 #include <cc/data.h>
 
+/*
+ * Some forward declarations.
+ */
+namespace asiolink {
+class DNSService;
+}
+
 namespace isc {
 namespace server_common {
 /**
@@ -39,7 +46,10 @@ namespace portconfig {
  * number. Anything more fancy would be an overkill, it is used only to pass
  * the addresses and ports around as intermediate results.
  */
-typedef std::pair<std::string, uint16_t> addr_t;
+typedef std::pair<std::string, uint16_t> AddressPair;
+
+/// \brief Bunch of address pairs
+typedef std::vector<AddressPair> AddressList;
 
 /**
  * \brief
@@ -72,10 +82,38 @@ typedef std::pair<std::string, uint16_t> addr_t;
  *     element in the hash, port number out of range).
  * \throw std::bad_alloc when allocation fails.
  */
-std::vector<addr_t>
+AddressList
 parseAddresses(isc::data::ConstElementPtr addresses,
                const std::string& elemName);
 
+/**
+ * \brief Changes current listening addresses and ports.
+ *
+ * Removes all sockets we currently listen on and starts listening on the
+ * addresses and ports requested in newAddresses.
+ *
+ * If it fails to set up the new addresses, it attempts to roll back to the
+ * previous addresses (but it still propagates the exception). If the rollback
+ * fails as well, it aborts the application (it assumes if it can't listen
+ * on the new addresses nor on the old ones, the application is useless anyway
+ * and should be restarted by Boss, not to mention that the internal state is
+ * probably broken).
+ *
+ * \param newAddresses are the addresses you want to listen on.
+ * \param addressStore is the place you store your current addresses. It is
+ *     used when there's a need for rollback. The newAddresses are copied here
+ *     when the change is successful.
+ * \param dnsService is the DNSService object we use now. The requests from
+ *     the new sockets are handled using this dnsService (and all current
+ *     sockets on the service are closed first).
+ * \throw asiolink::IOError when initialization or closing of socket fails.
+ * \throw std::bad_alloc when allocation fails.
+ */
+void
+installListenAddresses(const AddressList& newAddresses,
+                       AddressList& addressStore,
+                       asiolink::DNSService& dnsService);
+
 }
 }
 }




More information about the bind10-changes mailing list