Browse Source

Merge branch 'trac483'

Conflicts:
	src/bin/resolver/resolver.cc
Jelte Jansen 14 years ago
parent
commit
a07e078b4f

+ 39 - 2
src/bin/resolver/resolver.cc

@@ -76,7 +76,7 @@ public:
     void querySetup(DNSService& dnss) {
         assert(!rec_query_); // queryShutdown must be called first
         dlog("Query setup");
-        rec_query_ = new RecursiveQuery(dnss, upstream_, timeout_, retries_);
+        rec_query_ = new RecursiveQuery(dnss, upstream_, upstream_root_, timeout_, retries_);
     }
 
     void queryShutdown() {
@@ -107,6 +107,25 @@ public:
         }
     }
 
+    void setRootAddresses(const vector<addr_t>& upstream_root,
+                          DNSService *dnss)
+    {
+        queryShutdown();
+        upstream_root_ = upstream_root;
+        if (dnss) {
+            if (!upstream_root_.empty()) {
+                dlog("Setting root addresses:");
+                BOOST_FOREACH(const addr_t& address, upstream_root) {
+                    dlog(" " + address.first + ":" +
+                        boost::lexical_cast<string>(address.second));
+                }
+            } else {
+                dlog("No root addresses");
+            }
+            querySetup(*dnss);
+        }
+    }
+
     void processNormalQuery(const Question& question,
                             MessagePtr answer_message,
                             OutputBufferPtr buffer,
@@ -117,6 +136,8 @@ public:
 
     /// These members are public because Resolver accesses them directly.
     ModuleCCSession* config_session_;
+    /// Addresses of the root nameserver(s)
+    vector<addr_t> upstream_root_;
     /// Addresses of the forward nameserver
     vector<addr_t> upstream_;
     /// Addresses we listen on
@@ -445,7 +466,7 @@ parseAddresses(ConstElementPtr addresses) {
             }
         } else if (addresses->getType() != Element::null) {
             isc_throw(TypeError,
-                "forward_addresses config element must be a list");
+                "root_addresses, forward_addresses, and listen_on config element must be a list");
         }
     }
     return (result);
@@ -459,6 +480,8 @@ Resolver::updateConfig(ConstElementPtr config) {
 
     try {
         // Parse forward_addresses
+        ConstElementPtr rootAddressesE(config->get("root_addresses"));
+        vector<addr_t> rootAddresses(parseAddresses(rootAddressesE));
         ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
         vector<addr_t> forwardAddresses(parseAddresses(forwardAddressesE));
         ConstElementPtr listenAddressesE(config->get("listen_on"));
@@ -496,6 +519,9 @@ Resolver::updateConfig(ConstElementPtr config) {
             setForwardAddresses(forwardAddresses);
             need_query_restart = true;
         }
+        if (rootAddressesE) {
+            setRootAddresses(rootAddresses);
+        }
         if (set_timeouts) {
             setTimeouts(timeout, retries);
             need_query_restart = true;
@@ -518,6 +544,12 @@ Resolver::setForwardAddresses(const vector<addr_t>& addresses)
     impl_->setForwardAddresses(addresses, dnss_);
 }
 
+void
+Resolver::setRootAddresses(const vector<addr_t>& addresses)
+{
+    impl_->setRootAddresses(addresses, dnss_);
+}
+
 bool
 Resolver::isForwarding() const {
     return (!impl_->upstream_.empty());
@@ -528,6 +560,11 @@ Resolver::getForwardAddresses() const {
     return (impl_->upstream_);
 }
 
+vector<addr_t>
+Resolver::getRootAddresses() const {
+    return (impl_->upstream_root_);
+}
+
 namespace {
 
 void

+ 18 - 0
src/bin/resolver/resolver.h

@@ -112,6 +112,24 @@ public:
     bool isForwarding() const;
 
     /**
+     * \brief Specify the list of root nameservers.
+     *
+     * Specify the list of addresses of root nameservers
+     *
+     * @param addresses The list of addresses to use (each one is the address
+     * and port pair).
+     */
+    void setRootAddresses(const std::vector<std::pair<std::string,
+                          uint16_t> >& addresses);
+
+    /**
+     * \short Get list of root addresses.
+     *
+     * \see setRootAddresses.
+     */
+    std::vector<std::pair<std::string, uint16_t> > getRootAddresses() const;
+
+    /**
      * Set and get the addresses we listen on.
      */
     void setListenAddresses(const std::vector<std::pair<std::string,

+ 26 - 0
src/bin/resolver/resolver.spec.pre.in

@@ -42,6 +42,32 @@
         }
       },
       {
+        "item_name": "root_addresses",
+        "item_type": "list",
+        "item_optional": True,
+        "item_default": [],
+        "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": 53
+            }
+          ]
+        }
+      },
+      {
         "item_name": "listen_on",
         "item_type": "list",
         "item_optional": False,

+ 25 - 0
src/bin/resolver/tests/resolver_config_unittest.cc

@@ -96,6 +96,31 @@ TEST_F(ResolverConfig, forwardAddressConfig) {
     EXPECT_EQ(0, server.getForwardAddresses().size());
 }
 
+TEST_F(ResolverConfig, rootAddressConfig) {
+    // Try putting there some address
+    ElementPtr config(Element::fromJSON("{"
+        "\"root_addresses\": ["
+        "   {"
+        "       \"address\": \"192.0.2.1\","
+        "       \"port\": 53"
+        "   }"
+        "]"
+        "}"));
+    ConstElementPtr result(server.updateConfig(config));
+    EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
+    ASSERT_EQ(1, server.getRootAddresses().size());
+    EXPECT_EQ("192.0.2.1", server.getRootAddresses()[0].first);
+    EXPECT_EQ(53, server.getRootAddresses()[0].second);
+
+    // And then remove all addresses
+    config = Element::fromJSON("{"
+        "\"root_addresses\": null"
+        "}");
+    result = server.updateConfig(config);
+    EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
+    EXPECT_EQ(0, server.getRootAddresses().size());
+}
+
 void
 ResolverConfig::invalidTest(const string &JOSN) {
     ElementPtr config(Element::fromJSON(JOSN));

+ 29 - 5
src/lib/asiolink/asiolink.cc

@@ -283,8 +283,11 @@ typedef std::vector<std::pair<std::string, uint16_t> > AddressVector;
 }
 
 RecursiveQuery::RecursiveQuery(DNSService& dns_service,
-    const AddressVector& upstream, int timeout, unsigned retries) :
+    const AddressVector& upstream,
+    const AddressVector& upstream_root,
+    int timeout, unsigned retries) :
     dns_service_(dns_service), upstream_(new AddressVector(upstream)),
+    upstream_root_(new AddressVector(upstream_root)),
     timeout_(timeout), retries_(retries)
 {}
 
@@ -344,6 +347,9 @@ private:
     // we should differentiate between forwarding and resolving
     shared_ptr<AddressVector> upstream_;
 
+    // root servers...just copied over to the zone_servers_
+    shared_ptr<AddressVector> upstream_root_;
+
     // Buffer to store the result.
     OutputBufferPtr buffer_;
 
@@ -468,12 +474,14 @@ private:
 public:
     RunningQuery(asio::io_service& io, const Question &question,
         MessagePtr answer_message, shared_ptr<AddressVector> upstream,
+        shared_ptr<AddressVector> upstream_root,
         OutputBufferPtr buffer, DNSServer* server, int timeout,
         unsigned retries) :
         io_(io),
         question_(question),
         answer_message_(answer_message),
         upstream_(upstream),
+        upstream_root_(upstream_root),
         buffer_(buffer),
         server_(server->clone()),
         timeout_(timeout),
@@ -483,9 +491,25 @@ public:
         dlog("Started a new RunningQuery");
         done = false;
 
-        // hardcoded f.root-servers.net now, should use NSAS
+        // should use NSAS for root servers
+        // Adding root servers if not a forwarder
         if (upstream_->empty()) {
-            zone_servers_.push_back(addr_t("192.5.5.241", 53));
+            if (upstream_root_->empty()) { //if no root ips given, use this
+                zone_servers_.push_back(addr_t("192.5.5.241", 53));
+            }
+            else
+            {
+              //copy the list
+              dlog("Size is " + 
+                    boost::lexical_cast<string>(upstream_root_->size()) + 
+                    "\n");
+              //Use BOOST_FOREACH here? Is it faster?
+              for(AddressVector::iterator it = upstream_root_->begin();
+                   it < upstream_root_->end(); it++) {
+                zone_servers_.push_back(addr_t(it->first,it->second));
+                dlog("Put " + zone_servers_.back().first + "into root list\n");
+              }
+            }
         }
         send();
     }
@@ -538,8 +562,8 @@ RecursiveQuery::sendQuery(const Question& question,
     // we're only going to handle UDP.
     asio::io_service& io = dns_service_.get_io_service();
     // It will delete itself when it is done
-    new RunningQuery(io, question, answer_message, upstream_, buffer,
-                     server, timeout_, retries_);
+    new RunningQuery(io, question, answer_message, upstream_, upstream_root_,
+                         buffer, server, timeout_, retries_);
 }
 
 class IntervalTimerImpl {

+ 8 - 1
src/lib/asiolink/asiolink.h

@@ -538,6 +538,8 @@ public:
     ///        query on.
     /// \param upstream Addresses and ports of the upstream servers
     ///        to forward queries to.
+    /// \param upstream_root Addresses and ports of the root servers
+    ///        to use when resolving.
     /// \param timeout How long to timeout the query, in ms
     ///     -1 means never timeout (but do not use that).
     ///     TODO: This should be computed somehow dynamically in future
@@ -545,7 +547,10 @@ public:
     ///     and return if it returs).
     RecursiveQuery(DNSService& dns_service,
                    const std::vector<std::pair<std::string, uint16_t> >&
-                   upstream, int timeout = -1, unsigned retries = 0);
+                   upstream, 
+                   const std::vector<std::pair<std::string, uint16_t> >&
+                   upstream_root, 
+                   int timeout = -1, unsigned retries = 0);
     //@}
 
     /// \brief Initiates an upstream query in the \c RecursiveQuery object.
@@ -566,6 +571,8 @@ private:
     DNSService& dns_service_;
     boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
         upstream_;
+    boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
+        upstream_root_;
     int timeout_;
     unsigned retries_;
 };

+ 15 - 9
src/lib/asiolink/tests/asiolink_unittest.cc

@@ -645,15 +645,17 @@ singleAddress(const string &address, uint16_t port) {
 TEST_F(ASIOLinkTest, recursiveSetupV4) {
     setDNSService(true, false);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
-        port)));
+    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
+                                   singleAddress(TEST_IPV4_ADDR, port),
+                                   singleAddress(TEST_IPV4_ADDR, port)));
 }
 
 TEST_F(ASIOLinkTest, recursiveSetupV6) {
     setDNSService(false, true);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*dns_service_, singleAddress(TEST_IPV6_ADDR,
-        port)));
+    EXPECT_NO_THROW(RecursiveQuery(*dns_service_,
+                                   singleAddress(TEST_IPV6_ADDR, port),
+                                   singleAddress(TEST_IPV6_ADDR,port)));
 }
 
 // XXX:
@@ -669,7 +671,9 @@ TEST_F(ASIOLinkTest, forwarderSend) {
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
 
     MockServer server(*io_service_);
-    RecursiveQuery rq(*dns_service_, singleAddress(TEST_IPV4_ADDR, port));
+    RecursiveQuery rq(*dns_service_,
+                      singleAddress(TEST_IPV4_ADDR, port),
+                      singleAddress(TEST_IPV4_ADDR, port));
 
     Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
     OutputBufferPtr buffer(new OutputBuffer(0));
@@ -715,8 +719,10 @@ TEST_F(ASIOLinkTest, recursiveTimeout) {
 
     // Do the answer
     const uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    RecursiveQuery query(*dns_service_, singleAddress(TEST_IPV4_ADDR, port),
-        10, 2);
+    RecursiveQuery query(*dns_service_,
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         singleAddress(TEST_IPV4_ADDR, port),
+                         10, 2);
     Question question(Name("example.net"), RRClass::IN(), RRType::A());
     OutputBufferPtr buffer(new OutputBuffer(0));
     MessagePtr answer(new Message(Message::RENDER));
@@ -762,7 +768,7 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendOk) {
     
     MockServerStop server(*io_service_, &done);
     vector<pair<string, uint16_t> > empty_vector;
-    RecursiveQuery rq(*dns_service_, empty_vector, 10000, 0);
+    RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
 
     Question q(Name("www.isc.org"), RRClass::IN(), RRType::A());
     OutputBufferPtr buffer(new OutputBuffer(0));
@@ -787,7 +793,7 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSendNXDOMAIN) {
     
     MockServerStop server(*io_service_, &done);
     vector<pair<string, uint16_t> > empty_vector;
-    RecursiveQuery rq(*dns_service_, empty_vector, 10000, 0);
+    RecursiveQuery rq(*dns_service_, empty_vector, empty_vector, 10000, 0);
 
     Question q(Name("wwwdoesnotexist.isc.org"), RRClass::IN(), RRType::A());
     OutputBufferPtr buffer(new OutputBuffer(0));