[svn] commit: r2270 - in /branches/trac69/src/lib: datasrc/data_source.cc datasrc/tests/datasrc_unittest.cc dns/message.cc dns/message.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Jun 24 23:11:59 UTC 2010
Author: each
Date: Thu Jun 24 23:11:59 2010
New Revision: 2270
Log:
Prevent duplicate RRsets in answers, using the same method as BIND 9:
checking whether the answer already contains an rrset with a matching
name and type before inserting a new one. Added a new method
"hasRRset()" to the Message class, modified the data source
query logic to make use of it, and updated the CNAMELoop test to
confirm that only a single answer is returned, instead of the former 17.
Modified:
branches/trac69/src/lib/datasrc/data_source.cc
branches/trac69/src/lib/datasrc/tests/datasrc_unittest.cc
branches/trac69/src/lib/dns/message.cc
branches/trac69/src/lib/dns/message.h
Modified: branches/trac69/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac69/src/lib/datasrc/data_source.cc (original)
+++ branches/trac69/src/lib/datasrc/data_source.cc Thu Jun 24 23:11:59 2010
@@ -166,6 +166,25 @@
return (DataSrc::ERROR);
}
+// Add an RRset (and its associated RRSIG) to a message section,
+// checking first to ensure that there isn't already an RRset with
+// the same name and type.
+inline void
+addToMessage(Query& q, const Section& sect, RRsetPtr rrset,
+ bool no_dnssec = false)
+{
+ Message& m = q.message();
+ if (no_dnssec) {
+ if (rrset->getType() == RRType::RRSIG() || !m.hasRRset(sect, rrset)) {
+ m.addRRset(sect, rrset, false);
+ }
+ } else {
+ if (!m.hasRRset(sect, rrset)) {
+ m.addRRset(sect, rrset, q.wantDnssec());
+ }
+ }
+}
+
// Copy referral information into the authority section of a message
inline void
copyAuth(Query& q, RRsetList& auth) {
@@ -176,7 +195,7 @@
if (rrset->getType() == RRType::DS() && !q.wantDnssec()) {
continue;
}
- q.message().addRRset(Section::AUTHORITY(), rrset, q.wantDnssec());
+ addToMessage(q, Section::AUTHORITY(), rrset);
getAdditional(q, rrset);
}
}
@@ -232,14 +251,12 @@
RRsetPtr r = ref.findRRset(RRType::DNAME(), q.qclass());
if (r != NULL) {
RRsetList syn;
- q.message().addRRset(Section::ANSWER(), r, q.wantDnssec());
+ addToMessage(q, Section::ANSWER(), r);
q.message().setHeaderFlag(MessageFlag::AA());
synthesizeCname(task, r, syn);
if (syn.size() == 1) {
- q.message().addRRset(Section::ANSWER(),
- syn.findRRset(RRType::CNAME(),
- q.qclass()),
- q.wantDnssec());
+ addToMessage(q, Section::ANSWER(),
+ syn.findRRset(RRType::CNAME(), q.qclass()));
chaseCname(q, task, syn.findRRset(RRType::CNAME(),
q.qclass()));
return (true);
@@ -264,7 +281,6 @@
inline DataSrc::Result
addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
- Message& m = q.message();
RRsetList soa;
QueryTask newtask(*zonename, q.qclass(), RRType::SOA(),
@@ -274,8 +290,8 @@
return (DataSrc::ERROR);
}
- m.addRRset(Section::AUTHORITY(), soa.findRRset(RRType::SOA(), q.qclass()),
- q.wantDnssec());
+ addToMessage(q, Section::AUTHORITY(),
+ soa.findRRset(RRType::SOA(), q.qclass()));
return (DataSrc::SUCCESS);
}
@@ -284,14 +300,13 @@
const Name& zonename, const DataSrc* ds)
{
RRsetList nsec;
- Message& m = q.message();
QueryTask newtask(name, task->qclass, RRType::NSEC(),
QueryTask::SIMPLE_QUERY);
RETERR(doQueryTask(ds, &zonename, newtask, nsec));
if (newtask.flags == 0) {
- m.addRRset(Section::AUTHORITY(), nsec.findRRset(RRType::NSEC(),
- q.qclass()), true);
+ addToMessage(q, Section::AUTHORITY(),
+ nsec.findRRset(RRType::NSEC(), q.qclass()));
}
return (DataSrc::SUCCESS);
@@ -344,14 +359,13 @@
proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
const Name& zonename, const bool wildcard)
{
- Message& m = q.message();
ConstNsec3ParamPtr nsec3 = getNsec3Param(q, ds, zonename);
if (nsec3 != NULL) {
// Attach the NSEC3 record covering the QNAME
RRsetPtr rrset;
string hash1(nsec3->getHash(task->qname));
RETERR(getNsec3(ds, zonename, q.qclass(), hash1, rrset));
- m.addRRset(Section::AUTHORITY(), rrset, true);
+ addToMessage(q, Section::AUTHORITY(), rrset);
// If this is an NXRRSET or NOERROR/NODATA, we're done
if ((task->flags & DataSrc::TYPE_NOT_FOUND) != 0) {
@@ -376,7 +390,7 @@
// we don't want to use one until we find an exact match
RETERR(getNsec3(ds, zonename, q.qclass(), hash2, rrset));
if (hash2 == nodehash) {
- m.addRRset(Section::AUTHORITY(), rrset, true);
+ addToMessage(q, Section::AUTHORITY(), rrset);
break;
}
}
@@ -391,7 +405,7 @@
string hash3(nsec3->getHash(Name("*").concatenate(enclosure)));
RETERR(getNsec3(ds, zonename, q.qclass(), hash3, rrset));
if (hash3 != hash1 && hash3 != hash2) {
- m.addRRset(Section::AUTHORITY(), rrset, true);
+ addToMessage(q, Section::AUTHORITY(), rrset);
}
} else {
Name nsecname(task->qname);
@@ -487,13 +501,13 @@
RRsetPtr rrset = wild.findRRset(RRType::CNAME(), q.qclass());
if (rrset != NULL) {
rrset->setName(task->qname);
- m.addRRset(Section::ANSWER(), rrset, q.wantDnssec());
+ addToMessage(q, Section::ANSWER(), rrset);
chaseCname(q, task, rrset);
}
} else {
BOOST_FOREACH (RRsetPtr rrset, wild) {
rrset->setName(task->qname);
- m.addRRset(Section::ANSWER(), rrset, q.wantDnssec());
+ addToMessage(q, Section::ANSWER(), rrset);
}
RRsetList auth;
@@ -597,7 +611,7 @@
case QueryTask::GETANSWER:
case QueryTask::FOLLOWCNAME:
BOOST_FOREACH(RRsetPtr rrset, data) {
- m.addRRset(task->section, rrset, q.wantDnssec());
+ addToMessage(q, task->section, rrset);
if (q.tasks().empty()) {
need_auth = true;
}
@@ -647,7 +661,7 @@
// queue to look up its target.
RRsetPtr rrset = data.findRRset(RRType::CNAME(), q.qclass());
if (rrset != NULL) {
- m.addRRset(task->section, rrset, q.wantDnssec());
+ addToMessage(q, task->section, rrset);
chaseCname(q, task, rrset);
}
continue;
@@ -663,12 +677,12 @@
}
BOOST_FOREACH (RRsetPtr rrset, auth) {
if (rrset->getType() == RRType::NS()) {
- m.addRRset(Section::AUTHORITY(), rrset, q.wantDnssec());
+ addToMessage(q, Section::AUTHORITY(), rrset);
} else if (rrset->getType() == task->qtype) {
- m.addRRset(Section::ANSWER(), rrset, q.wantDnssec());
+ addToMessage(q, Section::ANSWER(), rrset);
} else if (rrset->getType() == RRType::DS() &&
q.wantDnssec()) {
- m.addRRset(Section::AUTHORITY(), rrset, true);
+ addToMessage(q, Section::AUTHORITY(), rrset);
}
getAdditional(q, rrset);
}
@@ -735,13 +749,13 @@
// space, signatures in additional section are
// optional.)
BOOST_FOREACH(RRsetPtr rrset, additional) {
- m.addRRset(Section::ADDITIONAL(), rrset, false);
+ addToMessage(q, Section::ADDITIONAL(), rrset, true);
}
if (q.wantDnssec()) {
BOOST_FOREACH(RRsetPtr rrset, additional) {
if (rrset->getRRsig()) {
- m.addRRset(Section::ADDITIONAL(), rrset->getRRsig(), false);
+ addToMessage(q, Section::ADDITIONAL(), rrset->getRRsig(), true);
}
}
}
Modified: branches/trac69/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac69/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac69/src/lib/datasrc/tests/datasrc_unittest.cc Thu Jun 24 23:11:59 2010
@@ -772,6 +772,8 @@
TEST_F(DataSrcTest, CNAMELoop) {
createAndProcessQuery(Name("loop1.example.com"), RRClass::IN(),
RRType::A());
+ EXPECT_EQ(Rcode::NOERROR(), msg.getRcode());
+ EXPECT_EQ(1, msg.getRRCount(Section::ANSWER()));
}
// NSEC query for the name of a zone cut for non-secure delegation.
Modified: branches/trac69/src/lib/dns/message.cc
==============================================================================
--- branches/trac69/src/lib/dns/message.cc (original)
+++ branches/trac69/src/lib/dns/message.cc Thu Jun 24 23:11:59 2010
@@ -21,6 +21,7 @@
#include <sstream>
#include <vector>
+#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
@@ -379,6 +380,20 @@
impl_->rrsets_[sectionCodeToId(section)].push_back(sp);
impl_->counts_[section.getCode()] += sp->getRdataCount();
}
+}
+
+bool
+Message::hasRRset(const Section& section, RRsetPtr rrset) {
+ BOOST_FOREACH(RRsetPtr r, impl_->rrsets_[sectionCodeToId(section)]) {
+ if (r->getType() == rrset->getType() &&
+ r->getName() == rrset->getName())
+ {
+ return (true);
+
+ }
+ }
+
+ return (false);
}
void
Modified: branches/trac69/src/lib/dns/message.h
==============================================================================
--- branches/trac69/src/lib/dns/message.h (original)
+++ branches/trac69/src/lib/dns/message.h Thu Jun 24 23:11:59 2010
@@ -741,6 +741,10 @@
/// Only allowed in the \c RENDER mode.
void addRRset(const Section& section, RRsetPtr rrset, bool sign = false);
+ /// \brief Determine whether the given section already has an RRset
+ /// matching the name and type of this one
+ bool hasRRset(const Section& section, RRsetPtr rrset);
+
// The following methods are not currently implemented.
//void removeQuestion(QuestionPtr question);
//void removeRRset(const Section& section, RRsetPtr rrset);
More information about the bind10-changes
mailing list