From: bert hubert Date: Sat, 3 Sep 2016 22:47:42 +0000 (+0200) Subject: yolo - big DNSResourceRecord removal X-Git-Tag: dnsdist-1.1.0-beta2~123^2~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90ba52e0e6dcc3efc10cf7738b169a400552e739;p=thirdparty%2Fpdns.git yolo - big DNSResourceRecord removal --- diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 9429903ee4..07330b4fa2 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -993,7 +993,7 @@ bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string nsec3zone=getNSEC3PARAM(auth, &ns3pr); if(!nsec3zone) { - DNSName dqname = DNSName(labelReverse(qname)); + DNSName dqname = DNSName(qname).labelReverse(); //cerr<<"in bind2backend::getBeforeAndAfterAbsolute: no nsec3 for "< *domains, bool include_disabled=false); static DNSBackend *maker(); diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 12aee0c98d..8e16900924 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -503,7 +503,7 @@ bool DNSSECKeeper::checkKeys(const DNSName& zone) bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, - DNSResourceRecord::Place signPlace, vector& rrsigs, uint32_t signTTL) + DNSResourceRecord::Place signPlace, vector& rrsigs, uint32_t signTTL) { // cerr<<"Doing DB lookup for precomputed RRSIGs for '"<<(wildcardname.empty() ? qname : wildcardname)<<"'"< parts; - stringtok(parts, rr.content); - if(parts[0] == qtype.getName() && DNSName(parts[7])==signer) { - // cerr<<"Got it"<(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; } diff --git a/pdns/dnsbackend.cc b/pdns/dnsbackend.cc index 4e43ffc2b1..c94d5b6670 100644 --- a/pdns/dnsbackend.cc +++ b/pdns/dnsbackend.cc @@ -263,22 +263,33 @@ bool DNSBackend::getSOA(const DNSName &domain, SOAData &sd, DNSPacket *p) 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 @@ -317,6 +328,32 @@ bool DNSBackend::calculateSOASerial(const DNSName& domain, const SOAData& sd, ti return true; } +void fillSOAData(const DNSZoneRecord& in, SOAData& sd) +{ + sd.domain_id = in.domain_id; + sd.ttl = in.dr.d_ttl; + + auto src=getRR(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 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(sd.nameserver, sd.hostmaster, st); +} + void fillSOAData(const string &content, SOAData &data) { diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index e97b879889..2c1adfd07e 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -113,6 +113,7 @@ public: //! 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 @@ -430,6 +431,9 @@ public: /** 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 makeSOAContent(const SOAData& sd); #endif diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index b2d3b1c029..7294ffa737 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -174,42 +174,36 @@ void DNSPacket::clearRecords() 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=["<::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"< DNSPacket::getAPRecords() +vector DNSPacket::getAPRecords() { - vector arrs; + vector arrs; - for(vector::iterator i=d_rrs.begin(); + for(vector::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); } @@ -219,15 +213,15 @@ vector DNSPacket::getAPRecords() } -vector DNSPacket::getAnswerRecords() +vector DNSPacket::getAnswerRecords() { - vector arrs; + vector arrs; - for(vector::iterator i=d_rrs.begin(); + for(vector::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; @@ -249,9 +243,9 @@ bool DNSPacket::couldBeCached() 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; @@ -262,6 +256,10 @@ bool DNSPacket::isEmpty() return (d_rrs.empty()); } +static void shuffle(vector& 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. */ @@ -271,13 +269,15 @@ void DNSPacket::wrapup() return; } - DNSResourceRecord rr; - vector::iterator pos; + DNSZoneRecord rr; + vector::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) { @@ -316,19 +316,12 @@ void DNSPacket::wrapup() for(pos=d_rrs.begin(); pos < d_rrs.end(); ++pos) { // cerr<<"during wrapup, content=["<content<<"]"<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 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; @@ -365,7 +358,7 @@ void DNSPacket::wrapup() 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; diff --git a/pdns/dnspacket.hh b/pdns/dnspacket.hh index 7230ea6ac4..6c76d45875 100644 --- a/pdns/dnspacket.hh +++ b/pdns/dnspacket.hh @@ -55,11 +55,10 @@ #include "pdnsexception.hh" #include "dnsrecords.hh" - - class UeberBackend; class DNSSECKeeper; + //! This class represents DNS packets, either received or to be sent. class DNSPacket { @@ -105,10 +104,10 @@ public: 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) @@ -118,8 +117,8 @@ public: 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 getAPRecords(); //!< get a vector with DNSResourceRecords that need additional processing - vector getAnswerRecords(); //!< get a vector with DNSResourceRecords that are answers + vector getAPRecords(); //!< get a vector with DNSZoneRecords that need additional processing + vector 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 @@ -164,7 +163,7 @@ public: 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& getRRS() { return d_rrs; } + vector& getRRS() { return d_rrs; } static bool s_doEDNSSubnetProcessing; static uint16_t s_udpTruncationThreshold; //2 private: @@ -177,7 +176,7 @@ private: DNSName d_tsigkeyname; string d_tsigprevious; - vector d_rrs; // 8 + vector d_rrs; // 8 string d_rawpacket; // this is where everything lives 8 string d_ednsping; EDNSSubnetOpts d_eso; diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 79a29737bd..f0620ed3e2 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -315,21 +315,30 @@ struct DNSRecord 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 { diff --git a/pdns/dnsproxy.cc b/pdns/dnsproxy.cc index f7061c0989..0feda4f7a5 100644 --- a/pdns/dnsproxy.cc +++ b/pdns/dnsproxy.cc @@ -249,15 +249,14 @@ void DNSProxy::mainloop(void) // cerr<<"comp: "<<(int)j->first.d_place-1<<" "<first.d_label<<" " << DNSRecordContent::NumberToType(j->first.d_type)<<" "<first.d_content->getZoneRepresentation()<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); } } } diff --git a/pdns/dnsrecords.hh b/pdns/dnsrecords.hh index e00a41ef68..f23b2c64fe 100644 --- a/pdns/dnsrecords.hh +++ b/pdns/dnsrecords.hh @@ -161,7 +161,6 @@ class TXTRecordContent : public DNSRecordContent public: includeboilerplate(TXT) -private: string d_text; }; @@ -198,6 +197,7 @@ class CNAMERecordContent : public DNSRecordContent { public: includeboilerplate(CNAME) + CNAMERecordContent(const DNSName& content) : d_content(content){} DNSName getTarget() const { return d_content; } private: DNSName d_content; @@ -208,7 +208,6 @@ class ALIASRecordContent : public DNSRecordContent public: includeboilerplate(ALIAS) -private: DNSName d_content; }; @@ -217,8 +216,6 @@ class DNAMERecordContent : public DNSRecordContent { public: includeboilerplate(DNAME) - -private: DNSName d_content; }; diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index 2c0f7ac55e..503ca5c106 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -154,7 +154,7 @@ string hashQNameWithSalt(const NSEC3PARAMRecordContent& ns3prc, const DNSName& q string hashQNameWithSalt(const std::string& salt, unsigned int iterations, const DNSName& qname); void decodeDERIntegerSequence(const std::string& input, vector& output); class DNSPacket; -void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const std::set& authMap, vector& rrs); +void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const std::set& authMap, vector& rrs); string calculateHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash); diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index d88d8e97cb..7a9a296649 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -173,7 +173,7 @@ public: 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& rrsigs, uint32_t signTTL); + bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector& rrsigs, uint32_t signTTL); bool isPresigned(const DNSName& zname); bool setPresigned(const DNSName& zname); bool unsetPresigned(const DNSName& zname); @@ -261,9 +261,11 @@ private: 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); diff --git a/pdns/dnssecsigner.cc b/pdns/dnssecsigner.cc index 8beca0f82d..7a2484f66b 100644 --- a/pdns/dnssecsigner.cc +++ b/pdns/dnssecsigner.cc @@ -71,7 +71,7 @@ int getRRSIGsForRRSET(DNSSECKeeper& dk, const DNSName& signer, const DNSName sig // 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 >& toSign, vector& outsigned, uint32_t origTTL) + vector >& toSign, vector& outsigned, uint32_t origTTL) { //cerr<<"Asked to sign '"<(rrc); outsigned.push_back(rr); } } @@ -159,9 +159,9 @@ void fillOutRRSIG(DNSSECPrivateKey& dpk, const DNSName& signQName, RRSIGRecordCo } } -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& authSet, const DNSName& name, DNSName& auth) @@ -179,7 +179,7 @@ static bool getBestAuthFromSet(const set& authSet, const DNSName& name, return false; } -void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, vector& rrs) +void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, vector& rrs) { stable_sort(rrs.begin(), rrs.end(), rrsigncomp); @@ -191,38 +191,30 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, DNSResourceRecord::Place signPlace=DNSResourceRecord::ANSWER; vector > toSign; - vector signedRecords; + vector signedRecords; signedRecords.reserve(rrs.size()*1.5); - // cout<::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 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)) diff --git a/pdns/lua-auth.cc b/pdns/lua-auth.cc index 18dfd7a306..38d8913978 100644 --- a/pdns/lua-auth.cc +++ b/pdns/lua-auth.cc @@ -207,7 +207,10 @@ static int ldp_addRecords(lua_State *L) { vector 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; } diff --git a/pdns/misc.cc b/pdns/misc.cc index ddfbc7b641..435434ccca 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -688,45 +688,6 @@ string stripDot(const string& dom) } -string labelReverse(const std::string& qname) -{ - if(qname.empty()) - return qname; - - bool dotName = qname.find('.') != string::npos; - - vector 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::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) { diff --git a/pdns/misc.hh b/pdns/misc.hh index 2b56cd982f..5cb60a2705 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -306,6 +306,7 @@ inline void unixDie(const string &why) string makeHexDump(const string& str); void shuffle(vector& rrs); void shuffle(vector& rrs); + void orderAndShuffle(vector& rrs); void normalizeTV(struct timeval& tv); @@ -442,9 +443,6 @@ inline DNSName toCanonic(const DNSName& zone, const string& qname) 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); diff --git a/pdns/packetcache.cc b/pdns/packetcache.cc index 5e3b7d90fc..35212fc417 100644 --- a/pdns/packetcache.cc +++ b/pdns/packetcache.cc @@ -196,7 +196,7 @@ void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryTyp S.inc("deferred-cache-inserts"); } -void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector& value, unsigned int ttl, int zoneID) +void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector& value, unsigned int ttl, int zoneID) { cleanupIfNeeded(); @@ -290,7 +290,7 @@ int PacketCache::purge(const string &match) } } // called from ueberbackend -bool PacketCache::getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector& value, int zoneID) +bool PacketCache::getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector& value, int zoneID) { if(d_ttl<0) getTTLS(); @@ -327,7 +327,7 @@ bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, Cache return ret; } -bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector& value, int zoneID) +bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector& value, int zoneID) { uint16_t qt = qtype.getCode(); //cerr<<"Lookup for maxReplyLen: "<& content, unsigned int ttl, int zoneID=-1); + void insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const vector& 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& entry, int zoneID=-1); + bool getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, vector& entry, int zoneID=-1); int size(); //!< number of entries in the cache @@ -86,7 +86,7 @@ public: 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& entry, int zoneID=-1); + bool getEntryLocked(const DNSName &content, const QType& qtype, CacheEntryType cet, vector& entry, int zoneID=-1); struct CacheEntry @@ -95,7 +95,7 @@ private: DNSName qname; string value; - vector drs; + vector drs; time_t created; time_t ttd; diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 57d02bee9f..8f58e46676 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -108,16 +108,16 @@ bool PacketHandler::addCDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) 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(value.first.getDNSKEY()); rr.auth=true; r->addRecord(rr); haveOne=true; @@ -127,7 +127,7 @@ bool PacketHandler::addCDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) 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; } @@ -145,16 +145,16 @@ bool PacketHandler::addCDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) **/ 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(value.first.getDNSKEY()); rr.auth=true; r->addRecord(rr); haveOne=true; @@ -164,7 +164,7 @@ bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd) 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; } @@ -192,10 +192,10 @@ bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd) vector 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; @@ -205,7 +205,7 @@ bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd) 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(makeDSFromDNSKey(p->qdomain, value.first.getDNSKEY(), std::stoi(digestAlgo))); r->addRecord(rr); haveOne=true; } @@ -215,7 +215,7 @@ bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd) 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; } @@ -227,15 +227,15 @@ bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd) /** 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(ns3prc); rr.auth = true; r->addRecord(rr); return true; @@ -247,24 +247,25 @@ bool PacketHandler::addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd) // 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::mastermake(QType::TXT, 1, content)); } else if (target==idserver) { // modes: disabled, hostname or custom @@ -274,17 +275,17 @@ int PacketHandler::doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target) r->setRcode(RCode::Refused); return 0; } - rr.content=id; + rr.dr.d_content=shared_ptr(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; } @@ -293,10 +294,10 @@ int PacketHandler::doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target) return 0; } -vector PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target) +vector PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target) { - vector ret; - DNSResourceRecord rr; + vector ret; + DNSZoneRecord rr; DNSName subdomain(target); do { if(subdomain == sd.qname) // stop at SOA @@ -311,10 +312,10 @@ vector PacketHandler::getBestReferralNS(DNSPacket *p, SOAData return ret; } -vector PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target) +vector PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target) { - vector ret; - DNSResourceRecord rr; + vector ret; + DNSZoneRecord rr; DNSName prefix; DNSName subdomain(target); do { @@ -323,11 +324,11 @@ vector PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData 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(prefix + getRR(rr.dr)->d_content)); rr.auth = 0; // don't sign CNAME - target= DNSName(rr.content); + target= getRR(rr.dr)->getTarget(); ret.push_back(rr); } if(!ret.empty()) @@ -343,10 +344,10 @@ vector PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData // Return best matching wildcard or next closer name -bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector* ret) +bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector* ret) { ret->clear(); - DNSResourceRecord rr; + DNSZoneRecord rr; DNSName subdomain(target); bool haveSomething=false; @@ -358,7 +359,7 @@ bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &ta 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; @@ -382,60 +383,49 @@ bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &ta /** 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 arrs=r->getAPRecords(); + vector arrs=r->getAPRecords(); if(arrs.empty()) return 1; DLOG(L< crrs; + vector crrs; - for(vector::const_iterator i=arrs.begin(); i!=arrs.end(); ++i) + for(vector::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::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(i->dr)->d_mxname; + else if(i->dr.d_type == QType::SRV) + lookup = getRR(i->dr)->d_target; + + B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), lookup, p); - if (i->qtype.getCode()==QType::SRV) { - vectorparts; - 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<qname<<" ("<dr.d_name<<" ("<addRecord(rr); } } @@ -464,19 +454,19 @@ void PacketHandler::emitNSEC(DNSPacket *r, const SOAData& sd, const DNSName& nam 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(nrc); + rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY; rr.auth = true; r->addRecord(rr); @@ -491,7 +481,7 @@ void PacketHandler::emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMR n3rc.d_salt = ns3prc.d_salt; n3rc.d_nexthash = nexthash; - DNSResourceRecord rr; + DNSZoneRecord rr; if(!name.empty()) { if (sd.qname == name) { @@ -510,19 +500,19 @@ void PacketHandler::emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMR 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(n3rc); + rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY; rr.auth = true; r->addRecord(rr); @@ -622,7 +612,7 @@ void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const DNSName& target, bool doNextcloser = false; string before, after, hashed; DNSName unhashed, closest; - DNSResourceRecord rr; + DNSZoneRecord rr; if (mode == 2 || mode == 3 || mode == 4) { closest=wildcard; @@ -642,7 +632,7 @@ void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const DNSName& target, DLOG(L<<"No matching NSEC3, do closest (provable) encloser"<qdomain, nsset, &nameserver, &account, &db)) { L<qdomain<<" for potential supermaster "<addRecord(rr); @@ -994,15 +986,15 @@ void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& targ 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); @@ -1017,11 +1009,11 @@ bool PacketHandler::addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DN { //cerr<<"Trying to find a DS for '"<qname<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; } @@ -1070,10 +1062,10 @@ bool PacketHandler::tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &ta if(!d_doDNAME) return false; DLOG(L< rrset = getBestDNAMESynth(p, sd, target); + vector 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; @@ -1085,7 +1077,7 @@ bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName retargeted = nodata = false; DNSName bestmatch; - vector rrset; + vector rrset; if(!getBestWildcard(p, sd, target, wildcard, &rrset)) return false; @@ -1096,16 +1088,16 @@ bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName else { DLOG(L<<"The best wildcard match: "<qname<(rr.dr)->getTarget(); } DLOG(L<<"\tadding '"<addRecord(rr); } } @@ -1119,7 +1111,7 @@ bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) { *shouldRecurse=false; - DNSResourceRecord rr; + DNSZoneRecord rr; SOAData sd; // string subdomain=""; @@ -1127,7 +1119,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) int retargetcount=0; set authSet; - vector rrset; + vector rrset; bool weDone=0, weRedirected=0, weHaveUnauth=0; DNSName haveAlias; @@ -1324,12 +1316,12 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) } 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; @@ -1363,27 +1355,27 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) while(B.get(rr)) { //cerr<<"got content: ["<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: "<qtype)<<", "<qtype.getCode() == QType::ANY || rr.qtype == p->qtype) && rr.auth) + // cerr<<"Auth: "<qtype)<<", "<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(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); @@ -1391,10 +1383,10 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) /* 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); @@ -1456,9 +1448,9 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) 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(rr.dr)->getTarget(); retargetcount++; goto retargeted; } @@ -1467,7 +1459,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) 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; } @@ -1478,7 +1470,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) 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; } @@ -1487,7 +1479,7 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) 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<qdomain<<"|"<qtype.getCode()<<"): you have a trailing dot, this could be the problem (or run pdnsutil rectify-zone " <qdomain<<"|"<qtype.getCode()<<"): please run pdnsutil rectify-zone "< getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target); - vector getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target); + vector getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target); + vector 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* ret); + bool getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector* 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); @@ -116,4 +116,5 @@ private: 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 makeSOAContent(const SOAData& sd); #endif /* PACKETHANDLER */ diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 6378d70f60..5d1a123c0b 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -714,9 +714,12 @@ int increaseSerial(const DNSName& zone, DNSSECKeeper &dk) sd.db->lookup(QType(QType::SOA), zone); vector 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) { @@ -744,7 +747,7 @@ int increaseSerial(const DNSName& zone, DNSSECKeeper &dk) } } else { - sd.serial = calculateEditSOA(sd, soaEditKind) + 1; + sd.serial = calculateEditSOA(szr, soaEditKind) + 1; } rrs[0].content = serializeSOAData(sd); @@ -1397,7 +1400,7 @@ void testSpeed(DNSSECKeeper& dk, const DNSName& zone, const string& remote, int ChunkedSigningPipe csp(DNSName(zone), 1, remote, cores); - vector signatures; + vector signatures; uint32_t rnd; unsigned char* octets = (unsigned char*)&rnd; char tmp[25]; @@ -1411,8 +1414,9 @@ void testSpeed(DNSSECKeeper& dk, const DNSName& zone, const string& remote, int 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()) ; } diff --git a/pdns/secpoll-auth.cc b/pdns/secpoll-auth.cc index 66cc0ed112..84ed625090 100644 --- a/pdns/secpoll-auth.cc +++ b/pdns/secpoll-auth.cc @@ -15,6 +15,7 @@ #include "namespaces.hh" #include "statbag.hh" #include "stubresolver.hh" +#include "dnsrecords.hh" #include #ifndef PACKAGEVERSION #define PACKAGEVERSION getPDNSVersion() @@ -44,17 +45,14 @@ void doSecPoll(bool first) boost::replace_all(query, "+", "_"); boost::replace_all(query, "~", "_"); - vector ret; + vector 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(ret.begin()->dr)->d_text; pair split = splitField(content, ' '); diff --git a/pdns/serialtweaker.cc b/pdns/serialtweaker.cc index 850071315c..f072c7a2be 100644 --- a/pdns/serialtweaker.cc +++ b/pdns/serialtweaker.cc @@ -41,9 +41,8 @@ uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq) bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp) { - vector& 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); @@ -52,19 +51,18 @@ bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp) 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(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(rr.dr); if(pdns_iequals(kind,"INCEPTION")) { L<00 */ + if(src->d_st.serial < inception_serial - 1) { /* less than 00 */ return inception_serial; /* return 01 (skipping 00 as possible value) */ - } else if(sd.serial <= dont_increment_after) { /* >= 00 but <= 99 */ - return (sd.serial + 2); /* "00" and "01" are reserved for inception increasing, so increment sd.serial by two */ + } else if(src->d_st.serial <= dont_increment_after) { /* >= 00 but <= 99 */ + return (src->d_st.serial + 2); /* "00" and "01" are reserved for inception increasing, so increment sd.serial by two */ } } else if(pdns_iequals(kind,"INCEPTION-WEEK")) { @@ -88,7 +86,7 @@ uint32_t calculateEditSOA(SOAData sd, const string& kind) { } 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<d_st.serial < inception) return inception; } else if(!kind.empty()) { - L<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(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(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); @@ -134,12 +143,24 @@ uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const stri 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(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; diff --git a/pdns/signingpipe.cc b/pdns/signingpipe.cc index 3cfbc13aaa..36558a733b 100644 --- a/pdns/signingpipe.cc +++ b/pdns/signingpipe.cc @@ -75,7 +75,7 @@ ChunkedSigningPipe::ChunkedSigningPipe(const DNSName& signerName, bool mustSign, d_maxchunkrecords(100), d_tids(d_numworkers), d_mustSign(mustSign), d_final(false) { d_rrsetToSign = new rrset_t; - d_chunks.push_back(vector()); // load an empty chunk + d_chunks.push_back(vector()); // load an empty chunk if(!d_mustSign) return; @@ -111,14 +111,14 @@ ChunkedSigningPipe::~ChunkedSigningPipe() 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 } } @@ -129,11 +129,11 @@ void ChunkedSigningPipe::dedupRRSet() 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(); @@ -268,7 +268,7 @@ void ChunkedSigningPipe::sendRRSetToWorker() // it sounds so socialist! unsigned int ChunkedSigningPipe::getReady() { unsigned int sum=0; - for(const std::vector& v : d_chunks) { + for(const auto& v : d_chunks) { sum += v.size(); } return sum; @@ -313,7 +313,7 @@ void ChunkedSigningPipe::flushToSign() d_rrsetToSign->clear(); } -vector ChunkedSigningPipe::getChunk(bool final) +vector ChunkedSigningPipe::getChunk(bool final) { if(final && !d_final) { // this means we should keep on reading until d_outstanding == 0 @@ -327,10 +327,10 @@ vector ChunkedSigningPipe::getChunk(bool final) } if(d_final) flushToSign(); // should help us wait - vector front=d_chunks.front(); + vector front=d_chunks.front(); d_chunks.pop_front(); if(d_chunks.empty()) - d_chunks.push_back(vector()); + d_chunks.push_back(vector()); /* if(d_final && front.empty()) cerr<<"getChunk returning empty in final"< rrset_t; + typedef vector 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 d_signed; @@ -64,7 +64,7 @@ private: int d_submitted; rrset_t* d_rrsetToSign; - std::deque< std::vector > d_chunks; + std::deque< std::vector > d_chunks; DNSName d_signer; chunk_t::size_type d_maxchunkrecords; diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 6d483f66f1..479c786ed2 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -547,7 +547,7 @@ void CommunicatorClass::suck(const DNSName &domain, const string &remote) } 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); diff --git a/pdns/stubresolver.cc b/pdns/stubresolver.cc index 87505e05c1..eab830e102 100644 --- a/pdns/stubresolver.cc +++ b/pdns/stubresolver.cc @@ -60,11 +60,11 @@ void stubParseResolveConf() } // s_stubresolvers contains the ComboAddresses that are used to resolve the -int stubDoResolve(const string& qname, uint16_t qtype, vector& ret) +int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret) { vector 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()) { @@ -78,17 +78,18 @@ int stubDoResolve(const string& qname, uint16_t qtype, vector } L< sizeof(struct dnsheader)) { struct dnsheader d; memcpy(&d, reply.c_str(), sizeof(d)); @@ -105,16 +106,14 @@ int stubDoResolve(const string& qname, uint16_t qtype, vector 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<& ret); +int stubDoResolve(const DNSName& qname, uint16_t qtype, vector& ret); diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 5ae781db17..084b27dbbd 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -626,7 +626,10 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou // SOA *must* go out first, our signing pipe might reorder DLOG(L<<"Sending out SOA"<addRecord(soa); + DNSZoneRecord dzrsoa; + dzrsoa.auth=true; + dzrsoa.dr=DNSRecord(soa); + outpacket->addRecord(dzrsoa); editSOA(dk, sd.qname, outpacket.get()); if(securedZone) { set authSet; @@ -651,46 +654,46 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou 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 cds, cdnskey; + vector cds, cdnskey; DNSSECKeeper::keyset_t entryPoints = dk.getEntryPoints(q->qdomain); set 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(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(value.first.getDNSKEY()); + cdnskey.push_back(zrr); } if(!publishCDS.empty()){ - rr.qtype=QType(QType::CDS); + zrr.dr.d_type=QType::CDS; vector 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(makeDSFromDNSKey(target, value.first.getDNSKEY(), pdns_stou(digestAlgo))); + cds.push_back(zrr); } } } @@ -698,9 +701,9 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou 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); } } @@ -708,15 +711,15 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou 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(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 @@ -730,65 +733,68 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou const bool rectify = !(presignedZone || ::arg().mustDo("disable-axfr-rectify")); set qnames, nsset, terms; - vector rrs; + vector 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 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 ips; + int ret1 = stubDoResolve(getRR(zrr.dr)->d_content, QType::A, ips); + int ret2 = stubDoResolve(getRR(zrr.dr)->d_content, QType::AAAA, ips); if(ret1 != RCode::NoError || ret2 != RCode::NoError) { - L<getZoneRepresentation()<<", aborting AXFR"<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< q, int ou // ents are only required for NSEC3 zones uint32_t maxent = ::arg().asNum("max-ent-entries"); set 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)) { @@ -809,8 +815,8 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou } } 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); @@ -819,8 +825,8 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou } } - 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)) { @@ -834,15 +840,15 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou } 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< q, int ou 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()) { @@ -930,14 +937,14 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou 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(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()) { @@ -960,19 +967,19 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou 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(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()) { @@ -1014,7 +1021,7 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr q, int ou DLOG(L<<"Done writing out records"<addRecord(soa); + outpacket->addRecord(dzrsoa); editSOA(dk, sd.qname, outpacket.get()); if(!tsigkeyname.empty()) outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true); @@ -1135,7 +1142,11 @@ int TCPNameserver::doIXFR(shared_ptr q, int outsock) // SOA *must* go out first, our signing pipe might reorder DLOG(L<<"Sending out SOA"<addRecord(soa); + DNSZoneRecord dzrsoa; + dzrsoa.dr=DNSRecord(soa); + dzrsoa.auth=true; + + outpacket->addRecord(dzrsoa); editSOA(dk, sd.qname, outpacket.get()); if(securedZone) { set authSet; diff --git a/pdns/tkey.cc b/pdns/tkey.cc index f31d6bc202..540ec6f1c9 100644 --- a/pdns/tkey.cc +++ b/pdns/tkey.cc @@ -71,19 +71,15 @@ void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) { 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) { diff --git a/pdns/ueberbackend.cc b/pdns/ueberbackend.cc index fe97528c4e..fdf1ad68a9 100644 --- a/pdns/ueberbackend.cc +++ b/pdns/ueberbackend.cc @@ -265,9 +265,8 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target) if(cstat == 1 && !d_answers.empty() && d_cache_ttl) { DLOG(L<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; @@ -327,15 +326,15 @@ bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target) 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 rrs; - rrs.push_back(rr); - addCache(d_question, rrs); + + addCache(d_question, {rr}); } } @@ -363,9 +362,9 @@ bool UeberBackend::getSOA(const DNSName &domain, SOAData &sd, DNSPacket *p) 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; } @@ -383,15 +382,16 @@ bool UeberBackend::getSOAUncached(const DNSName &domain, SOAData &sd, DNSPacket for(vector::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 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; } @@ -448,7 +448,7 @@ void UeberBackend::cleanup() #undef PC // returns -1 for miss, 0 for negative match, 1 for hit -int UeberBackend::cacheHas(const Question &q, vector &rrs) +int UeberBackend::cacheHas(const Question &q, vector &rrs) { extern PacketCache PC; static AtomicCounter *qcachehit=S.getPointer("query-cache-hit"); @@ -480,10 +480,10 @@ void UeberBackend::addNegCache(const Question &q) 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(), d_negcache_ttl, q.zoneId); + PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, vector(), d_negcache_ttl, q.zoneId); } -void UeberBackend::addCache(const Question &q, const vector &rrs) +void UeberBackend::addCache(const Question &q, const vector &rrs) { extern PacketCache PC; @@ -491,9 +491,9 @@ void UeberBackend::addCache(const Question &q, const vector & 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; } @@ -578,6 +578,18 @@ void UeberBackend::getAllDomains(vector *domains, bool include_disab } 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; @@ -643,7 +655,7 @@ UeberBackend::handle::~handle() --instances; } -bool UeberBackend::handle::get(DNSResourceRecord &r) +bool UeberBackend::handle::get(DNSZoneRecord &r) { DLOG(L << "Ueber get() was called for a "< *domains, bool include_disabled=false); static DNSBackend *maker(const map &); @@ -139,8 +140,8 @@ public: private: pthread_t tid; handle d_handle; - vector d_answers; - vector::const_iterator d_cachehandleiter; + vector d_answers; + vector::const_iterator d_cachehandleiter; static pthread_mutex_t d_mut; static pthread_cond_t d_cond; @@ -162,9 +163,9 @@ private: static bool d_go; bool stale; - int cacheHas(const Question &q, vector &rrs); + int cacheHas(const Question &q, vector &rrs); void addNegCache(const Question &q); - void addCache(const Question &q, const vector &rrs); + void addCache(const Question &q, const vector &rrs); }; diff --git a/pdns/zone2sql.cc b/pdns/zone2sql.cc index 424c55a5aa..5fb36047cb 100644 --- a/pdns/zone2sql.cc +++ b/pdns/zone2sql.cc @@ -202,7 +202,7 @@ static void emitRecord(const DNSName& zoneName, const DNSName &DNSqname, const s 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))<<", "<