}
/** dangling is declared true if we were unable to resolve everything */
-int PacketHandler::doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& soadata)
+int PacketHandler::doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& soadata, bool retargeted)
{
DNSResourceRecord rr;
SOAData sd;
// we now have a copy, push_back on packet might reallocate!
for(vector<DNSResourceRecord>::const_iterator i=crrs.begin(); i!=crrs.end(); ++i) {
- if(r->d.aa && !i->qname.empty() && i->qtype.getCode()==QType::NS && !B.getSOA(i->qname,sd,p)) { // drop AA in case of non-SOA-level NS answer, except for root referral
+ if(r->d.aa && !i->qname.empty() && i->qtype.getCode()==QType::NS && !B.getSOA(i->qname,sd,p) && !retargeted) { // drop AA in case of non-SOA-level NS answer, except for root referral
r->setA(false);
// i->d_place=DNSResourceRecord::AUTHORITY; // XXX FIXME
}
return gotOne;
}
-bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target)
+bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target, bool retargeted)
{
vector<DNSResourceRecord> rrset = getBestReferralNS(p, sd, target);
if(rrset.empty())
rr.d_place=DNSResourceRecord::AUTHORITY;
r->addRecord(rr);
}
- r->setA(false);
+ if(!retargeted)
+ r->setA(false);
if(d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->qname))
addNSECX(p, r, rrset.begin()->qname, "", sd.qname, 1);
}
DLOG(L<<"Checking for referrals first, unless this is a DS query"<<endl);
- if(p->qtype.getCode() != QType::DS && tryReferral(p, r, sd, target))
+ if(p->qtype.getCode() != QType::DS && tryReferral(p, r, sd, target, retargetcount))
goto sendit;
DLOG(L<<"Got no referrals, trying ANY"<<endl);
if(p->qtype.getCode() == QType::DS)
{
DLOG(L<<"DS query found no direct result, trying referral now"<<endl);
- if(tryReferral(p, r, sd, target))
+ if(tryReferral(p, r, sd, target, retargetcount))
{
DLOG(L<<"got referral for DS query"<<endl);
goto sendit;
}
else if(weHaveUnauth) {
DLOG(L<<"Have unauth data, so need to hunt for best NS records"<<endl);
- if(tryReferral(p, r, sd, target))
+ if(tryReferral(p, r, sd, target, retargetcount))
goto sendit;
// check whether this could be fixed easily
if (*(rr.qname.rbegin()) == '.') {
}
sendit:;
- if(doAdditionalProcessingAndDropAA(p, r, sd)<0) {
+ if(doAdditionalProcessingAndDropAA(p, r, sd, retargetcount)<0) {
delete r;
return 0;
}
bool addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd);
bool getAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);
bool getTLDAuth(DNSPacket *p, SOAData *sd, const string &target, int *zoneId);
- int doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& sd);
+ int doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool retargeted);
bool doDNSSECProcessing(DNSPacket* p, DNSPacket *r);
void addNSECX(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string &auth, int mode);
void addNSEC(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string& auth, int mode);
void makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd);
void makeNOError(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd, int mode);
vector<DNSResourceRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const string &target);
- bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target);
+ bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target, bool retargeted);
bool getBestWildcard(DNSPacket *p, SOAData& sd, const string &target, string &wildcard, vector<DNSResourceRecord>* ret);
bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata);