BIND 10 trac493, updated. 3cb71c8c163525c612460eff4292adb997f8a797 [trac493] Add NODATA response processing
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Feb 28 06:48:02 UTC 2011
The branch, trac493 has been updated
via 3cb71c8c163525c612460eff4292adb997f8a797 (commit)
from 2a0f21d3415558e8be812e74e554e11c6cbd6270 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3cb71c8c163525c612460eff4292adb997f8a797
Author: Ocean Wang <wanghaidong at cnnic.cn>
Date: Mon Feb 28 14:47:25 2011 +0800
[trac493] Add NODATA response processing
-----------------------------------------------------------------------
Summary of changes:
src/lib/cache/message_entry.cc | 58 +++++++++++++-------
src/lib/cache/message_entry.h | 11 +++-
src/lib/cache/tests/negative_cache_unittest.cc | 49 +++++++++++++++++
.../tests/testdata/message_example_com_soa.wire | 2 +-
4 files changed, 95 insertions(+), 25 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/cache/message_entry.cc b/src/lib/cache/message_entry.cc
index b857bd7..9df59b9 100644
--- a/src/lib/cache/message_entry.cc
+++ b/src/lib/cache/message_entry.cc
@@ -230,26 +230,12 @@ MessageEntry::parseSection(const isc::dns::Message& msg,
void
MessageEntry::parseNegativeResponseAuthoritySection(const isc::dns::Message& msg,
uint32_t& soa_ttl,
- uint16_t& rrset_count,
- bool& found_soa)
+ uint16_t& rrset_count)
{
- RRsetIterator iter;
- for(iter = msg.beginSection(Message::SECTION_AUTHORITY);
- iter != msg.endSection(Message::SECTION_AUTHORITY);
- ++iter){
- RRsetPtr rrset_ptr = *iter;
- if (rrset_ptr->getType() == RRType::SOA()){
- found_soa = true;
- break;
- }
- }
- if(!found_soa){
- return;
- }
// We found the SOA record, so we can cache the message and RRsets in the cache
uint16_t count = 0;
- for(iter = msg.beginSection(Message::SECTION_AUTHORITY);
+ for(RRsetIterator iter = msg.beginSection(Message::SECTION_AUTHORITY);
iter != msg.endSection(Message::SECTION_AUTHORITY);
++iter){
RRsetPtr rrset_ptr = *iter;
@@ -292,13 +278,15 @@ MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
} else {
uint32_t min_ttl = MAX_UINT32;
uint32_t soa_ttl = MAX_UINT32;
- bool found_soa = false;
uint16_t rrset_count = 0;
- parseNegativeResponseAuthoritySection(msg, soa_ttl, rrset_count, found_soa);
- // For negative response, if no soa RRset is found, dont cache it
- if(!found_soa) {
+
+ // For negative response, if no soa RRset is found in authority section, dont cache it
+ if(!hasTheRecordInAuthoritySection(msg, RRType::SOA())){
return;
}
+
+ parseNegativeResponseAuthoritySection(msg, soa_ttl, rrset_count);
+
authority_count_ = rrset_count;
parseSection(msg, Message::SECTION_ANSWER, min_ttl, answer_count_);
parseSection(msg, Message::SECTION_ADDITIONAL, min_ttl, additional_count_);
@@ -311,7 +299,35 @@ MessageEntry::initMessageEntry(const isc::dns::Message& msg) {
bool
MessageEntry::isNegativeResponse(const isc::dns::Message& msg)
{
- return msg.getRcode() == Rcode::NXDOMAIN();
+ 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;
+ }
+ }
+ }
+
+ 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;
}
} // namespace cache
diff --git a/src/lib/cache/message_entry.h b/src/lib/cache/message_entry.h
index 6d3c8a6..383e236 100644
--- a/src/lib/cache/message_entry.h
+++ b/src/lib/cache/message_entry.h
@@ -124,11 +124,9 @@ protected:
/// \param msg The message to parse the RRsets from
/// \param soa_ttl Get the ttl of soa rrset in the authority section
/// \param rrset_count the rrset count of the authority section
- /// \param found_soa whether the soa RRset is found in the authority section
void parseNegativeResponseAuthoritySection(const isc::dns::Message& msg,
uint32_t& soa_ttl,
- uint16_t& rrset_count,
- bool& found_soa);
+ uint16_t& rrset_count);
/// \brief Get RRset Trustworthiness
/// The algorithm refers to RFC2181 section 5.4.1
@@ -172,8 +170,15 @@ 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.
diff --git a/src/lib/cache/tests/negative_cache_unittest.cc b/src/lib/cache/tests/negative_cache_unittest.cc
index d8c122a..20b3fc5 100644
--- a/src/lib/cache/tests/negative_cache_unittest.cc
+++ b/src/lib/cache/tests/negative_cache_unittest.cc
@@ -115,4 +115,53 @@ TEST_F(NegativeCacheTest, testNXDOMAINWithoutSOA){
EXPECT_FALSE(cache->lookup(non_exist_qname, RRType::A(), RRClass::IN(), msg_nxdomain));
}
+TEST_F(NegativeCacheTest, testNoerrorNodata){
+ // NODATA/NOERROR response for MX type query of example.com
+ Message msg_nodata(Message::PARSE);
+ messageFromFile(msg_nodata, "message_nodata_with_soa.wire");
+ cache->update(msg_nodata);
+
+ msg_nodata.makeResponse();
+
+ Name example_dot_com("example.com.");
+ EXPECT_TRUE(cache->lookup(example_dot_com, RRType::MX(), RRClass::IN(), msg_nodata));
+
+ RRsetIterator iter = msg_nodata.beginSection(Message::SECTION_AUTHORITY);
+ RRsetPtr rrset_ptr = *iter;
+
+ // The TTL should equal to the TTL of SOA record
+ const RRTTL& nodata_ttl1 = rrset_ptr->getTTL();
+ EXPECT_EQ(nodata_ttl1.getValue(), 86400);
+
+
+ // Normal SOA response for example.com
+ Message msg_example_com_soa(Message::PARSE);
+ messageFromFile(msg_example_com_soa, "message_example_com_soa.wire");
+ cache->update(msg_example_com_soa);
+
+ msg_example_com_soa.makeResponse();
+ Name soa_qname("example.com.");
+ EXPECT_TRUE(cache->lookup(soa_qname, RRType::SOA(), RRClass::IN(), msg_example_com_soa));
+
+ iter = msg_example_com_soa.beginSection(Message::SECTION_ANSWER);
+ rrset_ptr = *iter;
+
+ // The TTL should equal to the TTL of SOA record in answer section
+ const RRTTL& soa_ttl = rrset_ptr->getTTL();
+ EXPECT_EQ(soa_ttl.getValue(), 172800);
+
+ // Query MX record of example.com again
+ Message msg_nodata2(Message::PARSE);
+ messageFromFile(msg_nodata2, "message_nodata_with_soa.wire");
+ msg_nodata2.makeResponse();
+
+ EXPECT_TRUE(cache->lookup(example_dot_com, RRType::MX(), RRClass::IN(), msg_nodata2));
+ iter = msg_nodata2.beginSection(Message::SECTION_AUTHORITY);
+ rrset_ptr = *iter;
+
+ // The TTL should equal to the TTL of negative response SOA record
+ const RRTTL& nodata_ttl2 = rrset_ptr->getTTL();
+ EXPECT_EQ(nodata_ttl2.getValue(), 86400);
+}
+
}
diff --git a/src/lib/cache/tests/testdata/message_example_com_soa.wire b/src/lib/cache/tests/testdata/message_example_com_soa.wire
index 054834e..6d70ed7 100644
--- a/src/lib/cache/tests/testdata/message_example_com_soa.wire
+++ b/src/lib/cache/tests/testdata/message_example_com_soa.wire
@@ -30,7 +30,7 @@ c0 0c
00 06
# Class: IN (0x0001)
00 01
-# Time to live: 2 days
+# Time to live: 2 days (172800s)
00 02 a3 00
# Data length: 49
00 31
More information about the bind10-changes
mailing list