]> granicus.if.org Git - pdns/commitdiff
yolo - big DNSResourceRecord removal
authorbert hubert <bert.hubert@netherlabs.nl>
Sat, 3 Sep 2016 22:47:42 +0000 (00:47 +0200)
committerbert hubert <bert.hubert@powerdns.com>
Tue, 13 Sep 2016 10:53:30 +0000 (12:53 +0200)
33 files changed:
modules/bindbackend/bindbackend2.cc
modules/bindbackend/bindbackend2.hh
pdns/dbdnsseckeeper.cc
pdns/dnsbackend.cc
pdns/dnsbackend.hh
pdns/dnspacket.cc
pdns/dnspacket.hh
pdns/dnsparser.hh
pdns/dnsproxy.cc
pdns/dnsrecords.hh
pdns/dnssecinfra.hh
pdns/dnsseckeeper.hh
pdns/dnssecsigner.cc
pdns/lua-auth.cc
pdns/misc.cc
pdns/misc.hh
pdns/packetcache.cc
pdns/packetcache.hh
pdns/packethandler.cc
pdns/packethandler.hh
pdns/pdnsutil.cc
pdns/secpoll-auth.cc
pdns/serialtweaker.cc
pdns/signingpipe.cc
pdns/signingpipe.hh
pdns/slavecommunicator.cc
pdns/stubresolver.cc
pdns/stubresolver.hh
pdns/tcpreceiver.cc
pdns/tkey.cc
pdns/ueberbackend.cc
pdns/ueberbackend.hh
pdns/zone2sql.cc

index 9429903ee44d703b76d1e0397528573b4c9e8b08..07330b4fa254bbd12031085f229d9fc8d55912b6 100644 (file)
@@ -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 "<<auth<<endl;
     return findBeforeAndAfterUnhashed(bbd, dqname, unhashed, before, after);
   }
index 21b45e3b4729e60fa56501e77aa29513fc352f6e..b3ec460753e5b759596902f5494f3ef2b20a6e76 100644 (file)
@@ -194,6 +194,7 @@ public:
   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();
index 12aee0c98dc001cbdcb9d30b0b987a9083bbe57e..8e16900924977b12a3464c92927d5e033c9c49d1 100644 (file)
@@ -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<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;
@@ -512,20 +512,16 @@ bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const DNSName& signer, const D
                 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;
 }
index 4e43ffc2b1dd981e8f55715f9cba78b5b1a38e99..c94d5b667081f15825c16d44eb0470c9407747df 100644 (file)
@@ -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<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)
 {
index e97b879889cca71803084cba0fb408c248c1239a..2c1adfd07e956e04d8d83cf0b66a035bea028ead 100644 (file)
@@ -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<DNSRecordContent> makeSOAContent(const SOAData& sd);
 
 #endif
index b2d3b1c029ed09a00e7d760ba6e399db50af7e45..7294ffa737b52abb6acb915b1438af846506c8ed 100644 (file)
@@ -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=["<<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);
         }
@@ -219,15 +213,15 @@ vector<DNSResourceRecord*> DNSPacket::getAPRecords()
 
 }
 
-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;
@@ -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<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.
  */
@@ -271,13 +269,15 @@ void DNSPacket::wrapup()
     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) {
@@ -316,19 +316,12 @@ void DNSPacket::wrapup()
       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;
@@ -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;
index 7230ea6ac4ff3d7a7fdec3a4aefd6c9bdfb1c6a8..6c76d45875383e7d79314fb3e1c2f9b17ca8fec0 100644 (file)
 #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<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
@@ -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<DNSResourceRecord>& getRRS() { return d_rrs; }
+  vector<DNSZoneRecord>& 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<DNSResourceRecord> d_rrs; // 8
+  vector<DNSZoneRecord> d_rrs; // 8
   string d_rawpacket; // this is where everything lives 8
   string d_ednsping;
   EDNSSubnetOpts d_eso;
index 79a29737bda386d9fdf9c237517335a567f5563e..f0620ed3e29cd11b4adae7b99325c5b1010021b2 100644 (file)
@@ -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
 {
index f7061c0989722e5af19a8d11d14d9ea10d75a813..0feda4f7a507e010a7bc7034ed67b6baf821bb7c 100644 (file)
@@ -249,15 +249,14 @@ void DNSProxy::mainloop(void)
            //      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);
              }
            }
          }
index e00a41ef68eb95656e21cb26b8383a1e3e828041..f23b2c64fe7ef0cf9d5e36f650190e2921d14c9c 100644 (file)
@@ -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;
 };
 
index 2c0f7ac55e54f92eb857b9fa46f05d74b70ee8b3..503ca5c106afbf4acc6037466c4a2f278de15dd7 100644 (file)
@@ -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<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);
 
index d88d8e97cb6c29ce0676d9849e8bf63ad9db52d2..7a9a296649752e5d3a58fcdbf046de3ae17673dd 100644 (file)
@@ -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<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);
@@ -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);
index 8beca0f82d6c470d17bb69c51fe6100d5be18717..7a2484f66b069bd29bfa595a3f30e9353a9982ad 100644 (file)
@@ -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<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())
@@ -87,17 +87,17 @@ void addSignature(DNSSECKeeper& dk, UeberBackend& db, const DNSName& signer, con
       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);
     }
   }
@@ -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<DNSName>& authSet, const DNSName& name, DNSName& auth)
@@ -179,7 +179,7 @@ static bool getBestAuthFromSet(const set<DNSName>& authSet, const DNSName& name,
   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);
   
@@ -191,38 +191,30 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet,
   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))
index 18dfd7a306c2f47328c8557406e0f9cbb98dcb83..38d8913978f9f4ec70e275ed285db7b1fce74690 100644 (file)
@@ -207,7 +207,10 @@ static int ldp_addRecords(lua_State *L) {
   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;
 }
index ddfbc7b641bb2a9ee34149cc51e791c7bf2fbab5..435434cccabc392a405f2400e42b88cfad9f42de 100644 (file)
@@ -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<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)
 {
index 2b56cd982ff75412df3eba774a048c896c4ac48f..5cb60a2705f20f7f7529a5aadec2ee10b70e5e85 100644 (file)
@@ -306,6 +306,7 @@ inline void unixDie(const string &why)
 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);
@@ -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);
index 5e3b7d90fca91d34f0f917be2b8b210b9bc156bc..35212fc417669aa1e1a382c51053586974911cc3 100644 (file)
@@ -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<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();
 
@@ -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<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();
@@ -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<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;
index fdfc48a710a4f9b961099823d793008aa35e72af..47c344537178e628b52382644567316386801349 100644 (file)
@@ -59,12 +59,12 @@ public:
   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
@@ -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<DNSResourceRecord>& entry, int zoneID=-1);
+  bool getEntryLocked(const DNSName &content, const QType& qtype, CacheEntryType cet, vector<DNSZoneRecord>& entry, int zoneID=-1);
 
 
   struct CacheEntry
@@ -95,7 +95,7 @@ private:
 
     DNSName qname;
     string value;
-    vector<DNSResourceRecord> drs;
+    vector<DNSZoneRecord> drs;
     time_t created;
     time_t ttd;
 
index 57d02bee9fd2558a4f4dd13ea2f8d81b77203258..8f58e46676a4312d2845cdf6b68a183033527a35 100644 (file)
@@ -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<DNSKEYRecordContent>(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<DNSKEYRecordContent>(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<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;
@@ -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<DSRecordContent>(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<NSEC3PARAMRecordContent>(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>(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>(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<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
@@ -311,10 +312,10 @@ vector<DNSResourceRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData
   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 {
@@ -323,11 +324,11 @@ vector<DNSResourceRecord> 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>(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())
@@ -343,10 +344,10 @@ vector<DNSResourceRecord> 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<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;
 
@@ -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<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);
       }
     }
@@ -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<NSECRecordContent>(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<NSEC3RecordContent>(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"<<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))
@@ -787,7 +777,7 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
   // 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;
   }
 
@@ -807,7 +797,7 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p, const DNSName& tsigke
   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;
@@ -972,16 +962,18 @@ DNSPacket *PacketHandler::question(DNSPacket *p)
   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);
@@ -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 '"<<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;
@@ -1029,21 +1021,21 @@ bool PacketHandler::addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DN
 
 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;
 }
@@ -1070,10 +1062,10 @@ bool PacketHandler::tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &ta
   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;
@@ -1085,7 +1077,7 @@ bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName
   retargeted = nodata = false;
   DNSName bestmatch;
 
-  vector<DNSResourceRecord> rrset;
+  vector<DNSZoneRecord> 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: "<<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);
     }
   }
@@ -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<DNSName> authSet;
 
-  vector<DNSResourceRecord> rrset;
+  vector<DNSZoneRecord> 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: ["<<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);
@@ -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<CNAMERecordContent>(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<<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;
index 886a5840d8e6dff355414f1c995ebfc335fda228..f3301fd26dc7b113028299e3b4ac9ecf54e49ae5 100644 (file)
@@ -91,12 +91,12 @@ private:
 
   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);
@@ -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<DNSRecordContent> makeSOAContent(const SOAData& sd);
 #endif /* PACKETHANDLER */
index 6378d70f601a4c5f565318f9119afee81caefb9a..5d1a123c0b7f2b50a13613c5c612a95fbea5a592 100644 (file)
@@ -714,9 +714,12 @@ int increaseSerial(const DNSName& zone, DNSSECKeeper &dk)
   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) {
@@ -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<DNSResourceRecord> signatures;
+  vector<DNSZoneRecord> 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())
         ;
   }
index 66cc0ed112302fc8dce1ef7271e87e3dedb1dc17..84ed625090f50f04521d96cfc28b39376df403d9 100644 (file)
@@ -15,6 +15,7 @@
 #include "namespaces.hh"
 #include "statbag.hh"
 #include "stubresolver.hh"
+#include "dnsrecords.hh"
 #include <stdint.h>
 #ifndef PACKAGEVERSION
 #define PACKAGEVERSION getPDNSVersion()
@@ -44,17 +45,14 @@ void doSecPoll(bool first)
   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, ' ');
 
index 850071315c4f40f264c6d0a8e92161d831ab0211..f072c7a2be0ce69b7c6af68091b72431fabd3751 100644 (file)
@@ -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<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);
@@ -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<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();
@@ -75,10 +73,10 @@ uint32_t calculateEditSOA(SOAData sd, const string& kind) {
     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")) {
@@ -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<<Logger::Warning<<"Deprecation warning: The 'EPOCH' soa-edit value will be removed in PowerDNS 4.1"<<endl;
@@ -96,32 +94,43 @@ uint32_t calculateEditSOA(SOAData sd, const string& kind) {
   }
   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);
@@ -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<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;
index 3cfbc13aaabe419ced34b8e924a2a1332ec12989..36558a733bf5edcede61ca68179c1cca1fe4e123 100644 (file)
@@ -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<DNSResourceRecord>()); // load an empty chunk
+  d_chunks.push_back(vector<DNSZoneRecord>()); // 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<DNSResourceRecord>& 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<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
@@ -327,10 +327,10 @@ vector<DNSResourceRecord> ChunkedSigningPipe::getChunk(bool final)
   }
   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;
index 99884982cafd46884c9a12de3f1ced1c57a3ac66..50c8c93e5f97057cea99c3a5babbd839e9016f06 100644 (file)
 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;
@@ -64,7 +64,7 @@ private:
   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;
index 6d483f66f1e1def136b22991daea821921fa6483..479c786ed2090e1544d135c01d364ec6665468f2 100644 (file)
@@ -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);
index 87505e05c1437ebf8a35b882f4cd522b097d6fd1..eab830e1026bed134b8a693245942540a15ba584 100644 (file)
@@ -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<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()) {
@@ -78,17 +78,18 @@ int stubDoResolve(const string& qname, uint16_t qtype, vector<DNSResourceRecord>
   }
   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));
@@ -105,16 +106,14 @@ int stubDoResolve(const string& qname, uint16_t qtype, vector<DNSResourceRecord>
 
     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
+}
index cb1620ca29c617aef10a48078c2b14c525ebad62..fbf9aeae1a31a5b2a7d8f7344544efe8c993cb2a 100644 (file)
@@ -24,4 +24,4 @@
 #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);
index 5ae781db17074f330f4daec12a48c8d71f14d85a..084b27dbbd0c7756a695c36c5786cb3cfb66648f 100644 (file)
@@ -626,7 +626,10 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> q, int ou
   // 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;
@@ -651,46 +654,46 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> 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<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);
         }
       }
     }
@@ -698,9 +701,9 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> 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<DNSPacket> 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<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
@@ -730,65 +733,68 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> q, int ou
 
   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;
@@ -798,9 +804,9 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> q, int ou
       // 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)) {
@@ -809,8 +815,8 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> 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<DNSPacket> 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<DNSPacket> 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<<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;);
   }
 
 
@@ -854,39 +860,40 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> 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<DNSPacket> 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<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()) {
@@ -960,19 +967,19 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> 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<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()) {
@@ -1014,7 +1021,7 @@ int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> q, int ou
   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); 
@@ -1135,7 +1142,11 @@ int TCPNameserver::doIXFR(shared_ptr<DNSPacket> q, int outsock)
     // 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;
index f31d6bc202cc27ff20e3ff3bd9b07079b0d0a244..540ec6f1c9104a56a3d59444fff082134da61347 100644 (file)
@@ -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)
   {
index fe97528c4e22ec97b0275d62ceb8acc58e078ce1..fdf1ad68a96165ef0d3b2ead1474165a6219a36f 100644 (file)
@@ -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<<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;
@@ -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<DNSResourceRecord> 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<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;
     }
@@ -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<DNSResourceRecord> &rrs)
+int UeberBackend::cacheHas(const Question &q, vector<DNSZoneRecord> &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<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;
 
@@ -491,9 +491,9 @@ void UeberBackend::addCache(const Question &q, const vector<DNSResourceRecord> &
     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<DomainInfo> *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 "<<qtype.getName()<<" record" << endl);
   bool isMore=false;
index ab1eb2dac51c98fc80ce95d7bf7dcc94c82e79d6..3b11672881010b8064a73938c3bfbf9bd4ab45d8 100644 (file)
@@ -79,7 +79,7 @@ public:
   class handle
   {
   public:
-    bool get(DNSResourceRecord &r);
+    bool get(DNSZoneRecord &dr);
     handle();
     ~handle();
 
@@ -108,6 +108,7 @@ public:
   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> &);
@@ -139,8 +140,8 @@ public:
 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;
@@ -162,9 +163,9 @@ private:
   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);
   
 };
 
index 424c55a5aa9283bae02e7767f343f071b6fc7a0f..5fb36047cbe0dd8d08e28b4d3a3c8fb02c9230b8 100644 (file)
@@ -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))<<", "<<ttl<<", "<<prio<<", '"<<(disabled ? 't': 'f') <<
       "' from domains where name="<<toLower(sqlstr(zname))<<";\n";