Browse Source

RecursiveQuery takes multiple addresses

It chooses randomly (something better should really be done there, it is
just to be able to accept them for now).

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/vorner-recursor-config@3332 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
0141596484

+ 9 - 4
src/lib/asiolink/asiolink.cc

@@ -16,6 +16,8 @@
 
 #include <config.h>
 
+#include <cstdlib> // For random(), temporary until better forwarding is done
+
 #include <unistd.h>             // for some IPC/network system calls
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -170,9 +172,9 @@ IOService::get_io_service() {
     return (impl_->io_service_);
 }
 
-RecursiveQuery::RecursiveQuery(IOService& io_service, const char& forward,
-                               uint16_t port) :
-    io_service_(io_service), ns_addr_(&forward), port_(port) 
+RecursiveQuery::RecursiveQuery(IOService& io_service,
+        const std::vector<std::pair<std::string, uint16_t> >& upstream) :
+    io_service_(io_service), upstream_(upstream)
 {}
 
 void
@@ -185,7 +187,10 @@ RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
     // UDP and then fall back to TCP on failure, but for the moment
     // we're only going to handle UDP.
     asio::io_service& io = io_service_.get_io_service();
-    UDPQuery q(io, question, ns_addr_, port_, buffer, server);
+    // TODO: Better way to choose the server
+    int serverIndex(random() % upstream_.size());
+    UDPQuery q(io, question, upstream_[serverIndex].first,
+        upstream_[serverIndex].second, buffer, server);
     io.post(q);
 }
 

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

@@ -25,6 +25,8 @@
 
 #include <functional>
 #include <string>
+#include <vector>
+#include <utility>
 
 #include <dns/buffer.h>
 #include <dns/message.h>
@@ -445,10 +447,11 @@ public:
     /// \brief Constructor for use when acting as a forwarder
     ///
     /// This is currently the only way to construct \c RecursiveQuery
-    /// object.  The address of the forward nameserver is specified,
-    /// and all upstream queries will be sent to that one address.
-    RecursiveQuery(IOService& io_service, const char& forward,
-                   uint16_t port = 53);
+    /// object.  The addresses of the forward nameservers is specified,
+    /// and every upstream query will be sent to one random address.
+    RecursiveQuery(IOService& io_service,
+                   const std::vector<std::pair<std::string, uint16_t> >&
+                   upstream);
     //@}
 
     /// \brief Initiates an upstream query in the \c RecursiveQuery object.
@@ -466,8 +469,7 @@ public:
                    DNSServer* server);
 private:
     IOService& io_service_;
-    IOAddress ns_addr_;
-    uint16_t port_;
+    std::vector<std::pair<std::string, uint16_t> > upstream_;
 };
 
 }      // asiolink

+ 12 - 3
src/lib/asiolink/tests/asiolink_unittest.cc

@@ -528,16 +528,25 @@ TEST_F(ASIOLinkTest, v4TCPOnly) {
     EXPECT_THROW(sendTCP(AF_INET6), IOError);
 }
 
+vector<pair<string, uint16_t> >
+singleAddress(const string &address, uint16_t port) {
+    vector<pair<string, uint16_t> > result;
+    result.push_back(pair<string, uint16_t>(address, port));
+    return (result);
+}
+
 TEST_F(ASIOLinkTest, recursiveSetupV4) {
     setIOService(true, false);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*io_service_, *TEST_IPV4_ADDR, port));
+    EXPECT_NO_THROW(RecursiveQuery(*io_service_, singleAddress(TEST_IPV6_ADDR,
+        port)));
 }
 
 TEST_F(ASIOLinkTest, recursiveSetupV6) {
     setIOService(false, true);
     uint16_t port = boost::lexical_cast<uint16_t>(TEST_CLIENT_PORT);
-    EXPECT_NO_THROW(RecursiveQuery(*io_service_, *TEST_IPV6_ADDR, port));
+    EXPECT_NO_THROW(RecursiveQuery(*io_service_, singleAddress(TEST_IPV6_ADDR,
+        port)));
 }
 
 // XXX:
@@ -555,7 +564,7 @@ TEST_F(ASIOLinkTest, recursiveSend) {
     asio::ip::address addr = asio::ip::address::from_string(TEST_IPV4_ADDR);
 
     MockServer server(io, addr, port, NULL, NULL, NULL);
-    RecursiveQuery rq(*io_service_, *TEST_IPV4_ADDR, port);
+    RecursiveQuery rq(*io_service_, singleAddress(TEST_IPV4_ADDR, port));
 
     Question q(Name("example.com"), RRClass::IN(), RRType::TXT());
     OutputBufferPtr buffer(new OutputBuffer(0));