From: Christian Hofstaedtler Date: Thu, 26 Feb 2015 22:30:31 +0000 (+0100) Subject: Change SOA-EDIT-API to work like SOA-EDIT-DNSUPDATE X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~98^2~39^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6448d959c9c83b0b985d460f54102878792459b;p=thirdparty%2Fpdns.git Change SOA-EDIT-API to work like SOA-EDIT-DNSUPDATE The SOA-EDIT-DNSUPDATE behaviour makes for a better ruleset for incremental updates, like they are done via the API. Also SOA-EDIT-API now defaults to DEFAULT, if it's not given at all during zone creation (over the API). --- diff --git a/docs/markdown/httpapi/api_spec.md b/docs/markdown/httpapi/api_spec.md index c33bcb82e5..0c352384e6 100644 --- a/docs/markdown/httpapi/api_spec.md +++ b/docs/markdown/httpapi/api_spec.md @@ -336,7 +336,8 @@ zone_collection * `soa_edit_api` MAY be set. If it is set, on changes to the contents of a zone made through the API, the SOA record will be edited according to - the SOA-EDIT-API rules. (Which are the same as the SOA-EDIT rules.) + the SOA-EDIT-API rules. (Which are the same as the SOA-EDIT-DNSUPDATE rules.) + If not set at all during zone creation, defaults to `DEFAULT`. **Note**: Authoritative only. * `account` MAY be set. It's value is defined by local policy. diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index 9031eb946a..c1786e5f42 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -167,8 +167,12 @@ private: }; class DNSPacket; -uint32_t calculateEditSOA(SOAData sd, const string& kind); uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq); +// for SOA-EDIT +uint32_t calculateEditSOA(SOAData sd, const string& kind); bool editSOA(DNSSECKeeper& dk, const string& qname, DNSPacket* dp); bool editSOARecord(DNSResourceRecord& rr, const string& kind); +// 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); #endif diff --git a/pdns/rfc2136handler.cc b/pdns/rfc2136handler.cc index 4b254378e1..6be9c4ec9a 100644 --- a/pdns/rfc2136handler.cc +++ b/pdns/rfc2136handler.cc @@ -961,39 +961,14 @@ void PacketHandler::increaseSerial(const string &msgPrefix, const DomainInfo *di vector soaEditSetting; B.getDomainMetadata(di->zone, "SOA-EDIT", soaEditSetting); if (soaEditSetting.empty()) { - L<zone <<"\". Using DEFAULT for SOA-EDIT-DNSUPDATE"< rrset; diff --git a/pdns/serialtweaker.cc b/pdns/serialtweaker.cc index c6c4a1775b..b170f0984b 100644 --- a/pdns/serialtweaker.cc +++ b/pdns/serialtweaker.cc @@ -97,3 +97,50 @@ uint32_t calculateEditSOA(SOAData sd, const string& kind) { } return sd.serial; } + +// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. +uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) { + // 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; + } + return new_serial; + } + else if (pdns_iequals(increaseKind, "SOA-EDIT")) { + return calculateEditSOA(sd, editKind); + } + } + + if (pdns_iequals(increaseKind, "INCREASE")) { + return sd.serial + 1; + } + else if (pdns_iequals(increaseKind, "EPOCH")) { + return time(0); + } + + // DEFAULT case + time_t now = time(0); + struct tm tm; + localtime_r(&now, &tm); + 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 = atol(newdate.c_str()); + if (new_serial <= sd.serial) { + new_serial = sd.serial + 1; + } + return new_serial; +} + +bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) { + if (increaseKind.empty()) + return false; + + SOAData sd; + fillSOAData(rr.content, sd); + sd.serial = calculateIncreaseSOA(sd, increaseKind, editKind); + rr.content = serializeSOAData(sd); + return true; +} diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 7b35a91b64..9fe2272bd4 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -626,8 +626,15 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { throw ApiException("Nameservers list must be given (but can be empty if NS records are supplied)"); string soa_edit_api_kind; - if (document["soa_edit_api"].IsString()) + if (document["soa_edit_api"].IsString()) { soa_edit_api_kind = document["soa_edit_api"].GetString(); + } + else { + soa_edit_api_kind = "DEFAULT"; + } + string soa_edit_kind; + if (document["soa_edit"].IsString()) + soa_edit_kind = document["soa_edit"].GetString(); // if records/comments are given, load and check them bool have_soa = false; @@ -651,7 +658,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { if (rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, zonename)) { have_soa = true; - editSOARecord(rr, soa_edit_api_kind); + increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); } } @@ -680,7 +687,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { rr.content = serializeSOAData(sd); rr.qtype = "SOA"; - editSOARecord(rr, soa_edit_api_kind); + increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); new_records.push_back(rr); } @@ -948,7 +955,9 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { try { string soa_edit_api_kind; + string soa_edit_kind; di.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soa_edit_api_kind); + di.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soa_edit_kind); bool soa_edit_done = false; for(SizeType rrsetIdx = 0; rrsetIdx < rrsets.Size(); ++rrsetIdx) { @@ -982,7 +991,7 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" "+rr.content+": Record wrongly bundled with RRset " + qname + "/" + qtype.getName()); if (rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, zonename)) { - soa_edit_done = editSOARecord(rr, soa_edit_api_kind); + soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); } } @@ -1025,7 +1034,7 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { rr.domain_id = di.id; rr.auth = 1; rr.ttl = sd.ttl; - editSOARecord(rr, soa_edit_api_kind); + increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); if (!di.backend->replaceRRSet(di.id, rr.qname, rr.qtype, vector(1, rr))) { throw ApiException("Hosting backend does not support editing records.");