Permalink
Browse files

fix dual-stack superslave when multiple namservers share a ip

  • Loading branch information...
1 parent d951e52 commit 719f902410f73c896b04bb15fb8c48f17d08885d @mind04 mind04 committed with mind04 Dec 27, 2013
@@ -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<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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;
@@ -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<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
+ bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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:
@@ -88,7 +88,6 @@ class gMySQLFactory : public BackendFactory
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')");
@@ -89,7 +89,6 @@ class gOracleFactory : public BackendFactory
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')");
@@ -84,7 +84,6 @@ class gPgSQLFactory : public BackendFactory
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')");
@@ -105,8 +105,7 @@ class gSQLite3Factory : public BackendFactory
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')");
@@ -61,8 +61,8 @@ public:
// SUPERMASTER BACKEND
- bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
+ bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account);
// DNSSEC BACKEND
@@ -23,14 +23,14 @@
/*
//! determine if ip is a supermaster or a domain
- virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+ virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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<DNSResourceRecord>&nsset, string *account, DNSBackend **db) {
+bool LUABackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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;
@@ -560,7 +560,7 @@ void OdbxBackend::getUpdatedMasters( vector<DomainInfo>* updated )
-bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& set, string* account, DNSBackend** ddb )
+bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& 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
{
@@ -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<DNSResourceRecord>& 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<DNSResourceRecord>& nsset, string *nameserver, string* account, DNSBackend** ddb );
void getUpdatedMasters( vector<DomainInfo>* updated );
void getUnfreshSlaveInfos( vector<DomainInfo>* unfresh );
@@ -1143,7 +1143,8 @@ OracleBackend::abortTransaction ()
bool
OracleBackend::superMasterBackend (const string &ip, const string &domain,
const vector<DNSResourceRecord> &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;
@@ -74,9 +74,10 @@ public:
bool abortTransaction();
bool superMasterBackend(const string &ip, const string &domain,
const vector<DNSResourceRecord> &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<std::string>& meta);
bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
@@ -614,7 +614,7 @@ void RemoteBackend::setNotified(uint32_t id, uint32_t serial) {
}
}
-bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **ddb)
+bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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();
@@ -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<DNSResourceRecord>&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<DNSResourceRecord>&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<DNSResourceRecord>& rrset);
virtual bool feedRecord(const DNSResourceRecord &r, string *ordername);
virtual bool feedEnts(int domain_id, set<string>& nonterm);
@@ -199,15 +199,15 @@ 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);
}
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) {
@@ -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<DNSResourceRecord>&nsset, string *account, DNSBackend **ddb)
+bool GSQLBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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);
@@ -36,9 +36,9 @@ public:
bool feedEnts(int domain_id, set<string>& nonterm);
bool feedEnts3(int domain_id, const string &domain, set<string> &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<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
+ bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
void setFresh(uint32_t domain_id);
void getUnfreshSlaveInfos(vector<DomainInfo> *domains);
void getUpdatedMasters(vector<DomainInfo> *updatedDomains);
View
@@ -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<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+ virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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;
}
@@ -786,17 +786,17 @@ 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<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<". "<<nsset.size()<<" remote nameservers: "<<endl;
BOOST_FOREACH(class DNSResourceRecord& rr, nsset) {
L<<Logger::Error<<rr.content<<endl;
}
return RCode::Refused;
}
try {
- db->createSlaveDomain(p->getRemote(),p->qdomain,account);
+ db->createSlaveDomain(p->getRemote(), p->qdomain, nameserver, account);
}
catch(PDNSException& ae) {
L<<Logger::Error<<"Database error trying to create "<<p->qdomain<<" for potential supermaster "<<p->getRemote()<<": "<<ae.reason<<endl;
View
@@ -912,7 +912,7 @@ void testSchema(DNSSECKeeper& dk, const std::string& zone)
cout<<"Picking first backend - if this is not what you want, edit launch line!"<<endl;
DNSBackend *db = B.backends[0];
cout<<"Creating slave domain "<<zone<<endl;
- db->createSlaveDomain("127.0.0.1", zone, "_testschema");
+ db->createSlaveDomain("127.0.0.1", zone, "", "_testschema");
cout<<"Slave domain created"<<endl;
DomainInfo di;
@@ -297,13 +297,12 @@ bool UeberBackend::getSOA(const string &domain, SOAData &sd, DNSPacket *p)
return false;
}
-bool UeberBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
+bool UeberBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
{
for(vector<DNSBackend *>::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)
@@ -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<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
+ bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&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

0 comments on commit 719f902

Please sign in to comment.