nsec3zone=getNSEC3PARAM(auth, &ns3pr);
if(!nsec3zone) {
- DNSName dqname = DNSName(labelReverse(qname));
+ DNSName dqname = DNSName(qname).labelReverse();
//cerr<<"in bind2backend::getBeforeAndAfterAbsolute: no nsec3 for "<<auth<<endl;
return findBeforeAndAfterUnhashed(bbd, dqname, unhashed, before, after);
}
void lookup(const QType &, const DNSName &qdomain, DNSPacket *p=0, int zoneId=-1);
bool list(const DNSName &target, int id, bool include_disabled=false);
bool get(DNSResourceRecord &);
+ bool get(DNSZoneRecord &) override;
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
static DNSBackend *maker();
bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname,
const DNSName& wildcardname, const QType& qtype,
- DNSResourceRecord::Place signPlace, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL)
+ DNSResourceRecord::Place signPlace, vector<DNSZoneRecord>& rrsigs, uint32_t signTTL)
{
// cerr<<"Doing DB lookup for precomputed RRSIGs for '"<<(wildcardname.empty() ? qname : wildcardname)<<"'"<<endl;
SOAData sd;
return false;
}
db.lookup(QType(QType::RRSIG), wildcardname.countLabels() ? wildcardname : qname, NULL, sd.domain_id);
- DNSResourceRecord rr;
- while(db.get(rr)) {
- // cerr<<"Considering for '"<<qtype.getName()<<"' RRSIG '"<<rr.content<<"'\n";
- vector<string> parts;
- stringtok(parts, rr.content);
- if(parts[0] == qtype.getName() && DNSName(parts[7])==signer) {
- // cerr<<"Got it"<<endl;
- if (wildcardname.countLabels())
- rr.qname = qname;
- rr.d_place = signPlace;
- rr.ttl = signTTL;
- rrsigs.push_back(rr);
- }
- // else cerr<<"Skipping!"<<endl;
+ DNSZoneRecord rr;
+ while(db.get(rr)) {
+ auto rrsig = getRR<RRSIGRecordContent>(rr.dr);
+ if(rrsig->d_type == qtype.getCode() && rrsig->d_signer==signer) {
+ if (wildcardname.countLabels())
+ rr.dr.d_name = qname;
+ rr.dr.d_place = signPlace;
+ rr.dr.d_ttl = signTTL;
+ rrsigs.push_back(rr);
+ }
}
return true;
}
return true;
}
+bool DNSBackend::get(DNSZoneRecord& dzr)
+{
+ DNSResourceRecord rr;
+ if(!this->get(rr))
+ return false;
+ dzr.auth = rr.auth;
+ dzr.domain_id = rr.domain_id;
+ dzr.dr = DNSRecord(rr);
+ return true;
+}
+
bool DNSBackend::getBeforeAndAfterNames(uint32_t id, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after)
{
// FIXME400 FIXME400 FIXME400
// string lcqname=toLower(qname); FIXME400 tolower?
// string lczonename=toLower(zonename); FIXME400 tolower?
// lcqname=makeRelative(lcqname, lczonename);
- DNSName lczonename = DNSName(toLower(zonename.toString()));
+ DNSName lczonename = zonename.makeLowerCase();
// lcqname=labelReverse(lcqname);
DNSName dnc;
string relqname, sbefore, safter;
- relqname=labelReverse(makeRelative(qname.toStringNoDot(), zonename.toStringNoDot())); // FIXME400
+ relqname=qname.makeRelative(zonename).toStringNoDot();
//sbefore = before.toString();
//safter = after.toString();
bool ret = this->getBeforeAndAfterNamesAbsolute(id, relqname, dnc, sbefore, safter);
- before = DNSName(labelReverse(sbefore)) + lczonename;
- after = DNSName(labelReverse(safter)) + lczonename;
+ before = DNSName(sbefore).labelReverse() + lczonename;
+ after = DNSName(safter).labelReverse() + lczonename;
// before=dotConcat(labelReverse(before), lczonename); FIXME400
// after=dotConcat(labelReverse(after), lczonename); FIXME400
return true;
}
+void fillSOAData(const DNSZoneRecord& in, SOAData& sd)
+{
+ sd.domain_id = in.domain_id;
+ sd.ttl = in.dr.d_ttl;
+
+ auto src=getRR<SOARecordContent>(in.dr);
+ sd.nameserver = src->d_mname;
+ sd.hostmaster = src->d_rname;
+ sd.serial = src->d_st.serial;
+ sd.refresh = src->d_st.refresh;
+ sd.retry = src->d_st.retry;
+ sd.expire = src->d_st.expire;
+ sd.default_ttl = src->d_st.minimum;
+}
+
+std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& sd)
+{
+ struct soatimes st;
+ st.serial = sd.serial;
+ st.refresh = sd.refresh;
+ st.retry = sd.retry;
+ st.expire = sd.expire;
+ st.minimum = sd.default_ttl;
+ return std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
+}
+
void fillSOAData(const string &content, SOAData &data)
{
//! lookup() initiates a lookup. A lookup without results should not throw!
virtual void lookup(const QType &qtype, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
+ virtual bool get(DNSZoneRecord &r);
//! Initiates a list of the specified domain
/** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false
/** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */
void fillSOAData(const string &content, SOAData &data);
-
+// same but more karmic
+void fillSOAData(const DNSZoneRecord& in, SOAData& data);
+// the reverse
+std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& sd);
#endif
d_rrs.clear();
}
-void DNSPacket::addRecord(const DNSResourceRecord &rr)
+void DNSPacket::addRecord(const DNSZoneRecord &rr)
{
// this removes duplicates from the packet in case we are not compressing
// for AXFR, no such checking is performed!
// cerr<<"addrecord, content=["<<rr.content<<"]"<<endl;
- if(d_compress)
- for(vector<DNSResourceRecord>::const_iterator i=d_rrs.begin();i!=d_rrs.end();++i)
- if(rr.qname==i->qname && rr.qtype==i->qtype && rr.content==i->content) {
+ if(0 && d_compress) {
+ for(auto i=d_rrs.begin();i!=d_rrs.end();++i) {
+ if(rr.dr == i->dr)
return;
- }
+ }
+ }
+
// cerr<<"added to d_rrs"<<endl;
d_rrs.push_back(rr);
}
-static int rrcomp(const DNSResourceRecord &A, const DNSResourceRecord &B)
-{
- if(A.d_place < B.d_place)
- return 1;
-
- return 0;
-}
-
-vector<DNSResourceRecord*> DNSPacket::getAPRecords()
+vector<DNSZoneRecord*> DNSPacket::getAPRecords()
{
- vector<DNSResourceRecord*> arrs;
+ vector<DNSZoneRecord*> arrs;
- for(vector<DNSResourceRecord>::iterator i=d_rrs.begin();
+ for(vector<DNSZoneRecord>::iterator i=d_rrs.begin();
i!=d_rrs.end();
++i)
{
- if(i->d_place!=DNSResourceRecord::ADDITIONAL &&
- (i->qtype.getCode()==QType::MX ||
- i->qtype.getCode()==QType::NS ||
- i->qtype.getCode()==QType::SRV))
+ if(i->dr.d_place!=DNSResourceRecord::ADDITIONAL &&
+ (i->dr.d_type==QType::MX ||
+ i->dr.d_type==QType::NS ||
+ i->dr.d_type==QType::SRV))
{
arrs.push_back(&*i);
}
}
-vector<DNSResourceRecord*> DNSPacket::getAnswerRecords()
+vector<DNSZoneRecord*> DNSPacket::getAnswerRecords()
{
- vector<DNSResourceRecord*> arrs;
+ vector<DNSZoneRecord*> arrs;
- for(vector<DNSResourceRecord>::iterator i=d_rrs.begin();
+ for(vector<DNSZoneRecord>::iterator i=d_rrs.begin();
i!=d_rrs.end();
++i)
{
- if(i->d_place!=DNSResourceRecord::ADDITIONAL)
+ if(i->dr.d_place!=DNSResourceRecord::ADDITIONAL)
arrs.push_back(&*i);
}
return arrs;
unsigned int DNSPacket::getMinTTL()
{
unsigned int minttl = UINT_MAX;
- for(const DNSResourceRecord& rr : d_rrs) {
- if (rr.ttl < minttl)
- minttl = rr.ttl;
+ for(const DNSZoneRecord& rr : d_rrs) {
+ if (rr.dr.d_ttl < minttl)
+ minttl = rr.dr.d_ttl;
}
return minttl;
return (d_rrs.empty());
}
+static void shuffle(vector<DNSZoneRecord>& rrs)
+{
+}
+
/** Must be called before attempting to access getData(). This function stuffs all resource
* records found in rrs into the data buffer. It also frees resource records queued for us.
*/
return;
}
- DNSResourceRecord rr;
- vector<DNSResourceRecord>::iterator pos;
+ DNSZoneRecord rr;
+ vector<DNSZoneRecord>::iterator pos;
// we now need to order rrs so that the different sections come at the right place
// we want a stable sort, based on the d_place field
- stable_sort(d_rrs.begin(),d_rrs.end(), rrcomp);
+ stable_sort(d_rrs.begin(),d_rrs.end(), [](const DNSZoneRecord& a, const DNSZoneRecord& b) {
+ return a.dr.d_place < b.dr.d_place;
+ });
static bool mustNotShuffle = ::arg().mustDo("no-shuffle");
if(!d_tcp && !mustNotShuffle) {
for(pos=d_rrs.begin(); pos < d_rrs.end(); ++pos) {
// cerr<<"during wrapup, content=["<<pos->content<<"]"<<endl;
maxScopeMask = max(maxScopeMask, pos->scopeMask);
-
- if(!pos->content.empty() && pos->qtype.getCode()==QType::TXT && pos->content[0]!='"') {
- pos->content="\""+pos->content+"\"";
- }
- if(pos->content.empty()) // empty contents confuse the MOADNS setup
- pos->content=".";
- pw.startRecord(pos->qname, pos->qtype.getCode(), pos->ttl, pos->qclass, pos->d_place);
- shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), pos->qclass, pos->content));
- drc->toPacket(pw);
+ pw.startRecord(pos->dr.d_name, pos->dr.d_type, pos->dr.d_ttl, pos->dr.d_class, pos->dr.d_place);
+ pos->dr.d_content->toPacket(pw);
if(pw.size() + 20U > (d_tcp ? 65535 : getMaxReplyLen())) { // 20 = room for EDNS0
pw.rollback();
- if(pos->d_place == DNSResourceRecord::ANSWER || pos->d_place == DNSResourceRecord::AUTHORITY) {
+ if(pos->dr.d_place == DNSResourceRecord::ANSWER || pos->dr.d_place == DNSResourceRecord::AUTHORITY) {
pw.getHeader()->tc=1;
}
goto noCommit;
if(d_trc.d_algoName.countLabels())
addTSIG(pw, &d_trc, d_tsigkeyname, d_tsigsecret, d_tsigprevious, d_tsigtimersonly);
- d_rawpacket.assign((char*)&packet[0], packet.size());
+ d_rawpacket.assign((char*)&packet[0], packet.size()); // XXX we could do this natively on a vector..
// copy RR counts so LPE can read them
d.qdcount = pw.getHeader()->qdcount;
#include "pdnsexception.hh"
#include "dnsrecords.hh"
-
-
class UeberBackend;
class DNSSECKeeper;
+
//! This class represents DNS packets, either received or to be sent.
class DNSPacket
{
void clearRecords(); //!< when building a packet, wipe all previously added records (clears 'rrs')
- /** Add a DNSResourceRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
+ /** Add a DNSZoneRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
- DNSResourceRecord d_place field */
- void addRecord(const DNSResourceRecord &); // adds to 'rrs'
+ DNSZoneRecord d_place field */
+ void addRecord(const DNSZoneRecord &); // adds to 'rrs'
void setQuestion(int op, const DNSName &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (domain, type, class etc)
unsigned int getMinTTL(); //!< returns lowest TTL of any record in the packet
bool isEmpty(); //!< returns true if there are no rrs in the packet
- vector<DNSResourceRecord*> getAPRecords(); //!< get a vector with DNSResourceRecords that need additional processing
- vector<DNSResourceRecord*> getAnswerRecords(); //!< get a vector with DNSResourceRecords that are answers
+ vector<DNSZoneRecord*> getAPRecords(); //!< get a vector with DNSZoneRecords that need additional processing
+ vector<DNSZoneRecord*> getAnswerRecords(); //!< get a vector with DNSZoneRecords that are answers
void setCompress(bool compress);
DNSPacket *replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
void setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly=false);
bool getTKEYRecord(TKEYRecordContent* tr, DNSName* keyname) const;
- vector<DNSResourceRecord>& getRRS() { return d_rrs; }
+ vector<DNSZoneRecord>& getRRS() { return d_rrs; }
static bool s_doEDNSSubnetProcessing;
static uint16_t s_udpTruncationThreshold; //2
private:
DNSName d_tsigkeyname;
string d_tsigprevious;
- vector<DNSResourceRecord> d_rrs; // 8
+ vector<DNSZoneRecord> d_rrs; // 8
string d_rawpacket; // this is where everything lives 8
string d_ednsping;
EDNSSubnetOpts d_eso;
bool operator==(const DNSRecord& rhs) const
{
+ if(d_type != rhs.d_type || d_class != rhs.d_class || d_name != rhs.d_name)
+ return false;
+
string lzrp, rzrp;
if(d_content)
lzrp=toLower(d_content->getZoneRepresentation());
if(rhs.d_content)
rzrp=toLower(rhs.d_content->getZoneRepresentation());
-
- string llabel=toLower(d_name.toString());
- string rlabel=toLower(rhs.d_name.toString());
-
- return
- tie(llabel, d_type, d_class, lzrp) ==
- tie(rlabel, rhs.d_type, rhs.d_class, rzrp);
+
+ return lzrp == rzrp;
}
};
+struct DNSZoneRecord
+{
+ int domain_id;
+ uint8_t scopeMask;
+ int signttl;
+ DNSName wildcardname;
+ bool auth;
+ DNSRecord dr;
+};
+
+
//! This class can be used to parse incoming packets, and is copyable
class MOADNSParser : public boost::noncopyable
{
// cerr<<"comp: "<<(int)j->first.d_place-1<<" "<<j->first.d_label<<" " << DNSRecordContent::NumberToType(j->first.d_type)<<" "<<j->first.d_content->getZoneRepresentation()<<endl;
if(j->first.d_place == DNSResourceRecord::ANSWER || (j->first.d_place == DNSResourceRecord::AUTHORITY && j->first.d_type == QType::SOA)) {
- DNSResourceRecord rr;
-
if(j->first.d_type == i->second.qtype || (i->second.qtype == QType::ANY && (j->first.d_type == QType::A || j->first.d_type == QType::AAAA))) {
- rr.qname=i->second.aname;
- rr.qtype = j->first.d_type;
- rr.ttl=j->first.d_ttl;
- rr.d_place= j->first.d_place;
- rr.content=j->first.d_content->getZoneRepresentation();
- i->second.complete->addRecord(rr);
+ DNSZoneRecord dzr;
+ dzr.dr.d_name=i->second.aname;
+ dzr.dr.d_type = j->first.d_type;
+ dzr.dr.d_ttl=j->first.d_ttl;
+ dzr.dr.d_place= j->first.d_place;
+ dzr.dr.d_content=j->first.d_content;
+ i->second.complete->addRecord(dzr);
}
}
}
public:
includeboilerplate(TXT)
-private:
string d_text;
};
{
public:
includeboilerplate(CNAME)
+ CNAMERecordContent(const DNSName& content) : d_content(content){}
DNSName getTarget() const { return d_content; }
private:
DNSName d_content;
public:
includeboilerplate(ALIAS)
-private:
DNSName d_content;
};
{
public:
includeboilerplate(DNAME)
-
-private:
DNSName d_content;
};
string hashQNameWithSalt(const std::string& salt, unsigned int iterations, const DNSName& qname);
void decodeDERIntegerSequence(const std::string& input, vector<string>& output);
class DNSPacket;
-void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const std::set<DNSName>& authMap, vector<DNSResourceRecord>& rrs);
+void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const std::set<DNSName>& authMap, vector<DNSZoneRecord>& rrs);
string calculateHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash);
bool unsetNSEC3PARAM(const DNSName& zname);
void clearAllCaches();
void clearCaches(const DNSName& name);
- bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL);
+ bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector<DNSZoneRecord>& rrsigs, uint32_t signTTL);
bool isPresigned(const DNSName& zname);
bool setPresigned(const DNSName& zname);
bool unsetPresigned(const DNSName& zname);
class DNSPacket;
uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
// for SOA-EDIT
-uint32_t calculateEditSOA(SOAData sd, const string& kind);
+uint32_t calculateEditSOA(const DNSZoneRecord& rr, const string& kind);
+uint32_t calculateEditSOA(const SOAData& sd, const string& kind);
bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp);
-bool editSOARecord(DNSResourceRecord& rr, const string& kind, const DNSName& qname);
+bool editSOARecord(DNSZoneRecord& rr, const string& kind, const DNSName& qname);
// for SOA-EDIT-DNSUPDATE/API
uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind);
bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind);
+bool increaseSOARecord(DNSZoneRecord& rr, const string& increaseKind, const string& editKind);
// this is the entrypoint from DNSPacket
void addSignature(DNSSECKeeper& dk, UeberBackend& db, const DNSName& signer, const DNSName signQName, const DNSName& wildcardname, uint16_t signQType,
uint32_t signTTL, DNSResourceRecord::Place signPlace,
- vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned, uint32_t origTTL)
+ vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSZoneRecord>& outsigned, uint32_t origTTL)
{
//cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n";
if(toSign.empty())
return;
}
- DNSResourceRecord rr;
- rr.qname=signQName;
- rr.qtype=QType::RRSIG;
+ DNSZoneRecord rr;
+ rr.dr.d_name=signQName;
+ rr.dr.d_type=QType::RRSIG;
if(origTTL)
- rr.ttl=origTTL;
+ rr.dr.d_ttl=origTTL;
else
- rr.ttl=signTTL;
+ rr.dr.d_ttl=signTTL;
rr.auth=false;
- rr.d_place = signPlace;
+ rr.dr.d_place = signPlace;
for(RRSIGRecordContent& rrc : rrcs) {
- rr.content = rrc.getZoneRepresentation();
+ rr.dr.d_content = std::make_shared<RRSIGRecordContent>(rrc);
outsigned.push_back(rr);
}
}
}
}
-static bool rrsigncomp(const DNSResourceRecord& a, const DNSResourceRecord& b)
+static bool rrsigncomp(const DNSZoneRecord& a, const DNSZoneRecord& b)
{
- return tie(a.d_place, a.qtype) < tie(b.d_place, b.qtype);
+ return tie(a.dr.d_place, a.dr.d_type) < tie(b.dr.d_place, b.dr.d_type);
}
static bool getBestAuthFromSet(const set<DNSName>& authSet, const DNSName& name, DNSName& auth)
return false;
}
-void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet, vector<DNSResourceRecord>& rrs)
+void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet, vector<DNSZoneRecord>& rrs)
{
stable_sort(rrs.begin(), rrs.end(), rrsigncomp);
DNSResourceRecord::Place signPlace=DNSResourceRecord::ANSWER;
vector<shared_ptr<DNSRecordContent> > toSign;
- vector<DNSResourceRecord> signedRecords;
+ vector<DNSZoneRecord> signedRecords;
signedRecords.reserve(rrs.size()*1.5);
- // cout<<rrs.size()<<", "<<sizeof(DNSResourceRecord)<<endl;
+ // cout<<rrs.size()<<", "<<sizeof(DNSZoneRecord)<<endl;
DNSName signer;
- for(vector<DNSResourceRecord>::const_iterator pos = rrs.begin(); pos != rrs.end(); ++pos) {
- if(pos != rrs.begin() && (signQType != pos->qtype.getCode() || signQName != pos->qname)) {
+ for(auto pos = rrs.cbegin(); pos != rrs.cend(); ++pos) {
+ if(pos != rrs.cbegin() && (signQType != pos->dr.d_type || signQName != pos->dr.d_name)) {
if(getBestAuthFromSet(authSet, signQName, signer))
addSignature(dk, db, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords, origTTL);
}
signedRecords.push_back(*pos);
- signQName= pos->qname.makeLowerCase();
+ signQName= pos->dr.d_name.makeLowerCase();
if(!pos->wildcardname.empty())
wildcardQName = pos->wildcardname.makeLowerCase();
else
wildcardQName.clear();
- signQType = pos ->qtype.getCode();
+ signQType = pos->dr.d_type;
if(pos->signttl)
signTTL = pos->signttl;
else
- signTTL = pos->ttl;
- origTTL = pos->ttl;
- signPlace = pos->d_place;
- if(pos->auth || pos->qtype.getCode() == QType::DS) {
- string content = pos->content;
- if(!pos->content.empty() && pos->qtype.getCode()==QType::TXT && pos->content[0]!='"') {
- content="\""+pos->content+"\"";
- }
- if(pos->content.empty()) // empty contents confuse the MOADNS setup
- content=".";
-
- shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), 1, content));
- toSign.push_back(drc);
+ signTTL = pos->dr.d_ttl;
+ origTTL = pos->dr.d_ttl;
+ signPlace = pos->dr.d_place;
+ if(pos->auth || pos->dr.d_type == QType::DS) {
+ toSign.push_back(pos->dr.d_content); // so ponder.. should this be a deep copy perhaps?
}
}
if(getBestAuthFromSet(authSet, signQName, signer))
vector<DNSRecord> rrs;
popResourceRecordsTable(L, DNSName("BOGUS"), rrs);
for(const DNSRecord& dr : rrs) {
- p->addRecord(DNSResourceRecord(dr));
+ DNSZoneRecord dzr;
+ dzr.dr=dr;
+ dzr.auth=true; // LET'S HOPE THIS IS TRUE XXX
+ p->addRecord(dzr);
}
return 0;
}
}
-string labelReverse(const std::string& qname)
-{
- if(qname.empty())
- return qname;
-
- bool dotName = qname.find('.') != string::npos;
-
- vector<string> labels;
- stringtok(labels, qname, ". ");
- if(labels.size()==1)
- return qname;
-
- string ret; // vv const_reverse_iter http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11729
- for(vector<string>::reverse_iterator iter = labels.rbegin(); iter != labels.rend(); ++iter) {
- if(iter != labels.rbegin())
- ret.append(1, dotName ? ' ' : '.');
- ret+=*iter;
- }
- return ret;
-}
-
-// do NOT feed trailing dots!
-// www.powerdns.com, powerdns.com -> www
-string makeRelative(const std::string& fqdn, const std::string& zone)
-{
- if(zone.empty())
- return fqdn;
- if(toLower(fqdn) != toLower(zone))
- return fqdn.substr(0, fqdn.size() - zone.length() - 1); // strip domain name
- return "";
-}
-
-string dotConcat(const std::string& a, const std::string &b)
-{
- if(a.empty() || b.empty())
- return a+b;
- else
- return a+"."+b;
-}
int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
{
string makeHexDump(const string& str);
void shuffle(vector<DNSRecord>& rrs);
void shuffle(vector<DNSResourceRecord>& rrs);
+
void orderAndShuffle(vector<DNSRecord>& rrs);
void normalizeTV(struct timeval& tv);
string stripDot(const string& dom);
void seedRandom(const string& source);
-string makeRelative(const std::string& fqdn, const std::string& zone);
-string labelReverse(const std::string& qname);
-std::string dotConcat(const std::string& a, const std::string &b);
int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret);
int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret);
int makeUNsockaddr(const std::string& path, struct sockaddr_un* ret);
S.inc("deferred-cache-inserts");
}
-void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector<DNSResourceRecord>& value, unsigned int ttl, int zoneID)
+void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector<DNSZoneRecord>& value, unsigned int ttl, int zoneID)
{
cleanupIfNeeded();
}
}
// called from ueberbackend
-bool PacketCache::getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSResourceRecord>& value, int zoneID)
+bool PacketCache::getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSZoneRecord>& value, int zoneID)
{
if(d_ttl<0)
getTTLS();
return ret;
}
-bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSResourceRecord>& value, int zoneID)
+bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSZoneRecord>& value, int zoneID)
{
uint16_t qt = qtype.getCode();
//cerr<<"Lookup for maxReplyLen: "<<maxReplyLen<<endl;
void insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID=-1, bool meritsRecursion=false,
unsigned int maxReplyLen=512, bool dnssecOk=false, bool EDNS=false);
- void insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector<DNSResourceRecord>& content, unsigned int ttl, int zoneID=-1);
+ void insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector<DNSZoneRecord>& content, unsigned int ttl, int zoneID=-1);
int get(DNSPacket *p, DNSPacket *q, bool recursive); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method.
bool getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
bool meritsRecursion=false, unsigned int maxReplyLen=512, bool dnssecOk=false, bool hasEDNS=false, unsigned int *age=0);
- bool getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSResourceRecord>& entry, int zoneID=-1);
+ bool getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector<DNSZoneRecord>& entry, int zoneID=-1);
int size(); //!< number of entries in the cache
private:
bool getEntryLocked(const DNSName &content, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
bool meritsRecursion=false, unsigned int maxReplyLen=512, bool dnssecOk=false, bool hasEDNS=false, unsigned int *age=0);
- bool getEntryLocked(const DNSName &content, const QType& qtype, CacheEntryType cet, vector<DNSResourceRecord>& entry, int zoneID=-1);
+ bool getEntryLocked(const DNSName &content, const QType& qtype, CacheEntryType cet, vector<DNSZoneRecord>& entry, int zoneID=-1);
struct CacheEntry
DNSName qname;
string value;
- vector<DNSResourceRecord> drs;
+ vector<DNSZoneRecord> drs;
time_t created;
time_t ttd;
if (publishCDNSKEY != "1")
return false;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
bool haveOne=false;
DNSSECPrivateKey dpk;
DNSSECKeeper::keyset_t entryPoints = d_dk.getEntryPoints(p->qdomain);
for(const auto& value: entryPoints) {
- rr.qtype=QType::CDNSKEY;
- rr.ttl=sd.default_ttl;
- rr.qname=p->qdomain;
- rr.content=value.first.getDNSKEY().getZoneRepresentation();
+ rr.dr.d_type=QType::CDNSKEY;
+ rr.dr.d_ttl=sd.default_ttl;
+ rr.dr.d_name=p->qdomain;
+ rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
r->addRecord(rr);
haveOne=true;
B.lookup(QType(QType::CDNSKEY), p->qdomain, p, sd.domain_id);
while(B.get(rr)) {
- rr.ttl=sd.default_ttl;
+ rr.dr.d_ttl=sd.default_ttl;
r->addRecord(rr);
haveOne=true;
}
**/
bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd)
{
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
bool haveOne=false;
DNSSECPrivateKey dpk;
DNSSECKeeper::keyset_t keyset = d_dk.getKeys(p->qdomain);
for(const auto& value: keyset) {
- rr.qtype=QType::DNSKEY;
- rr.ttl=sd.default_ttl;
- rr.qname=p->qdomain;
- rr.content=value.first.getDNSKEY().getZoneRepresentation();
+ rr.dr.d_type=QType::DNSKEY;
+ rr.dr.d_ttl=sd.default_ttl;
+ rr.dr.d_name=p->qdomain;
+ rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
r->addRecord(rr);
haveOne=true;
B.lookup(QType(QType::DNSKEY), p->qdomain, p, sd.domain_id);
while(B.get(rr)) {
- rr.ttl=sd.default_ttl;
+ rr.dr.d_ttl=sd.default_ttl;
r->addRecord(rr);
haveOne=true;
}
vector<string> digestAlgos;
stringtok(digestAlgos, publishCDS, ", ");
- DNSResourceRecord rr;
- rr.qtype=QType::CDS;
- rr.ttl=sd.default_ttl;
- rr.qname=p->qdomain;
+ DNSZoneRecord rr;
+ rr.dr.d_type=QType::CDS;
+ rr.dr.d_ttl=sd.default_ttl;
+ rr.dr.d_name=p->qdomain;
rr.auth=true;
bool haveOne=false;
for(auto const &value : keyset) {
for(auto const &digestAlgo : digestAlgos){
- rr.content=makeDSFromDNSKey(p->qdomain, value.first.getDNSKEY(), std::stoi(digestAlgo)).getZoneRepresentation();
+ rr.dr.d_content=std::make_shared<DSRecordContent>(makeDSFromDNSKey(p->qdomain, value.first.getDNSKEY(), std::stoi(digestAlgo)));
r->addRecord(rr);
haveOne=true;
}
B.lookup(QType(QType::CDS), p->qdomain, p, sd.domain_id);
while(B.get(rr)) {
- rr.ttl=sd.default_ttl;
+ rr.dr.d_ttl=sd.default_ttl;
r->addRecord(rr);
haveOne=true;
}
/** This adds NSEC3PARAM records. Returns true if one was added */
bool PacketHandler::addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd)
{
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
NSEC3PARAMRecordContent ns3prc;
if(d_dk.getNSEC3PARAM(p->qdomain, &ns3prc)) {
- rr.qtype=QType::NSEC3PARAM;
- rr.ttl=sd.default_ttl;
- rr.qname=p->qdomain;
+ rr.dr.d_type=QType::NSEC3PARAM;
+ rr.dr.d_ttl=sd.default_ttl;
+ rr.dr.d_name=p->qdomain;
ns3prc.d_flags = 0; // the NSEC3PARAM 'flag' is defined to always be zero in RFC5155.
- rr.content=ns3prc.getZoneRepresentation();
+ rr.dr.d_content=std::make_shared<NSEC3PARAMRecordContent>(ns3prc);
rr.auth = true;
r->addRecord(rr);
return true;
// This is our chaos class requests handler. Return 1 if content was added, 0 if it wasn't
int PacketHandler::doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target)
{
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
if(p->qtype.getCode()==QType::TXT) {
static const DNSName versionbind("version.bind."), versionpdns("version.pdns."), idserver("id.server.");
if (target==versionbind || target==versionpdns) {
// modes: full, powerdns only, anonymous or custom
const static string mode=::arg()["version-string"];
-
+ string content;
if(mode.empty() || mode=="full")
- rr.content=fullVersionString();
+ content=fullVersionString();
else if(mode=="powerdns")
- rr.content="Served by PowerDNS - https://www.powerdns.com/";
+ content="Served by PowerDNS - https://www.powerdns.com/";
else if(mode=="anonymous") {
r->setRcode(RCode::ServFail);
return 0;
}
else
- rr.content=mode;
+ content=mode;
+ rr.dr.d_content = shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::TXT, 1, content));
}
else if (target==idserver) {
// modes: disabled, hostname or custom
r->setRcode(RCode::Refused);
return 0;
}
- rr.content=id;
+ rr.dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::TXT, 1, id));
}
else {
r->setRcode(RCode::Refused);
return 0;
}
- rr.ttl=5;
- rr.qname=target;
- rr.qtype=QType::TXT;
- rr.qclass=QClass::CHAOS;
+ rr.dr.d_ttl=5;
+ rr.dr.d_name=target;
+ rr.dr.d_type=QType::TXT;
+ rr.dr.d_class=QClass::CHAOS;
r->addRecord(rr);
return 1;
}
return 0;
}
-vector<DNSResourceRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target)
+vector<DNSZoneRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target)
{
- vector<DNSResourceRecord> ret;
- DNSResourceRecord rr;
+ vector<DNSZoneRecord> ret;
+ DNSZoneRecord rr;
DNSName subdomain(target);
do {
if(subdomain == sd.qname) // stop at SOA
return ret;
}
-vector<DNSResourceRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target)
+vector<DNSZoneRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target)
{
- vector<DNSResourceRecord> ret;
- DNSResourceRecord rr;
+ vector<DNSZoneRecord> ret;
+ DNSZoneRecord rr;
DNSName prefix;
DNSName subdomain(target);
do {
B.lookup(QType(QType::DNAME), subdomain, p, sd.domain_id);
while(B.get(rr)) {
ret.push_back(rr); // put in the original
- rr.qtype = QType::CNAME;
- rr.qname = prefix + rr.qname;
- rr.content = (prefix + DNSName(rr.content)).toStringNoDot();
+ rr.dr.d_type = QType::CNAME;
+ rr.dr.d_name = prefix + rr.dr.d_name;
+ rr.dr.d_content = std::make_shared<CNAMERecordContent>(CNAMERecordContent(prefix + getRR<DNAMERecordContent>(rr.dr)->d_content));
rr.auth = 0; // don't sign CNAME
- target= DNSName(rr.content);
+ target= getRR<CNAMERecordContent>(rr.dr)->getTarget();
ret.push_back(rr);
}
if(!ret.empty())
// Return best matching wildcard or next closer name
-bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSResourceRecord>* ret)
+bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* ret)
{
ret->clear();
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
DNSName subdomain(target);
bool haveSomething=false;
B.lookup(QType(QType::ANY), g_wildcarddnsname+subdomain, p, sd.domain_id);
}
while(B.get(rr)) {
- if(rr.qtype == p->qtype || rr.qtype.getCode() == QType::CNAME || (p->qtype.getCode() == QType::ANY && rr.qtype.getCode() != QType::RRSIG))
+ if(rr.dr.d_type == p->qtype.getCode() || rr.dr.d_type == QType::CNAME || (p->qtype.getCode() == QType::ANY && rr.dr.d_type != QType::RRSIG))
ret->push_back(rr);
wildcard=g_wildcarddnsname+subdomain;
haveSomething=true;
/** dangling is declared true if we were unable to resolve everything */
int PacketHandler::doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& soadata, bool retargeted)
{
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
SOAData sd;
sd.db=0;
if(p->qtype.getCode()!=QType::AXFR) { // this packet needs additional processing
- vector<DNSResourceRecord *> arrs=r->getAPRecords();
+ vector<DNSZoneRecord *> arrs=r->getAPRecords();
if(arrs.empty())
return 1;
DLOG(L<<Logger::Warning<<"This packet needs additional processing!"<<endl);
- vector<DNSResourceRecord> crrs;
+ vector<DNSZoneRecord> crrs;
- for(vector<DNSResourceRecord *>::const_iterator i=arrs.begin(); i!=arrs.end(); ++i)
+ for(vector<DNSZoneRecord *>::const_iterator i=arrs.begin(); i!=arrs.end(); ++i)
crrs.push_back(**i);
// 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.countLabels() && 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
+ for(auto i=crrs.cbegin(); i!=crrs.cend(); ++i) {
+ if(r->d.aa && i->dr.d_name.countLabels() && i->dr.d_type==QType::NS && !B.getSOA(i->dr.d_name,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
}
- string content = stripDot(i->content);
- if(i->qtype == QType::MX || i->qtype == QType::SRV) {
- string::size_type pos = content.find_first_not_of("0123456789");
- if(pos != string::npos)
- boost::erase_head(content, pos);
- trim_left(content);
- }
+ DNSName lookup;
+
+ if(i->dr.d_type == QType::MX)
+ lookup = getRR<MXRecordContent>(i->dr)->d_mxname;
+ else if(i->dr.d_type == QType::SRV)
+ lookup = getRR<SRVRecordContent>(i->dr)->d_target;
+
+ B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), lookup, p);
- if (i->qtype.getCode()==QType::SRV) {
- vector<string>parts;
- stringtok(parts, content);
- if (parts.size() >= 3) {
- B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), DNSName(parts[2]), p);
- }
- else
- continue;
- }
- else {
- B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), DNSName(content), p);
- }
while(B.get(rr)) {
- if(rr.qtype.getCode() != QType::A && rr.qtype.getCode()!=QType::AAAA)
+ if(rr.dr.d_type != QType::A && rr.dr.d_type!=QType::AAAA)
continue;
if(rr.domain_id!=i->domain_id && ::arg()["out-of-zone-additional-processing"]=="no") {
- DLOG(L<<Logger::Warning<<"Not including out-of-zone additional processing of "<<i->qname<<" ("<<rr.qname<<")"<<endl);
+ DLOG(L<<Logger::Warning<<"Not including out-of-zone additional processing of "<<i->dr.d_name<<" ("<<rr.dr.d_name<<")"<<endl);
continue; // not adding out-of-zone additional data
}
- if(rr.auth && !rr.qname.isPartOf(soadata.qname)) // don't sign out of zone data using the main key
+ if(rr.auth && !rr.dr.d_name.isPartOf(soadata.qname)) // don't sign out of zone data using the main key
rr.auth=false;
- rr.d_place=DNSResourceRecord::ADDITIONAL;
+ rr.dr.d_place=DNSResourceRecord::ADDITIONAL;
r->addRecord(rr);
}
}
nrc.d_set.insert(QType::CDS);
}
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
B.lookup(QType(QType::ANY), name, NULL, sd.domain_id);
while(B.get(rr)) {
- if(rr.qtype.getCode() == QType::NS || rr.auth)
- nrc.d_set.insert(rr.qtype.getCode());
+ if(rr.dr.d_type == QType::NS || rr.auth)
+ nrc.d_set.insert(rr.dr.d_type);
}
- rr.qname = name;
- rr.ttl = sd.default_ttl;
- rr.qtype = QType::NSEC;
- rr.content = nrc.getZoneRepresentation();
- rr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
+ rr.dr.d_name = name;
+ rr.dr.d_ttl = sd.default_ttl;
+ rr.dr.d_type = QType::NSEC;
+ rr.dr.d_content = std::make_shared<NSECRecordContent>(nrc);
+ rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
rr.auth = true;
r->addRecord(rr);
n3rc.d_salt = ns3prc.d_salt;
n3rc.d_nexthash = nexthash;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
if(!name.empty()) {
if (sd.qname == name) {
B.lookup(QType(QType::ANY), name, NULL, sd.domain_id);
while(B.get(rr)) {
- if(rr.qtype.getCode() && (rr.qtype.getCode() == QType::NS || rr.auth)) // skip empty non-terminals
- n3rc.d_set.insert(rr.qtype.getCode());
+ if(rr.dr.d_type && (rr.dr.d_type == QType::NS || rr.auth)) // skip empty non-terminals
+ n3rc.d_set.insert(rr.dr.d_type);
}
}
if (n3rc.d_set.size() && !(n3rc.d_set.size() == 1 && n3rc.d_set.count(QType::NS)))
n3rc.d_set.insert(QType::RRSIG);
- rr.qname = DNSName(toBase32Hex(namehash))+sd.qname;
- rr.ttl = sd.default_ttl;
- rr.qtype=QType::NSEC3;
- rr.content=n3rc.getZoneRepresentation();
- rr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
+ rr.dr.d_name = DNSName(toBase32Hex(namehash))+sd.qname;
+ rr.dr.d_ttl = sd.default_ttl;
+ rr.dr.d_type=QType::NSEC3;
+ rr.dr.d_content=std::make_shared<NSEC3RecordContent>(n3rc);
+ rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
rr.auth = true;
r->addRecord(rr);
bool doNextcloser = false;
string before, after, hashed;
DNSName unhashed, closest;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
if (mode == 2 || mode == 3 || mode == 4) {
closest=wildcard;
DLOG(L<<"No matching NSEC3, do closest (provable) encloser"<<endl);
bool doBreak = false;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
while( closest.chopOff() && (closest != sd.qname)) { // stop at SOA
B.lookup(QType(QType::ANY), closest, p, sd.domain_id);
while(B.get(rr))
// check if the returned records are NS records
bool haveNS=false;
for(const auto& ns: nsset) {
- if(ns.qtype.getCode()==QType::NS)
+ if(ns.qtype==QType::NS)
haveNS=true;
}
if(!B.superMasterBackend(remote, p->qdomain, nsset, &nameserver, &account, &db)) {
L<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<remote<<". Remote nameservers: "<<endl;
for(const auto& rr: nsset) {
- if(rr.qtype.getCode()==QType::NS)
+ if(rr.qtype==QType::NS)
L<<Logger::Error<<rr.content<<endl;
}
return RCode::Refused;
return ret;
}
+
void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd)
{
- DNSResourceRecord rr;
- rr.qname=sd.qname;
- rr.qtype=QType::SOA;
- rr.content=serializeSOAData(sd);
- rr.ttl=min(sd.ttl, sd.default_ttl);
+ DNSZoneRecord rr;
+ rr.dr.d_name=sd.qname;
+ rr.dr.d_type=QType::SOA;
+
+ rr.dr.d_content=makeSOAContent(sd);
+ rr.dr.d_ttl=min(sd.ttl, sd.default_ttl);
rr.signttl=sd.ttl;
rr.domain_id=sd.domain_id;
- rr.d_place=DNSResourceRecord::AUTHORITY;
+ rr.dr.d_place=DNSResourceRecord::AUTHORITY;
rr.auth = 1;
rr.scopeMask = sd.scopeMask;
r->addRecord(rr);
void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd, int mode)
{
- DNSResourceRecord rr;
- rr.qname=sd.qname;
- rr.qtype=QType::SOA;
- rr.content=serializeSOAData(sd);
- rr.ttl=sd.ttl;
- rr.ttl=min(sd.ttl, sd.default_ttl);
+ DNSZoneRecord rr;
+ rr.dr.d_name=sd.qname;
+ rr.dr.d_type=QType::SOA;
+ rr.dr.d_content=makeSOAContent(sd);
+ rr.dr.d_ttl=sd.ttl;
+ rr.dr.d_ttl=min(sd.ttl, sd.default_ttl);
rr.signttl=sd.ttl;
rr.domain_id=sd.domain_id;
- rr.d_place=DNSResourceRecord::AUTHORITY;
+ rr.dr.d_place=DNSResourceRecord::AUTHORITY;
rr.auth = 1;
r->addRecord(rr);
{
//cerr<<"Trying to find a DS for '"<<dsname<<"', domain_id = "<<sd.domain_id<<endl;
B.lookup(QType(QType::DS), dsname, p, sd.domain_id);
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
bool gotOne=false;
while(B.get(rr)) {
gotOne=true;
- rr.d_place = DNSResourceRecord::AUTHORITY;
+ rr.dr.d_place = DNSResourceRecord::AUTHORITY;
r->addRecord(rr);
}
return gotOne;
bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target, bool retargeted)
{
- vector<DNSResourceRecord> rrset = getBestReferralNS(p, sd, target);
+ vector<DNSZoneRecord> rrset = getBestReferralNS(p, sd, target);
if(rrset.empty())
return false;
DLOG(L<<"The best NS is: "<<rrset.begin()->qname<<endl);
for(auto& rr: rrset) {
DLOG(L<<"\tadding '"<<rr.content<<"'"<<endl);
- rr.d_place=DNSResourceRecord::AUTHORITY;
+ rr.dr.d_place=DNSResourceRecord::AUTHORITY;
r->addRecord(rr);
}
if(!retargeted)
r->setA(false);
- if(d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->qname))
- addNSECX(p, r, rrset.begin()->qname, DNSName(), sd.qname, 1);
+ if(d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->dr.d_name))
+ addNSECX(p, r, rrset.begin()->dr.d_name, DNSName(), sd.qname, 1);
return true;
}
if(!d_doDNAME)
return false;
DLOG(L<<Logger::Warning<<"Let's try DNAME.."<<endl);
- vector<DNSResourceRecord> rrset = getBestDNAMESynth(p, sd, target);
+ vector<DNSZoneRecord> rrset = getBestDNAMESynth(p, sd, target);
if(!rrset.empty()) {
for(auto& rr: rrset) {
- rr.d_place = DNSResourceRecord::ANSWER;
+ rr.dr.d_place = DNSResourceRecord::ANSWER;
r->addRecord(rr);
}
return true;
retargeted = nodata = false;
DNSName bestmatch;
- vector<DNSResourceRecord> rrset;
+ vector<DNSZoneRecord> rrset;
if(!getBestWildcard(p, sd, target, wildcard, &rrset))
return false;
else {
DLOG(L<<"The best wildcard match: "<<rrset.begin()->qname<<endl);
for(auto& rr: rrset) {
- rr.wildcardname = rr.qname;
- rr.qname=bestmatch=target;
+ rr.wildcardname = rr.dr.d_name;
+ rr.dr.d_name=bestmatch=target;
- if(rr.qtype.getCode() == QType::CNAME) {
+ if(rr.dr.d_type == QType::CNAME) {
retargeted=true;
- target=DNSName(rr.content);
+ target=getRR<CNAMERecordContent>(rr.dr)->getTarget();
}
DLOG(L<<"\tadding '"<<rr.content<<"'"<<endl);
- rr.d_place=DNSResourceRecord::ANSWER;
+ rr.dr.d_place=DNSResourceRecord::ANSWER;
r->addRecord(rr);
}
}
DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
{
*shouldRecurse=false;
- DNSResourceRecord rr;
+ DNSZoneRecord rr;
SOAData sd;
// string subdomain="";
int retargetcount=0;
set<DNSName> authSet;
- vector<DNSResourceRecord> rrset;
+ vector<DNSZoneRecord> rrset;
bool weDone=0, weRedirected=0, weHaveUnauth=0;
DNSName haveAlias;
}
if(p->qtype.getCode() == QType::SOA && sd.qname==p->qdomain) {
- rr.qname=sd.qname;
- rr.qtype=QType::SOA;
- rr.content=serializeSOAData(sd);
- rr.ttl=sd.ttl;
+ rr.dr.d_name=sd.qname;
+ rr.dr.d_type=QType::SOA;
+ rr.dr.d_content=makeSOAContent(sd);
+ rr.dr.d_ttl=sd.ttl;
rr.domain_id=sd.domain_id;
- rr.d_place=DNSResourceRecord::ANSWER;
+ rr.dr.d_place=DNSResourceRecord::ANSWER;
rr.auth = true;
r->addRecord(rr);
goto sendit;
while(B.get(rr)) {
//cerr<<"got content: ["<<rr.content<<"]"<<endl;
- if (p->qtype.getCode() == QType::ANY && !p->d_dnssecOk && (rr.qtype.getCode() == QType:: DNSKEY || rr.qtype.getCode() == QType::NSEC3PARAM))
+ if (p->qtype.getCode() == QType::ANY && !p->d_dnssecOk && (rr.dr.d_type == QType:: DNSKEY || rr.dr.d_type == QType::NSEC3PARAM))
continue; // Don't send dnssec info to non validating resolvers.
- if (rr.qtype.getCode() == QType::RRSIG) // RRSIGS are added later any way.
+ if (rr.dr.d_type == QType::RRSIG) // RRSIGS are added later any way.
continue; // TODO: this actually means addRRSig should check if the RRSig is already there
- // cerr<<"Auth: "<<rr.auth<<", "<<(rr.qtype == p->qtype)<<", "<<rr.qtype.getName()<<endl;
- if((p->qtype.getCode() == QType::ANY || rr.qtype == p->qtype) && rr.auth)
+ // cerr<<"Auth: "<<rr.auth<<", "<<(rr.dr.d_type == p->qtype)<<", "<<rr.dr.d_type.getName()<<endl;
+ if((p->qtype.getCode() == QType::ANY || rr.dr.d_type == p->qtype.getCode()) && rr.auth)
weDone=1;
// the line below fakes 'unauth NS' for delegations for non-DNSSEC backends.
- if((rr.qtype == p->qtype && !rr.auth) || (rr.qtype.getCode() == QType::NS && (!rr.auth || !(sd.qname==rr.qname))))
+ if((rr.dr.d_type == p->qtype.getCode() && !rr.auth) || (rr.dr.d_type == QType::NS && (!rr.auth || !(sd.qname==rr.dr.d_name))))
weHaveUnauth=1;
- if(rr.qtype.getCode() == QType::CNAME && p->qtype.getCode() != QType::CNAME)
+ if(rr.dr.d_type == QType::CNAME && p->qtype.getCode() != QType::CNAME)
weRedirected=1;
- if(DP && rr.qtype.getCode() == QType::ALIAS && (p->qtype.getCode() == QType::A || p->qtype.getCode() == QType::AAAA || p->qtype.getCode() == QType::ANY)) {
- haveAlias=DNSName(rr.content);
+ if(DP && rr.dr.d_type == QType::ALIAS && (p->qtype.getCode() == QType::A || p->qtype.getCode() == QType::AAAA || p->qtype.getCode() == QType::ANY)) {
+ haveAlias=getRR<ALIASRecordContent>(rr.dr)->d_content;
}
// Filter out all SOA's and add them in later
- if(rr.qtype.getCode() == QType::SOA)
+ if(rr.dr.d_type == QType::SOA)
continue;
rrset.push_back(rr);
/* Add in SOA if required */
if(target==sd.qname) {
- rr.qtype = QType::SOA;
- rr.content = serializeSOAData(sd);
- rr.qname = sd.qname;
- rr.ttl = sd.ttl;
+ rr.dr.d_type = QType::SOA;
+ rr.dr.d_content = makeSOAContent(sd);
+ rr.dr.d_name = sd.qname;
+ rr.dr.d_ttl = sd.ttl;
rr.domain_id = sd.domain_id;
rr.auth = true;
rrset.push_back(rr);
if(weRedirected) {
for(auto& rr: rrset) {
- if(rr.qtype.getCode() == QType::CNAME) {
+ if(rr.dr.d_type == QType::CNAME) {
r->addRecord(rr);
- target = DNSName(rr.content);
+ target = getRR<CNAMERecordContent>(rr.dr)->getTarget();
retargetcount++;
goto retargeted;
}
else if(weDone) {
bool haveRecords = false;
for(const auto& rr: rrset) {
- if((p->qtype.getCode() == QType::ANY || rr.qtype == p->qtype) && rr.qtype.getCode() && rr.qtype != QType::ALIAS && rr.auth) {
+ if((p->qtype.getCode() == QType::ANY || rr.dr.d_type == p->qtype.getCode()) && rr.dr.d_type && rr.dr.d_type != QType::ALIAS && rr.auth) {
r->addRecord(rr);
haveRecords = true;
}
completeANYRecords(p, r, sd, target);
}
else
- makeNOError(p, r, rr.qname, DNSName(), sd, 0);
+ makeNOError(p, r, rr.dr.d_name, DNSName(), sd, 0);
goto sendit;
}
if(tryReferral(p, r, sd, target, retargetcount))
goto sendit;
// check whether this could be fixed easily
- // if (*(rr.qname.rbegin()) == '.') {
+ // if (*(rr.dr.d_name.rbegin()) == '.') {
// L<<Logger::Error<<"Should not get here ("<<p->qdomain<<"|"<<p->qtype.getCode()<<"): you have a trailing dot, this could be the problem (or run pdnsutil rectify-zone " <<sd.qname<<")"<<endl;
// } else {
L<<Logger::Error<<"Should not get here ("<<p->qdomain<<"|"<<p->qtype.getCode()<<"): please run pdnsutil rectify-zone "<<sd.qname<<endl;
void makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd);
void makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd, int mode);
- vector<DNSResourceRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target);
- vector<DNSResourceRecord> getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target);
+ vector<DNSZoneRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target);
+ vector<DNSZoneRecord> getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target);
bool tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target);
bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target, bool retargeted);
- bool getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSResourceRecord>* ret);
+ bool getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* ret);
bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata);
bool addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DNSName& dsname);
void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target);
DNSSECKeeper d_dk; // B is shared with DNSSECKeeper
};
bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, bool decrement, DNSName& unhashed, string& before, string& after, int mode=0);
+std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& sd);
#endif /* PACKETHANDLER */
sd.db->lookup(QType(QType::SOA), zone);
vector<DNSResourceRecord> rrs;
DNSResourceRecord rr;
+ DNSZoneRecord szr;
while (sd.db->get(rr)) {
- if (rr.qtype.getCode() == QType::SOA)
+ if (rr.qtype.getCode() == QType::SOA) {
rrs.push_back(rr);
+ szr.dr=DNSRecord(rr) ;
+ }
}
if (rrs.size() > 1) {
}
}
else {
- sd.serial = calculateEditSOA(sd, soaEditKind) + 1;
+ sd.serial = calculateEditSOA(szr, soaEditKind) + 1;
}
rrs[0].content = serializeSOAData(sd);
ChunkedSigningPipe csp(DNSName(zone), 1, remote, cores);
- vector<DNSResourceRecord> signatures;
+ vector<DNSZoneRecord> signatures;
uint32_t rnd;
unsigned char* octets = (unsigned char*)&rnd;
char tmp[25];
snprintf(tmp, sizeof(tmp), "r-%u", rnd);
rr.qname=DNSName(tmp)+zone;
-
- if(csp.submit(rr))
+ DNSZoneRecord dzr;
+ dzr.dr=DNSRecord(rr);
+ if(csp.submit(dzr))
while(signatures = csp.getChunk(), !signatures.empty())
;
}
#include "namespaces.hh"
#include "statbag.hh"
#include "stubresolver.hh"
+#include "dnsrecords.hh"
#include <stdint.h>
#ifndef PACKAGEVERSION
#define PACKAGEVERSION getPDNSVersion()
boost::replace_all(query, "+", "_");
boost::replace_all(query, "~", "_");
- vector<DNSResourceRecord> ret;
+ vector<DNSZoneRecord> ret;
- int res=stubDoResolve(query, QType::TXT, ret);
+ int res=stubDoResolve(DNSName(query), QType::TXT, ret);
int security_status=0;
if(!res && !ret.empty()) {
- string content=ret.begin()->content;
- if(!content.empty() && content[0]=='"' && content[content.size()-1]=='"') {
- content=content.substr(1, content.length()-2);
- }
+ string content=getRR<TXTRecordContent>(ret.begin()->dr)->d_text;
pair<string, string> split = splitField(content, ' ');
bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp)
{
- vector<DNSResourceRecord>& rrs = dp->getRRS();
- for(DNSResourceRecord& rr : rrs) {
- if(rr.qtype.getCode() == QType::SOA && rr.qname == qname) {
+ for(auto& rr : dp->getRRS()) {
+ if(rr.dr.d_type == QType::SOA && rr.dr.d_name == qname) {
string kind;
dk.getSoaEdit(qname, kind);
return editSOARecord(rr, kind, qname);
return false;
}
-bool editSOARecord(DNSResourceRecord& rr, const string& kind, const DNSName& qname) {
+bool editSOARecord(DNSZoneRecord& rr, const string& kind, const DNSName& qname) {
if(kind.empty())
return false;
+ auto src = getRR<SOARecordContent>(rr.dr);
+ src->d_st.serial=calculateEditSOA(rr, kind);
- SOAData sd;
- sd.qname = qname;
- fillSOAData(rr.content, sd);
- sd.serial = calculateEditSOA(sd, kind);
- rr.content = serializeSOAData(sd);
return true;
}
-uint32_t calculateEditSOA(SOAData sd, const string& kind) {
+uint32_t calculateEditSOA(const DNSZoneRecord& rr, const string& kind)
+{
+ auto src = getRR<SOARecordContent>(rr.dr);
if(pdns_iequals(kind,"INCEPTION")) {
L<<Logger::Warning<<"Deprecation warning: The 'INCEPTION' soa-edit value will be removed in PowerDNS 4.1"<<endl;
time_t inception = getStartOfWeek();
uint32_t inception_serial = localtime_format_YYYYMMDDSS(inception, 1);
uint32_t dont_increment_after = localtime_format_YYYYMMDDSS(inception + 2*86400, 99);
- if(sd.serial < inception_serial - 1) { /* less than <inceptionday>00 */
+ if(src->d_st.serial < inception_serial - 1) { /* less than <inceptionday>00 */
return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
- } else if(sd.serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
- return (sd.serial + 2); /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so increment sd.serial by two */
+ } else if(src->d_st.serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
+ return (src->d_st.serial + 2); /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so increment sd.serial by two */
}
}
else if(pdns_iequals(kind,"INCEPTION-WEEK")) {
}
else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
time_t inception = getStartOfWeek();
- return (sd.serial + (inception / (7*86400)));
+ return (src->d_st.serial + (inception / (7*86400)));
}
else if(pdns_iequals(kind,"EPOCH")) {
L<<Logger::Warning<<"Deprecation warning: The 'EPOCH' soa-edit value will be removed in PowerDNS 4.1"<<endl;
}
else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
uint32_t inception = getStartOfWeek();
- if (sd.serial < inception)
+ if (src->d_st.serial < inception)
return inception;
} else if(!kind.empty()) {
- L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<sd.qname.toStringNoDot()<<" is unknown."<<endl;
+ L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<rr.dr.d_name<<" is unknown."<<endl;
}
- return sd.serial;
+ return src->d_st.serial;
+}
+
+uint32_t calculateEditSOA(const SOAData& sd, const string& kind)
+{
+ DNSZoneRecord dzr;
+ dzr.dr.d_name=sd.qname;
+ struct soatimes st;
+ st.serial = sd.serial;
+ dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
+ return calculateEditSOA(dzr, kind);
}
// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
-uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) {
+uint32_t calculateIncreaseSOA(DNSZoneRecord& dzr, const string& increaseKind, const string& editKind) {
+ auto src = getRR<SOARecordContent>(dzr.dr);
// These only work when SOA-EDIT is set, otherwise fall back to default.
if (!editKind.empty()) {
if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
- uint32_t new_serial = calculateEditSOA(sd, editKind);
- if (new_serial <= sd.serial) {
- new_serial = sd.serial + 1;
+ uint32_t new_serial = calculateEditSOA(dzr, editKind);
+ if (new_serial <= src->d_st.serial) {
+ new_serial = src->d_st.serial + 1;
}
return new_serial;
}
else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
- return calculateEditSOA(sd, editKind);
+ return calculateEditSOA(dzr, editKind);
}
}
if (pdns_iequals(increaseKind, "INCREASE")) {
- return sd.serial + 1;
+ return src->d_st.serial + 1;
}
else if (pdns_iequals(increaseKind, "EPOCH")) {
return time(0);
boost::format fmt("%04d%02d%02d%02d");
string newdate = (fmt % (tm.tm_year + 1900) % (tm.tm_mon + 1) % tm.tm_mday % 1).str();
uint32_t new_serial = pdns_stou(newdate);
- if (new_serial <= sd.serial) {
- new_serial = sd.serial + 1;
+ if (new_serial <= src->d_st.serial) {
+ new_serial = src->d_st.serial + 1;
}
return new_serial;
}
+// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
+uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) {
+ DNSZoneRecord dzr;
+ dzr.dr.d_name=sd.qname;
+ struct soatimes st;
+ st.serial = sd.serial;
+ dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
+ return calculateIncreaseSOA(dzr, increaseKind, editKind);
+}
+
+
+
bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
if (increaseKind.empty())
return false;
d_maxchunkrecords(100), d_tids(d_numworkers), d_mustSign(mustSign), d_final(false)
{
d_rrsetToSign = new rrset_t;
- d_chunks.push_back(vector<DNSResourceRecord>()); // load an empty chunk
+ d_chunks.push_back(vector<DNSZoneRecord>()); // load an empty chunk
if(!d_mustSign)
return;
namespace {
bool
-dedupLessThan(const DNSResourceRecord& a, const DNSResourceRecord &b)
+dedupLessThan(const DNSZoneRecord& a, const DNSZoneRecord &b)
{
- return (tie(a.content, a.ttl) < tie(b.content, b.ttl));
+ return make_tuple(a.dr.d_content->getZoneRepresentation(), a.dr.d_ttl) < make_tuple(b.dr.d_content->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW
}
-bool dedupEqual(const DNSResourceRecord& a, const DNSResourceRecord &b)
+bool dedupEqual(const DNSZoneRecord& a, const DNSZoneRecord &b)
{
- return(tie(a.content, a.ttl) == tie(b.content, b.ttl));
+ return make_tuple(a.dr.d_content->getZoneRepresentation(), a.dr.d_ttl) == make_tuple(b.dr.d_content->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW
}
}
d_rrsetToSign->erase(unique(d_rrsetToSign->begin(), d_rrsetToSign->end(), dedupEqual), d_rrsetToSign->end());
}
-bool ChunkedSigningPipe::submit(const DNSResourceRecord& rr)
+bool ChunkedSigningPipe::submit(const DNSZoneRecord& rr)
{
++d_submitted;
// check if we have a full RRSET to sign
- if(!d_rrsetToSign->empty() && (d_rrsetToSign->begin()->qtype.getCode() != rr.qtype.getCode() || d_rrsetToSign->begin()->qname != rr.qname))
+ if(!d_rrsetToSign->empty() && (d_rrsetToSign->begin()->dr.d_type != rr.dr.d_type || d_rrsetToSign->begin()->dr.d_name != rr.dr.d_name))
{
dedupRRSet();
sendRRSetToWorker();
unsigned int ChunkedSigningPipe::getReady()
{
unsigned int sum=0;
- for(const std::vector<DNSResourceRecord>& v : d_chunks) {
+ for(const auto& v : d_chunks) {
sum += v.size();
}
return sum;
d_rrsetToSign->clear();
}
-vector<DNSResourceRecord> ChunkedSigningPipe::getChunk(bool final)
+vector<DNSZoneRecord> ChunkedSigningPipe::getChunk(bool final)
{
if(final && !d_final) {
// this means we should keep on reading until d_outstanding == 0
}
if(d_final)
flushToSign(); // should help us wait
- vector<DNSResourceRecord> front=d_chunks.front();
+ vector<DNSZoneRecord> front=d_chunks.front();
d_chunks.pop_front();
if(d_chunks.empty())
- d_chunks.push_back(vector<DNSResourceRecord>());
+ d_chunks.push_back(vector<DNSZoneRecord>());
/* if(d_final && front.empty())
cerr<<"getChunk returning empty in final"<<endl; */
return front;
void writeLStringToSocket(int fd, const string& msg);
bool readLStringFromSocket(int fd, string& msg);
-/** input: DNSResourceRecords ordered in qname,qtype (we emit a signature chunk on a break)
- * output: "chunks" of those very same DNSResourceRecords, interleaved with signatures
+/** input: DNSZoneRecords ordered in qname,qtype (we emit a signature chunk on a break)
+ * output: "chunks" of those very same DNSZoneRecords, interleaved with signatures
*/
class ChunkedSigningPipe
{
public:
- typedef vector<DNSResourceRecord> rrset_t;
+ typedef vector<DNSZoneRecord> rrset_t;
typedef rrset_t chunk_t; // for now
ChunkedSigningPipe(const DNSName& signerName, bool mustSign, /* FIXME servers is unused? */ const string& servers=string(), unsigned int numWorkers=3);
~ChunkedSigningPipe();
- bool submit(const DNSResourceRecord& rr);
+ bool submit(const DNSZoneRecord& rr);
chunk_t getChunk(bool final=false);
std::atomic<unsigned long> d_signed;
int d_submitted;
rrset_t* d_rrsetToSign;
- std::deque< std::vector<DNSResourceRecord> > d_chunks;
+ std::deque< std::vector<DNSZoneRecord> > d_chunks;
DNSName d_signer;
chunk_t::size_type d_maxchunkrecords;
} else {
// NSEC
if (rr.auth || rr.qtype.getCode() == QType::NS) {
- ordername=toLower(labelReverse(makeRelative(rr.qname.toStringNoDot(), domain.toStringNoDot()))); // FIXME400
+ ordername=rr.qname.makeRelative(domain).makeLowerCase().labelReverse().toStringNoDot();
di.backend->feedRecord(rr, &ordername);
} else
di.backend->feedRecord(rr);
}
// s_stubresolvers contains the ComboAddresses that are used to resolve the
-int stubDoResolve(const string& qname, uint16_t qtype, vector<DNSResourceRecord>& ret)
+int stubDoResolve(const DNSName& qname, uint16_t qtype, vector<DNSZoneRecord>& ret)
{
vector<uint8_t> packet;
- DNSPacketWriter pw(packet, DNSName(qname), qtype);
+ DNSPacketWriter pw(packet, qname, qtype);
pw.getHeader()->id=dns_random(0xffff);
pw.getHeader()->rd=1;
if (s_stubresolvers.empty()) {
}
L<<Logger::Debug<<msg.substr(0, msg.length() - 2)<<endl;
- for(ComboAddress& dest : s_stubresolvers) {
+ for(const ComboAddress& dest : s_stubresolvers) {
Socket sock(dest.sin4.sin_family, SOCK_DGRAM);
sock.setNonBlocking();
- sock.sendTo(string(packet.begin(), packet.end()), dest);
+ sock.connect(dest);
+ sock.send(string(packet.begin(), packet.end()));
string reply;
waitForData(sock.getHandle(), 2, 0);
try {
retry:
- sock.recvFrom(reply, dest);
+ sock.read(reply); // this calls recv
if(reply.size() > sizeof(struct dnsheader)) {
struct dnsheader d;
memcpy(&d, reply.c_str(), sizeof(d));
for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {
if(i->first.d_place == 1 && i->first.d_type==qtype) {
- DNSResourceRecord rr;
- rr.qname = i->first.d_name;
- rr.qtype = QType(i->first.d_type);
- rr.content = i->first.d_content->getZoneRepresentation();
- rr.ttl=i->first.d_ttl;
- ret.push_back(rr);
+ DNSZoneRecord zrr;
+ zrr.dr = i->first;
+ zrr.auth=true;
+ ret.push_back(zrr);
}
}
L<<Logger::Debug<<"Question got answered by "<<dest.toString()<<endl;
return mdp.d_header.rcode;
}
return RCode::ServFail;
-}
\ No newline at end of file
+}
#include "dnsparser.hh"
void stubParseResolveConf();
-int stubDoResolve(const string& qname, uint16_t qtype, vector<DNSResourceRecord>& ret);
+int stubDoResolve(const DNSName& qname, uint16_t qtype, vector<DNSZoneRecord>& ret);
// SOA *must* go out first, our signing pipe might reorder
DLOG(L<<"Sending out SOA"<<endl);
DNSResourceRecord soa = makeDNSRRFromSOAData(sd);
- outpacket->addRecord(soa);
+ DNSZoneRecord dzrsoa;
+ dzrsoa.auth=true;
+ dzrsoa.dr=DNSRecord(soa);
+ outpacket->addRecord(dzrsoa);
editSOA(dk, sd.qname, outpacket.get());
if(securedZone) {
set<DNSName> authSet;
DNSSECKeeper::keyset_t keys = dk.getKeys(target);
- DNSResourceRecord rr;
+ DNSZoneRecord zrr;
- rr.qname = target;
- rr.ttl = sd.default_ttl;
- rr.auth = 1; // please sign!
+ zrr.dr.d_name = target;
+ zrr.dr.d_ttl = sd.default_ttl;
+ zrr.auth = 1; // please sign!
string publishCDNSKEY, publishCDS;
dk.getFromMeta(q->qdomain, "PUBLISH-CDNSKEY", publishCDNSKEY);
dk.getFromMeta(q->qdomain, "PUBLISH-CDS", publishCDS);
- vector<DNSResourceRecord> cds, cdnskey;
+ vector<DNSZoneRecord> cds, cdnskey;
DNSSECKeeper::keyset_t entryPoints = dk.getEntryPoints(q->qdomain);
set<uint32_t> entryPointIds;
for (auto const& value : entryPoints)
entryPointIds.insert(value.second.id);
for(const DNSSECKeeper::keyset_t::value_type& value : keys) {
- rr.qtype = QType(QType::DNSKEY);
- rr.content = value.first.getDNSKEY().getZoneRepresentation();
- string keyname = NSEC3Zone ? hashQNameWithSalt(ns3pr, rr.qname) : labelReverse(rr.qname.toString());
+ zrr.dr.d_type = QType::DNSKEY;
+ zrr.dr.d_content = std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
+ string keyname = NSEC3Zone ? hashQNameWithSalt(ns3pr, zrr.dr.d_name) : zrr.dr.d_name.labelReverse().toString();
NSECXEntry& ne = nsecxrepo[keyname];
- ne.d_set.insert(rr.qtype.getCode());
+ ne.d_set.insert(zrr.dr.d_type);
ne.d_ttl = sd.default_ttl;
- csp.submit(rr);
+ csp.submit(zrr);
// generate CDS and CDNSKEY records
if(entryPointIds.count(value.second.id) > 0){
if(publishCDNSKEY == "1") {
- rr.qtype=QType(QType::CDNSKEY);
- rr.content = value.first.getDNSKEY().getZoneRepresentation();
- cdnskey.push_back(rr);
+ zrr.dr.d_type=QType::CDNSKEY;
+ zrr.dr.d_content = std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
+ cdnskey.push_back(zrr);
}
if(!publishCDS.empty()){
- rr.qtype=QType(QType::CDS);
+ zrr.dr.d_type=QType::CDS;
vector<string> digestAlgos;
stringtok(digestAlgos, publishCDS, ", ");
for(auto const &digestAlgo : digestAlgos) {
- rr.content=makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo)).getZoneRepresentation();
- cds.push_back(rr);
+ zrr.dr.d_content=std::make_shared<DSRecordContent>(makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo)));
+ cds.push_back(zrr);
}
}
}
if(::arg().mustDo("direct-dnskey")) {
sd.db->lookup(QType(QType::DNSKEY), target, NULL, sd.domain_id);
- while(sd.db->get(rr)) {
- rr.ttl = sd.default_ttl;
- csp.submit(rr);
+ while(sd.db->get(zrr)) {
+ zrr.dr.d_ttl = sd.default_ttl;
+ csp.submit(zrr);
}
}
if(NSEC3Zone) { // now stuff in the NSEC3PARAM
flags = ns3pr.d_flags;
- rr.qtype = QType(QType::NSEC3PARAM);
+ zrr.dr.d_type = QType::NSEC3PARAM;
ns3pr.d_flags = 0;
- rr.content = ns3pr.getZoneRepresentation();
+ zrr.dr.d_content = std::make_shared<NSEC3PARAMRecordContent>(ns3pr);
ns3pr.d_flags = flags;
- string keyname = hashQNameWithSalt(ns3pr, rr.qname);
+ string keyname = hashQNameWithSalt(ns3pr, zrr.dr.d_name);
NSECXEntry& ne = nsecxrepo[keyname];
- ne.d_set.insert(rr.qtype.getCode());
- csp.submit(rr);
+ ne.d_set.insert(zrr.dr.d_type);
+ csp.submit(zrr);
}
// now start list zone
const bool rectify = !(presignedZone || ::arg().mustDo("disable-axfr-rectify"));
set<DNSName> qnames, nsset, terms;
- vector<DNSResourceRecord> rrs;
+ vector<DNSZoneRecord> zrrs;
// Add the CDNSKEY and CDS records we created earlier
- for (auto const &rr : cds)
- rrs.push_back(rr);
-
- for (auto const &rr : cdnskey)
- rrs.push_back(rr);
-
- while(sd.db->get(rr)) {
- if(rr.qname.isPartOf(target)) {
- if (rr.qtype.getCode() == QType::ALIAS && ::arg().mustDo("outgoing-axfr-expand-alias")) {
- vector<DNSResourceRecord> ips;
- int ret1 = stubDoResolve(rr.content, QType::A, ips);
- int ret2 = stubDoResolve(rr.content, QType::AAAA, ips);
+ for (auto const &zrr : cds)
+ zrrs.push_back(zrr);
+
+ for (auto const &zrr : cdnskey)
+ zrrs.push_back(zrr);
+
+ while(sd.db->get(zrr)) {
+ if(zrr.dr.d_name.isPartOf(target)) {
+ if (zrr.dr.d_type == QType::ALIAS && ::arg().mustDo("outgoing-axfr-expand-alias")) {
+ vector<DNSZoneRecord> ips;
+ int ret1 = stubDoResolve(getRR<ALIASRecordContent>(zrr.dr)->d_content, QType::A, ips);
+ int ret2 = stubDoResolve(getRR<ALIASRecordContent>(zrr.dr)->d_content, QType::AAAA, ips);
if(ret1 != RCode::NoError || ret2 != RCode::NoError) {
- L<<Logger::Error<<"Error resolving for ALIAS "<<rr.content<<", aborting AXFR"<<endl;
+ L<<Logger::Error<<"Error resolving for ALIAS "<<zrr.dr.d_content->getZoneRepresentation()<<", aborting AXFR"<<endl;
outpacket->setRcode(2); // 'SERVFAIL'
sendPacket(outpacket,outsock);
return 0;
}
for(const auto& ip: ips) {
- rr.qtype = ip.qtype;
- rr.content = ip.content;
- rrs.push_back(rr);
+ zrr.dr.d_type = ip.dr.d_type;
+ if(ip.dr.d_type == QType::A)
+ zrr.dr.d_content = ip.dr.d_content;
+ else
+ zrr.dr.d_content = ip.dr.d_content;
+ zrrs.push_back(zrr);
}
}
else {
- rrs.push_back(rr);
+ zrrs.push_back(zrr);
}
if (rectify) {
- if (rr.qtype.getCode()) {
- qnames.insert(rr.qname);
- if(rr.qtype.getCode() == QType::NS && rr.qname!=target)
- nsset.insert(rr.qname);
+ if (zrr.dr.d_type) {
+ qnames.insert(zrr.dr.d_name);
+ if(zrr.dr.d_type == QType::NS && zrr.dr.d_name!=target)
+ nsset.insert(zrr.dr.d_name);
} else {
// remove existing ents
continue;
}
}
} else {
- if (rr.qtype.getCode())
- L<<Logger::Warning<<"Zone '"<<target<<"' contains out-of-zone data '"<<rr.qname<<"|"<<rr.qtype.getName()<<"', ignoring"<<endl;
+ if (zrr.dr.d_type)
+ L<<Logger::Warning<<"Zone '"<<target<<"' contains out-of-zone data '"<<zrr.dr.d_name<<"|"<<DNSRecordContent::NumberToType(zrr.dr.d_type)<<"', ignoring"<<endl;
continue;
}
}
if(rectify) {
// set auth
- for(DNSResourceRecord &rr : rrs) {
- rr.auth=true;
- if (rr.qtype.getCode() != QType::NS || rr.qname!=target) {
- DNSName shorter(rr.qname);
+ for(DNSZoneRecord &zrr : zrrs) {
+ zrr.auth=true;
+ if (zrr.dr.d_type != QType::NS || zrr.dr.d_name!=target) {
+ DNSName shorter(zrr.dr.d_name);
do {
if (shorter==target) // apex is always auth
continue;
- if(nsset.count(shorter) && !(rr.qname==shorter && rr.qtype.getCode() == QType::DS))
- rr.auth=false;
+ if(nsset.count(shorter) && !(zrr.dr.d_name==shorter && zrr.dr.d_type == QType::DS))
+ zrr.auth=false;
} while(shorter.chopOff());
} else
continue;
// ents are only required for NSEC3 zones
uint32_t maxent = ::arg().asNum("max-ent-entries");
set<DNSName> nsec3set, nonterm;
- for (auto &rr: rrs) {
+ for (auto &zrr: zrrs) {
bool skip=false;
- DNSName shorter = rr.qname;
+ DNSName shorter = zrr.dr.d_name;
if (shorter != target && shorter.chopOff() && shorter != target) {
do {
if(nsset.count(shorter)) {
}
} while(shorter.chopOff() && shorter != target);
}
- shorter = rr.qname;
- if(!skip && (rr.qtype.getCode() != QType::NS || !ns3pr.d_flags)) {
+ shorter = zrr.dr.d_name;
+ if(!skip && (zrr.dr.d_type != QType::NS || !ns3pr.d_flags)) {
do {
if(!nsec3set.count(shorter)) {
nsec3set.insert(shorter);
}
}
- for(DNSResourceRecord &rr : rrs) {
- DNSName shorter(rr.qname);
+ for(DNSZoneRecord &zrr : zrrs) {
+ DNSName shorter(zrr.dr.d_name);
while(shorter != target && shorter.chopOff()) {
if(!qnames.count(shorter) && !nonterm.count(shorter) && nsec3set.count(shorter)) {
if(!(maxent)) {
}
for(const auto& nt : nonterm) {
- DNSResourceRecord rr;
- rr.qname=nt;
- rr.qtype="TYPE0";
- rr.auth=true;
- rrs.push_back(rr);
+ DNSZoneRecord zrr;
+ zrr.dr.d_name=nt;
+ zrr.dr.d_type=0; // was TYPE0
+ zrr.auth=true;
+ zrrs.push_back(zrr);
}
}
- DLOG(for(const auto &rr: rrs) cerr<<rr.qname<<"\t"<<rr.qtype.getName()<<"\t"<<rr.auth<<endl;);
+ DLOG(for(const auto &rr: rrs) cerr<<zrr.dr.d_name<<"\t"<<zrr.dr.d_type<<"\t"<<zrr.auth<<endl;);
}
DTime dt;
dt.set();
int records=0;
- for(DNSResourceRecord &rr : rrs) {
- if (rr.qtype.getCode() == QType::RRSIG) {
- RRSIGRecordContent rrc(rr.content);
- if(presignedZone && rrc.d_type == QType::NSEC3)
- ns3rrs.insert(fromBase32Hex(makeRelative(rr.qname.toStringNoDot(), target.toStringNoDot()))); // FIXME400
+ for(DNSZoneRecord &zrr : zrrs) {
+ if (zrr.dr.d_type == QType::RRSIG) {
+ if(presignedZone && zrr.dr.d_type == QType::NSEC3) {
+ DNSName relative=zrr.dr.d_name.makeRelative(target);
+ ns3rrs.insert(fromBase32Hex(relative.toStringNoDot()));
+ }
continue;
}
// only skip the DNSKEY, CDNSKEY and CDS if direct-dnskey is enabled, to avoid changing behaviour
// when it is not enabled.
- if(::arg().mustDo("direct-dnskey") && (rr.qtype.getCode() == QType::DNSKEY || rr.qtype.getCode() == QType::CDNSKEY || rr.qtype.getCode() == QType::CDS))
+ if(::arg().mustDo("direct-dnskey") && (zrr.dr.d_type == QType::DNSKEY || zrr.dr.d_type == QType::CDNSKEY || zrr.dr.d_type == QType::CDS))
continue;
records++;
- if(securedZone && (rr.auth || rr.qtype.getCode() == QType::NS)) {
- if (NSEC3Zone || rr.qtype.getCode()) {
- keyname = NSEC3Zone ? hashQNameWithSalt(ns3pr, rr.qname) : labelReverse(rr.qname.toString());
+ if(securedZone && (zrr.auth || zrr.dr.d_type == QType::NS)) {
+ if (NSEC3Zone || zrr.dr.d_type) {
+ keyname = NSEC3Zone ? hashQNameWithSalt(ns3pr, zrr.dr.d_name) : zrr.dr.d_name.labelReverse().toString();
NSECXEntry& ne = nsecxrepo[keyname];
ne.d_ttl = sd.default_ttl;
- ne.d_auth = (ne.d_auth || rr.auth || (NSEC3Zone && (!ns3pr.d_flags || (presignedZone && ns3pr.d_flags))));
- if (rr.qtype.getCode()) {
- ne.d_set.insert(rr.qtype.getCode());
+ ne.d_auth = (ne.d_auth || zrr.auth || (NSEC3Zone && (!ns3pr.d_flags || (presignedZone && ns3pr.d_flags))));
+ if (zrr.dr.d_type) {
+ ne.d_set.insert(zrr.dr.d_type);
}
}
}
- if (!rr.qtype.getCode())
+ if (!zrr.dr.d_type)
continue; // skip empty non-terminals
- if(rr.qtype.getCode() == QType::SOA)
+ if(zrr.dr.d_type == QType::SOA)
continue; // skip SOA - would indicate end of AXFR
- if(csp.submit(rr)) {
+ if(csp.submit(zrr)) {
for(;;) {
outpacket->getRRS() = csp.getChunk();
if(!outpacket->getRRS().empty()) {
inext = nsecxrepo.begin();
}
n3rc.d_nexthash = inext->first;
- rr.qname = DNSName(toBase32Hex(iter->first))+DNSName(sd.qname);
-
- rr.ttl = sd.default_ttl;
- rr.content = n3rc.getZoneRepresentation();
- rr.qtype = QType::NSEC3;
- rr.d_place = DNSResourceRecord::ANSWER;
- rr.auth=true;
- if(csp.submit(rr)) {
+ zrr.dr.d_name = DNSName(toBase32Hex(iter->first))+DNSName(sd.qname);
+
+ zrr.dr.d_ttl = sd.default_ttl;
+ zrr.dr.d_content = std::make_shared<NSEC3RecordContent>(n3rc);
+ zrr.dr.d_type = QType::NSEC3;
+ zrr.dr.d_place = DNSResourceRecord::ANSWER;
+ zrr.auth=true;
+ if(csp.submit(zrr)) {
for(;;) {
outpacket->getRRS() = csp.getChunk();
if(!outpacket->getRRS().empty()) {
nrc.d_set.insert(QType::RRSIG);
nrc.d_set.insert(QType::NSEC);
if(boost::next(iter) != nsecxrepo.end()) {
- nrc.d_next = DNSName(labelReverse(boost::next(iter)->first));
+ nrc.d_next = DNSName(boost::next(iter)->first).labelReverse();
}
else
- nrc.d_next=DNSName(labelReverse(nsecxrepo.begin()->first));
+ nrc.d_next=DNSName(nsecxrepo.begin()->first).labelReverse();
- rr.qname = DNSName(labelReverse(iter->first));
+ zrr.dr.d_name = DNSName(iter->first).labelReverse();
- rr.ttl = sd.default_ttl;
- rr.content = nrc.getZoneRepresentation();
- rr.qtype = QType::NSEC;
- rr.d_place = DNSResourceRecord::ANSWER;
- rr.auth=true;
- if(csp.submit(rr)) {
+ zrr.dr.d_ttl = sd.default_ttl;
+ zrr.dr.d_content = std::make_shared<NSECRecordContent>(nrc);
+ zrr.dr.d_type = QType::NSEC;
+ zrr.dr.d_place = DNSResourceRecord::ANSWER;
+ zrr.auth=true;
+ if(csp.submit(zrr)) {
for(;;) {
outpacket->getRRS() = csp.getChunk();
if(!outpacket->getRRS().empty()) {
DLOG(L<<"Done writing out records"<<endl);
/* and terminate with yet again the SOA record */
outpacket=getFreshAXFRPacket(q);
- outpacket->addRecord(soa);
+ outpacket->addRecord(dzrsoa);
editSOA(dk, sd.qname, outpacket.get());
if(!tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true);
// SOA *must* go out first, our signing pipe might reorder
DLOG(L<<"Sending out SOA"<<endl);
DNSResourceRecord soa = makeDNSRRFromSOAData(sd);
- outpacket->addRecord(soa);
+ DNSZoneRecord dzrsoa;
+ dzrsoa.dr=DNSRecord(soa);
+ dzrsoa.auth=true;
+
+ outpacket->addRecord(dzrsoa);
editSOA(dk, sd.qname, outpacket.get());
if(securedZone) {
set<DNSName> authSet;
tkey_out->d_keysize = tkey_out->d_key.size();
tkey_out->d_othersize = tkey_out->d_other.size();
- DNSRecord rec;
- rec.d_name = name;
- rec.d_ttl = 0;
- rec.d_type = QType::TKEY;
- rec.d_class = QClass::ANY;
- rec.d_content = tkey_out;
- rec.d_place = DNSResourceRecord::ANSWER;
+ DNSZoneRecord zrr;
- DNSResourceRecord rr(rec);
- rr.qclass = QClass::ANY;
- rr.qtype = QType::TKEY;
- rr.d_place = DNSResourceRecord::ANSWER;
- r->addRecord(rr);
+ zrr.dr.d_name = name;
+ zrr.dr.d_ttl = 0;
+ zrr.dr.d_type = QType::TKEY;
+ zrr.dr.d_class = QClass::ANY;
+ zrr.dr.d_content = tkey_out;
+ zrr.dr.d_place = DNSResourceRecord::ANSWER;
+ r->addRecord(zrr);
if (sign)
{
if(cstat == 1 && !d_answers.empty() && d_cache_ttl) {
DLOG(L<<Logger::Error<<"has pos cache entry: "<<choppedOff<<endl);
- fillSOAData(d_answers[0].content, *sd);
- sd->domain_id = d_answers[0].domain_id;
- sd->ttl = d_answers[0].ttl;
+ fillSOAData(d_answers[0], *sd);
+
sd->db = 0;
sd->qname = choppedOff;
goto found;
d_question.qname = sd->qname;
d_question.zoneId = -1;
- DNSResourceRecord rr;
- rr.qname = sd->qname;
- rr.qtype = QType::SOA;
- rr.content = serializeSOAData(*sd);
- rr.ttl = sd->ttl;
+ DNSZoneRecord rr;
+ rr.dr.d_name = sd->qname;
+ rr.dr.d_type = QType::SOA;
+
+ rr.dr.d_content = makeSOAContent(*sd);
+ rr.dr.d_ttl = sd->ttl;
rr.domain_id = sd->domain_id;
- vector<DNSResourceRecord> rrs;
- rrs.push_back(rr);
- addCache(d_question, rrs);
+
+ addCache(d_question, {rr});
}
}
return false;
}
else if(cstat==1 && !d_answers.empty()) {
- fillSOAData(d_answers[0].content,sd);
+ fillSOAData(d_answers[0],sd);
sd.domain_id=d_answers[0].domain_id;
- sd.ttl=d_answers[0].ttl;
+ sd.ttl=d_answers[0].dr.d_ttl;
sd.db=0;
return true;
}
for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
if((*i)->getSOA(domain, sd, p)) {
if( d_cache_ttl ) {
- DNSResourceRecord rr;
- rr.qname=domain;
- rr.qtype=QType::SOA;
- rr.content=serializeSOAData(sd);
- rr.ttl=sd.ttl;
- rr.domain_id=sd.domain_id;
- vector<DNSResourceRecord> rrs;
- rrs.push_back(rr);
- addCache(d_question, rrs);
+ DNSZoneRecord rr;
+ rr.dr.d_name = sd.qname;
+ rr.dr.d_type = QType::SOA;
+
+ rr.dr.d_content = makeSOAContent(sd);
+ rr.dr.d_ttl = sd.ttl;
+ rr.domain_id = sd.domain_id;
+
+ addCache(d_question, {rr});
+
}
return true;
}
#undef PC
// returns -1 for miss, 0 for negative match, 1 for hit
-int UeberBackend::cacheHas(const Question &q, vector<DNSResourceRecord> &rrs)
+int UeberBackend::cacheHas(const Question &q, vector<DNSZoneRecord> &rrs)
{
extern PacketCache PC;
static AtomicCounter *qcachehit=S.getPointer("query-cache-hit");
if(!d_negcache_ttl)
return;
// we should also not be storing negative answers if a pipebackend does scopeMask, but we can't pass a negative scopeMask in an empty set!
- PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, vector<DNSResourceRecord>(), d_negcache_ttl, q.zoneId);
+ PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, vector<DNSZoneRecord>(), d_negcache_ttl, q.zoneId);
}
-void UeberBackend::addCache(const Question &q, const vector<DNSResourceRecord> &rrs)
+void UeberBackend::addCache(const Question &q, const vector<DNSZoneRecord> &rrs)
{
extern PacketCache PC;
return;
unsigned int store_ttl = d_cache_ttl;
- for(const DNSResourceRecord& rr : rrs) {
- if (rr.ttl < d_cache_ttl)
- store_ttl = rr.ttl;
+ for(const auto& rr : rrs) {
+ if (rr.dr.d_ttl < d_cache_ttl)
+ store_ttl = rr.dr.d_ttl;
if (rr.scopeMask)
return;
}
}
bool UeberBackend::get(DNSResourceRecord &rr)
+{
+ DNSZoneRecord dzr;
+ if(!this->get(dzr))
+ return false;
+
+ rr=DNSResourceRecord(dzr.dr);
+ rr.auth = dzr.auth;
+ rr.domain_id = dzr.domain_id;
+ return true;
+}
+
+bool UeberBackend::get(DNSZoneRecord &rr)
{
if(d_negcached) {
return false;
--instances;
}
-bool UeberBackend::handle::get(DNSResourceRecord &r)
+bool UeberBackend::handle::get(DNSZoneRecord &r)
{
DLOG(L << "Ueber get() was called for a "<<qtype.getName()<<" record" << endl);
bool isMore=false;
class handle
{
public:
- bool get(DNSResourceRecord &r);
+ bool get(DNSZoneRecord &dr);
handle();
~handle();
bool getSOAUncached(const DNSName &domain, SOAData &sd, DNSPacket *p=0); // same, but ignores cache
bool list(const DNSName &target, int domain_id, bool include_disabled=false);
bool get(DNSResourceRecord &r);
+ bool get(DNSZoneRecord &r);
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
static DNSBackend *maker(const map<string,string> &);
private:
pthread_t tid;
handle d_handle;
- vector<DNSResourceRecord> d_answers;
- vector<DNSResourceRecord>::const_iterator d_cachehandleiter;
+ vector<DNSZoneRecord> d_answers;
+ vector<DNSZoneRecord>::const_iterator d_cachehandleiter;
static pthread_mutex_t d_mut;
static pthread_cond_t d_cond;
static bool d_go;
bool stale;
- int cacheHas(const Question &q, vector<DNSResourceRecord> &rrs);
+ int cacheHas(const Question &q, vector<DNSZoneRecord> &rrs);
void addNegCache(const Question &q);
- void addCache(const Question &q, const vector<DNSResourceRecord> &rrs);
+ void addCache(const Question &q, const vector<DNSZoneRecord> &rrs);
};
else if(g_mode==POSTGRES) {
cout<<"insert into records (domain_id, name, ordername, auth, type,content,ttl,prio,disabled) select id ,"<<
sqlstr(toLower(qname))<<", "<<
- sqlstr(toLower(labelReverse(makeRelative(qname, zname))))<<", '"<< (auth ? 't' : 'f') <<"', "<<
+ sqlstr(DNSName(qname).makeRelative(DNSName(zname)).toLower().labelReverse().toStringNoDot()<<", '"<< (auth ? 't' : 'f') <<"', "<<
sqlstr(qtype)<<", "<<
sqlstr(stripDotContent(content))<<", "<<ttl<<", "<<prio<<", '"<<(disabled ? 't': 'f') <<
"' from domains where name="<<toLower(sqlstr(zname))<<";\n";