Hi!
First version of a patch which does:
- add next_check to domains table
Postgresql:
ALTER TABLE domains ADD COLUMN next_check INTEGER DEFAULT 0;
CREATE INDEX nextchecktype_index ON domains (next_check,type);
- instead of calculation refresh-expiration every slave-batch cycle
calculate the next_check in advance and query only for SLAVE zones where
next_check is older than NOW().
- added "refresh" and "retry" values to DomainInfo struct.
- extended setFresh() function to set also next_check column
- modified gsql backend to set next_check on UPDATEs
- bind backend just ignores next_check
- on transfer failure UPDATE next_check with 'retry' value (there are
some scenarios where the retry value is not used, e.g. if SOA query
fails, there is no UPDATE to domain tables)
- tested with PowerDNS trunk version (not in production yet)
- modified PostgreSQL SQL queries
Probably the SQL queries for other databases need to be extended as
well, using the database's support for epoch calculation of NOW().
Maybe someone wants to review the patch and give some comments.
regards
Klaus
Index: pdns/dnsbackend.hh
===================================================================
--- pdns/dnsbackend.hh (revision 2265)
+++ pdns/dnsbackend.hh (working copy)
@@ -50,6 +50,8 @@
uint32_t notified_serial;
uint32_t serial;
time_t last_check;
+ uint32_t refresh;
+ uint32_t retry;
enum {Master,Slave,Native} kind;
DNSBackend *backend;
@@ -187,7 +189,7 @@
}
//! Called by PowerDNS to inform a backend that a domain has been checked
for freshness
- virtual void setFresh(uint32_t domain_id)
+ virtual void setFresh(uint32_t domain_id, uint32_t refresh)
{
}
Index: pdns/slavecommunicator.cc
===================================================================
--- pdns/slavecommunicator.cc (revision 2266)
+++ pdns/slavecommunicator.cc (working copy)
@@ -70,7 +70,8 @@
void CommunicatorClass::suck(const string &domain,const string &remote)
{
L<<Logger::Error<<"Initiating transfer of '"<<domain<<"' from remote
'"<<remote<<"'"<<endl;
- uint32_t domain_id;
+ uint32_t domain_id=0;
+ bool domain_id_isvalid=false; // 0 might be a valid domain_id
PacketHandler P; // fresh UeberBackend
DomainInfo di;
@@ -102,6 +103,7 @@
return;
}
domain_id=di.id;
+ domain_id_isvalid=true;
Resolver::res_t recs;
set<string> nsset, qnames;
@@ -155,6 +157,11 @@
nsset.insert(i->qname);
if(i->qtype.getCode() != QType::RRSIG) // this excludes us hashing
RRSIGs for NSEC(3)
qnames.insert(i->qname);
+ if(i->qtype.getCode() == QType::SOA) {
+ SOAData sdata;
+ fillSOAData(i->content, sdata);
+ di.refresh=sdata.refresh;
+ }
i->domain_id=domain_id;
#if 0
@@ -200,7 +207,7 @@
}
di.backend->commitTransaction();
- di.backend->setFresh(domain_id);
+ di.backend->setFresh(domain_id,di.refresh);
L<<Logger::Error<<"AXFR done for '"<<domain<<"', zone committed"<<endl;
if(::arg().mustDo("slave-renotify"))
notifyDomain(domain);
@@ -211,6 +218,8 @@
L<<Logger::Error<<"Aborting possible open transaction for domain
'"<<domain<<"' AXFR"<<endl;
di.backend->abortTransaction();
}
+ if(domain_id_isvalid)
+ di.backend->setFresh(domain_id,di.retry);
}
catch(MOADNSException &re) {
L<<Logger::Error<<"Unable to parse record during incoming AXFR of
'"+domain+"' (MOADNSException): "<<re.what()<<endl;
@@ -218,6 +227,8 @@
L<<Logger::Error<<"Aborting possible open transaction for domain
'"<<domain<<"' AXFR"<<endl;
di.backend->abortTransaction();
}
+ if(domain_id_isvalid)
+ di.backend->setFresh(domain_id,di.retry);
}
catch(std::exception &re) {
L<<Logger::Error<<"Unable to parse record during incoming AXFR of
'"+domain+"' (std::exception): "<<re.what()<<endl;
@@ -225,6 +236,8 @@
L<<Logger::Error<<"Aborting possible open transaction for domain
'"<<domain<<"' AXFR"<<endl;
di.backend->abortTransaction();
}
+ if(domain_id_isvalid)
+ di.backend->setFresh(domain_id,di.retry);
}
catch(ResolverException &re) {
L<<Logger::Error<<"Unable to AXFR zone '"+domain+"' from remote
'"<<remote<<"' (resolver): "<<re.reason<<endl;
@@ -232,6 +245,8 @@
L<<Logger::Error<<"Aborting possible open transaction for domain
'"<<domain<<"' AXFR"<<endl;
di.backend->abortTransaction();
}
+ if(domain_id_isvalid)
+ di.backend->setFresh(domain_id,di.retry);
}
}
namespace {
@@ -402,12 +417,12 @@
if(rfc1982LessThan(theirserial, ourserial)) {
L<<Logger::Error<<"Domain "<<di.zone<<" more recent than master, our
serial " << ourserial << " > their serial "<< theirserial << endl;
- di.backend->setFresh(di.id);
+ di.backend->setFresh(di.id,di.refresh);
}
else if(theirserial == ourserial) {
if(!dk.isPresigned(di.zone)) {
L<<Logger::Warning<<"Domain "<< di.zone<<" is fresh (not presigned, no
RRSIG check)"<<endl;
- di.backend->setFresh(di.id);
+ di.backend->setFresh(di.id,di.refresh);
}
else {
B->lookup(QType(QType::RRSIG), di.zone); // can't use DK before we are
done with this lookup!
@@ -422,7 +437,7 @@
}
if(maxInception == ssr.d_freshness[di.id].theirInception && maxExpire
== ssr.d_freshness[di.id].theirExpire) {
L<<Logger::Warning<<"Domain "<< di.zone<<" is fresh and apex RRSIGs
match"<<endl;
- di.backend->setFresh(di.id);
+ di.backend->setFresh(di.id, di.refresh);
}
else {
L<<Logger::Warning<<"Domain "<< di.zone<<" is fresh, but RRSIGS
differ, so DNSSEC stale"<<endl;
Index: pdns/backends/gsql/gsqlbackend.cc
===================================================================
--- pdns/backends/gsql/gsqlbackend.cc (revision 2265)
+++ pdns/backends/gsql/gsqlbackend.cc (working copy)
@@ -56,11 +56,12 @@
}
}
-void GSQLBackend::setFresh(uint32_t domain_id)
+void GSQLBackend::setFresh(uint32_t domain_id, uint32_t refresh)
{
char output[1024];
snprintf(output,sizeof(output)-1,d_UpdateLastCheckofZoneQuery.c_str(),
time(0),
+ time(0)+refresh,
domain_id);
try {
@@ -130,12 +131,17 @@
string type=d_result[0][5];
if(pdns_iequals(type,"SLAVE")) {
di.serial=0;
+ di.refresh=0;
+ di.retry=0;
try {
SOAData sd;
if(!getSOA(domain,sd))
L<<Logger::Notice<<"No serial for '"<<domain<<"' found - zone is
missing?"<<endl;
- else
+ else {
di.serial=sd.serial;
+ di.refresh=sd.refresh;
+ di.retry=sd.retry;
+ }
}
catch(AhuException &ae){
L<<Logger::Error<<"Error retrieving serial for '"<<domain<<"':
"<<ae.reason<<endl;
@@ -166,25 +172,22 @@
int numanswers=d_result.size();
for(int n=0;n<numanswers;++n) { // id,name,master,last_check
DomainInfo sd;
+ SOAData sdata;
+ sdata.serial=0;
+ sdata.refresh=0;
+ sdata.retry=0;
sd.id=atol(d_result[n][0].c_str());
sd.zone=d_result[n][1];
stringtok(sd.masters, d_result[n][2], ", \t");
sd.last_check=atol(d_result[n][3].c_str());
sd.backend=this;
sd.kind=DomainInfo::Slave;
- allSlaves.push_back(sd);
+ getSOA(sd.zone,sdata);
+ sd.serial=sdata.serial;
+ sd.refresh=sdata.refresh;
+ sd.retry=sdata.retry;
+ unfreshDomains->push_back(sd);
}
-
- for(vector<DomainInfo>::iterator i=allSlaves.begin();i!=allSlaves.end();++i)
{
- SOAData sdata;
- sdata.serial=0;
- sdata.refresh=0;
- getSOA(i->zone,sdata);
- if((time_t)(i->last_check+sdata.refresh) < time(0)) {
- i->serial=sdata.serial;
- unfreshDomains->push_back(*i);
- }
- }
}
void GSQLBackend::getUpdatedMasters(vector<DomainInfo> *updatedDomains)
Index: pdns/backends/gsql/gsqlbackend.hh
===================================================================
--- pdns/backends/gsql/gsqlbackend.hh (revision 2265)
+++ pdns/backends/gsql/gsqlbackend.hh (working copy)
@@ -33,7 +33,7 @@
bool feedRecord(const DNSResourceRecord &r);
bool createSlaveDomain(const string &ip, const string &domain, const string
&account);
bool superMasterBackend(const string &ip, const string &domain, const
vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
- void setFresh(uint32_t domain_id);
+ void setFresh(uint32_t domain_id, uint32_t refresh);
bool checkACL(const string &acl_type, const string &key, const string
&value);
void getUnfreshSlaveInfos(vector<DomainInfo> *domains);
void getUpdatedMasters(vector<DomainInfo> *updatedDomains);
Index: pdns/backends/bind/bindbackend2.hh
===================================================================
--- pdns/backends/bind/bindbackend2.hh (revision 2265)
+++ pdns/backends/bind/bindbackend2.hh (working copy)
@@ -135,7 +135,7 @@
static DNSBackend *maker();
static pthread_mutex_t s_startup_lock;
- void setFresh(uint32_t domain_id);
+ void setFresh(uint32_t domain_id, uint32_t refresh);
void setNotified(uint32_t id, uint32_t serial);
bool startTransaction(const string &qname, int id);
// bool Bind2Backend::stopTransaction(const string &qname, int id);
Index: pdns/backends/bind/bindbackend2.cc
===================================================================
--- pdns/backends/bind/bindbackend2.cc (revision 2265)
+++ pdns/backends/bind/bindbackend2.cc (working copy)
@@ -137,7 +137,7 @@
s_state->id_zone_map[id].d_lastnotified=serial;
}
-void Bind2Backend::setFresh(uint32_t domain_id)
+void Bind2Backend::setFresh(uint32_t domain_id, uint32_t refresh)
{
Lock l(&s_state_lock);
s_state->id_zone_map[domain_id].d_lastcheck=time(0);
@@ -335,12 +335,16 @@
di.backend=this;
di.kind=i->second.d_masters.empty() ? DomainInfo::Master :
DomainInfo::Slave;
di.serial=0;
+ di.refresh=0;
+ di.retry=0;
try {
SOAData sd;
sd.serial=0;
getSOA(i->second.d_name,sd); // we might not *have* a SOA yet
di.serial=sd.serial;
+ di.refresh=sd.refresh;
+ di.retry=sd.retry;
}
catch(...){}
Index: modules/gpgsqlbackend/gpgsqlbackend.cc
===================================================================
--- modules/gpgsqlbackend/gpgsqlbackend.cc (revision 2265)
+++ modules/gpgsqlbackend/gpgsqlbackend.cc (working copy)
@@ -78,7 +78,7 @@
declare(suffix,"info-zone-query","","select
id,name,master,last_check,notified_serial,type from domains where name=E'%s'");
- declare(suffix,"info-all-slaves-query","","select
id,name,master,last_check,type from domains where type='SLAVE'");
+ declare(suffix,"info-all-slaves-query","","select
id,name,master,last_check,type from domains where type='SLAVE' and next_check <
extract(epoch from now())::integer");
declare(suffix,"supermaster-query","", "select account from supermasters
where ip='%s' and nameserver=E'%s'");
declare(suffix,"insert-slave-query","", "insert into domains
(type,name,master,account) values('SLAVE',E'%s',E'%s',E'%s')");
declare(suffix,"insert-record-query","", "insert into records
(content,ttl,prio,type,domain_id,name) values (E'%s',%d,%d,'%s',%d,E'%s')");
@@ -90,7 +90,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,"update-lastcheck-query","", "update domains set
last_check=%d,next_check=%d where 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-users mailing list
[email protected]
http://mailman.powerdns.com/mailman/listinfo/pdns-users