]> granicus.if.org Git - pdns/commitdiff
Add rfc2136 implementation basics
authorRuben d'Arco <cyclops@prof-x.net>
Mon, 3 Dec 2012 05:13:01 +0000 (06:13 +0100)
committermind04 <mind04@monshouwer.org>
Fri, 12 Jul 2013 15:10:10 +0000 (17:10 +0200)
This commits adds a lot of files and code to implement rfc2136. The code was taken from a different branch and only added again.
There are still things missing.
Primary changes:
- Add rfc2136 methods to rfc2136handler.cc file and include file in build
- Add constructor for DNSResourceRecord to take a DNSRecord
- Add setContent and getZoneRepresentation to DNSResourceRecord for easy compare and set of content
  This removes the need to consantly check if it's an MX record, etc.
- Add compare operator to DNSResourceRecord to easily compare DNSResourceRecords
- Move SOA-EDIT calculation/changes to seperate method for re-use in rfc2136 code
- Move rfc1982LessThan to misc.hh for reuse
- Added code to handle update packets in questionOrRecurse

pdns/Makefile.am
pdns/dns.hh
pdns/dnsrecords.cc
pdns/dnsseckeeper.hh
pdns/misc.hh
pdns/packethandler.cc
pdns/packethandler.hh
pdns/slavecommunicator.cc

index a9157bb1f9e9557b9d1f79104a691efa42083253..d5b614c50f768b1cf9768a293766ae56065f55ee 100644 (file)
@@ -66,7 +66,7 @@ randomhelper.cc namespaces.hh nsecrecords.cc base32.cc dbdnsseckeeper.cc dnsseci
 dnsseckeeper.hh dnssecinfra.hh base32.hh dns.cc dnssecsigner.cc polarrsakeyinfra.cc \
 md5.hh signingpipe.cc signingpipe.hh dnslabeltext.cc lua-pdns.cc lua-auth.cc lua-auth.hh serialtweaker.cc \
 ednssubnet.cc ednssubnet.hh cachecleaner.hh json.cc json.hh \
-version.hh version.cc
+version.hh version.cc rfc2136handler.cc
 
 #
 pdns_server_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@  $(BOOST_SERIALIZATION_LDFLAGS) -rdynamic 
index 37932465ec787fab73cc10eb95cf4f13893f8463..1de3c203b7a8b2988c8da1d577e374092956edd2 100644 (file)
@@ -71,8 +71,12 @@ class DNSResourceRecord
 {
 public:
   DNSResourceRecord() : qclass(1), priority(0), signttl(0), last_modified(0), d_place(ANSWER), auth(1), scopeMask(0) {};
+  DNSResourceRecord(const struct DNSRecord&);
   ~DNSResourceRecord(){};
 
+  void setContent(const string& content);
+  string getZoneRepresentation();
+
   // data
   
   QType qtype; //!< qtype of this record, ie A, CNAME, MX etc
@@ -106,6 +110,8 @@ public:
     ar & d_place;
     ar & auth;
   }
+  
+  bool operator==(const DNSResourceRecord& rhs);
 
   bool operator<(const DNSResourceRecord &b) const
   {
index e862e101ce39927f111589854e8b5c30376d5af7..35d863a9ee871ba270c361dbe4ca6342ae89717a 100644 (file)
 #include "dnsrecords.hh"
 #include <boost/foreach.hpp>
 
+void DNSResourceRecord::setContent(const string &cont) {
+  content = cont;
+  if(!content.empty() && (qtype==QType::MX || qtype==QType::NS || qtype==QType::CNAME))
+    boost::erase_tail(content, 1);
+
+  if(qtype.getCode() == QType::MX) {
+    vector<string> parts;
+    stringtok(parts, content);
+    priority = atoi(parts[0].c_str());
+    if(parts.size() > 1)
+      content=parts[1];
+    else
+      content=".";
+  } else if(qtype.getCode() == QType::SRV) {
+    priority = atoi(content.c_str());
+    vector<pair<string::size_type, string::size_type> > fields;
+    vstringtok(fields, content, " ");
+    if(fields.size()==4) {
+      content=string(content.c_str() + fields[1].first, fields[3].second - fields[1].first);
+      content=stripDot(content);
+    }
+  }
+}
+
+string DNSResourceRecord::getZoneRepresentation() {
+  ostringstream ret;
+  switch(qtype.getCode()) {
+    case QType::SRV:
+    case QType::MX:
+      ret<<priority;
+      ret<<" "<<content<<".";
+    break;
+    case QType::CNAME:
+    case QType::NS:
+      ret<<content<<".";
+    break;
+    default:
+      ret<<content;
+    break;
+  }
+  return ret.str();
+}
+
+bool DNSResourceRecord::operator==(const DNSResourceRecord& rhs)
+{
+  string lcontent=toLower(content);
+  string rcontent=toLower(rhs.content);
+   
+  string llabel=toLower(qname);
+  string rlabel=toLower(rhs.qname);
+    
+  return 
+    tie(llabel, qtype, lcontent, ttl, priority) ==
+    tie(rlabel, rhs.qtype, rcontent, rhs.ttl, rhs.priority);
+}
+
+
+
+DNSResourceRecord::DNSResourceRecord(const DNSRecord &p) {
+  auth=true;
+  qname = p.d_label;
+  if(!qname.empty())
+    boost::erase_tail(qname, 1); // strip .
+  
+  qtype = p.d_type;
+  ttl = p.d_ttl;
+  priority=0;
+  setContent(p.d_content->getZoneRepresentation());
+}
+
+
 boilerplate_conv(A, ns_t_a, conv.xfrIP(d_ip));
 
 ARecordContent::ARecordContent(uint32_t ip) : DNSRecordContent(ns_t_a)
index f290d4c10218f17c3b5ec1b5d9900cd6f41241c2..827993515b081c9002c229b779e8d66b7fd68eae 100644 (file)
@@ -165,5 +165,5 @@ private:
 class DNSPacket;
 uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
 bool editSOA(DNSSECKeeper& dk, const string& qname, DNSPacket* dp);
-uint32_t calculateEditSoa(SOAData sd, const string& kind);
+uint32_t calculateEditSOA(SOAData sd, const string& kind);
 #endif
index 00a0e1caf3c50554fb2aa50e6ef0a741269e56ac..2ea637477feb5559117e7d5be42f08967598e18c 100644 (file)
@@ -126,6 +126,11 @@ stringtok (Container &container, string const &in,
   }
 }
 
+template<typename T> bool rfc1982LessThan(T a, T b)
+{
+  return ((signed)(a - b)) < 0;
+}
+
 // fills container with ranges, so {posbegin,posend}
 template <typename Container>
 void
index ad2a54f8dcc37bbb7020ee12860d1388e822d6e4..d44eea65212e7b124736ce00e3cb2d0b440b4483 100644 (file)
@@ -1122,7 +1122,11 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
       r=p->replyPacket();  // generate an empty reply packet
       if(d_logDNSDetails)
         L<<Logger::Error<<"Received a TSIG signed message with a non-validating key"<<endl;
-      r->setRcode(RCode::NotAuth);
+      // RFC3007 describes that a non-secure message should be sending Refused for DNS Updates
+      if (p->d.opcode == Opcode::Update)
+        r->setRcode(RCode::Refused); 
+      else 
+        r->setRcode(RCode::NotAuth);
       return r;
     }
     p->setTSIGDetails(trc, keyname, secret, trc.d_mac); // this will get copied by replyPacket()
@@ -1144,10 +1148,15 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
     }
     if(p->d.opcode) { // non-zero opcode (again thanks RA!)
       if(p->d.opcode==Opcode::Update) {
-        if(::arg().mustDo("log-failed-updates"))
-          L<<Logger::Notice<<"Received an UPDATE opcode from "<<p->getRemote()<<" for "<<p->qdomain<<", sending NOTIMP"<<endl;
-        r->setRcode(RCode::NotImp); // notimp;
-        return r; 
+        //S.inc("rfc2136-queries");
+        int res=processUpdate(p);
+        //if (res == RCode::Refused)
+        //  S.inc("rfc2136-refused");
+        //else if (res != RCode::ServFail)
+        //  S.inc("rfc2136-answers");
+        r->setRcode(res);
+        r->setOpcode(Opcode::Update);
+        return r;
       }
       else if(p->d.opcode==Opcode::Notify) {
         int res=processNotify(p);
index cb5be884c60e496e8c7b7c4f03f46f7f14556d07..3a1cff00ee845d327517ac8a50a6f1a2a1c6a8b6 100644 (file)
@@ -103,7 +103,11 @@ private:
   void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
   void emitNSEC(const std::string& before, const std::string& after, const std::string& toNSEC, const SOAData& sd, DNSPacket *r, int mode);
   void emitNSEC3(const NSEC3PARAMRecordContent &ns3rc, const SOAData& sd, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode);
-  
+  int processUpdate(DNSPacket *p);
+  uint16_t performUpdate(const string &msgPrefix, const DNSRecord *rr, DomainInfo *di, bool narrow, bool haveNSEC3, const NSEC3PARAMRecordContent *ns3pr, bool *updatedSerial);
+  int checkUpdatePrescan(const DNSRecord *rr);
+  int checkUpdatePrerequisites(const DNSRecord *rr, DomainInfo *di);
+  void increaseSerial(const string &msgPrefix, const DomainInfo& di);
 
   void synthesiseRRSIGs(DNSPacket* p, DNSPacket* r);
   void makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd);
index 9d9433411df5b12a839d656d281475b63710a7b3..6cd1236a1ab62a59df652ac774931505857438ba 100644 (file)
 #include <boost/scoped_ptr.hpp>
 using boost::scoped_ptr;
 
-template<typename T> bool rfc1982LessThan(T a, T b)
-{
-  return ((signed)(a - b)) < 0;
-}
 
 void CommunicatorClass::addSuckRequest(const string &domain, const string &master)
 {