|
@@ -14,23 +14,28 @@
|
|
|
|
|
|
// $Id$
|
|
// $Id$
|
|
|
|
|
|
|
|
+#include <limits>
|
|
#include <dns/message.h>
|
|
#include <dns/message.h>
|
|
#include <nsas/nsas_entry.h>
|
|
#include <nsas/nsas_entry.h>
|
|
#include <nsas/fetchable.h>
|
|
#include <nsas/fetchable.h>
|
|
#include "message_entry.h"
|
|
#include "message_entry.h"
|
|
#include "rrset_entry.h"
|
|
#include "rrset_entry.h"
|
|
|
|
+#include "rrset_cache.h"
|
|
|
|
|
|
|
|
|
|
using namespace isc::dns;
|
|
using namespace isc::dns;
|
|
|
|
+using namespace std;
|
|
|
|
|
|
namespace isc {
|
|
namespace isc {
|
|
namespace cache {
|
|
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):
|
|
boost::shared_ptr<RRsetCache> rrset_cache):
|
|
rrset_cache_(rrset_cache)
|
|
rrset_cache_(rrset_cache)
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+ initMessageEntry(msg);
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
bool
|
|
@@ -41,26 +46,100 @@ MessageEntry::genMessage(const time_t&,
|
|
return true;
|
|
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
|
|
void
|
|
MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
|
|
MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
|
|
query_count_ = msg.getRRCount(Message::SECTION_QUESTION);
|
|
query_count_ = msg.getRRCount(Message::SECTION_QUESTION);
|
|
answer_count_ = msg.getRRCount(Message::SECTION_ANSWER);
|
|
answer_count_ = msg.getRRCount(Message::SECTION_ANSWER);
|
|
authority_count_ = msg.getRRCount(Message::SECTION_AUTHORITY);
|
|
authority_count_ = msg.getRRCount(Message::SECTION_AUTHORITY);
|
|
additional_count_ = msg.getRRCount(Message::SECTION_ADDITIONAL);
|
|
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
|
|
} // namespace cache
|