Hi Peter,
On Thu, Oct 13, 2011 at 12:56 PM, Peter van Dijk
<[email protected]> wrote:
> Hello Zsolt,
>
> On Oct 1, 2011, at 22:03 , Zsolt Dollenstein wrote:
>
>> I have recently started using powerdns (props for a great piece of
>> software!), however I bumped into what looks like issue #301 on your
>> bugtracker (http://wiki.powerdns.com/trac/ticket/301). It has two
>> patches attached to it but it looks like they have never been merged
>> in. Are there any problems with them? If so, I'm willing to rewrite &
>> test them so they can be included in future versions.
>
> I have looked at both options in the ticket:
> 1. add a change_date to the query and do a minor patch
> 2. add a max(..) query to getSOA
>
> The first option would break existing setups if they have custom queries.
> This is of course a matter of documentation but I try to be careful in
> changing behaviour.
>
> The second option will not break existing setups (but if someone has a custom
> database schema, he still won't get auto serial with it - which is fine).
> However, the verbatim copying of code from dnsbackend to gsqlbackend looks a
> bit verbose.
>
> If you could look into making sure the second patch is not a dumb verbatim
> copy of code from dnsbackend, I'd be happy to consider it.
>
> My apologies for taking so long to reply.
I restructured the second patch and attached it (it's against HEAD).
Let me know what you think.
Thanks,
Zsolt
Index: pdns/dnsbackend.hh
===================================================================
--- pdns/dnsbackend.hh (revision 2283)
+++ pdns/dnsbackend.hh (working copy)
@@ -119,6 +119,9 @@
//! fills the soadata struct with the SOA details. Returns false if there is no SOA.
virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
+ //! Calculates a SOA serial for the zone and stores it in the third argument.
+ virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
+
virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) { return false;}
Index: pdns/dnsbackend.cc
===================================================================
--- pdns/dnsbackend.cc (revision 2283)
+++ pdns/dnsbackend.cc (working copy)
@@ -234,24 +234,14 @@
if(!sd.serial) { // magic time!
DLOG(L<<Logger::Warning<<"Doing soa serialnumber autocalculation for "<<rr.qname<<endl);
- // we do this by listing the domain and taking the maximum last modified timestamp
-
- DNSResourceRecord i;
- time_t newest=0;
-
- if(!(this->list(domain, sd.domain_id))) {
- DLOG(L<<Logger::Warning<<"Backend error trying to determine magic serial number of zone '"<<domain<<"'"<<endl);
- return false;
+ time_t serial;
+ if (calculateSOASerial(domain, sd, serial)) {
+ sd.serial = serial;
+ DLOG(L<<"autocalculated soa serialnumber for "<<rr.qname<<" is "<<newest<<endl);
+ } else {
+ DLOG(L<<"soa serialnumber calculation failed for "<<rr.qname<<endl);
}
-
- while(this->get(i)) {
- if(i.last_modified>newest)
- newest=i.last_modified;
- }
- sd.serial=newest; // +arg().asNum("soa-serial-offset");
- DLOG(L<<"autocalculated soa serialnumber for "<<rr.qname<<" is "<<newest<<endl);
-
}
sd.db=this;
return true;
@@ -270,3 +260,36 @@
after=dotConcat(labelReverse(after), zonename);
return ret;
}
+
+/**
+ * Calculates a SOA serial for the zone and stores it in the third
+ * argument. Returns false if calculation is not possible for some
+ * reason (in this case, the third argument is not inspected). If it
+ * returns true, the value returned in the third argument will be set
+ * as the SOA serial.
+ *
+ * \param domain The name of the domain
+ * \param sd Information about the SOA record already available
+ * \param serial Output parameter. Only inspected when we return true
+ */
+bool DNSBackend::calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial)
+{
+ // we do this by listing the domain and taking the maximum last modified timestamp
+
+ DNSResourceRecord i;
+ time_t newest=0;
+
+ if(!(this->list(domain, sd.domain_id))) {
+ DLOG(L<<Logger::Warning<<"Backend error trying to determine magic serial number of zone '"<<domain<<"'"<<endl);
+ return false;
+ }
+
+ while(this->get(i)) {
+ if(i.last_modified>newest)
+ newest=i.last_modified;
+ }
+
+ serial=newest; // +arg().asNum("soa-serial-offset");
+
+ return true;
+}
Index: pdns/backends/gsql/gsqlbackend.cc
===================================================================
--- pdns/backends/gsql/gsqlbackend.cc (revision 2283)
+++ pdns/backends/gsql/gsqlbackend.cc (working copy)
@@ -267,6 +267,7 @@
d_InsertRecordQuery=getArg("insert-record-query"+authswitch);
d_UpdateSerialOfZoneQuery=getArg("update-serial-query");
d_UpdateLastCheckofZoneQuery=getArg("update-lastcheck-query");
+ d_ZoneLastChangeQuery=getArg("zone-lastchange-query");
d_InfoOfAllMasterDomainsQuery=getArg("info-all-master-query");
d_DeleteZoneQuery=getArg("delete-zone-query");
d_CheckACLQuery=getArg("check-acl-query");
@@ -776,3 +777,31 @@
return true;
}
+bool GSQLBackend::calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial)
+{
+ if (d_ZoneLastChangeQuery.empty()) {
+ // query not set => fall back to default impl
+ return DNSBackend::calculateSOASerial(domain, sd, serial);
+ }
+
+ char output[1024];
+
+ snprintf(output, sizeof(output)-1,
+ d_ZoneLastChangeQuery.c_str(),
+ sd.domain_id);
+
+ try {
+ d_db->doQuery(output, d_result);
+ }
+ catch (const SSqlException& e) {
+ DLOG(L<<"GSQLBackend unable to calculate SOA serial: " << e.txtReason()<<endl);
+ return false;
+ }
+
+ if (not d_result.empty()) {
+ serial = atol(d_result[0][0].c_str());
+ return true;
+ }
+
+ return false;
+}
Index: pdns/backends/gsql/gsqlbackend.hh
===================================================================
--- pdns/backends/gsql/gsqlbackend.hh (revision 2283)
+++ pdns/backends/gsql/gsqlbackend.hh (working copy)
@@ -43,6 +43,8 @@
bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth);
virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth);
+ virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
+
int addDomainKey(const string& name, const KeyData& key);
bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
@@ -81,6 +83,7 @@
string d_UpdateLastCheckofZoneQuery;
string d_InfoOfAllMasterDomainsQuery;
string d_DeleteZoneQuery;
+ string d_ZoneLastChangeQuery;
string d_CheckACLQuery;
string d_beforeOrderQuery;
Index: modules/gmysqlbackend/gmysqlbackend.cc
===================================================================
--- modules/gmysqlbackend/gmysqlbackend.cc (revision 2283)
+++ modules/gmysqlbackend/gmysqlbackend.cc (working copy)
@@ -94,6 +94,7 @@
declare(suffix,"update-serial-query","", "update domains set notified_serial=%d where id=%d");
declare(suffix,"update-lastcheck-query","", "update domains set last_check=%d where id=%d");
+ declare(suffix,"zone-lastchange-query", "", "select max(change_date) from records where domain_id=%d");
declare(suffix,"info-all-master-query","", "select id,name,master,last_check,notified_serial,type from domains where type='MASTER'");
declare(suffix,"delete-zone-query","", "delete from records where domain_id=%d");
declare(suffix,"check-acl-query","", "select value from acls where acl_type='%s' and acl_key='%s'");
Index: modules/gsqlite3backend/gsqlite3backend.cc
===================================================================
--- modules/gsqlite3backend/gsqlite3backend.cc (revision 2283)
+++ modules/gsqlite3backend/gsqlite3backend.cc (working copy)
@@ -100,6 +100,7 @@
declare( suffix, "update-serial-query", "", "update domains set notified_serial=%d where id=%d");
declare( suffix, "update-lastcheck-query", "", "update domains set last_check=%d where id=%d");
+ declare (suffix, "zone-lastchange-query", "", "select max(change_date) from records where domain_id=%d");
declare( suffix, "info-all-master-query", "", "select id,name,master,last_check,notified_serial,type from domains where type='MASTER'");
declare( suffix, "delete-zone-query", "", "delete from records where domain_id=%d");
declare( suffix, "check-acl-query","", "select value from acls where acl_type='%s' and acl_key='%s'");
Index: modules/gpgsqlbackend/gpgsqlbackend.cc
===================================================================
--- modules/gpgsqlbackend/gpgsqlbackend.cc (revision 2283)
+++ modules/gpgsqlbackend/gpgsqlbackend.cc (working copy)
@@ -91,6 +91,7 @@
declare(suffix,"update-serial-query","", "update domains set notified_serial=%d where id=%d");
declare(suffix,"update-lastcheck-query","", "update domains set last_check=%d where id=%d");
+ declare(suffix,"zone-lastchange-query", "", "select max(change_date) from records where domain_id=%d");
declare(suffix,"info-all-master-query","", "select id,name,master,last_check,notified_serial,type from domains where type='MASTER'");
declare(suffix,"delete-zone-query","", "delete from records where domain_id=%d");
declare(suffix,"check-acl-query","", "select value from acls where acl_type='%s' and acl_key='%s'");
_______________________________________________
Pdns-dev mailing list
[email protected]
http://mailman.powerdns.com/mailman/listinfo/pdns-dev