From: Kees Monshouwer Date: Fri, 27 Dec 2013 11:06:39 +0000 (+0100) Subject: fix dual-stack superslave when multiple namservers share a ip X-Git-Tag: rec-3.6.0-rc1~268^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=719f902410f73c896b04bb15fb8c48f17d08885d;p=pdns fix dual-stack superslave when multiple namservers share a ip --- diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 7191bf166..251b1d565 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -1259,7 +1259,7 @@ bool Bind2Backend::isMaster(const string &name, const string &ip) return false; } -bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db) +bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) { // Check whether we have a configfile available. if (getArg("supermaster-config").empty()) @@ -1317,7 +1317,7 @@ BB2DomainInfo &Bind2Backend::createDomainEntry(const string &domain, const strin return bbd; } -bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &account) +bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) { string filename = getArg("supermaster-destdir")+'/'+domain; diff --git a/modules/bindbackend/bindbackend2.hh b/modules/bindbackend/bindbackend2.hh index a6dbb1b73..31853be34 100644 --- a/modules/bindbackend/bindbackend2.hh +++ b/modules/bindbackend/bindbackend2.hh @@ -182,9 +182,9 @@ public: bool isMaster(const string &name, const string &ip); // for supermaster support - bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db); + bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db); static pthread_mutex_t s_supermaster_config_lock; - bool createSlaveDomain(const string &ip, const string &domain, const string &account); + bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account); private: diff --git a/modules/gmysqlbackend/gmysqlbackend.cc b/modules/gmysqlbackend/gmysqlbackend.cc index 00e8de163..3e080a7d0 100644 --- a/modules/gmysqlbackend/gmysqlbackend.cc +++ b/modules/gmysqlbackend/gmysqlbackend.cc @@ -88,7 +88,6 @@ public: declare(suffix,"info-all-slaves-query","","select id,name,master,last_check,type from domains where type='SLAVE'"); declare(suffix,"supermaster-query","", "select account from supermasters where ip='%s' and nameserver='%s'"); declare(suffix,"supermaster-name-to-ips", "", "select ip from supermasters where nameserver='%s'"); - declare(suffix,"supermaster-ip-to-name", "", "select nameserver from supermasters where ip='%s'"); declare(suffix,"insert-zone-query","", "insert into domains (type,name) values('NATIVE','%s')"); declare(suffix,"insert-slave-query","", "insert into domains (type,name,master,account) values('SLAVE','%s','%s','%s')"); diff --git a/modules/goraclebackend/goraclebackend.cc b/modules/goraclebackend/goraclebackend.cc index eebcef97f..b9565a430 100644 --- a/modules/goraclebackend/goraclebackend.cc +++ b/modules/goraclebackend/goraclebackend.cc @@ -89,7 +89,6 @@ public: declare(suffix,"info-all-slaves-query","","select id,name,master,last_check,type from domains where type='SLAVE'"); declare(suffix,"supermaster-query","", "select account from supermasters where ip='%s' and nameserver='%s'"); declare(suffix,"supermaster-name-to-ips", "", "select ip from supermasters where nameserver='%s'"); - declare(suffix,"supermaster-ip-to-name", "", "select nameserver from supermasters where ip='%s'"); declare(suffix,"insert-zone-query","", "insert into domains (id, type, name) values(domain_id_sequence.nextval, 'NATIVE','%s')"); declare(suffix,"insert-slave-query","", "insert into domains (id, type,name,master,account) values(domain_id_sequence.nextval, 'SLAVE','%s','%s','%s')"); diff --git a/modules/gpgsqlbackend/gpgsqlbackend.cc b/modules/gpgsqlbackend/gpgsqlbackend.cc index 80910c3d8..0619b6431 100644 --- a/modules/gpgsqlbackend/gpgsqlbackend.cc +++ b/modules/gpgsqlbackend/gpgsqlbackend.cc @@ -84,7 +84,6 @@ public: declare(suffix,"info-all-slaves-query","","select id,name,master,last_check,type from domains where type='SLAVE'"); declare(suffix,"supermaster-query","", "select account from supermasters where ip='%s' and nameserver=E'%s'"); declare(suffix,"supermaster-name-to-ips", "", "select ip from supermasters where nameserver=E'%s'"); - declare(suffix,"supermaster-ip-to-name", "", "select nameserver from supermasters where ip='%s'"); declare(suffix,"insert-zone-query","", "insert into domains (type,name) values('NATIVE',E'%s')"); declare(suffix,"insert-slave-query","", "insert into domains (type,name,master,account) values('SLAVE',E'%s',E'%s',E'%s')"); diff --git a/modules/gsqlite3backend/gsqlite3backend.cc b/modules/gsqlite3backend/gsqlite3backend.cc index bba42491a..3f51a90ea 100644 --- a/modules/gsqlite3backend/gsqlite3backend.cc +++ b/modules/gsqlite3backend/gsqlite3backend.cc @@ -105,8 +105,7 @@ public: declare( suffix, "info-all-slaves-query", "","select id,name,master,last_check,type from domains where type='SLAVE'"); declare( suffix, "supermaster-query", "", "select account from supermasters where ip='%s' and nameserver='%s'"); - declare( suffix,"supermaster-name-to-ips", "", "select ip from supermasters where nameserver='%s'"); - declare( suffix,"supermaster-ip-to-name", "", "select nameserver from supermasters where ip='%s'"); + declare( suffix, "supermaster-name-to-ips", "", "select ip from supermasters where nameserver='%s'"); declare( suffix, "insert-zone-query", "", "insert into domains (type,name) values('NATIVE','%s')"); declare( suffix, "insert-slave-query", "", "insert into domains (type,name,master,account) values('SLAVE','%s','%s','%s')"); diff --git a/modules/luabackend/luabackend.hh b/modules/luabackend/luabackend.hh index f9eb31c4f..0e8654d55 100644 --- a/modules/luabackend/luabackend.hh +++ b/modules/luabackend/luabackend.hh @@ -61,8 +61,8 @@ public: // SUPERMASTER BACKEND - bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db); - bool createSlaveDomain(const string &ip, const string &domain, const string &account); + bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db); + bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account); // DNSSEC BACKEND diff --git a/modules/luabackend/supermaster.cc b/modules/luabackend/supermaster.cc index fa6cc0d45..0421e10d1 100644 --- a/modules/luabackend/supermaster.cc +++ b/modules/luabackend/supermaster.cc @@ -23,14 +23,14 @@ /* //! determine if ip is a supermaster or a domain - virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db) + virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) //! called by PowerDNS to create a slave record for a superMaster - virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account) + virtual bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) */ -bool LUABackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db) { +bool LUABackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) { if (f_lua_supermasterbackend == 0) return false; @@ -96,7 +96,7 @@ bool LUABackend::superMasterBackend(const string &ip, const string &domain, cons return ok; } -bool LUABackend::createSlaveDomain(const string &ip, const string &domain, const string &account) { +bool LUABackend::createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) { if (f_lua_createslavedomain == 0) return false; diff --git a/modules/opendbxbackend/odbxbackend.cc b/modules/opendbxbackend/odbxbackend.cc index bf354927d..2a3764314 100644 --- a/modules/opendbxbackend/odbxbackend.cc +++ b/modules/opendbxbackend/odbxbackend.cc @@ -560,7 +560,7 @@ void OdbxBackend::getUpdatedMasters( vector* updated ) -bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector& set, string* account, DNSBackend** ddb ) +bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector& set, string *nameserver, string* account, DNSBackend** ddb ) { try { @@ -604,7 +604,7 @@ bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, co -bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string& account ) +bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string &nameserver, const string& account ) { try { diff --git a/modules/opendbxbackend/odbxbackend.hh b/modules/opendbxbackend/odbxbackend.hh index a4b3649f6..bc9a29aa2 100644 --- a/modules/opendbxbackend/odbxbackend.hh +++ b/modules/opendbxbackend/odbxbackend.hh @@ -87,8 +87,8 @@ public: bool isMaster( const string& domain, const string& ip ); bool getDomainInfo( const string& domain, DomainInfo& di ); bool feedRecord( const DNSResourceRecord& rr, string *ordername=0 ); - bool createSlaveDomain( const string& ip, const string& domain, const string& account ); - bool superMasterBackend( const string& ip, const string& domain, const vector& nsset, string* account, DNSBackend** ddb ); + bool createSlaveDomain( const string& ip, const string& domain, const string &nameserver, const string& account ); + bool superMasterBackend( const string& ip, const string& domain, const vector& nsset, string *nameserver, string* account, DNSBackend** ddb ); void getUpdatedMasters( vector* updated ); void getUnfreshSlaveInfos( vector* unfresh ); diff --git a/modules/oraclebackend/oraclebackend.cc b/modules/oraclebackend/oraclebackend.cc index bf6dbd41c..9dc732ac7 100644 --- a/modules/oraclebackend/oraclebackend.cc +++ b/modules/oraclebackend/oraclebackend.cc @@ -1143,7 +1143,8 @@ OracleBackend::abortTransaction () bool OracleBackend::superMasterBackend (const string &ip, const string &domain, const vector &nsset, - string *account, DNSBackend **backend) + string *nameserver, string *account, + DNSBackend **backend) { sword rc; OCIStmt *stmt; @@ -1186,7 +1187,7 @@ OracleBackend::superMasterBackend (const string &ip, const string &domain, bool OracleBackend::createSlaveDomain(const string &ip, const string &domain, - const string &account) + const string &nameserver, const string &account) { sword rc; OCIStmt *insertSlaveQueryHandle; diff --git a/modules/oraclebackend/oraclebackend.hh b/modules/oraclebackend/oraclebackend.hh index 95aa90811..8d442dbdc 100644 --- a/modules/oraclebackend/oraclebackend.hh +++ b/modules/oraclebackend/oraclebackend.hh @@ -74,9 +74,10 @@ public: bool abortTransaction(); bool superMasterBackend(const string &ip, const string &domain, const vector &nsset, - string *account, DNSBackend **backend); + string *account, string *nameserver, + DNSBackend **backend); bool createSlaveDomain(const string &ip, const string &domain, - const string &account); + const string &nameserver, const string &account); bool getDomainMetadata(const string& name, const std::string& kind, std::vector& meta); bool setDomainMetadata(const string& name, const std::string& kind, const std::vector& meta); diff --git a/modules/remotebackend/remotebackend.cc b/modules/remotebackend/remotebackend.cc index a443b729b..e3243fc97 100644 --- a/modules/remotebackend/remotebackend.cc +++ b/modules/remotebackend/remotebackend.cc @@ -614,7 +614,7 @@ void RemoteBackend::setNotified(uint32_t id, uint32_t serial) { } } -bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **ddb) +bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **ddb) { rapidjson::Document query,answer; rapidjson::Value parameters; @@ -657,7 +657,7 @@ bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, c return true; } -bool RemoteBackend::createSlaveDomain(const string &ip, const string &domain, const string &account) { +bool RemoteBackend::createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) { rapidjson::Document query,answer; rapidjson::Value parameters; query.SetObject(); diff --git a/modules/remotebackend/remotebackend.hh b/modules/remotebackend/remotebackend.hh index 568b94f91..b2ed52098 100644 --- a/modules/remotebackend/remotebackend.hh +++ b/modules/remotebackend/remotebackend.hh @@ -144,8 +144,8 @@ class RemoteBackend : public DNSBackend virtual bool getDomainInfo(const string&, DomainInfo&); virtual void setNotified(uint32_t id, uint32_t serial); virtual bool doesDNSSEC(); - virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **ddb); - virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account); + virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **ddb); + virtual bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account); virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector& rrset); virtual bool feedRecord(const DNSResourceRecord &r, string *ordername); virtual bool feedEnts(int domain_id, set& nonterm); diff --git a/modules/remotebackend/test-remotebackend.cc b/modules/remotebackend/test-remotebackend.cc index f06f193e6..72cf1010c 100644 --- a/modules/remotebackend/test-remotebackend.cc +++ b/modules/remotebackend/test-remotebackend.cc @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(test_method_superMasterBackend) { rr.content = "ns2.example.com"; nsset.push_back(rr); - BOOST_CHECK(be->superMasterBackend("10.0.0.1", "example.com", nsset, NULL, &dbd)); + BOOST_CHECK(be->superMasterBackend("10.0.0.1", "example.com", nsset, NULL, NULL, &dbd)); // let's see what we got BOOST_CHECK_EQUAL(dbd, be); @@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(test_method_superMasterBackend) { BOOST_AUTO_TEST_CASE(test_method_createSlaveDomain) { BOOST_TEST_MESSAGE("Testing createSlaveDomain method"); - BOOST_CHECK(be->createSlaveDomain("10.0.0.1", "pirate.unit.test", "")); + BOOST_CHECK(be->createSlaveDomain("10.0.0.1", "pirate.unit.test", "", "")); } BOOST_AUTO_TEST_CASE(test_method_feedRecord) { diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index fc795f8b5..ecd3203c5 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -290,7 +290,6 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix) d_InfoOfDomainsZoneQuery=getArg("info-zone-query"); d_InfoOfAllSlaveDomainsQuery=getArg("info-all-slaves-query"); d_SuperMasterInfoQuery=getArg("supermaster-query"); - d_GetSuperMasterName=getArg("supermaster-ip-to-name"); d_GetSuperMasterIPs=getArg("supermaster-name-to-ips"); d_InsertZoneQuery=getArg("insert-zone-query"); d_InsertSlaveZoneQuery=getArg("insert-slave-query"); @@ -874,7 +873,7 @@ bool GSQLBackend::listSubZone(const string &zone, int domain_id) { -bool GSQLBackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **ddb) +bool GSQLBackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **ddb) { string format; char output[1024]; @@ -890,6 +889,7 @@ bool GSQLBackend::superMasterBackend(const string &ip, const string &domain, con } if(!d_result.empty()) { + *nameserver=i->content; *account=d_result[0][0]; *ddb=this; return true; @@ -910,23 +910,18 @@ bool GSQLBackend::createDomain(const string &domain) return true; } -bool GSQLBackend::createSlaveDomain(const string &ip, const string &domain, const string &account) +bool GSQLBackend::createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) { string format; string name; - string masters=ip; + string masters(ip); char output[1024]; try { - // figure out if there is a supermaster record for the IP address - format = d_GetSuperMasterName; - snprintf(output,sizeof(output)-1,format.c_str(),sqlEscape(ip).c_str()); - d_db->doQuery(output, d_result); - if (!d_result.empty()) { - // there is, now figure out all IP addresses for the master - name = d_result[0][0]; + if (!nameserver.empty()) { + // figure out all IP addresses for the master format = d_GetSuperMasterIPs; - snprintf(output,sizeof(output)-1,format.c_str(),sqlEscape(name).c_str()); + snprintf(output,sizeof(output)-1,format.c_str(),sqlEscape(nameserver).c_str()); d_db->doQuery(output, d_result); if (!d_result.empty()) { // collect all IP addresses @@ -935,9 +930,9 @@ bool GSQLBackend::createSlaveDomain(const string &ip, const string &domain, cons tmp.push_back(row[0]); } // set them as domain's masters, comma separated - masters = boost::join(tmp, ","); + masters = boost::join(tmp, ", "); } - } + } format = d_InsertSlaveZoneQuery; snprintf(output,sizeof(output)-1,format.c_str(),sqlEscape(domain).c_str(),sqlEscape(masters).c_str(),sqlEscape(account).c_str()); d_db->doCommand(output); diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index 94dcde2ee..21f0caa66 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -36,9 +36,9 @@ public: bool feedEnts(int domain_id, set& nonterm); bool feedEnts3(int domain_id, const string &domain, set &nonterm, unsigned int times, const string &salt, bool narrow); bool createDomain(const string &domain); - bool createSlaveDomain(const string &ip, const string &domain, const string &account); + bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account); bool deleteDomain(const string &domain); - bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db); + bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db); void setFresh(uint32_t domain_id); void getUnfreshSlaveInfos(vector *domains); void getUpdatedMasters(vector *updatedDomains); diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index 0f9fea4aa..906ce81cb 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -296,7 +296,7 @@ public: void setArgPrefix(const string &prefix); //! determine if ip is a supermaster or a domain - virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db) + virtual bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) { return false; } @@ -308,7 +308,7 @@ public: } //! called by PowerDNS to create a slave record for a superMaster - virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account) + virtual bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account) { return false; } diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 5efff7aed..fb7926b56 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -786,9 +786,9 @@ int PacketHandler::trySuperMasterSynchronous(DNSPacket *p) } } - string account; + string nameserver, account; DNSBackend *db; - if(!B.superMasterBackend(p->getRemote(), p->qdomain, nsset, &account, &db)) { + if(!B.superMasterBackend(p->getRemote(), p->qdomain, nsset, &nameserver, &account, &db)) { L<qdomain<<" for potential supermaster "<getRemote()<<". "<createSlaveDomain(p->getRemote(),p->qdomain,account); + db->createSlaveDomain(p->getRemote(), p->qdomain, nameserver, account); } catch(PDNSException& ae) { L<qdomain<<" for potential supermaster "<getRemote()<<": "<createSlaveDomain("127.0.0.1", zone, "_testschema"); + db->createSlaveDomain("127.0.0.1", zone, "", "_testschema"); cout<<"Slave domain created"<&nsset, string *account, DNSBackend **db) +bool UeberBackend::superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db) { for(vector::const_iterator i=backends.begin();i!=backends.end();++i) - if((*i)->superMasterBackend(ip,domain,nsset,account, db)) + if((*i)->superMasterBackend(ip, domain, nsset, nameserver, account, db)) return true; return false; - } void UeberBackend::setStatus(const string &st) diff --git a/pdns/ueberbackend.hh b/pdns/ueberbackend.hh index 23d583663..cf2fe237d 100644 --- a/pdns/ueberbackend.hh +++ b/pdns/ueberbackend.hh @@ -59,7 +59,7 @@ public: ~UeberBackend(); typedef DNSBackend *BackendMaker(); //!< typedef for functions returning pointers to new backends - bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db); + bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *nameserver, string *account, DNSBackend **db); /** contains BackendReporter objects, which contain maker functions and information about weather a module has already been reported to existing instances of the UeberBackend