[svn] commit: r3415 - in /branches/vorner-recursor-timeouts/src/lib/asiolink: asiolink.cc asiolink.h tests/asiolink_unittest.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Nov 2 10:47:53 UTC 2010
Author: vorner
Date: Tue Nov 2 10:47:53 2010
New Revision: 3415
Log:
Implement retries in forwarder
TODO Merge configuration, merge multiple namespace addresses from
configuration, etc
Modified:
branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.cc
branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.h
branches/vorner-recursor-timeouts/src/lib/asiolink/tests/asiolink_unittest.cc
Modified: branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.cc
==============================================================================
--- branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.cc (original)
+++ branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.cc Tue Nov 2 10:47:53 2010
@@ -233,24 +233,63 @@
RecursiveQuery::RecursiveQuery(DNSService& dns_service, const char& forward,
uint16_t port, int timeout, unsigned retries) :
- dns_service_(dns_service), ns_addr_(&forward), port_(port)
+ dns_service_(dns_service),
+ ns_addr_(&forward),
+ port_(port),
+ timeout_(timeout),
+ retries_(retries)
{}
namespace {
-// This is just temporary so the interface change does not propagate too far
-struct ServerNotify : public UDPQuery::Callback {
- ServerNotify(DNSServer* server) :
- server_(server)
- { }
- virtual void operator()(UDPQuery::Result result) {
- server_->resume(result == UDPQuery::SUCCESS);
- delete this;
- }
- private:
- // FIXME This is said it does problems when it is shared pointer, as
- // it is destroyed too soon. But who deletes it now?
- DNSServer* server_;
+class ServerNotify : public UDPQuery::Callback {
+ private:
+ asio::io_service& io_;
+ Question question_;
+ IOAddress address_;
+ uint16_t port_;
+ OutputBufferPtr buffer_;
+ /*
+ * FIXME This is said it does problems when it is shared pointer, as
+ * it is destroyed too soon. But who deletes it now?
+ */
+ DNSServer* server_;
+ /*
+ * TODO Do something more clever with timeouts. In the long term, some
+ * computation of average RTT, increase with each retry, etc.
+ */
+ int timeout_;
+ unsigned retries_;
+ void send() {
+ UDPQuery query(io_, question_, address_, port_, buffer_, this,
+ timeout_);
+ io_.post(query);
+ }
+ public:
+ ServerNotify(asio::io_service& io, const Question &question,
+ const IOAddress& address, uint16_t port,
+ OutputBufferPtr buffer, DNSServer *server, int timeout,
+ unsigned retries) :
+ io_(io),
+ question_(question),
+ address_(address),
+ port_(port),
+ buffer_(buffer),
+ server_(server),
+ timeout_(timeout),
+ retries_(retries)
+ {
+ send();
+ }
+ virtual void operator()(UDPQuery::Result result) {
+ if (result == UDPQuery::TIME_OUT && retries_ --) {
+ // We timed out, but we have some retries, so send again
+ send();
+ } else {
+ server_->resume(result == UDPQuery::SUCCESS);
+ delete this;
+ }
+ }
};
}
@@ -265,9 +304,9 @@
// UDP and then fall back to TCP on failure, but for the moment
// we're only going to handle UDP.
asio::io_service& io = dns_service_.get_io_service();
- UDPQuery q(io, question, ns_addr_, port_, buffer,
- new ServerNotify(server->clone()));
- io.post(q);
-}
-
-}
+ // It will delete itself when it is done
+ new ServerNotify(io, question, ns_addr_, port_, buffer, server->clone(),
+ timeout_, retries_);
+}
+
+}
Modified: branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.h
==============================================================================
--- branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.h (original)
+++ branches/vorner-recursor-timeouts/src/lib/asiolink/asiolink.h Tue Nov 2 10:47:53 2010
@@ -546,6 +546,8 @@
DNSService& dns_service_;
IOAddress ns_addr_;
uint16_t port_;
+ int timeout_;
+ unsigned retries_;
};
} // asiolink
Modified: branches/vorner-recursor-timeouts/src/lib/asiolink/tests/asiolink_unittest.cc
==============================================================================
--- branches/vorner-recursor-timeouts/src/lib/asiolink/tests/asiolink_unittest.cc (original)
+++ branches/vorner-recursor-timeouts/src/lib/asiolink/tests/asiolink_unittest.cc Tue Nov 2 10:47:53 2010
@@ -468,23 +468,21 @@
// This version of mock server just stops the io_service when it is resumed
class MockServerStop : public MockServer {
public:
- explicit MockServerStop(asio::io_service& io_service) :
- MockServer(io_service, asio::ip::address(), 0)
+ explicit MockServerStop(asio::io_service& io_service, bool* done) :
+ MockServer(io_service, asio::ip::address(), 0),
+ done_(done)
{}
- void operator()(asio::error_code ec = asio::error_code(),
- size_t length = 0)
- {
+ void resume(const bool done) {
+ *done_ = done;
io_.stop();
}
DNSServer* clone() {
return (new MockServerStop(*this));
}
-
- bool done() const {
- return done_;
- }
+ private:
+ bool* done_;
};
private:
@@ -647,7 +645,7 @@
void
receive_and_inc(udp::socket* socket, int* num) {
- *num ++;
+ (*num) ++;
static char inbuff[512];
socket->async_receive(asio::buffer(inbuff, 512),
boost::bind(receive_and_inc, socket, num));
@@ -669,7 +667,8 @@
receive_and_inc(&socket, &num);
// Prepare the server
- MockServerStop server(service);
+ bool done(true);
+ MockServerStop server(service, &done);
// Do the answer
RecursiveQuery query(*dns_service_, *TEST_IPV4_ADDR, port, 10, 2);
@@ -680,7 +679,8 @@
// Run the test
service.run();
- EXPECT_TRUE(server.done());
+ // The query should fail
+ EXPECT_FALSE(done);
EXPECT_EQ(3, num);
}
More information about the bind10-changes
mailing list