From: Ruben d'Arco Date: Mon, 3 Dec 2012 05:13:01 +0000 (+0100) Subject: Add rfc2136 implementation basics X-Git-Tag: rec-3.6.0-rc1~556^2~3^2~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7a69a4c1c9cce6814780ca2d6cf2ecf81005a1b;p=thirdparty%2Fpdns.git Add rfc2136 implementation basics 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 --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index a9157bb1f9..d5b614c50f 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -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 diff --git a/pdns/dns.hh b/pdns/dns.hh index 37932465ec..1de3c203b7 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -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 { diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index e862e101ce..35d863a9ee 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -20,6 +20,77 @@ #include "dnsrecords.hh" #include +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 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 > 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<getZoneRepresentation()); +} + + boilerplate_conv(A, ns_t_a, conv.xfrIP(d_ip)); ARecordContent::ARecordContent(uint32_t ip) : DNSRecordContent(ns_t_a) diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index f290d4c102..827993515b 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -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 diff --git a/pdns/misc.hh b/pdns/misc.hh index 00a0e1caf3..2ea637477f 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -126,6 +126,11 @@ stringtok (Container &container, string const &in, } } +template bool rfc1982LessThan(T a, T b) +{ + return ((signed)(a - b)) < 0; +} + // fills container with ranges, so {posbegin,posend} template void diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index ad2a54f8dc..d44eea6521 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -1122,7 +1122,11 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse) r=p->replyPacket(); // generate an empty reply packet if(d_logDNSDetails) L<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<getRemote()<<" for "<qdomain<<", sending NOTIMP"<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); diff --git a/pdns/packethandler.hh b/pdns/packethandler.hh index cb5be884c6..3a1cff00ee 100644 --- a/pdns/packethandler.hh +++ b/pdns/packethandler.hh @@ -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); diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index 9d9433411d..6cd1236a1a 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -43,10 +43,6 @@ #include using boost::scoped_ptr; -template bool rfc1982LessThan(T a, T b) -{ - return ((signed)(a - b)) < 0; -} void CommunicatorClass::addSuckRequest(const string &domain, const string &master) {