Commit af0eb33e authored by Ocean Wang's avatar Ocean Wang
Browse files

[trac493] Check whether the message can be cached before create the message

entry
parent ca06de9c
......@@ -29,5 +29,6 @@ libcache_la_SOURCES += rrset_entry.h rrset_entry.cc
libcache_la_SOURCES += cache_entry_key.h cache_entry_key.cc
libcache_la_SOURCES += rrset_copy.h rrset_copy.cc
libcache_la_SOURCES += local_zone_data.h local_zone_data.cc
libcache_la_SOURCES += message_utility.h message_utility.cc
CLEANFILES = *.gcno *.gcda
......@@ -20,14 +20,16 @@
#include <nsas/hash_table.h>
#include <nsas/hash_deleter.h>
#include "message_cache.h"
#include "message_utility.h"
#include "cache_entry_key.h"
namespace isc {
namespace cache {
using namespace isc::nsas;
using namespace isc::dns;
using namespace std;
namespace isc {
namespace cache {
using namespace MessageUtility;
MessageCache::MessageCache(boost::shared_ptr<RRsetCache> rrset_cache,
uint32_t cache_size, uint16_t message_class, boost::shared_ptr<RRsetCache> negative_soa_cache):
......@@ -58,6 +60,12 @@ MessageCache::lookup(const isc::dns::Name& qname,
bool
MessageCache::update(const Message& msg) {
// If the message is a negative response, but no SOA record is found in
// the authority section, the message cannot be cached
if (isNegativeResponse(msg) && !hasTheRecordInAuthoritySection(msg, RRType::SOA())){
return (false);
}
QuestionIterator iter = msg.beginQuestion();
std::string entry_name = genCacheEntryName((*iter)->getName(), (*iter)->getType());
HashKey entry_key = HashKey(entry_name, RRClass(message_class_));
......
......@@ -18,9 +18,9 @@
#include <limits>
#include <dns/message.h>
#include <dns/rcode.h>
#include <nsas/nsas_entry.h>
#include "message_entry.h"
#include "message_utility.h"
#include "rrset_cache.h"
using namespace isc::dns;
......@@ -242,8 +242,8 @@ MessageEntry::parseNegativeResponseAuthoritySection(const isc::dns::Message& msg
Message::SECTION_AUTHORITY);
boost::shared_ptr<RRsetCache> rrset_cache_ptr = rrset_cache_;
if (rrset_ptr->getType() == RRType::SOA()) {
rrset_cache_ptr.reset(negative_soa_cache_);
}
rrset_cache_ptr = negative_soa_cache_;
}
RRsetEntryPtr rrset_entry = rrset_cache_ptr->update(*rrset_ptr, level);
rrsets_.push_back(RRsetRef(rrset_ptr->getName(),
......@@ -274,60 +274,17 @@ MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
query_class_ = (*iter)->getClass().getCode();
uint32_t min_ttl = MAX_UINT32;
if (!isNegativeResponse(msg)){
parseSection(msg, Message::SECTION_ANSWER, min_ttl, answer_count_);
parseSection(msg, Message::SECTION_ANSWER, min_ttl, answer_count_);
if (!MessageUtility::isNegativeResponse(msg)){
parseSection(msg, Message::SECTION_AUTHORITY, min_ttl, authority_count_);
parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl, additional_count_);
} else {
// For negative response, if no soa RRset is found in authority
// section, don't cache it
if (!hasTheRecordInAuthoritySection(msg, RRType::SOA())) {
return;
}
parseNegativeResponseAuthoritySection(msg, min_ttl, authority_count_);
parseSection(msg, Message::SECTION_ANSWER, min_ttl, answer_count_);
parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl, additional_count_);
}
expire_time_ = time(NULL) + min_ttl;
}
bool
MessageEntry::isNegativeResponse(const isc::dns::Message& msg)
{
if (msg.getRcode() == Rcode::NXDOMAIN()) {
return (true);
} else if (msg.getRcode() == Rcode::NOERROR()) {
// no data in the answer section
if (msg.getRRCount(Message::SECTION_ANSWER) == 0) {
// NODATA type 1/ type 2 (ref sec2.2 of RFC2308)
if (hasTheRecordInAuthoritySection(msg, RRType::SOA())) {
return (true);
} else if (!hasTheRecordInAuthoritySection(msg, RRType::NS())) { // NODATA type 3 (sec2.2 of RFC2308)
return (true);
}
}
}
parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl, additional_count_);
return (false);
}
bool
MessageEntry::hasTheRecordInAuthoritySection(const isc::dns::Message& msg, const isc::dns::RRType& type)
{
for (RRsetIterator iter = msg.beginSection(Message::SECTION_AUTHORITY);
iter != msg.endSection(Message::SECTION_AUTHORITY);
++iter) {
RRsetPtr rrset_ptr = *iter;
if (rrset_ptr->getType() == type) {
return (true);
}
}
return (false);
expire_time_ = time(NULL) + min_ttl;
}
} // namespace cache
} // namespace isc
......@@ -168,20 +168,6 @@ protected:
//@}
private:
/// \brief Check whetehr the message is a negative response
/// (NXDOMAIN or NOERROR_NODATA)
///
/// \param msg The response message
bool isNegativeResponse(const isc::dns::Message& msg);
/// \brief Check whether there is some type of record in
/// Authority section
///
/// \param msg The response message to be checked
/// \param type The RR type that need to check
bool hasTheRecordInAuthoritySection(const isc::dns::Message& msg,
const isc::dns::RRType& type);
std::string entry_name_; // The name for this entry(name + type)
HashKey* hash_key_ptr_; // the key for messag entry in hash table.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment