BIND 10 trac598, updated. 306da065b7635b9d29fbafee45b1c77a8e43f05c [trac598] Quick fix:passing DO and RQ bit to forwarder.
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Mar 16 12:22:08 UTC 2011
The branch, trac598 has been updated
via 306da065b7635b9d29fbafee45b1c77a8e43f05c (commit)
from 617ec7cf8793d84e92b63aca279768a7bf0164cf (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 306da065b7635b9d29fbafee45b1c77a8e43f05c
Author: zhanglikun <zhanglikun at cnnic.cn>
Date: Wed Mar 16 20:21:47 2011 +0800
[trac598] Quick fix:passing DO and RQ bit to forwarder.
-----------------------------------------------------------------------
Summary of changes:
src/bin/resolver/resolver.cc | 16 ++-
src/lib/asiolink/io_fetch.cc | 36 ++++++-
src/lib/asiolink/io_fetch.h | 6 +
src/lib/asiolink/recursive_query.cc | 127 +++++++++++++++-----
src/lib/asiolink/recursive_query.h | 15 +++
src/lib/asiolink/tests/recursive_query_unittest.cc | 1 +
src/lib/dns/message.h | 1 +
7 files changed, 166 insertions(+), 36 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/resolver/resolver.cc b/src/bin/resolver/resolver.cc
index 84df9d2..aa80d60 100644
--- a/src/bin/resolver/resolver.cc
+++ b/src/bin/resolver/resolver.cc
@@ -133,7 +133,7 @@ public:
void resolve(const isc::dns::QuestionPtr& question,
const isc::resolve::ResolverInterface::CallbackPtr& callback);
- void processNormalQuery(const Question& question,
+ void processNormalQuery(ConstMessagePtr query_message,
MessagePtr answer_message,
OutputBufferPtr buffer,
DNSServer* server);
@@ -440,7 +440,7 @@ Resolver::processMessage(const IOMessage& io_message,
// The RecursiveQuery object will post the "resume" event to the
// DNSServer when an answer arrives, so we don't have to do it now.
sendAnswer = false;
- impl_->processNormalQuery(*question, answer_message,
+ impl_->processNormalQuery(query_message, answer_message,
buffer, server);
}
}
@@ -458,13 +458,19 @@ ResolverImpl::resolve(const QuestionPtr& question,
}
void
-ResolverImpl::processNormalQuery(const Question& question,
+ResolverImpl::processNormalQuery(ConstMessagePtr query_message,
MessagePtr answer_message,
OutputBufferPtr buffer,
DNSServer* server)
{
- dlog("Processing normal query");
- rec_query_->resolve(question, answer_message, buffer, server);
+ if (upstream_.empty()) {
+ dlog("Processing normal query");
+ ConstQuestionPtr question = *query_message->beginQuestion();
+ rec_query_->resolve(*question, answer_message, buffer, server);
+ } else {
+ dlog("Processing forward query");
+ rec_query_->forward(query_message, answer_message, buffer, server);
+ }
}
ConstElementPtr
diff --git a/src/lib/asiolink/io_fetch.cc b/src/lib/asiolink/io_fetch.cc
index 6cd6064..222ccea 100644
--- a/src/lib/asiolink/io_fetch.cc
+++ b/src/lib/asiolink/io_fetch.cc
@@ -21,7 +21,6 @@
#include <boost/bind.hpp>
-#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/opcode.h>
#include <dns/rcode.h>
@@ -56,6 +55,11 @@ namespace {
return (data);
}
+
+ void copyMessageFlag(ConstMessagePtr src, MessagePtr dst,
+ const Message::HeaderFlag flag) {
+ dst->setHeaderFlag(flag, src->getHeaderFlag(flag));
+ }
}
namespace asiolink {
@@ -78,6 +82,36 @@ IOFetch::IOFetch(int protocol, IOService& service,
port, buff, cb, wait));
}
+IOFetch::IOFetch(int protocol, IOService& service,
+ ConstMessagePtr query_message, const IOAddress& address, uint16_t port,
+ isc::dns::OutputBufferPtr& buff, Callback* cb, int wait)
+{
+ MessagePtr msg(new Message(Message::RENDER));
+
+ msg->setQid(QidGenerator::getInstance().generateQid());
+ msg->setOpcode(Opcode::QUERY());
+ msg->setRcode(Rcode::NOERROR());
+ copyMessageFlag(query_message, msg, Message::HEADERFLAG_RD);
+ copyMessageFlag(query_message, msg, Message::HEADERFLAG_CD);
+
+ ConstEDNSPtr edns(query_message->getEDNS());
+ const bool dnssec_ok = edns && edns->getDNSSECAwareness();
+ if (edns) {
+ EDNSPtr edns_response(new EDNS());
+ edns_response->setDNSSECAwareness(dnssec_ok);
+
+ // TODO: We should make our own edns bufsize length configurable
+ edns_response->setUDPSize(Message::DEFAULT_MAX_EDNS0_UDPSIZE);
+ msg->setEDNS(edns_response);
+ }
+
+ msg->addQuestion(*(*query_message->beginQuestion()));
+
+ data_ = boost::shared_ptr<IOFetchData>(new IOFetch::IOFetchData(
+ protocol, service, msg, address,
+ port, buff, cb, wait));
+}
+
/// The function operator is implemented with the "stackless coroutine"
/// pattern; see internal/coroutine.h for details.
diff --git a/src/lib/asiolink/io_fetch.h b/src/lib/asiolink/io_fetch.h
index d0bad34..db84ef1 100644
--- a/src/lib/asiolink/io_fetch.h
+++ b/src/lib/asiolink/io_fetch.h
@@ -30,6 +30,7 @@
#include <dns/buffer.h>
#include <dns/question.h>
+#include <dns/message.h>
#include <asiolink/io_asio_socket.h>
#include <asiolink/io_endpoint.h>
@@ -198,6 +199,11 @@ public:
const isc::dns::Question& question, const IOAddress& address,
uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
int wait = -1);
+
+ IOFetch(int protocol, IOService& service,
+ isc::dns::ConstMessagePtr query_message, const IOAddress& address,
+ uint16_t port, isc::dns::OutputBufferPtr& buff, Callback* cb,
+ int wait = -1);
/// \brief Coroutine entry point
///
diff --git a/src/lib/asiolink/recursive_query.cc b/src/lib/asiolink/recursive_query.cc
index 0bdf24e..678f778 100644
--- a/src/lib/asiolink/recursive_query.cc
+++ b/src/lib/asiolink/recursive_query.cc
@@ -78,6 +78,9 @@ private:
// Info for (re)sending the query (the question and destination)
Question question_;
+ // This is the query message got from client
+ ConstMessagePtr query_message_;
+
// This is where we build and store our final answer
MessagePtr answer_message_;
@@ -137,23 +140,6 @@ private:
// Reference to our cache
isc::cache::ResolverCache& cache_;
- // perform a single lookup; first we check the cache to see
- // if we have a response for our query stored already. if
- // so, call handlerecursiveresponse(), if not, we call send()
- void doLookup() {
- dlog("doLookup: try cache");
- Message cached_message(Message::RENDER);
- isc::resolve::initResponseMessage(question_, cached_message);
- if (cache_.lookup(question_.getName(), question_.getType(),
- question_.getClass(), cached_message)) {
- dlog("Message found in cache, returning that");
- handleRecursiveAnswer(cached_message);
- } else {
- send();
- }
-
- }
-
// (re)send the query to the server.
void send() {
const int uc = upstream_->size();
@@ -163,12 +149,26 @@ private:
int serverIndex = rand() % uc;
dlog("Sending upstream query (" + question_.toText() +
") to " + upstream_->at(serverIndex).first);
- IOFetch query(IPPROTO_UDP, io_, question_,
- upstream_->at(serverIndex).first,
- upstream_->at(serverIndex).second, buffer_, this,
- query_timeout_);
+ // Forward the query, create the IOFetch with
+ // query message, so that query flags can be forwarded
+ // together.
+ IOFetch* query = NULL;
+ if (query_message_) {
+ query = new IOFetch(IPPROTO_UDP, io_, query_message_,
+ upstream_->at(serverIndex).first,
+ upstream_->at(serverIndex).second,
+ buffer_, this, query_timeout_);
+
+ } else {
+ query = new IOFetch(IPPROTO_UDP, io_, question_,
+ upstream_->at(serverIndex).first,
+ upstream_->at(serverIndex).second,
+ buffer_, this, query_timeout_);
+ }
++queries_out_;
- io_.get_io_service().post(query);
+ std::cout << "==========================================post qury" << std::endl;
+ io_.get_io_service().post(*query);
+ delete query;
} else if (zs > 0) {
int serverIndex = rand() % zs;
dlog("Sending query to zone server (" + question_.toText() +
@@ -327,6 +327,7 @@ public:
isc::cache::ResolverCache& cache) :
io_(io),
question_(question),
+ query_message_(),
answer_message_(answer_message),
upstream_(upstream),
upstream_root_(upstream_root),
@@ -361,8 +362,10 @@ public:
if (upstream_->empty()) {
setZoneServersToRoot();
}
+ }
- doLookup();
+ void setQueryMessage(ConstMessagePtr query_message) {
+ query_message_ = query_message;
}
void setZoneServersToRoot() {
@@ -381,6 +384,23 @@ public:
}
}
}
+
+ // perform a single lookup; first we check the cache to see
+ // if we have a response for our query stored already. if
+ // so, call handlerecursiveresponse(), if not, we call send()
+ void doLookup() {
+ dlog("doLookup: try cache");
+ Message cached_message(Message::RENDER);
+ isc::resolve::initResponseMessage(question_, cached_message);
+ if (cache_.lookup(question_.getName(), question_.getType(),
+ question_.getClass(), cached_message)) {
+ dlog("Message found in cache, returning that");
+ handleRecursiveAnswer(cached_message);
+ } else {
+ send();
+ }
+ }
+
virtual void clientTimeout() {
// Return a SERVFAIL, but do not stop until
// we have an answer or timeout ourselves
@@ -400,6 +420,7 @@ public:
// here again.
// same goes if we have an outstanding query (can't delete
// until that one comes back to us)
+ std::cout << "stop=====================================" << std::endl;
done_ = true;
if (resume && !answer_sent_) {
answer_sent_ = true;
@@ -495,10 +516,12 @@ RecursiveQuery::resolve(const QuestionPtr& question,
} else {
dlog("Message not found in cache, starting recursive query");
// It will delete itself when it is done
- new RunningQuery(io, *question, answer_message, upstream_,
- upstream_root_, buffer, callback, query_timeout_,
- client_timeout_, lookup_timeout_, retries_,
- cache_);
+ RunningQuery* query = new RunningQuery(io, *question, answer_message,
+ upstream_, upstream_root_,
+ buffer, callback, query_timeout_,
+ client_timeout_, lookup_timeout_,
+ retries_, cache_);
+ query->doLookup();
}
}
@@ -532,9 +555,53 @@ RecursiveQuery::resolve(const Question& question,
} else {
dlog("Message not found in cache, starting recursive query");
// It will delete itself when it is done
- new RunningQuery(io, question, answer_message, upstream_, upstream_root_,
- buffer, crs, query_timeout_, client_timeout_,
- lookup_timeout_, retries_, cache_);
+ RunningQuery* query = new RunningQuery(io, question, answer_message,
+ upstream_, upstream_root_,
+ buffer, crs, query_timeout_,
+ client_timeout_, lookup_timeout_,
+ retries_, cache_);
+ query->doLookup();
+ }
+}
+
+void
+RecursiveQuery::forward(ConstMessagePtr query_message,
+ MessagePtr answer_message,
+ OutputBufferPtr buffer,
+ DNSServer* server)
+{
+ // XXX: eventually we will need to be able to determine whether
+ // the message should be sent via TCP or UDP, or sent initially via
+ // UDP and then fall back to TCP on failure, but for the moment
+ // we're only going to handle UDP.
+ IOService& io = dns_service_.getIOService();
+
+ isc::resolve::ResolverInterface::CallbackPtr crs(
+ new isc::resolve::ResolverCallbackServer(server));
+
+ // TODO: general 'prepareinitialanswer'
+ answer_message->setOpcode(isc::dns::Opcode::QUERY());
+ ConstQuestionPtr question = *query_message->beginQuestion();
+ answer_message->addQuestion(*question);
+
+ // First try to see if we have something cached in the messagecache
+ dlog("Try out cache first (started by incoming event)");
+ if (cache_.lookup(question->getName(), question->getType(),
+ question->getClass(), *answer_message)) {
+ dlog("Message found in cache, returning that");
+ // TODO: err, should cache set rcode as well?
+ answer_message->setRcode(Rcode::NOERROR());
+ crs->success(answer_message);
+ } else {
+ dlog("Message not found in cache, starting recursive query");
+ // It will delete itself when it is done
+ RunningQuery* query = new RunningQuery(io, *question, answer_message,
+ upstream_, upstream_root_,
+ buffer, crs, query_timeout_,
+ client_timeout_, lookup_timeout_,
+ retries_, cache_);
+ query->setQueryMessage(query_message);
+ query->doLookup();
}
}
diff --git a/src/lib/asiolink/recursive_query.h b/src/lib/asiolink/recursive_query.h
index 6ef0069..09f7c16 100644
--- a/src/lib/asiolink/recursive_query.h
+++ b/src/lib/asiolink/recursive_query.h
@@ -98,6 +98,21 @@ public:
isc::dns::MessagePtr answer_message,
isc::dns::OutputBufferPtr buffer,
DNSServer* server);
+
+ /// \brief Initiates resolving for the given question.
+ ///
+ /// This actually calls the previous sendQuery() with a default
+ /// callback object, which calls resume() on the given DNSServer
+ /// object.
+ ///
+ /// \param question The question being answered <qname/qclass/qtype>
+ /// \param answer_message An output Message into which the final response will be copied
+ /// \param buffer An output buffer into which the intermediate responses will be copied
+ /// \param server A pointer to the \c DNSServer object handling the client
+ void forward(isc::dns::ConstMessagePtr query_message,
+ isc::dns::MessagePtr answer_message,
+ isc::dns::OutputBufferPtr buffer,
+ DNSServer* server);
private:
DNSService& dns_service_;
boost::shared_ptr<std::vector<std::pair<std::string, uint16_t> > >
diff --git a/src/lib/asiolink/tests/recursive_query_unittest.cc b/src/lib/asiolink/tests/recursive_query_unittest.cc
index f4fc2ac..33cbbc6 100644
--- a/src/lib/asiolink/tests/recursive_query_unittest.cc
+++ b/src/lib/asiolink/tests/recursive_query_unittest.cc
@@ -607,6 +607,7 @@ bool tryRead(int sock_, int recv_options, size_t max, int* num) {
do {
char inbuff[512];
if (recv(sock_, inbuff, sizeof(inbuff), recv_options) < 0) {
+ std::cout << "recv < 0===============================\n";
return false;
} else {
++i;
diff --git a/src/lib/dns/message.h b/src/lib/dns/message.h
index 11167d2..e65c09d 100644
--- a/src/lib/dns/message.h
+++ b/src/lib/dns/message.h
@@ -559,6 +559,7 @@ private:
/// that ongoing state information will not be lost if the object
/// that originated the asynchronous call falls out of scope.
typedef boost::shared_ptr<Message> MessagePtr;
+typedef boost::shared_ptr<const Message> ConstMessagePtr;
std::ostream& operator<<(std::ostream& os, const Message& message);
}
More information about the bind10-changes
mailing list