|
@@ -31,9 +31,25 @@ namespace cache {
|
|
|
|
|
|
static uint32_t MAX_UINT32 = numeric_limits<uint32_t>::max();
|
|
|
|
|
|
+// As with caching positive responses it is sensible for a resolver to
|
|
|
+// limit for how long it will cache a negative response as the protocol
|
|
|
+// supports caching for up to 68 years. Such a limit should not be
|
|
|
+// greater than that applied to positive answers and preferably be
|
|
|
+// tunable. Values of one to three hours have been found to work well
|
|
|
+// and would make sensible a default. Values exceeding one day have
|
|
|
+// been found to be problematic. (sec 5, RFC2308)
|
|
|
+// The default value is 3 hourse (10800 seconds)
|
|
|
+// TODO:Give an option to let user configure
|
|
|
+static uint32_t MAX_NEGATIVE_CACHE_TTL = 10800;
|
|
|
+
|
|
|
+// Sets the maximum time for which the server will cache ordinary (positive) answers. The
|
|
|
+// default is one week (7 days = 604800 seconds)
|
|
|
+// TODO:Give an option to let user configure
|
|
|
+static uint32_t MAX_NORMAL_CACHE_TTL = 604800;
|
|
|
+
|
|
|
MessageEntry::MessageEntry(const isc::dns::Message& msg,
|
|
|
- boost::shared_ptr<RRsetCache> rrset_cache,
|
|
|
- boost::shared_ptr<RRsetCache> negative_soa_cache):
|
|
|
+ const RRsetCachePtr& rrset_cache,
|
|
|
+ const RRsetCachePtr& negative_soa_cache):
|
|
|
rrset_cache_(rrset_cache),
|
|
|
negative_soa_cache_(negative_soa_cache),
|
|
|
headerflag_aa_(false),
|
|
@@ -51,7 +67,7 @@ MessageEntry::getRRsetEntries(vector<RRsetEntryPtr>& rrset_entry_vec,
|
|
|
uint16_t entry_count = answer_count_ + authority_count_ + additional_count_;
|
|
|
rrset_entry_vec.reserve(rrset_entry_vec.size() + entry_count);
|
|
|
for (int index = 0; index < entry_count; ++index) {
|
|
|
- boost::shared_ptr<RRsetCache> rrset_cache = rrsets_[index].cache_;
|
|
|
+ RRsetCache* rrset_cache = rrsets_[index].cache_;
|
|
|
RRsetEntryPtr rrset_entry = rrset_cache->lookup(rrsets_[index].name_,
|
|
|
rrsets_[index].type_);
|
|
|
if (time_now < rrset_entry->getExpireTime()) {
|
|
@@ -106,7 +122,9 @@ MessageEntry::genMessage(const time_t& time_now,
|
|
|
// Begin message generation. We don't need to add question
|
|
|
// section, since it has been included in the message.
|
|
|
// Set cached header flags.
|
|
|
- msg.setHeaderFlag(Message::HEADERFLAG_AA, headerflag_aa_);
|
|
|
+ // The AA flag bit should be cleared because this is a response from
|
|
|
+ // resolver cache
|
|
|
+ msg.setHeaderFlag(Message::HEADERFLAG_AA, false);
|
|
|
msg.setHeaderFlag(Message::HEADERFLAG_TC, headerflag_tc_);
|
|
|
|
|
|
bool dnssec_need = msg.getEDNS().get();
|
|
@@ -216,7 +234,7 @@ MessageEntry::parseSection(const isc::dns::Message& msg,
|
|
|
RRsetTrustLevel level = getRRsetTrustLevel(msg, rrset_ptr, section);
|
|
|
RRsetEntryPtr rrset_entry = rrset_cache_->update(*rrset_ptr, level);
|
|
|
rrsets_.push_back(RRsetRef(rrset_ptr->getName(), rrset_ptr->getType(),
|
|
|
- rrset_cache_));
|
|
|
+ rrset_cache_.get()));
|
|
|
|
|
|
uint32_t rrset_ttl = rrset_entry->getTTL();
|
|
|
if (smaller_ttl > rrset_ttl) {
|
|
@@ -249,7 +267,7 @@ MessageEntry::parseNegativeResponseAuthoritySection(const isc::dns::Message& msg
|
|
|
RRsetEntryPtr rrset_entry = rrset_cache_ptr->update(*rrset_ptr, level);
|
|
|
rrsets_.push_back(RRsetRef(rrset_ptr->getName(),
|
|
|
rrset_ptr->getType(),
|
|
|
- rrset_cache_ptr));
|
|
|
+ rrset_cache_ptr.get()));
|
|
|
uint32_t rrset_ttl = rrset_entry->getTTL();
|
|
|
if (min_ttl > rrset_ttl) {
|
|
|
min_ttl = rrset_ttl;
|
|
@@ -276,14 +294,27 @@ MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
|
|
|
|
|
|
uint32_t min_ttl = MAX_UINT32;
|
|
|
|
|
|
+ bool isNegativeResponse = MessageUtility::isNegativeResponse(msg);
|
|
|
+
|
|
|
parseSection(msg, Message::SECTION_ANSWER, min_ttl, answer_count_);
|
|
|
- if (!MessageUtility::isNegativeResponse(msg)){
|
|
|
+ if (!isNegativeResponse) {
|
|
|
parseSection(msg, Message::SECTION_AUTHORITY, min_ttl, authority_count_);
|
|
|
} else {
|
|
|
parseNegativeResponseAuthoritySection(msg, min_ttl, authority_count_);
|
|
|
}
|
|
|
parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl, additional_count_);
|
|
|
|
|
|
+ // Limit the ttl to a prset max-value
|
|
|
+ if (!isNegativeResponse) {
|
|
|
+ if (min_ttl > MAX_NORMAL_CACHE_TTL) {
|
|
|
+ min_ttl = MAX_NORMAL_CACHE_TTL;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (min_ttl > MAX_NEGATIVE_CACHE_TTL) {
|
|
|
+ min_ttl = MAX_NEGATIVE_CACHE_TTL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
expire_time_ = time(NULL) + min_ttl;
|
|
|
}
|
|
|
|