Browse Source

[trac491] initial basic hookup of the cache

It only stores the final result, and only looks into the cache at the start of a resolve() call right now, but it appears to work
Jelte Jansen 14 years ago
parent
commit
4864018bdb

+ 1 - 0
src/bin/auth/Makefile.am

@@ -50,6 +50,7 @@ b10_auth_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
 b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+b10_auth_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
 b10_auth_LDADD += $(SQLITE_LIBS)
 

+ 1 - 0
src/bin/auth/benchmarks/Makefile.am

@@ -21,5 +21,6 @@ query_bench_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
 query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 query_bench_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
 query_bench_LDADD += $(top_builddir)/src/lib/log/liblog.la
+query_bench_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 query_bench_LDADD += $(SQLITE_LIBS)

+ 1 - 0
src/bin/auth/tests/Makefile.am

@@ -45,6 +45,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
 run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 endif
 
 noinst_PROGRAMS = $(TESTS)

+ 2 - 0
src/bin/resolver/Makefile.am

@@ -48,6 +48,8 @@ b10_resolver_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 b10_resolver_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 b10_resolver_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
 b10_resolver_LDADD += $(top_builddir)/src/lib/log/liblog.la
+b10_resolver_LDADD += $(top_builddir)/src/lib/cache/libcache.la
+b10_resolver_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 b10_resolver_LDADD += $(top_builddir)/src/bin/auth/change_user.o
 b10_resolver_LDFLAGS = -pthread
 

+ 3 - 8
src/bin/resolver/resolver.cc

@@ -256,11 +256,10 @@ public:
         const qid_t qid = query_message->getQid();
         const bool rd = query_message->getHeaderFlag(Message::HEADERFLAG_RD);
         const bool cd = query_message->getHeaderFlag(Message::HEADERFLAG_CD);
-        const Opcode& opcode = query_message->getOpcode();
-
-        // Fill in the final details of the answer message
+        
+        // The opcode and question section should have already been set,
+        // fill in the final details of the answer message
         answer_message->setQid(qid);
-        answer_message->setOpcode(opcode);
 
         answer_message->setHeaderFlag(Message::HEADERFLAG_QR);
         answer_message->setHeaderFlag(Message::HEADERFLAG_RA);
@@ -271,10 +270,6 @@ public:
             answer_message->setHeaderFlag(Message::HEADERFLAG_CD);
         }
 
-        vector<QuestionPtr> questions;
-        questions.assign(query_message->beginQuestion(), query_message->endQuestion());
-        for_each(questions.begin(), questions.end(), QuestionInserter(answer_message));
-        
         // Now we can clear the buffer and render the new message into it
         buffer->clear();
         MessageRenderer renderer(*buffer);

+ 2 - 0
src/bin/resolver/tests/Makefile.am

@@ -37,6 +37,8 @@ run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
 run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDADD += $(top_builddir)/src/lib/cache/libcache.la
+run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 
 # Note the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS

+ 2 - 0
src/lib/asiolink/Makefile.am

@@ -43,3 +43,5 @@ endif
 libasiolink_la_CPPFLAGS = $(AM_CPPFLAGS)
 libasiolink_la_LIBADD = $(top_builddir)/src/lib/log/liblog.la
 libasiolink_la_LIBADD += $(top_builddir)/src/lib/resolve/libresolve.la
+libasiolink_la_LIBADD += $(top_builddir)/src/lib/cache/libcache.la
+libasiolink_la_LIBADD += $(top_builddir)/src/lib/nsas/libnsas.la

+ 55 - 12
src/lib/asiolink/recursive_query.cc

@@ -32,9 +32,12 @@
 
 #include <dns/question.h>
 #include <dns/message.h>
+#include <dns/opcode.h>
 
 #include <resolve/resolve.h>
 
+#include <cache/resolver_cache.h>
+
 using isc::log::dlog;
 using namespace isc::dns;
 
@@ -123,7 +126,7 @@ private:
     asio::deadline_timer lookup_timer;
 
     size_t queries_out_;
-
+    
     // If we timed out ourselves (lookup timeout), stop issuing queries
     bool done_;
 
@@ -132,6 +135,9 @@ private:
     // answer if we do find one later (or if we have a lookup_timeout)
     bool answer_sent_;
 
+    // Reference to our cache
+    isc::cache::ResolverCache& cache_;
+
     // (re)send the query to the server.
     void send() {
         const int uc = upstream_->size();
@@ -291,7 +297,8 @@ public:
         OutputBufferPtr buffer,
         isc::resolve::ResolverInterface::CallbackPtr cb,
         int query_timeout, int client_timeout, int lookup_timeout,
-        unsigned retries) :
+        unsigned retries,
+        isc::cache::ResolverCache& cache) :
         io_(io),
         question_(question),
         answer_message_(answer_message),
@@ -306,7 +313,8 @@ public:
         lookup_timer(io),
         queries_out_(0),
         done_(false),
-        answer_sent_(false)
+        answer_sent_(false),
+        cache_(cache)
     {
         // Setup the timer to stop trying (lookup_timeout)
         if (lookup_timeout >= 0) {
@@ -366,6 +374,11 @@ public:
         // until that one comes back to us)
         done_ = true;
         if (resume && !answer_sent_) {
+            // Store the answer we found in our cache
+            std::cout << "[XX] caching our answer:" << std::endl;
+            std::cout << answer_message_->toText();
+            cache_.update(*answer_message_);
+            std::cout << "[XX] done caching our answer" << std::endl;
             resolvercallback_->success(answer_message_);
         } else {
             resolvercallback_->failure();
@@ -424,11 +437,26 @@ RecursiveQuery::resolve(const QuestionPtr& question,
 
     MessagePtr answer_message(new Message(Message::RENDER));
     OutputBufferPtr buffer(new OutputBuffer(0));
-    
-    // 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_);
+
+    // TODO: general 'prepareinitialanswer'
+    answer_message->setOpcode(isc::dns::Opcode::QUERY());
+    answer_message->addQuestion(question);
+    dlog("Try out cache first (direct call to resolve)");
+    // First try to see if we have something cached in the messagecache
+    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());
+        callback->success(answer_message);
+    } 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_);
+    }
 }
 
 void
@@ -445,11 +473,26 @@ RecursiveQuery::resolve(const Question& question,
 
     isc::resolve::ResolverInterface::CallbackPtr crs(
         new isc::resolve::ResolverCallbackServer(server));
+
+    // TODO: general 'prepareinitialanswer'
+    answer_message->setOpcode(isc::dns::Opcode::QUERY());
+    answer_message->addQuestion(question);
     
-    // 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_);
+    // 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
+        new RunningQuery(io, question, answer_message, upstream_, upstream_root_,
+                             buffer, crs, query_timeout_, client_timeout_,
+                             lookup_timeout_, retries_, cache_);
+    }
 }
 
 

+ 4 - 0
src/lib/asiolink/recursive_query.h

@@ -18,6 +18,7 @@
 #include <asiolink/dns_service.h>
 #include <asiolink/dns_server.h>
 #include <dns/buffer.h>
+#include <cache/resolver_cache.h>
 
 namespace asiolink {
 /// \brief The \c RecursiveQuery class provides a layer of abstraction around
@@ -107,6 +108,9 @@ private:
     int client_timeout_;
     int lookup_timeout_;
     unsigned retries_;
+    // Cache. TODO: I think we want this initialized in Resolver class,
+    // not here
+    isc::cache::ResolverCache cache_;
 };
 
 }      // namespace asiolink

+ 2 - 0
src/lib/asiolink/tests/Makefile.am

@@ -33,6 +33,8 @@ run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/libdns++.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
 run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
+run_unittests_LDADD += $(top_builddir)/src/lib/cache/libcache.la
+run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
 run_unittests_CXXFLAGS = $(AM_CXXFLAGS)

+ 2 - 0
src/lib/asiolink/udp_server.cc

@@ -28,6 +28,8 @@
 
 #include <asiolink/udp_server.h>
 
+#include <dns/opcode.h>
+
 using namespace asio;
 using asio::ip::udp;
 using asio::ip::tcp;

+ 2 - 0
src/lib/cache/message_cache.cc

@@ -45,6 +45,7 @@ MessageCache::lookup(const isc::dns::Name& qname,
                      isc::dns::Message& response)
 {
     std::string entry_name = genCacheEntryName(qname, qtype);
+    std::cout << "[XX] MESSAGECACHE LOOKUP: " << entry_name << std::endl;
     HashKey entry_key = HashKey(entry_name, RRClass(message_class_));
     MessageEntryPtr msg_entry = message_table_.get(entry_key);
     if(msg_entry) {
@@ -59,6 +60,7 @@ bool
 MessageCache::update(const Message& msg) {
     QuestionIterator iter = msg.beginQuestion();
     std::string entry_name = genCacheEntryName((*iter)->getName(), (*iter)->getType());
+    std::cout << "[XX] MESSAGECACHE UDPATE: " << entry_name << std::endl;
     HashKey entry_key = HashKey(entry_name, RRClass(message_class_));
 
     // The simplest way to update is removing the old message entry directly.

+ 1 - 1
src/lib/cache/resolver_cache.cc

@@ -201,8 +201,8 @@ ResolverCache::lookupClosestRRset(const isc::dns::Name& qname,
 
 bool
 ResolverCache::update(const isc::dns::Message& msg) {
-    
     QuestionIterator iter = msg.beginQuestion();
+    RRClass c = (*iter)->getClass();
     ResolverClassCache* cc = getClassCache((*iter)->getClass());
     if (cc) {
         return (cc->update(msg));

+ 1 - 1
src/lib/cache/rrset_cache.h

@@ -17,7 +17,7 @@
 #ifndef __RRSET_CACHE_H
 #define __RRSET_CACHE_H
 
-#include <rrset_entry.h>
+#include <cache/rrset_entry.h>
 #include <nsas/hash_table.h>
 #include <nsas/lru_list.h>