[svn] commit: r4111 - in /branches/trac449/src/lib/cache: message_cache.cc message_cache.h message_entry.cc message_entry.h rrset_cache.cc rrset_cache.h rrset_entry.cc rrset_entry.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Dec 31 10:58:35 UTC 2010
Author: zhanglikun
Date: Fri Dec 31 10:58:34 2010
New Revision: 4111
Log:
Commit the latest code of recursor cache.
Modified:
branches/trac449/src/lib/cache/message_cache.cc
branches/trac449/src/lib/cache/message_cache.h
branches/trac449/src/lib/cache/message_entry.cc
branches/trac449/src/lib/cache/message_entry.h
branches/trac449/src/lib/cache/rrset_cache.cc
branches/trac449/src/lib/cache/rrset_cache.h
branches/trac449/src/lib/cache/rrset_entry.cc
branches/trac449/src/lib/cache/rrset_entry.h
Modified: branches/trac449/src/lib/cache/message_cache.cc
==============================================================================
--- branches/trac449/src/lib/cache/message_cache.cc (original)
+++ branches/trac449/src/lib/cache/message_cache.cc Fri Dec 31 10:58:34 2010
@@ -33,7 +33,6 @@
message_table_(new NsasEntryCompare<MessageEntry>, cache_size),
message_lru_((3 * cache_size),
new HashDeleter<MessageEntry>(message_table_))
-
{
}
@@ -43,12 +42,8 @@
const uint16_t query_header,
isc::dns::Message& response)
{
- CacheEntryKey keydata = genCacheEntryKey(qname, qtype);
-
- //TODO, HashKey need to be refactored, since we don't need query class
- // as the parameters.
- boost::shared_ptr<MessageEntry> msg_entry = message_table_.get(HashKey(
- keydata.first, keydata.second, RRClass(message_class_)));
+ HashKey entry_key = getEntryHashKey(qname, qtype);
+ MessageEntryPtr msg_entry = message_table_.get(entry_key);
if(msg_entry) {
return msg_entry->genMessage(time(NULL), query_header, response);
}
@@ -57,20 +52,37 @@
}
bool
-MessageCache::update(const Message&) {
- return true;
+MessageCache::update(const Message& msg) {
+ // The simplest way to update is removing the old message entry directly.
+ QuestionIterator iter = msg.beginQuestion();
+ HashKey entry_key = getEntryHashKey((*iter)->getName(),
+ (*iter)->getType());
+ message_table_.remove(entry_key);
+ MessageEntryPtr msg_entry(new MessageEntry(msg, rrset_cache_));
+ //TODO, lru list touch
+ return message_table_.add(msg_entry, entry_key, true);
+}
+
+HashKey
+MessageCache::getEntryHashKey(const Name& name, const RRType& type) const
+{
+ CacheEntryKey keydata = genCacheEntryKey(name, type);
+ return HashKey(keydata.first, keydata.second, RRClass(message_class_));
}
void
MessageCache::dump(const std::string&) {
+ //TODO
}
void
MessageCache::load(const std::string&) {
+ //TODO
}
bool
MessageCache::resize(uint32_t) {
+ //TODO
return true;
}
Modified: branches/trac449/src/lib/cache/message_cache.h
==============================================================================
--- branches/trac449/src/lib/cache/message_cache.h (original)
+++ branches/trac449/src/lib/cache/message_cache.h Fri Dec 31 10:58:34 2010
@@ -71,6 +71,14 @@
/// \brief Resize the size of message cache in runtime.
bool resize(uint32_t size);
+protected:
+ /// \brief Get the hash key for the message entry in the cache.
+ /// \param name query name of the message.
+ /// \param type query type of the message.
+ /// \return return the hash key.
+ HashKey getEntryHashKey(const isc::dns::Name& name,
+ const isc::dns::RRType& type) const;
+
private:
uint16_t message_class_; // The class of the message cache.
boost::shared_ptr<RRsetCache> rrset_cache_;
Modified: branches/trac449/src/lib/cache/message_entry.cc
==============================================================================
--- branches/trac449/src/lib/cache/message_entry.cc (original)
+++ branches/trac449/src/lib/cache/message_entry.cc Fri Dec 31 10:58:34 2010
@@ -14,23 +14,28 @@
// $Id$
+#include <limits>
#include <dns/message.h>
#include <nsas/nsas_entry.h>
#include <nsas/fetchable.h>
#include "message_entry.h"
#include "rrset_entry.h"
+#include "rrset_cache.h"
using namespace isc::dns;
+using namespace std;
namespace isc {
namespace cache {
-MessageEntry::MessageEntry(const isc::dns::Message&,
+static uint32_t MAX_UINT32 = numeric_limits<uint32_t>::max();
+
+MessageEntry::MessageEntry(const isc::dns::Message& msg,
boost::shared_ptr<RRsetCache> rrset_cache):
rrset_cache_(rrset_cache)
{
-
+ initMessageEntry(msg);
}
bool
@@ -41,26 +46,100 @@
return true;
}
+RRsetTrustLevel
+MessageEntry::getRRsetTrustLevel(const Message& message,
+ const RRset&,
+ const Message::Section& section)
+{
+ bool aa = message.getHeaderFlag(Message::HEADERFLAG_AA);
+ switch(section) {
+ case Message::SECTION_ANSWER: {
+ if (aa) {
+ //TODO, according RFC2181 section 5.4.1, only the record
+ // describing that ailas is necessarily authoritative.
+ return RRSET_TRUST_ANSWER_AA;
+ } else {
+ return RRSET_TRUST_ANSWER_NONAA;
+ }
+ break;
+ }
+
+ case Message::SECTION_AUTHORITY: {
+ if (aa) {
+ return RRSET_TRUST_AUTHORITY_AA;
+ } else {
+ return RRSET_TRUST_AUTHORITY_NONAA;
+ }
+ break;
+ }
+
+ case Message::SECTION_ADDITIONAL: {
+ if (aa) {
+ return RRSET_TRUST_ADDITIONAL_AA;
+ } else {
+ return RRSET_TRUST_ADDITIONAL_NONAA;
+ }
+ break;
+ }
+
+ default:
+ return RRSET_TRUST_DEFAULT;
+ }
+}
+
+void
+MessageEntry::parseSection(const isc::dns::Message& msg,
+ const Message::Section& section,
+ uint32_t& smaller_ttl)
+{
+ RRsetIterator iter;
+ for (iter = msg.beginSection(section);
+ iter != msg.endSection(section);
+ ++iter) {
+ // Add the rrset entry to rrset_cache or update the existed
+ // rrset entry if the new one is more authoritative.
+ //TODO set proper rrset trust level.
+ RRsetPtr rrset_ptr = *iter;
+ RRsetTrustLevel level = getRRsetTrustLevel(msg, *rrset_ptr, section);
+ RRsetEntryPtr rrset_entry = rrset_cache_->update(*rrset_ptr, level);
+ rrsets_.push_back(rrset_entry);
+
+ uint32_t rrset_ttl = rrset_entry->getTTL();
+ if (smaller_ttl > rrset_ttl) {
+ smaller_ttl = rrset_ttl;
+ }
+ }
+}
+
void
MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
query_count_ = msg.getRRCount(Message::SECTION_QUESTION);
answer_count_ = msg.getRRCount(Message::SECTION_ANSWER);
authority_count_ = msg.getRRCount(Message::SECTION_AUTHORITY);
additional_count_ = msg.getRRCount(Message::SECTION_ADDITIONAL);
+
+ //TODO how to cache the header?
+ // query_header
- // query_header \\TODO how to cache the header?
- RRsetIterator iter;
- for (iter = msg.beginSection(Message::SECTION_ANSWER);
- iter != msg.endSection(Message::SECTION_ANSWER);
- ++iter) {
- //*rit is one pointer to RRset.
- //boost::shared_ptr<RRsetEntry> entry_ptr = new RRsetEntry(*(*iter);
- //rrsets_.append(entry_ptr);
+ // We only cache the first question in question section.
+ // TODO, do we need to support muptiple questions?
+ QuestionIterator iter = msg.beginQuestion();
+ query_name_ = (*iter)->getName().toText();
+ query_type_ = (*iter)->getType().getCode();
+ query_class_ = (*iter)->getClass().getCode();
+
+ uint32_t min_ttl = MAX_UINT32;
+ parseSection(msg, Message::SECTION_ANSWER, min_ttl);
+ parseSection(msg, Message::SECTION_AUTHORITY, min_ttl);
+ parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl);
- // Add the rrset entry to rrset_cache or update the existed
- // rrset entry if the new one is more authoritative.
- }
+ expire_time_ = time(NULL) + min_ttl;
+}
+HashKey
+MessageEntry::hashKey() const {
+ CacheEntryKey keydata = genCacheEntryKey(query_name_, query_type_);
+ return HashKey(keydata.first, keydata.second, RRClass(query_class_));
}
} // namespace cache
Modified: branches/trac449/src/lib/cache/message_entry.h
==============================================================================
--- branches/trac449/src/lib/cache/message_entry.h (original)
+++ branches/trac449/src/lib/cache/message_entry.h Fri Dec 31 10:58:34 2010
@@ -21,6 +21,7 @@
#include <dns/message.h>
#include <nsas/nsas_entry.h>
#include <nsas/fetchable.h>
+#include "rrset_entry.h"
using namespace isc::nsas;
@@ -43,8 +44,9 @@
/// message.
/// \param message The message used to initialize MessageEntry.
/// \param rrset_cache the pointer of RRsetCache. When one message
- /// entry is created, some new rrset entries may be created/updated
- /// if they doesn't exist in the rrset cache.
+ /// entry is created, rrset cache needs to be updated, since some
+ /// new rrset entries may be inserted into the rrset cache, or the
+ /// existed rrset entries need to be updated.
MessageEntry(const isc::dns::Message& message,
boost::shared_ptr<RRsetCache> rrset_cache);
@@ -60,10 +62,35 @@
bool genMessage(const time_t& time_now,
const uint16_t query_header,
isc::dns::Message& response);
+
+ /// \brief Get the hash key of the message entry.
+ /// \return return hash key
+ virtual HashKey hashKey() const;
+
protected:
- // Initialize the message entry with dns message.
+ /// \brief Initialize the message entry with dns message.
void initMessageEntry(const isc::dns::Message& message);
+ /// \brief These two functions should be static functions
+ /// placed in cc file. Put them here just for easy unit
+ /// test.
+ //@{
+ /// \brief Parse the rrsets in specified section.
+ /// \param smaller_ttl Get the smallest ttl of rrsets in
+ /// specified section, if it's smaller than the given value.
+ void parseSection(const isc::dns::Message& msg,
+ const isc::dns::Message::Section& section,
+ uint32_t& smaller_ttl);
+
+ /// \brief Get RRset Trust worthiness
+ /// only the rrset can be updated by the rrsets
+ /// with higher trust level.
+ ///
+ /// \return return rrset trust level.
+ RRsetTrustLevel getRRsetTrustLevel(const isc::dns::Message& message,
+ const isc::dns::RRset& rrset,
+ const isc::dns::Message::Section& section);
+ //@}
private:
time_t expire_time_; // Expiration time of the message.
@@ -77,7 +104,7 @@
uint16_t authority_count_; // rrset count in authority section.
uint16_t additional_count_; // rrset count in addition section.
- std::vector<boost::shared_ptr<RRsetEntry*> > rrsets_;
+ std::vector<boost::shared_ptr<RRsetEntry> > rrsets_;
boost::shared_ptr<RRsetCache> rrset_cache_;
};
Modified: branches/trac449/src/lib/cache/rrset_cache.cc
==============================================================================
--- branches/trac449/src/lib/cache/rrset_cache.cc (original)
+++ branches/trac449/src/lib/cache/rrset_cache.cc Fri Dec 31 10:58:34 2010
@@ -33,7 +33,7 @@
{
}
-
+
RRsetEntryPtr
RRsetCache::lookup(const isc::dns::Name& qname,
const isc::dns::RRType& qtype)
@@ -41,8 +41,14 @@
CacheEntryKey keydata = genCacheEntryKey(qname, qtype);
//TODO, HashKey need to be refactored, since we don't need query class
// as the parameters.
- return rrset_table_.get(HashKey(
+ RRsetEntryPtr entry_ptr = rrset_table_.get(HashKey(
keydata.first, keydata.second, RRClass(class_)));
+
+ //If the rrset entry has expired, return NULL.
+ if(time(NULL) > entry_ptr->getExpireTime()) {
+ return RRsetEntryPtr();
+ }
+ return entry_ptr;
}
RRsetEntryPtr
@@ -53,7 +59,8 @@
// rrset entry doesn't exist, create one rrset entry for the rrset
// and add it directly.
entry_ptr.reset(new RRsetEntry(rrset, level));
- rrset_table_.add(entry_ptr, entry_ptr->hashKey());
+ // Replace the expired rrset entry if it exists.
+ rrset_table_.add(entry_ptr, entry_ptr->hashKey(), true);
//TODO , lru list touch.
return entry_ptr;
} else {
@@ -69,22 +76,33 @@
rrset_table_.remove(key);
entry_ptr.reset(new RRsetEntry(rrset, level));
//TODO, lru list touch.
- rrset_table_.add(entry_ptr, key);
+ // Replace the expired rrset entry if it exists.
+ rrset_table_.add(entry_ptr, key, true);
return entry_ptr;
}
}
}
+HashKey
+RRsetCache::getEntryHashKey(const Name& name, const RRType& type) const
+{
+ CacheEntryKey keydata = genCacheEntryKey(name, type);
+ return HashKey(keydata.first, keydata.second, RRClass(class_));
+}
+
void
RRsetCache::dump(const std::string&) {
+ //TODO
}
void
RRsetCache::load(const std::string&) {
+ //TODO
}
bool
RRsetCache::resize(uint32_t) {
+ //TODO
return true;
}
Modified: branches/trac449/src/lib/cache/rrset_cache.h
==============================================================================
--- branches/trac449/src/lib/cache/rrset_cache.h (original)
+++ branches/trac449/src/lib/cache/rrset_cache.h Fri Dec 31 10:58:34 2010
@@ -65,6 +65,14 @@
/// \brief Resize the size of rrset cache in runtime.
bool resize(uint32_t size);
+protected:
+ /// \brief Get the hash key for the rrset entry in the cache.
+ /// \param name name of the rrset.
+ /// \param type type of the rrset.
+ /// \return return the hash key.
+ HashKey getEntryHashKey(const isc::dns::Name& name,
+ const isc::dns::RRType& type) const;
+
private:
uint16_t class_; // The class of the rrset cache.
isc::nsas::HashTable<RRsetEntry> rrset_table_;
Modified: branches/trac449/src/lib/cache/rrset_entry.cc
==============================================================================
--- branches/trac449/src/lib/cache/rrset_entry.cc (original)
+++ branches/trac449/src/lib/cache/rrset_entry.cc Fri Dec 31 10:58:34 2010
@@ -30,18 +30,17 @@
}
void
-RRsetEntry::generateRRset(isc::dns::RRset&) const {
+RRsetEntry::genRRset(isc::dns::RRset&) const {
}
time_t
-RRsetEntry::getExpirationTime() const {
+RRsetEntry::getExpireTime() const {
return expire_time_;
}
HashKey
RRsetEntry::hashKey() const {
CacheEntryKey keydata = genCacheEntryKey(name_, type_);
- // as the parameters.
return HashKey(keydata.first, keydata.second, RRClass(class_));
}
Modified: branches/trac449/src/lib/cache/rrset_entry.h
==============================================================================
--- branches/trac449/src/lib/cache/rrset_entry.h (original)
+++ branches/trac449/src/lib/cache/rrset_entry.h Fri Dec 31 10:58:34 2010
@@ -27,7 +27,7 @@
namespace isc {
namespace cache {
-/// \brief RRset Trustworthiness
+/// \enum RRset Trustworthiness
/// For detail of rrset trustworthiness, please refer to
/// RFC2181 section5.4.1.
/// Bigger value is more trustworthy.
@@ -67,10 +67,15 @@
RRsetEntry(const isc::dns::RRset& rrset, const RRsetTrustLevel& level);
/// \brief Generate one rrset according the entry information.
- void generateRRset(isc::dns::RRset& rrset) const;
+ void genRRset(isc::dns::RRset& rrset) const;
/// \brief Get the expiration time of the rrset.
- time_t getExpirationTime() const;
+ time_t getExpireTime() const;
+
+ /// \brief Get the ttl of the rrset.
+ uint32_t getTTL() const {
+ return ttl_;
+ }
/// \return return hash key
virtual HashKey hashKey() const;
More information about the bind10-changes
mailing list