|
@@ -166,6 +166,25 @@ doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
|
|
|
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 @@ copyAuth(Query& q, RRsetList& auth) {
|
|
|
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 @@ hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
|
|
|
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 @@ hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
|
|
|
|
|
|
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 @@ addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
|
|
|
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 @@ addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
|
|
|
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 @@ inline DataSrc::Result
|
|
|
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 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
|
// 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 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
|
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 @@ tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
|
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 @@ DataSrc::doQuery(Query& q) {
|
|
|
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;
|
|
|
}
|
|
@@ -650,7 +664,7 @@ DataSrc::doQuery(Query& q) {
|
|
|
// 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;
|
|
@@ -666,12 +680,12 @@ DataSrc::doQuery(Query& q) {
|
|
|
}
|
|
|
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);
|
|
|
}
|
|
@@ -739,13 +753,13 @@ DataSrc::doQuery(Query& q) {
|
|
|
// 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);
|
|
|
}
|
|
|
}
|
|
|
}
|