- run:
name: Check formatting
command: |
- ./build-scripts/format-code pdns/recursordist/*.[ch][ch]
+ ./build-scripts/format-code pdns/recursordist/*.[ch][ch] $(find modules -name '*.[ch][ch]')
git --no-pager diff
exit $(git diff | wc -l)
working_directory: ~/project
*/
Bind2Backend::state_t Bind2Backend::s_state;
-int Bind2Backend::s_first=1;
-bool Bind2Backend::s_ignore_broken_records=false;
+int Bind2Backend::s_first = 1;
+bool Bind2Backend::s_ignore_broken_records = false;
ReadWriteLock Bind2Backend::s_state_lock;
std::mutex Bind2Backend::s_supermaster_config_lock; // protects writes to config file
std::mutex Bind2Backend::s_startup_lock;
-string Bind2Backend::s_binddirectory;
+string Bind2Backend::s_binddirectory;
template <typename T>
std::mutex LookButDontTouch<T>::s_lock;
BB2DomainInfo::BB2DomainInfo()
{
- d_loaded=false;
- d_lastcheck=0;
- d_checknow=false;
- d_status="Unknown";
+ d_loaded = false;
+ d_lastcheck = 0;
+ d_checknow = false;
+ d_status = "Unknown";
}
void BB2DomainInfo::setCheckInterval(time_t seconds)
{
- d_checkinterval=seconds;
+ d_checkinterval = seconds;
}
bool BB2DomainInfo::current()
{
- if(d_checknow) {
+ if (d_checknow) {
return false;
}
- if(!d_checkinterval)
+ if (!d_checkinterval)
return true;
- if(time(nullptr) - d_lastcheck < d_checkinterval)
+ if (time(nullptr) - d_lastcheck < d_checkinterval)
return true;
-
- if(d_filename.empty())
+
+ if (d_filename.empty())
return true;
- return (getCtime()==d_ctime);
+ return (getCtime() == d_ctime);
}
time_t BB2DomainInfo::getCtime()
{
struct stat buf;
-
- if(d_filename.empty() || stat(d_filename.c_str(),&buf)<0)
- return 0;
- d_lastcheck=time(nullptr);
+
+ if (d_filename.empty() || stat(d_filename.c_str(), &buf) < 0)
+ return 0;
+ d_lastcheck = time(nullptr);
return buf.st_ctime;
}
void BB2DomainInfo::setCtime()
{
struct stat buf;
- if(stat(d_filename.c_str(),&buf)<0)
- return;
- d_ctime=buf.st_ctime;
+ if (stat(d_filename.c_str(), &buf) < 0)
+ return;
+ d_ctime = buf.st_ctime;
}
bool Bind2Backend::safeGetBBDomainInfo(int id, BB2DomainInfo* bbd)
{
ReadLock rl(&s_state_lock);
state_t::const_iterator iter = s_state.find(id);
- if(iter == s_state.end())
+ if (iter == s_state.end())
return false;
- *bbd=*iter;
+ *bbd = *iter;
return true;
}
nameindex_t& nameindex = boost::multi_index::get<NameTag>(s_state);
nameindex_t::const_iterator iter = nameindex.find(name);
- if(iter == nameindex.end())
+ if (iter == nameindex.end())
return false;
- *bbd=*iter;
+ *bbd = *iter;
return true;
}
nameindex_t& nameindex = boost::multi_index::get<NameTag>(s_state);
nameindex_t::iterator iter = nameindex.find(name);
- if(iter == nameindex.end())
+ if (iter == nameindex.end())
return false;
nameindex.erase(iter);
return true;
void Bind2Backend::setFresh(uint32_t domain_id)
{
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(domain_id, &bbd)) {
- bbd.d_lastcheck=time(nullptr);
+ if (safeGetBBDomainInfo(domain_id, &bbd)) {
+ bbd.d_lastcheck = time(nullptr);
safePutBBDomainInfo(bbd);
}
}
-bool Bind2Backend::startTransaction(const DNSName &qname, int id)
+bool Bind2Backend::startTransaction(const DNSName& qname, int id)
{
- if(id < 0) {
+ if (id < 0) {
d_transaction_tmpname.clear();
- d_transaction_id=id;
+ d_transaction_id = id;
return false;
}
- if(id == 0) {
+ if (id == 0) {
throw DBException("domain_id 0 is invalid for this backend.");
}
- d_transaction_id=id;
- d_transaction_qname=qname;
+ d_transaction_id = id;
+ d_transaction_qname = qname;
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(id, &bbd)) {
+ if (safeGetBBDomainInfo(id, &bbd)) {
d_transaction_tmpname = bbd.d_filename + "XXXXXX";
int fd = mkstemp(&d_transaction_tmpname.at(0));
if (fd == -1) {
- throw DBException("Unable to create a unique temporary zonefile '"+d_transaction_tmpname+"': "+stringerror());
+ throw DBException("Unable to create a unique temporary zonefile '" + d_transaction_tmpname + "': " + stringerror());
return false;
}
d_of = std::unique_ptr<ofstream>(new ofstream(d_transaction_tmpname.c_str()));
- if(!*d_of) {
+ if (!*d_of) {
unlink(d_transaction_tmpname.c_str());
close(fd);
fd = -1;
d_of.reset();
- throw DBException("Unable to open temporary zonefile '"+d_transaction_tmpname+"': "+stringerror());
+ throw DBException("Unable to open temporary zonefile '" + d_transaction_tmpname + "': " + stringerror());
}
close(fd);
fd = -1;
- *d_of<<"; Written by PowerDNS, don't edit!"<<endl;
- *d_of<<"; Zone '"<<bbd.d_name<<"' retrieved from master "<<endl<<"; at "<<nowTime()<<endl; // insert master info here again
+ *d_of << "; Written by PowerDNS, don't edit!" << endl;
+ *d_of << "; Zone '" << bbd.d_name << "' retrieved from master " << endl
+ << "; at " << nowTime() << endl; // insert master info here again
return true;
}
bool Bind2Backend::commitTransaction()
{
- if(d_transaction_id < 0)
+ if (d_transaction_id < 0)
return false;
d_of.reset();
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(d_transaction_id, &bbd)) {
- if(rename(d_transaction_tmpname.c_str(), bbd.d_filename.c_str())<0)
- throw DBException("Unable to commit (rename to: '" + bbd.d_filename+"') AXFRed zone: "+stringerror());
+ if (safeGetBBDomainInfo(d_transaction_id, &bbd)) {
+ if (rename(d_transaction_tmpname.c_str(), bbd.d_filename.c_str()) < 0)
+ throw DBException("Unable to commit (rename to: '" + bbd.d_filename + "') AXFRed zone: " + stringerror());
queueReloadAndStore(bbd.d_id);
}
- d_transaction_id=0;
+ d_transaction_id = 0;
return true;
}
// -1 = dnssec speciality
// 0 = invalid transact
// >0 = actual transaction
- if(d_transaction_id > 0) {
+ if (d_transaction_id > 0) {
unlink(d_transaction_tmpname.c_str());
d_of.reset();
- d_transaction_id=0;
+ d_transaction_id = 0;
}
return true;
}
-bool Bind2Backend::feedRecord(const DNSResourceRecord &rr, const DNSName &ordername, bool ordernameIsNSEC3)
+bool Bind2Backend::feedRecord(const DNSResourceRecord& rr, const DNSName& ordername, bool ordernameIsNSEC3)
{
if (d_transaction_id < 1) {
throw DBException("Bind2Backend::feedRecord() called outside of transaction");
}
}
else {
- throw DBException("out-of-zone data '"+rr.qname.toLogString()+"' during AXFR of zone '"+d_transaction_qname.toLogString()+"'");
+ throw DBException("out-of-zone data '" + rr.qname.toLogString() + "' during AXFR of zone '" + d_transaction_qname.toLogString() + "'");
}
shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(rr.qtype.getCode(), QClass::IN, rr.content));
string content = drc->getZoneRepresentation();
// SOA needs stripping too! XXX FIXME - also, this should not be here I think
- switch(rr.qtype.getCode()) {
+ switch (rr.qtype.getCode()) {
case QType::MX:
case QType::SRV:
case QType::CNAME:
// fallthrough
default:
if (d_of && *d_of) {
- *d_of<<qname<<"\t"<<rr.ttl<<"\t"<<rr.qtype.getName()<<"\t"<<content<<endl;
+ *d_of << qname << "\t" << rr.ttl << "\t" << rr.qtype.getName() << "\t" << content << endl;
}
}
return true;
}
-void Bind2Backend::getUpdatedMasters(vector<DomainInfo> *changedDomains)
+void Bind2Backend::getUpdatedMasters(vector<DomainInfo>* changedDomains)
{
vector<DomainInfo> consider;
{
ReadLock rl(&s_state_lock);
- for(const auto & i : s_state) {
- if(i.d_kind != DomainInfo::Master && this->alsoNotify.empty() && i.d_also_notify.empty())
+ for (const auto& i : s_state) {
+ if (i.d_kind != DomainInfo::Master && this->alsoNotify.empty() && i.d_also_notify.empty())
continue;
DomainInfo di;
- di.id=i.d_id;
- di.zone=i.d_name;
- di.last_check=i.d_lastcheck;
- di.notified_serial=i.d_lastnotified;
- di.backend=this;
- di.kind=DomainInfo::Master;
+ di.id = i.d_id;
+ di.zone = i.d_name;
+ di.last_check = i.d_lastcheck;
+ di.notified_serial = i.d_lastnotified;
+ di.backend = this;
+ di.kind = DomainInfo::Master;
consider.push_back(std::move(di));
}
}
SOAData soadata;
- for(DomainInfo& di : consider) {
- soadata.serial=0;
+ for (DomainInfo& di : consider) {
+ soadata.serial = 0;
try {
this->getSOA(di.zone, soadata); // we might not *have* a SOA yet, but this might trigger a load of it
}
- catch(...) {
+ catch (...) {
continue;
}
- if(di.notified_serial != soadata.serial) {
+ if (di.notified_serial != soadata.serial) {
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(di.id, &bbd)) {
- bbd.d_lastnotified=soadata.serial;
+ if (safeGetBBDomainInfo(di.id, &bbd)) {
+ bbd.d_lastnotified = soadata.serial;
safePutBBDomainInfo(bbd);
}
- if(di.notified_serial) { // don't do notification storm on startup
- di.serial=soadata.serial;
+ if (di.notified_serial) { // don't do notification storm on startup
+ di.serial = soadata.serial;
changedDomains->push_back(std::move(di));
}
}
}
}
-void Bind2Backend::getAllDomains(vector<DomainInfo> *domains, bool include_disabled)
+void Bind2Backend::getAllDomains(vector<DomainInfo>* domains, bool include_disabled)
{
SOAData soadata;
ReadLock rl(&s_state_lock);
domains->reserve(s_state.size());
- for(const auto & i : s_state) {
+ for (const auto& i : s_state) {
DomainInfo di;
- di.id=i.d_id;
- di.zone=i.d_name;
- di.last_check=i.d_lastcheck;
- di.kind=i.d_kind;
- di.masters=i.d_masters;
- di.backend=this;
+ di.id = i.d_id;
+ di.zone = i.d_name;
+ di.last_check = i.d_lastcheck;
+ di.kind = i.d_kind;
+ di.masters = i.d_masters;
+ di.backend = this;
domains->push_back(std::move(di));
};
}
- for(DomainInfo &di : *domains) {
+ for (DomainInfo& di : *domains) {
// do not corrupt di if domain supplied by another backend.
if (di.backend != this)
continue;
try {
this->getSOA(di.zone, soadata);
- } catch(...) {
+ }
+ catch (...) {
continue;
}
- di.serial=soadata.serial;
+ di.serial = soadata.serial;
}
}
-void Bind2Backend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
+void Bind2Backend::getUnfreshSlaveInfos(vector<DomainInfo>* unfreshDomains)
{
vector<DomainInfo> domains;
{
ReadLock rl(&s_state_lock);
domains.reserve(s_state.size());
- for(const auto & i : s_state) {
- if(i.d_kind != DomainInfo::Slave)
+ for (const auto& i : s_state) {
+ if (i.d_kind != DomainInfo::Slave)
continue;
DomainInfo sd;
- sd.id=i.d_id;
- sd.zone=i.d_name;
- sd.masters=i.d_masters;
- sd.last_check=i.d_lastcheck;
- sd.backend=this;
- sd.kind=DomainInfo::Slave;
+ sd.id = i.d_id;
+ sd.zone = i.d_name;
+ sd.masters = i.d_masters;
+ sd.last_check = i.d_lastcheck;
+ sd.backend = this;
+ sd.kind = DomainInfo::Slave;
domains.push_back(std::move(sd));
}
}
unfreshDomains->reserve(domains.size());
- for(DomainInfo &sd : domains) {
+ for (DomainInfo& sd : domains) {
SOAData soadata;
- soadata.refresh=0;
- soadata.serial=0;
+ soadata.refresh = 0;
+ soadata.serial = 0;
try {
- getSOA(sd.zone,soadata); // we might not *have* a SOA yet
+ getSOA(sd.zone, soadata); // we might not *have* a SOA yet
+ }
+ catch (...) {
}
- catch(...){}
- sd.serial=soadata.serial;
- if(sd.last_check+soadata.refresh < (unsigned int)time(nullptr))
+ sd.serial = soadata.serial;
+ if (sd.last_check + soadata.refresh < (unsigned int)time(nullptr))
unfreshDomains->push_back(std::move(sd));
}
}
-bool Bind2Backend::getDomainInfo(const DNSName& domain, DomainInfo &di, bool getSerial)
+bool Bind2Backend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
{
BB2DomainInfo bbd;
- if(!safeGetBBDomainInfo(domain, &bbd))
+ if (!safeGetBBDomainInfo(domain, &bbd))
return false;
- di.id=bbd.d_id;
- di.zone=domain;
- di.masters=bbd.d_masters;
- di.last_check=bbd.d_lastcheck;
- di.backend=this;
- di.kind=bbd.d_kind;
- di.serial=0;
- if(getSerial) {
+ di.id = bbd.d_id;
+ di.zone = domain;
+ di.masters = bbd.d_masters;
+ di.last_check = bbd.d_lastcheck;
+ di.backend = this;
+ di.kind = bbd.d_kind;
+ di.serial = 0;
+ if (getSerial) {
try {
SOAData sd;
- sd.serial=0;
+ sd.serial = 0;
- getSOA(bbd.d_name,sd); // we might not *have* a SOA yet
- di.serial=sd.serial;
+ getSOA(bbd.d_name, sd); // we might not *have* a SOA yet
+ di.serial = sd.serial;
+ }
+ catch (...) {
}
- catch(...){}
}
-
+
return true;
}
-void Bind2Backend::alsoNotifies(const DNSName& domain, set<string> *ips)
+void Bind2Backend::alsoNotifies(const DNSName& domain, set<string>* ips)
{
// combine global list with local list
- for(const auto & i : this->alsoNotify) {
+ for (const auto& i : this->alsoNotify) {
(*ips).insert(i);
}
// check metadata too if available
vector<string> meta;
if (getDomainMetadata(domain, "ALSO-NOTIFY", meta)) {
- for(const auto& str: meta) {
+ for (const auto& str : meta) {
(*ips).insert(str);
}
}
ReadLock rl(&s_state_lock);
- for(const auto & i : s_state) {
- if(i.d_name == domain) {
- for(const auto & it : i.d_also_notify) {
+ for (const auto& i : s_state) {
+ if (i.d_name == domain) {
+ for (const auto& it : i.d_also_notify) {
(*ips).insert(it);
}
return;
}
- }
+ }
}
// only parses, does NOT add to s_state!
-void Bind2Backend::parseZoneFile(BB2DomainInfo *bbd)
+void Bind2Backend::parseZoneFile(BB2DomainInfo* bbd)
{
NSEC3PARAMRecordContent ns3pr;
bool nsec3zone;
if (d_hybrid) {
DNSSECKeeper dk;
- nsec3zone=dk.getNSEC3PARAM(bbd->d_name, &ns3pr);
- } else
- nsec3zone=getNSEC3PARAM(bbd->d_name, &ns3pr);
+ nsec3zone = dk.getNSEC3PARAM(bbd->d_name, &ns3pr);
+ }
+ else
+ nsec3zone = getNSEC3PARAM(bbd->d_name, &ns3pr);
auto records = std::make_shared<recordstorage_t>();
ZoneParserTNG zpt(bbd->d_filename, bbd->d_name, s_binddirectory, d_upgradeContent);
zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps"));
DNSResourceRecord rr;
string hashed;
- while(zpt.get(rr)) {
- if(rr.qtype.getCode() == QType::NSEC || rr.qtype.getCode() == QType::NSEC3 || rr.qtype.getCode() == QType::NSEC3PARAM)
+ while (zpt.get(rr)) {
+ if (rr.qtype.getCode() == QType::NSEC || rr.qtype.getCode() == QType::NSEC3 || rr.qtype.getCode() == QType::NSEC3PARAM)
continue; // we synthesise NSECs on demand
insertRecord(records, bbd->d_name, rr.qname, rr.qtype, rr.content, rr.ttl, "");
fixupOrderAndAuth(records, bbd->d_name, nsec3zone, ns3pr);
doEmptyNonTerminals(records, bbd->d_name, nsec3zone, ns3pr);
bbd->setCtime();
- bbd->d_loaded=true;
- bbd->d_checknow=false;
- bbd->d_status="parsed into memory at "+nowTime();
+ bbd->d_loaded = true;
+ bbd->d_checknow = false;
+ bbd->d_status = "parsed into memory at " + nowTime();
bbd->d_records = LookButDontTouch<recordstorage_t>(records);
}
/** THIS IS AN INTERNAL FUNCTION! It does moadnsparser prio impedance matching
Much of the complication is due to the efforts to benefit from std::string reference counting copy on write semantics */
-void Bind2Backend::insertRecord(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, const DNSName &qname, const QType &qtype, const string &content, int ttl, const std::string& hashed, bool *auth)
+void Bind2Backend::insertRecord(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, const DNSName& qname, const QType& qtype, const string& content, int ttl, const std::string& hashed, bool* auth)
{
Bind2DNSRecord bdr;
- bdr.qname=qname;
+ bdr.qname = qname;
- if(zoneName.empty())
+ if (zoneName.empty())
;
- else if(bdr.qname.isPartOf(zoneName))
+ else if (bdr.qname.isPartOf(zoneName))
bdr.qname.makeUsRelative(zoneName);
else {
- string msg = "Trying to insert non-zone data, name='"+bdr.qname.toLogString()+"', qtype="+qtype.getName()+", zone='"+zoneName.toLogString()+"'";
- if(s_ignore_broken_records) {
- g_log<<Logger::Warning<<msg<< " ignored" << endl;
- return;
+ string msg = "Trying to insert non-zone data, name='" + bdr.qname.toLogString() + "', qtype=" + qtype.getName() + ", zone='" + zoneName.toLogString() + "'";
+ if (s_ignore_broken_records) {
+ g_log << Logger::Warning << msg << " ignored" << endl;
+ return;
}
else
throw PDNSException(msg);
}
-// bdr.qname.swap(bdr.qname);
+ // bdr.qname.swap(bdr.qname);
- if(!records->empty() && bdr.qname==boost::prior(records->end())->qname)
- bdr.qname=boost::prior(records->end())->qname;
+ if (!records->empty() && bdr.qname == boost::prior(records->end())->qname)
+ bdr.qname = boost::prior(records->end())->qname;
- bdr.qname=bdr.qname;
- bdr.qtype=qtype.getCode();
- bdr.content=content;
+ bdr.qname = bdr.qname;
+ bdr.qtype = qtype.getCode();
+ bdr.content = content;
bdr.nsec3hash = hashed;
-
+
if (auth) // Set auth on empty non-terminals
- bdr.auth=*auth;
+ bdr.auth = *auth;
else
- bdr.auth=true;
+ bdr.auth = true;
- bdr.ttl=ttl;
+ bdr.ttl = ttl;
records->insert(std::move(bdr));
}
-string Bind2Backend::DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid)
+string Bind2Backend::DLReloadNowHandler(const vector<string>& parts, Utility::pid_t ppid)
{
ostringstream ret;
- for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i) {
+ for (vector<string>::const_iterator i = parts.begin() + 1; i < parts.end(); ++i) {
BB2DomainInfo bbd;
DNSName zone(*i);
- if(safeGetBBDomainInfo(zone, &bbd)) {
+ if (safeGetBBDomainInfo(zone, &bbd)) {
Bind2Backend bb2;
bb2.queueReloadAndStore(bbd.d_id);
if (!safeGetBBDomainInfo(zone, &bbd)) // Read the *new* domain status
- ret << *i << ": [missing]\n";
+ ret << *i << ": [missing]\n";
else
- ret<< *i << ": "<< (bbd.d_wasRejectedLastReload ? "[rejected]": "") <<"\t"<<bbd.d_status<<"\n";
+ ret << *i << ": " << (bbd.d_wasRejectedLastReload ? "[rejected]" : "") << "\t" << bbd.d_status << "\n";
}
else
- ret<< *i << " no such domain\n";
- }
- if(ret.str().empty())
- ret<<"no domains reloaded";
+ ret << *i << " no such domain\n";
+ }
+ if (ret.str().empty())
+ ret << "no domains reloaded";
return ret.str();
}
-
-string Bind2Backend::DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid)
+string Bind2Backend::DLDomStatusHandler(const vector<string>& parts, Utility::pid_t ppid)
{
ostringstream ret;
- if(parts.size() > 1) {
- for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i) {
+ if (parts.size() > 1) {
+ for (vector<string>::const_iterator i = parts.begin() + 1; i < parts.end(); ++i) {
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(DNSName(*i), &bbd)) {
- ret<< *i << ": "<< (bbd.d_loaded ? "": "[rejected]") <<"\t"<<bbd.d_status<<"\n";
+ if (safeGetBBDomainInfo(DNSName(*i), &bbd)) {
+ ret << *i << ": " << (bbd.d_loaded ? "" : "[rejected]") << "\t" << bbd.d_status << "\n";
}
else {
- ret<< *i << " no such domain\n";
+ ret << *i << " no such domain\n";
}
}
}
else {
ReadLock rl(&s_state_lock);
- for(const auto & i : s_state) {
- ret<< i.d_name << ": "<< (i.d_loaded ? "": "[rejected]") <<"\t"<<i.d_status<<"\n";
+ for (const auto& i : s_state) {
+ ret << i.d_name << ": " << (i.d_loaded ? "" : "[rejected]") << "\t" << i.d_status << "\n";
}
}
- if(ret.str().empty())
- ret<<"no domains passed";
+ if (ret.str().empty())
+ ret << "no domains passed";
return ret.str();
}
ret << "\t Last notified: " << info.d_lastnotified << std::endl;
}
-string Bind2Backend::DLDomExtendedStatusHandler(const vector<string>&parts, Utility::pid_t ppid)
+string Bind2Backend::DLDomExtendedStatusHandler(const vector<string>& parts, Utility::pid_t ppid)
{
ostringstream ret;
if (parts.size() > 1) {
- for (vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i) {
+ for (vector<string>::const_iterator i = parts.begin() + 1; i < parts.end(); ++i) {
BB2DomainInfo bbd;
if (safeGetBBDomainInfo(DNSName(*i), &bbd)) {
printDomainExtendedStatus(ret, bbd);
return ret.str();
}
-string Bind2Backend::DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid)
+string Bind2Backend::DLListRejectsHandler(const vector<string>& parts, Utility::pid_t ppid)
{
ostringstream ret;
ReadLock rl(&s_state_lock);
- for(const auto & i : s_state) {
- if(!i.d_loaded)
- ret<<i.d_name<<"\t"<<i.d_status<<endl;
+ for (const auto& i : s_state) {
+ if (!i.d_loaded)
+ ret << i.d_name << "\t" << i.d_status << endl;
}
return ret.str();
}
-string Bind2Backend::DLAddDomainHandler(const vector<string>&parts, Utility::pid_t ppid)
+string Bind2Backend::DLAddDomainHandler(const vector<string>& parts, Utility::pid_t ppid)
{
- if(parts.size() < 3)
+ if (parts.size() < 3)
return "ERROR: Domain name and zone filename are required";
DNSName domainname(parts[1]);
- const string &filename = parts[2];
+ const string& filename = parts[2];
BB2DomainInfo bbd;
- if(safeGetBBDomainInfo(domainname, &bbd))
+ if (safeGetBBDomainInfo(domainname, &bbd))
return "Already loaded";
if (!boost::starts_with(filename, "/") && ::arg()["chroot"].empty())
return "Unable to load zone " + domainname.toLogString() + " from " + filename + ": " + strerror(errno);
Bind2Backend bb2; // createdomainentry needs access to our configuration
- bbd=bb2.createDomainEntry(domainname, filename);
- bbd.d_filename=filename;
- bbd.d_checknow=true;
- bbd.d_loaded=true;
- bbd.d_lastcheck=0;
- bbd.d_status="parsing into memory";
+ bbd = bb2.createDomainEntry(domainname, filename);
+ bbd.d_filename = filename;
+ bbd.d_checknow = true;
+ bbd.d_loaded = true;
+ bbd.d_lastcheck = 0;
+ bbd.d_status = "parsing into memory";
bbd.setCtime();
safePutBBDomainInfo(bbd);
- g_log<<Logger::Warning<<"Zone "<<domainname<< " loaded"<<endl;
+ g_log << Logger::Warning << "Zone " << domainname << " loaded" << endl;
return "Loaded zone " + domainname.toLogString() + " from " + filename;
}
-Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
+Bind2Backend::Bind2Backend(const string& suffix, bool loadZones)
{
d_getAllDomainMetadataQuery_stmt = nullptr;
d_getDomainMetadataQuery_stmt = nullptr;
d_deleteTSIGKeyQuery_stmt = nullptr;
d_getTSIGKeysQuery_stmt = nullptr;
- setArgPrefix("bind"+suffix);
- d_logprefix="[bind"+suffix+"backend]";
- d_hybrid=mustDo("hybrid");
- d_transaction_id=0;
- s_ignore_broken_records=mustDo("ignore-broken-records");
- d_upgradeContent=::arg().mustDo("upgrade-unknown-types");
+ setArgPrefix("bind" + suffix);
+ d_logprefix = "[bind" + suffix + "backend]";
+ d_hybrid = mustDo("hybrid");
+ d_transaction_id = 0;
+ s_ignore_broken_records = mustDo("ignore-broken-records");
+ d_upgradeContent = ::arg().mustDo("upgrade-unknown-types");
if (!loadZones && d_hybrid)
return;
std::lock_guard<std::mutex> l(s_startup_lock);
-
+
setupDNSSEC();
- if(!s_first) {
+ if (!s_first) {
return;
}
-
- if(loadZones) {
+
+ if (loadZones) {
loadConfig();
- s_first=0;
+ s_first = 0;
}
-
+
DynListener::registerFunc("BIND-RELOAD-NOW", &DLReloadNowHandler, "bindbackend: reload domains", "<domains>");
DynListener::registerFunc("BIND-DOMAIN-STATUS", &DLDomStatusHandler, "bindbackend: list status of all domains", "[domains]");
DynListener::registerFunc("BIND-DOMAIN-EXTENDED-STATUS", &DLDomExtendedStatusHandler, "bindbackend: list the extended status of all domains", "[domains]");
}
Bind2Backend::~Bind2Backend()
-{ freeStatements(); } // deallocate statements
+{
+ freeStatements();
+} // deallocate statements
-void Bind2Backend::rediscover(string *status)
+void Bind2Backend::rediscover(string* status)
{
loadConfig(status);
}
void Bind2Backend::reload()
{
WriteLock rwl(&s_state_lock);
- for(const auto & i : s_state) {
- i.d_checknow=true; // being a bit cheeky here, don't index state_t on this (mutable)
+ for (const auto& i : s_state) {
+ i.d_checknow = true; // being a bit cheeky here, don't index state_t on this (mutable)
}
}
DNSName shorter;
set<DNSName> nssets, dssets;
- for(const auto& bdr: *records) {
- if(!bdr.qname.isRoot() && bdr.qtype == QType::NS)
+ for (const auto& bdr : *records) {
+ if (!bdr.qname.isRoot() && bdr.qtype == QType::NS)
nssets.insert(bdr.qname);
- else if(bdr.qtype == QType::DS)
+ else if (bdr.qtype == QType::DS)
dssets.insert(bdr.qname);
}
- for(auto iter = records->begin(); iter != records->end(); iter++) {
+ for (auto iter = records->begin(); iter != records->end(); iter++) {
skip = false;
shorter = iter->qname;
if (!iter->qname.isRoot() && shorter.chopOff() && !iter->qname.isRoot()) {
do {
- if(nssets.count(shorter)) {
+ if (nssets.count(shorter)) {
skip = true;
break;
}
- } while(shorter.chopOff() && !iter->qname.isRoot());
+ } while (shorter.chopOff() && !iter->qname.isRoot());
}
iter->auth = (!skip && (iter->qtype == QType::DS || iter->qtype == QType::RRSIG || !nssets.count(iter->qname)));
- if(!skip && nsec3zone && iter->qtype != QType::RRSIG && (iter->auth || (iter->qtype == QType::NS && !ns3pr.d_flags) || dssets.count(iter->qname))) {
+ if (!skip && nsec3zone && iter->qtype != QType::RRSIG && (iter->auth || (iter->qtype == QType::NS && !ns3pr.d_flags) || dssets.count(iter->qname))) {
Bind2DNSRecord bdr = *iter;
- bdr.nsec3hash = toBase32Hex(hashQNameWithSalt(ns3pr, bdr.qname+zoneName));
+ bdr.nsec3hash = toBase32Hex(hashQNameWithSalt(ns3pr, bdr.qname + zoneName));
records->replace(iter, bdr);
}
uint32_t maxent = ::arg().asNum("max-ent-entries");
- for(const auto& bdr : *records)
+ for (const auto& bdr : *records)
qnames.insert(bdr.qname);
- for(const auto& bdr : *records) {
+ for (const auto& bdr : *records) {
if (!bdr.auth && bdr.qtype == QType::NS)
auth = (!nsec3zone || !ns3pr.d_flags);
auth = bdr.auth;
shorter = bdr.qname;
- while(shorter.chopOff())
- {
- if(!qnames.count(shorter))
- {
- if(!(maxent))
- {
- g_log<<Logger::Error<<"Zone '"<<zoneName<<"' has too many empty non terminals."<<endl;
+ while (shorter.chopOff()) {
+ if (!qnames.count(shorter)) {
+ if (!(maxent)) {
+ g_log << Logger::Error << "Zone '" << zoneName << "' has too many empty non terminals." << endl;
return;
}
if (!nonterm.count(shorter)) {
nonterm.emplace(shorter, auth);
--maxent;
- } else if (auth)
+ }
+ else if (auth)
nonterm[shorter] = true;
}
}
rr.qtype = "#0";
rr.content = "";
rr.ttl = 0;
- for(auto& nt : nonterm)
- {
+ for (auto& nt : nonterm) {
string hashed;
rr.qname = nt.first + zoneName;
- if(nsec3zone && nt.second)
+ if (nsec3zone && nt.second)
hashed = toBase32Hex(hashQNameWithSalt(ns3pr, rr.qname));
insertRecord(records, zoneName, rr.qname, rr.qtype, rr.content, rr.ttl, hashed, &nt.second);
void Bind2Backend::loadConfig(string* status)
{
- static int domain_id=1;
+ static int domain_id = 1;
- if(!getArg("config").empty()) {
+ if (!getArg("config").empty()) {
BindParser BP;
try {
BP.parse(getArg("config"));
}
- catch(PDNSException &ae) {
- g_log<<Logger::Error<<"Error parsing bind configuration: "<<ae.reason<<endl;
+ catch (PDNSException& ae) {
+ g_log << Logger::Error << "Error parsing bind configuration: " << ae.reason << endl;
throw;
}
-
- vector<BindDomainInfo> domains=BP.getDomains();
+
+ vector<BindDomainInfo> domains = BP.getDomains();
this->alsoNotify = BP.getAlsoNotify();
- s_binddirectory=BP.getDirectory();
+ s_binddirectory = BP.getDirectory();
// ZP.setDirectory(d_binddirectory);
- g_log<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
-
+ g_log << Logger::Warning << d_logprefix << " Parsing " << domains.size() << " domain(s), will report when done" << endl;
+
set<DNSName> oldnames, newnames;
{
ReadLock rl(&s_state_lock);
- for(const BB2DomainInfo& bbd : s_state) {
+ for (const BB2DomainInfo& bbd : s_state) {
oldnames.insert(bbd.d_name);
}
}
- int rejected=0;
- int newdomains=0;
+ int rejected = 0;
+ int newdomains = 0;
struct stat st;
-
- for(auto & domain : domains)
- {
- if(stat(domain.filename.c_str(), &st) == 0) {
+
+ for (auto& domain : domains) {
+ if (stat(domain.filename.c_str(), &st) == 0) {
domain.d_dev = st.st_dev;
domain.d_ino = st.st_ino;
}
}
sort(domains.begin(), domains.end()); // put stuff in inode order
- for(const auto & domain : domains)
- {
- if (!(domain.hadFileDirective)) {
- g_log<<Logger::Warning<<d_logprefix<<" Zone '"<<domain.name<<"' has no 'file' directive set in "<<getArg("config")<<endl;
- rejected++;
- continue;
+ for (const auto& domain : domains) {
+ if (!(domain.hadFileDirective)) {
+ g_log << Logger::Warning << d_logprefix << " Zone '" << domain.name << "' has no 'file' directive set in " << getArg("config") << endl;
+ rejected++;
+ continue;
+ }
+
+ if (domain.type == "")
+ g_log << Logger::Notice << d_logprefix << " Zone '" << domain.name << "' has no type specified, assuming 'native'" << endl;
+ if (domain.type != "master" && domain.type != "slave" && domain.type != "native" && domain.type != "") {
+ g_log << Logger::Warning << d_logprefix << " Warning! Skipping zone '" << domain.name << "' because type '" << domain.type << "' is invalid" << endl;
+ rejected++;
+ continue;
+ }
+
+ BB2DomainInfo bbd;
+ bool isNew = false;
+
+ if (!safeGetBBDomainInfo(domain.name, &bbd)) {
+ isNew = true;
+ bbd.d_id = domain_id++;
+ bbd.setCheckInterval(getArgAsNum("check-interval"));
+ bbd.d_lastnotified = 0;
+ bbd.d_loaded = false;
+ }
+
+ // overwrite what we knew about the domain
+ bbd.d_name = domain.name;
+ bool filenameChanged = (bbd.d_filename != domain.filename);
+ bool addressesChanged = (bbd.d_masters != domain.masters || bbd.d_also_notify != domain.alsoNotify);
+ bbd.d_filename = domain.filename;
+ bbd.d_masters = domain.masters;
+ bbd.d_also_notify = domain.alsoNotify;
+
+ DomainInfo::DomainKind kind = DomainInfo::Native;
+ if (domain.type == "master")
+ kind = DomainInfo::Master;
+ if (domain.type == "slave")
+ kind = DomainInfo::Slave;
+
+ bool kindChanged = (bbd.d_kind != kind);
+ bbd.d_kind = kind;
+
+ newnames.insert(bbd.d_name);
+ if (filenameChanged || !bbd.d_loaded || !bbd.current()) {
+ g_log << Logger::Info << d_logprefix << " parsing '" << domain.name << "' from file '" << domain.filename << "'" << endl;
+
+ try {
+ parseZoneFile(&bbd);
}
+ catch (PDNSException& ae) {
+ ostringstream msg;
+ msg << " error at " + nowTime() + " parsing '" << domain.name << "' from file '" << domain.filename << "': " << ae.reason;
+
+ if (status)
+ *status += msg.str();
+ bbd.d_status = msg.str();
- if(domain.type == "")
- g_log<<Logger::Notice<<d_logprefix<<" Zone '"<<domain.name<<"' has no type specified, assuming 'native'"<<endl;
- if(domain.type!="master" && domain.type!="slave" && domain.type != "native" && domain.type != "") {
- g_log<<Logger::Warning<<d_logprefix<<" Warning! Skipping zone '"<<domain.name<<"' because type '"<<domain.type<<"' is invalid"<<endl;
+ g_log << Logger::Warning << d_logprefix << msg.str() << endl;
rejected++;
- continue;
}
+ catch (std::system_error& ae) {
+ ostringstream msg;
+ if (ae.code().value() == ENOENT && isNew && domain.type == "slave")
+ msg << " error at " + nowTime() << " no file found for new slave domain '" << domain.name << "'. Has not been AXFR'd yet";
+ else
+ msg << " error at " + nowTime() + " parsing '" << domain.name << "' from file '" << domain.filename << "': " << ae.what();
+
+ if (status)
+ *status += msg.str();
+ bbd.d_status = msg.str();
+ g_log << Logger::Warning << d_logprefix << msg.str() << endl;
+ rejected++;
+ }
+ catch (std::exception& ae) {
+ ostringstream msg;
+ msg << " error at " + nowTime() + " parsing '" << domain.name << "' from file '" << domain.filename << "': " << ae.what();
- BB2DomainInfo bbd;
- bool isNew = false;
+ if (status)
+ *status += msg.str();
+ bbd.d_status = msg.str();
- if(!safeGetBBDomainInfo(domain.name, &bbd)) {
- isNew = true;
- bbd.d_id=domain_id++;
- bbd.setCheckInterval(getArgAsNum("check-interval"));
- bbd.d_lastnotified=0;
- bbd.d_loaded=false;
- }
-
- // overwrite what we knew about the domain
- bbd.d_name=domain.name;
- bool filenameChanged = (bbd.d_filename!=domain.filename);
- bool addressesChanged = (bbd.d_masters!=domain.masters || bbd.d_also_notify!=domain.alsoNotify);
- bbd.d_filename=domain.filename;
- bbd.d_masters=domain.masters;
- bbd.d_also_notify=domain.alsoNotify;
-
- DomainInfo::DomainKind kind = DomainInfo::Native;
- if (domain.type == "master")
- kind = DomainInfo::Master;
- if (domain.type == "slave")
- kind = DomainInfo::Slave;
-
- bool kindChanged = (bbd.d_kind!=kind);
- bbd.d_kind = kind;
-
- newnames.insert(bbd.d_name);
- if(filenameChanged || !bbd.d_loaded || !bbd.current()) {
- g_log<<Logger::Info<<d_logprefix<<" parsing '"<<domain.name<<"' from file '"<<domain.filename<<"'"<<endl;
-
- try {
- parseZoneFile(&bbd);
- }
- catch(PDNSException &ae) {
- ostringstream msg;
- msg<<" error at "+nowTime()+" parsing '"<<domain.name<<"' from file '"<<domain.filename<<"': "<<ae.reason;
-
- if(status)
- *status+=msg.str();
- bbd.d_status=msg.str();
-
- g_log<<Logger::Warning<<d_logprefix<<msg.str()<<endl;
- rejected++;
- }
- catch(std::system_error &ae) {
- ostringstream msg;
- if (ae.code().value() == ENOENT && isNew && domain.type == "slave")
- msg<<" error at "+nowTime()<<" no file found for new slave domain '"<<domain.name<<"'. Has not been AXFR'd yet";
- else
- msg<<" error at "+nowTime()+" parsing '"<<domain.name<<"' from file '"<<domain.filename<<"': "<<ae.what();
-
- if(status)
- *status+=msg.str();
- bbd.d_status=msg.str();
- g_log<<Logger::Warning<<d_logprefix<<msg.str()<<endl;
- rejected++;
- }
- catch(std::exception &ae) {
- ostringstream msg;
- msg<<" error at "+nowTime()+" parsing '"<<domain.name<<"' from file '"<<domain.filename<<"': "<<ae.what();
-
- if(status)
- *status+=msg.str();
- bbd.d_status=msg.str();
-
- g_log<<Logger::Warning<<d_logprefix<<msg.str()<<endl;
- rejected++;
- }
- safePutBBDomainInfo(bbd);
- } else if(addressesChanged || kindChanged) {
- safePutBBDomainInfo(bbd);
+ g_log << Logger::Warning << d_logprefix << msg.str() << endl;
+ rejected++;
}
+ safePutBBDomainInfo(bbd);
}
+ else if (addressesChanged || kindChanged) {
+ safePutBBDomainInfo(bbd);
+ }
+ }
vector<DNSName> diff;
set_difference(oldnames.begin(), oldnames.end(), newnames.begin(), newnames.end(), back_inserter(diff));
- unsigned int remdomains=diff.size();
-
- for(const DNSName& name: diff) {
+ unsigned int remdomains = diff.size();
+
+ for (const DNSName& name : diff) {
safeRemoveBBDomainInfo(name);
}
// count number of entirely new domains
diff.clear();
set_difference(newnames.begin(), newnames.end(), oldnames.begin(), oldnames.end(), back_inserter(diff));
- newdomains=diff.size();
+ newdomains = diff.size();
ostringstream msg;
- msg<<" Done parsing domains, "<<rejected<<" rejected, "<<newdomains<<" new, "<<remdomains<<" removed";
- if(status)
- *status=msg.str();
+ msg << " Done parsing domains, " << rejected << " rejected, " << newdomains << " new, " << remdomains << " removed";
+ if (status)
+ *status = msg.str();
- g_log<<Logger::Error<<d_logprefix<<msg.str()<<endl;
+ g_log << Logger::Error << d_logprefix << msg.str() << endl;
}
}
{
BB2DomainInfo bbold;
try {
- if(!safeGetBBDomainInfo(id, &bbold))
+ if (!safeGetBBDomainInfo(id, &bbold))
return;
BB2DomainInfo bbnew(bbold);
/* make sure that nothing will be able to alter the existing records,
we will load them from the zone file instead */
bbnew.d_records = LookButDontTouch<recordstorage_t>();
parseZoneFile(&bbnew);
- bbnew.d_checknow=false;
- bbnew.d_wasRejectedLastReload=false;
+ bbnew.d_checknow = false;
+ bbnew.d_wasRejectedLastReload = false;
safePutBBDomainInfo(bbnew);
- g_log<<Logger::Warning<<"Zone '"<<bbnew.d_name<<"' ("<<bbnew.d_filename<<") reloaded"<<endl;
+ g_log << Logger::Warning << "Zone '" << bbnew.d_name << "' (" << bbnew.d_filename << ") reloaded" << endl;
}
- catch(PDNSException &ae) {
+ catch (PDNSException& ae) {
ostringstream msg;
- msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.reason;
- g_log<<Logger::Warning<<" error parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.reason<<endl;
- bbold.d_status=msg.str();
- bbold.d_wasRejectedLastReload=true;
+ msg << " error at " + nowTime() + " parsing '" << bbold.d_name << "' from file '" << bbold.d_filename << "': " << ae.reason;
+ g_log << Logger::Warning << " error parsing '" << bbold.d_name << "' from file '" << bbold.d_filename << "': " << ae.reason << endl;
+ bbold.d_status = msg.str();
+ bbold.d_wasRejectedLastReload = true;
safePutBBDomainInfo(bbold);
}
- catch(std::exception &ae) {
+ catch (std::exception& ae) {
ostringstream msg;
- msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.what();
- g_log<<Logger::Warning<<" error parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.what()<<endl;
- bbold.d_status=msg.str();
- bbold.d_wasRejectedLastReload=true;
+ msg << " error at " + nowTime() + " parsing '" << bbold.d_name << "' from file '" << bbold.d_filename << "': " << ae.what();
+ g_log << Logger::Warning << " error parsing '" << bbold.d_name << "' from file '" << bbold.d_filename << "': " << ae.what() << endl;
+ bbold.d_status = msg.str();
+ bbold.d_wasRejectedLastReload = true;
safePutBBDomainInfo(bbold);
}
}
iterBefore = iterAfter = records->upper_bound(qname.makeLowerCase());
- if(iterBefore != records->begin())
+ if (iterBefore != records->begin())
--iterBefore;
- while((!iterBefore->auth && iterBefore->qtype != QType::NS) || !iterBefore->qtype)
+ while ((!iterBefore->auth && iterBefore->qtype != QType::NS) || !iterBefore->qtype)
--iterBefore;
- before=iterBefore->qname;
+ before = iterBefore->qname;
- if(iterAfter == records->end()) {
+ if (iterAfter == records->end()) {
iterAfter = records->begin();
- } else {
- while((!iterAfter->auth && iterAfter->qtype != QType::NS) || !iterAfter->qtype) {
+ }
+ else {
+ while ((!iterAfter->auth && iterAfter->qtype != QType::NS) || !iterAfter->qtype) {
++iterAfter;
- if(iterAfter == records->end()) {
+ if (iterAfter == records->end()) {
iterAfter = records->begin();
break;
}
bool nsec3zone;
if (d_hybrid) {
DNSSECKeeper dk;
- nsec3zone=dk.getNSEC3PARAM(bbd.d_name, &ns3pr);
- } else
- nsec3zone=getNSEC3PARAM(bbd.d_name, &ns3pr);
+ nsec3zone = dk.getNSEC3PARAM(bbd.d_name, &ns3pr);
+ }
+ else
+ nsec3zone = getNSEC3PARAM(bbd.d_name, &ns3pr);
shared_ptr<const recordstorage_t> records = bbd.d_records.get();
- if(!nsec3zone) {
+ if (!nsec3zone) {
return findBeforeAndAfterUnhashed(records, qname, unhashed, before, after);
}
else {
- auto& hashindex=boost::multi_index::get<NSEC3Tag>(*records);
+ auto& hashindex = boost::multi_index::get<NSEC3Tag>(*records);
// for(auto iter = first; iter != hashindex.end(); iter++)
// cerr<<iter->nsec3hash<<endl;
--iter;
before = DNSName(iter->nsec3hash);
after = DNSName(first->nsec3hash);
- } else {
+ }
+ else {
after = DNSName(iter->nsec3hash);
if (iter != first)
--iter;
iter = --hashindex.end();
before = DNSName(iter->nsec3hash);
}
- unhashed = iter->qname+bbd.d_name;
+ unhashed = iter->qname + bbd.d_name;
return true;
}
}
-void Bind2Backend::lookup(const QType &qtype, const DNSName &qname, int zoneId, DNSPacket *pkt_p )
+void Bind2Backend::lookup(const QType& qtype, const DNSName& qname, int zoneId, DNSPacket* pkt_p)
{
d_handle.reset();
- static bool mustlog=::arg().mustDo("query-logging");
+ static bool mustlog = ::arg().mustDo("query-logging");
bool found;
DNSName domain;
BB2DomainInfo bbd;
- if(mustlog)
- g_log<<Logger::Warning<<"Lookup for '"<<qtype.getName()<<"' of '"<<qname<<"' within zoneID "<<zoneId<<endl;
+ if (mustlog)
+ g_log << Logger::Warning << "Lookup for '" << qtype.getName() << "' of '" << qname << "' within zoneID " << zoneId << endl;
if (zoneId >= 0) {
if ((found = (safeGetBBDomainInfo(zoneId, &bbd) && qname.isPartOf(bbd.d_name)))) {
domain = std::move(bbd.d_name);
}
- } else {
+ }
+ else {
domain = qname;
do {
found = safeGetBBDomainInfo(domain, &bbd);
} while (!found && qtype != QType::SOA && domain.chopOff());
}
- if(!found) {
- if(mustlog)
- g_log<<Logger::Warning<<"Found no authoritative zone for '"<<qname<<"' and/or id "<<zoneId<<endl;
- d_handle.d_list=false;
+ if (!found) {
+ if (mustlog)
+ g_log << Logger::Warning << "Found no authoritative zone for '" << qname << "' and/or id " << zoneId << endl;
+ d_handle.d_list = false;
return;
}
- if(mustlog)
- g_log<<Logger::Warning<<"Found a zone '"<<domain<<"' (with id " << bbd.d_id<<") that might contain data "<<endl;
+ if (mustlog)
+ g_log << Logger::Warning << "Found a zone '" << domain << "' (with id " << bbd.d_id << ") that might contain data " << endl;
- d_handle.id=bbd.d_id;
- d_handle.qname=qname.makeRelative(domain); // strip domain name
- d_handle.qtype=qtype;
- d_handle.domain=std::move(domain);
+ d_handle.id = bbd.d_id;
+ d_handle.qname = qname.makeRelative(domain); // strip domain name
+ d_handle.qtype = qtype;
+ d_handle.domain = std::move(domain);
- if(!bbd.d_loaded) {
+ if (!bbd.d_loaded) {
d_handle.reset();
- throw DBException("Zone for '"+d_handle.domain.toLogString()+"' in '"+bbd.d_filename+"' temporarily not available (file missing, or master dead)"); // fsck
+ throw DBException("Zone for '" + d_handle.domain.toLogString() + "' in '" + bbd.d_filename + "' temporarily not available (file missing, or master dead)"); // fsck
}
-
- if(!bbd.current()) {
- g_log<<Logger::Warning<<"Zone '"<<d_handle.domain<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
+
+ if (!bbd.current()) {
+ g_log << Logger::Warning << "Zone '" << d_handle.domain << "' (" << bbd.d_filename << ") needs reloading" << endl;
queueReloadAndStore(bbd.d_id);
if (!safeGetBBDomainInfo(d_handle.domain, &bbd))
- throw DBException("Zone '"+bbd.d_name.toLogString()+"' ("+bbd.d_filename+") gone after reload"); // if we don't throw here, we crash for some reason
+ throw DBException("Zone '" + bbd.d_name.toLogString() + "' (" + bbd.d_filename + ") gone after reload"); // if we don't throw here, we crash for some reason
}
d_handle.d_records = bbd.d_records.get();
-
- if(d_handle.d_records->empty())
- DLOG(g_log<<"Query with no results"<<endl);
+
+ if (d_handle.d_records->empty())
+ DLOG(g_log << "Query with no results" << endl);
d_handle.mustlog = mustlog;
auto& hashedidx = boost::multi_index::get<UnorderedNameTag>(*d_handle.d_records);
auto range = hashedidx.equal_range(d_handle.qname);
-
- if(range.first==range.second) {
- d_handle.d_list=false;
- d_handle.d_iter = d_handle.d_end_iter = range.first;
+
+ if (range.first == range.second) {
+ d_handle.d_list = false;
+ d_handle.d_iter = d_handle.d_end_iter = range.first;
return;
}
else {
- d_handle.d_iter=range.first;
- d_handle.d_end_iter=range.second;
+ d_handle.d_iter = range.first;
+ d_handle.d_end_iter = range.second;
}
- d_handle.d_list=false;
+ d_handle.d_list = false;
}
Bind2Backend::handle::handle()
{
- mustlog=false;
+ mustlog = false;
}
-bool Bind2Backend::get(DNSResourceRecord &r)
+bool Bind2Backend::get(DNSResourceRecord& r)
{
- if(!d_handle.d_records) {
- if(d_handle.mustlog)
- g_log<<Logger::Warning<<"There were no answers"<<endl;
+ if (!d_handle.d_records) {
+ if (d_handle.mustlog)
+ g_log << Logger::Warning << "There were no answers" << endl;
return false;
}
- if(!d_handle.get(r)) {
- if(d_handle.mustlog)
- g_log<<Logger::Warning<<"End of answers"<<endl;
+ if (!d_handle.get(r)) {
+ if (d_handle.mustlog)
+ g_log << Logger::Warning << "End of answers" << endl;
d_handle.reset();
return false;
}
- if(d_handle.mustlog)
- g_log<<Logger::Warning<<"Returning: '"<<r.qtype.getName()<<"' of '"<<r.qname<<"', content: '"<<r.content<<"'"<<endl;
+ if (d_handle.mustlog)
+ g_log << Logger::Warning << "Returning: '" << r.qtype.getName() << "' of '" << r.qname << "', content: '" << r.content << "'" << endl;
return true;
}
-bool Bind2Backend::handle::get(DNSResourceRecord &r)
+bool Bind2Backend::handle::get(DNSResourceRecord& r)
{
- if(d_list)
+ if (d_list)
return get_list(r);
else
return get_normal(r);
{
d_records.reset();
qname.clear();
- mustlog=false;
+ mustlog = false;
}
//#define DLOG(x) x
-bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
+bool Bind2Backend::handle::get_normal(DNSResourceRecord& r)
{
- DLOG(g_log << "Bind2Backend get() was called for "<<qtype.getName() << " record for '"<<
- qname<<"' - "<<d_records->size()<<" available in total!"<<endl);
-
- if(d_iter==d_end_iter) {
+ DLOG(g_log << "Bind2Backend get() was called for " << qtype.getName() << " record for '" << qname << "' - " << d_records->size() << " available in total!" << endl);
+
+ if (d_iter == d_end_iter) {
return false;
}
- while(d_iter!=d_end_iter && !(qtype.getCode()==QType::ANY || (d_iter)->qtype==qtype.getCode())) {
- DLOG(g_log<<Logger::Warning<<"Skipped "<<qname<<"/"<<QType(d_iter->qtype).getName()<<": '"<<d_iter->content<<"'"<<endl);
+ while (d_iter != d_end_iter && !(qtype.getCode() == QType::ANY || (d_iter)->qtype == qtype.getCode())) {
+ DLOG(g_log << Logger::Warning << "Skipped " << qname << "/" << QType(d_iter->qtype).getName() << ": '" << d_iter->content << "'" << endl);
d_iter++;
}
- if(d_iter==d_end_iter) {
+ if (d_iter == d_end_iter) {
return false;
}
- DLOG(g_log << "Bind2Backend get() returning a rr with a "<<QType(d_iter->qtype).getCode()<<endl);
+ DLOG(g_log << "Bind2Backend get() returning a rr with a " << QType(d_iter->qtype).getCode() << endl);
- r.qname=qname.empty() ? domain : (qname+domain);
- r.domain_id=id;
- r.content=(d_iter)->content;
+ r.qname = qname.empty() ? domain : (qname + domain);
+ r.domain_id = id;
+ r.content = (d_iter)->content;
// r.domain_id=(d_iter)->domain_id;
- r.qtype=(d_iter)->qtype;
- r.ttl=(d_iter)->ttl;
+ r.qtype = (d_iter)->qtype;
+ r.ttl = (d_iter)->ttl;
//if(!d_iter->auth && r.qtype.getCode() != QType::A && r.qtype.getCode()!=QType::AAAA && r.qtype.getCode() != QType::NS)
// cerr<<"Warning! Unauth response for qtype "<< r.qtype.getName() << " for '"<<r.qname<<"'"<<endl;
bool Bind2Backend::list(const DNSName& target, int id, bool include_disabled)
{
BB2DomainInfo bbd;
-
- if(!safeGetBBDomainInfo(id, &bbd))
+
+ if (!safeGetBBDomainInfo(id, &bbd))
return false;
- d_handle.reset();
- DLOG(g_log<<"Bind2Backend constructing handle for list of "<<id<<endl);
+ d_handle.reset();
+ DLOG(g_log << "Bind2Backend constructing handle for list of " << id << endl);
- d_handle.d_records=bbd.d_records.get(); // give it a copy, which will stay around
- d_handle.d_qname_iter= d_handle.d_records->begin();
- d_handle.d_qname_end=d_handle.d_records->end(); // iter now points to a vector of pointers to vector<BBResourceRecords>
+ d_handle.d_records = bbd.d_records.get(); // give it a copy, which will stay around
+ d_handle.d_qname_iter = d_handle.d_records->begin();
+ d_handle.d_qname_end = d_handle.d_records->end(); // iter now points to a vector of pointers to vector<BBResourceRecords>
- d_handle.id=id;
- d_handle.domain=bbd.d_name;
- d_handle.d_list=true;
+ d_handle.id = id;
+ d_handle.domain = bbd.d_name;
+ d_handle.d_list = true;
return true;
}
-bool Bind2Backend::handle::get_list(DNSResourceRecord &r)
+bool Bind2Backend::handle::get_list(DNSResourceRecord& r)
{
- if(d_qname_iter!=d_qname_end) {
- r.qname=d_qname_iter->qname.empty() ? domain : (d_qname_iter->qname+domain);
- r.domain_id=id;
- r.content=(d_qname_iter)->content;
- r.qtype=(d_qname_iter)->qtype;
- r.ttl=(d_qname_iter)->ttl;
+ if (d_qname_iter != d_qname_end) {
+ r.qname = d_qname_iter->qname.empty() ? domain : (d_qname_iter->qname + domain);
+ r.domain_id = id;
+ r.content = (d_qname_iter)->content;
+ r.qtype = (d_qname_iter)->qtype;
+ r.ttl = (d_qname_iter)->ttl;
r.auth = d_qname_iter->auth;
d_qname_iter++;
return true;
return false;
}
-bool Bind2Backend::superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
+bool Bind2Backend::superMasterBackend(const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** db)
{
// Check whether we have a configfile available.
if (getArg("supermaster-config").empty())
ii >> saccount;
break;
}
- }
+ }
c_if.close();
- if (sip != ip) // ip not found in authorization list - reject
+ if (sip != ip) // ip not found in authorization list - reject
return false;
-
+
// ip authorized as supermaster - accept
*db = this;
if (saccount.length() > 0)
- *account = saccount.c_str();
+ *account = saccount.c_str();
return true;
}
-
-BB2DomainInfo Bind2Backend::createDomainEntry(const DNSName& domain, const string &filename)
+BB2DomainInfo Bind2Backend::createDomainEntry(const DNSName& domain, const string& filename)
{
- int newid=1;
- { // Find a free zone id nr.
+ int newid = 1;
+ { // Find a free zone id nr.
ReadLock rl(&s_state_lock);
if (!s_state.empty()) {
// older (1.53) versions of boost have an expression for s_state.rbegin()
// that is ambiguous in C++17. So construct it explicitly
- newid = boost::make_reverse_iterator(s_state.end())->d_id+1;
+ newid = boost::make_reverse_iterator(s_state.end())->d_id + 1;
}
}
-
+
BB2DomainInfo bbd;
bbd.d_kind = DomainInfo::Native;
bbd.d_id = newid;
- bbd.d_records = std::make_shared<recordstorage_t >();
+ bbd.d_records = std::make_shared<recordstorage_t>();
bbd.d_name = domain;
bbd.setCheckInterval(getArgAsNum("check-interval"));
bbd.d_filename = filename;
-
+
return bbd;
}
-bool Bind2Backend::createSlaveDomain(const string &ip, const DNSName& domain, const string &nameserver, const string &account)
+bool Bind2Backend::createSlaveDomain(const string& ip, const DNSName& domain, const string& nameserver, const string& account)
{
- string filename = getArg("supermaster-destdir")+'/'+domain.toStringNoDot();
-
+ string filename = getArg("supermaster-destdir") + '/' + domain.toStringNoDot();
+
g_log << Logger::Warning << d_logprefix
- << " Writing bind config zone statement for superslave zone '" << domain
- << "' from supermaster " << ip << endl;
+ << " Writing bind config zone statement for superslave zone '" << domain
+ << "' from supermaster " << ip << endl;
{
std::lock_guard<std::mutex> l2(s_supermaster_config_lock);
-
- ofstream c_of(getArg("supermaster-config").c_str(), std::ios::app);
+
+ ofstream c_of(getArg("supermaster-config").c_str(), std::ios::app);
if (!c_of) {
g_log << Logger::Error << "Unable to open supermaster configfile for append: " << stringerror() << endl;
- throw DBException("Unable to open supermaster configfile for append: "+stringerror());
+ throw DBException("Unable to open supermaster configfile for append: " + stringerror());
}
-
+
c_of << endl;
c_of << "# Superslave zone '" << domain.toString() << "' (added: " << nowTime() << ") (account: " << account << ')' << endl;
c_of << "zone \"" << domain.toStringNoDot() << "\" {" << endl;
return true;
}
-bool Bind2Backend::searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result)
+bool Bind2Backend::searchRecords(const string& pattern, int maxResults, vector<DNSResourceRecord>& result)
{
- SimpleMatch sm(pattern,true);
- static bool mustlog=::arg().mustDo("query-logging");
- if(mustlog)
- g_log<<Logger::Warning<<"Search for pattern '"<<pattern<<"'"<<endl;
+ SimpleMatch sm(pattern, true);
+ static bool mustlog = ::arg().mustDo("query-logging");
+ if (mustlog)
+ g_log << Logger::Warning << "Search for pattern '" << pattern << "'" << endl;
{
ReadLock rl(&s_state_lock);
- for(const auto & i : s_state) {
+ for (const auto& i : s_state) {
BB2DomainInfo h;
if (!safeGetBBDomainInfo(i.d_id, &h)) {
continue;
shared_ptr<const recordstorage_t> rhandle = h.d_records.get();
- for(recordstorage_t::const_iterator ri = rhandle->begin(); result.size() < static_cast<vector<DNSResourceRecord>::size_type>(maxResults) && ri != rhandle->end(); ri++) {
- DNSName name = ri->qname.empty() ? i.d_name : (ri->qname+i.d_name);
+ for (recordstorage_t::const_iterator ri = rhandle->begin(); result.size() < static_cast<vector<DNSResourceRecord>::size_type>(maxResults) && ri != rhandle->end(); ri++) {
+ DNSName name = ri->qname.empty() ? i.d_name : (ri->qname + i.d_name);
if (sm.match(name) || sm.match(ri->content)) {
DNSResourceRecord r;
- r.qname=name;
- r.domain_id=i.d_id;
- r.content=ri->content;
- r.qtype=ri->qtype;
- r.ttl=ri->ttl;
+ r.qname = name;
+ r.domain_id = i.d_id;
+ r.content = ri->content;
+ r.qtype = ri->qtype;
+ r.ttl = ri->ttl;
r.auth = ri->auth;
result.push_back(std::move(r));
}
class Bind2Factory : public BackendFactory
{
- public:
- Bind2Factory() : BackendFactory("bind") {}
-
- void declareArguments(const string &suffix="") override
- {
- declare(suffix,"ignore-broken-records","Ignore records that are out-of-bound for the zone.","no");
- declare(suffix,"config","Location of named.conf","");
- declare(suffix,"check-interval","Interval for zonefile changes","0");
- declare(suffix,"supermaster-config","Location of (part of) named.conf where pdns can write zone-statements to","");
- declare(suffix,"supermasters","List of IP-addresses of supermasters","");
- declare(suffix,"supermaster-destdir","Destination directory for newly added slave zones",::arg()["config-dir"]);
- declare(suffix,"dnssec-db","Filename to store & access our DNSSEC metadatabase, empty for none", "");
- declare(suffix,"dnssec-db-journal-mode","SQLite3 journal mode", "WAL");
- declare(suffix,"hybrid","Store DNSSEC metadata in other backend","no");
- }
+public:
+ Bind2Factory() :
+ BackendFactory("bind") {}
- DNSBackend *make(const string &suffix="") override
- {
- assertEmptySuffix(suffix);
- return new Bind2Backend(suffix);
- }
-
- DNSBackend *makeMetadataOnly(const string &suffix="") override
- {
- assertEmptySuffix(suffix);
- return new Bind2Backend(suffix, false);
- }
- private:
- void assertEmptySuffix(const string &suffix)
- {
- if(suffix.length())
- throw PDNSException("launch= suffixes are not supported on the bindbackend");
- }
+ void declareArguments(const string& suffix = "") override
+ {
+ declare(suffix, "ignore-broken-records", "Ignore records that are out-of-bound for the zone.", "no");
+ declare(suffix, "config", "Location of named.conf", "");
+ declare(suffix, "check-interval", "Interval for zonefile changes", "0");
+ declare(suffix, "supermaster-config", "Location of (part of) named.conf where pdns can write zone-statements to", "");
+ declare(suffix, "supermasters", "List of IP-addresses of supermasters", "");
+ declare(suffix, "supermaster-destdir", "Destination directory for newly added slave zones", ::arg()["config-dir"]);
+ declare(suffix, "dnssec-db", "Filename to store & access our DNSSEC metadatabase, empty for none", "");
+ declare(suffix, "dnssec-db-journal-mode", "SQLite3 journal mode", "WAL");
+ declare(suffix, "hybrid", "Store DNSSEC metadata in other backend", "no");
+ }
+
+ DNSBackend* make(const string& suffix = "") override
+ {
+ assertEmptySuffix(suffix);
+ return new Bind2Backend(suffix);
+ }
+
+ DNSBackend* makeMetadataOnly(const string& suffix = "") override
+ {
+ assertEmptySuffix(suffix);
+ return new Bind2Backend(suffix, false);
+ }
+
+private:
+ void assertEmptySuffix(const string& suffix)
+ {
+ if (suffix.length())
+ throw PDNSException("launch= suffixes are not supported on the bindbackend");
+ }
};
//! Magic class that is activated when the dynamic library is loaded
BackendMakers().report(new Bind2Factory);
g_log << Logger::Info << "[bind2backend] This is the bind backend version " << VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
#ifdef HAVE_SQLITE3
- << " (with bind-dnssec-db support)"
+ << " (with bind-dnssec-db support)"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
static Bind2Loader bind2loader;
mutable bool auth;
bool operator<(const Bind2DNSRecord& rhs) const
{
- if(qname.canonCompare(rhs.qname))
+ if (qname.canonCompare(rhs.qname))
return true;
- if(rhs.qname.canonCompare(qname))
+ if (rhs.qname.canonCompare(qname))
return false;
- if(qtype==QType::SOA && rhs.qtype!=QType::SOA)
+ if (qtype == QType::SOA && rhs.qtype != QType::SOA)
return true;
- return tie(qtype,content, ttl) < tie(rhs.qtype, rhs.content, rhs.ttl);
+ return tie(qtype, content, ttl) < tie(rhs.qtype, rhs.content, rhs.ttl);
}
};
-struct Bind2DNSCompare : std::less<Bind2DNSRecord>
-{
- using std::less<Bind2DNSRecord>::operator();
- // use operator<
- bool operator() (const DNSName& a, const Bind2DNSRecord& b) const
- {return a.canonCompare(b.qname);}
- bool operator() (const Bind2DNSRecord& a, const DNSName& b) const
- {return a.qname.canonCompare(b);}
- bool operator() (const Bind2DNSRecord& a, const Bind2DNSRecord& b) const
- {return a.qname.canonCompare(b.qname);}
+struct Bind2DNSCompare : std::less<Bind2DNSRecord>
+{
+ using std::less<Bind2DNSRecord>::operator();
+ // use operator<
+ bool operator()(const DNSName& a, const Bind2DNSRecord& b) const
+ {
+ return a.canonCompare(b.qname);
+ }
+ bool operator()(const Bind2DNSRecord& a, const DNSName& b) const
+ {
+ return a.qname.canonCompare(b);
+ }
+ bool operator()(const Bind2DNSRecord& a, const Bind2DNSRecord& b) const
+ {
+ return a.qname.canonCompare(b.qname);
+ }
};
-struct NSEC3Tag{};
-struct UnorderedNameTag{};
+struct NSEC3Tag
+{
+};
+struct UnorderedNameTag
+{
+};
typedef multi_index_container<
Bind2DNSRecord,
- indexed_by <
- ordered_non_unique<identity<Bind2DNSRecord>, Bind2DNSCompare >,
- hashed_non_unique<tag<UnorderedNameTag>, member<Bind2DNSRecord, DNSName, &Bind2DNSRecord::qname> >,
- ordered_non_unique<tag<NSEC3Tag>, member<Bind2DNSRecord, std::string, &Bind2DNSRecord::nsec3hash> >
- >
-> recordstorage_t;
+ indexed_by<
+ ordered_non_unique<identity<Bind2DNSRecord>, Bind2DNSCompare>,
+ hashed_non_unique<tag<UnorderedNameTag>, member<Bind2DNSRecord, DNSName, &Bind2DNSRecord::qname>>,
+ ordered_non_unique<tag<NSEC3Tag>, member<Bind2DNSRecord, std::string, &Bind2DNSRecord::nsec3hash>>>>
+ recordstorage_t;
template <typename T>
class LookButDontTouch // : public boost::noncopyable
LookButDontTouch()
{
}
- LookButDontTouch(shared_ptr<T> records) : d_records(records)
+ LookButDontTouch(shared_ptr<T> records) :
+ d_records(records)
{
}
shared_ptr<T> d_records;
};
-
/** Class which describes all metadata of a domain for storage by the Bind2Backend, and also contains a pointer to a vector of Bind2DNSRecord's */
class BB2DomainInfo
{
return d_checkinterval;
}
- DNSName d_name; //!< actual name of the domain
+ DNSName d_name; //!< actual name of the domain
DomainInfo::DomainKind d_kind; //!< the kind of domain
string d_filename; //!< full absolute filename of the zone on disk
string d_status; //!< message describing status of a domain, for human consumption
- vector<ComboAddress> d_masters; //!< IP address of the master of this domain
+ vector<ComboAddress> d_masters; //!< IP address of the master of this domain
set<string> d_also_notify; //!< IP list of hosts to also notify
- LookButDontTouch<recordstorage_t> d_records; //!< the actual records belonging to this domain
- time_t d_ctime{0}; //!< last known ctime of the file on disk
+ LookButDontTouch<recordstorage_t> d_records; //!< the actual records belonging to this domain
+ time_t d_ctime{0}; //!< last known ctime of the file on disk
time_t d_lastcheck{0}; //!< last time domain was checked for freshness
uint32_t d_lastnotified{0}; //!< Last serial number we notified our slaves of
- unsigned int d_id; //!< internal id of the domain
+ unsigned int d_id; //!< internal id of the domain
mutable bool d_checknow; //!< if this domain has been flagged for a check
- bool d_loaded; //!< if a domain is loaded
+ bool d_loaded; //!< if a domain is loaded
bool d_wasRejectedLastReload{false}; //!< if the domain was rejected during Bind2Backend::queueReloadAndStore
private:
class NSEC3PARAMRecordContent;
struct NameTag
-{};
+{
+};
class Bind2Backend : public DNSBackend
{
public:
- Bind2Backend(const string &suffix="", bool loadZones=true);
+ Bind2Backend(const string& suffix = "", bool loadZones = true);
~Bind2Backend();
- void getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains) override;
- void getUpdatedMasters(vector<DomainInfo> *changedDomains) override;
- bool getDomainInfo(const DNSName &domain, DomainInfo &di, bool getSerial=true ) override;
- time_t getCtime(const string &fname);
- // DNSSEC
+ void getUnfreshSlaveInfos(vector<DomainInfo>* unfreshDomains) override;
+ void getUpdatedMasters(vector<DomainInfo>* changedDomains) override;
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
+ time_t getCtime(const string& fname);
+ // DNSSEC
bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override;
- void lookup(const QType &, const DNSName &qdomain, int zoneId, DNSPacket *p=nullptr) override;
- bool list(const DNSName &target, int id, bool include_disabled=false) override;
- bool get(DNSResourceRecord &) override;
- void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
+ void lookup(const QType&, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override;
+ bool list(const DNSName& target, int id, bool include_disabled = false) override;
+ bool get(DNSResourceRecord&) override;
+ void getAllDomains(vector<DomainInfo>* domains, bool include_disabled = false) override;
- static DNSBackend *maker();
+ static DNSBackend* maker();
static std::mutex s_startup_lock;
void setFresh(uint32_t domain_id) override;
void setNotified(uint32_t id, uint32_t serial) override;
- bool startTransaction(const DNSName &qname, int id) override;
- bool feedRecord(const DNSResourceRecord &rr, const DNSName &ordername, bool ordernameIsNSEC3=false) override;
+ bool startTransaction(const DNSName& qname, int id) override;
+ bool feedRecord(const DNSResourceRecord& rr, const DNSName& ordername, bool ordernameIsNSEC3 = false) override;
bool commitTransaction() override;
bool abortTransaction() override;
- void alsoNotifies(const DNSName &domain, set<string> *ips) override;
- bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result) override;
+ void alsoNotifies(const DNSName& domain, set<string>* ips) override;
+ bool searchRecords(const string& pattern, int maxResults, vector<DNSResourceRecord>& result) override;
-// the DNSSEC related (getDomainMetadata has broader uses too)
- bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override;
+ // the DNSSEC related (getDomainMetadata has broader uses too)
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta) override;
bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override;
bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) override;
bool getDomainKeys(const DNSName& name, std::vector<KeyData>& keys) override;
bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content) override;
bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) override;
bool deleteTSIGKey(const DNSName& name) override;
- bool getTSIGKeys(std::vector< struct TSIGKey > &keys) override;
+ bool getTSIGKeys(std::vector<struct TSIGKey>& keys) override;
bool doesDNSSEC() override;
- // end of DNSSEC
+ // end of DNSSEC
- typedef multi_index_container < BB2DomainInfo ,
- indexed_by < ordered_unique<member<BB2DomainInfo, unsigned int, &BB2DomainInfo::d_id> >,
- ordered_unique<tag<NameTag>, member<BB2DomainInfo, DNSName, &BB2DomainInfo::d_name> >
- > > state_t;
+ typedef multi_index_container<BB2DomainInfo,
+ indexed_by<ordered_unique<member<BB2DomainInfo, unsigned int, &BB2DomainInfo::d_id>>,
+ ordered_unique<tag<NameTag>, member<BB2DomainInfo, DNSName, &BB2DomainInfo::d_name>>>>
+ state_t;
static state_t s_state;
static ReadWriteLock s_state_lock;
- void parseZoneFile(BB2DomainInfo *bbd);
- void rediscover(string *status=nullptr) override;
-
+ void parseZoneFile(BB2DomainInfo* bbd);
+ void rediscover(string* status = nullptr) override;
// for supermaster support
- bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db) override;
+ bool superMasterBackend(const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** db) override;
static std::mutex s_supermaster_config_lock;
- bool createSlaveDomain(const string &ip, const DNSName &domain, const string &nameserver, const string &account) override;
+ bool createSlaveDomain(const string& ip, const DNSName& domain, const string& nameserver, const string& account) override;
private:
void setupDNSSEC();
class handle
{
public:
- bool get(DNSResourceRecord &);
+ bool get(DNSResourceRecord&);
void reset();
-
+
handle();
- shared_ptr<const recordstorage_t > d_records;
+ shared_ptr<const recordstorage_t> d_records;
recordstorage_t::index<UnorderedNameTag>::type::const_iterator d_iter, d_end_iter;
recordstorage_t::const_iterator d_qname_iter, d_qname_end;
bool mustlog;
private:
- bool get_normal(DNSResourceRecord &);
- bool get_list(DNSResourceRecord &);
+ bool get_normal(DNSResourceRecord&);
+ bool get_list(DNSResourceRecord&);
- void operator=(const handle& ); // don't go copying this
- handle(const handle &);
+ void operator=(const handle&); // don't go copying this
+ handle(const handle&);
};
unique_ptr<SSqlStatement> d_getAllDomainMetadataQuery_stmt;
set<string> alsoNotify; //!< this is used to store the also-notify list of interested peers.
std::unique_ptr<ofstream> d_of;
handle d_handle;
- static string s_binddirectory; //!< this is used to store the 'directory' setting of the bind configuration
- static int s_first; //!< this is raised on construction to prevent multiple instances of us being generated
+ static string s_binddirectory; //!< this is used to store the 'directory' setting of the bind configuration
+ static int s_first; //!< this is raised on construction to prevent multiple instances of us being generated
int d_transaction_id;
static bool s_ignore_broken_records;
bool d_hybrid;
bool d_upgradeContent;
- BB2DomainInfo createDomainEntry(const DNSName& domain, const string &filename); //!< does not insert in s_state
+ BB2DomainInfo createDomainEntry(const DNSName& domain, const string& filename); //!< does not insert in s_state
void queueReloadAndStore(unsigned int id);
static bool findBeforeAndAfterUnhashed(std::shared_ptr<const recordstorage_t>& records, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after);
- static void insertRecord(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, const DNSName &qname, const QType &qtype, const string &content, int ttl, const std::string& hashed=string(), bool *auth=nullptr);
+ static void insertRecord(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, const DNSName& qname, const QType& qtype, const string& content, int ttl, const std::string& hashed = string(), bool* auth = nullptr);
void reload() override;
- static string DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
- static string DLDomExtendedStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
- static string DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid);
- static string DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid);
- static string DLAddDomainHandler(const vector<string>&parts, Utility::pid_t ppid);
+ static string DLDomStatusHandler(const vector<string>& parts, Utility::pid_t ppid);
+ static string DLDomExtendedStatusHandler(const vector<string>& parts, Utility::pid_t ppid);
+ static string DLListRejectsHandler(const vector<string>& parts, Utility::pid_t ppid);
+ static string DLReloadNowHandler(const vector<string>& parts, Utility::pid_t ppid);
+ static string DLAddDomainHandler(const vector<string>& parts, Utility::pid_t ppid);
static void fixupOrderAndAuth(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, bool nsec3zone, const NSEC3PARAMRecordContent& ns3pr);
static void doEmptyNonTerminals(std::shared_ptr<recordstorage_t>& records, const DNSName& zoneName, bool nsec3zone, const NSEC3PARAMRecordContent& ns3pr);
- void loadConfig(string *status=nullptr);
+ void loadConfig(string* status = nullptr);
};
void Bind2Backend::setupDNSSEC()
{
- if(!getArg("dnssec-db").empty())
+ if (!getArg("dnssec-db").empty())
throw runtime_error("bind-dnssec-db requires building PowerDNS with SQLite3");
}
bool Bind2Backend::doesDNSSEC()
-{ return d_hybrid; }
+{
+ return d_hybrid;
+}
bool Bind2Backend::getNSEC3PARAM(const DNSName& name, NSEC3PARAMRecordContent* ns3p)
-{ return false; }
+{
+ return false;
+}
-bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
-{ return false; }
+bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
+{
+ return false;
+}
bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::getDomainKeys(const DNSName& name, std::vector<KeyData>& keys)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::publishDomainKey(const DNSName& name, unsigned int id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::unpublishDomainKey(const DNSName& name, unsigned int id)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
-{ return false; }
+{
+ return false;
+}
bool Bind2Backend::deleteTSIGKey(const DNSName& name)
-{ return false; }
+{
+ return false;
+}
-bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey> &keys)
-{ return false; }
+bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
+{
+ return false;
+}
void Bind2Backend::setupStatements()
-{ return; }
+{
+ return;
+}
void Bind2Backend::freeStatements()
-{ return; }
+{
+ return;
+}
#else
#include "pdns/logger.hh"
#include "pdns/ssqlite3.hh"
-#define ASSERT_ROW_COLUMNS(query, row, num) { if (row.size() != num) { throw PDNSException(std::string(query) + " returned wrong number of columns, expected " #num ", got " + std::to_string(row.size())); } }
+#define ASSERT_ROW_COLUMNS(query, row, num) \
+ { \
+ if (row.size() != num) { \
+ throw PDNSException(std::string(query) + " returned wrong number of columns, expected " #num ", got " + std::to_string(row.size())); \
+ } \
+ }
void Bind2Backend::setupDNSSEC()
{
- if(getArg("dnssec-db").empty() || d_hybrid)
+ if (getArg("dnssec-db").empty() || d_hybrid)
return;
try {
d_dnssecdb = shared_ptr<SSQLite3>(new SSQLite3(getArg("dnssec-db"), getArg("dnssec-db-journal-mode")));
setupStatements();
}
- catch(SSqlException& se) {
+ catch (SSqlException& se) {
// this error is meant to kill the server dead - it makes no sense to continue..
- throw runtime_error("Error opening DNSSEC database in BIND backend: "+se.txtReason());
+ throw runtime_error("Error opening DNSSEC database in BIND backend: " + se.txtReason());
}
d_dnssecdb->setLog(::arg().mustDo("query-logging"));
void Bind2Backend::setupStatements()
{
- d_getAllDomainMetadataQuery_stmt = d_dnssecdb->prepare("select kind, content from domainmetadata where domain=:domain",1);
- d_getDomainMetadataQuery_stmt = d_dnssecdb->prepare("select content from domainmetadata where domain=:domain and kind=:kind",2);
- d_deleteDomainMetadataQuery_stmt = d_dnssecdb->prepare("delete from domainmetadata where domain=:domain and kind=:kind",2);
- d_insertDomainMetadataQuery_stmt = d_dnssecdb->prepare("insert into domainmetadata (domain, kind, content) values (:domain,:kind,:content)",3);
- d_getDomainKeysQuery_stmt = d_dnssecdb->prepare("select id,flags, active, published, content from cryptokeys where domain=:domain",1);
- d_deleteDomainKeyQuery_stmt = d_dnssecdb->prepare("delete from cryptokeys where domain=:domain and id=:key_id",2);
+ d_getAllDomainMetadataQuery_stmt = d_dnssecdb->prepare("select kind, content from domainmetadata where domain=:domain", 1);
+ d_getDomainMetadataQuery_stmt = d_dnssecdb->prepare("select content from domainmetadata where domain=:domain and kind=:kind", 2);
+ d_deleteDomainMetadataQuery_stmt = d_dnssecdb->prepare("delete from domainmetadata where domain=:domain and kind=:kind", 2);
+ d_insertDomainMetadataQuery_stmt = d_dnssecdb->prepare("insert into domainmetadata (domain, kind, content) values (:domain,:kind,:content)", 3);
+ d_getDomainKeysQuery_stmt = d_dnssecdb->prepare("select id,flags, active, published, content from cryptokeys where domain=:domain", 1);
+ d_deleteDomainKeyQuery_stmt = d_dnssecdb->prepare("delete from cryptokeys where domain=:domain and id=:key_id", 2);
d_insertDomainKeyQuery_stmt = d_dnssecdb->prepare("insert into cryptokeys (domain, flags, active, published, content) values (:domain, :flags, :active, :published, :content)", 5);
d_GetLastInsertedKeyIdQuery_stmt = d_dnssecdb->prepare("select last_insert_rowid()", 0);
d_activateDomainKeyQuery_stmt = d_dnssecdb->prepare("update cryptokeys set active=1 where domain=:domain and id=:key_id", 2);
bool Bind2Backend::getNSEC3PARAM(const DNSName& name, NSEC3PARAMRecordContent* ns3p)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
string value;
vector<string> meta;
getDomainMetadata(name, "NSEC3PARAM", meta);
- if(!meta.empty())
- value=*meta.begin();
+ if (!meta.empty())
+ value = *meta.begin();
else
return false; // No NSEC3 zone
- static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations");
- if(ns3p) {
- auto tmp=std::dynamic_pointer_cast<NSEC3PARAMRecordContent>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value));
+ static int maxNSEC3Iterations = ::arg().asNum("max-nsec3-iterations");
+ if (ns3p) {
+ auto tmp = std::dynamic_pointer_cast<NSEC3PARAMRecordContent>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value));
*ns3p = *tmp;
if (ns3p->d_iterations > maxNSEC3Iterations) {
ns3p->d_iterations = maxNSEC3Iterations;
- g_log<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<name<<"' is above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl;
+ g_log << Logger::Error << "Number of NSEC3 iterations for zone '" << name << "' is above 'max-nsec3-iterations'. Value adjusted to: " << maxNSEC3Iterations << endl;
}
if (ns3p->d_algorithm != 1) {
- g_log<<Logger::Error<<"Invalid hash algorithm for NSEC3: '"<<std::to_string(ns3p->d_algorithm)<<"', setting to 1 for zone '"<<name<<"'."<<endl;
+ g_log << Logger::Error << "Invalid hash algorithm for NSEC3: '" << std::to_string(ns3p->d_algorithm) << "', setting to 1 for zone '" << name << "'." << endl;
ns3p->d_algorithm = 1;
}
}
return true;
}
-bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
+bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_getAllDomainMetadataQuery_stmt->
- bind("domain", name)->
- execute();
+ d_getAllDomainMetadataQuery_stmt->bind("domain", name)->execute();
SSqlStatement::row_t row;
- while(d_getAllDomainMetadataQuery_stmt->hasNextRow()) {
+ while (d_getAllDomainMetadataQuery_stmt->hasNextRow()) {
d_getAllDomainMetadataQuery_stmt->nextRow(row);
meta[row[0]].push_back(row[1]);
}
d_getAllDomainMetadataQuery_stmt->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, getAllDomainMetadata(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, getAllDomainMetadata(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_getDomainMetadataQuery_stmt->
- bind("domain", name)->
- bind("kind", kind)->
- execute();
+ d_getDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->execute();
SSqlStatement::row_t row;
- while(d_getDomainMetadataQuery_stmt->hasNextRow()) {
+ while (d_getDomainMetadataQuery_stmt->hasNextRow()) {
d_getDomainMetadataQuery_stmt->nextRow(row);
meta.push_back(row[0]);
}
d_getDomainMetadataQuery_stmt->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainMetadata(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainMetadata(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_deleteDomainMetadataQuery_stmt->
- bind("domain", name)->
- bind("kind", kind)->
- execute()->
- reset();
- if(!meta.empty()) {
- for(const auto& value: meta) {
- d_insertDomainMetadataQuery_stmt->
- bind("domain", name)->
- bind("kind", kind)->
- bind("content", value)->
- execute()->
- reset();
+ d_deleteDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->execute()->reset();
+ if (!meta.empty()) {
+ for (const auto& value : meta) {
+ d_insertDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->bind("content", value)->execute()->reset();
}
}
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, setDomainMetadata(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, setDomainMetadata(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::getDomainKeys(const DNSName& name, std::vector<KeyData>& keys)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_getDomainKeysQuery_stmt->
- bind("domain", name)->
- execute();
+ d_getDomainKeysQuery_stmt->bind("domain", name)->execute();
KeyData kd;
SSqlStatement::row_t row;
- while(d_getDomainKeysQuery_stmt->hasNextRow()) {
+ while (d_getDomainKeysQuery_stmt->hasNextRow()) {
d_getDomainKeysQuery_stmt->nextRow(row);
kd.id = pdns_stou(row[0]);
kd.flags = pdns_stou(row[1]);
d_getDomainKeysQuery_stmt->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainKeys(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainKeys(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_deleteDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("key_id", id)->
- execute()->
- reset();
+ d_deleteDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, removeDomainKeys(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, removeDomainKeys(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_insertDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("flags", key.flags)->
- bind("active", key.active)->
- bind("published", key.published)->
- bind("content", key.content)->
- execute()->
- reset();
+ d_insertDomainKeyQuery_stmt->bind("domain", name)->bind("flags", key.flags)->bind("active", key.active)->bind("published", key.published)->bind("content", key.content)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, addDomainKey(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, addDomainKey(): " + se.txtReason());
}
try {
d_GetLastInsertedKeyIdQuery_stmt->reset();
return true;
}
- catch (SSqlException &e) {
+ catch (SSqlException& e) {
id = -2;
return true;
}
bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_activateDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("key_id", id)->
- execute()->
- reset();
+ d_activateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, activateDomainKey(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, activateDomainKey(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_deactivateDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("key_id", id)->
- execute()->
- reset();
+ d_deactivateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, deactivateDomainKey(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, deactivateDomainKey(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::publishDomainKey(const DNSName& name, unsigned int id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_publishDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("key_id", id)->
- execute()->
- reset();
+ d_publishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, publishDomainKey(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, publishDomainKey(): " + se.txtReason());
}
return true;
}
bool Bind2Backend::unpublishDomainKey(const DNSName& name, unsigned int id)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_unpublishDomainKeyQuery_stmt->
- bind("domain", name)->
- bind("key_id", id)->
- execute()->
- reset();
+ d_unpublishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
}
- catch(SSqlException& se) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, unpublishDomainKey(): "+se.txtReason());
+ catch (SSqlException& se) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, unpublishDomainKey(): " + se.txtReason());
}
return true;
}
-
bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_getTSIGKeyQuery_stmt->
- bind("key_name", name)->
- execute();
+ d_getTSIGKeyQuery_stmt->bind("key_name", name)->execute();
SSqlStatement::row_t row;
content->clear();
- while(d_getTSIGKeyQuery_stmt->hasNextRow()) {
+ while (d_getTSIGKeyQuery_stmt->hasNextRow()) {
d_getTSIGKeyQuery_stmt->nextRow(row);
- if(row.size() >= 2 && (algorithm->empty() || *algorithm == DNSName(row[0]))) {
+ if (row.size() >= 2 && (algorithm->empty() || *algorithm == DNSName(row[0]))) {
*algorithm = DNSName(row[0]);
*content = row[1];
}
d_getTSIGKeyQuery_stmt->reset();
}
- catch (SSqlException &e) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKey(): "+e.txtReason());
+ catch (SSqlException& e) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKey(): " + e.txtReason());
}
return !content->empty();
}
bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_setTSIGKeyQuery_stmt->
- bind("key_name", name)->
- bind("algorithm", algorithm)->
- bind("content", content)->
- execute()->
- reset();
+ d_setTSIGKeyQuery_stmt->bind("key_name", name)->bind("algorithm", algorithm)->bind("content", content)->execute()->reset();
}
- catch (SSqlException &e) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, setTSIGKey(): "+e.txtReason());
+ catch (SSqlException& e) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, setTSIGKey(): " + e.txtReason());
}
return true;
}
bool Bind2Backend::deleteTSIGKey(const DNSName& name)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_deleteTSIGKeyQuery_stmt->
- bind("key_name", name)->
- execute()->
- reset();
+ d_deleteTSIGKeyQuery_stmt->bind("key_name", name)->execute()->reset();
}
- catch (SSqlException &e) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, deleteTSIGKey(): "+e.txtReason());
+ catch (SSqlException& e) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, deleteTSIGKey(): " + e.txtReason());
}
return true;
}
-bool Bind2Backend::getTSIGKeys(std::vector< struct TSIGKey > &keys)
+bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
{
- if(!d_dnssecdb || d_hybrid)
+ if (!d_dnssecdb || d_hybrid)
return false;
try {
- d_getTSIGKeysQuery_stmt->
- execute();
+ d_getTSIGKeysQuery_stmt->execute();
SSqlStatement::row_t row;
- while(d_getTSIGKeysQuery_stmt->hasNextRow()) {
+ while (d_getTSIGKeysQuery_stmt->hasNextRow()) {
d_getTSIGKeysQuery_stmt->nextRow(row);
struct TSIGKey key;
key.name = DNSName(row[0]);
d_getTSIGKeysQuery_stmt->reset();
}
- catch (SSqlException &e) {
- throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKeys(): "+e.txtReason());
+ catch (SSqlException& e) {
+ throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKeys(): " + e.txtReason());
}
return !keys.empty();
}
ReadWriteLock GeoIPBackend::s_state_lock;
-struct GeoIPDNSResourceRecord: DNSResourceRecord {
+struct GeoIPDNSResourceRecord : DNSResourceRecord
+{
int weight;
bool has_weight;
};
-struct GeoIPService {
- NetmaskTree<vector<string> > masks;
+struct GeoIPService
+{
+ NetmaskTree<vector<string>> masks;
unsigned int netmask4;
unsigned int netmask6;
};
-struct GeoIPDomain {
+struct GeoIPDomain
+{
int id;
DNSName domain;
int ttl;
map<DNSName, GeoIPService> services;
- map<DNSName, vector<GeoIPDNSResourceRecord> > records;
+ map<DNSName, vector<GeoIPDNSResourceRecord>> records;
vector<string> mapping_lookup_formats;
map<std::string, std::string> custom_mapping;
};
static vector<GeoIPDomain> s_domains;
static int s_rc = 0; // refcount - always accessed under lock
-static string GeoIP_WEEKDAYS[] = { "mon", "tue", "wed", "thu", "fri", "sat", "sun" };
-static string GeoIP_MONTHS[] = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" };
+static string GeoIP_WEEKDAYS[] = {"mon", "tue", "wed", "thu", "fri", "sat", "sun"};
+static string GeoIP_MONTHS[] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
/* So how does it work - we have static records and services. Static records "win".
We also insert empty non terminals for records and services.
If the reference is external, we spoof up a CNAME, and good luck with that
*/
-GeoIPBackend::GeoIPBackend(const string& suffix) {
+GeoIPBackend::GeoIPBackend(const string& suffix)
+{
WriteLock wl(&s_state_lock);
d_dnssec = false;
setArgPrefix("geoip" + suffix);
if (getArg("dnssec-keydir").empty() == false) {
- DIR *d = opendir(getArg("dnssec-keydir").c_str());
+ DIR* d = opendir(getArg("dnssec-keydir").c_str());
if (d == NULL) {
throw PDNSException("dnssec-keydir " + getArg("dnssec-keydir") + " does not exist");
}
s_rc++;
}
-static vector<std::unique_ptr<GeoIPInterface> > s_geoip_files;
+static vector<std::unique_ptr<GeoIPInterface>> s_geoip_files;
string getGeoForLua(const std::string& ip, int qaint);
static string queryGeoIP(const Netmask& addr, GeoIPInterface::GeoIPQueryAttribute attribute, GeoIPNetmask& gl);
// validateMappingLookupFormats validates any custom format provided by the
// user does not use the custom mapping placeholder again, else it would do an
// infinite recursion.
-static bool validateMappingLookupFormats(const vector<string>& formats) {
- string::size_type cur,last;
+static bool validateMappingLookupFormats(const vector<string>& formats)
+{
+ string::size_type cur, last;
for (const auto& lookupFormat : formats) {
- last=0;
- while((cur = lookupFormat.find("%", last)) != string::npos) {
- if (!lookupFormat.compare(cur,3,"%mp")) {
+ last = 0;
+ while ((cur = lookupFormat.find("%", last)) != string::npos) {
+ if (!lookupFormat.compare(cur, 3, "%mp")) {
return false;
- } else if (!lookupFormat.compare(cur,2,"%%")) { // Ensure escaped % is also accepted
- last = cur + 2; continue;
+ }
+ else if (!lookupFormat.compare(cur, 2, "%%")) { // Ensure escaped % is also accepted
+ last = cur + 2;
+ continue;
}
last = cur + 1; // move to next attribute
}
return true;
}
-void GeoIPBackend::initialize() {
+void GeoIPBackend::initialize()
+{
YAML::Node config;
vector<GeoIPDomain> tmp_domains;
if (getArg("database-files").empty() == false) {
vector<string> files;
stringtok(files, getArg("database-files"), " ,\t\r\n");
- for(auto const& file: files) {
+ for (auto const& file : files) {
s_geoip_files.push_back(GeoIPInterface::makeInterface(file));
}
}
if (s_geoip_files.empty())
- g_log<<Logger::Warning<<"No GeoIP database files loaded!"<<endl;
+ g_log << Logger::Warning << "No GeoIP database files loaded!" << endl;
- if(!getArg("zones-file").empty()) {
+ if (!getArg("zones-file").empty()) {
try {
- config = YAML::LoadFile(getArg("zones-file"));
- } catch (YAML::Exception &ex) {
- throw PDNSException(string("Cannot read config file ") + ex.msg);
+ config = YAML::LoadFile(getArg("zones-file"));
+ }
+ catch (YAML::Exception& ex) {
+ throw PDNSException(string("Cannot read config file ") + ex.msg);
}
}
global_custom_mapping = mapping.as<map<std::string, std::string>>();
}
- for(YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) {
+ for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) {
const auto& domain = *_domain;
GeoIPDomain dom;
dom.id = tmp_domains.size();
dom.domain = DNSName(domain["domain"].as<string>());
dom.ttl = domain["ttl"].as<int>();
- for(YAML::const_iterator recs = domain["records"].begin(); recs != domain["records"].end(); recs++) {
+ for (YAML::const_iterator recs = domain["records"].begin(); recs != domain["records"].end(); recs++) {
DNSName qname = DNSName(recs->first.as<string>());
vector<GeoIPDNSResourceRecord> rrs;
- for(YAML::const_iterator item = recs->second.begin(); item != recs->second.end(); item++) {
+ for (YAML::const_iterator item = recs->second.begin(); item != recs->second.end(); item++) {
YAML::const_iterator rec = item->begin();
GeoIPDNSResourceRecord rr;
rr.domain_id = dom.id;
rr.qname = qname;
if (rec->first.IsNull()) {
rr.qtype = QType(0);
- } else {
+ }
+ else {
string qtype = boost::to_upper_copy(rec->first.as<string>());
rr.qtype = qtype;
}
rr.weight = 100;
if (rec->second.IsNull()) {
rr.content = "";
- } else if (rec->second.IsMap()) {
- for(YAML::const_iterator iter = rec->second.begin(); iter != rec->second.end(); iter++) {
- string attr = iter->first.as<string>();
- if (attr == "content") {
- string content = iter->second.as<string>();
- rr.content = content;
- } else if (attr == "weight") {
- rr.weight = iter->second.as<int>();
- if (rr.weight <= 0) {
- g_log<<Logger::Error<<"Weight must be positive for " << rr.qname << endl;
- throw PDNSException(string("Weight must be positive for ") + rr.qname.toLogString());
- }
- rr.has_weight = true;
- } else if (attr == "ttl") {
- rr.ttl = iter->second.as<int>();
- } else {
- g_log<<Logger::Error<<"Unsupported record attribute " << attr << " for " << rr.qname << endl;
- throw PDNSException(string("Unsupported record attribute ") + attr + string(" for ") + rr.qname.toLogString());
- }
- }
- } else {
- string content=rec->second.as<string>();
+ }
+ else if (rec->second.IsMap()) {
+ for (YAML::const_iterator iter = rec->second.begin(); iter != rec->second.end(); iter++) {
+ string attr = iter->first.as<string>();
+ if (attr == "content") {
+ string content = iter->second.as<string>();
+ rr.content = content;
+ }
+ else if (attr == "weight") {
+ rr.weight = iter->second.as<int>();
+ if (rr.weight <= 0) {
+ g_log << Logger::Error << "Weight must be positive for " << rr.qname << endl;
+ throw PDNSException(string("Weight must be positive for ") + rr.qname.toLogString());
+ }
+ rr.has_weight = true;
+ }
+ else if (attr == "ttl") {
+ rr.ttl = iter->second.as<int>();
+ }
+ else {
+ g_log << Logger::Error << "Unsupported record attribute " << attr << " for " << rr.qname << endl;
+ throw PDNSException(string("Unsupported record attribute ") + attr + string(" for ") + rr.qname.toLogString());
+ }
+ }
+ }
+ else {
+ string content = rec->second.as<string>();
rr.content = content;
rr.weight = 100;
}
std::swap(dom.records[qname], rrs);
}
- for(YAML::const_iterator service = domain["services"].begin(); service != domain["services"].end(); service++) {
+ for (YAML::const_iterator service = domain["services"].begin(); service != domain["services"].end(); service++) {
unsigned int netmask4 = 0, netmask6 = 0;
DNSName srvName{service->first.as<string>()};
- NetmaskTree<vector<string> > nmt;
+ NetmaskTree<vector<string>> nmt;
// if it's an another map, we need to iterate it again, otherwise we just add two root entries.
if (service->second.IsMap()) {
- for(YAML::const_iterator net = service->second.begin(); net != service->second.end(); net++) {
+ for (YAML::const_iterator net = service->second.begin(); net != service->second.end(); net++) {
vector<string> value;
if (net->second.IsSequence()) {
- value = net->second.as<vector<string> >();
- } else {
+ value = net->second.as<vector<string>>();
+ }
+ else {
value.push_back(net->second.as<string>());
}
if (net->first.as<string>() == "default") {
- nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(),value.end());
+ nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end());
nmt.insert(Netmask("::/0")).second.swap(value);
- } else {
+ }
+ else {
Netmask nm{net->first.as<string>()};
nmt.insert(nm).second.swap(value);
if (nm.isIPv6() == true && netmask6 < nm.getBits())
netmask4 = nm.getBits();
}
}
- } else {
+ }
+ else {
vector<string> value;
if (service->second.IsSequence()) {
- value = service->second.as<vector<string> >();
- } else {
+ value = service->second.as<vector<string>>();
+ }
+ else {
value.push_back(service->second.as<string>());
}
- nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(),value.end());
+ nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end());
nmt.insert(Netmask("::/0")).second.swap(value);
}
throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString());
dom.mapping_lookup_formats = mapping_lookup_formats;
- } else {
+ }
+ else {
dom.mapping_lookup_formats = global_mapping_lookup_formats;
}
if (YAML::Node mapping = domain["custom_mapping"]) {
- dom.custom_mapping = mapping.as<map<std::string,std::string>>();
- } else {
+ dom.custom_mapping = mapping.as<map<std::string, std::string>>();
+ }
+ else {
dom.custom_mapping = global_custom_mapping;
}
}
// rectify the zone, first static records
- for(auto &item : dom.records) {
+ for (auto& item : dom.records) {
// ensure we have parent in records
DNSName name = item.first;
- while(name.chopOff() && name.isPartOf(dom.domain)) {
+ while (name.chopOff() && name.isPartOf(dom.domain)) {
if (dom.records.find(name) == dom.records.end() && !dom.services.count(name)) { // don't ENT out a service!
GeoIPDNSResourceRecord rr;
vector<GeoIPDNSResourceRecord> rrs;
}
// then services
- for(auto &item : dom.services) {
+ for (auto& item : dom.services) {
// ensure we have parent in records
DNSName name = item.first;
- while(name.chopOff() && name.isPartOf(dom.domain)) {
+ while (name.chopOff() && name.isPartOf(dom.domain)) {
if (dom.records.find(name) == dom.records.end()) {
GeoIPDNSResourceRecord rr;
vector<GeoIPDNSResourceRecord> rrs;
}
// finally fix weights
- for(auto &item: dom.records) {
+ for (auto& item : dom.records) {
map<uint16_t, float> weights;
map<uint16_t, float> sums;
map<uint16_t, GeoIPDNSResourceRecord*> lasts;
- bool has_weight=false;
+ bool has_weight = false;
// first we look for used weight
- for(const auto &rr: item.second) {
+ for (const auto& rr : item.second) {
weights[rr.qtype.getCode()] += rr.weight;
- if (rr.has_weight) has_weight = true;
+ if (rr.has_weight)
+ has_weight = true;
}
if (has_weight) {
// put them back as probabilities and values..
- for(auto &rr: item.second) {
+ for (auto& rr : item.second) {
uint16_t rr_type = rr.qtype.getCode();
- rr.weight=static_cast<int>((static_cast<float>(rr.weight) / weights[rr_type])*1000.0);
+ rr.weight = static_cast<int>((static_cast<float>(rr.weight) / weights[rr_type]) * 1000.0);
sums[rr_type] += rr.weight;
rr.has_weight = has_weight;
lasts[rr_type] = &rr;
}
// remove rounding gap
- for(auto &x: lasts) {
+ for (auto& x : lasts) {
float sum = sums[x.first];
if (sum < 1000)
- x.second->weight += (1000-sum);
+ x.second->weight += (1000 - sum);
}
}
}
g_getGeo = getGeoForLua;
}
-GeoIPBackend::~GeoIPBackend() {
+GeoIPBackend::~GeoIPBackend()
+{
try {
WriteLock wl(&s_state_lock);
s_rc--;
s_domains.clear();
}
}
- catch(...) {
+ catch (...) {
}
}
-bool GeoIPBackend::lookup_static(const GeoIPDomain &dom, const DNSName &search, const QType &qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask &gl) {
+bool GeoIPBackend::lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl)
+{
const auto& i = dom.records.find(search);
- map<uint16_t,int> cumul_probabilities;
- map<uint16_t,bool> weighted_match;
- int probability_rnd = 1+(dns_random(1000)); // setting probability=0 means it never is used
+ map<uint16_t, int> cumul_probabilities;
+ map<uint16_t, bool> weighted_match;
+ int probability_rnd = 1 + (dns_random(1000)); // setting probability=0 means it never is used
if (i != dom.records.end()) { // return static value
- for(const auto& rr : i->second) {
+ for (const auto& rr : i->second) {
if ((qtype != QType::ANY && rr.qtype != qtype) || weighted_match[rr.qtype.getCode()])
continue;
if (rr.has_weight) {
- gl.netmask = (addr.isIPv6()?128:32);
+ gl.netmask = (addr.isIPv6() ? 128 : 32);
int comp = cumul_probabilities[rr.qtype.getCode()];
cumul_probabilities[rr.qtype.getCode()] += rr.weight;
if (rr.weight == 0 || probability_rnd < comp || probability_rnd > (comp + rr.weight))
continue;
}
const string& content = format2str(rr.content, addr, gl, dom);
- if (rr.qtype != QType::ENT && rr.qtype != QType::TXT && content.empty()) continue;
+ if (rr.qtype != QType::ENT && rr.qtype != QType::TXT && content.empty())
+ continue;
d_result.push_back(rr);
d_result.back().content = content;
d_result.back().qname = qdomain;
weighted_match[rr.qtype.getCode()] = true;
}
// ensure we get most strict netmask
- for(DNSResourceRecord& rr: d_result) {
+ for (DNSResourceRecord& rr : d_result) {
rr.scopeMask = gl.netmask;
}
return true; // no need to go further
return false;
};
-void GeoIPBackend::lookup(const QType &qtype, const DNSName& qdomain, int zoneId, DNSPacket *pkt_p) {
+void GeoIPBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p)
+{
ReadLock rl(&s_state_lock);
const GeoIPDomain* dom;
GeoIPNetmask gl;
bool found = false;
- if (d_result.size()>0)
+ if (d_result.size() > 0)
throw PDNSException("Cannot perform lookup while another is running");
d_result.clear();
if (zoneId > -1 && zoneId < static_cast<int>(s_domains.size()))
dom = &(s_domains[zoneId]);
else {
- for(const GeoIPDomain& i : s_domains) { // this is arguably wrong, we should probably find the most specific match
+ for (const GeoIPDomain& i : s_domains) { // this is arguably wrong, we should probably find the most specific match
if (qdomain.isPartOf(i.domain)) {
dom = &i;
found = true;
break;
}
}
- if (!found) return; // not found
+ if (!found)
+ return; // not found
}
Netmask addr{"0.0.0.0/0"};
(void)this->lookup_static(*dom, qdomain, qtype, qdomain, addr, gl);
const auto& target = (*dom).services.find(qdomain);
- if (target == (*dom).services.end()) return; // no hit
+ if (target == (*dom).services.end())
+ return; // no hit
- const NetmaskTree<vector<string> >::node_type* node = target->second.masks.lookup(addr);
- if (node == NULL) return; // no hit, again.
+ const NetmaskTree<vector<string>>::node_type* node = target->second.masks.lookup(addr);
+ if (node == NULL)
+ return; // no hit, again.
DNSName sformat;
gl.netmask = node->first.getBits();
else
gl.netmask = target->second.netmask4;
}
- } else {
+ }
+ else {
if (addr.isIPv6())
gl.netmask = target->second.netmask6;
else
}
// note that this means the array format won't work with indirect
- for(auto it = node->second.begin(); it != node->second.end(); it++) {
+ for (auto it = node->second.begin(); it != node->second.end(); it++) {
sformat = DNSName(format2str(*it, addr, gl, *dom));
// see if the record can be found
}
if (!d_result.empty()) {
- g_log<<Logger::Error<<
- "Cannot have static record and CNAME at the same time." <<
- "Please fix your configuration for \"" << qdomain << "\", so that " <<
- "it can be resolved by GeoIP backend directly."<< std::endl;
+ g_log << Logger::Error << "Cannot have static record and CNAME at the same time."
+ << "Please fix your configuration for \"" << qdomain << "\", so that "
+ << "it can be resolved by GeoIP backend directly." << std::endl;
d_result.clear();
return;
}
// we need this line since we otherwise claim to have NS records etc
- if (!(qtype == QType::ANY || qtype == QType::CNAME)) return;
+ if (!(qtype == QType::ANY || qtype == QType::CNAME))
+ return;
DNSResourceRecord rr;
rr.domain_id = dom->id;
d_result.push_back(rr);
}
-bool GeoIPBackend::get(DNSResourceRecord &r) {
- if (d_result.empty()) return false;
+bool GeoIPBackend::get(DNSResourceRecord& r)
+{
+ if (d_result.empty())
+ return false;
r = d_result.back();
d_result.pop_back();
return true;
}
-static string queryGeoIP(const Netmask& addr, GeoIPInterface::GeoIPQueryAttribute attribute, GeoIPNetmask& gl) {
+static string queryGeoIP(const Netmask& addr, GeoIPInterface::GeoIPQueryAttribute attribute, GeoIPNetmask& gl)
+{
string ret = "unknown";
- for(auto const& gi: s_geoip_files) {
+ for (auto const& gi : s_geoip_files) {
string val;
const string ip = addr.toStringNoMask();
bool found = false;
- switch(attribute) {
+ switch (attribute) {
case GeoIPInterface::ASn:
- if (addr.isIPv6()) found = gi->queryASnumV6(val, gl, ip);
- else found =gi->queryASnum(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryASnumV6(val, gl, ip);
+ else
+ found = gi->queryASnum(val, gl, ip);
break;
case GeoIPInterface::Name:
- if (addr.isIPv6()) found = gi->queryNameV6(val, gl, ip);
- else found = gi->queryName(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryNameV6(val, gl, ip);
+ else
+ found = gi->queryName(val, gl, ip);
break;
case GeoIPInterface::Continent:
- if (addr.isIPv6()) found = gi->queryContinentV6(val, gl, ip);
- else found = gi->queryContinent(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryContinentV6(val, gl, ip);
+ else
+ found = gi->queryContinent(val, gl, ip);
break;
case GeoIPInterface::Region:
- if (addr.isIPv6()) found = gi->queryRegionV6(val, gl, ip);
- else found = gi->queryRegion(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryRegionV6(val, gl, ip);
+ else
+ found = gi->queryRegion(val, gl, ip);
break;
case GeoIPInterface::Country:
- if (addr.isIPv6()) found = gi->queryCountryV6(val, gl, ip);
- else found = gi->queryCountry(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryCountryV6(val, gl, ip);
+ else
+ found = gi->queryCountry(val, gl, ip);
break;
case GeoIPInterface::Country2:
- if (addr.isIPv6()) found = gi->queryCountry2V6(val, gl, ip);
- else found = gi->queryCountry2(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryCountry2V6(val, gl, ip);
+ else
+ found = gi->queryCountry2(val, gl, ip);
break;
case GeoIPInterface::City:
- if (addr.isIPv6()) found = gi->queryCityV6(val, gl, ip);
- else found = gi->queryCity(val, gl, ip);
+ if (addr.isIPv6())
+ found = gi->queryCityV6(val, gl, ip);
+ else
+ found = gi->queryCity(val, gl, ip);
break;
case GeoIPInterface::Location:
- double lat=0, lon=0;
+ double lat = 0, lon = 0;
boost::optional<int> alt, prec;
- if (addr.isIPv6()) found = gi->queryLocationV6(gl, ip, lat, lon, alt, prec);
- else found = gi->queryLocation(gl, ip, lat, lon, alt, prec);
- val = std::to_string(lat)+" "+std::to_string(lon);
+ if (addr.isIPv6())
+ found = gi->queryLocationV6(gl, ip, lat, lon, alt, prec);
+ else
+ found = gi->queryLocation(gl, ip, lat, lon, alt, prec);
+ val = std::to_string(lat) + " " + std::to_string(lon);
break;
}
- if (!found || val.empty() || val == "--") continue; // try next database
+ if (!found || val.empty() || val == "--")
+ continue; // try next database
ret = val;
std::transform(ret.begin(), ret.end(), ret.begin(), ::tolower);
break;
}
- if (ret == "unknown") gl.netmask = (addr.isIPv6()?128:32); // prevent caching
+ if (ret == "unknown")
+ gl.netmask = (addr.isIPv6() ? 128 : 32); // prevent caching
return ret;
}
try {
const Netmask addr{ip};
GeoIPNetmask gl;
- string res=queryGeoIP(addr, qa, gl);
+ string res = queryGeoIP(addr, qa, gl);
// cout<<"Result for "<<ip<<" lookup: "<<res<<endl;
- if(qa==GeoIPInterface::ASn && boost::starts_with(res, "as"))
+ if (qa == GeoIPInterface::ASn && boost::starts_with(res, "as"))
return res.substr(2);
return res;
}
- catch(std::exception& e) {
- cout<<"Error: "<<e.what()<<endl;
+ catch (std::exception& e) {
+ cout << "Error: " << e.what() << endl;
}
- catch(PDNSException& e) {
- cout<<"Error: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cout << "Error: " << e.reason << endl;
}
return "";
}
static bool queryGeoLocation(const Netmask& addr, GeoIPNetmask& gl, double& lat, double& lon,
- boost::optional<int>& alt, boost::optional<int>& prec)
+ boost::optional<int>& alt, boost::optional<int>& prec)
{
- for(auto const& gi: s_geoip_files) {
+ for (auto const& gi : s_geoip_files) {
string val;
if (addr.isIPv6()) {
if (gi->queryLocationV6(gl, addr.toStringNoMask(), lat, lon, alt, prec))
return true;
- } else if (gi->queryLocation(gl, addr.toStringNoMask(), lat, lon, alt, prec))
- return true;
+ }
+ else if (gi->queryLocation(gl, addr.toStringNoMask(), lat, lon, alt, prec))
+ return true;
}
return false;
}
-string GeoIPBackend::format2str(string sformat, const Netmask& addr, GeoIPNetmask& gl, const GeoIPDomain &dom) {
- string::size_type cur,last;
+string GeoIPBackend::format2str(string sformat, const Netmask& addr, GeoIPNetmask& gl, const GeoIPDomain& dom)
+{
+ string::size_type cur, last;
boost::optional<int> alt, prec;
double lat, lon;
time_t t = time((time_t*)NULL);
GeoIPNetmask tmp_gl; // largest wins
struct tm gtm;
gmtime_r(&t, >m);
- last=0;
+ last = 0;
- while((cur = sformat.find("%", last)) != string::npos) {
+ while ((cur = sformat.find("%", last)) != string::npos) {
string rep;
- int nrep=3;
+ int nrep = 3;
tmp_gl.netmask = 0;
- if (!sformat.compare(cur,3,"%mp")) {
+ if (!sformat.compare(cur, 3, "%mp")) {
rep = "unknown";
for (const auto& lookupFormat : dom.mapping_lookup_formats) {
auto it = dom.custom_mapping.find(format2str(lookupFormat, addr, gl, dom));
break;
}
}
- } else if (!sformat.compare(cur,3,"%cn")) {
+ }
+ else if (!sformat.compare(cur, 3, "%cn")) {
rep = queryGeoIP(addr, GeoIPInterface::Continent, tmp_gl);
- } else if (!sformat.compare(cur,3,"%co")) {
+ }
+ else if (!sformat.compare(cur, 3, "%co")) {
rep = queryGeoIP(addr, GeoIPInterface::Country, tmp_gl);
- } else if (!sformat.compare(cur,3,"%cc")) {
+ }
+ else if (!sformat.compare(cur, 3, "%cc")) {
rep = queryGeoIP(addr, GeoIPInterface::Country2, tmp_gl);
- } else if (!sformat.compare(cur,3,"%af")) {
- rep = (addr.isIPv6()?"v6":"v4");
- } else if (!sformat.compare(cur,3,"%as")) {
+ }
+ else if (!sformat.compare(cur, 3, "%af")) {
+ rep = (addr.isIPv6() ? "v6" : "v4");
+ }
+ else if (!sformat.compare(cur, 3, "%as")) {
rep = queryGeoIP(addr, GeoIPInterface::ASn, tmp_gl);
- } else if (!sformat.compare(cur,3,"%re")) {
+ }
+ else if (!sformat.compare(cur, 3, "%re")) {
rep = queryGeoIP(addr, GeoIPInterface::Region, tmp_gl);
- } else if (!sformat.compare(cur,3,"%na")) {
+ }
+ else if (!sformat.compare(cur, 3, "%na")) {
rep = queryGeoIP(addr, GeoIPInterface::Name, tmp_gl);
- } else if (!sformat.compare(cur,3,"%ci")) {
+ }
+ else if (!sformat.compare(cur, 3, "%ci")) {
rep = queryGeoIP(addr, GeoIPInterface::City, tmp_gl);
- } else if (!sformat.compare(cur,4,"%loc")) {
+ }
+ else if (!sformat.compare(cur, 4, "%loc")) {
char ns, ew;
int d1, d2, m1, m2;
double s1, s2;
if (!queryGeoLocation(addr, gl, lat, lon, alt, prec)) {
rep = "";
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else {
- ns = (lat>0) ? 'N' : 'S';
- ew = (lon>0) ? 'E' : 'W';
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else {
+ ns = (lat > 0) ? 'N' : 'S';
+ ew = (lon > 0) ? 'E' : 'W';
/* remove sign */
lat = fabs(lat);
lon = fabs(lon);
d1 = static_cast<int>(lat);
d2 = static_cast<int>(lon);
- m1 = static_cast<int>((lat - d1)*60.0);
- m2 = static_cast<int>((lon - d2)*60.0);
- s1 = static_cast<double>(lat - d1 - m1/60.0)*3600.0;
- s2 = static_cast<double>(lon - d2 - m2/60.0)*3600.0;
- rep = str(boost::format("%d %d %0.3f %c %d %d %0.3f %c") %
- d1 % m1 % s1 % ns % d2 % m2 % s2 % ew);
+ m1 = static_cast<int>((lat - d1) * 60.0);
+ m2 = static_cast<int>((lon - d2) * 60.0);
+ s1 = static_cast<double>(lat - d1 - m1 / 60.0) * 3600.0;
+ s2 = static_cast<double>(lon - d2 - m2 / 60.0) * 3600.0;
+ rep = str(boost::format("%d %d %0.3f %c %d %d %0.3f %c") % d1 % m1 % s1 % ns % d2 % m2 % s2 % ew);
if (alt)
rep = rep + str(boost::format(" %d.00") % *alt);
else
rep = rep + str(boost::format(" %dm") % *prec);
}
nrep = 4;
- } else if (!sformat.compare(cur,4,"%lat")) {
+ }
+ else if (!sformat.compare(cur, 4, "%lat")) {
if (!queryGeoLocation(addr, gl, lat, lon, alt, prec)) {
rep = "";
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else {
rep = str(boost::format("%lf") % lat);
}
nrep = 4;
- } else if (!sformat.compare(cur,4,"%lon")) {
+ }
+ else if (!sformat.compare(cur, 4, "%lon")) {
if (!queryGeoLocation(addr, gl, lat, lon, alt, prec)) {
rep = "";
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else {
rep = str(boost::format("%lf") % lon);
}
nrep = 4;
- } else if (!sformat.compare(cur,3,"%hh")) {
+ }
+ else if (!sformat.compare(cur, 3, "%hh")) {
rep = boost::str(boost::format("%02d") % gtm.tm_hour);
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,3,"%yy")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 3, "%yy")) {
rep = boost::str(boost::format("%02d") % (gtm.tm_year + 1900));
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,3,"%dd")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 3, "%dd")) {
rep = boost::str(boost::format("%02d") % (gtm.tm_yday + 1));
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,4,"%wds")) {
- nrep=4;
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 4, "%wds")) {
+ nrep = 4;
rep = GeoIP_WEEKDAYS[gtm.tm_wday];
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,4,"%mos")) {
- nrep=4;
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 4, "%mos")) {
+ nrep = 4;
rep = GeoIP_MONTHS[gtm.tm_mon];
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,3,"%wd")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 3, "%wd")) {
rep = boost::str(boost::format("%02d") % (gtm.tm_wday + 1));
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,3,"%mo")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 3, "%mo")) {
rep = boost::str(boost::format("%02d") % (gtm.tm_mon + 1));
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,4,"%ip6")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 4, "%ip6")) {
nrep = 4;
if (addr.isIPv6())
rep = addr.toStringNoMask();
else
rep = "";
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,4,"%ip4")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 4, "%ip4")) {
nrep = 4;
if (!addr.isIPv6())
rep = addr.toStringNoMask();
else
rep = "";
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,3,"%ip")) {
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 3, "%ip")) {
rep = addr.toStringNoMask();
- tmp_gl.netmask = (addr.isIPv6()?128:32);
- } else if (!sformat.compare(cur,2,"%%")) {
- last = cur + 2; continue;
- } else {
- last = cur + 1; continue;
+ tmp_gl.netmask = (addr.isIPv6() ? 128 : 32);
+ }
+ else if (!sformat.compare(cur, 2, "%%")) {
+ last = cur + 2;
+ continue;
}
- if (tmp_gl.netmask > gl.netmask) gl.netmask = tmp_gl.netmask;
+ else {
+ last = cur + 1;
+ continue;
+ }
+ if (tmp_gl.netmask > gl.netmask)
+ gl.netmask = tmp_gl.netmask;
sformat.replace(cur, nrep, rep);
last = cur + rep.size(); // move to next attribute
}
return sformat;
}
-void GeoIPBackend::reload() {
+void GeoIPBackend::reload()
+{
WriteLock wl(&s_state_lock);
try {
initialize();
- } catch (PDNSException &pex) {
- g_log<<Logger::Error<<"GeoIP backend reload failed: " << pex.reason << endl;
- } catch (std::exception &stex) {
- g_log<<Logger::Error<<"GeoIP backend reload failed: " << stex.what() << endl;
- } catch (...) {
- g_log<<Logger::Error<<"GeoIP backend reload failed" << endl;
+ }
+ catch (PDNSException& pex) {
+ g_log << Logger::Error << "GeoIP backend reload failed: " << pex.reason << endl;
+ }
+ catch (std::exception& stex) {
+ g_log << Logger::Error << "GeoIP backend reload failed: " << stex.what() << endl;
+ }
+ catch (...) {
+ g_log << Logger::Error << "GeoIP backend reload failed" << endl;
}
}
-void GeoIPBackend::rediscover(string* status) {
+void GeoIPBackend::rediscover(string* status)
+{
reload();
}
-bool GeoIPBackend::getDomainInfo(const DNSName& domain, DomainInfo &di, bool getSerial) {
+bool GeoIPBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
+{
ReadLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == domain) {
SOAData sd;
this->getSOA(domain, sd);
return false;
}
-bool GeoIPBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
+{
+ if (!d_dnssec)
+ return false;
ReadLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
if (hasDNSSECkey(dom.domain)) {
meta[string("NSEC3NARROW")].push_back("1");
return false;
}
-bool GeoIPBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
+{
+ if (!d_dnssec)
+ return false;
ReadLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
if (hasDNSSECkey(dom.domain)) {
if (kind == "NSEC3NARROW")
return false;
}
-bool GeoIPBackend::getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys)
+{
+ if (!d_dnssec)
+ return false;
ReadLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
regex_t reg;
regmatch_t regm[5];
- regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE|REG_EXTENDED);
+ regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE | REG_EXTENDED);
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
- for(size_t i=0;i<glob_result.gl_pathc;i++) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
if (regexec(®, glob_result.gl_pathv[i], 5, regm, 0) == 0) {
DNSBackend::KeyData kd;
- kd.id = pdns_stou(glob_result.gl_pathv[i]+regm[3].rm_so);
- kd.active = !strncmp(glob_result.gl_pathv[i]+regm[4].rm_so, "1", 1);
+ kd.id = pdns_stou(glob_result.gl_pathv[i] + regm[3].rm_so);
+ kd.active = !strncmp(glob_result.gl_pathv[i] + regm[4].rm_so, "1", 1);
kd.published = true;
- kd.flags = pdns_stou(glob_result.gl_pathv[i]+regm[2].rm_so);
+ kd.flags = pdns_stou(glob_result.gl_pathv[i] + regm[2].rm_so);
ifstream ifs(glob_result.gl_pathv[i]);
ostringstream content;
char buffer[1024];
- while(ifs.good()) {
+ while (ifs.good()) {
ifs.read(buffer, sizeof buffer);
- if (ifs.gcount()>0) {
+ if (ifs.gcount() > 0) {
content << string(buffer, ifs.gcount());
}
}
return false;
}
-bool GeoIPBackend::removeDomainKey(const DNSName& name, unsigned int id) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::removeDomainKey(const DNSName& name, unsigned int id)
+{
+ if (!d_dnssec)
+ return false;
WriteLock rl(&s_state_lock);
ostringstream path;
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
regex_t reg;
regmatch_t regm[5];
- regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE|REG_EXTENDED);
+ regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE | REG_EXTENDED);
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
- for(size_t i=0;i<glob_result.gl_pathc;i++) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
if (regexec(®, glob_result.gl_pathv[i], 5, regm, 0) == 0) {
- unsigned int kid = pdns_stou(glob_result.gl_pathv[i]+regm[3].rm_so);
+ unsigned int kid = pdns_stou(glob_result.gl_pathv[i] + regm[3].rm_so);
if (kid == id) {
if (unlink(glob_result.gl_pathv[i])) {
cerr << "Cannot delete key:" << strerror(errno) << endl;
return false;
}
-bool GeoIPBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id)
+{
+ if (!d_dnssec)
+ return false;
WriteLock rl(&s_state_lock);
- unsigned int nextid=1;
+ unsigned int nextid = 1;
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
regex_t reg;
regmatch_t regm[5];
- regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE|REG_EXTENDED);
+ regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE | REG_EXTENDED);
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
- for(size_t i=0;i<glob_result.gl_pathc;i++) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
if (regexec(®, glob_result.gl_pathv[i], 5, regm, 0) == 0) {
- unsigned int kid = pdns_stou(glob_result.gl_pathv[i]+regm[3].rm_so);
- if (kid >= nextid) nextid = kid+1;
+ unsigned int kid = pdns_stou(glob_result.gl_pathv[i] + regm[3].rm_so);
+ if (kid >= nextid)
+ nextid = kid + 1;
}
}
}
regfree(®);
globfree(&glob_result);
pathname.str("");
- pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << key.flags << "." << nextid << "." << (key.active?"1":"0") << ".key";
+ pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << key.flags << "." << nextid << "." << (key.active ? "1" : "0") << ".key";
ofstream ofs(pathname.str().c_str());
ofs.write(key.content.c_str(), key.content.size());
ofs.close();
}
}
return false;
-
}
-bool GeoIPBackend::activateDomainKey(const DNSName& name, unsigned int id) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::activateDomainKey(const DNSName& name, unsigned int id)
+{
+ if (!d_dnssec)
+ return false;
WriteLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
regex_t reg;
regmatch_t regm[5];
- regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE|REG_EXTENDED);
+ regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE | REG_EXTENDED);
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
- for(size_t i=0;i<glob_result.gl_pathc;i++) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
if (regexec(®, glob_result.gl_pathv[i], 5, regm, 0) == 0) {
- unsigned int kid = pdns_stou(glob_result.gl_pathv[i]+regm[3].rm_so);
- if (kid == id && !strcmp(glob_result.gl_pathv[i]+regm[4].rm_so,"0")) {
+ unsigned int kid = pdns_stou(glob_result.gl_pathv[i] + regm[3].rm_so);
+ if (kid == id && !strcmp(glob_result.gl_pathv[i] + regm[4].rm_so, "0")) {
ostringstream newpath;
- newpath << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << pdns_stou(glob_result.gl_pathv[i]+regm[2].rm_so) << "." << kid << ".1.key";
+ newpath << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << pdns_stou(glob_result.gl_pathv[i] + regm[2].rm_so) << "." << kid << ".1.key";
if (rename(glob_result.gl_pathv[i], newpath.str().c_str())) {
cerr << "Cannot activate key: " << strerror(errno) << endl;
}
return false;
}
-bool GeoIPBackend::deactivateDomainKey(const DNSName& name, unsigned int id) {
- if (!d_dnssec) return false;
+bool GeoIPBackend::deactivateDomainKey(const DNSName& name, unsigned int id)
+{
+ if (!d_dnssec)
+ return false;
WriteLock rl(&s_state_lock);
- for(GeoIPDomain dom : s_domains) {
+ for (GeoIPDomain dom : s_domains) {
if (dom.domain == name) {
regex_t reg;
regmatch_t regm[5];
- regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE|REG_EXTENDED);
+ regcomp(®, "(.*)[.]([0-9]+)[.]([0-9]+)[.]([01])[.]key$", REG_ICASE | REG_EXTENDED);
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
- for(size_t i=0;i<glob_result.gl_pathc;i++) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
+ for (size_t i = 0; i < glob_result.gl_pathc; i++) {
if (regexec(®, glob_result.gl_pathv[i], 5, regm, 0) == 0) {
- unsigned int kid = pdns_stou(glob_result.gl_pathv[i]+regm[3].rm_so);
- if (kid == id && !strcmp(glob_result.gl_pathv[i]+regm[4].rm_so,"1")) {
+ unsigned int kid = pdns_stou(glob_result.gl_pathv[i] + regm[3].rm_so);
+ if (kid == id && !strcmp(glob_result.gl_pathv[i] + regm[4].rm_so, "1")) {
ostringstream newpath;
- newpath << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << pdns_stou(glob_result.gl_pathv[i]+regm[2].rm_so) << "." << kid << ".0.key";
+ newpath << getArg("dnssec-keydir") << "/" << dom.domain.toStringNoDot() << "." << pdns_stou(glob_result.gl_pathv[i] + regm[2].rm_so) << "." << kid << ".0.key";
if (rename(glob_result.gl_pathv[i], newpath.str().c_str())) {
cerr << "Cannot deactivate key: " << strerror(errno) << endl;
}
return false;
}
-bool GeoIPBackend::publishDomainKey(const DNSName& name, unsigned int id) {
+bool GeoIPBackend::publishDomainKey(const DNSName& name, unsigned int id)
+{
return false;
}
-bool GeoIPBackend::unpublishDomainKey(const DNSName& name, unsigned int id) {
+bool GeoIPBackend::unpublishDomainKey(const DNSName& name, unsigned int id)
+{
return false;
}
-
-bool GeoIPBackend::hasDNSSECkey(const DNSName& name) {
+bool GeoIPBackend::hasDNSSECkey(const DNSName& name)
+{
ostringstream pathname;
pathname << getArg("dnssec-keydir") << "/" << name.toStringNoDot() << "*.key";
glob_t glob_result;
- if (glob(pathname.str().c_str(),GLOB_ERR,NULL,&glob_result) == 0) {
+ if (glob(pathname.str().c_str(), GLOB_ERR, NULL, &glob_result) == 0) {
globfree(&glob_result);
return true;
}
return false;
}
-class GeoIPFactory : public BackendFactory{
+class GeoIPFactory : public BackendFactory
+{
public:
- GeoIPFactory() : BackendFactory("geoip") {}
+ GeoIPFactory() :
+ BackendFactory("geoip") {}
- void declareArguments(const string &suffix = "") override {
+ void declareArguments(const string& suffix = "") override
+ {
declare(suffix, "zones-file", "YAML file to load zone(s) configuration", "");
declare(suffix, "database-files", "File(s) to load geoip data from ([driver:]path[;opt=value]", "");
declare(suffix, "dnssec-keydir", "Directory to hold dnssec keys (also turns DNSSEC on)", "");
}
- DNSBackend *make(const string &suffix) override {
+ DNSBackend* make(const string& suffix) override
+ {
return new GeoIPBackend(suffix);
}
};
-class GeoIPLoader {
+class GeoIPLoader
+{
public:
- GeoIPLoader() {
+ GeoIPLoader()
+ {
BackendMakers().report(new GeoIPFactory);
g_log << Logger::Info << "[geoipbackend] This is the geoip backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
struct GeoIPDomain;
-struct GeoIPNetmask {
+struct GeoIPNetmask
+{
int netmask;
};
-class GeoIPBackend: public DNSBackend {
+class GeoIPBackend : public DNSBackend
+{
public:
- GeoIPBackend(const std::string& suffix="");
+ GeoIPBackend(const std::string& suffix = "");
~GeoIPBackend();
- void lookup(const QType &qtype, const DNSName &qdomain, int zoneId, DNSPacket *pkt_p=nullptr) override;
- bool list(const DNSName &target, int domain_id, bool include_disabled=false) override { return false; } // not supported
- bool get(DNSResourceRecord &r) override;
+ void lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p = nullptr) override;
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override { return false; } // not supported
+ bool get(DNSResourceRecord& r) override;
void reload() override;
- void rediscover(string *status = 0) override;
- bool getDomainInfo(const DNSName& domain, DomainInfo &di, bool getSerial=true) override;
+ void rediscover(string* status = 0) override;
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
// dnssec support
bool doesDNSSEC() override { return d_dnssec; };
- bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override;
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta) override;
bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override;
bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) override;
bool removeDomainKey(const DNSName& name, unsigned int id) override;
static ReadWriteLock s_state_lock;
void initialize();
- string format2str(string format, const Netmask &addr, GeoIPNetmask& gl, const GeoIPDomain &dom);
+ string format2str(string format, const Netmask& addr, GeoIPNetmask& gl, const GeoIPDomain& dom);
bool d_dnssec;
bool hasDNSSECkey(const DNSName& name);
- bool lookup_static(const GeoIPDomain &dom, const DNSName &search, const QType &qtype, const DNSName& qdomain, const Netmask &addr, GeoIPNetmask& gl);
+ bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl);
vector<DNSResourceRecord> d_result;
vector<GeoIPInterface> d_files;
};
#include "GeoIPCity.h"
#include "GeoIP.h"
-struct geoip_deleter {
- void operator()(GeoIP* ptr) {
+struct geoip_deleter
+{
+ void operator()(GeoIP* ptr)
+ {
if (ptr) {
GeoIP_delete(ptr);
}
};
};
-struct geoiprecord_deleter {
- void operator()(GeoIPRecord* ptr) {
+struct geoiprecord_deleter
+{
+ void operator()(GeoIPRecord* ptr)
+ {
if (ptr) {
GeoIPRecord_delete(ptr);
}
}
};
-struct geoipregion_deleter {
- void operator()(GeoIPRegion* ptr) {
+struct geoipregion_deleter
+{
+ void operator()(GeoIPRegion* ptr)
+ {
if (ptr) {
GeoIPRegion_delete(ptr);
}
}
};
-class GeoIPInterfaceDAT : public GeoIPInterface {
+class GeoIPInterfaceDAT : public GeoIPInterface
+{
public:
- GeoIPInterfaceDAT(const string &fname, const string &modeStr) {
+ GeoIPInterfaceDAT(const string& fname, const string& modeStr)
+ {
int flags;
if (modeStr == "standard")
flags = GEOIP_STANDARD;
d_db_type = GeoIP_database_edition(d_gi.get());
}
- bool queryCountry(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
int id;
if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_code3_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_code3_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
ret = gir->country_code3;
return false;
}
- bool queryCountryV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountryV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION_V6 ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
int id;
if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_code3_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_code3_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
ret = gir->country_code3;
return false;
}
- bool queryCountry2(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry2(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
int id;
if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_code_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
- std::unique_ptr<GeoIPRegion,geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl));
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
+ std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_code_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
ret = gir->country_code;
return false;
}
- bool queryCountry2V6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry2V6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION_V6 ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
int id;
if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_code_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_code_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
ret = gir->country_code;
return false;
}
- bool queryContinent(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryContinent(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) {
int id;
if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_continent_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
- ret = ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code));
+ ret = ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code));
gl.netmask = gir->netmask;
return true;
}
return false;
}
- bool queryContinentV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryContinentV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_COUNTRY_EDITION_V6 ||
- d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
+ if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) {
int id;
if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) {
ret = GeoIP_continent_by_id(id);
gl.netmask = tmp_gl.netmask;
return true;
}
- } else if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code));
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code));
return false;
}
- bool queryName(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryName(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_ISP_EDITION ||
- d_db_type == GEOIP_ORG_EDITION) {
+ if (d_db_type == GEOIP_ISP_EDITION || d_db_type == GEOIP_ORG_EDITION) {
char* result = GeoIP_name_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl);
if (result != nullptr) {
ret = result;
ret = boost::replace_all_copy(ret, " ", "-");
return true;
}
-
}
return false;
}
- bool queryNameV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryNameV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_ISP_EDITION_V6 ||
- d_db_type == GEOIP_ORG_EDITION_V6) {
+ if (d_db_type == GEOIP_ISP_EDITION_V6 || d_db_type == GEOIP_ORG_EDITION_V6) {
char* result = GeoIP_name_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl);
if (result != nullptr) {
ret = result;
return false;
}
- bool queryASnum(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryASnum(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
vector<string> asnr;
free(result);
stringtok(asnr, val);
- if(asnr.size()>0) {
+ if (asnr.size() > 0) {
gl.netmask = tmp_gl.netmask;
ret = asnr[0];
return true;
return false;
}
- bool queryASnumV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryASnumV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
vector<string> asnr;
free(result);
stringtok(asnr, val);
- if(asnr.size()>0) {
+ if (asnr.size() > 0) {
gl.netmask = tmp_gl.netmask;
ret = asnr[0];
return true;
return false;
}
- bool queryRegion(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryRegion(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
- ret = valueOrEmpty<char*,string>(gir->region);
+ ret = valueOrEmpty<char*, string>(gir->region);
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
- ret = valueOrEmpty<char*,string>(gir->region);
+ ret = valueOrEmpty<char*, string>(gir->region);
gl.netmask = gir->netmask;
return true;
}
return false;
}
- bool queryRegionV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryRegionV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
GeoIPLookup tmp_gl = {
.netmask = gl.netmask,
};
- if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1) {
+ if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) {
std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl));
if (gir) {
gl.netmask = tmp_gl.netmask;
- ret = valueOrEmpty<char*,string>(gir->region);
+ ret = valueOrEmpty<char*, string>(gir->region);
return true;
}
- } else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ }
+ else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
- ret = valueOrEmpty<char*,string>(gir->region);
+ ret = valueOrEmpty<char*, string>(gir->region);
gl.netmask = gir->netmask;
return true;
}
return false;
}
- bool queryCity(string &ret, GeoIPNetmask& gl, const string &ip) override {
- if (d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ bool queryCity(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
+ if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
- ret = valueOrEmpty<char*,string>(gir->city);
+ ret = valueOrEmpty<char*, string>(gir->city);
gl.netmask = gir->netmask;
return true;
}
return false;
}
- bool queryCityV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
- if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ bool queryCityV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
+ if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
- ret = valueOrEmpty<char*,string>(gir->city);
+ ret = valueOrEmpty<char*, string>(gir->city);
gl.netmask = gir->netmask;
return true;
}
return false;
}
- bool queryLocationV6(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) override {
- if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1 ||
- d_db_type == GEOIP_CITY_EDITION_REV0_V6 ||
- d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
+ bool queryLocationV6(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec) override
+ {
+ if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1 || d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str()));
if (gir) {
latitude = gir->latitude;
return false;
}
- bool queryLocation(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) override {
- if (d_db_type == GEOIP_REGION_EDITION_REV0 ||
- d_db_type == GEOIP_REGION_EDITION_REV1 ||
- d_db_type == GEOIP_CITY_EDITION_REV0 ||
- d_db_type == GEOIP_CITY_EDITION_REV1) {
+ bool queryLocation(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec) override
+ {
+ if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1 || d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) {
std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str()));
if (gir) {
latitude = gir->latitude;
return false;
}
- ~GeoIPInterfaceDAT() { }
+ ~GeoIPInterfaceDAT() {}
+
private:
unsigned int d_db_type;
unique_ptr<GeoIP, geoip_deleter> d_gi;
};
-unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface(const string &fname, const map<string, string>& opts) {
+unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface(const string& fname, const map<string, string>& opts)
+{
string mode = "standard";
- const auto &opt = opts.find("mode");
+ const auto& opt = opts.find("mode");
if (opt != opts.end())
mode = opt->second;
return unique_ptr<GeoIPInterface>(new GeoIPInterfaceDAT(fname, mode));
#else
-unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface(const string &fname, const map<string, string>& opts) {
+unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface(const string& fname, const map<string, string>& opts)
+{
throw PDNSException("libGeoIP support not compiled in");
}
#include "maxminddb.h"
-class GeoIPInterfaceMMDB : public GeoIPInterface {
+class GeoIPInterfaceMMDB : public GeoIPInterface
+{
public:
- GeoIPInterfaceMMDB(const string &fname, const string &modeStr, const string& language) {
+ GeoIPInterfaceMMDB(const string& fname, const string& modeStr, const string& language)
+ {
int ec;
int flags = 0;
if (modeStr == "")
if ((ec = MMDB_open(fname.c_str(), flags, &d_s)) < 0)
throw PDNSException(string("Cannot open ") + fname + string(": ") + string(MMDB_strerror(ec)));
d_lang = language;
- g_log<<Logger::Debug<<"Opened MMDB database "<<fname<<"(type: "<<d_s.metadata.database_type<<
- " version: "<<d_s.metadata.binary_format_major_version << "." <<
- d_s.metadata.binary_format_minor_version << ")" << endl;
+ g_log << Logger::Debug << "Opened MMDB database " << fname << "(type: " << d_s.metadata.database_type << " version: " << d_s.metadata.binary_format_major_version << "." << d_s.metadata.binary_format_minor_version << ")" << endl;
}
- bool queryCountry(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
return true;
};
- bool queryCountryV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountryV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return true;
};
- bool queryCountry2(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry2(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
return queryCountry(ret, gl, ip);
}
- bool queryCountry2V6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCountry2V6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
return queryCountryV6(ret, gl, ip);
}
- bool queryContinent(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryContinent(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
if (MMDB_get_value(&res.entry, &data, "continent", "code", NULL) != MMDB_SUCCESS || !data.has_data)
return false;
ret = string(data.utf8_string, data.data_size);
- return true;
+ return true;
}
- bool queryContinentV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryContinentV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return true;
}
- bool queryName(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryName(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
return true;
}
- bool queryNameV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryNameV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return true;
}
- bool queryASnum(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryASnum(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
return true;
}
- bool queryASnumV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryASnumV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return true;
}
- bool queryRegion(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryRegion(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
return true;
}
- bool queryRegionV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryRegionV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return true;
}
- bool queryCity(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCity(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
return false;
- if ((MMDB_get_value(&res.entry, &data, "cities", "0", NULL) != MMDB_SUCCESS || !data.has_data) &&
- (MMDB_get_value(&res.entry, &data, "city", "names", d_lang.c_str(), NULL) != MMDB_SUCCESS || !data.has_data))
+ if ((MMDB_get_value(&res.entry, &data, "cities", "0", NULL) != MMDB_SUCCESS || !data.has_data) && (MMDB_get_value(&res.entry, &data, "city", "names", d_lang.c_str(), NULL) != MMDB_SUCCESS || !data.has_data))
return false;
ret = string(data.utf8_string, data.data_size);
return true;
}
- bool queryCityV6(string &ret, GeoIPNetmask& gl, const string &ip) override {
+ bool queryCityV6(string& ret, GeoIPNetmask& gl, const string& ip) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
return false;
- if ((MMDB_get_value(&res.entry, &data, "cities", "0", NULL) != MMDB_SUCCESS || !data.has_data) &&
- (MMDB_get_value(&res.entry, &data, "city", "names", d_lang.c_str(), NULL) != MMDB_SUCCESS || !data.has_data))
+ if ((MMDB_get_value(&res.entry, &data, "cities", "0", NULL) != MMDB_SUCCESS || !data.has_data) && (MMDB_get_value(&res.entry, &data, "city", "names", d_lang.c_str(), NULL) != MMDB_SUCCESS || !data.has_data))
return false;
ret = string(data.utf8_string, data.data_size);
return true;
}
- bool queryLocation(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) override {
+ bool queryLocation(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, false, gl, res))
if (MMDB_get_value(&res.entry, &data, "location", "latitude", NULL) != MMDB_SUCCESS || !data.has_data)
return false;
latitude = data.double_value;
- if (MMDB_get_value(&res.entry, &data, "location", "longitude", NULL) != MMDB_SUCCESS || !data.has_data)
+ if (MMDB_get_value(&res.entry, &data, "location", "longitude", NULL) != MMDB_SUCCESS || !data.has_data)
return false;
longitude = data.double_value;
if (MMDB_get_value(&res.entry, &data, "location", "accuracy_radius", NULL) != MMDB_SUCCESS || !data.has_data)
return true;
}
- bool queryLocationV6(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) override {
+ bool queryLocationV6(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec) override
+ {
MMDB_entry_data_s data;
MMDB_lookup_result_s res;
if (!mmdbLookup(ip, true, gl, res))
if (MMDB_get_value(&res.entry, &data, "location", "latitude", NULL) != MMDB_SUCCESS || !data.has_data)
return false;
latitude = data.double_value;
- if (MMDB_get_value(&res.entry, &data, "location", "longitude", NULL) != MMDB_SUCCESS || !data.has_data)
+ if (MMDB_get_value(&res.entry, &data, "location", "longitude", NULL) != MMDB_SUCCESS || !data.has_data)
return false;
longitude = data.double_value;
if (MMDB_get_value(&res.entry, &data, "location", "accuracy_radius", NULL) != MMDB_SUCCESS || !data.has_data)
}
~GeoIPInterfaceMMDB() { MMDB_close(&d_s); };
+
private:
MMDB_s d_s;
string d_lang;
- bool mmdbLookup(const string &ip, bool v6, GeoIPNetmask& gl, MMDB_lookup_result_s& res) {
+ bool mmdbLookup(const string& ip, bool v6, GeoIPNetmask& gl, MMDB_lookup_result_s& res)
+ {
int gai_ec = 0, mmdb_ec = 0;
res = MMDB_lookup_string(&d_s, ip.c_str(), &gai_ec, &mmdb_ec);
-
+
if (gai_ec != 0)
- g_log<<Logger::Warning<<"MMDB_lookup_string("<<ip<<") failed: "<<gai_strerror(gai_ec)<<endl;
+ g_log << Logger::Warning << "MMDB_lookup_string(" << ip << ") failed: " << gai_strerror(gai_ec) << endl;
else if (mmdb_ec != MMDB_SUCCESS)
- g_log<<Logger::Warning<<"MMDB_lookup_string("<<ip<<") failed: "<<MMDB_strerror(mmdb_ec)<<endl;
+ g_log << Logger::Warning << "MMDB_lookup_string(" << ip << ") failed: " << MMDB_strerror(mmdb_ec) << endl;
else if (res.found_entry) {
gl.netmask = res.netmask;
/* If it's a IPv6 database, IPv4 netmasks are reduced from 128, so we need to deduct
}
};
-unique_ptr<GeoIPInterface> GeoIPInterface::makeMMDBInterface(const string &fname, const map<string, string>& opts) {
+unique_ptr<GeoIPInterface> GeoIPInterface::makeMMDBInterface(const string& fname, const map<string, string>& opts)
+{
string mode = "";
string language = "en";
- const auto &opt_mode = opts.find("mode");
+ const auto& opt_mode = opts.find("mode");
if (opt_mode != opts.end())
mode = opt_mode->second;
- const auto &opt_lang = opts.find("language");
+ const auto& opt_lang = opts.find("language");
if (opt_lang != opts.end())
language = opt_lang->second;
return unique_ptr<GeoIPInterface>(new GeoIPInterfaceMMDB(fname, mode, language));
#else
-unique_ptr<GeoIPInterface> GeoIPInterface::makeMMDBInterface(const string &fname, const map<string, string>& opts) {
+unique_ptr<GeoIPInterface> GeoIPInterface::makeMMDBInterface(const string& fname, const map<string, string>& opts)
+{
throw PDNSException("libmaxminddb support not compiled in");
}
#include "geoipbackend.hh"
#include "geoipinterface.hh"
-unique_ptr<GeoIPInterface> GeoIPInterface::makeInterface(const string& dbStr) {
+unique_ptr<GeoIPInterface> GeoIPInterface::makeInterface(const string& dbStr)
+{
/* parse dbStr */
map<string, string> opts;
vector<string> parts1, parts2;
filename = parts2[0];
size_t pos = filename.find_last_of(".");
if (pos != string::npos)
- driver = filename.substr(pos+1);
+ driver = filename.substr(pos + 1);
else
driver = "unknown";
- } else {
+ }
+ else {
driver = parts1[0];
stringtok(parts2, parts1[1], ";");
filename = parts2[0];
}
if (parts2.size() > 1) {
- parts2.erase(parts2.begin(), parts2.begin()+1);
- for(const auto &opt: parts2) {
- vector<string> kv;
- stringtok(kv, opt, "=");
- opts[kv[0]] = kv[1];
- }
+ parts2.erase(parts2.begin(), parts2.begin() + 1);
+ for (const auto& opt : parts2) {
+ vector<string> kv;
+ stringtok(kv, opt, "=");
+ opts[kv[0]] = kv[1];
+ }
}
if (driver == "dat") {
- return makeDATInterface(filename, opts);
- } else if (driver == "mmdb") {
- return makeMMDBInterface(filename, opts);
- } else {
- throw PDNSException(string("Unsupported file type '") + driver + string("' (use type: prefix to force type)"));
+ return makeDATInterface(filename, opts);
+ }
+ else if (driver == "mmdb") {
+ return makeMMDBInterface(filename, opts);
+ }
+ else {
+ throw PDNSException(string("Unsupported file type '") + driver + string("' (use type: prefix to force type)"));
}
}
#include "geoipbackend.hh"
-class GeoIPInterface {
+class GeoIPInterface
+{
public:
- enum GeoIPQueryAttribute {
+ enum GeoIPQueryAttribute
+ {
ASn,
City,
Continent,
Location
};
- virtual bool queryCountry(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryCountryV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryCountry2(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryCountry2V6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryContinent(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryContinentV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryName(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryNameV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryASnum(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryASnumV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryRegion(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryRegionV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryCity(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryCityV6(string &ret, GeoIPNetmask& gl, const string &ip) = 0;
- virtual bool queryLocation(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) = 0;
- virtual bool queryLocationV6(GeoIPNetmask& gl, const string &ip,
- double& latitude, double& longitude,
- boost::optional<int>& alt, boost::optional<int>& prec) = 0;
+ virtual bool queryCountry(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryCountryV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryCountry2(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryCountry2V6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryContinent(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryContinentV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryName(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryNameV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryASnum(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryASnumV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryRegion(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryRegionV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryCity(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryCityV6(string& ret, GeoIPNetmask& gl, const string& ip) = 0;
+ virtual bool queryLocation(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec)
+ = 0;
+ virtual bool queryLocationV6(GeoIPNetmask& gl, const string& ip,
+ double& latitude, double& longitude,
+ boost::optional<int>& alt, boost::optional<int>& prec)
+ = 0;
- virtual ~GeoIPInterface() { }
+ virtual ~GeoIPInterface() {}
static unique_ptr<GeoIPInterface> makeInterface(const string& dbStr);
+
private:
- static unique_ptr<GeoIPInterface> makeMMDBInterface(const string &fname, const map<string, string>& opts);
+ static unique_ptr<GeoIPInterface> makeMMDBInterface(const string& fname, const map<string, string>& opts);
static unique_ptr<GeoIPInterface> makeDATInterface(const string& fname, const map<string, string>& opts);
};
#include "smysql.hh"
#include <sstream>
-gMySQLBackend::gMySQLBackend(const string &mode, const string &suffix) : GSQLBackend(mode,suffix)
+gMySQLBackend::gMySQLBackend(const string& mode, const string& suffix) :
+ GSQLBackend(mode, suffix)
{
try {
reconnect();
}
- catch(SSqlException &e) {
- g_log<<Logger::Error<<mode<<" Connection failed: "<<e.txtReason()<<endl;
- throw PDNSException("Unable to launch "+mode+" connection: "+e.txtReason());
+ catch (SSqlException& e) {
+ g_log << Logger::Error << mode << " Connection failed: " << e.txtReason() << endl;
+ throw PDNSException("Unable to launch " + mode + " connection: " + e.txtReason());
}
- g_log<<Logger::Info<<mode<<" Connection successful. Connected to database '"<<getArg("dbname")<<"' on '"<<(getArg("host").empty() ? getArg("socket") : getArg("host"))<<"'."<<endl;
+ g_log << Logger::Info << mode << " Connection successful. Connected to database '" << getArg("dbname") << "' on '" << (getArg("host").empty() ? getArg("socket") : getArg("host")) << "'." << endl;
}
void gMySQLBackend::reconnect()
{
setDB(new SMySQL(getArg("dbname"),
- getArg("host"),
- getArgAsNum("port"),
- getArg("socket"),
- getArg("user"),
- getArg("password"),
- getArg("group"),
- mustDo("innodb-read-committed"),
- getArgAsNum("timeout"),
- mustDo("thread-cleanup"),
- mustDo("ssl")));
+ getArg("host"),
+ getArgAsNum("port"),
+ getArg("socket"),
+ getArg("user"),
+ getArg("password"),
+ getArg("group"),
+ mustDo("innodb-read-committed"),
+ getArgAsNum("timeout"),
+ mustDo("thread-cleanup"),
+ mustDo("ssl")));
allocateStatements();
}
class gMySQLFactory : public BackendFactory
{
public:
- gMySQLFactory(const string &mode) : BackendFactory(mode),d_mode(mode) {}
+ gMySQLFactory(const string& mode) :
+ BackendFactory(mode), d_mode(mode) {}
- void declareArguments(const string &suffix="") override
+ void declareArguments(const string& suffix = "") override
{
- declare(suffix,"dbname","Database name to connect to","powerdns");
- declare(suffix,"user","Database backend user to connect as","powerdns");
- declare(suffix,"host","Database backend host to connect to","");
- declare(suffix,"port","Database backend port to connect to","3306");
- declare(suffix,"socket","Database backend socket to connect to","");
- declare(suffix,"password","Database backend password to connect with","");
- declare(suffix,"group", "Database backend MySQL 'group' to connect as", "client");
- declare(suffix,"innodb-read-committed","Use InnoDB READ-COMMITTED transaction isolation level","yes");
- declare(suffix,"timeout", "The timeout in seconds for each attempt to read/write to the server", "10");
- declare(suffix,"thread-cleanup","Explicitly call mysql_thread_end() when threads end","no");
- declare(suffix,"ssl","Send the SSL capability flag to the server","no");
-
- declare(suffix,"dnssec","Enable DNSSEC processing","no");
+ declare(suffix, "dbname", "Database name to connect to", "powerdns");
+ declare(suffix, "user", "Database backend user to connect as", "powerdns");
+ declare(suffix, "host", "Database backend host to connect to", "");
+ declare(suffix, "port", "Database backend port to connect to", "3306");
+ declare(suffix, "socket", "Database backend socket to connect to", "");
+ declare(suffix, "password", "Database backend password to connect with", "");
+ declare(suffix, "group", "Database backend MySQL 'group' to connect as", "client");
+ declare(suffix, "innodb-read-committed", "Use InnoDB READ-COMMITTED transaction isolation level", "yes");
+ declare(suffix, "timeout", "The timeout in seconds for each attempt to read/write to the server", "10");
+ declare(suffix, "thread-cleanup", "Explicitly call mysql_thread_end() when threads end", "no");
+ declare(suffix, "ssl", "Send the SSL capability flag to the server", "no");
+
+ declare(suffix, "dnssec", "Enable DNSSEC processing", "no");
string record_query = "SELECT content,ttl,prio,type,domain_id,disabled,name,auth FROM records WHERE";
- declare(suffix, "basic-query", "Basic query", record_query+" disabled=0 and type=? and name=?");
- declare(suffix, "id-query", "Basic with ID query", record_query+" disabled=0 and type=? and name=? and domain_id=?");
- declare(suffix, "any-query", "Any query", record_query+" disabled=0 and name=?");
- declare(suffix, "any-id-query", "Any with ID query", record_query+" disabled=0 and name=? and domain_id=?");
+ declare(suffix, "basic-query", "Basic query", record_query + " disabled=0 and type=? and name=?");
+ declare(suffix, "id-query", "Basic with ID query", record_query + " disabled=0 and type=? and name=? and domain_id=?");
+ declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=?");
+ declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=? and domain_id=?");
- declare(suffix, "list-query", "AXFR query", record_query+" (disabled=0 OR ?) and domain_id=? order by name, type");
- declare(suffix, "list-subzone-query", "Subzone listing", record_query+" disabled=0 and (name=? OR name like ?) and domain_id=?");
+ declare(suffix, "list-query", "AXFR query", record_query + " (disabled=0 OR ?) and domain_id=? order by name, type");
+ declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=? OR name like ?) and domain_id=?");
declare(suffix, "remove-empty-non-terminals-from-zone-query", "remove all empty non-terminals from zone", "delete from records where domain_id=? and type is null");
declare(suffix, "delete-empty-non-terminal-query", "delete empty non-terminal from zone", "delete from records where domain_id=? and name=? and type is null");
- declare(suffix,"info-zone-query","","select id,name,master,last_check,notified_serial,type,account from domains where name=?");
+ declare(suffix, "info-zone-query", "", "select id,name,master,last_check,notified_serial,type,account from domains where name=?");
- declare(suffix,"info-all-slaves-query","","select id,name,master,last_check from domains where type='SLAVE'");
- declare(suffix,"supermaster-query","", "select account from supermasters where ip=? and nameserver=?");
- declare(suffix,"supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=? and account=?");
- declare(suffix,"supermaster-add","", "insert into supermasters (ip, nameserver, account) values (?,?,?)");
+ declare(suffix, "info-all-slaves-query", "", "select id,name,master,last_check from domains where type='SLAVE'");
+ declare(suffix, "supermaster-query", "", "select account from supermasters where ip=? and nameserver=?");
+ declare(suffix, "supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=? and account=?");
+ declare(suffix, "supermaster-add", "", "insert into supermasters (ip, nameserver, account) values (?,?,?)");
- declare(suffix,"insert-zone-query","", "insert into domains (type,name,master,account,last_check,notified_serial) values(?,?,?,?,NULL,NULL)");
+ declare(suffix, "insert-zone-query", "", "insert into domains (type,name,master,account,last_check,notified_serial) values(?,?,?,?,NULL,NULL)");
declare(suffix, "insert-record-query", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values (?,?,?,?,?,?,?,?,?)");
declare(suffix, "insert-empty-non-terminal-order-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth,content,ttl,prio) values (null,?,0,?,?,?,NULL,NULL,NULL)");
declare(suffix, "nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth for a qname query", "update records set ordername=NULL,auth=? where domain_id=? and name=? and disabled=0");
declare(suffix, "nullify-ordername-and-update-auth-type-query", "DNSSEC nullify ordername and update auth for a rrset query", "update records set ordername=NULL,auth=? where domain_id=? and name=? and type=? and disabled=0");
- declare(suffix,"update-master-query","", "update domains set master=? where name=?");
- declare(suffix,"update-kind-query","", "update domains set type=? where name=?");
- declare(suffix,"update-account-query","", "update domains set account=? where name=?");
- declare(suffix,"update-serial-query","", "update domains set notified_serial=? where id=?");
- declare(suffix,"update-lastcheck-query","", "update domains set last_check=? where id=?");
- declare(suffix,"info-all-master-query","", "select d.id, d.name, d.notified_serial, r.content from records r join domains d on r.name=d.name where r.type='SOA' and r.disabled=0 and d.type='MASTER'");
- declare(suffix,"delete-domain-query","", "delete from domains where name=?");
- declare(suffix,"delete-zone-query","", "delete from records where domain_id=?");
- declare(suffix,"delete-rrset-query","","delete from records where domain_id=? and name=? and type=?");
- declare(suffix,"delete-names-query","","delete from records where domain_id=? and name=?");
-
- declare(suffix,"add-domain-key-query","", "insert into cryptokeys (domain_id, flags, active, published, content) select id, ?, ?, ?, ? from domains where name=?");
- declare(suffix,"get-last-inserted-key-id-query", "", "select LAST_INSERT_ID()");
- declare(suffix,"list-domain-keys-query","", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=?");
- declare(suffix,"get-all-domain-metadata-query","", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=?");
- declare(suffix,"get-domain-metadata-query","", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=? and domainmetadata.kind=?");
- declare(suffix,"clear-domain-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=?) and domainmetadata.kind=?");
- declare(suffix,"clear-domain-all-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=?)");
- declare(suffix,"set-domain-metadata-query","", "insert into domainmetadata (domain_id, kind, content) select id, ?, ? from domains where name=?");
- declare(suffix,"activate-domain-key-query","", "update cryptokeys set active=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"publish-domain-key-query","", "update cryptokeys set published=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"unpublish-domain-key-query","", "update cryptokeys set published=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"clear-domain-all-keys-query","", "delete from cryptokeys where domain_id=(select id from domains where name=?)");
- declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name=?");
- declare(suffix,"set-tsig-key-query","", "replace into tsigkeys (name,algorithm,secret) values(?,?,?)");
- declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name=?");
- declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys");
+ declare(suffix, "update-master-query", "", "update domains set master=? where name=?");
+ declare(suffix, "update-kind-query", "", "update domains set type=? where name=?");
+ declare(suffix, "update-account-query", "", "update domains set account=? where name=?");
+ declare(suffix, "update-serial-query", "", "update domains set notified_serial=? where id=?");
+ declare(suffix, "update-lastcheck-query", "", "update domains set last_check=? where id=?");
+ declare(suffix, "info-all-master-query", "", "select d.id, d.name, d.notified_serial, r.content from records r join domains d on r.name=d.name where r.type='SOA' and r.disabled=0 and d.type='MASTER'");
+ declare(suffix, "delete-domain-query", "", "delete from domains where name=?");
+ declare(suffix, "delete-zone-query", "", "delete from records where domain_id=?");
+ declare(suffix, "delete-rrset-query", "", "delete from records where domain_id=? and name=? and type=?");
+ declare(suffix, "delete-names-query", "", "delete from records where domain_id=? and name=?");
+
+ declare(suffix, "add-domain-key-query", "", "insert into cryptokeys (domain_id, flags, active, published, content) select id, ?, ?, ?, ? from domains where name=?");
+ declare(suffix, "get-last-inserted-key-id-query", "", "select LAST_INSERT_ID()");
+ declare(suffix, "list-domain-keys-query", "", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=?");
+ declare(suffix, "get-all-domain-metadata-query", "", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=?");
+ declare(suffix, "get-domain-metadata-query", "", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=? and domainmetadata.kind=?");
+ declare(suffix, "clear-domain-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=?) and domainmetadata.kind=?");
+ declare(suffix, "clear-domain-all-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=?)");
+ declare(suffix, "set-domain-metadata-query", "", "insert into domainmetadata (domain_id, kind, content) select id, ?, ? from domains where name=?");
+ declare(suffix, "activate-domain-key-query", "", "update cryptokeys set active=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "deactivate-domain-key-query", "", "update cryptokeys set active=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "publish-domain-key-query", "", "update cryptokeys set published=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "unpublish-domain-key-query", "", "update cryptokeys set published=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "remove-domain-key-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "clear-domain-all-keys-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=?)");
+ declare(suffix, "get-tsig-key-query", "", "select algorithm, secret from tsigkeys where name=?");
+ declare(suffix, "set-tsig-key-query", "", "replace into tsigkeys (name,algorithm,secret) values(?,?,?)");
+ declare(suffix, "delete-tsig-key-query", "", "delete from tsigkeys where name=?");
+ declare(suffix, "get-tsig-keys-query", "", "select name,algorithm, secret from tsigkeys");
declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR ?");
declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (?, ?, ?, ?, ?, ?)");
declare(suffix, "delete-comment-rrset-query", "", "DELETE FROM comments WHERE domain_id=? AND name=? AND type=?");
declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=?");
- declare(suffix, "search-records-query", "", record_query+" name LIKE ? OR content LIKE ? LIMIT ?");
+ declare(suffix, "search-records-query", "", record_query + " name LIKE ? OR content LIKE ? LIMIT ?");
declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE ? OR comment LIKE ? LIMIT ?");
}
- DNSBackend *make(const string &suffix="") override
+ DNSBackend* make(const string& suffix = "") override
{
- return new gMySQLBackend(d_mode,suffix);
+ return new gMySQLBackend(d_mode, suffix);
}
+
private:
const string d_mode;
};
-
//! Magic class that is activated when the dynamic library is loaded
class gMySQLLoader
{
BackendMakers().report(new gMySQLFactory("gmysql"));
g_log << Logger::Info << "[gmysqlbackend] This is the gmysql backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
static gMySQLLoader gmysqlloader;
class gMySQLBackend : public GSQLBackend
{
public:
- gMySQLBackend(const string &mode, const string &suffix); //!< Makes our connection to the database. Throws an exception if it fails.
+ gMySQLBackend(const string& mode, const string& suffix); //!< Makes our connection to the database. Throws an exception if it fails.
protected:
void reconnect() override;
};
class MySQLThreadCloser
{
public:
- ~MySQLThreadCloser() {
- if(d_enabled) {
+ ~MySQLThreadCloser()
+ {
+ if (d_enabled) {
mysql_thread_end();
}
}
- void enable() {
- d_enabled = true;
+ void enable()
+ {
+ d_enabled = true;
}
private:
bool SMySQL::s_dolog;
std::mutex SMySQL::s_myinitlock;
-class SMySQLStatement: public SSqlStatement
+class SMySQLStatement : public SSqlStatement
{
public:
- SMySQLStatement(const string& query, bool dolog, int nparams, MYSQL* db) : d_prepared(false)
+ SMySQLStatement(const string& query, bool dolog, int nparams, MYSQL* db) :
+ d_prepared(false)
{
d_db = db;
d_dolog = dolog;
}
}
- SSqlStatement* bind(const string& name, bool value) {
+ SSqlStatement* bind(const string& name, bool value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
}
d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_TINY;
d_req_bind[d_paridx].buffer = new char[1];
- *((char*)d_req_bind[d_paridx].buffer) = (value?1:0);
+ *((char*)d_req_bind[d_paridx].buffer) = (value ? 1 : 0);
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, int value) {
+ SSqlStatement* bind(const string& name, int value)
+ {
return bind(name, (long)value);
}
- SSqlStatement* bind(const string& name, uint32_t value) {
+ SSqlStatement* bind(const string& name, uint32_t value)
+ {
return bind(name, (unsigned long)value);
}
- SSqlStatement* bind(const string& name, long value) {
+ SSqlStatement* bind(const string& name, long value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, unsigned long value) {
+ SSqlStatement* bind(const string& name, unsigned long value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, long long value) {
+ SSqlStatement* bind(const string& name, long long value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, unsigned long long value) {
+ SSqlStatement* bind(const string& name, unsigned long long value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, const std::string& value) {
+ SSqlStatement* bind(const string& name, const std::string& value)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
throw SSqlException("Attempt to bind more parameters than query has: " + d_query);
}
d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_STRING;
- d_req_bind[d_paridx].buffer = new char[value.size()+1];
+ d_req_bind[d_paridx].buffer = new char[value.size() + 1];
d_req_bind[d_paridx].length = new unsigned long[1];
*d_req_bind[d_paridx].length = value.size();
- d_req_bind[d_paridx].buffer_length = *d_req_bind[d_paridx].length+1;
- memset(d_req_bind[d_paridx].buffer, 0, value.size()+1);
+ d_req_bind[d_paridx].buffer_length = *d_req_bind[d_paridx].length + 1;
+ memset(d_req_bind[d_paridx].buffer, 0, value.size() + 1);
value.copy((char*)d_req_bind[d_paridx].buffer, value.size());
d_paridx++;
return this;
}
- SSqlStatement* bindNull(const string& name) {
+ SSqlStatement* bindNull(const string& name)
+ {
prepareStatement();
if (d_paridx >= d_parnum) {
releaseStatement();
return this;
}
- SSqlStatement* execute() {
+ SSqlStatement* execute()
+ {
prepareStatement();
- if (!d_stmt) return this;
+ if (!d_stmt)
+ return this;
if (d_dolog) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": " << d_query << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_query << endl;
d_dtime.set();
}
throw SSqlException("Could not store mysql statement: " + d_query + string(": ") + error);
}
- if ((d_fnum = static_cast<int>(mysql_stmt_field_count(d_stmt)))>0) {
+ if ((d_fnum = static_cast<int>(mysql_stmt_field_count(d_stmt))) > 0) {
// prepare for result
d_resnum = mysql_stmt_num_rows(d_stmt);
-
+
if (d_resnum > 0 && d_res_bind == nullptr) {
MYSQL_RES* meta = mysql_stmt_result_metadata(d_stmt);
d_fnum = static_cast<int>(mysql_num_fields(meta)); // ensure correct number of fields
d_res_bind = new MYSQL_BIND[d_fnum];
- memset(d_res_bind, 0, sizeof(MYSQL_BIND)*d_fnum);
+ memset(d_res_bind, 0, sizeof(MYSQL_BIND) * d_fnum);
MYSQL_FIELD* fields = mysql_fetch_fields(meta);
- for(int i = 0; i < d_fnum; i++) {
- unsigned long len = std::max(fields[i].max_length, fields[i].length)+1;
- if (len > 128 * 1024) len = 128 * 1024; // LONGTEXT may tell us it needs 4GB!
+ for (int i = 0; i < d_fnum; i++) {
+ unsigned long len = std::max(fields[i].max_length, fields[i].length) + 1;
+ if (len > 128 * 1024)
+ len = 128 * 1024; // LONGTEXT may tell us it needs 4GB!
d_res_bind[i].is_null = new my_bool[1];
d_res_bind[i].error = new my_bool[1];
d_res_bind[i].length = new unsigned long[1];
d_res_bind[i].buffer_length = len;
d_res_bind[i].buffer_type = MYSQL_TYPE_STRING;
}
-
+
mysql_free_result(meta);
}
}
}
- if(d_dolog)
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" usec to execute"<<endl;
+ if (d_dolog)
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl;
return this;
}
- bool hasNextRow() {
- if(d_dolog && d_residx == d_resnum) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" total usec to last row"<<endl;
+ bool hasNextRow()
+ {
+ if (d_dolog && d_residx == d_resnum) {
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " total usec to last row" << endl;
}
return d_residx < d_resnum;
}
- SSqlStatement* nextRow(row_t& row) {
+ SSqlStatement* nextRow(row_t& row)
+ {
int err;
row.clear();
if (!hasNextRow()) {
row.reserve(d_fnum);
- for(int i=0;i<d_fnum;i++) {
+ for (int i = 0; i < d_fnum; i++) {
if (err == MYSQL_DATA_TRUNCATED && *d_res_bind[i].error) {
- g_log<<Logger::Warning<<"Result field at row " << d_residx << " column " << i << " has been truncated, we allocated " << d_res_bind[i].buffer_length << " bytes but at least " << *d_res_bind[i].length << " was needed" << endl;
+ g_log << Logger::Warning << "Result field at row " << d_residx << " column " << i << " has been truncated, we allocated " << d_res_bind[i].buffer_length << " bytes but at least " << *d_res_bind[i].length << " was needed" << endl;
}
if (*d_res_bind[i].is_null) {
row.emplace_back("");
continue;
- } else {
+ }
+ else {
row.emplace_back((char*)d_res_bind[i].buffer, std::min(d_res_bind[i].buffer_length, *d_res_bind[i].length));
}
}
#if MYSQL_VERSION_ID >= 50500
if (d_residx >= d_resnum) {
mysql_stmt_free_result(d_stmt);
- while(!mysql_stmt_next_result(d_stmt)) {
+ while (!mysql_stmt_next_result(d_stmt)) {
if (mysql_stmt_store_result(d_stmt) != 0) {
string error(mysql_stmt_error(d_stmt));
releaseStatement();
}
}
#endif
- return this;
+ return this;
}
- SSqlStatement* getResult(result_t& result) {
+ SSqlStatement* getResult(result_t& result)
+ {
result.clear();
result.reserve(d_resnum);
row_t row;
- while(hasNextRow()) {
+ while (hasNextRow()) {
nextRow(row);
result.push_back(std::move(row));
}
- return this;
+ return this;
}
- SSqlStatement* reset() {
- if (!d_stmt) return this;
- int err=0;
+ SSqlStatement* reset()
+ {
+ if (!d_stmt)
+ return this;
+ int err = 0;
mysql_stmt_free_result(d_stmt);
#if MYSQL_VERSION_ID >= 50500
- while((err = mysql_stmt_next_result(d_stmt)) == 0) {
+ while ((err = mysql_stmt_next_result(d_stmt)) == 0) {
mysql_stmt_free_result(d_stmt);
}
#endif
- if (err>0) {
+ if (err > 0) {
string error(mysql_stmt_error(d_stmt));
releaseStatement();
throw SSqlException("Could not get next result from mysql statement: " + d_query + string(": ") + error);
}
mysql_stmt_reset(d_stmt);
if (d_req_bind) {
- for(int i=0;i<d_parnum;i++) {
- if (d_req_bind[i].buffer) delete [] (char*)d_req_bind[i].buffer;
- if (d_req_bind[i].length) delete [] d_req_bind[i].length;
+ for (int i = 0; i < d_parnum; i++) {
+ if (d_req_bind[i].buffer)
+ delete[](char*) d_req_bind[i].buffer;
+ if (d_req_bind[i].length)
+ delete[] d_req_bind[i].length;
}
- memset(d_req_bind, 0, sizeof(MYSQL_BIND)*d_parnum);
+ memset(d_req_bind, 0, sizeof(MYSQL_BIND) * d_parnum);
}
d_residx = d_resnum = 0;
d_paridx = 0;
const std::string& getQuery() { return d_query; }
- ~SMySQLStatement() {
+ ~SMySQLStatement()
+ {
releaseStatement();
}
-private:
- void prepareStatement() {
- if (d_prepared) return;
+private:
+ void prepareStatement()
+ {
+ if (d_prepared)
+ return;
if (d_query.empty()) {
d_prepared = true;
return;
}
- if ((d_stmt = mysql_stmt_init(d_db))==nullptr)
+ if ((d_stmt = mysql_stmt_init(d_db)) == nullptr)
throw SSqlException("Could not initialize mysql statement, out of memory: " + d_query);
if (mysql_stmt_prepare(d_stmt, d_query.c_str(), d_query.size()) != 0) {
throw SSqlException("Provided parameter count does not match statement: " + d_query);
}
- if (d_parnum>0) {
+ if (d_parnum > 0) {
d_req_bind = new MYSQL_BIND[d_parnum];
- memset(d_req_bind, 0, sizeof(MYSQL_BIND)*d_parnum);
+ memset(d_req_bind, 0, sizeof(MYSQL_BIND) * d_parnum);
}
d_prepared = true;
}
- void releaseStatement() {
+ void releaseStatement()
+ {
d_prepared = false;
if (d_stmt)
mysql_stmt_close(d_stmt);
d_stmt = nullptr;
if (d_req_bind) {
- for(int i=0;i<d_parnum;i++) {
- if (d_req_bind[i].buffer) delete [] (char*)d_req_bind[i].buffer;
- if (d_req_bind[i].length) delete [] d_req_bind[i].length;
+ for (int i = 0; i < d_parnum; i++) {
+ if (d_req_bind[i].buffer)
+ delete[](char*) d_req_bind[i].buffer;
+ if (d_req_bind[i].length)
+ delete[] d_req_bind[i].length;
}
- delete [] d_req_bind;
+ delete[] d_req_bind;
d_req_bind = nullptr;
}
if (d_res_bind) {
- for(int i=0;i<d_fnum;i++) {
- if (d_res_bind[i].buffer) delete [] (char*)d_res_bind[i].buffer;
- if (d_res_bind[i].length) delete [] d_res_bind[i].length;
- if (d_res_bind[i].error) delete [] d_res_bind[i].error;
- if (d_res_bind[i].is_null) delete [] d_res_bind[i].is_null;
+ for (int i = 0; i < d_fnum; i++) {
+ if (d_res_bind[i].buffer)
+ delete[](char*) d_res_bind[i].buffer;
+ if (d_res_bind[i].length)
+ delete[] d_res_bind[i].length;
+ if (d_res_bind[i].error)
+ delete[] d_res_bind[i].error;
+ if (d_res_bind[i].is_null)
+ delete[] d_res_bind[i].is_null;
}
- delete [] d_res_bind;
+ delete[] d_res_bind;
d_res_bind = nullptr;
}
d_paridx = d_fnum = d_resnum = d_residx = 0;
MYSQL_BIND* d_res_bind;
string d_query;
-
+
bool d_prepared;
bool d_dolog;
DTime d_dtime; // only used if d_dolog is set
void SMySQL::connect()
{
- int retry=1;
+ int retry = 1;
std::lock_guard<std::mutex> l(s_myinitlock);
if (d_threadCleanup) {
#endif
#if MYSQL_VERSION_ID >= 50100
- if(d_timeout) {
+ if (d_timeout) {
mysql_options(&d_db, MYSQL_OPT_READ_TIMEOUT, &d_timeout);
mysql_options(&d_db, MYSQL_OPT_WRITE_TIMEOUT, &d_timeout);
}
#endif
if (d_setIsolation && (retry == 1))
- mysql_options(&d_db, MYSQL_INIT_COMMAND,"SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED");
+ mysql_options(&d_db, MYSQL_INIT_COMMAND, "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED");
mysql_options(&d_db, MYSQL_READ_DEFAULT_GROUP, d_group.c_str());
if (!mysql_real_connect(&d_db, d_host.empty() ? nullptr : d_host.c_str(),
- d_user.empty() ? nullptr : d_user.c_str(),
- d_password.empty() ? nullptr : d_password.c_str(),
- d_database.empty() ? nullptr : d_database.c_str(),
- d_port,
- d_msocket.empty() ? nullptr : d_msocket.c_str(),
- (d_clientSSL ? CLIENT_SSL : 0) | CLIENT_MULTI_RESULTS)) {
+ d_user.empty() ? nullptr : d_user.c_str(),
+ d_password.empty() ? nullptr : d_password.c_str(),
+ d_database.empty() ? nullptr : d_database.c_str(),
+ d_port,
+ d_msocket.empty() ? nullptr : d_msocket.c_str(),
+ (d_clientSSL ? CLIENT_SSL : 0) | CLIENT_MULTI_RESULTS)) {
if (retry == 0)
throw sPerrorException("Unable to connect to database");
--retry;
- } else {
+ }
+ else {
if (retry == 0) {
mysql_close(&d_db);
throw sPerrorException("Please add '(gmysql-)innodb-read-committed=no' to your PowerDNS configuration, and reconsider your storage engine if it does not support transactions.");
}
- retry=-1;
+ retry = -1;
}
} while (retry >= 0);
}
SMySQL::SMySQL(string database, string host, uint16_t port, string msocket, string user,
- string password, string group, bool setIsolation, unsigned int timeout, bool threadCleanup, bool clientSSL):
+ string password, string group, bool setIsolation, unsigned int timeout, bool threadCleanup, bool clientSSL) :
d_database(std::move(database)), d_host(std::move(host)), d_msocket(std::move(msocket)), d_user(std::move(user)), d_password(std::move(password)), d_group(std::move(group)), d_timeout(timeout), d_port(port), d_setIsolation(setIsolation), d_threadCleanup(threadCleanup), d_clientSSL(clientSSL)
{
connect();
void SMySQL::setLog(bool state)
{
- s_dolog=state;
+ s_dolog = state;
}
SMySQL::~SMySQL()
mysql_close(&d_db);
}
-SSqlException SMySQL::sPerrorException(const string &reason)
+SSqlException SMySQL::sPerrorException(const string& reason)
{
- return SSqlException(reason+string(": ERROR ")+std::to_string(mysql_errno(&d_db))+" ("+string(mysql_sqlstate(&d_db))+"): "+mysql_error(&d_db));
+ return SSqlException(reason + string(": ERROR ") + std::to_string(mysql_errno(&d_db)) + " (" + string(mysql_sqlstate(&d_db)) + "): " + mysql_error(&d_db));
}
std::unique_ptr<SSqlStatement> SMySQL::prepare(const string& query, int nparams)
void SMySQL::execute(const string& query)
{
- if(s_dolog)
- g_log<<Logger::Warning<<"Query: "<<query<<endl;
+ if (s_dolog)
+ g_log << Logger::Warning << "Query: " << query << endl;
int err;
- if((err=mysql_query(&d_db,query.c_str())))
- throw sPerrorException("Failed to execute mysql_query '" + query + "' Err="+itoa(err));
+ if ((err = mysql_query(&d_db, query.c_str())))
+ throw sPerrorException("Failed to execute mysql_query '" + query + "' Err=" + itoa(err));
}
-void SMySQL::startTransaction() {
+void SMySQL::startTransaction()
+{
execute("begin");
}
-void SMySQL::commit() {
+void SMySQL::commit()
+{
execute("commit");
}
-void SMySQL::rollback() {
+void SMySQL::rollback()
+{
execute("rollback");
}
class SMySQL : public SSql
{
public:
- SMySQL(string database, string host="", uint16_t port=0,
- string msocket="",string user="",
- string password="", string group="",
- bool setIsolation=false, unsigned int timeout=10,
- bool threadCleanup=false, bool clientSSL=false);
+ SMySQL(string database, string host = "", uint16_t port = 0,
+ string msocket = "", string user = "",
+ string password = "", string group = "",
+ bool setIsolation = false, unsigned int timeout = 10,
+ bool threadCleanup = false, bool clientSSL = false);
~SMySQL();
- SSqlException sPerrorException(const string &reason) override;
+ SSqlException sPerrorException(const string& reason) override;
void setLog(bool state) override;
std::unique_ptr<SSqlStatement> prepare(const string& query, int nparams) override;
void execute(const string& query) override;
void commit() override;
void rollback() override;
bool isConnectionUsable() override;
+
private:
void connect();
#include "sodbc.hh"
#include "godbcbackend.hh"
-
// Connects to the database.
-gODBCBackend::gODBCBackend (const std::string & mode, const std::string & suffix) : GSQLBackend( mode, suffix )
+gODBCBackend::gODBCBackend(const std::string& mode, const std::string& suffix) :
+ GSQLBackend(mode, suffix)
{
- try
- {
- setDB( new SODBC( getArg( "datasource" ), getArg( "username" ), getArg( "password" )));
+ try {
+ setDB(new SODBC(getArg("datasource"), getArg("username"), getArg("password")));
}
- catch( SSqlException & e )
- {
- g_log<<Logger::Error<< mode << " Connection failed: " << e.txtReason() << std::endl;
- throw PDNSException( "Unable to launch " + mode + " connection: " + e.txtReason());
+ catch (SSqlException& e) {
+ g_log << Logger::Error << mode << " Connection failed: " << e.txtReason() << std::endl;
+ throw PDNSException("Unable to launch " + mode + " connection: " + e.txtReason());
}
allocateStatements();
g_log << Logger::Warning << mode << " Connection successful" << std::endl;
}
-
//! Constructs a gODBCBackend
class gODBCFactory : public BackendFactory
{
public:
//! Constructor.
- gODBCFactory( const std::string & mode ) : BackendFactory( mode ), d_mode( mode )
+ gODBCFactory(const std::string& mode) :
+ BackendFactory(mode), d_mode(mode)
{
}
//! Declares all needed arguments.
- void declareArguments( const std::string & suffix = "" ) override
+ void declareArguments(const std::string& suffix = "") override
{
- declare( suffix, "datasource", "Datasource (DSN) to use","PowerDNS");
- declare( suffix, "username", "User to connect as","powerdns");
- declare( suffix, "password", "Password to connect with","");
- declare(suffix,"dnssec","Enable DNSSEC processing","no");
+ declare(suffix, "datasource", "Datasource (DSN) to use", "PowerDNS");
+ declare(suffix, "username", "User to connect as", "powerdns");
+ declare(suffix, "password", "Password to connect with", "");
+ declare(suffix, "dnssec", "Enable DNSSEC processing", "no");
string record_query = "SELECT content,ttl,prio,type,domain_id,disabled,name,auth FROM records WHERE";
- declare(suffix, "basic-query", "Basic query", record_query+" disabled=0 and type=? and name=?");
- declare(suffix, "id-query", "Basic with ID query", record_query+" disabled=0 and type=? and name=? and domain_id=?");
- declare(suffix, "any-query", "Any query", record_query+" disabled=0 and name=?");
- declare(suffix, "any-id-query", "Any with ID query", record_query+" disabled=0 and name=? and domain_id=?");
+ declare(suffix, "basic-query", "Basic query", record_query + " disabled=0 and type=? and name=?");
+ declare(suffix, "id-query", "Basic with ID query", record_query + " disabled=0 and type=? and name=? and domain_id=?");
+ declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=?");
+ declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=? and domain_id=?");
- declare(suffix, "list-query", "AXFR query", record_query+" (disabled=0 OR disabled=?) and domain_id=? order by name, type");
- declare(suffix, "list-subzone-query", "Subzone listing", record_query+" disabled=0 and (name=? OR name like ?) and domain_id=?");
+ declare(suffix, "list-query", "AXFR query", record_query + " (disabled=0 OR disabled=?) and domain_id=? order by name, type");
+ declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=? OR name like ?) and domain_id=?");
declare(suffix, "remove-empty-non-terminals-from-zone-query", "remove all empty non-terminals from zone", "delete from records where domain_id=? and type is null");
declare(suffix, "delete-empty-non-terminal-query", "delete empty non-terminal from zone", "delete from records where domain_id=? and name=? and type is null");
- declare(suffix,"info-zone-query","","select id,name,master,last_check,notified_serial,type,account from domains where name=?");
+ declare(suffix, "info-zone-query", "", "select id,name,master,last_check,notified_serial,type,account from domains where name=?");
- declare(suffix,"info-all-slaves-query","","select id,name,master,last_check from domains where type='SLAVE'");
- declare(suffix,"supermaster-query","", "select account from supermasters where ip=? and nameserver=?");
- declare(suffix,"supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=? and account=?");
- declare(suffix,"supermaster-add","", "insert into supermasters (ip, nameserver, account) values (?,?,?)");
+ declare(suffix, "info-all-slaves-query", "", "select id,name,master,last_check from domains where type='SLAVE'");
+ declare(suffix, "supermaster-query", "", "select account from supermasters where ip=? and nameserver=?");
+ declare(suffix, "supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=? and account=?");
+ declare(suffix, "supermaster-add", "", "insert into supermasters (ip, nameserver, account) values (?,?,?)");
- declare(suffix,"insert-zone-query","", "insert into domains (type,name,master,account,last_check,notified_serial) values(?,?,?,?,null,null)");
+ declare(suffix, "insert-zone-query", "", "insert into domains (type,name,master,account,last_check,notified_serial) values(?,?,?,?,null,null)");
declare(suffix, "insert-record-query", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values (?,?,?,?,?,?,?,convert(varbinary(255),?),?)");
declare(suffix, "insert-empty-non-terminal-order-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth,ttl,prio,content) values (null,?,0,?,convert(varbinary(255),?),?,null,null,null)");
declare(suffix, "nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth for a qname query", "update records set ordername=NULL,auth=? where domain_id=? and name=? and disabled=0");
declare(suffix, "nullify-ordername-and-update-auth-type-query", "DNSSEC nullify ordername and update auth for a rrset query", "update records set ordername=NULL,auth=? where domain_id=? and name=? and type=? and disabled=0");
- declare(suffix,"update-master-query","", "update domains set master=? where name=?");
- declare(suffix,"update-kind-query","", "update domains set type=? where name=?");
- declare(suffix,"update-account-query","", "update domains set account=? where name=?");
- declare(suffix,"update-serial-query","", "update domains set notified_serial=? where id=?");
- declare(suffix,"update-lastcheck-query","", "update domains set last_check=? where id=?");
- declare(suffix,"info-all-master-query","", "select domains.id, domains.name, domains.notified_serial, records.content from records join domains on records.name=domains.name where records.type='SOA' and records.disabled=0 and domains.type='MASTER'");
- declare(suffix,"delete-domain-query","", "delete from domains where name=?");
- declare(suffix,"delete-zone-query","", "delete from records where domain_id=?");
- declare(suffix,"delete-rrset-query","","delete from records where domain_id=? and name=? and type=?");
- declare(suffix,"delete-names-query","","delete from records where domain_id=? and name=?");
-
- declare(suffix,"add-domain-key-query","", "insert into cryptokeys (domain_id, flags, active, published, content) select id, ?, ?, ?, ? from domains where name=?");
- declare(suffix,"get-last-inserted-key-id-query", "", "select ident_current('cryptokeys')");
- declare(suffix,"list-domain-keys-query","", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=?");
- declare(suffix,"get-all-domain-metadata-query","", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=?");
- declare(suffix,"get-domain-metadata-query","", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=? and domainmetadata.kind=?");
- declare(suffix,"clear-domain-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=?) and domainmetadata.kind=?");
- declare(suffix,"clear-domain-all-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=?)");
- declare(suffix,"set-domain-metadata-query","", "insert into domainmetadata (domain_id, kind, content) select id, ?, ? from domains where name=?");
- declare(suffix,"activate-domain-key-query","", "update cryptokeys set active=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"publish-domain-key-query","", "update cryptokeys set published=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"unpublish-domain-key-query","", "update cryptokeys set published=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
- declare(suffix,"clear-domain-all-keys-query","", "delete from cryptokeys where domain_id=(select id from domains where name=?)");
- declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name=?");
+ declare(suffix, "update-master-query", "", "update domains set master=? where name=?");
+ declare(suffix, "update-kind-query", "", "update domains set type=? where name=?");
+ declare(suffix, "update-account-query", "", "update domains set account=? where name=?");
+ declare(suffix, "update-serial-query", "", "update domains set notified_serial=? where id=?");
+ declare(suffix, "update-lastcheck-query", "", "update domains set last_check=? where id=?");
+ declare(suffix, "info-all-master-query", "", "select domains.id, domains.name, domains.notified_serial, records.content from records join domains on records.name=domains.name where records.type='SOA' and records.disabled=0 and domains.type='MASTER'");
+ declare(suffix, "delete-domain-query", "", "delete from domains where name=?");
+ declare(suffix, "delete-zone-query", "", "delete from records where domain_id=?");
+ declare(suffix, "delete-rrset-query", "", "delete from records where domain_id=? and name=? and type=?");
+ declare(suffix, "delete-names-query", "", "delete from records where domain_id=? and name=?");
+
+ declare(suffix, "add-domain-key-query", "", "insert into cryptokeys (domain_id, flags, active, published, content) select id, ?, ?, ?, ? from domains where name=?");
+ declare(suffix, "get-last-inserted-key-id-query", "", "select ident_current('cryptokeys')");
+ declare(suffix, "list-domain-keys-query", "", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=?");
+ declare(suffix, "get-all-domain-metadata-query", "", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=?");
+ declare(suffix, "get-domain-metadata-query", "", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=? and domainmetadata.kind=?");
+ declare(suffix, "clear-domain-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=?) and domainmetadata.kind=?");
+ declare(suffix, "clear-domain-all-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=?)");
+ declare(suffix, "set-domain-metadata-query", "", "insert into domainmetadata (domain_id, kind, content) select id, ?, ? from domains where name=?");
+ declare(suffix, "activate-domain-key-query", "", "update cryptokeys set active=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "deactivate-domain-key-query", "", "update cryptokeys set active=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "publish-domain-key-query", "", "update cryptokeys set published=1 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "unpublish-domain-key-query", "", "update cryptokeys set published=0 where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "remove-domain-key-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=?) and cryptokeys.id=?");
+ declare(suffix, "clear-domain-all-keys-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=?)");
+ declare(suffix, "get-tsig-key-query", "", "select algorithm, secret from tsigkeys where name=?");
/* FIXME: set-tsig-key-query only works on an empty database right now. For MySQL we use the "update into" statement..
According to the internet, we need to construct a pretty hefty "merge" query: https://msdn.microsoft.com/en-us/library/bb510625.aspx
*/
- declare(suffix,"set-tsig-key-query","", "insert into tsigkeys (name,algorithm,secret) values(?,?,?)");
- declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name=?");
- declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys");
+ declare(suffix, "set-tsig-key-query", "", "insert into tsigkeys (name,algorithm,secret) values(?,?,?)");
+ declare(suffix, "delete-tsig-key-query", "", "delete from tsigkeys where name=?");
+ declare(suffix, "get-tsig-keys-query", "", "select name,algorithm, secret from tsigkeys");
declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR records.disabled=?");
declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (?, ?, ?, ?, ?, ?)");
declare(suffix, "delete-comment-rrset-query", "", "DELETE FROM comments WHERE domain_id=? AND name=? AND type=?");
declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=?");
- declare(suffix, "search-records-query", "", record_query+" name LIKE ? OR content LIKE ? LIMIT ?");
+ declare(suffix, "search-records-query", "", record_query + " name LIKE ? OR content LIKE ? LIMIT ?");
declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE ? OR comment LIKE ? LIMIT ?");
}
//! Constructs a new gODBCBackend object.
- DNSBackend *make(const string & suffix = "" ) override
+ DNSBackend* make(const string& suffix = "") override
{
- return new gODBCBackend( d_mode, suffix );
+ return new gODBCBackend(d_mode, suffix);
}
private:
const string d_mode;
};
-
//! Magic class that is activated when the dynamic library is loaded
class gODBCLoader
{
//! This reports us to the main UeberBackend class
gODBCLoader()
{
- BackendMakers().report( new gODBCFactory("godbc"));
- g_log<<Logger::Warning << "This is module godbcbackend reporting" << std::endl;
+ BackendMakers().report(new gODBCFactory("godbc"));
+ g_log << Logger::Warning << "This is module godbcbackend reporting" << std::endl;
}
};
{
public:
//! Constructor that connects to the database, throws an exception if something went wrong.
- gODBCBackend( const std::string & mode, const std::string & suffix );
-
+ gODBCBackend(const std::string& mode, const std::string& suffix);
};
#include "sodbc.hh"
#include <string.h>
-static bool realTestResult( SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string & message, std::string & errorMessage)
+static bool realTestResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string& message, std::string& errorMessage)
{
// cerr<<"result = "<<result<<endl;
- if ( result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO )
+ if (result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO)
return true;
ostringstream errmsg;
errmsg << message << ": ";
- if ( result != SQL_ERROR && result != SQL_SUCCESS_WITH_INFO ) {
- cerr<<"handle "<<handle<<" got result "<<result<<endl;
- errmsg << "SQL function returned "<<result<<", no additional information available"<<endl;
+ if (result != SQL_ERROR && result != SQL_SUCCESS_WITH_INFO) {
+ cerr << "handle " << handle << " got result " << result << endl;
+ errmsg << "SQL function returned " << result << ", no additional information available" << endl;
errorMessage = errmsg.str();
return false;
}
SQLINTEGER i = 0;
SQLINTEGER native;
- SQLCHAR state[ 7 ];
+ SQLCHAR state[7];
SQLCHAR text[256];
SQLSMALLINT len;
SQLRETURN ret;
- do
- {
+ do {
// cerr<<"getting sql diag record "<<i<<endl;
ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
- sizeof(text), &len );
+ sizeof(text), &len);
// cerr<<"getdiagrec said "<<ret<<endl;
if (SQL_SUCCEEDED(ret)) { // cerr<<"got it"<<endl;
- errmsg<<state<<i<<native<<text<<"/";
+ errmsg << state << i << native << text << "/";
}
- }
- while( ret == SQL_SUCCESS );
+ } while (ret == SQL_SUCCESS);
errorMessage = errmsg.str();
return false;
}
-class SODBCStatement: public SSqlStatement
+class SODBCStatement : public SSqlStatement
{
public:
SODBCStatement(const string& query, bool dolog, int nparams, SQLHDBC connection)
d_parnum = nparams;
}
- struct ODBCParam {
- SQLPOINTER ParameterValuePtr;
- SQLLEN* LenPtr;
- SQLSMALLINT ParameterType;
- SQLSMALLINT ValueType;
+ struct ODBCParam
+ {
+ SQLPOINTER ParameterValuePtr;
+ SQLLEN* LenPtr;
+ SQLSMALLINT ParameterType;
+ SQLSMALLINT ValueType;
};
vector<ODBCParam> d_req_bind;
- SSqlStatement* bind(const string& name, ODBCParam& p) {
+ SSqlStatement* bind(const string& name, ODBCParam& p)
+ {
prepareStatement();
d_req_bind.push_back(p);
SQLRETURN result = SQLBindParameter(
- d_statement, // StatementHandle,
- d_paridx+1, // ParameterNumber,
- SQL_PARAM_INPUT, // InputOutputType,
- p.ValueType, // ValueType,
- p.ParameterType, // ParameterType,
- 0, // ColumnSize,
- 0, // DecimalDigits,
- p.ParameterValuePtr, // ParameterValuePtr,
- 0, // BufferLength,
- p.LenPtr // StrLen_or_IndPtr
+ d_statement, // StatementHandle,
+ d_paridx + 1, // ParameterNumber,
+ SQL_PARAM_INPUT, // InputOutputType,
+ p.ValueType, // ValueType,
+ p.ParameterType, // ParameterType,
+ 0, // ColumnSize,
+ 0, // DecimalDigits,
+ p.ParameterValuePtr, // ParameterValuePtr,
+ 0, // BufferLength,
+ p.LenPtr // StrLen_or_IndPtr
);
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not bind parameter.");
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not bind parameter.");
d_paridx++;
return this;
}
- SSqlStatement* bind(const string& name, bool value) { prepareStatement(); return bind(name, (uint32_t)value); }
+ SSqlStatement* bind(const string& name, bool value)
+ {
+ prepareStatement();
+ return bind(name, (uint32_t)value);
+ }
- SSqlStatement* bind(const string& name, long value) { prepareStatement(); return bind(name, (unsigned long)value); }
+ SSqlStatement* bind(const string& name, long value)
+ {
+ prepareStatement();
+ return bind(name, (unsigned long)value);
+ }
- SSqlStatement* bind(const string& name, int value) { prepareStatement(); return bind(name, (uint32_t)value); }
+ SSqlStatement* bind(const string& name, int value)
+ {
+ prepareStatement();
+ return bind(name, (uint32_t)value);
+ }
- SSqlStatement* bind(const string& name, long long value) { prepareStatement(); return bind(name, (unsigned long long)value); }
+ SSqlStatement* bind(const string& name, long long value)
+ {
+ prepareStatement();
+ return bind(name, (unsigned long long)value);
+ }
- SSqlStatement* bind(const string& name, uint32_t value) {
+ SSqlStatement* bind(const string& name, uint32_t value)
+ {
prepareStatement();
ODBCParam p;
- p.ParameterValuePtr = new UDWORD {value};
- p.LenPtr = new SQLLEN {sizeof(UDWORD)};
+ p.ParameterValuePtr = new UDWORD{value};
+ p.LenPtr = new SQLLEN{sizeof(UDWORD)};
p.ParameterType = SQL_INTEGER;
p.ValueType = SQL_INTEGER;
return bind(name, p);
}
- SSqlStatement* bind(const string& name, unsigned long value) {
+ SSqlStatement* bind(const string& name, unsigned long value)
+ {
prepareStatement();
ODBCParam p;
- p.ParameterValuePtr = new ULONG {value};
- p.LenPtr = new SQLLEN {sizeof(ULONG)};
+ p.ParameterValuePtr = new ULONG{value};
+ p.LenPtr = new SQLLEN{sizeof(ULONG)};
p.ParameterType = SQL_INTEGER;
p.ValueType = SQL_INTEGER;
return bind(name, p);
}
- SSqlStatement* bind(const string& name, unsigned long long value) {
+ SSqlStatement* bind(const string& name, unsigned long long value)
+ {
prepareStatement();
ODBCParam p;
- p.ParameterValuePtr = new unsigned long long {value};
- p.LenPtr = new SQLLEN {sizeof(unsigned long long)};
+ p.ParameterValuePtr = new unsigned long long{value};
+ p.LenPtr = new SQLLEN{sizeof(unsigned long long)};
p.ParameterType = SQL_BIGINT;
p.ValueType = SQL_C_UBIGINT;
return bind(name, p);
}
- SSqlStatement* bind(const string& name, const std::string& value) {
+ SSqlStatement* bind(const string& name, const std::string& value)
+ {
// cerr<<"asked to bind string "<<value<<endl;
- if(d_req_bind.size() > (d_parnum+1)) throw SSqlException("Trying to bind too many parameters.");
+ if (d_req_bind.size() > (d_parnum + 1))
+ throw SSqlException("Trying to bind too many parameters.");
prepareStatement();
ODBCParam p;
- p.ParameterValuePtr = (char*) new char[value.size()+1];
+ p.ParameterValuePtr = (char*)new char[value.size() + 1];
value.copy((char*)p.ParameterValuePtr, value.size());
- ((char*)p.ParameterValuePtr)[value.size()]=0;
- p.LenPtr=new SQLLEN;
- *(p.LenPtr)=value.size();
+ ((char*)p.ParameterValuePtr)[value.size()] = 0;
+ p.LenPtr = new SQLLEN;
+ *(p.LenPtr) = value.size();
p.ParameterType = SQL_VARCHAR;
p.ValueType = SQL_C_CHAR;
return bind(name, p);
}
- SSqlStatement* bindNull(const string& name) {
- if(d_req_bind.size() > (d_parnum+1)) throw SSqlException("Trying to bind too many parameters.");
+ SSqlStatement* bindNull(const string& name)
+ {
+ if (d_req_bind.size() > (d_parnum + 1))
+ throw SSqlException("Trying to bind too many parameters.");
prepareStatement();
ODBCParam p;
p.ParameterValuePtr = NULL;
- p.LenPtr=new SQLLEN;
- *(p.LenPtr)=SQL_NULL_DATA;
+ p.LenPtr = new SQLLEN;
+ *(p.LenPtr) = SQL_NULL_DATA;
p.ParameterType = SQL_VARCHAR;
p.ValueType = SQL_C_CHAR;
SQLRETURN result;
// cerr<<"execute("<<d_query<<")"<<endl;
if (d_dolog) {
- g_log<<Logger::Warning<<"Query: "<<d_query<<endl;
+ g_log << Logger::Warning << "Query: " << d_query << endl;
}
result = SQLExecute(d_statement);
- if(result != SQL_NO_DATA) // odbc+sqlite returns this on 'no rows updated'
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not execute query ("+d_query+")." );
+ if (result != SQL_NO_DATA) // odbc+sqlite returns this on 'no rows updated'
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not execute query (" + d_query + ").");
// Determine the number of columns.
- result = SQLNumResultCols( d_statement, &m_columncount );
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not determine the number of columns." );
+ result = SQLNumResultCols(d_statement, &m_columncount);
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not determine the number of columns.");
// cerr<<"got "<<m_columncount<<" columns"<<endl;
- if(m_columncount) {
+ if (m_columncount) {
// cerr<<"first SQLFetch"<<endl;
d_result = SQLFetch(d_statement);
// cerr<<"first SQLFetch done, d_result="<<d_result<<endl;
else
d_result = SQL_NO_DATA;
- if(d_result != SQL_NO_DATA)
- testResult( d_result, SQL_HANDLE_STMT, d_statement, "Could not do first SQLFetch for ("+d_query+")." );
+ if (d_result != SQL_NO_DATA)
+ testResult(d_result, SQL_HANDLE_STMT, d_statement, "Could not do first SQLFetch for (" + d_query + ").");
return this;
}
- bool hasNextRow() {
+ bool hasNextRow()
+ {
// cerr<<"hasNextRow d_result="<<d_result<<endl;
- return d_result!=SQL_NO_DATA;
+ return d_result != SQL_NO_DATA;
}
SSqlStatement* nextRow(row_t& row);
- SSqlStatement* getResult(result_t& result) {
+ SSqlStatement* getResult(result_t& result)
+ {
result.clear();
// if (d_res == NULL) return this;
row_t row;
- while(hasNextRow()) { nextRow(row); result.push_back(row); }
+ while (hasNextRow()) {
+ nextRow(row);
+ result.push_back(row);
+ }
return this;
}
- SSqlStatement* reset() {
+ SSqlStatement* reset()
+ {
SQLCloseCursor(d_statement); // hack, this probably violates some state transitions
- for(auto &i: d_req_bind) {
- if (i.ParameterType == SQL_VARCHAR) delete [] (char*)i.ParameterValuePtr;
- else if (i.ParameterType == SQL_INTEGER) delete (ULONG*)i.ParameterValuePtr;
- else if (i.ParameterType == SQL_C_UBIGINT) delete (unsigned long long*)i.ParameterValuePtr;
+ for (auto& i : d_req_bind) {
+ if (i.ParameterType == SQL_VARCHAR)
+ delete[](char*) i.ParameterValuePtr;
+ else if (i.ParameterType == SQL_INTEGER)
+ delete (ULONG*)i.ParameterValuePtr;
+ else if (i.ParameterType == SQL_C_UBIGINT)
+ delete (unsigned long long*)i.ParameterValuePtr;
delete i.LenPtr;
}
d_req_bind.clear();
}
const std::string& getQuery() { return d_query; }
- ~SODBCStatement() {
+ ~SODBCStatement()
+ {
releaseStatement();
}
-private:
- void testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string & message) {
- std::string errorMessage;
- if (!realTestResult(result, type, handle, message, errorMessage)) {
- releaseStatement();
- throw SSqlException(errorMessage);
- }
+private:
+ void testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string& message)
+ {
+ std::string errorMessage;
+ if (!realTestResult(result, type, handle, message, errorMessage)) {
+ releaseStatement();
+ throw SSqlException(errorMessage);
+ }
}
- void releaseStatement() {
+ void releaseStatement()
+ {
reset();
if (d_statement != NULL)
SQLFreeHandle(SQL_HANDLE_STMT, d_statement);
d_prepared = false;
}
- void prepareStatement() {
- if (d_prepared) return;
+ void prepareStatement()
+ {
+ if (d_prepared)
+ return;
SQLRETURN result;
// Allocate statement handle.
- result = SQLAllocHandle( SQL_HANDLE_STMT, d_conn, &d_statement );
- testResult( result, SQL_HANDLE_DBC, d_conn, "Could not allocate a statement handle." );
+ result = SQLAllocHandle(SQL_HANDLE_STMT, d_conn, &d_statement);
+ testResult(result, SQL_HANDLE_DBC, d_conn, "Could not allocate a statement handle.");
- result = SQLPrepare(d_statement, (SQLCHAR *) d_query.c_str(), SQL_NTS);
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not prepare query." );
+ result = SQLPrepare(d_statement, (SQLCHAR*)d_query.c_str(), SQL_NTS);
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not prepare query.");
SQLSMALLINT paramcount;
result = SQLNumParams(d_statement, ¶mcount);
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not get parameter count." );
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not get parameter count.");
if (paramcount != static_cast<SQLSMALLINT>(d_parnum)) {
releaseStatement();
bool d_dolog;
bool d_prepared;
int d_residx;
- size_t d_paridx,d_parnum;
+ size_t d_paridx, d_parnum;
SQLRETURN d_result;
SQLHDBC d_conn;
- SQLHSTMT d_statement; //!< Database statement handle.
+ SQLHSTMT d_statement; //!< Database statement handle.
//! Column type.
struct column_t
{
- SQLSMALLINT m_type; //!< Type of the column.
- SQLULEN m_size; //!< Column size.
- SQLPOINTER m_pData; //!< Pointer to the memory where to store the data.
- bool m_canBeNull; //!< Can this column be null?
+ SQLSMALLINT m_type; //!< Type of the column.
+ SQLULEN m_size; //!< Column size.
+ SQLPOINTER m_pData; //!< Pointer to the memory where to store the data.
+ bool m_canBeNull; //!< Can this column be null?
};
//! Column info.
SQLSMALLINT m_columncount;
-
};
SSqlStatement* SODBCStatement::nextRow(row_t& row)
result = d_result;
// cerr<<"at start of nextRow, previous SQLFetch result is "<<result<<endl;
// FIXME handle errors (SQL_NO_DATA==100, anything other than the two SUCCESS options below is bad news)
- if ( result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO )
- {
+ if (result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO) {
// cerr<<"got row"<<endl;
// We've got a data row, now lets get the results.
- for ( int i = 0; i < m_columncount; i++ )
- {
+ for (int i = 0; i < m_columncount; i++) {
SQLLEN len;
- SQLCHAR coldata[128*1024];
+ SQLCHAR coldata[128 * 1024];
std::string strres = "";
- result = SQLGetData( d_statement, i + 1, SQL_C_CHAR, (SQLPOINTER) coldata, sizeof(coldata), &len);
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not get data." );
+ result = SQLGetData(d_statement, i + 1, SQL_C_CHAR, (SQLPOINTER)coldata, sizeof(coldata), &len);
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not get data.");
if (len > SQL_NULL_DATA)
- strres = std::string(reinterpret_cast<const char*>(coldata), std::min<SQLLEN>(sizeof(coldata)-1,len)); // do not use nil byte
+ strres = std::string(reinterpret_cast<const char*>(coldata), std::min<SQLLEN>(sizeof(coldata) - 1, len)); // do not use nil byte
row.push_back(strres);
}
// cerr<<"SQLFetch"<<endl;
d_result = SQLFetch(d_statement);
// cerr<<"subsequent SQLFetch done, d_result="<<d_result<<endl;
- if(d_result == SQL_NO_DATA) {
+ if (d_result == SQL_NO_DATA) {
SQLRETURN result2 = SQLMoreResults(d_statement);
// cerr<<"SQLMoreResults done, result="<<d_result2<<endl;
if (result2 == SQL_NO_DATA) {
d_result = result2;
}
else {
- testResult( result2, SQL_HANDLE_STMT, d_statement, "Could not fetch next result set for ("+d_query+").");
- d_result = SQLFetch(d_statement);
+ testResult(result2, SQL_HANDLE_STMT, d_statement, "Could not fetch next result set for (" + d_query + ").");
+ d_result = SQLFetch(d_statement);
}
}
- testResult( result, SQL_HANDLE_STMT, d_statement, "Could not do subsequent SQLFetch for ("+d_query+")." );
+ testResult(result, SQL_HANDLE_STMT, d_statement, "Could not do subsequent SQLFetch for (" + d_query + ").");
return this;
}
- SQLFreeStmt( d_statement, SQL_CLOSE );
- throw SSqlException( "Should not get here." );
+ SQLFreeStmt(d_statement, SQL_CLOSE);
+ throw SSqlException("Should not get here.");
return this;
}
// Constructor.
SODBC::SODBC(
- const std::string & dsn,
- const std::string & username,
- const std::string & password
- )
+ const std::string& dsn,
+ const std::string& username,
+ const std::string& password)
{
- SQLRETURN result;
+ SQLRETURN result;
// Allocate an environment handle.
- result = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_environment );
- testResult( result, SQL_NULL_HANDLE, NULL, "Could not allocate an environment handle." );
+ result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_environment);
+ testResult(result, SQL_NULL_HANDLE, NULL, "Could not allocate an environment handle.");
// Set ODBC version. (IEUW!)
- result = SQLSetEnvAttr( m_environment, SQL_ATTR_ODBC_VERSION, reinterpret_cast< void * >( SQL_OV_ODBC3 ), 0 );
- testResult( result, SQL_HANDLE_ENV, m_environment, "Could not set the ODBC version." );
+ result = SQLSetEnvAttr(m_environment, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+ testResult(result, SQL_HANDLE_ENV, m_environment, "Could not set the ODBC version.");
// Allocate connection handle.
- result = SQLAllocHandle( SQL_HANDLE_DBC, m_environment, &m_connection );
- testResult( result, SQL_HANDLE_ENV, m_environment, "Could not allocate a connection handle." );
+ result = SQLAllocHandle(SQL_HANDLE_DBC, m_environment, &m_connection);
+ testResult(result, SQL_HANDLE_ENV, m_environment, "Could not allocate a connection handle.");
// Connect to the database.
- char *l_dsn = strdup( dsn.c_str());
- char *l_username = strdup( username.c_str());
- char *l_password = strdup( password.c_str());
-
- result = SQLConnect( m_connection,
- reinterpret_cast< SQLTCHAR * >( l_dsn ), dsn.length(),
- reinterpret_cast< SQLTCHAR * >( l_username ), username.length(),
- reinterpret_cast< SQLTCHAR * >( l_password ), password.length());
+ char* l_dsn = strdup(dsn.c_str());
+ char* l_username = strdup(username.c_str());
+ char* l_password = strdup(password.c_str());
- free( l_dsn );
- free( l_username );
- free( l_password );
+ result = SQLConnect(m_connection,
+ reinterpret_cast<SQLTCHAR*>(l_dsn), dsn.length(),
+ reinterpret_cast<SQLTCHAR*>(l_username), username.length(),
+ reinterpret_cast<SQLTCHAR*>(l_password), password.length());
- testResult( result, SQL_HANDLE_DBC, m_connection, "Could not connect to ODBC datasource." );
+ free(l_dsn);
+ free(l_username);
+ free(l_password);
+ testResult(result, SQL_HANDLE_DBC, m_connection, "Could not connect to ODBC datasource.");
- m_busy = false;
- m_log = false;
+ m_busy = false;
+ m_log = false;
}
-
// Destructor.
-SODBC::~SODBC( void )
+SODBC::~SODBC(void)
{
// Disconnect from database and free all used resources.
// SQLFreeHandle( SQL_HANDLE_STMT, m_statement );
- SQLDisconnect( m_connection );
+ SQLDisconnect(m_connection);
- SQLFreeHandle( SQL_HANDLE_DBC, m_connection );
- SQLFreeHandle( SQL_HANDLE_ENV, m_environment );
+ SQLFreeHandle(SQL_HANDLE_DBC, m_connection);
+ SQLFreeHandle(SQL_HANDLE_ENV, m_environment);
// Free all allocated column memory.
// for ( int i = 0; i < m_columnInfo.size(); i++ )
}
// Executes a command.
-void SODBC::execute( const std::string & command )
+void SODBC::execute(const std::string& command)
{
SODBCStatement stmt(command, m_log, 0, m_connection);
}
// Sets the log state.
-void SODBC::setLog( bool state )
+void SODBC::setLog(bool state)
{
m_log = state;
}
// Returns an exception.
-SSqlException SODBC::sPerrorException( const std::string & reason )
+SSqlException SODBC::sPerrorException(const std::string& reason)
{
- return SSqlException( reason );
+ return SSqlException(reason);
}
std::unique_ptr<SSqlStatement> SODBC::prepare(const string& query, int nparams)
return std::unique_ptr<SSqlStatement>(new SODBCStatement(query, m_log, nparams, m_connection));
}
-
-void SODBC::startTransaction() {
+void SODBC::startTransaction()
+{
// cerr<<"starting transaction"<<endl;
SQLRETURN result;
result = SQLSetConnectAttr(m_connection, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
- testResult( result, SQL_HANDLE_DBC, m_connection, "startTransaction (enable autocommit) failed" );
+ testResult(result, SQL_HANDLE_DBC, m_connection, "startTransaction (enable autocommit) failed");
}
-void SODBC::commit() {
+void SODBC::commit()
+{
// cerr<<"commit!"<<endl;
SQLRETURN result;
result = SQLEndTran(SQL_HANDLE_DBC, m_connection, SQL_COMMIT); // don't really need this, AUTOCOMMIT_OFF below will also commit
- testResult( result, SQL_HANDLE_DBC, m_connection, "commit failed" );
+ testResult(result, SQL_HANDLE_DBC, m_connection, "commit failed");
result = SQLSetConnectAttr(m_connection, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
- testResult( result, SQL_HANDLE_DBC, m_connection, "disabling autocommit after commit failed" );
+ testResult(result, SQL_HANDLE_DBC, m_connection, "disabling autocommit after commit failed");
}
-void SODBC::rollback() {
+void SODBC::rollback()
+{
// cerr<<"rollback!"<<endl;
SQLRETURN result;
result = SQLEndTran(SQL_HANDLE_DBC, m_connection, SQL_ROLLBACK);
- testResult( result, SQL_HANDLE_DBC, m_connection, "rollback failed" );
+ testResult(result, SQL_HANDLE_DBC, m_connection, "rollback failed");
result = SQLSetConnectAttr(m_connection, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
- testResult( result, SQL_HANDLE_DBC, m_connection, "disabling autocommit after rollback failed" );
+ testResult(result, SQL_HANDLE_DBC, m_connection, "disabling autocommit after rollback failed");
}
-void SODBC::testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string & message) {
+void SODBC::testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string& message)
+{
std::string errorMessage;
- if (!realTestResult(result, type, handle, message, errorMessage)) throw SSqlException(errorMessage);
+ if (!realTestResult(result, type, handle, message, errorMessage))
+ throw SSqlException(errorMessage);
}
class SODBC : public SSql
{
private:
+ bool m_log; //!< Should we log?
+ bool m_busy; //!< Are we busy executing a query?
+ SQLHDBC m_connection; //!< Database connection handle.
+ SQLHENV m_environment; //!< Database environment handle
- bool m_log; //!< Should we log?
- bool m_busy; //!< Are we busy executing a query?
-
- SQLHDBC m_connection; //!< Database connection handle.
- SQLHENV m_environment; //!< Database environment handle
-
- void testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string & message);
+ void testResult(SQLRETURN result, SQLSMALLINT type, SQLHANDLE handle, const std::string& message);
public:
//! Default constructor.
\param password Password to use.
*/
SODBC(
- const std::string & dsn,
- const std::string & username,
- const std::string & password
- );
+ const std::string& dsn,
+ const std::string& username,
+ const std::string& password);
//! Destructor.
- virtual ~SODBC( void );
+ virtual ~SODBC(void);
//! Sets the logging state.
- void setLog( bool state ) override;
+ void setLog(bool state) override;
std::unique_ptr<SSqlStatement> prepare(const string& query, int nparams) override;
void execute(const string& query) override;
void commit() override;
//! Returns an exception.
- SSqlException sPerrorException( const std::string & reason ) override;
-
+ SSqlException sPerrorException(const std::string& reason) override;
};
#include <sys/time.h>
#include <sstream>
-gPgSQLBackend::gPgSQLBackend(const string &mode, const string &suffix) : GSQLBackend(mode,suffix)
+gPgSQLBackend::gPgSQLBackend(const string& mode, const string& suffix) :
+ GSQLBackend(mode, suffix)
{
try {
setDB(new SPgSQL(getArg("dbname"),
- getArg("host"),
- getArg("port"),
- getArg("user"),
- getArg("password"),
- getArg("extra-connection-parameters"),
- mustDo("prepared-statements")));
+ getArg("host"),
+ getArg("port"),
+ getArg("user"),
+ getArg("password"),
+ getArg("extra-connection-parameters"),
+ mustDo("prepared-statements")));
}
- catch(SSqlException &e) {
- g_log<<Logger::Error<<mode<<" Connection failed: "<<e.txtReason()<<endl;
- throw PDNSException("Unable to launch "+mode+" connection: "+e.txtReason());
+ catch (SSqlException& e) {
+ g_log << Logger::Error << mode << " Connection failed: " << e.txtReason() << endl;
+ throw PDNSException("Unable to launch " + mode + " connection: " + e.txtReason());
}
allocateStatements();
- g_log<<Logger::Info<<mode<<" Connection successful. Connected to database '"<<getArg("dbname")<<"' on '"<<getArg("host")<<"'."<<endl;
+ g_log << Logger::Info << mode << " Connection successful. Connected to database '" << getArg("dbname") << "' on '" << getArg("host") << "'." << endl;
}
void gPgSQLBackend::reconnect()
class gPgSQLFactory : public BackendFactory
{
public:
- gPgSQLFactory(const string &mode) : BackendFactory(mode),d_mode(mode) {}
+ gPgSQLFactory(const string& mode) :
+ BackendFactory(mode), d_mode(mode) {}
- void declareArguments(const string &suffix="") override
+ void declareArguments(const string& suffix = "") override
{
- declare(suffix,"dbname","Backend database name to connect to","");
- declare(suffix,"user","Database backend user to connect as","");
- declare(suffix,"host","Database backend host to connect to","");
- declare(suffix,"port","Database backend port to connect to","");
- declare(suffix,"password","Database backend password to connect with","");
- declare(suffix,"extra-connection-parameters", "Extra parameters to add to connection string","");
- declare(suffix,"prepared-statements", "Use prepared statements instead of parameterized queries", "yes");
+ declare(suffix, "dbname", "Backend database name to connect to", "");
+ declare(suffix, "user", "Database backend user to connect as", "");
+ declare(suffix, "host", "Database backend host to connect to", "");
+ declare(suffix, "port", "Database backend port to connect to", "");
+ declare(suffix, "password", "Database backend password to connect with", "");
+ declare(suffix, "extra-connection-parameters", "Extra parameters to add to connection string", "");
+ declare(suffix, "prepared-statements", "Use prepared statements instead of parameterized queries", "yes");
- declare(suffix,"dnssec","Enable DNSSEC processing","no");
+ declare(suffix, "dnssec", "Enable DNSSEC processing", "no");
string record_query = "SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int FROM records WHERE";
- declare(suffix, "basic-query", "Basic query", record_query+" disabled=false and type=$1 and name=$2");
- declare(suffix, "id-query", "Basic with ID query", record_query+" disabled=false and type=$1 and name=$2 and domain_id=$3");
- declare(suffix, "any-query", "Any query", record_query+" disabled=false and name=$1");
- declare(suffix, "any-id-query", "Any with ID query", record_query+" disabled=false and name=$1 and domain_id=$2");
+ declare(suffix, "basic-query", "Basic query", record_query + " disabled=false and type=$1 and name=$2");
+ declare(suffix, "id-query", "Basic with ID query", record_query + " disabled=false and type=$1 and name=$2 and domain_id=$3");
+ declare(suffix, "any-query", "Any query", record_query + " disabled=false and name=$1");
+ declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=false and name=$1 and domain_id=$2");
- declare(suffix, "list-query", "AXFR query", record_query+" (disabled=false OR $1) and domain_id=$2 order by name, type");
- declare(suffix, "list-subzone-query", "Subzone listing", record_query+" disabled=false and (name=$1 OR name like $2) and domain_id=$3");
+ declare(suffix, "list-query", "AXFR query", record_query + " (disabled=false OR $1) and domain_id=$2 order by name, type");
+ declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=false and (name=$1 OR name like $2) and domain_id=$3");
- declare(suffix,"remove-empty-non-terminals-from-zone-query", "remove all empty non-terminals from zone", "delete from records where domain_id=$1 and type is null");
- declare(suffix,"delete-empty-non-terminal-query", "delete empty non-terminal from zone", "delete from records where domain_id=$1 and name=$2 and type is null");
+ declare(suffix, "remove-empty-non-terminals-from-zone-query", "remove all empty non-terminals from zone", "delete from records where domain_id=$1 and type is null");
+ declare(suffix, "delete-empty-non-terminal-query", "delete empty non-terminal from zone", "delete from records where domain_id=$1 and name=$2 and type is null");
- declare(suffix,"info-zone-query","","select id,name,master,last_check,notified_serial,type,account from domains where name=$1");
+ declare(suffix, "info-zone-query", "", "select id,name,master,last_check,notified_serial,type,account from domains where name=$1");
- declare(suffix,"info-all-slaves-query","","select id,name,master,last_check from domains where type='SLAVE'");
- declare(suffix,"supermaster-query","", "select account from supermasters where ip=$1 and nameserver=$2");
- declare(suffix,"supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=$1 and account=$2");
- declare(suffix,"supermaster-add","", "insert into supermasters (ip, nameserver, account) values ($1,$2,$3)");
+ declare(suffix, "info-all-slaves-query", "", "select id,name,master,last_check from domains where type='SLAVE'");
+ declare(suffix, "supermaster-query", "", "select account from supermasters where ip=$1 and nameserver=$2");
+ declare(suffix, "supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=$1 and account=$2");
+ declare(suffix, "supermaster-add", "", "insert into supermasters (ip, nameserver, account) values ($1,$2,$3)");
- declare(suffix,"insert-zone-query","", "insert into domains (type,name,master,account,last_check, notified_serial) values($1,$2,$3,$4,null,null)");
+ declare(suffix, "insert-zone-query", "", "insert into domains (type,name,master,account,last_check, notified_serial) values($1,$2,$3,$4,null,null)");
declare(suffix, "insert-record-query", "", "insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)");
declare(suffix, "insert-empty-non-terminal-order-query", "insert empty non-terminal in zone", "insert into records (type,domain_id,disabled,name,ordername,auth,ttl,prio,content) values (null,$1,false,$2,$3,$4,null,null,null)");
declare(suffix, "nullify-ordername-and-update-auth-query", "DNSSEC nullify ordername and update auth for a qname query", "update records set ordername=NULL,auth=$1 where domain_id=$2 and name=$3 and disabled=false");
declare(suffix, "nullify-ordername-and-update-auth-type-query", "DNSSEC nullify ordername and update auth for a rrset query", "update records set ordername=NULL,auth=$1 where domain_id=$2 and name=$3 and type=$4 and disabled=false");
- declare(suffix,"update-master-query","", "update domains set master=$1 where name=$2");
- declare(suffix,"update-kind-query","", "update domains set type=$1 where name=$2");
- declare(suffix,"update-account-query","", "update domains set account=$1 where name=$2");
- declare(suffix,"update-serial-query","", "update domains set notified_serial=$1 where id=$2");
- declare(suffix,"update-lastcheck-query","", "update domains set last_check=$1 where id=$2");
- declare(suffix,"info-all-master-query","", "select domains.id, domains.name, domains.notified_serial, records.content from records join domains on records.name=domains.name where records.type='SOA' and records.disabled=false and domains.type='MASTER'");
- declare(suffix,"delete-domain-query","", "delete from domains where name=$1");
- declare(suffix,"delete-zone-query","", "delete from records where domain_id=$1");
- declare(suffix,"delete-rrset-query","","delete from records where domain_id=$1 and name=$2 and type=$3");
- declare(suffix,"delete-names-query","","delete from records where domain_id=$1 and name=$2");
-
- declare(suffix,"add-domain-key-query","", "insert into cryptokeys (domain_id, flags, active, published, content) select id, $1, $2, $3, $4 from domains where name=$5");
- declare(suffix,"get-last-inserted-key-id-query","", "select lastval()");
- declare(suffix,"list-domain-keys-query","", "select cryptokeys.id, flags, case when active then 1 else 0 end as active, case when published then 1 else 0 end as published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=$1");
- declare(suffix,"get-all-domain-metadata-query","", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1");
- declare(suffix,"get-domain-metadata-query","", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1 and domainmetadata.kind=$2");
- declare(suffix,"clear-domain-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=$1) and domainmetadata.kind=$2");
- declare(suffix,"clear-domain-all-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=$1)");
- declare(suffix,"set-domain-metadata-query","", "insert into domainmetadata (domain_id, kind, content) select id, $1, $2 from domains where name=$3");
- declare(suffix,"activate-domain-key-query","", "update cryptokeys set active=true where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
- declare(suffix,"deactivate-domain-key-query","", "update cryptokeys set active=false where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
- declare(suffix,"publish-domain-key-query","", "update cryptokeys set published=true where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
- declare(suffix,"unpublish-domain-key-query","", "update cryptokeys set published=false where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
- declare(suffix,"remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
- declare(suffix,"clear-domain-all-keys-query","", "delete from cryptokeys where domain_id=(select id from domains where name=$1)");
- declare(suffix,"get-tsig-key-query","", "select algorithm, secret from tsigkeys where name=$1");
- declare(suffix,"set-tsig-key-query","", "insert into tsigkeys (name,algorithm,secret) values($1,$2,$3)");
- declare(suffix,"delete-tsig-key-query","", "delete from tsigkeys where name=$1");
- declare(suffix,"get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys");
+ declare(suffix, "update-master-query", "", "update domains set master=$1 where name=$2");
+ declare(suffix, "update-kind-query", "", "update domains set type=$1 where name=$2");
+ declare(suffix, "update-account-query", "", "update domains set account=$1 where name=$2");
+ declare(suffix, "update-serial-query", "", "update domains set notified_serial=$1 where id=$2");
+ declare(suffix, "update-lastcheck-query", "", "update domains set last_check=$1 where id=$2");
+ declare(suffix, "info-all-master-query", "", "select domains.id, domains.name, domains.notified_serial, records.content from records join domains on records.name=domains.name where records.type='SOA' and records.disabled=false and domains.type='MASTER'");
+ declare(suffix, "delete-domain-query", "", "delete from domains where name=$1");
+ declare(suffix, "delete-zone-query", "", "delete from records where domain_id=$1");
+ declare(suffix, "delete-rrset-query", "", "delete from records where domain_id=$1 and name=$2 and type=$3");
+ declare(suffix, "delete-names-query", "", "delete from records where domain_id=$1 and name=$2");
+
+ declare(suffix, "add-domain-key-query", "", "insert into cryptokeys (domain_id, flags, active, published, content) select id, $1, $2, $3, $4 from domains where name=$5");
+ declare(suffix, "get-last-inserted-key-id-query", "", "select lastval()");
+ declare(suffix, "list-domain-keys-query", "", "select cryptokeys.id, flags, case when active then 1 else 0 end as active, case when published then 1 else 0 end as published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=$1");
+ declare(suffix, "get-all-domain-metadata-query", "", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1");
+ declare(suffix, "get-domain-metadata-query", "", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1 and domainmetadata.kind=$2");
+ declare(suffix, "clear-domain-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=$1) and domainmetadata.kind=$2");
+ declare(suffix, "clear-domain-all-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=$1)");
+ declare(suffix, "set-domain-metadata-query", "", "insert into domainmetadata (domain_id, kind, content) select id, $1, $2 from domains where name=$3");
+ declare(suffix, "activate-domain-key-query", "", "update cryptokeys set active=true where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
+ declare(suffix, "deactivate-domain-key-query", "", "update cryptokeys set active=false where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
+ declare(suffix, "publish-domain-key-query", "", "update cryptokeys set published=true where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
+ declare(suffix, "unpublish-domain-key-query", "", "update cryptokeys set published=false where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
+ declare(suffix, "remove-domain-key-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=$1) and cryptokeys.id=$2");
+ declare(suffix, "clear-domain-all-keys-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=$1)");
+ declare(suffix, "get-tsig-key-query", "", "select algorithm, secret from tsigkeys where name=$1");
+ declare(suffix, "set-tsig-key-query", "", "insert into tsigkeys (name,algorithm,secret) values($1,$2,$3)");
+ declare(suffix, "delete-tsig-key-query", "", "delete from tsigkeys where name=$1");
+ declare(suffix, "get-tsig-keys-query", "", "select name,algorithm, secret from tsigkeys");
declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=false OR $1");
declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES ($1, $2, $3, $4, $5, $6)");
declare(suffix, "delete-comment-rrset-query", "", "DELETE FROM comments WHERE domain_id=$1 AND name=$2 AND type=$3");
declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=$1");
- declare(suffix, "search-records-query", "", record_query+" name ILIKE $1 OR content ILIKE $2 LIMIT $3");
+ declare(suffix, "search-records-query", "", record_query + " name ILIKE $1 OR content ILIKE $2 LIMIT $3");
declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name ILIKE $1 OR comment ILIKE $2 LIMIT $3");
-
}
- DNSBackend *make(const string &suffix="") override
+ DNSBackend* make(const string& suffix = "") override
{
- return new gPgSQLBackend(d_mode,suffix);
+ return new gPgSQLBackend(d_mode, suffix);
}
+
private:
const string d_mode;
};
-
//! Magic class that is activated when the dynamic library is loaded
class gPgSQLLoader
{
BackendMakers().report(new gPgSQLFactory("gpgsql"));
g_log << Logger::Info << "[gpgsqlbackend] This is the gpgsql backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
static gPgSQLLoader gpgsqlloader;
class gPgSQLBackend : public GSQLBackend
{
public:
- gPgSQLBackend(const string &mode, const string &suffix); //!< Makes our connection to the database. Throws an exception if it fails.
+ gPgSQLBackend(const string& mode, const string& suffix); //!< Makes our connection to the database. Throws an exception if it fails.
protected:
void reconnect() override;
bool inTransaction() override;
#include "pdns/namespaces.hh"
#include <algorithm>
-class SPgSQLStatement: public SSqlStatement
+class SPgSQLStatement : public SSqlStatement
{
public:
- SPgSQLStatement(const string& query, bool dolog, int nparams, SPgSQL* db, unsigned int nstatement) {
+ SPgSQLStatement(const string& query, bool dolog, int nparams, SPgSQL* db, unsigned int nstatement)
+ {
d_query = query;
d_dolog = dolog;
d_parent = db;
SSqlStatement* bind(const string& name, unsigned long value) { return bind(name, std::to_string(value)); }
SSqlStatement* bind(const string& name, long long value) { return bind(name, std::to_string(value)); }
SSqlStatement* bind(const string& name, unsigned long long value) { return bind(name, std::to_string(value)); }
- SSqlStatement* bind(const string& name, const std::string& value) {
+ SSqlStatement* bind(const string& name, const std::string& value)
+ {
prepareStatement();
allocate();
- if (d_paridx>=d_nparams) {
+ if (d_paridx >= d_nparams) {
releaseStatement();
throw SSqlException("Attempt to bind more parameters than query has: " + d_query);
}
- paramValues[d_paridx] = new char[value.size()+1];
- memset(paramValues[d_paridx], 0, sizeof(char)*(value.size()+1));
+ paramValues[d_paridx] = new char[value.size() + 1];
+ memset(paramValues[d_paridx], 0, sizeof(char) * (value.size() + 1));
value.copy(paramValues[d_paridx], value.size());
paramLengths[d_paridx] = value.size();
d_paridx++;
return this;
}
- SSqlStatement* bindNull(const string& name) { prepareStatement(); d_paridx++; return this; } // these are set null in allocate()
- SSqlStatement* execute() {
+ SSqlStatement* bindNull(const string& name)
+ {
+ prepareStatement();
+ d_paridx++;
+ return this;
+ } // these are set null in allocate()
+ SSqlStatement* execute()
+ {
prepareStatement();
if (d_dolog) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": Statement: " << d_query << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": Statement: " << d_query << endl;
if (d_paridx) {
// Log message is similar, but not exactly the same as the postgres server log.
std::stringstream log_message;
- log_message<< "Query "<<((long)(void*)this)<<": Parameters: ";
+ log_message << "Query " << ((long)(void*)this) << ": Parameters: ";
for (int i = 0; i < d_paridx; i++) {
if (i != 0) {
log_message << ", ";
}
log_message << "$" << (i + 1) << " = '" << paramValues[i] << "'";
}
- g_log<<Logger::Warning<< log_message.str() << endl;
+ g_log << Logger::Warning << log_message.str() << endl;
}
d_dtime.set();
}
if (!d_stmt.empty()) {
d_res_set = PQexecPrepared(d_db(), d_stmt.c_str(), d_nparams, paramValues, paramLengths, nullptr, 0);
- } else {
+ }
+ else {
d_res_set = PQexecParams(d_db(), d_query.c_str(), d_nparams, nullptr, paramValues, paramLengths, nullptr, 0);
}
ExecStatusType status = PQresultStatus(d_res_set);
throw SSqlException("Fatal error during query: " + d_query + string(": ") + errmsg);
}
d_cur_set = 0;
- if(d_dolog) {
+ if (d_dolog) {
auto diff = d_dtime.udiffNoReset();
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<< diff <<" usec to execute"<<endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << diff << " usec to execute" << endl;
}
nextResult();
return this;
}
- void nextResult() {
- if (d_res_set == nullptr) return; // no refcursor
+ void nextResult()
+ {
+ if (d_res_set == nullptr)
+ return; // no refcursor
if (d_cur_set >= PQntuples(d_res_set)) {
PQclear(d_res_set);
d_res_set = nullptr;
if (PQftype(d_res_set, 0) == 1790) { // REFCURSOR
#if PG_VERSION_NUM > 90000
// PQescapeIdentifier was added to libpq in postgresql 9.0
- char *val = PQgetvalue(d_res_set, d_cur_set++, 0);
- char *portal = PQescapeIdentifier(d_db(), val, strlen(val));
+ char* val = PQgetvalue(d_res_set, d_cur_set++, 0);
+ char* portal = PQescapeIdentifier(d_db(), val, strlen(val));
string cmd = string("FETCH ALL FROM \"") + string(portal) + string("\"");
PQfreemem(portal);
#else
#endif
// execute FETCH
if (d_dolog) {
- g_log<<Logger::Warning<<"Query: "<<cmd<<endl;
+ g_log << Logger::Warning << "Query: " << cmd << endl;
}
- d_res = PQexec(d_db(),cmd.c_str());
+ d_res = PQexec(d_db(), cmd.c_str());
d_resnum = PQntuples(d_res);
d_residx = 0;
- } else {
+ }
+ else {
d_res = d_res_set;
d_res_set = nullptr;
d_resnum = PQntuples(d_res);
bool hasNextRow()
{
- if(d_dolog && d_residx == d_resnum) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiff()<<" total usec to last row"<<endl;
+ if (d_dolog && d_residx == d_resnum) {
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiff() << " total usec to last row" << endl;
}
- return d_residx<d_resnum;
+ return d_residx < d_resnum;
}
- SSqlStatement* nextRow(row_t& row) {
+ SSqlStatement* nextRow(row_t& row)
+ {
int i;
row.clear();
- if (d_residx>=d_resnum || !d_res) return this;
+ if (d_residx >= d_resnum || !d_res)
+ return this;
row.reserve(PQnfields(d_res));
- for(i=0;i<PQnfields(d_res);i++) {
+ for (i = 0; i < PQnfields(d_res); i++) {
if (PQgetisnull(d_res, d_residx, i)) {
row.emplace_back("");
- } else if (PQftype(d_res, i) == 16) { // BOOLEAN
- char *val = PQgetvalue(d_res, d_residx, i);
+ }
+ else if (PQftype(d_res, i) == 16) { // BOOLEAN
+ char* val = PQgetvalue(d_res, d_residx, i);
row.emplace_back(val[0] == 't' ? "1" : "0");
- } else {
+ }
+ else {
row.emplace_back(PQgetvalue(d_res, d_residx, i));
}
}
return this;
}
- SSqlStatement* getResult(result_t& result) {
+ SSqlStatement* getResult(result_t& result)
+ {
result.clear();
- if (d_res == nullptr) return this;
+ if (d_res == nullptr)
+ return this;
result.reserve(d_resnum);
row_t row;
- while(hasNextRow()) { nextRow(row); result.push_back(std::move(row)); }
+ while (hasNextRow()) {
+ nextRow(row);
+ result.push_back(std::move(row));
+ }
return this;
}
- SSqlStatement* reset() {
- int i;
- if (d_res) {
- PQclear(d_res);
- }
- if (d_res_set) {
- PQclear(d_res_set);
- }
- d_res_set = nullptr;
- d_res = nullptr;
- d_paridx = d_residx = d_resnum = 0;
- if (paramValues) {
- for(i=0;i<d_nparams;i++) {
- if (paramValues[i]) {
- delete [] paramValues[i];
- }
- }
- }
- delete [] paramValues;
- paramValues = nullptr;
- delete [] paramLengths;
- paramLengths = nullptr;
- return this;
+ SSqlStatement* reset()
+ {
+ int i;
+ if (d_res) {
+ PQclear(d_res);
+ }
+ if (d_res_set) {
+ PQclear(d_res_set);
+ }
+ d_res_set = nullptr;
+ d_res = nullptr;
+ d_paridx = d_residx = d_resnum = 0;
+ if (paramValues) {
+ for (i = 0; i < d_nparams; i++) {
+ if (paramValues[i]) {
+ delete[] paramValues[i];
+ }
+ }
+ }
+ delete[] paramValues;
+ paramValues = nullptr;
+ delete[] paramLengths;
+ paramLengths = nullptr;
+ return this;
}
const std::string& getQuery() { return d_query; }
- ~SPgSQLStatement() {
+ ~SPgSQLStatement()
+ {
releaseStatement();
}
+
private:
- PGconn* d_db() {
+ PGconn* d_db()
+ {
return d_parent->db();
}
- void releaseStatement() {
+ void releaseStatement()
+ {
d_prepared = false;
reset();
if (!d_stmt.empty()) {
string cmd = string("DEALLOCATE " + d_stmt);
- PGresult *res = PQexec(d_db(), cmd.c_str());
+ PGresult* res = PQexec(d_db(), cmd.c_str());
PQclear(res);
d_stmt.clear();
}
}
- void prepareStatement() {
- if (d_prepared) return;
+ void prepareStatement()
+ {
+ if (d_prepared)
+ return;
if (d_parent->usePrepared()) {
// prepare a statement; name must be unique per session (using d_nstatement to ensure this).
this->d_stmt = string("stmt") + std::to_string(d_nstatement);
d_prepared = true;
}
- void allocate() {
- if (paramValues != nullptr) return;
- paramValues = new char*[d_nparams];
- paramLengths = new int[d_nparams];
- memset(paramValues, 0, sizeof(char*)*d_nparams);
- memset(paramLengths, 0, sizeof(int)*d_nparams);
+ void allocate()
+ {
+ if (paramValues != nullptr)
+ return;
+ paramValues = new char*[d_nparams];
+ paramLengths = new int[d_nparams];
+ memset(paramValues, 0, sizeof(char*) * d_nparams);
+ memset(paramLengths, 0, sizeof(int) * d_nparams);
}
string d_query;
string d_stmt;
- SPgSQL *d_parent;
- PGresult *d_res_set{nullptr};
- PGresult *d_res{nullptr};
+ SPgSQL* d_parent;
+ PGresult* d_res_set{nullptr};
+ PGresult* d_res{nullptr};
bool d_dolog;
DTime d_dtime; // only used if d_dolog is set
bool d_prepared{false};
int d_nparams;
int d_paridx{0};
- char **paramValues{nullptr};
- int *paramLengths{nullptr};
+ char** paramValues{nullptr};
+ int* paramLengths{nullptr};
int d_residx{0};
int d_resnum{0};
int d_cur_set{0};
bool SPgSQL::s_dolog;
-static string escapeForPQparam(const string &v)
+static string escapeForPQparam(const string& v)
{
string ret = v;
boost::replace_all(ret, "\\", "\\\\");
boost::replace_all(ret, "'", "\\'");
- return string("'")+ret+string("'");
+ return string("'") + ret + string("'");
}
-SPgSQL::SPgSQL(const string &database, const string &host, const string& port, const string &user,
- const string &password, const string &extra_connection_parameters, const bool use_prepared)
+SPgSQL::SPgSQL(const string& database, const string& host, const string& port, const string& user,
+ const string& password, const string& extra_connection_parameters, const bool use_prepared)
{
d_db = nullptr;
d_in_trx = false;
d_nstatements = 0;
if (!database.empty())
- d_connectstr+="dbname="+escapeForPQparam(database);
+ d_connectstr += "dbname=" + escapeForPQparam(database);
if (!user.empty())
- d_connectstr+=" user="+escapeForPQparam(user);
+ d_connectstr += " user=" + escapeForPQparam(user);
- if(!host.empty())
- d_connectstr+=" host="+escapeForPQparam(host);
+ if (!host.empty())
+ d_connectstr += " host=" + escapeForPQparam(host);
- if(!port.empty())
- d_connectstr+=" port="+escapeForPQparam(port);
+ if (!port.empty())
+ d_connectstr += " port=" + escapeForPQparam(port);
- if(!extra_connection_parameters.empty())
- d_connectstr+=" " + extra_connection_parameters;
+ if (!extra_connection_parameters.empty())
+ d_connectstr += " " + extra_connection_parameters;
- d_connectlogstr=d_connectstr;
+ d_connectlogstr = d_connectstr;
- if(!password.empty()) {
- d_connectlogstr+=" password=<HIDDEN>";
- d_connectstr+=" password="+escapeForPQparam(password);
+ if (!password.empty()) {
+ d_connectlogstr += " password=<HIDDEN>";
+ d_connectstr += " password=" + escapeForPQparam(password);
}
d_use_prepared = use_prepared;
- d_db=PQconnectdb(d_connectstr.c_str());
+ d_db = PQconnectdb(d_connectstr.c_str());
- if (!d_db || PQstatus(d_db)==CONNECTION_BAD) {
+ if (!d_db || PQstatus(d_db) == CONNECTION_BAD) {
try {
- throw sPerrorException("Unable to connect to database, connect string: "+d_connectlogstr);
+ throw sPerrorException("Unable to connect to database, connect string: " + d_connectlogstr);
}
- catch(...) {
- if(d_db)
+ catch (...) {
+ if (d_db)
PQfinish(d_db);
d_db = 0;
throw;
void SPgSQL::setLog(bool state)
{
- s_dolog=state;
+ s_dolog = state;
}
SPgSQL::~SPgSQL()
PQfinish(d_db);
}
-SSqlException SPgSQL::sPerrorException(const string &reason)
+SSqlException SPgSQL::sPerrorException(const string& reason)
{
- return SSqlException(reason+string(": ")+(d_db ? PQerrorMessage(d_db) : "no connection"));
+ return SSqlException(reason + string(": ") + (d_db ? PQerrorMessage(d_db) : "no connection"));
}
void SPgSQL::execute(const string& query)
return std::unique_ptr<SSqlStatement>(new SPgSQLStatement(query, s_dolog, nparams, this, d_nstatements));
}
-void SPgSQL::startTransaction() {
+void SPgSQL::startTransaction()
+{
execute("begin");
d_in_trx = true;
}
-void SPgSQL::commit() {
+void SPgSQL::commit()
+{
execute("commit");
d_in_trx = false;
}
-void SPgSQL::rollback() {
+void SPgSQL::rollback()
+{
execute("rollback");
d_in_trx = false;
}
class SPgSQL : public SSql
{
public:
- SPgSQL(const string &database, const string &host="", const string& port="",
- const string &user="", const string &password="",
- const string &extra_connection_parameters="", const bool use_prepared = true);
+ SPgSQL(const string& database, const string& host = "", const string& port = "",
+ const string& user = "", const string& password = "",
+ const string& extra_connection_parameters = "", const bool use_prepared = true);
~SPgSQL();
-
- SSqlException sPerrorException(const string &reason) override;
+
+ SSqlException sPerrorException(const string& reason) override;
void setLog(bool state) override;
unique_ptr<SSqlStatement> prepare(const string& query, int nparams) override;
void execute(const string& query) override;
#include <boost/algorithm/string.hpp>
// Connects to the database.
-gSQLite3Backend::gSQLite3Backend( const std::string & mode, const std::string & suffix ) : GSQLBackend( mode, suffix )
+gSQLite3Backend::gSQLite3Backend(const std::string& mode, const std::string& suffix) :
+ GSQLBackend(mode, suffix)
{
- try
- {
- SSQLite3 *ptr = new SSQLite3( getArg( "database" ), getArg( "pragma-journal-mode") );
+ try {
+ SSQLite3* ptr = new SSQLite3(getArg("database"), getArg("pragma-journal-mode"));
setDB(ptr);
allocateStatements();
- if(!getArg("pragma-synchronous").empty()) {
- ptr->execute("PRAGMA synchronous="+getArg("pragma-synchronous"));
+ if (!getArg("pragma-synchronous").empty()) {
+ ptr->execute("PRAGMA synchronous=" + getArg("pragma-synchronous"));
}
if (mustDo("pragma-foreign-keys")) {
ptr->execute("PRAGMA foreign_keys = 1");
}
- }
- catch( SSqlException & e )
- {
+ }
+ catch (SSqlException& e) {
g_log << Logger::Error << mode << ": connection failed: " << e.txtReason() << std::endl;
- throw PDNSException( "Unable to launch " + mode + " connection: " + e.txtReason());
+ throw PDNSException("Unable to launch " + mode + " connection: " + e.txtReason());
}
- g_log << Logger::Info << mode << ": connection to '"<<getArg("database")<<"' successful" << std::endl;
+ g_log << Logger::Info << mode << ": connection to '" << getArg("database") << "' successful" << std::endl;
}
-
//! Constructs a gSQLite3Backend
class gSQLite3Factory : public BackendFactory
{
public:
//! Constructor.
- gSQLite3Factory( const std::string & mode ) : BackendFactory( mode ), d_mode( mode )
+ gSQLite3Factory(const std::string& mode) :
+ BackendFactory(mode), d_mode(mode)
{
}
-
+
//! Declares all needed arguments.
- void declareArguments( const std::string & suffix = "" ) override
+ void declareArguments(const std::string& suffix = "") override
{
declare(suffix, "database", "Filename of the SQLite3 database", "powerdns.sqlite");
declare(suffix, "pragma-synchronous", "Set this to 0 for blazing speed", "");
- declare(suffix, "pragma-foreign-keys", "Enable foreign key constraints", "no" );
+ declare(suffix, "pragma-foreign-keys", "Enable foreign key constraints", "no");
declare(suffix, "pragma-journal-mode", "SQLite3 journal mode", "WAL");
- declare(suffix, "dnssec", "Enable DNSSEC processing","no");
+ declare(suffix, "dnssec", "Enable DNSSEC processing", "no");
string record_query = "SELECT content,ttl,prio,type,domain_id,disabled,name,auth FROM records WHERE";
- declare(suffix, "basic-query", "Basic query", record_query+" disabled=0 and type=:qtype and name=:qname");
- declare(suffix, "id-query", "Basic with ID query", record_query+" disabled=0 and type=:qtype and name=:qname and domain_id=:domain_id");
- declare(suffix, "any-query", "Any query", record_query+" disabled=0 and name=:qname");
- declare(suffix, "any-id-query", "Any with ID query", record_query+" disabled=0 and name=:qname and domain_id=:domain_id");
+ declare(suffix, "basic-query", "Basic query", record_query + " disabled=0 and type=:qtype and name=:qname");
+ declare(suffix, "id-query", "Basic with ID query", record_query + " disabled=0 and type=:qtype and name=:qname and domain_id=:domain_id");
+ declare(suffix, "any-query", "Any query", record_query + " disabled=0 and name=:qname");
+ declare(suffix, "any-id-query", "Any with ID query", record_query + " disabled=0 and name=:qname and domain_id=:domain_id");
- declare(suffix, "list-query", "AXFR query", record_query+" (disabled=0 OR :include_disabled) and domain_id=:domain_id order by name, type");
- declare(suffix, "list-subzone-query", "Subzone listing", record_query+" disabled=0 and (name=:zone OR name like :wildzone) and domain_id=:domain_id");
+ declare(suffix, "list-query", "AXFR query", record_query + " (disabled=0 OR :include_disabled) and domain_id=:domain_id order by name, type");
+ declare(suffix, "list-subzone-query", "Subzone listing", record_query + " disabled=0 and (name=:zone OR name like :wildzone) and domain_id=:domain_id");
declare(suffix, "remove-empty-non-terminals-from-zone-query", "remove all empty non-terminals from zone", "delete from records where domain_id=:domain_id and type is null");
declare(suffix, "delete-empty-non-terminal-query", "delete empty non-terminal from zone", "delete from records where domain_id=:domain_id and name=:qname and type is null");
- declare(suffix, "info-zone-query", "","select id,name,master,last_check,notified_serial,type,account from domains where name=:domain");
+ declare(suffix, "info-zone-query", "", "select id,name,master,last_check,notified_serial,type,account from domains where name=:domain");
- declare(suffix, "info-all-slaves-query", "","select id,name,master,last_check from domains where type='SLAVE'");
+ declare(suffix, "info-all-slaves-query", "", "select id,name,master,last_check from domains where type='SLAVE'");
declare(suffix, "supermaster-query", "", "select account from supermasters where ip=:ip and nameserver=:nameserver");
declare(suffix, "supermaster-name-to-ips", "", "select ip,account from supermasters where nameserver=:nameserver and account=:account");
- declare(suffix,"supermaster-add","", "insert into supermasters (ip, nameserver, account) values (:ip,:nameserver,:account)");
+ declare(suffix, "supermaster-add", "", "insert into supermasters (ip, nameserver, account) values (:ip,:nameserver,:account)");
declare(suffix, "insert-zone-query", "", "insert into domains (type,name,master,account,last_check,notified_serial) values(:type, :domain, :masters, :account, null, null)");
declare(suffix, "update-master-query", "", "update domains set master=:master where name=:domain");
declare(suffix, "update-kind-query", "", "update domains set type=:kind where name=:domain");
- declare(suffix, "update-account-query","", "update domains set account=:account where name=:domain");
+ declare(suffix, "update-account-query", "", "update domains set account=:account where name=:domain");
declare(suffix, "update-serial-query", "", "update domains set notified_serial=:serial where id=:domain_id");
declare(suffix, "update-lastcheck-query", "", "update domains set last_check=:last_check where id=:domain_id");
declare(suffix, "info-all-master-query", "", "select domains.id, domains.name, domains.notified_serial, records.content from records join domains on records.name=domains.name where records.type='SOA' and records.disabled=0 and domains.type='MASTER'");
- declare(suffix, "delete-domain-query","", "delete from domains where name=:domain");
+ declare(suffix, "delete-domain-query", "", "delete from domains where name=:domain");
declare(suffix, "delete-zone-query", "", "delete from records where domain_id=:domain_id");
declare(suffix, "delete-rrset-query", "", "delete from records where domain_id=:domain_id and name=:qname and type=:qtype");
declare(suffix, "delete-names-query", "", "delete from records where domain_id=:domain_id and name=:qname");
- declare(suffix, "add-domain-key-query","", "insert into cryptokeys (domain_id, flags, active, published, content) select id, :flags, :active, :published, :content from domains where name=:domain");
+ declare(suffix, "add-domain-key-query", "", "insert into cryptokeys (domain_id, flags, active, published, content) select id, :flags, :active, :published, :content from domains where name=:domain");
declare(suffix, "get-last-inserted-key-id-query", "", "select last_insert_rowid()");
- declare(suffix, "list-domain-keys-query","", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=:domain");
- declare(suffix, "get-all-domain-metadata-query","", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=:domain");
- declare(suffix, "get-domain-metadata-query","", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=:domain and domainmetadata.kind=:kind");
- declare(suffix, "clear-domain-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=:domain) and domainmetadata.kind=:kind");
- declare(suffix, "clear-domain-all-metadata-query","", "delete from domainmetadata where domain_id=(select id from domains where name=:domain)");
- declare(suffix, "set-domain-metadata-query","", "insert into domainmetadata (domain_id, kind, content) select id, :kind, :content from domains where name=:domain");
- declare(suffix, "activate-domain-key-query","", "update cryptokeys set active=1 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
- declare(suffix, "deactivate-domain-key-query","", "update cryptokeys set active=0 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
- declare(suffix, "publish-domain-key-query","", "update cryptokeys set published=1 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
- declare(suffix, "unpublish-domain-key-query","", "update cryptokeys set published=0 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
- declare(suffix, "remove-domain-key-query","", "delete from cryptokeys where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
- declare(suffix, "clear-domain-all-keys-query","", "delete from cryptokeys where domain_id=(select id from domains where name=:domain)");
- declare(suffix, "get-tsig-key-query","", "select algorithm, secret from tsigkeys where name=:key_name");
- declare(suffix, "set-tsig-key-query","", "replace into tsigkeys (name,algorithm,secret) values(:key_name,:algorithm,:content)");
- declare(suffix, "delete-tsig-key-query","", "delete from tsigkeys where name=:key_name");
- declare(suffix, "get-tsig-keys-query","", "select name,algorithm, secret from tsigkeys");
+ declare(suffix, "list-domain-keys-query", "", "select cryptokeys.id, flags, active, published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=:domain");
+ declare(suffix, "get-all-domain-metadata-query", "", "select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=:domain");
+ declare(suffix, "get-domain-metadata-query", "", "select content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=:domain and domainmetadata.kind=:kind");
+ declare(suffix, "clear-domain-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=:domain) and domainmetadata.kind=:kind");
+ declare(suffix, "clear-domain-all-metadata-query", "", "delete from domainmetadata where domain_id=(select id from domains where name=:domain)");
+ declare(suffix, "set-domain-metadata-query", "", "insert into domainmetadata (domain_id, kind, content) select id, :kind, :content from domains where name=:domain");
+ declare(suffix, "activate-domain-key-query", "", "update cryptokeys set active=1 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
+ declare(suffix, "deactivate-domain-key-query", "", "update cryptokeys set active=0 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
+ declare(suffix, "publish-domain-key-query", "", "update cryptokeys set published=1 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
+ declare(suffix, "unpublish-domain-key-query", "", "update cryptokeys set published=0 where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
+ declare(suffix, "remove-domain-key-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=:domain) and cryptokeys.id=:key_id");
+ declare(suffix, "clear-domain-all-keys-query", "", "delete from cryptokeys where domain_id=(select id from domains where name=:domain)");
+ declare(suffix, "get-tsig-key-query", "", "select algorithm, secret from tsigkeys where name=:key_name");
+ declare(suffix, "set-tsig-key-query", "", "replace into tsigkeys (name,algorithm,secret) values(:key_name,:algorithm,:content)");
+ declare(suffix, "delete-tsig-key-query", "", "delete from tsigkeys where name=:key_name");
+ declare(suffix, "get-tsig-keys-query", "", "select name,algorithm, secret from tsigkeys");
declare(suffix, "get-all-domains-query", "Retrieve all domains", "select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=0 OR :include_disabled");
declare(suffix, "insert-comment-query", "", "INSERT INTO comments (domain_id, name, type, modified_at, account, comment) VALUES (:domain_id, :qname, :qtype, :modified_at, :account, :content)");
declare(suffix, "delete-comment-rrset-query", "", "DELETE FROM comments WHERE domain_id=:domain_id AND name=:qname AND type=:qtype");
declare(suffix, "delete-comments-query", "", "DELETE FROM comments WHERE domain_id=:domain_id");
- declare(suffix, "search-records-query", "", record_query+" name LIKE :value ESCAPE '\\' OR content LIKE :value2 ESCAPE '\\' LIMIT :limit");
+ declare(suffix, "search-records-query", "", record_query + " name LIKE :value ESCAPE '\\' OR content LIKE :value2 ESCAPE '\\' LIMIT :limit");
declare(suffix, "search-comments-query", "", "SELECT domain_id,name,type,modified_at,account,comment FROM comments WHERE name LIKE :value ESCAPE '\\' OR comment LIKE :value2 ESCAPE '\\' LIMIT :limit");
}
//! Constructs a new gSQLite3Backend object.
- DNSBackend *make( const string & suffix = "" ) override
+ DNSBackend* make(const string& suffix = "") override
{
- return new gSQLite3Backend( d_mode, suffix );
+ return new gSQLite3Backend(d_mode, suffix);
}
private:
const string d_mode;
};
-
//! Magic class that is activated when the dynamic library is loaded
class gSQLite3Loader
{
//! This reports us to the main UeberBackend class
gSQLite3Loader()
{
- BackendMakers().report( new gSQLite3Factory( "gsqlite3" ));
+ BackendMakers().report(new gSQLite3Factory("gsqlite3"));
g_log << Logger::Info << "[gsqlite3] This is the gsqlite3 backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
//! Reports the backendloader to the UeberBackend.
static gSQLite3Loader gsqlite3loader;
-
{
public:
//! Constructs the backend, throws an exception if it failed..
- gSQLite3Backend( const std::string & mode, const std::string & suffix );
+ gSQLite3Backend(const std::string& mode, const std::string& suffix);
};
class LDAPException : public std::runtime_error
{
- public:
- explicit LDAPException( const std::string &str ) : std::runtime_error( str ) {}
+public:
+ explicit LDAPException(const std::string& str) :
+ std::runtime_error(str) {}
};
class LDAPTimeout : public LDAPException
{
- public:
- explicit LDAPTimeout() : LDAPException( "Timeout" ) {}
+public:
+ explicit LDAPTimeout() :
+ LDAPException("Timeout") {}
};
class LDAPNoConnection : public LDAPException
{
- public:
- explicit LDAPNoConnection() : LDAPException( "No connection to LDAP server" ) {}
+public:
+ explicit LDAPNoConnection() :
+ LDAPException("No connection to LDAP server") {}
};
class LDAPNoSuchObject : public LDAPException
{
- public:
- explicit LDAPNoSuchObject() : LDAPException( "No such object" ) {}
+public:
+ explicit LDAPNoSuchObject() :
+ LDAPException("No such object") {}
};
-
*
****************************/
-LdapSimpleAuthenticator::LdapSimpleAuthenticator( const std::string& dn, const std::string& pw, int tmout )
- : d_binddn( dn ), d_bindpw( pw ), d_timeout( tmout )
+LdapSimpleAuthenticator::LdapSimpleAuthenticator(const std::string& dn, const std::string& pw, int tmout) :
+ d_binddn(dn), d_bindpw(pw), d_timeout(tmout)
{
}
-bool LdapSimpleAuthenticator::authenticate( LDAP *conn )
+bool LdapSimpleAuthenticator::authenticate(LDAP* conn)
{
int msgid;
int rc;
struct berval passwd;
- passwd.bv_val = (char *)d_bindpw.c_str();
- passwd.bv_len = strlen( passwd.bv_val );
+ passwd.bv_val = (char*)d_bindpw.c_str();
+ passwd.bv_len = strlen(passwd.bv_val);
- if( ( rc = ldap_sasl_bind( conn, d_binddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid ) ) != LDAP_SUCCESS )
- {
- fillLastError( conn, rc );
+ if ((rc = ldap_sasl_bind(conn, d_binddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid)) != LDAP_SUCCESS) {
+ fillLastError(conn, rc);
return false;
}
#else
- if( ( msgid = ldap_bind( conn, d_binddn.c_str(), d_bindpw.c_str(), LDAP_AUTH_SIMPLE ) ) == -1 )
- {
- fillLastError( conn, msgid );
+ if ((msgid = ldap_bind(conn, d_binddn.c_str(), d_bindpw.c_str(), LDAP_AUTH_SIMPLE)) == -1) {
+ fillLastError(conn, msgid);
return false;
}
#endif
- ldapWaitResult( conn, msgid, d_timeout, NULL );
+ ldapWaitResult(conn, msgid, d_timeout, NULL);
return true;
}
return d_lastError;
}
-void LdapSimpleAuthenticator::fillLastError( LDAP* conn, int code )
+void LdapSimpleAuthenticator::fillLastError(LDAP* conn, int code)
{
- d_lastError = ldapGetError( conn, code );
+ d_lastError = ldapGetError(conn, code);
}
/*****************************
*
****************************/
-static int ldapGssapiAuthenticatorSaslInteractCallback( LDAP *conn, unsigned flags, void *defaults, void *in )
+static int ldapGssapiAuthenticatorSaslInteractCallback(LDAP* conn, unsigned flags, void* defaults, void* in)
{
return LDAP_SUCCESS;
}
-LdapGssapiAuthenticator::LdapGssapiAuthenticator( const std::string& kt, const std::string &ccache, int tmout )
- : d_logPrefix( "[LDAP GSSAPI] " ), d_keytabFile( kt ), d_cCacheFile( ccache )
+LdapGssapiAuthenticator::LdapGssapiAuthenticator(const std::string& kt, const std::string& ccache, int tmout) :
+ d_logPrefix("[LDAP GSSAPI] "), d_keytabFile(kt), d_cCacheFile(ccache)
{
krb5_error_code code;
- if ( ( code = krb5_init_context( &d_context ) ) != 0 )
- throw PDNSException( d_logPrefix + std::string( "Failed to initialize krb5 context" ) );
+ if ((code = krb5_init_context(&d_context)) != 0)
+ throw PDNSException(d_logPrefix + std::string("Failed to initialize krb5 context"));
// Locate the credentials cache file
- if ( !d_cCacheFile.empty() ) {
- std::string cCacheStr( "FILE:" + d_cCacheFile );
- code = krb5_cc_resolve( d_context, cCacheStr.c_str(), &d_ccache );
+ if (!d_cCacheFile.empty()) {
+ std::string cCacheStr("FILE:" + d_cCacheFile);
+ code = krb5_cc_resolve(d_context, cCacheStr.c_str(), &d_ccache);
}
else {
- code = krb5_cc_default( d_context, &d_ccache );
+ code = krb5_cc_default(d_context, &d_ccache);
}
- if ( code != 0 )
- throw PDNSException( d_logPrefix +
- std::string( "krb5 error when locating the credentials cache file: " ) +
- std::string( krb5_get_error_message( d_context, code ) ) );
+ if (code != 0)
+ throw PDNSException(d_logPrefix + std::string("krb5 error when locating the credentials cache file: ") + std::string(krb5_get_error_message(d_context, code)));
}
LdapGssapiAuthenticator::~LdapGssapiAuthenticator()
{
- krb5_cc_close( d_context, d_ccache );
- krb5_free_context( d_context );
+ krb5_cc_close(d_context, d_ccache);
+ krb5_free_context(d_context);
}
-bool LdapGssapiAuthenticator::authenticate( LDAP *conn )
+bool LdapGssapiAuthenticator::authenticate(LDAP* conn)
{
- int code = attemptAuth( conn );
+ int code = attemptAuth(conn);
- if ( code == -1 ) {
+ if (code == -1) {
return false;
}
- else if ( code == -2 ) {
+ else if (code == -2) {
// Here it may be possible to retry after obtaining a fresh ticket
- g_log<<Logger::Debug << d_logPrefix << "No TGT found, trying to acquire a new one" << std::endl;
+ g_log << Logger::Debug << d_logPrefix << "No TGT found, trying to acquire a new one" << std::endl;
code = updateTgt();
- if ( attemptAuth( conn ) != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "Failed to acquire a TGT" << std::endl;
+ if (attemptAuth(conn) != 0) {
+ g_log << Logger::Error << d_logPrefix << "Failed to acquire a TGT" << std::endl;
return false;
}
}
return d_lastError;
}
-int LdapGssapiAuthenticator::attemptAuth( LDAP *conn )
+int LdapGssapiAuthenticator::attemptAuth(LDAP* conn)
{
// Create SASL defaults
SaslDefaults defaults;
- char *ldapOption = nullptr;
+ char* ldapOption = nullptr;
- int optret = ldap_get_option( conn, LDAP_OPT_X_SASL_MECH, &ldapOption );
- if ( ( optret != LDAP_OPT_SUCCESS ) || !ldapOption )
- defaults.mech = std::string( "GSSAPI" );
+ int optret = ldap_get_option(conn, LDAP_OPT_X_SASL_MECH, &ldapOption);
+ if ((optret != LDAP_OPT_SUCCESS) || !ldapOption)
+ defaults.mech = std::string("GSSAPI");
else
- defaults.mech = std::string( ldapOption );
- ldap_memfree( ldapOption );
+ defaults.mech = std::string(ldapOption);
+ ldap_memfree(ldapOption);
ldapOption = nullptr;
- optret = ldap_get_option( conn, LDAP_OPT_X_SASL_REALM, &ldapOption );
- if ( ( optret == LDAP_OPT_SUCCESS ) && ldapOption )
- defaults.realm = std::string( ldapOption );
- ldap_memfree( ldapOption );
+ optret = ldap_get_option(conn, LDAP_OPT_X_SASL_REALM, &ldapOption);
+ if ((optret == LDAP_OPT_SUCCESS) && ldapOption)
+ defaults.realm = std::string(ldapOption);
+ ldap_memfree(ldapOption);
ldapOption = nullptr;
- optret = ldap_get_option( conn, LDAP_OPT_X_SASL_AUTHCID, &ldapOption );
- if ( ( optret == LDAP_OPT_SUCCESS ) && ldapOption )
- defaults.authcid = std::string( ldapOption );
- ldap_memfree( ldapOption );
+ optret = ldap_get_option(conn, LDAP_OPT_X_SASL_AUTHCID, &ldapOption);
+ if ((optret == LDAP_OPT_SUCCESS) && ldapOption)
+ defaults.authcid = std::string(ldapOption);
+ ldap_memfree(ldapOption);
ldapOption = nullptr;
- optret = ldap_get_option( conn, LDAP_OPT_X_SASL_AUTHZID, &ldapOption );
- if ( ( optret == LDAP_OPT_SUCCESS ) && ldapOption )
- defaults.authzid = std::string( ldapOption );
- ldap_memfree( ldapOption );
+ optret = ldap_get_option(conn, LDAP_OPT_X_SASL_AUTHZID, &ldapOption);
+ if ((optret == LDAP_OPT_SUCCESS) && ldapOption)
+ defaults.authzid = std::string(ldapOption);
+ ldap_memfree(ldapOption);
ldapOption = nullptr;
// And now try to bind
- int rc = ldap_sasl_interactive_bind_s( conn, "", defaults.mech.c_str(),
- NULL, NULL, LDAP_SASL_QUIET,
- ldapGssapiAuthenticatorSaslInteractCallback, &defaults );
- g_log<<Logger::Debug << d_logPrefix << "ldap_sasl_interactive_bind_s returned " << rc << std::endl;
+ int rc = ldap_sasl_interactive_bind_s(conn, "", defaults.mech.c_str(),
+ NULL, NULL, LDAP_SASL_QUIET,
+ ldapGssapiAuthenticatorSaslInteractCallback, &defaults);
+ g_log << Logger::Debug << d_logPrefix << "ldap_sasl_interactive_bind_s returned " << rc << std::endl;
- if ( rc == LDAP_LOCAL_ERROR ) {
+ if (rc == LDAP_LOCAL_ERROR) {
// This may mean that the ticket has expired, so let the caller know
- d_lastError = ldapGetError( conn, rc );
+ d_lastError = ldapGetError(conn, rc);
return -2;
}
- else if ( rc != LDAP_SUCCESS ) {
- d_lastError = ldapGetError( conn, rc );
+ else if (rc != LDAP_SUCCESS) {
+ d_lastError = ldapGetError(conn, rc);
return -1;
}
krb5_creds credentials;
krb5_keytab keytab;
krb5_principal principal;
- krb5_get_init_creds_opt *options;
+ krb5_get_init_creds_opt* options;
- if ( !d_keytabFile.empty() ) {
- std::string keytabStr( "FILE:" + d_keytabFile );
- code = krb5_kt_resolve( d_context, keytabStr.c_str(), &keytab );
+ if (!d_keytabFile.empty()) {
+ std::string keytabStr("FILE:" + d_keytabFile);
+ code = krb5_kt_resolve(d_context, keytabStr.c_str(), &keytab);
}
else {
- code = krb5_kt_default( d_context, &keytab );
+ code = krb5_kt_default(d_context, &keytab);
}
- if ( code != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when locating the keytab file: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
+ if (code != 0) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when locating the keytab file: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
return code;
}
// Extract the principal name from the keytab
krb5_kt_cursor cursor;
- if ( ( code = krb5_kt_start_seq_get( d_context, keytab, &cursor ) ) != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when initiating keytab search: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_kt_close( d_context, keytab );
+ if ((code = krb5_kt_start_seq_get(d_context, keytab, &cursor)) != 0) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when initiating keytab search: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_kt_close(d_context, keytab);
return code;
}
krb5_keytab_entry entry;
- if ( ( code = krb5_kt_next_entry( d_context, keytab, &entry, &cursor ) ) != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when retrieving first keytab entry: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_kt_close( d_context, keytab );
+ if ((code = krb5_kt_next_entry(d_context, keytab, &entry, &cursor)) != 0) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when retrieving first keytab entry: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_kt_close(d_context, keytab);
return code;
}
- if ( ( code = krb5_copy_principal( d_context, entry.principal, &principal ) ) != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when extracting principal information: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_kt_close( d_context, keytab );
- krb5_kt_free_entry( d_context, &entry );
+ if ((code = krb5_copy_principal(d_context, entry.principal, &principal)) != 0) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when extracting principal information: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_kt_close(d_context, keytab);
+ krb5_kt_free_entry(d_context, &entry);
return code;
}
- krb5_kt_free_entry( d_context, &entry );
- krb5_kt_end_seq_get( d_context, keytab, &cursor );
+ krb5_kt_free_entry(d_context, &entry);
+ krb5_kt_end_seq_get(d_context, keytab, &cursor);
- if ( ( code = krb5_get_init_creds_opt_alloc( d_context, &options ) ) != 0 ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when allocating credentials cache structure: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_kt_close( d_context, keytab );
- krb5_free_principal( d_context, principal );
+ if ((code = krb5_get_init_creds_opt_alloc(d_context, &options)) != 0) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when allocating credentials cache structure: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_kt_close(d_context, keytab);
+ krb5_free_principal(d_context, principal);
return code;
}
- krb5_get_init_creds_opt_set_default_flags( d_context, "pdns", krb5_principal_get_realm( d_context, principal ), options );
+ krb5_get_init_creds_opt_set_default_flags(d_context, "pdns", krb5_principal_get_realm(d_context, principal), options);
// Get the ticket
- code = krb5_get_init_creds_keytab( d_context, &credentials, principal, keytab, 0, NULL, options );
- if ( code ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when getting the TGT: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_get_init_creds_opt_free( d_context, options );
- krb5_free_cred_contents( d_context, &credentials );
- krb5_kt_close( d_context, keytab );
- krb5_free_principal( d_context, principal );
+ code = krb5_get_init_creds_keytab(d_context, &credentials, principal, keytab, 0, NULL, options);
+ if (code) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when getting the TGT: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_get_init_creds_opt_free(d_context, options);
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_kt_close(d_context, keytab);
+ krb5_free_principal(d_context, principal);
return code;
}
- krb5_get_init_creds_opt_free( d_context, options );
- krb5_kt_close( d_context, keytab );
+ krb5_get_init_creds_opt_free(d_context, options);
+ krb5_kt_close(d_context, keytab);
// Use a temporary cache to get the initial credentials. This will be moved to the user-configured one later.
krb5_ccache tmp_ccache = NULL;
- code = krb5_cc_new_unique( d_context, krb5_cc_get_type( d_context, d_ccache ), NULL, &tmp_ccache );
- if ( code ) {
- g_log<<Logger::Error<< d_logPrefix << "krb5 error when creating the temporary cache file: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_free_cred_contents( d_context, &credentials );
- krb5_free_principal( d_context, principal );
+ code = krb5_cc_new_unique(d_context, krb5_cc_get_type(d_context, d_ccache), NULL, &tmp_ccache);
+ if (code) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when creating the temporary cache file: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_free_principal(d_context, principal);
return code;
}
- code = krb5_cc_initialize( d_context, tmp_ccache, principal );
- if ( code ) {
- g_log<<Logger::Error<< d_logPrefix << "krb5 error when initializing the temporary cache file: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_free_cred_contents( d_context, &credentials );
- krb5_free_principal( d_context, principal );
+ code = krb5_cc_initialize(d_context, tmp_ccache, principal);
+ if (code) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when initializing the temporary cache file: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_free_principal(d_context, principal);
return code;
}
- code = krb5_cc_store_cred( d_context, tmp_ccache, &credentials );
- if ( code ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when storing the ticket in the credentials cache: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_cc_close( d_context, tmp_ccache );
- krb5_free_cred_contents( d_context, &credentials );
- krb5_free_principal( d_context, principal );
+ code = krb5_cc_store_cred(d_context, tmp_ccache, &credentials);
+ if (code) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when storing the ticket in the credentials cache: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_cc_close(d_context, tmp_ccache);
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_free_principal(d_context, principal);
return code;
}
- code = krb5_cc_move( d_context, tmp_ccache, d_ccache );
- if ( code ) {
- g_log<<Logger::Error << d_logPrefix << "krb5 error when moving the credentials cache: " << std::string( krb5_get_error_message( d_context, code ) ) << std::endl;
- krb5_free_cred_contents( d_context, &credentials );
- krb5_free_principal( d_context, principal );
+ code = krb5_cc_move(d_context, tmp_ccache, d_ccache);
+ if (code) {
+ g_log << Logger::Error << d_logPrefix << "krb5 error when moving the credentials cache: " << std::string(krb5_get_error_message(d_context, code)) << std::endl;
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_free_principal(d_context, principal);
return code;
}
- krb5_free_cred_contents( d_context, &credentials );
- krb5_free_principal( d_context, principal );
+ krb5_free_cred_contents(d_context, &credentials);
+ krb5_free_principal(d_context, principal);
- g_log<<Logger::Debug << d_logPrefix << "done getting TGT, will return " << code << std::endl;
+ g_log << Logger::Debug << d_logPrefix << "done getting TGT, will return " << code << std::endl;
return code;
}
class LdapAuthenticator
{
- public:
- virtual ~LdapAuthenticator() {}
- virtual bool authenticate( LDAP *connection ) = 0;
- virtual std::string getError() const = 0;
+public:
+ virtual ~LdapAuthenticator() {}
+ virtual bool authenticate(LDAP* connection) = 0;
+ virtual std::string getError() const = 0;
};
-
#include "ldapauthenticator.hh"
#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
-#define krb5_get_init_creds_opt_set_default_flags( a, b, c, d ) /* This does not exist with MIT Kerberos */
+#define krb5_get_init_creds_opt_set_default_flags(a, b, c, d) /* This does not exist with MIT Kerberos */
#endif
class LdapSimpleAuthenticator : public LdapAuthenticator
{
- std::string d_binddn;
- std::string d_bindpw;
- int d_timeout;
- std::string d_lastError;
-
- void fillLastError( LDAP *conn, int code );
-
- public:
- LdapSimpleAuthenticator( const std::string &dn, const std::string &pw, int timeout );
- virtual bool authenticate( LDAP *conn );
- virtual std::string getError() const;
+ std::string d_binddn;
+ std::string d_bindpw;
+ int d_timeout;
+ std::string d_lastError;
+
+ void fillLastError(LDAP* conn, int code);
+
+public:
+ LdapSimpleAuthenticator(const std::string& dn, const std::string& pw, int timeout);
+ virtual bool authenticate(LDAP* conn);
+ virtual std::string getError() const;
};
class LdapGssapiAuthenticator : public LdapAuthenticator
{
- std::string d_logPrefix;
- std::string d_keytabFile;
- std::string d_cCacheFile;
- std::string d_lastError;
+ std::string d_logPrefix;
+ std::string d_keytabFile;
+ std::string d_cCacheFile;
+ std::string d_lastError;
- krb5_context d_context;
- krb5_ccache d_ccache;
-
- struct SaslDefaults {
- std::string mech;
- std::string realm;
- std::string authcid;
- std::string authzid;
- };
-
- int attemptAuth( LDAP *conn );
- int updateTgt();
-
- public:
- LdapGssapiAuthenticator( const std::string &keytab, const std::string &credsCache, int timeout );
- ~LdapGssapiAuthenticator();
- virtual bool authenticate( LDAP *conn );
- virtual std::string getError() const;
-};
+ krb5_context d_context;
+ krb5_ccache d_ccache;
+ struct SaslDefaults
+ {
+ std::string mech;
+ std::string realm;
+ std::string authcid;
+ std::string authzid;
+ };
+
+ int attemptAuth(LDAP* conn);
+ int updateTgt();
+
+public:
+ LdapGssapiAuthenticator(const std::string& keytab, const std::string& credsCache, int timeout);
+ ~LdapGssapiAuthenticator();
+ virtual bool authenticate(LDAP* conn);
+ virtual std::string getError() const;
+};
unsigned int ldap_host_index = 0;
-LdapBackend::LdapBackend( const string &suffix )
+LdapBackend::LdapBackend(const string& suffix)
{
string hoststr;
unsigned int i, idx;
vector<string> hosts;
-
- try
- {
+ try {
d_qname.clear();
d_pldap = NULL;
d_authenticator = NULL;
- d_qlog = arg().mustDo( "query-logging" );
- d_default_ttl = arg().asNum( "default-ttl" );
+ d_qlog = arg().mustDo("query-logging");
+ d_default_ttl = arg().asNum("default-ttl");
d_myname = "[LdapBackend]";
d_in_list = false;
- setArgPrefix( "ldap" + suffix );
+ setArgPrefix("ldap" + suffix);
d_getdn = false;
- d_reconnect_attempts = getArgAsNum( "reconnect-attempts" );
+ d_reconnect_attempts = getArgAsNum("reconnect-attempts");
d_list_fcnt = &LdapBackend::list_simple;
d_lookup_fcnt = &LdapBackend::lookup_simple;
- if( getArg( "method" ) == "tree" )
- {
+ if (getArg("method") == "tree") {
d_lookup_fcnt = &LdapBackend::lookup_tree;
}
- if( getArg( "method" ) == "strict" || mustDo( "disable-ptrrecord" ) )
- {
+ if (getArg("method") == "strict" || mustDo("disable-ptrrecord")) {
d_list_fcnt = &LdapBackend::list_strict;
d_lookup_fcnt = &LdapBackend::lookup_strict;
}
- stringtok( hosts, getArg( "host" ), ", " );
+ stringtok(hosts, getArg("host"), ", ");
idx = ldap_host_index++ % hosts.size();
hoststr = hosts[idx];
- for( i = 1; i < hosts.size(); i++ )
- {
- hoststr += " " + hosts[ ( idx + i ) % hosts.size() ];
+ for (i = 1; i < hosts.size(); i++) {
+ hoststr += " " + hosts[(idx + i) % hosts.size()];
}
g_log << Logger::Info << d_myname << " LDAP servers = " << hoststr << endl;
- d_pldap = new PowerLDAP( hoststr.c_str(), LDAP_PORT, mustDo( "starttls" ), getArgAsNum( "timeout" ) );
- d_pldap->setOption( LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS );
+ d_pldap = new PowerLDAP(hoststr.c_str(), LDAP_PORT, mustDo("starttls"), getArgAsNum("timeout"));
+ d_pldap->setOption(LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS);
- string bindmethod = getArg( "bindmethod" );
- if ( bindmethod == "gssapi" ) {
- setenv( "KRB5CCNAME", getArg( "krb5-ccache" ).c_str(), 1 );
- d_authenticator = new LdapGssapiAuthenticator( getArg( "krb5-keytab" ), getArg( "krb5-ccache" ), getArgAsNum( "timeout" ) );
+ string bindmethod = getArg("bindmethod");
+ if (bindmethod == "gssapi") {
+ setenv("KRB5CCNAME", getArg("krb5-ccache").c_str(), 1);
+ d_authenticator = new LdapGssapiAuthenticator(getArg("krb5-keytab"), getArg("krb5-ccache"), getArgAsNum("timeout"));
}
else {
- d_authenticator = new LdapSimpleAuthenticator( getArg( "binddn" ), getArg( "secret" ), getArgAsNum( "timeout" ) );
+ d_authenticator = new LdapSimpleAuthenticator(getArg("binddn"), getArg("secret"), getArgAsNum("timeout"));
}
- d_pldap->bind( d_authenticator );
+ d_pldap->bind(d_authenticator);
g_log << Logger::Notice << d_myname << " Ldap connection succeeded" << endl;
return;
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Error << d_myname << " Ldap connection to server failed because of timeout" << endl;
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Ldap connection to server failed: " << le.what() << endl;
}
- catch( std::exception &e )
- {
+ catch (std::exception& e) {
g_log << Logger::Error << d_myname << " Caught STL exception: " << e.what() << endl;
}
- if( d_pldap != NULL ) { delete( d_pldap ); }
- throw PDNSException( "Unable to connect to ldap server" );
+ if (d_pldap != NULL) {
+ delete (d_pldap);
+ }
+ throw PDNSException("Unable to connect to ldap server");
}
-
-
LdapBackend::~LdapBackend()
{
d_search.reset(); // This is necessary otherwise d_pldap will get deleted first and
- // we may hang in SearchResult::~SearchResult() waiting for the
- // current operation to be abandoned
- delete( d_pldap );
- delete( d_authenticator );
+ // we may hang in SearchResult::~SearchResult() waiting for the
+ // current operation to be abandoned
+ delete (d_pldap);
+ delete (d_authenticator);
g_log << Logger::Notice << d_myname << " Ldap connection closed" << endl;
}
-
-
bool LdapBackend::reconnect()
{
int attempts = d_reconnect_attempts;
bool connected = false;
- while ( !connected && attempts > 0 ) {
+ while (!connected && attempts > 0) {
g_log << Logger::Debug << d_myname << " Reconnection attempts left: " << attempts << endl;
connected = d_pldap->connect();
- if ( !connected )
- Utility::usleep( 250 );
+ if (!connected)
+ Utility::usleep(250);
--attempts;
}
- if ( connected )
- d_pldap->bind( d_authenticator );
+ if (connected)
+ d_pldap->bind(d_authenticator);
return connected;
}
+void LdapBackend::extract_common_attributes(DNSResult& result)
+{
+ if (d_result.count("dNSTTL") && !d_result["dNSTTL"].empty()) {
+ char* endptr;
+ uint32_t ttl = (uint32_t)strtol(d_result["dNSTTL"][0].c_str(), &endptr, 10);
-void LdapBackend::extract_common_attributes( DNSResult &result ) {
- if ( d_result.count( "dNSTTL" ) && !d_result["dNSTTL"].empty() ) {
- char *endptr;
- uint32_t ttl = (uint32_t) strtol( d_result["dNSTTL"][0].c_str(), &endptr, 10 );
-
- if ( *endptr != '\0' ) {
+ if (*endptr != '\0') {
// NOTE: this will not give the entry for which the TTL was off.
// TODO: improve this.
// - Check how d_getdn is used, because if it's never false then we
}
// We have to erase the attribute, otherwise this will mess up the records retrieval later.
- d_result.erase( "dNSTTL" );
+ d_result.erase("dNSTTL");
}
- if ( d_result.count( "modifyTimestamp" ) && !d_result["modifyTimestamp"].empty() ) {
+ if (d_result.count("modifyTimestamp") && !d_result["modifyTimestamp"].empty()) {
time_t tstamp = 0;
- if ( ( tstamp = str2tstamp( d_result["modifyTimestamp"][0] ) ) == 0 ) {
+ if ((tstamp = str2tstamp(d_result["modifyTimestamp"][0])) == 0) {
// Same note as above, we don't know which entry failed here
g_log << Logger::Warning << d_myname << " Invalid modifyTimestamp for " << d_qname << ": " << d_result["modifyTimestamp"][0] << endl;
}
}
// Here too we have to erase this attribute.
- d_result.erase( "modifyTimestamp" );
+ d_result.erase("modifyTimestamp");
}
}
-
-void LdapBackend::extract_entry_results( const DNSName& domain, const DNSResult& result_template, QType qtype ) {
- std:: string attrname, qstr;
+void LdapBackend::extract_entry_results(const DNSName& domain, const DNSResult& result_template, QType qtype)
+{
+ std::string attrname, qstr;
QType qt;
bool has_records = false;
- for ( const auto& attribute : d_result ) {
+ for (const auto& attribute : d_result) {
// Find if we're dealing with a record attribute
- if ( attribute.first.length() > 6 && attribute.first.compare( attribute.first.length() - 6, 6, "Record" ) == 0 ) {
+ if (attribute.first.length() > 6 && attribute.first.compare(attribute.first.length() - 6, 6, "Record") == 0) {
has_records = true;
attrname = attribute.first;
// extract qtype string from ldap attribute name by removing the 'Record' suffix.
- qstr = attrname.substr( 0, attrname.length() - 6 );
- qt = toUpper( qstr );
+ qstr = attrname.substr(0, attrname.length() - 6);
+ qt = toUpper(qstr);
- for ( const auto& value : attribute.second ) {
- if(qtype != qt && qtype != QType::ANY) {
+ for (const auto& value : attribute.second) {
+ if (qtype != qt && qtype != QType::ANY) {
continue;
}
// Now let's see if we have some PDNS record data
// TTL
- if ( d_result.count( "PdnsRecordTTL" ) && !d_result["PdnsRecordTTL"].empty() ) {
- for ( const auto& rdata : d_result["PdnsRecordTTL"] ) {
+ if (d_result.count("PdnsRecordTTL") && !d_result["PdnsRecordTTL"].empty()) {
+ for (const auto& rdata : d_result["PdnsRecordTTL"]) {
std::string qtype2;
- std::size_t pos = rdata.find_first_of( '|', 0 );
- if ( pos == std::string::npos )
+ std::size_t pos = rdata.find_first_of('|', 0);
+ if (pos == std::string::npos)
continue;
- qtype2 = rdata.substr( 0, pos );
- if ( qtype2 != QType( local_result.qtype ).getName() )
+ qtype2 = rdata.substr(0, pos);
+ if (qtype2 != QType(local_result.qtype).getName())
continue;
- local_result.ttl = pdns_stou( rdata.substr( pos + 1 ) );
+ local_result.ttl = pdns_stou(rdata.substr(pos + 1));
}
}
// Not authoritative
- if ( d_result.count( "PdnsRecordNoAuth" ) && !d_result["PdnsRecordNoAuth"].empty() ) {
- for ( const auto& rdata : d_result["PdnsRecordNoAuth"] ) {
- if ( rdata == QType( local_result.qtype ).getName() )
+ if (d_result.count("PdnsRecordNoAuth") && !d_result["PdnsRecordNoAuth"].empty()) {
+ for (const auto& rdata : d_result["PdnsRecordNoAuth"]) {
+ if (rdata == QType(local_result.qtype).getName())
local_result.auth = false;
}
}
// Ordername
- if ( d_result.count( "PdnsRecordOrdername" ) && !d_result["PdnsRecordOrdername"].empty() ) {
+ if (d_result.count("PdnsRecordOrdername") && !d_result["PdnsRecordOrdername"].empty()) {
std::string defaultOrdername;
- for ( const auto& rdata : d_result["PdnsRecordOrdername"] ) {
+ for (const auto& rdata : d_result["PdnsRecordOrdername"]) {
std::string qtype2;
- std::size_t pos = rdata.find_first_of( '|', 0 );
- if ( pos == std::string::npos ) {
+ std::size_t pos = rdata.find_first_of('|', 0);
+ if (pos == std::string::npos) {
// This is the default ordername for all records in this entry
defaultOrdername = rdata;
continue;
}
- qtype2 = rdata.substr( 0, pos );
- if ( qtype2 != QType( local_result.qtype ).getName() )
+ qtype2 = rdata.substr(0, pos);
+ if (qtype2 != QType(local_result.qtype).getName())
continue;
- local_result.ordername = rdata.substr( pos + 1 );
+ local_result.ordername = rdata.substr(pos + 1);
}
- if ( local_result.ordername.empty() && !defaultOrdername.empty() )
+ if (local_result.ordername.empty() && !defaultOrdername.empty())
local_result.ordername = defaultOrdername;
}
- d_results_cache.push_back( local_result );
+ d_results_cache.push_back(local_result);
}
}
}
- if ( !has_records ) {
+ if (!has_records) {
// This is an ENT
DNSResult local_result = result_template;
local_result.qname = domain;
- if ( !d_result.count( "PdnsRecordOrdername" ) || d_result["PdnsRecordOrdername"].empty() ) {
+ if (!d_result.count("PdnsRecordOrdername") || d_result["PdnsRecordOrdername"].empty()) {
// An ENT with an order name is authoritative
local_result.auth = false;
}
- d_results_cache.push_back( local_result );
+ d_results_cache.push_back(local_result);
}
}
-
class LdapFactory : public BackendFactory
{
- public:
-
- LdapFactory() : BackendFactory( "ldap" ) {}
-
- void declareArguments( const string &suffix="" ) override
- {
- declare( suffix, "host", "One or more LDAP server with ports or LDAP URIs (separated by spaces)","ldap://127.0.0.1:389/" );
- declare( suffix, "starttls", "Use TLS to encrypt connection (unused for LDAP URIs)", "no" );
- declare( suffix, "basedn", "Search root in ldap tree (must be set)","" );
- declare( suffix, "basedn-axfr-override", "Override base dn for AXFR subtree search", "no" );
- declare( suffix, "bindmethod", "Bind method to use (simple or gssapi)", "simple" );
- declare( suffix, "binddn", "User dn for non anonymous binds","" );
- declare( suffix, "secret", "User password for non anonymous binds", "" );
- declare( suffix, "krb5-keytab", "The keytab to use for GSSAPI authentication", "" );
- declare( suffix, "krb5-ccache", "The credentials cache used for GSSAPI authentication", "" );
- declare( suffix, "timeout", "Seconds before connecting to server fails", "5" );
- declare( suffix, "method", "How to search entries (simple, strict or tree)", "simple" );
- declare( suffix, "filter-axfr", "LDAP filter for limiting AXFR results", "(:target:)" );
- declare( suffix, "filter-lookup", "LDAP filter for limiting IP or name lookups", "(:target:)" );
- declare( suffix, "disable-ptrrecord", "Deprecated, use ldap-method=strict instead", "no" );
- declare( suffix, "reconnect-attempts", "Number of attempts to re-establish a lost LDAP connection", "5" );
- }
+public:
+ LdapFactory() :
+ BackendFactory("ldap") {}
+ void declareArguments(const string& suffix = "") override
+ {
+ declare(suffix, "host", "One or more LDAP server with ports or LDAP URIs (separated by spaces)", "ldap://127.0.0.1:389/");
+ declare(suffix, "starttls", "Use TLS to encrypt connection (unused for LDAP URIs)", "no");
+ declare(suffix, "basedn", "Search root in ldap tree (must be set)", "");
+ declare(suffix, "basedn-axfr-override", "Override base dn for AXFR subtree search", "no");
+ declare(suffix, "bindmethod", "Bind method to use (simple or gssapi)", "simple");
+ declare(suffix, "binddn", "User dn for non anonymous binds", "");
+ declare(suffix, "secret", "User password for non anonymous binds", "");
+ declare(suffix, "krb5-keytab", "The keytab to use for GSSAPI authentication", "");
+ declare(suffix, "krb5-ccache", "The credentials cache used for GSSAPI authentication", "");
+ declare(suffix, "timeout", "Seconds before connecting to server fails", "5");
+ declare(suffix, "method", "How to search entries (simple, strict or tree)", "simple");
+ declare(suffix, "filter-axfr", "LDAP filter for limiting AXFR results", "(:target:)");
+ declare(suffix, "filter-lookup", "LDAP filter for limiting IP or name lookups", "(:target:)");
+ declare(suffix, "disable-ptrrecord", "Deprecated, use ldap-method=strict instead", "no");
+ declare(suffix, "reconnect-attempts", "Number of attempts to re-establish a lost LDAP connection", "5");
+ }
- DNSBackend* make( const string &suffix="" ) override
- {
- return new LdapBackend( suffix );
- }
+ DNSBackend* make(const string& suffix = "") override
+ {
+ return new LdapBackend(suffix);
+ }
};
-
-
-
-
class LdapLoader
{
- LdapFactory factory;
-
- public:
+ LdapFactory factory;
- LdapLoader()
- {
- BackendMakers().report( &factory );
- g_log << Logger::Info << "[ldapbackend] This is the ldap backend version " VERSION
+public:
+ LdapLoader()
+ {
+ BackendMakers().report(&factory);
+ g_log << Logger::Info << "[ldapbackend] This is the ldap backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
- }
+ << " reporting" << endl;
+ }
};
-
static LdapLoader ldaploader;
#include "powerldap.hh"
#include "utils.hh"
-
using std::string;
using std::vector;
* Types which aren't active are currently not supported by PDNS
*/
-__attribute__ ((unused)) static const char* ldap_attrany[] = {
+__attribute__((unused)) static const char* ldap_attrany[] = {
"associatedDomain",
"dNSTTL",
"ALIASRecord",
"tXTRecord",
"rPRecord",
"aFSDBRecord",
-// "SigRecord",
+ // "SigRecord",
"KeyRecord",
-// "gPosRecord",
+ // "gPosRecord",
"aAAARecord",
"lOCRecord",
"sRVRecord",
"nAPTRRecord",
"kXRecord",
"certRecord",
-// "a6Record",
+ // "a6Record",
"dNameRecord",
-// "aPLRecord",
+ // "aPLRecord",
"dSRecord",
"sSHFPRecord",
"iPSecKeyRecord",
"PdnsRecordTTL",
"PdnsRecordAuth",
"PdnsRecordOrdername",
- NULL
-};
-
-
+ NULL};
class LdapBackend : public DNSBackend
{
- string d_myname;
-
- bool d_qlog;
- uint32_t d_default_ttl;
- int d_reconnect_attempts;
-
- bool d_getdn;
- PowerLDAP::SearchResult::Ptr d_search;
- PowerLDAP::sentry_t d_result;
- bool d_in_list;
-
- struct DNSResult {
- QType qtype;
- DNSName qname;
- uint32_t ttl;
- time_t lastmod;
- std::string value;
- bool auth;
- std::string ordername;
-
- DNSResult()
- : ttl( 0 ), lastmod( 0 ), value( "" ), auth( true ), ordername( "" )
- {
- }
- };
- std::list<DNSResult> d_results_cache;
-
- DNSName d_qname;
- QType d_qtype;
-
- PowerLDAP* d_pldap;
- LdapAuthenticator *d_authenticator;
-
- bool (LdapBackend::*d_list_fcnt)( const DNSName&, int );
- void (LdapBackend::*d_lookup_fcnt)( const QType&, const DNSName&, DNSPacket*, int );
-
- bool list_simple( const DNSName& target, int domain_id );
- bool list_strict( const DNSName& target, int domain_id );
-
- void lookup_simple( const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid );
- void lookup_strict( const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid );
- void lookup_tree( const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid );
-
- bool reconnect();
-
- // Extracts common attributes from the current result stored in d_result and sets them in the given DNSResult.
- // This will modify d_result by removing attributes that may interfere with the records extraction later.
- void extract_common_attributes( DNSResult &result );
-
- // Extract LDAP attributes for the current result stored in d_result and create a new DNSResult that will
- // be appended in the results cache. The result parameter is used as a template that will be copied for
- // each result extracted from the entry.
- // The given domain will be added as the qname attribute of the result.
- // The qtype parameter is used to filter extracted results.
- void extract_entry_results( const DNSName& domain, const DNSResult& result, QType qtype );
-
- public:
-
- LdapBackend( const string &suffix="" );
- ~LdapBackend();
-
- // Native backend
- bool list( const DNSName& target, int domain_id, bool include_disabled=false ) override;
- void lookup( const QType& qtype, const DNSName& qdomain, int zoneid, DNSPacket* p = nullptr ) override;
- bool get( DNSResourceRecord& rr ) override;
-
- bool getDomainInfo( const DNSName& domain, DomainInfo& di, bool getSerial=true ) override;
-
- // Master backend
- void getUpdatedMasters( vector<DomainInfo>* domains ) override;
- void setNotified( uint32_t id, uint32_t serial ) override;
+ string d_myname;
+
+ bool d_qlog;
+ uint32_t d_default_ttl;
+ int d_reconnect_attempts;
+
+ bool d_getdn;
+ PowerLDAP::SearchResult::Ptr d_search;
+ PowerLDAP::sentry_t d_result;
+ bool d_in_list;
+
+ struct DNSResult
+ {
+ QType qtype;
+ DNSName qname;
+ uint32_t ttl;
+ time_t lastmod;
+ std::string value;
+ bool auth;
+ std::string ordername;
+
+ DNSResult() :
+ ttl(0), lastmod(0), value(""), auth(true), ordername("")
+ {
+ }
+ };
+ std::list<DNSResult> d_results_cache;
+
+ DNSName d_qname;
+ QType d_qtype;
+
+ PowerLDAP* d_pldap;
+ LdapAuthenticator* d_authenticator;
+
+ bool (LdapBackend::*d_list_fcnt)(const DNSName&, int);
+ void (LdapBackend::*d_lookup_fcnt)(const QType&, const DNSName&, DNSPacket*, int);
+
+ bool list_simple(const DNSName& target, int domain_id);
+ bool list_strict(const DNSName& target, int domain_id);
+
+ void lookup_simple(const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid);
+ void lookup_strict(const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid);
+ void lookup_tree(const QType& qtype, const DNSName& qdomain, DNSPacket* p, int zoneid);
+
+ bool reconnect();
+
+ // Extracts common attributes from the current result stored in d_result and sets them in the given DNSResult.
+ // This will modify d_result by removing attributes that may interfere with the records extraction later.
+ void extract_common_attributes(DNSResult& result);
+
+ // Extract LDAP attributes for the current result stored in d_result and create a new DNSResult that will
+ // be appended in the results cache. The result parameter is used as a template that will be copied for
+ // each result extracted from the entry.
+ // The given domain will be added as the qname attribute of the result.
+ // The qtype parameter is used to filter extracted results.
+ void extract_entry_results(const DNSName& domain, const DNSResult& result, QType qtype);
+
+public:
+ LdapBackend(const string& suffix = "");
+ ~LdapBackend();
+
+ // Native backend
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override;
+ void lookup(const QType& qtype, const DNSName& qdomain, int zoneid, DNSPacket* p = nullptr) override;
+ bool get(DNSResourceRecord& rr) override;
+
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
+
+ // Master backend
+ void getUpdatedMasters(vector<DomainInfo>* domains) override;
+ void setNotified(uint32_t id, uint32_t serial) override;
};
-
#include "ldaputils.hh"
#include <sys/time.h>
-void ldapSetOption( LDAP *conn, int option, void *value )
+void ldapSetOption(LDAP* conn, int option, void* value)
{
- if( ldap_set_option( conn, option, value ) != LDAP_OPT_SUCCESS )
- {
- throw LDAPException( "Unable to set option" );
+ if (ldap_set_option(conn, option, value) != LDAP_OPT_SUCCESS) {
+ throw LDAPException("Unable to set option");
}
}
-void ldapGetOption( LDAP *conn, int option, void *value )
+void ldapGetOption(LDAP* conn, int option, void* value)
{
- if( ldap_get_option( conn, option, value ) != LDAP_OPT_SUCCESS )
- {
- throw LDAPException( "Unable to get option" );
+ if (ldap_get_option(conn, option, value) != LDAP_OPT_SUCCESS) {
+ throw LDAPException("Unable to get option");
}
}
-std::string ldapGetError( LDAP *conn, int code )
+std::string ldapGetError(LDAP* conn, int code)
{
- if ( code == -1 )
- ldapGetOption( conn, LDAP_OPT_ERROR_NUMBER, &code );
- return std::string( ldap_err2string( code ) );
+ if (code == -1)
+ ldapGetOption(conn, LDAP_OPT_ERROR_NUMBER, &code);
+ return std::string(ldap_err2string(code));
}
-int ldapWaitResult( LDAP *conn, int msgid, int timeout, LDAPMessage** result )
+int ldapWaitResult(LDAP* conn, int msgid, int timeout, LDAPMessage** result)
{
struct timeval tv;
LDAPMessage* res;
-
tv.tv_sec = timeout;
tv.tv_usec = 0;
- int rc = ldap_result( conn, msgid, LDAP_MSG_ONE, &tv, &res );
+ int rc = ldap_result(conn, msgid, LDAP_MSG_ONE, &tv, &res);
- if ( rc == -1 || rc == 0 )
+ if (rc == -1 || rc == 0)
return rc;
- if( result == NULL )
- {
- ldap_msgfree( res );
+ if (result == NULL) {
+ ldap_msgfree(res);
return rc;
}
#include <ldap.h>
#include <string>
-void ldapSetOption( LDAP *conn, int option, void *value );
+void ldapSetOption(LDAP* conn, int option, void* value);
-void ldapGetOption( LDAP *conn, int option, void *value );
+void ldapGetOption(LDAP* conn, int option, void* value);
-std::string ldapGetError( LDAP *conn, int code );
-
-int ldapWaitResult( LDAP *conn, int msgid, int timeout, LDAPMessage** result = NULL );
+std::string ldapGetError(LDAP* conn, int code);
+int ldapWaitResult(LDAP* conn, int msgid, int timeout, LDAPMessage** result = NULL);
#include "ldapbackend.hh"
#include <cstdlib>
-
-void LdapBackend::getUpdatedMasters( vector<DomainInfo>* domains )
+void LdapBackend::getUpdatedMasters(vector<DomainInfo>* domains)
{
string filter;
PowerLDAP::SearchResult::Ptr search;
PowerLDAP::sentry_t result;
const char* attronly[] = {
"associatedDomain",
- NULL
- };
+ NULL};
- try
- {
+ try {
// First get all domains on which we are master.
- filter = strbind( ":target:", "&(SOARecord=*)(PdnsDomainId=*)", getArg( "filter-axfr" ) );
- search = d_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attronly );
+ filter = strbind(":target:", "&(SOARecord=*)(PdnsDomainId=*)", getArg("filter-axfr"));
+ search = d_pldap->search(getArg("basedn"), LDAP_SCOPE_SUBTREE, filter, attronly);
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Warning << d_myname << " Unable to search LDAP directory: " << lt.what() << endl;
- throw DBException( "LDAP server timeout" );
+ throw DBException("LDAP server timeout");
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->getUpdatedMasters( domains );
+ if (reconnect())
+ this->getUpdatedMasters(domains);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to search LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
- throw DBException( "STL exception" );
+ catch (std::exception& e) {
+ throw DBException("STL exception");
}
- while( search->getNext( result ) ) {
- if( !result.count( "associatedDomain" ) || result["associatedDomain"].empty() )
+ while (search->getNext(result)) {
+ if (!result.count("associatedDomain") || result["associatedDomain"].empty())
continue;
DomainInfo di;
- if ( !getDomainInfo( DNSName( result["associatedDomain"][0] ), di ) )
+ if (!getDomainInfo(DNSName(result["associatedDomain"][0]), di))
continue;
- if( di.notified_serial < di.serial )
- domains->push_back( di );
+ if (di.notified_serial < di.serial)
+ domains->push_back(di);
}
}
-
-
-void LdapBackend::setNotified( uint32_t id, uint32_t serial )
+void LdapBackend::setNotified(uint32_t id, uint32_t serial)
{
string filter;
PowerLDAP::SearchResult::Ptr search;
PowerLDAP::sresult_t results;
PowerLDAP::sentry_t entry;
- const char* attronly[] = { "associatedDomain", NULL };
+ const char* attronly[] = {"associatedDomain", NULL};
- try
- {
+ try {
// Try to find the notified domain
- filter = strbind( ":target:", "PdnsDomainId=" + std::to_string( id ), getArg( "filter-axfr" ) );
- search = d_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attronly );
- search->getAll( results, true );
+ filter = strbind(":target:", "PdnsDomainId=" + std::to_string(id), getArg("filter-axfr"));
+ search = d_pldap->search(getArg("basedn"), LDAP_SCOPE_SUBTREE, filter, attronly);
+ search->getAll(results, true);
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Warning << d_myname << " Unable to search LDAP directory: " << lt.what() << endl;
- throw DBException( "LDAP server timeout" );
+ throw DBException("LDAP server timeout");
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->setNotified( id, serial );
+ if (reconnect())
+ this->setNotified(id, serial);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to search LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
- throw DBException( "STL exception" );
+ catch (std::exception& e) {
+ throw DBException("STL exception");
}
- if ( results.empty() )
- throw PDNSException( "No results found when trying to update domain notified_serial for ID " + std::to_string( id ) );
+ if (results.empty())
+ throw PDNSException("No results found when trying to update domain notified_serial for ID " + std::to_string(id));
entry = results.front();
string dn = entry["dn"][0];
- string serialStr = std::to_string( serial );
- LDAPMod *mods[2];
+ string serialStr = std::to_string(serial);
+ LDAPMod* mods[2];
LDAPMod mod;
- char *vals[2];
+ char* vals[2];
mod.mod_op = LDAP_MOD_REPLACE;
mod.mod_type = (char*)"PdnsDomainNotifiedSerial";
- vals[0] = const_cast<char*>( serialStr.c_str() );
+ vals[0] = const_cast<char*>(serialStr.c_str());
vals[1] = NULL;
mod.mod_values = vals;
mods[0] = &mod;
mods[1] = NULL;
- try
- {
- d_pldap->modify( dn, mods );
+ try {
+ d_pldap->modify(dn, mods);
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->setNotified( id, serial );
+ if (reconnect())
+ this->setNotified(id, serial);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to search LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
- throw DBException( "STL exception" );
+ catch (std::exception& e) {
+ throw DBException("STL exception");
}
}
#include "ldapbackend.hh"
#include <cstdlib>
-
-bool LdapBackend::list( const DNSName& target, int domain_id, bool include_disabled )
+bool LdapBackend::list(const DNSName& target, int domain_id, bool include_disabled)
{
- try
- {
+ try {
d_in_list = true;
d_qname = target;
d_qtype = QType::ANY;
d_results_cache.clear();
- return (this->*d_list_fcnt)( target, domain_id );
+ return (this->*d_list_fcnt)(target, domain_id);
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Warning << d_myname << " Unable to get zone " << target << " from LDAP directory: " << lt.what() << endl;
- throw DBException( "LDAP server timeout" );
+ throw DBException("LDAP server timeout");
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->list( target, domain_id );
+ if (reconnect())
+ this->list(target, domain_id);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to get zone " << target << " from LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
+ catch (std::exception& e) {
g_log << Logger::Error << d_myname << " Caught STL exception for target " << target << ": " << e.what() << endl;
- throw DBException( "STL exception" );
+ throw DBException("STL exception");
}
return false;
}
-
-
-bool LdapBackend::list_simple( const DNSName& target, int domain_id )
+bool LdapBackend::list_simple(const DNSName& target, int domain_id)
{
string dn;
string filter;
string qesc;
-
- dn = getArg( "basedn" );
- qesc = toLower( d_pldap->escape( target.toStringRootDot() ) );
+ dn = getArg("basedn");
+ qesc = toLower(d_pldap->escape(target.toStringRootDot()));
// search for SOARecord of target
- filter = strbind( ":target:", "&(associatedDomain=" + qesc + ")(sOARecord=*)", getArg( "filter-axfr" ) );
- PowerLDAP::SearchResult::Ptr search = d_pldap->search( dn, LDAP_SCOPE_SUBTREE, filter, (const char**) ldap_attrany );
- if ( !search->getNext( d_result, true ) )
+ filter = strbind(":target:", "&(associatedDomain=" + qesc + ")(sOARecord=*)", getArg("filter-axfr"));
+ PowerLDAP::SearchResult::Ptr search = d_pldap->search(dn, LDAP_SCOPE_SUBTREE, filter, (const char**)ldap_attrany);
+ if (!search->getNext(d_result, true))
return false;
- if( d_result.count( "dn" ) && !d_result["dn"].empty() )
- {
- if( !mustDo( "basedn-axfr-override" ) )
- {
+ if (d_result.count("dn") && !d_result["dn"].empty()) {
+ if (!mustDo("basedn-axfr-override")) {
dn = d_result["dn"][0];
}
}
DNSResult soa_result;
soa_result.ttl = d_default_ttl;
soa_result.lastmod = 0;
- this->extract_common_attributes( soa_result );
- this->extract_entry_results( d_qname, soa_result, QType(uint16_t(QType::ANY)) );
+ this->extract_common_attributes(soa_result);
+ this->extract_entry_results(d_qname, soa_result, QType(uint16_t(QType::ANY)));
- filter = strbind( ":target:", "associatedDomain=*." + qesc, getArg( "filter-axfr" ) );
+ filter = strbind(":target:", "associatedDomain=*." + qesc, getArg("filter-axfr"));
g_log << Logger::Debug << d_myname << " Search = basedn: " << dn << ", filter: " << filter << endl;
- d_search = d_pldap->search( dn, LDAP_SCOPE_SUBTREE, filter, (const char**) ldap_attrany );
+ d_search = d_pldap->search(dn, LDAP_SCOPE_SUBTREE, filter, (const char**)ldap_attrany);
return true;
}
-
-bool LdapBackend::list_strict( const DNSName& target, int domain_id )
+bool LdapBackend::list_strict(const DNSName& target, int domain_id)
{
- if( target.isPartOf(DNSName("in-addr.arpa")) || target.isPartOf(DNSName("ip6.arpa")) )
- {
+ if (target.isPartOf(DNSName("in-addr.arpa")) || target.isPartOf(DNSName("ip6.arpa"))) {
g_log << Logger::Warning << d_myname << " Request for reverse zone AXFR, but this is not supported in strict mode" << endl;
- return false; // AXFR isn't supported in strict mode. Use simple mode and additional PTR records
+ return false; // AXFR isn't supported in strict mode. Use simple mode and additional PTR records
}
- return list_simple( target, domain_id );
+ return list_simple(target, domain_id);
}
-
-
-void LdapBackend::lookup( const QType &qtype, const DNSName &qname, int zoneid, DNSPacket *dnspkt )
+void LdapBackend::lookup(const QType& qtype, const DNSName& qname, int zoneid, DNSPacket* dnspkt)
{
- try
- {
+ try {
d_in_list = false;
d_qname = qname;
d_qtype = qtype;
d_results_cache.clear();
- if( d_qlog ) { g_log.log( "Query: '" + qname.toStringRootDot() + "|" + qtype.getName() + "'", Logger::Error ); }
- (this->*d_lookup_fcnt)( qtype, qname, dnspkt, zoneid );
+ if (d_qlog) {
+ g_log.log("Query: '" + qname.toStringRootDot() + "|" + qtype.getName() + "'", Logger::Error);
+ }
+ (this->*d_lookup_fcnt)(qtype, qname, dnspkt, zoneid);
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Warning << d_myname << " Unable to search LDAP directory: " << lt.what() << endl;
- throw DBException( "LDAP server timeout" );
+ throw DBException("LDAP server timeout");
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->lookup( qtype, qname, zoneid, dnspkt );
+ if (reconnect())
+ this->lookup(qtype, qname, zoneid, dnspkt);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to search LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
+ catch (std::exception& e) {
g_log << Logger::Error << d_myname << " Caught STL exception for qname " << qname << ": " << e.what() << endl;
- throw DBException( "STL exception" );
+ throw DBException("STL exception");
}
}
-
-
-void LdapBackend::lookup_simple( const QType &qtype, const DNSName &qname, DNSPacket *dnspkt, int zoneid )
+void LdapBackend::lookup_simple(const QType& qtype, const DNSName& qname, DNSPacket* dnspkt, int zoneid)
{
string filter, attr, qesc;
- const char** attributes = ldap_attrany + 1; // skip associatedDomain
- const char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL };
-
+ const char** attributes = ldap_attrany + 1; // skip associatedDomain
+ const char* attronly[] = {NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL};
- qesc = toLower( d_pldap->escape( qname.toStringRootDot() ) );
+ qesc = toLower(d_pldap->escape(qname.toStringRootDot()));
filter = "associatedDomain=" + qesc;
- if( qtype.getCode() != QType::ANY )
- {
+ if (qtype.getCode() != QType::ANY) {
attr = qtype.getName() + "Record";
filter = "&(" + filter + ")(" + attr + "=*)";
attronly[0] = attr.c_str();
attributes = attronly;
}
- filter = strbind( ":target:", filter, getArg( "filter-lookup" ) );
+ filter = strbind(":target:", filter, getArg("filter-lookup"));
- g_log << Logger::Debug << d_myname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
- d_search = d_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attributes );
+ g_log << Logger::Debug << d_myname << " Search = basedn: " << getArg("basedn") << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
+ d_search = d_pldap->search(getArg("basedn"), LDAP_SCOPE_SUBTREE, filter, attributes);
}
-
-
-void LdapBackend::lookup_strict( const QType &qtype, const DNSName &qname, DNSPacket *dnspkt, int zoneid )
+void LdapBackend::lookup_strict(const QType& qtype, const DNSName& qname, DNSPacket* dnspkt, int zoneid)
{
int len;
vector<string> parts;
string filter, attr, qesc;
- const char** attributes = ldap_attrany + 1; // skip associatedDomain
- const char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL };
+ const char** attributes = ldap_attrany + 1; // skip associatedDomain
+ const char* attronly[] = {NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL};
-
- qesc = toLower( d_pldap->escape( qname.toStringRootDot() ) );
- stringtok( parts, qesc, "." );
+ qesc = toLower(d_pldap->escape(qname.toStringRootDot()));
+ stringtok(parts, qesc, ".");
len = qesc.length();
- if( parts.size() == 6 && len > 13 && qesc.substr( len - 13, 13 ) == ".in-addr.arpa" ) // IPv4 reverse lookups
+ if (parts.size() == 6 && len > 13 && qesc.substr(len - 13, 13) == ".in-addr.arpa") // IPv4 reverse lookups
{
- filter = "aRecord=" + ptr2ip4( parts );
+ filter = "aRecord=" + ptr2ip4(parts);
attronly[0] = "associatedDomain";
attributes = attronly;
}
- else if( parts.size() == 34 && len > 9 && ( qesc.substr( len - 9, 9 ) == ".ip6.arpa" ) ) // IPv6 reverse lookups
+ else if (parts.size() == 34 && len > 9 && (qesc.substr(len - 9, 9) == ".ip6.arpa")) // IPv6 reverse lookups
{
- filter = "aAAARecord=" + ptr2ip6( parts );
+ filter = "aAAARecord=" + ptr2ip6(parts);
attronly[0] = "associatedDomain";
attributes = attronly;
}
- else // IPv4 and IPv6 lookups
+ else // IPv4 and IPv6 lookups
{
filter = "associatedDomain=" + qesc;
}
- if( qtype.getCode() != QType::ANY )
- {
+ if (qtype.getCode() != QType::ANY) {
attr = qtype.getName() + "Record";
filter = "&(" + filter + ")(" + attr + "=*)";
attronly[0] = attr.c_str();
attributes = attronly;
}
- filter = strbind( ":target:", filter, getArg( "filter-lookup" ) );
+ filter = strbind(":target:", filter, getArg("filter-lookup"));
- g_log << Logger::Debug << d_myname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
- d_search = d_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attributes );
+ g_log << Logger::Debug << d_myname << " Search = basedn: " << getArg("basedn") << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
+ d_search = d_pldap->search(getArg("basedn"), LDAP_SCOPE_SUBTREE, filter, attributes);
}
-
-
-void LdapBackend::lookup_tree( const QType &qtype, const DNSName &qname, DNSPacket *dnspkt, int zoneid )
+void LdapBackend::lookup_tree(const QType& qtype, const DNSName& qname, DNSPacket* dnspkt, int zoneid)
{
string filter, attr, qesc, dn;
- const char** attributes = ldap_attrany + 1; // skip associatedDomain
- const char* attronly[] = { NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL };
+ const char** attributes = ldap_attrany + 1; // skip associatedDomain
+ const char* attronly[] = {NULL, "dNSTTL", "modifyTimestamp", "PdnsRecordTTL", "PdnsRecordAuth", "PdnsRecordOrdername", NULL};
vector<string> parts;
-
- qesc = toLower( d_pldap->escape( qname.toStringRootDot() ) );
+ qesc = toLower(d_pldap->escape(qname.toStringRootDot()));
filter = "associatedDomain=" + qesc;
- if( qtype.getCode() != QType::ANY )
- {
+ if (qtype.getCode() != QType::ANY) {
attr = qtype.getName() + "Record";
filter = "&(" + filter + ")(" + attr + "=*)";
attronly[0] = attr.c_str();
attributes = attronly;
}
- filter = strbind( ":target:", filter, getArg( "filter-lookup" ) );
+ filter = strbind(":target:", filter, getArg("filter-lookup"));
- stringtok( parts, toLower( qname.toString() ), "." );
- for(auto i = parts.crbegin(); i != parts.crend(); i++ )
- {
+ stringtok(parts, toLower(qname.toString()), ".");
+ for (auto i = parts.crbegin(); i != parts.crend(); i++) {
dn = "dc=" + *i + "," + dn;
}
- g_log << Logger::Debug << d_myname << " Search = basedn: " << dn + getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
- d_search = d_pldap->search( dn + getArg( "basedn" ), LDAP_SCOPE_BASE, filter, attributes );
+ g_log << Logger::Debug << d_myname << " Search = basedn: " << dn + getArg("basedn") << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
+ d_search = d_pldap->search(dn + getArg("basedn"), LDAP_SCOPE_BASE, filter, attributes);
}
-
-bool LdapBackend::get( DNSResourceRecord &rr )
+bool LdapBackend::get(DNSResourceRecord& rr)
{
- if ( d_results_cache.empty() ) {
- while ( d_results_cache.empty() ) {
+ if (d_results_cache.empty()) {
+ while (d_results_cache.empty()) {
bool exhausted = false;
bool valid_entry_found = false;
- while ( !valid_entry_found && !exhausted ) {
+ while (!valid_entry_found && !exhausted) {
try {
- exhausted = !d_search->getNext( d_result, true );
+ exhausted = !d_search->getNext(d_result, true);
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Failed to get next result: " << le.what() << endl;
- throw PDNSException( "Get next result impossible" );
+ throw PDNSException("Get next result impossible");
}
- if ( !exhausted ) {
- if ( !d_in_list ) {
+ if (!exhausted) {
+ if (!d_in_list) {
// All entries are valid here
valid_entry_found = true;
}
else {
// If we're called after list() then the entry *must* contain
// associatedDomain, otherwise let's just skip it
- if ( d_result.count( "associatedDomain" ) )
+ if (d_result.count("associatedDomain"))
valid_entry_found = true;
}
}
}
- if ( exhausted ) {
+ if (exhausted) {
break;
}
DNSResult result_template;
result_template.ttl = d_default_ttl;
result_template.lastmod = 0;
- this->extract_common_attributes( result_template );
+ this->extract_common_attributes(result_template);
std::vector<std::string> associatedDomains;
- if ( d_result.count( "associatedDomain" ) ) {
- if ( d_in_list ) {
+ if (d_result.count("associatedDomain")) {
+ if (d_in_list) {
// We can have more than one associatedDomain in the entry, so for each of them we have to check
// that they are indeed under the domain we've been asked to list (nothing enforces this, so you
// can have one associatedDomain set to "host.first-domain.com" and another one set to
// and the others above we've already cleaned it's just a matter of iterating over them.
unsigned int axfrqlen = d_qname.toStringRootDot().length();
- for ( auto i = d_result["associatedDomain"].begin(); i != d_result["associatedDomain"].end(); ++i ) {
+ for (auto i = d_result["associatedDomain"].begin(); i != d_result["associatedDomain"].end(); ++i) {
// Sanity checks: is this associatedDomain attribute under the requested domain?
- if ( i->size() >= axfrqlen && i->substr( i->size() - axfrqlen, axfrqlen ) == d_qname.toStringRootDot() )
- associatedDomains.push_back( *i );
+ if (i->size() >= axfrqlen && i->substr(i->size() - axfrqlen, axfrqlen) == d_qname.toStringRootDot())
+ associatedDomains.push_back(*i);
}
}
else {
}
}
- if ( d_in_list ) {
- for ( const auto& domain : associatedDomains )
- this->extract_entry_results( DNSName( domain ), result_template, QType(uint16_t(QType::ANY)) );
+ if (d_in_list) {
+ for (const auto& domain : associatedDomains)
+ this->extract_entry_results(DNSName(domain), result_template, QType(uint16_t(QType::ANY)));
}
else {
- this->extract_entry_results( d_qname, result_template, QType(uint16_t(QType::ANY)) );
+ this->extract_entry_results(d_qname, result_template, QType(uint16_t(QType::ANY)));
}
}
- if ( d_results_cache.empty() )
+ if (d_results_cache.empty())
return false;
}
return true;
}
-
-bool LdapBackend::getDomainInfo( const DNSName& domain, DomainInfo& di, bool getSerial )
+bool LdapBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
{
string filter;
SOAData sd;
"PdnsDomainLastCheck",
"PdnsDomainMaster",
"PdnsDomainType",
- NULL
- };
+ NULL};
- try
- {
+ try {
// search for SOARecord of domain
- filter = "(&(associatedDomain=" + toLower( d_pldap->escape( domain.toStringRootDot() ) ) + ")(SOARecord=*))";
- d_search = d_pldap->search( getArg( "basedn" ), LDAP_SCOPE_SUBTREE, filter, attronly );
- if (!d_search->getNext( result )) {
+ filter = "(&(associatedDomain=" + toLower(d_pldap->escape(domain.toStringRootDot())) + ")(SOARecord=*))";
+ d_search = d_pldap->search(getArg("basedn"), LDAP_SCOPE_SUBTREE, filter, attronly);
+ if (!d_search->getNext(result)) {
return false;
}
}
- catch( LDAPTimeout < )
- {
+ catch (LDAPTimeout& lt) {
g_log << Logger::Warning << d_myname << " Unable to search LDAP directory: " << lt.what() << endl;
- throw DBException( "LDAP server timeout" );
+ throw DBException("LDAP server timeout");
}
- catch( LDAPNoConnection &lnc )
- {
+ catch (LDAPNoConnection& lnc) {
g_log << Logger::Warning << d_myname << " Connection to LDAP lost, trying to reconnect" << endl;
- if ( reconnect() )
- this->getDomainInfo( domain, di );
+ if (reconnect())
+ this->getDomainInfo(domain, di);
else
- throw PDNSException( "Failed to reconnect to LDAP server" );
+ throw PDNSException("Failed to reconnect to LDAP server");
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
g_log << Logger::Error << d_myname << " Unable to search LDAP directory: " << le.what() << endl;
- throw PDNSException( "LDAP server unreachable" ); // try to reconnect to another server
+ throw PDNSException("LDAP server unreachable"); // try to reconnect to another server
}
- catch( std::exception &e )
- {
- throw DBException( "STL exception" );
+ catch (std::exception& e) {
+ throw DBException("STL exception");
}
- if( result.count( "sOARecord" ) && !result["sOARecord"].empty() )
- {
+ if (result.count("sOARecord") && !result["sOARecord"].empty()) {
sd.serial = 0;
- fillSOAData( result["sOARecord"][0], sd );
+ fillSOAData(result["sOARecord"][0], sd);
- if ( result.count( "PdnsDomainId" ) && !result["PdnsDomainId"].empty() )
- di.id = std::stoi( result["PdnsDomainId"][0] );
+ if (result.count("PdnsDomainId") && !result["PdnsDomainId"].empty())
+ di.id = std::stoi(result["PdnsDomainId"][0]);
else
di.id = 0;
di.serial = sd.serial;
di.zone = DNSName(domain);
- if( result.count( "PdnsDomainLastCheck" ) && !result["PdnsDomainLastCheck"].empty() )
- di.last_check = pdns_stou( result["PdnsDomainLastCheck"][0] );
+ if (result.count("PdnsDomainLastCheck") && !result["PdnsDomainLastCheck"].empty())
+ di.last_check = pdns_stou(result["PdnsDomainLastCheck"][0]);
else
di.last_check = 0;
- if ( result.count( "PdnsDomainNotifiedSerial" ) && !result["PdnsDomainNotifiedSerial"].empty() )
- di.notified_serial = pdns_stou( result["PdnsDomainNotifiedSerial"][0] );
+ if (result.count("PdnsDomainNotifiedSerial") && !result["PdnsDomainNotifiedSerial"].empty())
+ di.notified_serial = pdns_stou(result["PdnsDomainNotifiedSerial"][0]);
else
di.notified_serial = 0;
- if ( result.count( "PdnsDomainMaster" ) && !result["PdnsDomainMaster"].empty() ) {
- for(const auto &m : result["PdnsDomainMaster"])
+ if (result.count("PdnsDomainMaster") && !result["PdnsDomainMaster"].empty()) {
+ for (const auto& m : result["PdnsDomainMaster"])
di.masters.emplace_back(m, 53);
}
- if ( result.count( "PdnsDomainType" ) && !result["PdnsDomainType"].empty() ) {
+ if (result.count("PdnsDomainType") && !result["PdnsDomainType"].empty()) {
string kind = result["PdnsDomainType"][0];
- if ( kind == "master" )
+ if (kind == "master")
di.kind = DomainInfo::Master;
- else if ( kind == "slave" )
+ else if (kind == "slave")
di.kind = DomainInfo::Slave;
else
di.kind = DomainInfo::Native;
#include "pdns/misc.hh"
#include <sys/time.h>
-
-PowerLDAP::SearchResult::SearchResult( int msgid, LDAP* ld )
- : d_ld( ld ), d_msgid( msgid ), d_finished( false )
+PowerLDAP::SearchResult::SearchResult(int msgid, LDAP* ld) :
+ d_ld(ld), d_msgid(msgid), d_finished(false)
{
}
-
PowerLDAP::SearchResult::~SearchResult()
{
- if ( !d_finished )
- ldap_abandon_ext( d_ld, d_msgid, NULL, NULL ); // We don't really care about the return code as there's
- // not much we can do now
+ if (!d_finished)
+ ldap_abandon_ext(d_ld, d_msgid, NULL, NULL); // We don't really care about the return code as there's
+ // not much we can do now
}
-
-bool PowerLDAP::SearchResult::getNext( PowerLDAP::sentry_t& entry, bool dn, int timeout )
+bool PowerLDAP::SearchResult::getNext(PowerLDAP::sentry_t& entry, bool dn, int timeout)
{
int i;
char* attr;
LDAPMessage* result = NULL;
LDAPMessage* object;
- while ( !d_finished && result == NULL ) {
- i = ldapWaitResult( d_ld, d_msgid, 5, &result );
- switch ( i ) {
- case -1:
- int err_code;
- ldapGetOption( d_ld, LDAP_OPT_ERROR_NUMBER, &err_code );
- if ( err_code == LDAP_SERVER_DOWN || err_code == LDAP_CONNECT_ERROR )
- throw LDAPNoConnection();
- else
- throw LDAPException( "Error waiting for LDAP result: " + ldapGetError( d_ld, err_code ) );
- break;
- case 0:
- throw LDAPTimeout();
- break;
- case LDAP_NO_SUCH_OBJECT:
- return false;
- case LDAP_RES_SEARCH_REFERENCE:
- ldap_msgfree( result );
- result = NULL;
- break;
- case LDAP_RES_SEARCH_RESULT:
- d_finished = true;
- ldap_msgfree( result );
- break;
- case LDAP_RES_SEARCH_ENTRY:
- // Yay!
- break;
+ while (!d_finished && result == NULL) {
+ i = ldapWaitResult(d_ld, d_msgid, 5, &result);
+ switch (i) {
+ case -1:
+ int err_code;
+ ldapGetOption(d_ld, LDAP_OPT_ERROR_NUMBER, &err_code);
+ if (err_code == LDAP_SERVER_DOWN || err_code == LDAP_CONNECT_ERROR)
+ throw LDAPNoConnection();
+ else
+ throw LDAPException("Error waiting for LDAP result: " + ldapGetError(d_ld, err_code));
+ break;
+ case 0:
+ throw LDAPTimeout();
+ break;
+ case LDAP_NO_SUCH_OBJECT:
+ return false;
+ case LDAP_RES_SEARCH_REFERENCE:
+ ldap_msgfree(result);
+ result = NULL;
+ break;
+ case LDAP_RES_SEARCH_RESULT:
+ d_finished = true;
+ ldap_msgfree(result);
+ break;
+ case LDAP_RES_SEARCH_ENTRY:
+ // Yay!
+ break;
}
}
- if ( d_finished )
+ if (d_finished)
return false;
- if( ( object = ldap_first_entry( d_ld, result ) ) == NULL )
- {
- ldap_msgfree( result );
- throw LDAPException( "Couldn't get first result entry: " + ldapGetError( d_ld, -1 ) );
+ if ((object = ldap_first_entry(d_ld, result)) == NULL) {
+ ldap_msgfree(result);
+ throw LDAPException("Couldn't get first result entry: " + ldapGetError(d_ld, -1));
}
entry.clear();
- if( dn )
- {
- attr = ldap_get_dn( d_ld, object );
- values.push_back( string( attr ) );
- ldap_memfree( attr );
+ if (dn) {
+ attr = ldap_get_dn(d_ld, object);
+ values.push_back(string(attr));
+ ldap_memfree(attr);
entry["dn"] = values;
}
- if( ( attr = ldap_first_attribute( d_ld, object, &ber ) ) != NULL )
- {
- do
- {
- if( ( berval = ldap_get_values_len( d_ld, object, attr ) ) != NULL )
- {
+ if ((attr = ldap_first_attribute(d_ld, object, &ber)) != NULL) {
+ do {
+ if ((berval = ldap_get_values_len(d_ld, object, attr)) != NULL) {
values.clear();
- for( i = 0; i < ldap_count_values_len( berval ); i++ )
- {
- values.push_back( berval[i]->bv_val ); // use berval[i]->bv_len for non string values?
+ for (i = 0; i < ldap_count_values_len(berval); i++) {
+ values.push_back(berval[i]->bv_val); // use berval[i]->bv_len for non string values?
}
entry[attr] = values;
- ldap_value_free_len( berval );
+ ldap_value_free_len(berval);
}
- ldap_memfree( attr );
- }
- while( ( attr = ldap_next_attribute( d_ld, object, ber ) ) != NULL );
+ ldap_memfree(attr);
+ } while ((attr = ldap_next_attribute(d_ld, object, ber)) != NULL);
- ber_free( ber, 0 );
+ ber_free(ber, 0);
}
- ldap_msgfree( result );
+ ldap_msgfree(result);
return true;
}
-
-void PowerLDAP::SearchResult::getAll( PowerLDAP::sresult_t& results, bool dn, int timeout )
+void PowerLDAP::SearchResult::getAll(PowerLDAP::sresult_t& results, bool dn, int timeout)
{
PowerLDAP::sentry_t entry;
- while( getNext( entry, dn, timeout ) )
- {
- results.push_back( entry );
+ while (getNext(entry, dn, timeout)) {
+ results.push_back(entry);
}
}
-
-PowerLDAP::PowerLDAP( const string& hosts, uint16_t port, bool tls, int timeout )
+PowerLDAP::PowerLDAP(const string& hosts, uint16_t port, bool tls, int timeout)
{
d_ld = 0;
d_hosts = hosts;
{
int err;
- if(d_ld) {
- ldap_unbind_ext( d_ld, NULL, NULL );
+ if (d_ld) {
+ ldap_unbind_ext(d_ld, NULL, NULL);
}
#ifdef HAVE_LDAP_INITIALIZE
- if( ( err = ldap_initialize( &d_ld, d_hosts.c_str() ) ) != LDAP_SUCCESS )
- {
+ if ((err = ldap_initialize(&d_ld, d_hosts.c_str())) != LDAP_SUCCESS) {
string ldapuris;
vector<string> uris;
- stringtok( uris, d_hosts );
+ stringtok(uris, d_hosts);
- for( size_t i = 0; i < uris.size(); i++ )
- {
+ for (size_t i = 0; i < uris.size(); i++) {
ldapuris += " ldap://" + uris[i];
}
- if( ( err = ldap_initialize( &d_ld, ldapuris.c_str() ) ) != LDAP_SUCCESS )
- {
- throw LDAPException( "Error initializing LDAP connection to '" + ldapuris + ": " + getError( err ) );
+ if ((err = ldap_initialize(&d_ld, ldapuris.c_str())) != LDAP_SUCCESS) {
+ throw LDAPException("Error initializing LDAP connection to '" + ldapuris + ": " + getError(err));
}
}
#else
- if( ( d_ld = ldap_init( d_hosts.c_str(), d_port ) ) == NULL )
- {
- throw LDAPException( "Error initializing LDAP connection to '" + d_hosts + "': " + string( strerror( errno ) ) );
+ if ((d_ld = ldap_init(d_hosts.c_str(), d_port)) == NULL) {
+ throw LDAPException("Error initializing LDAP connection to '" + d_hosts + "': " + string(strerror(errno)));
}
#endif
int protocol = LDAP_VERSION3;
- if( ldap_set_option( d_ld, LDAP_OPT_PROTOCOL_VERSION, &protocol ) != LDAP_OPT_SUCCESS )
- {
+ if (ldap_set_option(d_ld, LDAP_OPT_PROTOCOL_VERSION, &protocol) != LDAP_OPT_SUCCESS) {
protocol = LDAP_VERSION2;
- if( ldap_set_option( d_ld, LDAP_OPT_PROTOCOL_VERSION, &protocol ) != LDAP_OPT_SUCCESS )
- {
- ldap_unbind_ext( d_ld, NULL, NULL );
- throw LDAPException( "Couldn't set protocol version to LDAPv3 or LDAPv2" );
+ if (ldap_set_option(d_ld, LDAP_OPT_PROTOCOL_VERSION, &protocol) != LDAP_OPT_SUCCESS) {
+ ldap_unbind_ext(d_ld, NULL, NULL);
+ throw LDAPException("Couldn't set protocol version to LDAPv3 or LDAPv2");
}
}
- if( d_tls && ( err = ldap_start_tls_s( d_ld, NULL, NULL ) ) != LDAP_SUCCESS )
- {
- ldap_unbind_ext( d_ld, NULL, NULL );
- throw LDAPException( "Couldn't perform STARTTLS: " + getError( err ) );
+ if (d_tls && (err = ldap_start_tls_s(d_ld, NULL, NULL)) != LDAP_SUCCESS) {
+ ldap_unbind_ext(d_ld, NULL, NULL);
+ throw LDAPException("Couldn't perform STARTTLS: " + getError(err));
}
}
-
PowerLDAP::~PowerLDAP()
{
- ldap_unbind_ext( d_ld, NULL, NULL );
+ ldap_unbind_ext(d_ld, NULL, NULL);
}
-
bool PowerLDAP::connect()
{
- try
- {
+ try {
ensureConnect();
return true;
}
- catch( LDAPException &le )
- {
+ catch (LDAPException& le) {
return false;
}
}
-
-void PowerLDAP::setOption( int option, int value )
+void PowerLDAP::setOption(int option, int value)
{
- ldapSetOption( d_ld, option, (void*) &value );
+ ldapSetOption(d_ld, option, (void*)&value);
}
-
-void PowerLDAP::getOption( int option, int *value )
+void PowerLDAP::getOption(int option, int* value)
{
- ldapGetOption( d_ld, option, (void*) value );
+ ldapGetOption(d_ld, option, (void*)value);
}
-
-void PowerLDAP::bind( LdapAuthenticator* authenticator )
+void PowerLDAP::bind(LdapAuthenticator* authenticator)
{
- if ( !authenticator->authenticate( d_ld ) )
- throw LDAPException( "Failed to bind to LDAP server: " + authenticator->getError() );
+ if (!authenticator->authenticate(d_ld))
+ throw LDAPException("Failed to bind to LDAP server: " + authenticator->getError());
}
-
-void PowerLDAP::bind( const string& ldapbinddn, const string& ldapsecret, int method)
+void PowerLDAP::bind(const string& ldapbinddn, const string& ldapsecret, int method)
{
int msgid;
int rc;
struct berval passwd;
- passwd.bv_val = (char *)ldapsecret.c_str();
- passwd.bv_len = strlen( passwd.bv_val );
+ passwd.bv_val = (char*)ldapsecret.c_str();
+ passwd.bv_len = strlen(passwd.bv_val);
- if( ( rc = ldap_sasl_bind( d_ld, ldapbinddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid ) ) != LDAP_SUCCESS )
- {
- throw LDAPException( "Failed to bind to LDAP server: " + getError( rc ) );
+ if ((rc = ldap_sasl_bind(d_ld, ldapbinddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid)) != LDAP_SUCCESS) {
+ throw LDAPException("Failed to bind to LDAP server: " + getError(rc));
}
#else
- if( ( msgid = ldap_bind( d_ld, ldapbinddn.c_str(), ldapsecret.c_str(), method ) ) == -1 )
- {
- throw LDAPException( "Failed to bind to LDAP server: " + getError( msgid ) );
+ if ((msgid = ldap_bind(d_ld, ldapbinddn.c_str(), ldapsecret.c_str(), method)) == -1) {
+ throw LDAPException("Failed to bind to LDAP server: " + getError(msgid));
}
#endif
- ldapWaitResult( d_ld, msgid, d_timeout, NULL );
+ ldapWaitResult(d_ld, msgid, d_timeout, NULL);
}
-
/**
* Deprecated, use PowerLDAP::bind() instead
*/
-void PowerLDAP::simpleBind( const string& ldapbinddn, const string& ldapsecret )
+void PowerLDAP::simpleBind(const string& ldapbinddn, const string& ldapsecret)
{
- this->bind( ldapbinddn, ldapsecret, LDAP_AUTH_SIMPLE );
+ this->bind(ldapbinddn, ldapsecret, LDAP_AUTH_SIMPLE);
}
-
-void PowerLDAP::add( const string &dn, LDAPMod *mods[] )
+void PowerLDAP::add(const string& dn, LDAPMod* mods[])
{
int rc;
- rc = ldap_add_ext_s( d_ld, dn.c_str(), mods, NULL, NULL );
- if ( rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR )
+ rc = ldap_add_ext_s(d_ld, dn.c_str(), mods, NULL, NULL);
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
throw LDAPNoConnection();
- else if ( rc != LDAP_SUCCESS )
- throw LDAPException( "Error adding LDAP entry " + dn + ": " + getError( rc ) );
+ else if (rc != LDAP_SUCCESS)
+ throw LDAPException("Error adding LDAP entry " + dn + ": " + getError(rc));
}
-
-void PowerLDAP::modify( const string &dn, LDAPMod *mods[], LDAPControl **scontrols, LDAPControl **ccontrols )
+void PowerLDAP::modify(const string& dn, LDAPMod* mods[], LDAPControl** scontrols, LDAPControl** ccontrols)
{
int rc;
- rc = ldap_modify_ext_s( d_ld, dn.c_str(), mods, scontrols, ccontrols );
- if ( rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR )
+ rc = ldap_modify_ext_s(d_ld, dn.c_str(), mods, scontrols, ccontrols);
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
throw LDAPNoConnection();
- else if ( rc != LDAP_SUCCESS )
- throw LDAPException( "Error modifying LDAP entry " + dn + ": " + getError( rc ) );
+ else if (rc != LDAP_SUCCESS)
+ throw LDAPException("Error modifying LDAP entry " + dn + ": " + getError(rc));
}
-
-void PowerLDAP::del( const string& dn )
+void PowerLDAP::del(const string& dn)
{
int rc;
- rc = ldap_delete_ext_s( d_ld, dn.c_str(), NULL, NULL );
- if ( rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR )
+ rc = ldap_delete_ext_s(d_ld, dn.c_str(), NULL, NULL);
+ if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
throw LDAPNoConnection();
- else if ( rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT )
- throw LDAPException( "Error deleting LDAP entry " + dn + ": " + getError( rc ) );
+ else if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT)
+ throw LDAPException("Error deleting LDAP entry " + dn + ": " + getError(rc));
}
-
-PowerLDAP::SearchResult::Ptr PowerLDAP::search( const string& base, int scope, const string& filter, const char** attr )
+PowerLDAP::SearchResult::Ptr PowerLDAP::search(const string& base, int scope, const string& filter, const char** attr)
{
int msgid, rc;
- if ( ( rc = ldap_search_ext( d_ld, base.c_str(), scope, filter.c_str(), const_cast<char**> (attr), 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid ) ) ) {
- throw LDAPException( "Starting LDAP search: " + getError( rc ) );
+ if ((rc = ldap_search_ext(d_ld, base.c_str(), scope, filter.c_str(), const_cast<char**>(attr), 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid))) {
+ throw LDAPException("Starting LDAP search: " + getError(rc));
}
- return SearchResult::Ptr( new SearchResult( msgid, d_ld ) );
+ return SearchResult::Ptr(new SearchResult(msgid, d_ld));
}
-
/**
* Function waits for a result, returns its type and optionally stores the result.
* If the result is returned, the caller is responsible for freeing it with
* ldap_msgfree!
*/
-int PowerLDAP::waitResult( int msgid, LDAPMessage** result )
+int PowerLDAP::waitResult(int msgid, LDAPMessage** result)
{
- return ldapWaitResult( d_ld, msgid, d_timeout, result );
+ return ldapWaitResult(d_ld, msgid, d_timeout, result);
}
-
-bool PowerLDAP::getSearchEntry( int msgid, sentry_t& entry, bool dn )
+bool PowerLDAP::getSearchEntry(int msgid, sentry_t& entry, bool dn)
{
int i;
char* attr;
LDAPMessage* object;
bool hasResult = false;
- while ( !hasResult ) {
- i = waitResult( msgid, &result );
+ while (!hasResult) {
+ i = waitResult(msgid, &result);
// Here we deliberately ignore LDAP_RES_SEARCH_REFERENCE as we don't follow them.
// Instead we get the next result.
// If the function returned an error (i <= 0) we'll deal with after this loop too.
- if ( i == LDAP_RES_SEARCH_ENTRY || i == LDAP_RES_SEARCH_RESULT || i <= 0 )
+ if (i == LDAP_RES_SEARCH_ENTRY || i == LDAP_RES_SEARCH_RESULT || i <= 0)
hasResult = true;
}
- if ( i == -1 ) {
+ if (i == -1) {
// Error while retrieving the message
int err_code;
- ldapGetOption( d_ld, LDAP_OPT_ERROR_NUMBER, &err_code );
- if ( err_code == LDAP_SERVER_DOWN || err_code == LDAP_CONNECT_ERROR )
+ ldapGetOption(d_ld, LDAP_OPT_ERROR_NUMBER, &err_code);
+ if (err_code == LDAP_SERVER_DOWN || err_code == LDAP_CONNECT_ERROR)
throw LDAPNoConnection();
else
- throw LDAPException( "PowerLDAP::getSearchEntry(): Error when retrieving LDAP result: " + getError( err_code ) );
+ throw LDAPException("PowerLDAP::getSearchEntry(): Error when retrieving LDAP result: " + getError(err_code));
}
- if ( i == 0 ) {
+ if (i == 0) {
// Timeout expired before the message could be retrieved
throw LDAPTimeout();
}
- if ( i == LDAP_RES_SEARCH_RESULT ) {
+ if (i == LDAP_RES_SEARCH_RESULT) {
// We're done with this request
- ldap_msgfree( result );
+ ldap_msgfree(result);
return false;
}
- if( ( object = ldap_first_entry( d_ld, result ) ) == NULL )
- {
- ldap_msgfree( result );
- throw LDAPException( "Couldn't get first result entry: " + getError() );
+ if ((object = ldap_first_entry(d_ld, result)) == NULL) {
+ ldap_msgfree(result);
+ throw LDAPException("Couldn't get first result entry: " + getError());
}
entry.clear();
- if( dn )
- {
- attr = ldap_get_dn( d_ld, object );
- values.push_back( string( attr ) );
- ldap_memfree( attr );
+ if (dn) {
+ attr = ldap_get_dn(d_ld, object);
+ values.push_back(string(attr));
+ ldap_memfree(attr);
entry["dn"] = values;
}
- if( ( attr = ldap_first_attribute( d_ld, object, &ber ) ) != NULL )
- {
- do
- {
- if( ( berval = ldap_get_values_len( d_ld, object, attr ) ) != NULL )
- {
+ if ((attr = ldap_first_attribute(d_ld, object, &ber)) != NULL) {
+ do {
+ if ((berval = ldap_get_values_len(d_ld, object, attr)) != NULL) {
values.clear();
- for( i = 0; i < ldap_count_values_len( berval ); i++ )
- {
- values.push_back( berval[i]->bv_val ); // use berval[i]->bv_len for non string values?
+ for (i = 0; i < ldap_count_values_len(berval); i++) {
+ values.push_back(berval[i]->bv_val); // use berval[i]->bv_len for non string values?
}
entry[attr] = values;
- ldap_value_free_len( berval );
+ ldap_value_free_len(berval);
}
- ldap_memfree( attr );
- }
- while( ( attr = ldap_next_attribute( d_ld, object, ber ) ) != NULL );
+ ldap_memfree(attr);
+ } while ((attr = ldap_next_attribute(d_ld, object, ber)) != NULL);
- ber_free( ber, 0 );
+ ber_free(ber, 0);
}
- ldap_msgfree( result );
+ ldap_msgfree(result);
return true;
}
-
-void PowerLDAP::getSearchResults( int msgid, sresult_t& result, bool dn )
+void PowerLDAP::getSearchResults(int msgid, sresult_t& result, bool dn)
{
sentry_t entry;
result.clear();
- while( getSearchEntry( msgid, entry, dn ) )
- {
- result.push_back( entry );
+ while (getSearchEntry(msgid, entry, dn)) {
+ result.push_back(entry);
}
}
-
-const string PowerLDAP::getError( int rc )
+const string PowerLDAP::getError(int rc)
{
- return ldapGetError( d_ld, rc );
+ return ldapGetError(d_ld, rc);
}
-
-const string PowerLDAP::escape( const string& str )
+const string PowerLDAP::escape(const string& str)
{
string a;
string::const_iterator i;
char tmp[4];
- for( i = str.begin(); i != str.end(); i++ )
- {
- // RFC4515 3
- if( (unsigned char)*i == '*' ||
- (unsigned char)*i == '(' ||
- (unsigned char)*i == ')' ||
- (unsigned char)*i == '\\' ||
- (unsigned char)*i == '\0' ||
- (unsigned char)*i > 127)
- {
- snprintf(tmp, sizeof(tmp), "\\%02x", (unsigned char)*i);
-
- a += tmp;
- }
- else
- a += *i;
+ for (i = str.begin(); i != str.end(); i++) {
+ // RFC4515 3
+ if ((unsigned char)*i == '*' || (unsigned char)*i == '(' || (unsigned char)*i == ')' || (unsigned char)*i == '\\' || (unsigned char)*i == '\0' || (unsigned char)*i > 127) {
+ snprintf(tmp, sizeof(tmp), "\\%02x", (unsigned char)*i);
+
+ a += tmp;
+ }
+ else
+ a += *i;
}
return a;
class PowerLDAP
{
+ LDAP* d_ld;
+ string d_hosts;
+ int d_port;
+ bool d_tls;
+ int d_timeout;
+
+ const string getError(int rc = -1);
+ int waitResult(int msgid = LDAP_RES_ANY, LDAPMessage** result = NULL);
+ void ensureConnect();
+
+public:
+ typedef map<string, vector<string>> sentry_t;
+ typedef vector<sentry_t> sresult_t;
+
+ class SearchResult
+ {
LDAP* d_ld;
- string d_hosts;
- int d_port;
- bool d_tls;
- int d_timeout;
+ int d_msgid;
+ bool d_finished;
- const string getError( int rc = -1 );
- int waitResult( int msgid = LDAP_RES_ANY, LDAPMessage** result = NULL );
- void ensureConnect();
+ SearchResult(const SearchResult& other);
+ SearchResult& operator=(const SearchResult& other);
public:
- typedef map<string, vector<string> > sentry_t;
- typedef vector<sentry_t> sresult_t;
-
- class SearchResult {
- LDAP* d_ld;
- int d_msgid;
- bool d_finished;
-
- SearchResult( const SearchResult& other );
- SearchResult& operator=( const SearchResult& other );
-
- public:
- typedef std::unique_ptr<SearchResult> Ptr;
-
- SearchResult( int msgid, LDAP* ld );
- ~SearchResult();
-
- bool getNext( PowerLDAP::sentry_t& entry, bool dn = false, int timeout = 5 );
- void getAll( PowerLDAP::sresult_t& results, bool dn = false, int timeout = 5 );
- };
-
- PowerLDAP( const string& hosts, uint16_t port, bool tls, int timeout );
- ~PowerLDAP();
-
- bool connect();
-
- void getOption( int option, int* value );
- void setOption( int option, int value );
-
- void bind( LdapAuthenticator *authenticator );
- void bind( const string& ldapbinddn = "", const string& ldapsecret = "", int method = LDAP_AUTH_SIMPLE );
- void simpleBind( const string& ldapbinddn = "", const string& ldapsecret = "" );
- SearchResult::Ptr search( const string& base, int scope, const string& filter, const char** attr = 0 );
- void add( const string &dn, LDAPMod *mods[] );
- void modify( const string& dn, LDAPMod *mods[], LDAPControl **scontrols = 0, LDAPControl **ccontrols = 0 );
- void del( const string& dn );
-
- bool getSearchEntry( int msgid, sentry_t& entry, bool dn = false );
- void getSearchResults( int msgid, sresult_t& result, bool dn = false );
-
- static const string escape( const string& tobe );
-};
+ typedef std::unique_ptr<SearchResult> Ptr;
+
+ SearchResult(int msgid, LDAP* ld);
+ ~SearchResult();
+
+ bool getNext(PowerLDAP::sentry_t& entry, bool dn = false, int timeout = 5);
+ void getAll(PowerLDAP::sresult_t& results, bool dn = false, int timeout = 5);
+ };
+ PowerLDAP(const string& hosts, uint16_t port, bool tls, int timeout);
+ ~PowerLDAP();
+
+ bool connect();
+
+ void getOption(int option, int* value);
+ void setOption(int option, int value);
+
+ void bind(LdapAuthenticator* authenticator);
+ void bind(const string& ldapbinddn = "", const string& ldapsecret = "", int method = LDAP_AUTH_SIMPLE);
+ void simpleBind(const string& ldapbinddn = "", const string& ldapsecret = "");
+ SearchResult::Ptr search(const string& base, int scope, const string& filter, const char** attr = 0);
+ void add(const string& dn, LDAPMod* mods[]);
+ void modify(const string& dn, LDAPMod* mods[], LDAPControl** scontrols = 0, LDAPControl** ccontrols = 0);
+ void del(const string& dn);
+
+ bool getSearchEntry(int msgid, sentry_t& entry, bool dn = false);
+ void getSearchResults(int msgid, sresult_t& result, bool dn = false);
+
+ static const string escape(const string& tobe);
+};
using std::string;
using std::vector;
-
-inline string ptr2ip4( vector<string>& parts )
+inline string ptr2ip4(vector<string>& parts)
{
string ip;
parts.pop_back();
parts.pop_back();
-
ip = parts.back();
parts.pop_back();
- while( !parts.empty() )
- {
+ while (!parts.empty()) {
ip += "." + parts.back();
parts.pop_back();
}
return ip;
}
-
-inline string ptr2ip6( vector<string>& parts )
+inline string ptr2ip6(vector<string>& parts)
{
int i = 0;
string ip;
-
parts.pop_back();
parts.pop_back();
- while( i < 3 && parts.size() > 1 && parts.back() == "0" )
- {
+ while (i < 3 && parts.size() > 1 && parts.back() == "0") {
parts.pop_back();
i++;
}
- while( i++ < 4 && !parts.empty() )
- {
+ while (i++ < 4 && !parts.empty()) {
ip += parts.back();
parts.pop_back();
}
- while( !parts.empty() )
- {
+ while (!parts.empty()) {
i = 0;
ip += ":";
- while( i < 3 && parts.size() > 1 && parts.back() == "0" )
- {
+ while (i < 3 && parts.size() > 1 && parts.back() == "0") {
parts.pop_back();
i++;
}
- while( i++ < 4 && !parts.empty() )
- {
+ while (i++ < 4 && !parts.empty()) {
ip += parts.back();
parts.pop_back();
}
return ip;
}
-
-inline string ip2ptr4( const string& ip )
+inline string ip2ptr4(const string& ip)
{
string ptr;
vector<string> parts;
- stringtok( parts, ip, "." );
- while( !parts.empty() )
- {
- ptr += parts.back() + ".";
+ stringtok(parts, ip, ".");
+ while (!parts.empty()) {
+ ptr += parts.back() + ".";
parts.pop_back();
}
return ptr + "in-addr.arpa";
}
-
-inline string ip2ptr6( const string& ip )
+inline string ip2ptr6(const string& ip)
{
string ptr, part, defstr;
vector<string> parts;
- stringtok( parts, ip, ":" );
- while( !parts.empty() )
- {
+ stringtok(parts, ip, ":");
+ while (!parts.empty()) {
defstr = "0.0.0.0.";
part = parts.back();
- while( part.length() < 4 )
- {
+ while (part.length() < 4) {
part = "0" + part;
}
return ptr + "ip6.arpa";
}
-
-inline string strbind( const string& search, const string& replace, string subject )
+inline string strbind(const string& search, const string& replace, string subject)
{
size_t pos = 0;
-
- while( ( pos = subject.find( search, pos ) ) != string::npos )
- {
- subject.replace( pos, search.size(), replace );
+ while ((pos = subject.find(search, pos)) != string::npos) {
+ subject.replace(pos, search.size(), replace);
pos += replace.size();
}
* Convert a LDAP time string to a time_t. Return 0 if unable to convert
*/
-inline time_t str2tstamp( const string& str )
+inline time_t str2tstamp(const string& str)
{
char* tmp;
struct tm tm;
- tmp = strptime( str.c_str(), "%Y%m%d%H%M%SZ", &tm );
+ tmp = strptime(str.c_str(), "%Y%m%d%H%M%SZ", &tm);
- if( tmp != NULL && *tmp == 0 )
- {
- return Utility::timegm( &tm );
+ if (tmp != NULL && *tmp == 0) {
+ return Utility::timegm(&tm);
}
return 0;
}
-
throw std::runtime_error("LMDB backend does not suport multiple instances");
}
- setArgPrefix("lmdb"+suffix);
-
+ setArgPrefix("lmdb" + suffix);
+
string syncMode = toLower(getArg("sync-mode"));
- if(syncMode == "nosync")
+ if (syncMode == "nosync")
d_asyncFlag = MDB_NOSYNC;
- else if(syncMode == "nometasync")
+ else if (syncMode == "nometasync")
d_asyncFlag = MDB_NOMETASYNC;
- else if(syncMode == "mapasync")
+ else if (syncMode == "mapasync")
d_asyncFlag = MDB_MAPASYNC;
- else if(syncMode.empty() || syncMode == "sync")
+ else if (syncMode.empty() || syncMode == "sync")
d_asyncFlag = 0;
else
- throw std::runtime_error("Unknown sync mode "+syncMode+" requested for LMDB backend");
+ throw std::runtime_error("Unknown sync mode " + syncMode + " requested for LMDB backend");
d_tdomains = std::make_shared<tdomains_t>(getMDBEnv(getArg("filename").c_str(), MDB_NOSUBDIR | d_asyncFlag, 0600), "domains");
d_tmeta = std::make_shared<tmeta_t>(d_tdomains->getEnv(), "metadata");
d_tkdb = std::make_shared<tkdb_t>(d_tdomains->getEnv(), "keydata");
d_ttsig = std::make_shared<ttsig_t>(d_tdomains->getEnv(), "tsig");
-
+
auto pdnsdbi = d_tdomains->getEnv()->openDB("pdns", MDB_CREATE);
if (s_first) {
uint32_t schemaversion = 1;
MDBOutVal _schemaversion;
- if(!txn->get(pdnsdbi, "schemaversion", _schemaversion)) {
+ if (!txn->get(pdnsdbi, "schemaversion", _schemaversion)) {
schemaversion = _schemaversion.get<uint32_t>();
}
if (schemaversion != SCHEMAVERSION) {
if (getArgAsNum("schema-version") != SCHEMAVERSION) {
- throw std::runtime_error("Expected LMDB schema version "+std::to_string(SCHEMAVERSION)+" but got "+std::to_string(schemaversion));
+ throw std::runtime_error("Expected LMDB schema version " + std::to_string(SCHEMAVERSION) + " but got " + std::to_string(schemaversion));
}
txn->put(pdnsdbi, "schemaversion", SCHEMAVERSION);
}
MDBOutVal shards;
- if(!txn->get(pdnsdbi, "shards", shards)) {
+ if (!txn->get(pdnsdbi, "shards", shards)) {
s_shards = shards.get<uint32_t>();
- if(s_shards != atoi(getArg("shards").c_str())) {
- g_log << Logger::Warning<<"Note: configured number of lmdb shards ("<<atoi(getArg("shards").c_str())<<") is different from on-disk ("<<s_shards<<"). Using on-disk shard number"<<endl;
+ if (s_shards != atoi(getArg("shards").c_str())) {
+ g_log << Logger::Warning << "Note: configured number of lmdb shards (" << atoi(getArg("shards").c_str()) << ") is different from on-disk (" << s_shards << "). Using on-disk shard number" << endl;
}
}
else {
if (schemaversion < 3) {
if (!upgradeToSchemav3()) {
- throw std::runtime_error("Failed to perform LMDB schema version upgrade to "+std::to_string(SCHEMAVERSION)+" from "+std::to_string(schemaversion));
+ throw std::runtime_error("Failed to perform LMDB schema version upgrade to " + std::to_string(SCHEMAVERSION) + " from " + std::to_string(schemaversion));
}
}
s_first = false;
d_dolog = ::arg().mustDo("query-logging");
}
-
-
-namespace boost {
-namespace serialization {
-
-template<class Archive>
-void save(Archive & ar, const DNSName& g, const unsigned int version)
+namespace boost
{
- if(!g.empty()) {
- std::string tmp = g.toDNSStringLC(); // g++ 4.8 woes
- ar & tmp;
- }
- else
- ar & "";
-}
-
-template<class Archive>
-void load(Archive & ar, DNSName& g, const unsigned int version)
+namespace serialization
{
- string tmp;
- ar & tmp;
- if(tmp.empty())
- g = DNSName();
- else
- g = DNSName(tmp.c_str(), tmp.size(), 0, false);
-}
-template<class Archive>
-void save(Archive & ar, const QType& g, const unsigned int version)
-{
- uint16_t tmp = g.getCode(); // g++ 4.8 woes
- ar & tmp;
-}
+ template <class Archive>
+ void save(Archive& ar, const DNSName& g, const unsigned int version)
+ {
+ if (!g.empty()) {
+ std::string tmp = g.toDNSStringLC(); // g++ 4.8 woes
+ ar& tmp;
+ }
+ else
+ ar & "";
+ }
-template<class Archive>
-void load(Archive & ar, QType& g, const unsigned int version)
-{
- uint16_t tmp;
- ar & tmp;
- g = QType(tmp);
-}
-
-template<class Archive>
-void serialize(Archive & ar, DomainInfo& g, const unsigned int version)
-{
- ar & g.zone;
- ar & g.last_check;
- ar & g.account;
- ar & g.masters;
- ar & g.id;
- ar & g.notified_serial;
- ar & g.kind;
-}
+ template <class Archive>
+ void load(Archive& ar, DNSName& g, const unsigned int version)
+ {
+ string tmp;
+ ar& tmp;
+ if (tmp.empty())
+ g = DNSName();
+ else
+ g = DNSName(tmp.c_str(), tmp.size(), 0, false);
+ }
-template<class Archive>
-void serialize(Archive & ar, LMDBBackend::DomainMeta& g, const unsigned int version)
-{
- ar & g.domain & g.key & g.value;
-}
+ template <class Archive>
+ void save(Archive& ar, const QType& g, const unsigned int version)
+ {
+ uint16_t tmp = g.getCode(); // g++ 4.8 woes
+ ar& tmp;
+ }
-template<class Archive>
-void save(Archive & ar, const LMDBBackend::KeyDataDB& g, const unsigned int version)
-{
- ar & g.domain & g.content & g.flags & g.active & g.published;
-}
+ template <class Archive>
+ void load(Archive& ar, QType& g, const unsigned int version)
+ {
+ uint16_t tmp;
+ ar& tmp;
+ g = QType(tmp);
+ }
-template<class Archive>
-void load(Archive & ar, LMDBBackend::KeyDataDB& g, const unsigned int version)
-{
- ar & g.domain & g.content & g.flags & g.active;
- if (version >= 1) {
- ar & g.published;
- } else {
- g.published = true;
+ template <class Archive>
+ void serialize(Archive& ar, DomainInfo& g, const unsigned int version)
+ {
+ ar& g.zone;
+ ar& g.last_check;
+ ar& g.account;
+ ar& g.masters;
+ ar& g.id;
+ ar& g.notified_serial;
+ ar& g.kind;
}
-}
+ template <class Archive>
+ void serialize(Archive& ar, LMDBBackend::DomainMeta& g, const unsigned int version)
+ {
+ ar& g.domain& g.key& g.value;
+ }
-template<class Archive>
-void serialize(Archive & ar, TSIGKey& g, const unsigned int version)
-{
- ar & g.name;
- ar & g.algorithm; // this is the ordername
- ar & g.key;
-}
+ template <class Archive>
+ void save(Archive& ar, const LMDBBackend::KeyDataDB& g, const unsigned int version)
+ {
+ ar& g.domain& g.content& g.flags& g.active& g.published;
+ }
+
+ template <class Archive>
+ void load(Archive& ar, LMDBBackend::KeyDataDB& g, const unsigned int version)
+ {
+ ar& g.domain& g.content& g.flags& g.active;
+ if (version >= 1) {
+ ar& g.published;
+ }
+ else {
+ g.published = true;
+ }
+ }
+ template <class Archive>
+ void serialize(Archive& ar, TSIGKey& g, const unsigned int version)
+ {
+ ar& g.name;
+ ar& g.algorithm; // this is the ordername
+ ar& g.key;
+ }
-
} // namespace serialization
} // namespace boost
BOOST_SERIALIZATION_SPLIT_FREE(LMDBBackend::KeyDataDB);
BOOST_IS_BITWISE_SERIALIZABLE(ComboAddress);
-template<>
+template <>
std::string serToString(const DNSResourceRecord& rr)
{
// only does content, ttl, auth
std::string ret;
uint16_t len = rr.content.length();
- ret.reserve(2+len+8);
-
+ ret.reserve(2 + len + 8);
+
ret.assign((const char*)&len, 2);
ret += rr.content;
ret.append((const char*)&rr.ttl, 4);
return ret;
}
-template<>
+template <>
std::string serToString(const vector<DNSResourceRecord>& rrs)
{
std::string ret;
- for(const auto& rr: rrs) {
+ for (const auto& rr : rrs) {
ret += serToString(rr);
}
{
uint16_t len;
memcpy(&len, &str[0], 2);
- rr.content.assign(&str[2], len); // len bytes
+ rr.content.assign(&str[2], len); // len bytes
memcpy(&rr.ttl, &str[2] + len, 4);
rr.auth = str[2 + len + 4];
rr.disabled = str[2 + len + 4 + 2];
return 2 + len + 7;
}
-template<>
+template <>
void serFromString(const string_view& str, DNSResourceRecord& rr)
{
serOneRRFromString(str, rr);
}
-template<>
+template <>
void serFromString(const string_view& str, vector<DNSResourceRecord>& rrs)
{
auto str_copy = str;
static std::shared_ptr<DNSRecordContent> deserializeContentZR(uint16_t qtype, const DNSName& qname, const std::string& content)
{
- if(qtype == QType::A && content.size() == 4) {
+ if (qtype == QType::A && content.size() == 4) {
return std::make_shared<ARecordContent>(*((uint32_t*)content.c_str()));
}
return DNSRecordContent::deserialize(qname, qtype, content);
}
-
/* design. If you ask a question without a zone id, we lookup the best
zone id for you, and answer from that. This is different than other backends, but I can't see why it would not work.
auto cursor = txn.txn->getCursor(txn.db->dbi);
MDBOutVal key, val;
// cout<<"Match: "<<makeHexDump(match);
- if(!cursor.lower_bound(match, key, val) ) {
- while(key.get<StringView>().rfind(match, 0) == 0) {
- if(qtype == QType::ANY || co.getQType(key.get<StringView>()) == qtype)
+ if (!cursor.lower_bound(match, key, val)) {
+ while (key.get<StringView>().rfind(match, 0) == 0) {
+ if (qtype == QType::ANY || co.getQType(key.get<StringView>()) == qtype)
cursor.del();
- if(cursor.next(key, val)) break;
- }
+ if (cursor.next(key, val))
+ break;
+ }
}
}
*/
-bool LMDBBackend::startTransaction(const DNSName &domain, int domain_id)
+bool LMDBBackend::startTransaction(const DNSName& domain, int domain_id)
{
// cout <<"startTransaction("<<domain<<", "<<domain_id<<")"<<endl;
int real_id = domain_id;
- if(real_id < 0) {
+ if (real_id < 0) {
auto rotxn = d_tdomains->getROTransaction();
DomainInfo di;
real_id = rotxn.get<0>(domain, di);
// cout<<"real_id = "<<real_id << endl;
- if(!real_id)
+ if (!real_id)
return false;
}
- if(d_rwtxn) {
+ if (d_rwtxn) {
throw DBException("Attempt to start a transaction while one was open already");
}
d_rwtxn = getRecordsRWTransaction(real_id);
-
+
d_transactiondomain = domain;
d_transactiondomainid = real_id;
- if(domain_id >= 0) {
+ if (domain_id >= 0) {
deleteDomainRecords(*d_rwtxn, domain_id);
}
}
// d_rwtxn must be set here
-bool LMDBBackend::feedRecord(const DNSResourceRecord &r, const DNSName &ordername, bool ordernameIsNSEC3)
+bool LMDBBackend::feedRecord(const DNSResourceRecord& r, const DNSName& ordername, bool ordernameIsNSEC3)
{
DNSResourceRecord rr(r);
rr.qname.makeUsRelative(d_transactiondomain);
string rrs;
MDBOutVal _rrs;
- if(!d_rwtxn->txn->get(d_rwtxn->db->dbi, matchName, _rrs)) {
+ if (!d_rwtxn->txn->get(d_rwtxn->db->dbi, matchName, _rrs)) {
rrs = _rrs.get<string>();
}
-
+
rrs += serToString(rr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, matchName, rrs);
- if(ordernameIsNSEC3 && !ordername.empty()) {
+ if (ordernameIsNSEC3 && !ordername.empty()) {
MDBOutVal val;
- if(d_rwtxn->txn->get(d_rwtxn->db->dbi, co(r.domain_id, rr.qname, QType::NSEC3), val)) {
+ if (d_rwtxn->txn->get(d_rwtxn->db->dbi, co(r.domain_id, rr.qname, QType::NSEC3), val)) {
rr.ttl = 0;
- rr.content=rr.qname.toDNSStringLC();
+ rr.content = rr.qname.toDNSStringLC();
rr.auth = 0;
string ser = serToString(rr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(r.domain_id, ordername, QType::NSEC3), ser);
return true;
}
-bool LMDBBackend::feedEnts(int domain_id, map<DNSName,bool>& nonterm)
+bool LMDBBackend::feedEnts(int domain_id, map<DNSName, bool>& nonterm)
{
DNSResourceRecord rr;
rr.ttl = 0;
compoundOrdername co;
- for(const auto& nt: nonterm) {
+ for (const auto& nt : nonterm) {
rr.qname = nt.first.makeRelative(d_transactiondomain);
rr.auth = nt.second;
rr.disabled = true;
return true;
}
-bool LMDBBackend::feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bool> &nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow)
+bool LMDBBackend::feedEnts3(int domain_id, const DNSName& domain, map<DNSName, bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow)
{
string ser;
DNSName ordername;
DNSResourceRecord rr;
compoundOrdername co;
- for(const auto& nt: nonterm) {
+ for (const auto& nt : nonterm) {
rr.qname = nt.first.makeRelative(domain);
rr.ttl = 0;
rr.auth = nt.second;
ser = serToString(rr);
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, rr.qname, 0), ser);
- if(!narrow && rr.auth) {
+ if (!narrow && rr.auth) {
rr.content = rr.qname.toDNSString();
rr.auth = false;
rr.disabled = false;
ser = serToString(rr);
- ordername=DNSName(toBase32Hex(hashQNameWithSalt(ns3prc, nt.first)));
+ ordername = DNSName(toBase32Hex(hashQNameWithSalt(ns3prc, nt.first)));
d_rwtxn->txn->put(d_rwtxn->db->dbi, co(domain_id, ordername, QType::NSEC3), ser);
rr.ttl = 1;
return true;
}
-
// might be called within a transaction, might also be called alone
bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
{
// zonk qname/qtype within domain_id (go through qname, check domain_id && qtype)
shared_ptr<RecordsRWTransaction> txn;
bool needCommit = false;
- if(d_rwtxn && d_transactiondomainid==domain_id) {
+ if (d_rwtxn && d_transactiondomainid == domain_id) {
txn = d_rwtxn;
// cout<<"Reusing open transaction"<<endl;
}
compoundOrdername co;
auto cursor = txn->txn->getCursor(txn->db->dbi);
MDBOutVal key, val;
- string match =co(domain_id, qname.makeRelative(di.zone), qt.getCode());
- if(!cursor.find(match, key, val)) {
+ string match = co(domain_id, qname.makeRelative(di.zone), qt.getCode());
+ if (!cursor.find(match, key, val)) {
cursor.del();
}
- if(!rrset.empty()) {
+ if (!rrset.empty()) {
vector<DNSResourceRecord> adjustedRRSet;
- for(auto rr : rrset) {
+ for (auto rr : rrset) {
rr.content = serializeContent(rr.qtype.getCode(), rr.qname, rr.content);
rr.qname.makeUsRelative(di.zone);
adjustedRRSet.push_back(rr);
txn->txn->put(txn->db->dbi, match, serToString(adjustedRRSet));
}
- if(needCommit)
+ if (needCommit)
txn->txn->commit();
return true;
// tempting to templatize these two functions but the pain is not worth it
std::shared_ptr<LMDBBackend::RecordsRWTransaction> LMDBBackend::getRecordsRWTransaction(uint32_t id)
{
- auto& shard =d_trecords[id % s_shards];
- if(!shard.env) {
- shard.env = getMDBEnv( (getArg("filename")+"-"+std::to_string(id % s_shards)).c_str(),
- MDB_NOSUBDIR | d_asyncFlag, 0600);
+ auto& shard = d_trecords[id % s_shards];
+ if (!shard.env) {
+ shard.env = getMDBEnv((getArg("filename") + "-" + std::to_string(id % s_shards)).c_str(),
+ MDB_NOSUBDIR | d_asyncFlag, 0600);
shard.dbi = shard.env->openDB("records", MDB_CREATE);
}
auto ret = std::make_shared<RecordsRWTransaction>(shard.env->getRWTransaction());
std::shared_ptr<LMDBBackend::RecordsROTransaction> LMDBBackend::getRecordsROTransaction(uint32_t id, std::shared_ptr<LMDBBackend::RecordsRWTransaction> rwtxn)
{
- auto& shard =d_trecords[id % s_shards];
- if(!shard.env) {
+ auto& shard = d_trecords[id % s_shards];
+ if (!shard.env) {
if (rwtxn) {
throw DBException("attempting to start nested transaction without open parent env");
}
- shard.env = getMDBEnv( (getArg("filename")+"-"+std::to_string(id % s_shards)).c_str(),
- MDB_NOSUBDIR | d_asyncFlag, 0600);
+ shard.env = getMDBEnv((getArg("filename") + "-" + std::to_string(id % s_shards)).c_str(),
+ MDB_NOSUBDIR | d_asyncFlag, 0600);
shard.dbi = shard.env->openDB("records", MDB_CREATE);
}
-
+
if (rwtxn) {
auto ret = std::make_shared<RecordsROTransaction>(rwtxn->txn->getROTransaction());
ret->db = std::make_shared<RecordsDB>(shard);
return ret;
- } else {
+ }
+ else {
auto ret = std::make_shared<RecordsROTransaction>(shard.env->getROTransaction());
ret->db = std::make_shared<RecordsDB>(shard);
return ret;
bool LMDBBackend::upgradeToSchemav3()
{
- g_log << Logger::Warning<<"Upgrading LMDB schema"<<endl;
-
- for(auto i = 0; i < s_shards; i++) {
- string filename = getArg("filename")+"-"+std::to_string(i);
- if (rename(filename.c_str(), (filename+"-old").c_str()) < 0) {
- if (errno == ENOENT) {
- // apparently this shard doesn't exist yet, moving on
- continue;
- }
- unixDie("Rename failed during LMDB upgrade");
+ g_log << Logger::Warning << "Upgrading LMDB schema" << endl;
+
+ for (auto i = 0; i < s_shards; i++) {
+ string filename = getArg("filename") + "-" + std::to_string(i);
+ if (rename(filename.c_str(), (filename + "-old").c_str()) < 0) {
+ if (errno == ENOENT) {
+ // apparently this shard doesn't exist yet, moving on
+ continue;
+ }
+ unixDie("Rename failed during LMDB upgrade");
}
LMDBBackend::RecordsDB oldShard, newShard;
- oldShard.env = getMDBEnv( (filename+"-old").c_str(),
- MDB_NOSUBDIR | d_asyncFlag, 0600);
+ oldShard.env = getMDBEnv((filename + "-old").c_str(),
+ MDB_NOSUBDIR | d_asyncFlag, 0600);
oldShard.dbi = oldShard.env->openDB("records", MDB_CREATE | MDB_DUPSORT);
- auto txn = oldShard.env->getROTransaction();
+ auto txn = oldShard.env->getROTransaction();
auto cursor = txn->getROCursor(oldShard.dbi);
- newShard.env = getMDBEnv( (filename).c_str(),
- MDB_NOSUBDIR | d_asyncFlag, 0600);
+ newShard.env = getMDBEnv((filename).c_str(),
+ MDB_NOSUBDIR | d_asyncFlag, 0600);
newShard.dbi = newShard.env->openDB("records", MDB_CREATE);
- auto newTxn = newShard.env->getRWTransaction();
+ auto newTxn = newShard.env->getRWTransaction();
MDBOutVal key, val;
if (cursor.first(key, val) != 0) {
}
string_view currentKey;
string value;
- for(;;) {
+ for (;;) {
auto newKey = key.get<string_view>();
if (currentKey.compare(newKey) != 0) {
if (value.size() > 0) {
value = "";
}
value += val.get<string>();
- if (cursor.next(key, val) != 0){
+ if (cursor.next(key, val) != 0) {
if (value.size() > 0) {
newTxn->put(newShard.dbi, currentKey, value);
}
return true;
}
-bool LMDBBackend::deleteDomain(const DNSName &domain)
+bool LMDBBackend::deleteDomain(const DNSName& domain)
{
auto doms = d_tdomains->getRWTransaction();
DomainInfo di;
- auto id = doms.get<0>(domain, di);
- if(!id)
+ auto id = doms.get<0>(domain, di);
+ if (!id)
return false;
-
+
shared_ptr<RecordsRWTransaction> txn;
bool needCommit = false;
- if(d_rwtxn && d_transactiondomainid == id) {
+ if (d_rwtxn && d_transactiondomainid == id) {
txn = d_rwtxn;
// cout<<"Reusing open transaction"<<endl;
}
needCommit = true;
}
-
doms.del(id);
compoundOrdername co;
- string match=co(id);
+ string match = co(id);
auto cursor = txn->txn->getCursor(txn->db->dbi);
MDBOutVal key, val;
- if(!cursor.find(match, key, val)) {
+ if (!cursor.find(match, key, val)) {
do {
cursor.del();
- } while(!cursor.next(key, val) && key.get<StringView>().rfind(match, 0) == 0);
+ } while (!cursor.next(key, val) && key.get<StringView>().rfind(match, 0) == 0);
}
- if(needCommit)
+ if (needCommit)
txn->txn->commit();
-
+
doms.commit();
return true;
}
-bool LMDBBackend::list(const DNSName &target, int id, bool include_disabled)
+bool LMDBBackend::list(const DNSName& target, int id, bool include_disabled)
{
DomainInfo di;
{
auto dtxn = d_tdomains->getROTransaction();
- if((di.id = dtxn.get<0>(target, di)))
+ if ((di.id = dtxn.get<0>(target, di)))
; // cout<<"Found domain "<<target<<" on domain_id "<<di.id <<", list requested "<<id<<endl;
else {
// cout<<"Did not find "<<target<<endl;
d_matchkey = co(di.id);
MDBOutVal key, val;
- if(d_getcursor->lower_bound(d_matchkey, key, val) || key.get<StringView>().rfind(d_matchkey, 0) != 0) {
+ if (d_getcursor->lower_bound(d_matchkey, key, val) || key.get<StringView>().rfind(d_matchkey, 0) != 0) {
// cout<<"Found nothing for list"<<endl;
d_getcursor.reset();
}
return true;
}
-void LMDBBackend::lookup(const QType &type, const DNSName &qdomain, int zoneId, DNSPacket *p)
+void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p)
{
- if(d_dolog) {
- g_log << Logger::Warning << "Got lookup for "<<qdomain<<"|"<<type.getName()<<" in zone "<< zoneId<<endl;
+ if (d_dolog) {
+ g_log << Logger::Warning << "Got lookup for " << qdomain << "|" << type.getName() << " in zone " << zoneId << endl;
d_dtime.set();
}
DNSName hunt(qdomain);
DomainInfo di;
- if(zoneId < 0) {
+ if (zoneId < 0) {
auto rotxn = d_tdomains->getROTransaction();
-
+
do {
zoneId = rotxn.get<0>(hunt, di);
} while (!zoneId && type != QType::SOA && hunt.chopOff());
- if(zoneId <= 0) {
+ if (zoneId <= 0) {
// cout << "Did not find zone for "<< qdomain<<endl;
d_getcursor.reset();
return;
}
}
else {
- if(!d_tdomains->getROTransaction().get(zoneId, di)) {
+ if (!d_tdomains->getROTransaction().get(zoneId, di)) {
// cout<<"Could not find a zone with id "<<zoneId<<endl;
d_getcursor.reset();
return;
}
hunt = di.zone;
}
-
+
DNSName relqname = qdomain.makeRelative(hunt);
// cout<<"get will look for "<<relqname<< " in zone "<<hunt<<" with id "<<zoneId<<" and type "<<type.getName()<<endl;
d_rotxn = getRecordsROTransaction(zoneId, d_rwtxn);
compoundOrdername co;
d_getcursor = std::make_shared<MDBROCursor>(d_rotxn->txn->getCursor(d_rotxn->db->dbi));
MDBOutVal key, val;
- if(type.getCode() == QType::ANY) {
+ if (type.getCode() == QType::ANY) {
d_matchkey = co(zoneId, relqname);
}
else {
- d_matchkey= co(zoneId, relqname, type.getCode());
+ d_matchkey = co(zoneId, relqname, type.getCode());
}
-
- if(d_getcursor->lower_bound(d_matchkey, key, val) || key.get<StringView>().rfind(d_matchkey, 0) != 0) {
+
+ if (d_getcursor->lower_bound(d_matchkey, key, val) || key.get<StringView>().rfind(d_matchkey, 0) != 0) {
d_getcursor.reset();
- if(d_dolog) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" usec to execute (found nothing)"<<endl;
+ if (d_dolog) {
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute (found nothing)" << endl;
}
return;
}
-
- if(d_dolog) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" usec to execute"<<endl;
+
+ if (d_dolog) {
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl;
}
d_lookupdomain = hunt;
d_currentrrsetpos = 0;
}
-
bool LMDBBackend::get(DNSZoneRecord& rr)
{
- for(;;) {
- if(!d_getcursor) {
+ for (;;) {
+ if (!d_getcursor) {
d_rotxn.reset();
return false;
}
key = d_currentKey.get<string_view>();
rr.dr.d_type = compoundOrdername::getQType(key).getCode();
- if(rr.dr.d_type == QType::NSEC3) {
+ if (rr.dr.d_type == QType::NSEC3) {
// Hit a magic NSEC3 skipping
- if(d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.get<StringView>().rfind(d_matchkey, 0) != 0) {
+ if (d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.get<StringView>().rfind(d_matchkey, 0) != 0) {
d_getcursor.reset();
}
continue;
serFromString(d_currentVal.get<string>(), d_currentrrset);
d_currentrrsetpos = 0;
- } else {
+ }
+ else {
key = d_currentKey.get<string_view>();
}
rr.dr.d_content = deserializeContentZR(rr.dr.d_type, rr.dr.d_name, drr.content);
rr.auth = drr.auth;
- if(d_currentrrsetpos >= d_currentrrset.size()) {
+ if (d_currentrrsetpos >= d_currentrrset.size()) {
d_currentrrset.clear();
- if(d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.get<StringView>().rfind(d_matchkey, 0) != 0) {
+ if (d_getcursor->next(d_currentKey, d_currentVal) || d_currentKey.get<StringView>().rfind(d_matchkey, 0) != 0) {
d_getcursor.reset();
}
}
- } catch (const std::exception &e) {
+ }
+ catch (const std::exception& e) {
throw PDNSException(e.what());
}
return true;
}
-
bool LMDBBackend::get(DNSResourceRecord& rr)
{
DNSZoneRecord dzr;
- if(!get(dzr)) {
+ if (!get(dzr)) {
return false;
}
return true;
}
-
-bool LMDBBackend::getDomainInfo(const DNSName &domain, DomainInfo &di, bool getSerial)
+bool LMDBBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
{
auto txn = d_tdomains->getROTransaction();
- if(!(di.id=txn.get<0>(domain, di)))
+ if (!(di.id = txn.get<0>(domain, di)))
return false;
di.backend = this;
di.serial = 0;
- if(getSerial) {
+ if (getSerial) {
auto txn2 = getRecordsROTransaction(di.id);
compoundOrdername co;
MDBOutVal val;
- if(!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
+ if (!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
DNSResourceRecord rr;
serFromString(val.get<string_view>(), rr);
- if(rr.content.size() >= 5 * sizeof(uint32_t)) {
+ if (rr.content.size() >= 5 * sizeof(uint32_t)) {
uint32_t serial;
// a SOA has five 32 bit fields, the first of which is the serial
// there are two variable length names before the serial, so we calculate from the back
return true;
}
-
int LMDBBackend::genChangeDomain(const DNSName& domain, std::function<void(DomainInfo&)> func)
{
auto txn = d_tdomains->getRWTransaction();
auto id = txn.get<0>(domain, di);
func(di);
txn.put(di, id);
-
+
txn.commit();
return true;
}
auto txn = d_tdomains->getRWTransaction();
- if(!txn.get(id , di))
+ if (!txn.get(id, di))
return false;
-
+
func(di);
-
+
txn.put(di, id);
txn.commit();
return true;
}
-
-bool LMDBBackend::setKind(const DNSName &domain, const DomainInfo::DomainKind kind)
+bool LMDBBackend::setKind(const DNSName& domain, const DomainInfo::DomainKind kind)
{
return genChangeDomain(domain, [kind](DomainInfo& di) {
- di.kind = kind;
- });
+ di.kind = kind;
+ });
}
-bool LMDBBackend::setAccount(const DNSName &domain, const std::string& account)
+bool LMDBBackend::setAccount(const DNSName& domain, const std::string& account)
{
return genChangeDomain(domain, [account](DomainInfo& di) {
- di.account = account;
- });
+ di.account = account;
+ });
}
-
void LMDBBackend::setFresh(uint32_t domain_id)
{
genChangeDomain(domain_id, [](DomainInfo& di) {
- di.last_check = time(0);
- });
+ di.last_check = time(0);
+ });
}
void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial)
{
genChangeDomain(domain_id, [serial](DomainInfo& di) {
- di.serial = serial;
- });
+ di.serial = serial;
+ });
}
-
-bool LMDBBackend::setMasters(const DNSName &domain, const vector<ComboAddress> &masters)
+bool LMDBBackend::setMasters(const DNSName& domain, const vector<ComboAddress>& masters)
{
return genChangeDomain(domain, [&masters](DomainInfo& di) {
- di.masters = masters;
- });
+ di.masters = masters;
+ });
}
-bool LMDBBackend::createDomain(const DNSName &domain, const DomainInfo::DomainKind kind, const vector<ComboAddress> &masters, const string &account)
+bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKind kind, const vector<ComboAddress>& masters, const string& account)
{
DomainInfo di;
auto txn = d_tdomains->getRWTransaction();
- if(txn.get<0>(domain, di)) {
- throw DBException("Domain '"+domain.toLogString()+"' exists already");
+ if (txn.get<0>(domain, di)) {
+ throw DBException("Domain '" + domain.toLogString() + "' exists already");
}
di.zone = domain;
return true;
}
-void LMDBBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabled)
+void LMDBBackend::getAllDomains(vector<DomainInfo>* domains, bool include_disabled)
{
compoundOrdername co;
MDBOutVal val;
domains->clear();
auto txn = d_tdomains->getROTransaction();
- for(auto iter = txn.begin(); iter != txn.end(); ++iter) {
- DomainInfo di=*iter;
+ for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
+ DomainInfo di = *iter;
di.id = iter.getID();
auto txn2 = getRecordsROTransaction(iter.getID());
- if(!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
+ if (!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
DNSResourceRecord rr;
serFromString(val.get<string_view>(), rr);
- if(rr.content.size() >= 5 * sizeof(uint32_t)) {
+ if (rr.content.size() >= 5 * sizeof(uint32_t)) {
uint32_t serial;
// a SOA has five 32 bit fields, the first of which is the serial
// there are two variable length names before the serial, so we calculate from the back
memcpy(&serial, &rr.content[rr.content.size() - (5 * sizeof(uint32_t))], sizeof(serial));
di.serial = ntohl(serial);
}
- } else if(!include_disabled) {
+ }
+ else if (!include_disabled) {
continue;
}
di.backend = this;
auto txn = d_tdomains->getROTransaction();
time_t now = time(0);
- for(auto iter = txn.begin(); iter != txn.end(); ++iter) {
- if(iter->kind != DomainInfo::Slave)
+ for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
+ if (iter->kind != DomainInfo::Slave)
continue;
auto txn2 = getRecordsROTransaction(iter.getID());
compoundOrdername co;
MDBOutVal val;
uint32_t serial = 0;
- if(!txn2->txn->get(txn2->db->dbi, co(iter.getID(), g_rootdnsname, QType::SOA), val)) {
+ if (!txn2->txn->get(txn2->db->dbi, co(iter.getID(), g_rootdnsname, QType::SOA), val)) {
DNSResourceRecord rr;
serFromString(val.get<string_view>(), rr);
struct soatimes st;
-
- memcpy(&st, &rr.content[rr.content.size()-sizeof(soatimes)], sizeof(soatimes));
- if((time_t)(iter->last_check + ntohl(st.refresh)) >= now) { // still fresh
+ memcpy(&st, &rr.content[rr.content.size() - sizeof(soatimes)], sizeof(soatimes));
+
+ if ((time_t)(iter->last_check + ntohl(st.refresh)) >= now) { // still fresh
continue; // try next domain
}
// cout << di.last_check <<" + " <<sdata.refresh<<" > = " << now << "\n";
}
else {
// cout << "Could not find SOA for "<<iter->zone<<" with id "<<iter.getID()<<endl;
- serial=0;
+ serial = 0;
}
- DomainInfo di=*iter;
+ DomainInfo di = *iter;
di.id = iter.getID();
di.serial = serial;
di.backend = this;
// cout<<"END of getUnfreshSlaveInfos"<<endl;
}
-bool LMDBBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
+bool LMDBBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
{
meta.clear();
auto txn = d_tmeta->getROTransaction();
auto range = txn.equal_range<0>(name);
-
- for(auto& iter = range.first; iter != range.second; ++iter) {
+
+ for (auto& iter = range.first; iter != range.second; ++iter) {
meta[iter->key].push_back(iter->value);
}
return true;
auto range = txn.equal_range<0>(name);
- for(auto& iter = range.first; iter != range.second; ++iter) {
- if(iter-> key == kind)
+ for (auto& iter = range.first; iter != range.second; ++iter) {
+ if (iter->key == kind)
iter.del();
}
- for(const auto& m : meta) {
+ for (const auto& m : meta) {
DomainMeta dm{name, kind, m};
txn.put(dm);
}
txn.commit();
return true;
-
}
bool LMDBBackend::getDomainKeys(const DNSName& name, std::vector<KeyData>& keys)
{
auto txn = d_tkdb->getROTransaction();
auto range = txn.equal_range<0>(name);
- for(auto& iter = range.first; iter != range.second; ++iter) {
+ for (auto& iter = range.first; iter != range.second; ++iter) {
KeyData kd{iter->content, iter.getID(), iter->flags, iter->active, iter->published};
keys.push_back(kd);
}
{
auto txn = d_tkdb->getRWTransaction();
KeyDataDB kdb;
- if(txn.get(id, kdb)) {
- if(kdb.domain == name) {
+ if (txn.get(id, kdb)) {
+ if (kdb.domain == name) {
txn.del(id);
txn.commit();
return true;
KeyDataDB kdb{name, key.content, key.flags, key.active, key.published};
id = txn.put(kdb);
txn.commit();
-
+
return true;
}
{
auto txn = d_tkdb->getRWTransaction();
KeyDataDB kdb;
- if(txn.get(id, kdb)) {
- if(kdb.domain == name) {
- txn.modify(id, [](KeyDataDB& kdbarg)
- {
- kdbarg.active = true;
- });
+ if (txn.get(id, kdb)) {
+ if (kdb.domain == name) {
+ txn.modify(id, [](KeyDataDB& kdbarg) {
+ kdbarg.active = true;
+ });
txn.commit();
return true;
}
{
auto txn = d_tkdb->getRWTransaction();
KeyDataDB kdb;
- if(txn.get(id, kdb)) {
- if(kdb.domain == name) {
- txn.modify(id, [](KeyDataDB& kdbarg)
- {
- kdbarg.active = false;
- });
+ if (txn.get(id, kdb)) {
+ if (kdb.domain == name) {
+ txn.modify(id, [](KeyDataDB& kdbarg) {
+ kdbarg.active = false;
+ });
txn.commit();
return true;
}
{
auto txn = d_tkdb->getRWTransaction();
KeyDataDB kdb;
- if(txn.get(id, kdb)) {
- if(kdb.domain == name) {
- txn.modify(id, [](KeyDataDB& kdbarg)
- {
- kdbarg.published = true;
- });
+ if (txn.get(id, kdb)) {
+ if (kdb.domain == name) {
+ txn.modify(id, [](KeyDataDB& kdbarg) {
+ kdbarg.published = true;
+ });
txn.commit();
return true;
}
{
auto txn = d_tkdb->getRWTransaction();
KeyDataDB kdb;
- if(txn.get(id, kdb)) {
- if(kdb.domain == name) {
- txn.modify(id, [](KeyDataDB& kdbarg)
- {
- kdbarg.published = false;
- });
+ if (txn.get(id, kdb)) {
+ if (kdb.domain == name) {
+ txn.modify(id, [](KeyDataDB& kdbarg) {
+ kdbarg.published = false;
+ });
txn.commit();
return true;
}
return true;
}
-
-bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
+bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
{
// cout << __PRETTY_FUNCTION__<< ": "<<id <<", "<<qname << " " << unhashed<<endl;
DomainInfo di;
- if(!d_tdomains->getROTransaction().get(id, di)) {
+ if (!d_tdomains->getROTransaction().get(id, di)) {
// domain does not exist, tough luck
return false;
}
// cout <<"Zone: "<<di.zone<<endl;
-
+
compoundOrdername co;
auto txn = getRecordsROTransaction(id);
MDBOutVal key, val;
DNSResourceRecord rr;
-
+
string matchkey = co(id, qname, QType::NSEC3);
- if(cursor.lower_bound(matchkey, key, val)) {
+ if (cursor.lower_bound(matchkey, key, val)) {
// this is beyond the end of the database
// cout << "Beyond end of database!" << endl;
cursor.last(key, val);
- for(;;) {
- if(co.getDomainID(key.get<StringView>()) != id) {
+ for (;;) {
+ if (co.getDomainID(key.get<StringView>()) != id) {
//cout<<"Last record also not part of this zone!"<<endl;
// this implies something is wrong in the database, nothing we can do
return false;
}
-
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl) // the kind of NSEC3 we need
+ if (!rr.ttl) // the kind of NSEC3 we need
break;
}
- if(cursor.prev(key, val)) {
+ if (cursor.prev(key, val)) {
// hit beginning of database, again means something is wrong with it
return false;
}
unhashed = DNSName(rr.content.c_str(), rr.content.size(), 0, false) + di.zone;
// now to find after .. at the beginning of the zone
- if(cursor.lower_bound(co(id), key, val)) {
+ if (cursor.lower_bound(co(id), key, val)) {
// cout<<"hit end of zone find when we shouldn't"<<endl;
return false;
}
- for(;;) {
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ for (;;) {
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl)
+ if (!rr.ttl)
break;
}
- if(cursor.next(key, val) || co.getDomainID(key.get<StringView>()) != id) {
+ if (cursor.next(key, val) || co.getDomainID(key.get<StringView>()) != id) {
// cout<<"hit end of zone or database when we shouldn't"<<endl;
return false;
}
// cout<<"Ended up at "<<co.getQName(key.get<StringView>()) <<endl;
before = co.getQName(key.get<StringView>());
- if(before == qname) {
+ if (before == qname) {
// cout << "Ended up on exact right node" << endl;
before = co.getQName(key.get<StringView>());
// unhashed should be correct now, maybe check?
- if(cursor.next(key, val)) {
+ if (cursor.next(key, val)) {
// xxx should find first hash now
- if(cursor.lower_bound(co(id), key, val)) {
+ if (cursor.lower_bound(co(id), key, val)) {
// cout<<"hit end of zone find when we shouldn't for id "<<id<< __LINE__<<endl;
return false;
}
- for(;;) {
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ for (;;) {
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl)
+ if (!rr.ttl)
break;
}
-
- if(cursor.next(key, val) || co.getDomainID(key.get<StringView>()) != id) {
+
+ if (cursor.next(key, val) || co.getDomainID(key.get<StringView>()) != id) {
// cout<<"hit end of zone or database when we shouldn't" << __LINE__<<endl;
return false;
}
}
else {
// cout <<"Going backwards to find 'before'"<<endl;
- int count=0;
- for(;;) {
- if(co.getQName(key.get<StringView>()).canonCompare(qname) && co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ int count = 0;
+ for (;;) {
+ if (co.getQName(key.get<StringView>()).canonCompare(qname) && co.getQType(key.get<StringView>()) == QType::NSEC3) {
// cout<<"Potentially stopping traverse at "<< co.getQName(key.get<StringView>()) <<", " << (co.getQName(key.get<StringView>()).canonCompare(qname))<<endl;
// cout<<"qname = "<<qname<<endl;
// cout<<"here = "<<co.getQName(key.get<StringView>())<<endl;
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl)
+ if (!rr.ttl)
break;
}
-
- if(cursor.prev(key, val) || co.getDomainID(key.get<StringView>()) != id ) {
+
+ if (cursor.prev(key, val) || co.getDomainID(key.get<StringView>()) != id) {
// cout <<"XXX Hit *beginning* of zone or database"<<endl;
// this can happen, must deal with it
// should now find the last hash of the zone
- if(cursor.lower_bound(co(id+1), key, val)) {
+ if (cursor.lower_bound(co(id + 1), key, val)) {
// cout << "Could not find the next higher zone, going to the end of the database then"<<endl;
cursor.last(key, val);
}
else
cursor.prev(key, val);
- for(;;) {
- if(co.getDomainID(key.get<StringView>()) != id) {
+ for (;;) {
+ if (co.getDomainID(key.get<StringView>()) != id) {
//cout<<"Last record also not part of this zone!"<<endl;
// this implies something is wrong in the database, nothing we can do
return false;
}
-
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl) // the kind of NSEC3 we need
+ if (!rr.ttl) // the kind of NSEC3 we need
break;
}
- if(cursor.prev(key, val)) {
+ if (cursor.prev(key, val)) {
// hit beginning of database, again means something is wrong with it
return false;
}
// cout <<"Should still find 'after'!"<<endl;
// for 'after', we need to find the first hash of this zone
- if(cursor.lower_bound(co(id), key, val)) {
+ if (cursor.lower_bound(co(id), key, val)) {
// cout<<"hit end of zone find when we shouldn't"<<endl;
// means database is wrong, nothing we can do
return false;
}
- for(;;) {
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ for (;;) {
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl)
+ if (!rr.ttl)
break;
}
-
- if(cursor.next(key, val)) {
+
+ if (cursor.next(key, val)) {
// means database is wrong, nothing we can do
// cout<<"hit end of zone when we shouldn't 2"<<endl;
return false;
}
after = co.getQName(key.get<StringView>());
-
// cout<<"returning: before="<<before<<", after="<<after<<", unhashed: "<<unhashed<<endl;
return true;
}
unhashed = DNSName(rr.content.c_str(), rr.content.size(), 0, false) + di.zone;
// cout<<"Went backwards, found "<<before<<endl;
// return us to starting point
- while(count--)
+ while (count--)
cursor.next(key, val);
}
// cout<<"Now going forward"<<endl;
- for(int count = 0 ;;++count) {
- if((count && cursor.next(key, val)) || co.getDomainID(key.get<StringView>()) != id ) {
+ for (int count = 0;; ++count) {
+ if ((count && cursor.next(key, val)) || co.getDomainID(key.get<StringView>()) != id) {
// cout <<"Hit end of database or zone, finding first hash then in zone "<<id<<endl;
- if(cursor.lower_bound(co(id), key, val)) {
+ if (cursor.lower_bound(co(id), key, val)) {
// cout<<"hit end of zone find when we shouldn't"<<endl;
// means database is wrong, nothing we can do
return false;
}
- for(;;) {
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ for (;;) {
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl)
+ if (!rr.ttl)
break;
}
-
- if(cursor.next(key, val)) {
+
+ if (cursor.next(key, val)) {
// means database is wrong, nothing we can do
// cout<<"hit end of zone when we shouldn't 2"<<endl;
return false;
// cout << "Next.. "<<endl;
}
after = co.getQName(key.get<StringView>());
-
+
// cout<<"returning: before="<<before<<", after="<<after<<", unhashed: "<<unhashed<<endl;
return true;
}
-
+
// cout<<"After "<<co.getQName(key.get<StringView>()) <<endl;
- if(co.getQType(key.get<StringView>()) == QType::NSEC3) {
+ if (co.getQType(key.get<StringView>()) == QType::NSEC3) {
serFromString(val.get<StringView>(), rr);
- if(!rr.ttl) {
+ if (!rr.ttl) {
break;
}
}
auto txn = getRecordsROTransaction(id);
compoundOrdername co;
DNSName qname2 = qname.makeRelative(zonename);
- string matchkey=co(id,qname2);
+ string matchkey = co(id, qname2);
auto cursor = txn->txn->getCursor(txn->db->dbi);
MDBOutVal key, val;
// cout<<"Lower_bound for "<<qname2<<endl;
- if(cursor.lower_bound(matchkey, key, val)) {
+ if (cursor.lower_bound(matchkey, key, val)) {
// cout << "Hit end of database, bummer"<<endl;
cursor.last(key, val);
- if(co.getDomainID(key.get<string_view>()) == id) {
+ if (co.getDomainID(key.get<string_view>()) == id) {
before = co.getQName(key.get<string_view>()) + zonename;
after = zonename;
}
// else
- // cout << "We were at end of database, but this zone is not there?!"<<endl;
+ // cout << "We were at end of database, but this zone is not there?!"<<endl;
return true;
}
// cout<<"Cursor is at "<<co.getQName(key.get<string_view>()) <<", in zone id "<<co.getDomainID(key.get<string_view>())<< endl;
- if(co.getQType(key.get<string_view>()).getCode() && co.getDomainID(key.get<string_view>()) ==id && co.getQName(key.get<string_view>()) == qname2) { // don't match ENTs
+ if (co.getQType(key.get<string_view>()).getCode() && co.getDomainID(key.get<string_view>()) == id && co.getQName(key.get<string_view>()) == qname2) { // don't match ENTs
// cout << "Had an exact match!"<<endl;
before = qname2 + zonename;
int rc;
- for(;;) {
- rc=cursor.next(key, val);
- if(rc) break;
-
- if(co.getDomainID(key.get<string_view>()) == id && key.get<StringView>().rfind(matchkey, 0)==0)
+ for (;;) {
+ rc = cursor.next(key, val);
+ if (rc)
+ break;
+
+ if (co.getDomainID(key.get<string_view>()) == id && key.get<StringView>().rfind(matchkey, 0) == 0)
continue;
DNSResourceRecord rr;
serFromString(val.get<StringView>(), rr);
- if(co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS))
+ if (co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS))
break;
}
- if(rc || co.getDomainID(key.get<string_view>()) != id) {
+ if (rc || co.getDomainID(key.get<string_view>()) != id) {
// cout << "We hit the end of the zone or database. 'after' is apex" << endl;
- after=zonename;
+ after = zonename;
return false;
}
after = co.getQName(key.get<string_view>()) + zonename;
return true;
}
-
- if(co.getDomainID(key.get<string_view>()) != id) {
+ if (co.getDomainID(key.get<string_view>()) != id) {
// cout << "Ended up in next zone, 'after' is zonename" <<endl;
after = zonename;
// cout << "Now hunting for previous" << endl;
int rc;
- for(;;) {
- rc=cursor.prev(key, val);
- if(rc) {
+ for (;;) {
+ rc = cursor.prev(key, val);
+ if (rc) {
// cout<<"Reversed into zone, but got not found from lmdb" <<endl;
return false;
}
-
- if(co.getDomainID(key.get<string_view>()) != id) {
+
+ if (co.getDomainID(key.get<string_view>()) != id) {
// cout<<"Reversed into zone, but found wrong zone id " << co.getDomainID(key.get<string_view>()) << " != "<<id<<endl;
// "this can't happen"
return false;
}
DNSResourceRecord rr;
serFromString(val.get<StringView>(), rr);
- if(co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS))
+ if (co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS))
break;
}
// cout <<"We ended up after "<<qname<<", on "<<co.getQName(key.get<string_view>())<<endl;
int skips = 0;
- for(; ;) {
+ for (;;) {
DNSResourceRecord rr;
serFromString(val.get<StringView>(), rr);
- if(co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS)) {
+ if (co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()).getCode() == QType::NS)) {
after = co.getQName(key.get<string_view>()) + zonename;
// cout <<"Found auth ("<<rr.auth<<") or an NS record "<<after<<", type: "<<co.getQType(key.get<string_view>()).getName()<<", ttl = "<<rr.ttl<<endl;
// cout << makeHexDump(val.get<string>()) << endl;
}
// cout <<" oops, " << co.getQName(key.get<string_view>()) << " was not auth "<<rr.auth<< " type=" << rr.qtype.getName()<<" or NS, so need to skip ahead a bit more" << endl;
int rc = cursor.next(key, val);
- if(!rc)
+ if (!rc)
++skips;
- if(rc || co.getDomainID(key.get<string_view>()) != id ) {
+ if (rc || co.getDomainID(key.get<string_view>()) != id) {
// cout << " oops, hit end of database or zone. This means after is apex" <<endl;
after = zonename;
break;
}
}
// go back to where we were
- while(skips--)
- cursor.prev(key,val);
-
- for(;;) {
+ while (skips--)
+ cursor.prev(key, val);
+
+ for (;;) {
int rc = cursor.prev(key, val);
- if(rc || co.getDomainID(key.get<string_view>()) != id) {
+ if (rc || co.getDomainID(key.get<string_view>()) != id) {
// XX I don't think this case can happen
// cout << "We hit the beginning of the zone or database.. now what" << endl;
return false;
DNSResourceRecord rr;
serFromString(val.get<string_view>(), rr);
// cout<<"And before to "<<before<<", auth = "<<rr.auth<<endl;
- if(co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()) == QType::NS))
+ if (co.getQType(key.get<string_view>()).getCode() && (rr.auth || co.getQType(key.get<string_view>()) == QType::NS))
break;
// cout << "Oops, that was wrong, go back one more"<<endl;
}
return true;
-
}
bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName& qname, const DNSName& ordername, bool auth, const uint16_t qtype)
// cout << __PRETTY_FUNCTION__<< ": "<< domain_id <<", '"<<qname <<"', '"<<ordername<<"', "<<auth<< ", " << qtype << endl;
shared_ptr<RecordsRWTransaction> txn;
bool needCommit = false;
- if(d_rwtxn && d_transactiondomainid==domain_id) {
+ if (d_rwtxn && d_transactiondomainid == domain_id) {
txn = d_rwtxn;
// cout<<"Reusing open transaction"<<endl;
}
}
DomainInfo di;
- if(!d_tdomains->getROTransaction().get(domain_id, di)) {
+ if (!d_tdomains->getROTransaction().get(domain_id, di)) {
// cout<<"Could not find domain_id "<<domain_id <<endl;
return false;
}
auto cursor = txn->txn->getCursor(txn->db->dbi);
MDBOutVal key, val;
- if(cursor.lower_bound(matchkey, key, val)) {
+ if (cursor.lower_bound(matchkey, key, val)) {
// cout << "Could not find anything"<<endl;
return false;
}
bool hasOrderName = !ordername.empty();
bool needNSEC3 = hasOrderName;
- for(; key.get<StringView>().rfind(matchkey,0) == 0; ) {
+ for (; key.get<StringView>().rfind(matchkey, 0) == 0;) {
vector<DNSResourceRecord> rrs;
- if(co.getQType(key.get<StringView>()) != QType::NSEC3) {
+ if (co.getQType(key.get<StringView>()) != QType::NSEC3) {
serFromString(val.get<StringView>(), rrs);
bool changed = false;
vector<DNSResourceRecord> newRRs;
- for(auto rr: rrs) {
+ for (auto rr : rrs) {
rr.qtype = co.getQType(key.get<StringView>());
- if(!needNSEC3 && qtype != QType::ANY) {
+ if (!needNSEC3 && qtype != QType::ANY) {
needNSEC3 = (rr.disabled && QType(qtype) != rr.qtype);
}
- if((qtype == QType::ANY || QType(qtype) == rr.qtype) && (rr.disabled != hasOrderName || rr.auth != auth)) {
+ if ((qtype == QType::ANY || QType(qtype) == rr.qtype) && (rr.disabled != hasOrderName || rr.auth != auth)) {
rr.auth = auth;
rr.disabled = hasOrderName;
changed = true;
}
}
- if(cursor.next(key, val))
+ if (cursor.next(key, val))
break;
}
bool del = false;
DNSResourceRecord rr;
- matchkey = co(domain_id,rel,QType::NSEC3);
- if(!txn->txn->get(txn->db->dbi, matchkey, val)) {
+ matchkey = co(domain_id, rel, QType::NSEC3);
+ if (!txn->txn->get(txn->db->dbi, matchkey, val)) {
serFromString(val.get<string_view>(), rr);
- if(needNSEC3) {
- if(hasOrderName && rr.content != ordername.toDNSStringLC()) {
- del = true;
+ if (needNSEC3) {
+ if (hasOrderName && rr.content != ordername.toDNSStringLC()) {
+ del = true;
}
- } else {
+ }
+ else {
del = true;
}
- if(del) {
+ if (del) {
txn->txn->del(txn->db->dbi, co(domain_id, DNSName(rr.content.c_str(), rr.content.size(), 0, false), QType::NSEC3));
txn->txn->del(txn->db->dbi, matchkey);
}
- } else {
+ }
+ else {
del = true;
}
- if(hasOrderName && del) {
- matchkey = co(domain_id,rel,QType::NSEC3);
+ if (hasOrderName && del) {
+ matchkey = co(domain_id, rel, QType::NSEC3);
- rr.ttl=0;
- rr.auth=0;
- rr.content=rel.toDNSStringLC();
+ rr.ttl = 0;
+ rr.auth = 0;
+ rr.content = rel.toDNSStringLC();
string str = serToString(rr);
- txn->txn->put(txn->db->dbi, co(domain_id,ordername,QType::NSEC3), str);
+ txn->txn->put(txn->db->dbi, co(domain_id, ordername, QType::NSEC3), str);
rr.ttl = 1;
rr.content = ordername.toDNSStringLC();
str = serToString(rr);
- txn->txn->put(txn->db->dbi, matchkey, str); // 2
+ txn->txn->put(txn->db->dbi, matchkey, str); // 2
}
- if(needCommit)
+ if (needCommit)
txn->txn->commit();
return false;
}
-bool LMDBBackend::updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& insert, set<DNSName>& erase, bool remove)
+bool LMDBBackend::updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& insert, set<DNSName>& erase, bool remove)
{
// cout << __PRETTY_FUNCTION__<< ": "<< domain_id << ", insert.size() "<<insert.size()<<", "<<erase.size()<<", " <<remove<<endl;
bool needCommit = false;
shared_ptr<RecordsRWTransaction> txn;
- if(d_rwtxn && d_transactiondomainid == domain_id) {
+ if (d_rwtxn && d_transactiondomainid == domain_id) {
txn = d_rwtxn;
// cout<<"Reusing open transaction"<<endl;
}
needCommit = true;
}
-
// if remove is set, all ENTs should be removed & nothing else should be done
- if(remove) {
+ if (remove) {
deleteDomainRecords(*txn, domain_id, 0);
}
else {
DomainInfo di;
auto rotxn = d_tdomains->getROTransaction();
- if(!rotxn.get(domain_id, di)) {
+ if (!rotxn.get(domain_id, di)) {
// cout <<"No such domain with id "<<domain_id<<endl;
return false;
}
compoundOrdername co;
- for(const auto& n : insert) {
+ for (const auto& n : insert) {
DNSResourceRecord rr;
rr.qname = n.makeRelative(di.zone);
rr.ttl = 0;
DNSResourceRecord rr2;
serFromString(ser, rr2);
-
+
// cout <<" +"<<n<<endl;
}
- for(auto n : erase) {
+ for (auto n : erase) {
// cout <<" -"<<n<<endl;
n.makeUsRelative(di.zone);
txn->txn->del(txn->db->dbi, co(domain_id, n, 0));
}
}
- if(needCommit)
+ if (needCommit)
txn->txn->commit();
return false;
}
auto txn = d_ttsig->getROTransaction();
TSIGKey tk;
- if(!txn.get<0>(name, tk))
+ if (!txn.get<0>(name, tk))
return false;
- if(algorithm)
+ if (algorithm)
*algorithm = tk.algorithm;
- if(content)
+ if (content)
*content = tk.key;
return true;
-
}
// this deletes an old key if it has the same algorithm
bool LMDBBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
{
auto txn = d_ttsig->getRWTransaction();
- for(auto range = txn.equal_range<0>(name); range.first != range.second; ++range.first) {
- if(range.first->algorithm == algorithm)
+ for (auto range = txn.equal_range<0>(name); range.first != range.second; ++range.first) {
+ if (range.first->algorithm == algorithm)
range.first.del();
}
TSIGKey tk;
tk.name = name;
tk.algorithm = algorithm;
- tk.key=content;
-
+ tk.key = content;
+
txn.put(tk);
txn.commit();
-
+
return true;
}
bool LMDBBackend::deleteTSIGKey(const DNSName& name)
auto txn = d_ttsig->getRWTransaction();
TSIGKey tk;
- for(auto range = txn.equal_range<0>(name); range.first != range.second; ++range.first) {
+ for (auto range = txn.equal_range<0>(name); range.first != range.second; ++range.first) {
range.first.del();
}
txn.commit();
return true;
}
-bool LMDBBackend::getTSIGKeys(std::vector< struct TSIGKey > &keys)
+bool LMDBBackend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
{
auto txn = d_ttsig->getROTransaction();
keys.clear();
- for(auto iter = txn.begin(); iter != txn.end(); ++iter) {
+ for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
keys.push_back(*iter);
}
return false;
}
-
-
-
class LMDBFactory : public BackendFactory
{
public:
- LMDBFactory() : BackendFactory("lmdb") {}
- void declareArguments(const string &suffix="") override
+ LMDBFactory() :
+ BackendFactory("lmdb") {}
+ void declareArguments(const string& suffix = "") override
{
- declare(suffix,"filename","Filename for lmdb","./pdns.lmdb");
- declare(suffix,"sync-mode","Synchronisation mode: nosync, nometasync, mapasync, sync","mapasync");
+ declare(suffix, "filename", "Filename for lmdb", "./pdns.lmdb");
+ declare(suffix, "sync-mode", "Synchronisation mode: nosync, nometasync, mapasync, sync", "mapasync");
// there just is no room for more on 32 bit
- declare(suffix,"shards","Records database will be split into this number of shards", (sizeof(long) == 4) ? "2" : "64");
- declare(suffix,"schema-version","Maximum allowed schema version to run on this DB. If a lower version is found, auto update is performed", std::to_string(SCHEMAVERSION));
+ declare(suffix, "shards", "Records database will be split into this number of shards", (sizeof(long) == 4) ? "2" : "64");
+ declare(suffix, "schema-version", "Maximum allowed schema version to run on this DB. If a lower version is found, auto update is performed", std::to_string(SCHEMAVERSION));
}
- DNSBackend *make(const string &suffix="") override
+ DNSBackend* make(const string& suffix = "") override
{
return new LMDBBackend(suffix);
}
};
-
-
-
/* THIRD PART */
class LMDBLoader
BackendMakers().report(new LMDBFactory);
g_log << Logger::Info << "[lmdbbackend] This is the lmdb backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
- }
+ << " reporting" << endl;
+ }
};
static LMDBLoader randomLoader;
#include "pdns/dnsbackend.hh"
#include "ext/lmdb-safe/lmdb-typed.hh"
-template<class T, typename std::enable_if<std::is_same<T, DNSName>::value,T>::type* = nullptr>
+template <class T, typename std::enable_if<std::is_same<T, DNSName>::value, T>::type* = nullptr>
std::string keyConv(const T& t)
{
/* www.ds9a.nl -> nl0ds9a0www0
nl -> nl0
*/
- if(t.isRoot())
+ if (t.isRoot())
return std::string(1, (char)0);
std::string in = t.labelReverse().toDNSStringLC(); // www.ds9a.nl is now 2nl4ds9a3www0
std::string ret;
ret.reserve(in.size());
-
- for(auto iter = in.begin(); iter != in.end(); ++iter) {
+
+ for (auto iter = in.begin(); iter != in.end(); ++iter) {
uint8_t len = *iter;
- if(iter != in.begin())
+ if (iter != in.begin())
ret.append(1, (char)0);
- if(!len)
+ if (!len)
break;
- ret.append(&*(iter+1), len);
- iter+=len;
+ ret.append(&*(iter + 1), len);
+ iter += len;
}
return ret;
}
-
class LMDBBackend : public DNSBackend
{
public:
- explicit LMDBBackend(const string &suffix="");
+ explicit LMDBBackend(const string& suffix = "");
- bool list(const DNSName &target, int id, bool include_disabled) override;
+ bool list(const DNSName& target, int id, bool include_disabled) override;
- bool getDomainInfo(const DNSName &domain, DomainInfo &di, bool getSerial=true) override;
- bool createDomain(const DNSName &domain, const DomainInfo::DomainKind kind, const vector<ComboAddress> &masters, const string &account) override;
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
+ bool createDomain(const DNSName& domain, const DomainInfo::DomainKind kind, const vector<ComboAddress>& masters, const string& account) override;
- bool startTransaction(const DNSName &domain, int domain_id=-1) override;
+ bool startTransaction(const DNSName& domain, int domain_id = -1) override;
bool commitTransaction() override;
bool abortTransaction() override;
- bool feedRecord(const DNSResourceRecord &r, const DNSName &ordername, bool ordernameIsNSEC3=false) override;
- bool feedEnts(int domain_id, map<DNSName,bool>& nonterm) override;
- bool feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bool> &nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
+ bool feedRecord(const DNSResourceRecord& r, const DNSName& ordername, bool ordernameIsNSEC3 = false) override;
+ bool feedEnts(int domain_id, map<DNSName, bool>& nonterm) override;
+ bool feedEnts3(int domain_id, const DNSName& domain, map<DNSName, bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) override;
- void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
- void lookup(const QType &type, const DNSName &qdomain, int zoneId, DNSPacket *p=nullptr) override;
- bool get(DNSResourceRecord &rr) override;
+ void getAllDomains(vector<DomainInfo>* domains, bool include_disabled = false) override;
+ void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override;
+ bool get(DNSResourceRecord& rr) override;
bool get(DNSZoneRecord& dzr) override;
void getUnfreshSlaveInfos(vector<DomainInfo>* domains) override;
-
- bool setMasters(const DNSName &domain, const vector<ComboAddress> &masters) override;
- bool setKind(const DNSName &domain, const DomainInfo::DomainKind kind) override;
- bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override;
+
+ bool setMasters(const DNSName& domain, const vector<ComboAddress>& masters) override;
+ bool setKind(const DNSName& domain, const DomainInfo::DomainKind kind) override;
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta) override;
bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override
{
// std::cout<<"Request for metadata items for zone "<<name<<", kind "<<kind<<endl;
meta.clear();
- std::map<std::string, std::vector<std::string> > metas;
- if(getAllDomainMetadata(name, metas)) {
- for(const auto& m : metas) {
- if(m.first == kind) {
+ std::map<std::string, std::vector<std::string>> metas;
+ if (getAllDomainMetadata(name, metas)) {
+ for (const auto& m : metas) {
+ if (m.first == kind) {
meta = m.second;
return true;
}
bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) override;
void setFresh(uint32_t domain_id) override;
void setNotified(uint32_t id, uint32_t serial) override;
- bool setAccount(const DNSName &domain, const std::string& account) override;
- bool deleteDomain(const DNSName &domain) override;
+ bool setAccount(const DNSName& domain, const std::string& account) override;
+ bool deleteDomain(const DNSName& domain) override;
bool getDomainKeys(const DNSName& name, std::vector<KeyData>& keys) override;
bool removeDomainKey(const DNSName& name, unsigned int id) override;
bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content) override;
bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) override;
bool deleteTSIGKey(const DNSName& name) override;
- bool getTSIGKeys(std::vector< struct TSIGKey > &keys) override;
+ bool getTSIGKeys(std::vector<struct TSIGKey>& keys) override;
-
// DNSSEC
bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override;
virtual bool getBeforeAndAfterNames(uint32_t id, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after) override;
- bool updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName& qname, const DNSName& ordername, bool auth, const uint16_t qtype=QType::ANY) override;
+ bool updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName& qname, const DNSName& ordername, bool auth, const uint16_t qtype = QType::ANY) override;
bool updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& insert, set<DNSName>& erase, bool remove) override;
{
return true;
}
-private:
+private:
struct compoundOrdername
{
std::string operator()(uint32_t id, const DNSName& t, uint16_t qtype)
DNSName ret;
auto iter = key.cbegin() + 4;
auto end = key.cend() - 2;
- while(iter < end) {
+ while (iter < end) {
auto startpos = iter;
- while(iter != end && *iter)
+ while (iter != end && *iter)
++iter;
- if(iter == startpos)
+ if (iter == startpos)
break;
- string part(&*startpos, iter-startpos);
+ string part(&*startpos, iter - startpos);
ret.prependRawLabel(part);
// cout << "Prepending part: "<<part<<endl;
- if(iter != end)
+ if (iter != end)
++iter;
}
- if(ret.empty())
+ if (ret.empty())
return g_rootdnsname;
return ret;
}
static QType getQType(const string_view& key)
{
uint16_t ret;
- memcpy(&ret, &key[key.size()-2], sizeof(ret));
+ memcpy(&ret, &key[key.size() - 2], sizeof(ret));
return QType(ntohs(ret));
}
};
};
private:
-
typedef TypedDBI<DomainInfo,
- index_on<DomainInfo, DNSName, &DomainInfo::zone>
- > tdomains_t;
+ index_on<DomainInfo, DNSName, &DomainInfo::zone>>
+ tdomains_t;
-
typedef TypedDBI<DomainMeta,
- index_on<DomainMeta, DNSName, &DomainMeta::domain>
- > tmeta_t;
-
+ index_on<DomainMeta, DNSName, &DomainMeta::domain>>
+ tmeta_t;
+
typedef TypedDBI<KeyDataDB,
- index_on<KeyDataDB, DNSName, &KeyDataDB::domain>
- > tkdb_t;
+ index_on<KeyDataDB, DNSName, &KeyDataDB::domain>>
+ tkdb_t;
typedef TypedDBI<TSIGKey,
- index_on<TSIGKey, DNSName, &TSIGKey::name>
- > ttsig_t;
-
+ index_on<TSIGKey, DNSName, &TSIGKey::name>>
+ ttsig_t;
+
int d_asyncFlag;
struct RecordsDB
struct RecordsROTransaction
{
- RecordsROTransaction(MDBROTransaction&& intxn) : txn(std::move(intxn))
+ RecordsROTransaction(MDBROTransaction&& intxn) :
+ txn(std::move(intxn))
{}
shared_ptr<RecordsDB> db;
MDBROTransaction txn;
};
struct RecordsRWTransaction
{
- RecordsRWTransaction(MDBRWTransaction&& intxn) : txn(std::move(intxn))
+ RecordsRWTransaction(MDBRWTransaction&& intxn) :
+ txn(std::move(intxn))
{}
shared_ptr<RecordsDB> db;
MDBRWTransaction txn;
};
- vector<RecordsDB> d_trecords;;
+ vector<RecordsDB> d_trecords;
+ ;
std::shared_ptr<MDBROCursor> d_getcursor;
shared_ptr<tmeta_t> d_tmeta;
shared_ptr<tkdb_t> d_tkdb;
shared_ptr<ttsig_t> d_ttsig;
-
+
shared_ptr<RecordsROTransaction> d_rotxn; // for lookup and list
shared_ptr<RecordsRWTransaction> d_rwtxn; // for feedrecord within begin/aborttransaction
std::shared_ptr<RecordsRWTransaction> getRecordsRWTransaction(uint32_t id);
std::shared_ptr<RecordsROTransaction> getRecordsROTransaction(uint32_t id, std::shared_ptr<LMDBBackend::RecordsRWTransaction> rwtxn = nullptr);
int genChangeDomain(const DNSName& domain, std::function<void(DomainInfo&)> func);
int genChangeDomain(uint32_t id, std::function<void(DomainInfo&)> func);
- void deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain_id, uint16_t qtype=QType::ANY);
+ void deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain_id, uint16_t qtype = QType::ANY);
bool upgradeToSchemav3();
-
- bool get_list(DNSZoneRecord &rr);
- bool get_lookup(DNSZoneRecord &rr);
+
+ bool get_list(DNSZoneRecord& rr);
+ bool get_lookup(DNSZoneRecord& rr);
std::string d_matchkey;
DNSName d_lookupdomain;
size_t d_currentrrsetpos;
MDBOutVal d_currentKey;
MDBOutVal d_currentVal;
-
+
DNSName d_transactiondomain;
uint32_t d_transactiondomainid;
bool d_dolog;
#endif
#include "lua2backend.hh"
-Lua2BackendAPIv2::~Lua2BackendAPIv2() {
+Lua2BackendAPIv2::~Lua2BackendAPIv2()
+{
if (f_deinit)
f_deinit();
}
#include "boost/algorithm/string/join.hpp"
#include "pdns/arguments.hh"
-class Lua2BackendAPIv2 : public DNSBackend, AuthLua4 {
+class Lua2BackendAPIv2 : public DNSBackend, AuthLua4
+{
private:
typedef std::function<void()> init_call_t;
typedef std::function<void()> deinit_call_t;
- typedef std::vector<std::pair<string, string> > lookup_context_t;
+ typedef std::vector<std::pair<string, string>> lookup_context_t;
- typedef std::vector<std::pair<int, std::vector<std::pair<string, boost::variant<bool, int, DNSName, string, QType> > > > > lookup_result_t;
- typedef std::function<lookup_result_t(const QType& qtype, const DNSName& qname, int domain_id, const lookup_context_t &ctx)> lookup_call_t;
+ typedef std::vector<std::pair<int, std::vector<std::pair<string, boost::variant<bool, int, DNSName, string, QType>>>>> lookup_result_t;
+ typedef std::function<lookup_result_t(const QType& qtype, const DNSName& qname, int domain_id, const lookup_context_t& ctx)> lookup_call_t;
typedef boost::variant<bool, lookup_result_t> list_result_t;
typedef std::function<list_result_t(const DNSName& qname, int domain_id)> list_call_t;
- typedef vector<pair<string, boost::variant<bool, long, string, vector<string> > > > domaininfo_result_t;
+ typedef vector<pair<string, boost::variant<bool, long, string, vector<string>>>> domaininfo_result_t;
typedef boost::variant<bool, domaininfo_result_t> get_domaininfo_result_t;
- typedef vector<pair<DNSName, domaininfo_result_t> > get_all_domains_result_t;
+ typedef vector<pair<DNSName, domaininfo_result_t>> get_all_domains_result_t;
typedef std::function<get_domaininfo_result_t(const DNSName& domain)> get_domaininfo_call_t;
typedef std::function<get_all_domains_result_t()> get_all_domains_call_t;
- typedef vector<pair<int, string> > domain_metadata_result_t;
+ typedef vector<pair<int, string>> domain_metadata_result_t;
typedef boost::variant<bool, domain_metadata_result_t> get_domain_metadata_result_t;
- typedef boost::variant<bool, vector<pair<string, domain_metadata_result_t> > > get_all_domain_metadata_result_t;
+ typedef boost::variant<bool, vector<pair<string, domain_metadata_result_t>>> get_all_domain_metadata_result_t;
typedef std::function<get_domain_metadata_result_t(const DNSName& domain, const string& kind)> get_domain_metadata_call_t;
typedef std::function<get_all_domain_metadata_result_t(const DNSName& domain)> get_all_domain_metadata_call_t;
- typedef vector<pair<string, boost::variant<bool, int, string> > > keydata_result_t;
- typedef boost::variant<bool, vector<pair<int, keydata_result_t> > > get_domain_keys_result_t;
+ typedef vector<pair<string, boost::variant<bool, int, string>>> keydata_result_t;
+ typedef boost::variant<bool, vector<pair<int, keydata_result_t>>> get_domain_keys_result_t;
typedef std::function<get_domain_keys_result_t(const DNSName& domain)> get_domain_keys_call_t;
- typedef std::vector<std::pair<string, boost::variant<string, DNSName> > > before_and_after_names_result_t;
+ typedef std::vector<std::pair<string, boost::variant<string, DNSName>>> before_and_after_names_result_t;
typedef boost::variant<bool, before_and_after_names_result_t> get_before_and_after_names_absolute_result_t;
typedef std::function<get_before_and_after_names_absolute_result_t(int id, const DNSName& qname)> get_before_and_after_names_absolute_call_t;
typedef std::function<void(int, long)> set_notified_call_t;
typedef std::function<string(const string& cmd)> direct_backend_cmd_call_t;
+
public:
- Lua2BackendAPIv2(const string& suffix) {
- setArgPrefix("lua2"+suffix);
+ Lua2BackendAPIv2(const string& suffix)
+ {
+ setArgPrefix("lua2" + suffix);
d_debug_log = mustDo("query-logging");
prepareContext();
loadFile(getArg("filename"));
~Lua2BackendAPIv2();
- #define logCall(func, var) { if (d_debug_log) { g_log<<Logger::Debug<<"["<<getPrefix()<<"] Calling "<<func<<"("<<var<<")"<< endl; } }
- #define logResult(var) { if (d_debug_log) { g_log<<Logger::Debug<<"["<<getPrefix()<<"] Got result " << "'" << var << "'" << endl; } }
+#define logCall(func, var) \
+ { \
+ if (d_debug_log) { \
+ g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << func << "(" << var << ")" << endl; \
+ } \
+ }
+#define logResult(var) \
+ { \
+ if (d_debug_log) { \
+ g_log << Logger::Debug << "[" << getPrefix() << "] Got result " \
+ << "'" << var << "'" << endl; \
+ } \
+ }
- virtual void postPrepareContext() override {
+ virtual void postPrepareContext() override
+ {
AuthLua4::postPrepareContext();
}
- virtual void postLoad() override {
+ virtual void postLoad() override
+ {
f_lookup = d_lw->readVariable<boost::optional<lookup_call_t>>("dns_lookup").get_value_or(0);
f_list = d_lw->readVariable<boost::optional<list_call_t>>("dns_list").get_value_or(0);
f_get_all_domains = d_lw->readVariable<boost::optional<get_all_domains_call_t>>("dns_get_all_domains").get_value_or(0);
throw PDNSException("dns_dnssec is true but dns_get_before_and_after_names_absolute is missing");
/* domain keys is not strictly speaking necessary for dnssec backend */
if (f_get_domain_keys == nullptr)
- g_log<<Logger::Warning<<"dns_get_domain_keys missing - cannot do live signing"<<endl;
+ g_log << Logger::Warning << "dns_get_domain_keys missing - cannot do live signing" << endl;
}
}
- bool doesDNSSEC() override {
+ bool doesDNSSEC() override
+ {
return d_dnssec;
}
- void parseLookup(const lookup_result_t& result) {
- for(const auto& row: result) {
+ void parseLookup(const lookup_result_t& result)
+ {
+ for (const auto& row : result) {
DNSResourceRecord rec;
- for(const auto& item: row.second) {
- if (item.first == "type") {
- if (item.second.which() == 1)
- rec.qtype = QType(boost::get<int>(item.second));
- else if (item.second.which() == 3)
- rec.qtype = boost::get<string>(item.second);
- else if (item.second.which() == 4)
- rec.qtype = boost::get<QType>(item.second);
- else
- throw PDNSException("Unsupported value for type");
- } else if (item.first == "name") {
+ for (const auto& item : row.second) {
+ if (item.first == "type") {
+ if (item.second.which() == 1)
+ rec.qtype = QType(boost::get<int>(item.second));
+ else if (item.second.which() == 3)
+ rec.qtype = boost::get<string>(item.second);
+ else if (item.second.which() == 4)
+ rec.qtype = boost::get<QType>(item.second);
+ else
+ throw PDNSException("Unsupported value for type");
+ }
+ else if (item.first == "name") {
if (item.second.which() == 3)
rec.qname = DNSName(boost::get<string>(item.second));
else if (item.second.which() == 2)
rec.qname = boost::get<DNSName>(item.second);
else
throw PDNSException("Unsupported value for name");
- } else if (item.first == "domain_id")
+ }
+ else if (item.first == "domain_id")
rec.domain_id = boost::get<int>(item.second);
else if (item.first == "auth")
rec.auth = boost::get<bool>(item.second);
else if (item.first == "scopeMask")
rec.scopeMask = boost::get<int>(item.second);
else
- g_log<<Logger::Warning<<"Unsupported key '"<<item.first<<"' in lookup or list result"<<endl;
-
+ g_log << Logger::Warning << "Unsupported key '" << item.first << "' in lookup or list result" << endl;
}
- logResult(rec.qname<<" IN "<<rec.qtype.getName()<<" "<<rec.ttl<<" "<<rec.getZoneRepresentation());
+ logResult(rec.qname << " IN " << rec.qtype.getName() << " " << rec.ttl << " " << rec.getZoneRepresentation());
d_result.push_back(rec);
}
if (d_result.empty() && d_debug_log)
- g_log<<Logger::Debug<<"["<<getPrefix()<<"] Got empty result"<<endl;
+ g_log << Logger::Debug << "[" << getPrefix() << "] Got empty result" << endl;
}
- bool list(const DNSName &target, int domain_id, bool include_disabled=false) override {
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override
+ {
if (f_list == nullptr) {
- g_log<<Logger::Error<<"["<<getPrefix()<<"] dns_list missing - cannot do AXFR"<<endl;
+ g_log << Logger::Error << "[" << getPrefix() << "] dns_list missing - cannot do AXFR" << endl;
return false;
}
if (d_result.size() != 0)
throw PDNSException("list attempted while another was running");
- logCall("list", "target="<<target<<",domain_id="<<domain_id);
+ logCall("list", "target=" << target << ",domain_id=" << domain_id);
list_result_t result = f_list(target, domain_id);
if (result.which() == 0)
return true;
}
- void lookup(const QType &qtype, const DNSName &qname, int domain_id, DNSPacket *p=nullptr) override {
+ void lookup(const QType& qtype, const DNSName& qname, int domain_id, DNSPacket* p = nullptr) override
+ {
if (d_result.size() != 0)
throw PDNSException("lookup attempted while another was running");
ctx.emplace_back(lookup_context_t::value_type{"real_source_address", p->getRealRemote().toString()});
}
- logCall("lookup", "qtype="<<qtype.getName()<<",qname="<<qname<<",domain_id="<<domain_id);
+ logCall("lookup", "qtype=" << qtype.getName() << ",qname=" << qname << ",domain_id=" << domain_id);
lookup_result_t result = f_lookup(qtype, qname, domain_id, ctx);
parseLookup(result);
}
- bool get(DNSResourceRecord &rr) override {
+ bool get(DNSResourceRecord& rr) override
+ {
if (d_result.size() == 0)
return false;
rr = std::move(d_result.front());
return true;
}
- string directBackendCmd(const string& querystr) override {
+ string directBackendCmd(const string& querystr) override
+ {
string::size_type pos = querystr.find_first_of(" \t");
string cmd = querystr;
string par = "";
if (pos != string::npos) {
cmd = querystr.substr(0, pos);
- par = querystr.substr(pos+1);
+ par = querystr.substr(pos + 1);
}
direct_backend_cmd_call_t f = d_lw->readVariable<boost::optional<direct_backend_cmd_call_t>>(cmd).get_value_or(0);
if (f == nullptr) {
return cmd + "not found";
}
- logCall(cmd, "parameter="<<par);
+ logCall(cmd, "parameter=" << par);
return f(par);
}
- void setNotified(uint32_t id, uint32_t serial) override {
+ void setNotified(uint32_t id, uint32_t serial) override
+ {
if (f_set_notified == NULL)
return;
- logCall("dns_set_notified", "id="<<static_cast<int>(id)<<",serial="<<serial);
+ logCall("dns_set_notified", "id=" << static_cast<int>(id) << ",serial=" << serial);
f_set_notified(static_cast<int>(id), serial);
}
- void parseDomainInfo(const domaininfo_result_t& row, DomainInfo& di) {
- for(const auto& item: row) {
- if (item.first == "account")
- di.account = boost::get<string>(item.second);
- else if (item.first == "last_check")
- di.last_check = static_cast<time_t>(boost::get<long>(item.second));
- else if (item.first == "masters")
- for(const auto& master: boost::get<vector<string>>(item.second))
- di.masters.push_back(ComboAddress(master, 53));
- else if (item.first == "id")
- di.id = static_cast<int>(boost::get<long>(item.second));
- else if (item.first == "notified_serial")
- di.notified_serial = static_cast<unsigned int>(boost::get<long>(item.second));
- else if (item.first == "serial")
- di.serial = static_cast<unsigned int>(boost::get<long>(item.second));
- else if (item.first == "kind")
- di.kind = DomainInfo::stringToKind(boost::get<string>(item.second));
- else
- g_log<<Logger::Warning<<"Unsupported key '"<<item.first<<"' in domaininfo result"<<endl;
- }
- di.backend = this;
- logResult("zone="<<di.zone<<",serial="<<di.serial<<",kind="<<di.getKindString());
+ void parseDomainInfo(const domaininfo_result_t& row, DomainInfo& di)
+ {
+ for (const auto& item : row) {
+ if (item.first == "account")
+ di.account = boost::get<string>(item.second);
+ else if (item.first == "last_check")
+ di.last_check = static_cast<time_t>(boost::get<long>(item.second));
+ else if (item.first == "masters")
+ for (const auto& master : boost::get<vector<string>>(item.second))
+ di.masters.push_back(ComboAddress(master, 53));
+ else if (item.first == "id")
+ di.id = static_cast<int>(boost::get<long>(item.second));
+ else if (item.first == "notified_serial")
+ di.notified_serial = static_cast<unsigned int>(boost::get<long>(item.second));
+ else if (item.first == "serial")
+ di.serial = static_cast<unsigned int>(boost::get<long>(item.second));
+ else if (item.first == "kind")
+ di.kind = DomainInfo::stringToKind(boost::get<string>(item.second));
+ else
+ g_log << Logger::Warning << "Unsupported key '" << item.first << "' in domaininfo result" << endl;
+ }
+ di.backend = this;
+ logResult("zone=" << di.zone << ",serial=" << di.serial << ",kind=" << di.getKindString());
}
- bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial=true) override {
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override
+ {
if (f_get_domaininfo == nullptr) {
// use getAuth instead
SOAData sd;
return true;
}
- logCall("get_domaininfo","domain="<<domain);
+ logCall("get_domaininfo", "domain=" << domain);
get_domaininfo_result_t result = f_get_domaininfo(domain);
if (result.which() == 0)
return true;
}
- void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override {
- if (f_get_all_domains == nullptr)
- return;
-
- logCall("get_all_domains", "");
- for(const auto& row: f_get_all_domains()) {
- DomainInfo di;
- di.zone = row.first;
- logResult(di.zone);
- parseDomainInfo(row.second, di);
- domains->push_back(di);
- }
+ void getAllDomains(vector<DomainInfo>* domains, bool include_disabled = false) override
+ {
+ if (f_get_all_domains == nullptr)
+ return;
+
+ logCall("get_all_domains", "");
+ for (const auto& row : f_get_all_domains()) {
+ DomainInfo di;
+ di.zone = row.first;
+ logResult(di.zone);
+ parseDomainInfo(row.second, di);
+ domains->push_back(di);
+ }
}
- bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override {
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta) override
+ {
if (f_get_all_domain_metadata == nullptr)
return false;
- logCall("get_all_domain_metadata","name="<<name);
+ logCall("get_all_domain_metadata", "name=" << name);
get_all_domain_metadata_result_t result = f_get_all_domain_metadata(name);
if (result.which() == 0)
return false;
- for(const auto& row: boost::get< vector<pair<string, domain_metadata_result_t> > >(result)) {
- meta[row.first].clear();
- for(const auto& item: row.second)
- meta[row.first].push_back(item.second);
- logResult("kind="<<row.first<<",value="<<boost::algorithm::join(meta[row.first], ", "));
+ for (const auto& row : boost::get<vector<pair<string, domain_metadata_result_t>>>(result)) {
+ meta[row.first].clear();
+ for (const auto& item : row.second)
+ meta[row.first].push_back(item.second);
+ logResult("kind=" << row.first << ",value=" << boost::algorithm::join(meta[row.first], ", "));
}
return true;
}
- bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override {
+ bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override
+ {
if (f_get_domain_metadata == nullptr)
return false;
- logCall("get_domain_metadata","name="<<name<<",kind="<<kind);
+ logCall("get_domain_metadata", "name=" << name << ",kind=" << kind);
get_domain_metadata_result_t result = f_get_domain_metadata(name, kind);
if (result.which() == 0)
return false;
meta.clear();
- for(const auto& item: boost::get<domain_metadata_result_t>(result))
+ for (const auto& item : boost::get<domain_metadata_result_t>(result))
meta.push_back(item.second);
- logResult("value="<<boost::algorithm::join(meta, ", "));
+ logResult("value=" << boost::algorithm::join(meta, ", "));
return true;
}
- bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) override {
+ bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) override
+ {
if (f_get_domain_keys == nullptr)
return false;
- logCall("get_domain_keys","name="<<name);
+ logCall("get_domain_keys", "name=" << name);
get_domain_keys_result_t result = f_get_domain_keys(name);
if (result.which() == 0)
return false;
- for(const auto& row: boost::get<vector<pair<int, keydata_result_t> > >(result)) {
+ for (const auto& row : boost::get<vector<pair<int, keydata_result_t>>>(result)) {
DNSBackend::KeyData key;
key.published = true;
- for(const auto& item: row.second) {
+ for (const auto& item : row.second) {
if (item.first == "content")
key.content = boost::get<string>(item.second);
else if (item.first == "id")
else if (item.first == "published")
key.published = boost::get<bool>(item.second);
else
- g_log<<Logger::Warning<<"["<<getPrefix()<<"] Unsupported key '"<<item.first<<"' in keydata result"<<endl;
+ g_log << Logger::Warning << "[" << getPrefix() << "] Unsupported key '" << item.first << "' in keydata result" << endl;
}
- logResult("id="<<key.id<<",flags="<<key.flags<<",active="<<(key.active ? "true" : "false")<<",published="<<(key.published ? "true" : "false"));
+ logResult("id=" << key.id << ",flags=" << key.flags << ",active=" << (key.active ? "true" : "false") << ",published=" << (key.published ? "true" : "false"));
keys.push_back(key);
}
return true;
}
- bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override {
+ bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override
+ {
if (f_get_before_and_after_names_absolute == nullptr)
return false;
- logCall("get_before_and_after_names_absolute", "id=<<"<<id<<",qname="<<qname);
+ logCall("get_before_and_after_names_absolute", "id=<<" << id << ",qname=" << qname);
get_before_and_after_names_absolute_result_t result = f_get_before_and_after_names_absolute(id, qname);
if (result.which() == 0)
before_and_after_names_result_t row = boost::get<before_and_after_names_result_t>(result);
if (row.size() != 3) {
- g_log<<Logger::Error<<"Invalid result from dns_get_before_and_after_names_absolute, expected array with 3 items, got "<<row.size()<<"item(s)"<<endl;
+ g_log << Logger::Error << "Invalid result from dns_get_before_and_after_names_absolute, expected array with 3 items, got " << row.size() << "item(s)" << endl;
return false;
}
- for(const auto& item: row) {
+ for (const auto& item : row) {
DNSName value;
if (item.second.which() == 0)
- value = DNSName(boost::get<string>(item.second));
+ value = DNSName(boost::get<string>(item.second));
else
- value = DNSName(boost::get<DNSName>(item.second));
+ value = DNSName(boost::get<DNSName>(item.second));
if (item.first == "unhashed")
unhashed = value;
else if (item.first == "before")
else if (item.first == "after")
after = value;
else {
- g_log<<Logger::Error<<"Invalid result from dns_get_before_and_after_names_absolute, unexpected key "<<item.first<<endl;
+ g_log << Logger::Error << "Invalid result from dns_get_before_and_after_names_absolute, unexpected key " << item.first << endl;
return false;
}
}
- logResult("unhashed="<<unhashed<<",before="<<before<<",after="<<after);
+ logResult("unhashed=" << unhashed << ",before=" << before << ",after=" << after);
return true;
}
class Lua2Factory : public BackendFactory
{
public:
- Lua2Factory() : BackendFactory("lua2") {}
+ Lua2Factory() :
+ BackendFactory("lua2") {}
- void declareArguments(const string &suffix="") override
+ void declareArguments(const string& suffix = "") override
{
- declare(suffix,"filename","Filename of the script for lua backend","powerdns-luabackend.lua");
- declare(suffix,"query-logging","Logging of the Lua2 Backend","no");
- declare(suffix,"api","Lua backend API version","2");
+ declare(suffix, "filename", "Filename of the script for lua backend", "powerdns-luabackend.lua");
+ declare(suffix, "query-logging", "Logging of the Lua2 Backend", "no");
+ declare(suffix, "api", "Lua backend API version", "2");
}
- DNSBackend *make(const string &suffix="") override
+ DNSBackend* make(const string& suffix = "") override
{
const std::string apiSet = "lua2" + suffix + "-api";
const int api = ::arg().asNum(apiSet);
- DNSBackend *be;
- switch(api) {
+ DNSBackend* be;
+ switch (api) {
case 1:
throw PDNSException("Use luabackend for api version 1");
case 2:
- be = new Lua2BackendAPIv2(suffix); break;
+ be = new Lua2BackendAPIv2(suffix);
+ break;
default:
throw PDNSException("Unsupported ABI version " + ::arg()[apiSet]);
}
g_log << Logger::Info << "[lua2backend] This is the lua2 backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
#include <boost/algorithm/string.hpp>
#include <vector>
-CoProcess::CoProcess(const string &command,int timeout, int infd, int outfd): d_infd(infd), d_outfd(outfd), d_timeout(timeout)
+CoProcess::CoProcess(const string& command, int timeout, int infd, int outfd) :
+ d_infd(infd), d_outfd(outfd), d_timeout(timeout)
{
split(d_params, command, boost::is_any_of(" "));
- d_argv.resize(d_params.size()+1);
- d_argv[d_params.size()]=nullptr;
+ d_argv.resize(d_params.size() + 1);
+ d_argv[d_params.size()] = nullptr;
for (size_t n = 0; n < d_params.size(); n++) {
- d_argv[n]=d_params[n].c_str();
+ d_argv[n] = d_params[n].c_str();
}
d_pid = 0;
}
{
signal(SIGPIPE, SIG_IGN);
- if(access(d_argv[0],X_OK)) // check before fork so we can throw
- throw PDNSException("Command '"+string(d_argv[0])+"' cannot be executed: "+stringerror());
+ if (access(d_argv[0], X_OK)) // check before fork so we can throw
+ throw PDNSException("Command '" + string(d_argv[0]) + "' cannot be executed: " + stringerror());
- if(pipe(d_fd1)<0 || pipe(d_fd2)<0)
- throw PDNSException("Unable to open pipe for coprocess: "+string(strerror(errno)));
+ if (pipe(d_fd1) < 0 || pipe(d_fd2) < 0)
+ throw PDNSException("Unable to open pipe for coprocess: " + string(strerror(errno)));
- if((d_pid=fork())<0)
- throw PDNSException("Unable to fork for coprocess: "+stringerror());
- else if(d_pid>0) { // parent speaking
+ if ((d_pid = fork()) < 0)
+ throw PDNSException("Unable to fork for coprocess: " + stringerror());
+ else if (d_pid > 0) { // parent speaking
// no need to keep this around
d_argv.clear();
close(d_fd1[0]);
setNonBlocking(d_fd2[0]);
}
}
- else if(!d_pid) { // child
+ else if (!d_pid) { // child
signal(SIGCHLD, SIG_DFL); // silence a warning from perl
close(d_fd1[1]);
close(d_fd2[0]);
- if(d_fd1[0]!= d_infd) {
+ if (d_fd1[0] != d_infd) {
dup2(d_fd1[0], d_infd);
close(d_fd1[0]);
}
- if(d_fd2[1]!= d_outfd) {
+ if (d_fd2[1] != d_outfd) {
dup2(d_fd2[1], d_outfd);
close(d_fd2[1]);
}
// stdin & stdout are now connected, fire up our coprocess!
- if(execv(d_argv[0], const_cast<char * const *>(d_argv.data()))<0) // now what
+ if (execv(d_argv[0], const_cast<char* const*>(d_argv.data())) < 0) // now what
exit(123);
/* not a lot we can do here. We shouldn't return because that will leave a forked process around.
CoProcess::~CoProcess()
{
int status;
- if(d_pid){
- if(!waitpid(d_pid, &status, WNOHANG)) {
+ if (d_pid) {
+ if (!waitpid(d_pid, &status, WNOHANG)) {
kill(d_pid, 9);
waitpid(d_pid, &status, 0);
}
}
-
+
close(d_fd1[1]);
close(d_fd2[0]);
}
void CoProcess::checkStatus()
{
int status;
- int ret=waitpid(d_pid, &status, WNOHANG);
- if(ret<0)
- throw PDNSException("Unable to ascertain status of coprocess "+itoa(d_pid)+" from "+itoa(getpid())+": "+string(strerror(errno)));
- else if(ret) {
- if(WIFEXITED(status)) {
- int exitStatus=WEXITSTATUS(status);
- throw PDNSException("Coprocess exited with code "+itoa(exitStatus));
+ int ret = waitpid(d_pid, &status, WNOHANG);
+ if (ret < 0)
+ throw PDNSException("Unable to ascertain status of coprocess " + itoa(d_pid) + " from " + itoa(getpid()) + ": " + string(strerror(errno)));
+ else if (ret) {
+ if (WIFEXITED(status)) {
+ int exitStatus = WEXITSTATUS(status);
+ throw PDNSException("Coprocess exited with code " + itoa(exitStatus));
}
- if(WIFSIGNALED(status)) {
- int sig=WTERMSIG(status);
- string reason="CoProcess died on receiving signal "+itoa(sig);
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ string reason = "CoProcess died on receiving signal " + itoa(sig);
#ifdef WCOREDUMP
- if(WCOREDUMP(status))
- reason+=". Dumped core";
+ if (WCOREDUMP(status))
+ reason += ". Dumped core";
#endif
-
+
throw PDNSException(reason);
}
}
}
-void CoProcess::send(const string &snd)
+void CoProcess::send(const string& snd)
{
checkStatus();
string line(snd);
- line.append(1,'\n');
-
- unsigned int sent=0;
+ line.append(1, '\n');
+
+ unsigned int sent = 0;
int bytes;
// writen routine - socket may not accept al data in one go
- while(sent<line.size()) {
- bytes=write(d_fd1[1],line.c_str()+sent,line.length()-sent);
- if(bytes<0)
- throw PDNSException("Writing to coprocess failed: "+string(strerror(errno)));
+ while (sent < line.size()) {
+ bytes = write(d_fd1[1], line.c_str() + sent, line.length() - sent);
+ if (bytes < 0)
+ throw PDNSException("Writing to coprocess failed: " + string(strerror(errno)));
- sent+=bytes;
+ sent += bytes;
}
}
-void CoProcess::receive(string &received)
+void CoProcess::receive(string& received)
{
received.clear();
continue;
}
if (saved == EAGAIN) {
- if(d_timeout) {
+ if (d_timeout) {
int ret = waitForData(d_fd2[0], 0, d_timeout * 1000);
- if(ret<0)
- throw PDNSException("Error waiting on data from coprocess: "+string(strerror(saved)));
- if(!ret)
+ if (ret < 0)
+ throw PDNSException("Error waiting on data from coprocess: " + string(strerror(saved)));
+ if (!ret)
throw PDNSException("Timeout waiting for data from coprocess");
}
}
else {
throw PDNSException("Error reading from child's pipe:" + string(strerror(saved)));
}
- } else {
+ }
+ else {
received.resize(existingSize + static_cast<size_t>(got));
}
}
boost::trim_right(received);
}
-void CoProcess::sendReceive(const string &snd, string &rcv)
+void CoProcess::sendReceive(const string& snd, string& rcv)
{
checkStatus();
send(snd);
receive(rcv);
-
}
-UnixRemote::UnixRemote(const string& path, int timeout)
+UnixRemote::UnixRemote(const string& path, int timeout)
{
d_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if(d_fd < 0)
- throw PDNSException("Unable to create UNIX domain socket: "+string(strerror(errno)));
+ if (d_fd < 0)
+ throw PDNSException("Unable to create UNIX domain socket: " + string(strerror(errno)));
struct sockaddr_un remote;
if (makeUNsockaddr(path, &remote))
- throw PDNSException("Unable to create UNIX domain socket: Path '"+path+"' is not a valid UNIX socket path.");
+ throw PDNSException("Unable to create UNIX domain socket: Path '" + path + "' is not a valid UNIX socket path.");
// fcntl(fd, F_SETFL, O_NONBLOCK, &sock);
- if(connect(d_fd, (struct sockaddr*)&remote, sizeof(remote)) < 0)
- unixDie("Unable to connect to remote '"+path+"' using UNIX domain socket");
+ if (connect(d_fd, (struct sockaddr*)&remote, sizeof(remote)) < 0)
+ unixDie("Unable to connect to remote '" + path + "' using UNIX domain socket");
- d_fp = std::unique_ptr<FILE, int(*)(FILE*)>(fdopen(d_fd, "r"), fclose);
+ d_fp = std::unique_ptr<FILE, int (*)(FILE*)>(fdopen(d_fd, "r"), fclose);
}
void UnixRemote::send(const string& line)
boost::trim_right(line);
}
-void UnixRemote::sendReceive(const string &snd, string &rcv)
+void UnixRemote::sendReceive(const string& snd, string& rcv)
{
// checkStatus();
send(snd);
bool isUnixSocket(const string& fname)
{
struct stat st;
- if(stat(fname.c_str(), &st) < 0)
+ if (stat(fname.c_str(), &st) < 0)
return false; // not a unix socket in any case ;-)
return (st.st_mode & S_IFSOCK) == S_IFSOCK;
}
-
#ifdef TESTDRIVER
main()
{
CoProcess cp("./irc.pl");
string reply;
cp.sendReceive("www.trilab.com", reply);
- cout<<"Answered: '"<<reply<<"'"<<endl;
+ cout << "Answered: '" << reply << "'" << endl;
}
- catch(PDNSException &ae) {
- cerr<<ae.reason<<endl;
+ catch (PDNSException& ae) {
+ cerr << ae.reason << endl;
}
-
}
#endif
{
public:
virtual ~CoRemote() {}
- virtual void sendReceive(const string &send, string &receive) = 0;
- virtual void receive(string &rcv) = 0;
- virtual void send(const string &send) = 0;
-
+ virtual void sendReceive(const string& send, string& receive) = 0;
+ virtual void receive(string& rcv) = 0;
+ virtual void send(const string& send) = 0;
};
class CoProcess : public CoRemote
{
public:
- CoProcess(const string &command,int timeout=0, int infd=0, int outfd=1);
+ CoProcess(const string& command, int timeout = 0, int infd = 0, int outfd = 1);
~CoProcess();
- void sendReceive(const string &send, string &receive) override;
- void receive(string &rcv) override;
- void send(const string &send) override;
+ void sendReceive(const string& send, string& receive) override;
+ void receive(string& rcv) override;
+ void send(const string& send) override;
void launch();
+
private:
void checkStatus();
std::vector<std::string> d_params;
- std::vector<const char *> d_argv;
+ std::vector<const char*> d_argv;
std::string d_remaining;
int d_fd1[2], d_fd2[2];
int d_pid;
class UnixRemote : public CoRemote
{
public:
- UnixRemote(const string &path, int timeout=0);
- void sendReceive(const string &send, string &receive) override;
- void receive(string &rcv) override;
- void send(const string &send) override;
+ UnixRemote(const string& path, int timeout = 0);
+ void sendReceive(const string& send, string& receive) override;
+ void receive(string& rcv) override;
+ void send(const string& send) override;
+
private:
int d_fd;
- std::unique_ptr<FILE, int(*)(FILE*)> d_fp{nullptr, fclose};
+ std::unique_ptr<FILE, int (*)(FILE*)> d_fp{nullptr, fclose};
};
bool isUnixSocket(const string& fname);
#include <arpa/inet.h>
#include "pipebackend.hh"
-static const char *kBackendId = "[PIPEBackend]";
+static const char* kBackendId = "[PIPEBackend]";
-CoWrapper::CoWrapper(const string &command, int timeout, int abiVersion)
+CoWrapper::CoWrapper(const string& command, int timeout, int abiVersion)
{
- d_command=command;
- d_timeout=timeout;
- d_abiVersion = abiVersion;
- launch(); // let exceptions fall through - if initial launch fails, we want to die
- // I think
+ d_command = command;
+ d_timeout = timeout;
+ d_abiVersion = abiVersion;
+ launch(); // let exceptions fall through - if initial launch fails, we want to die
+ // I think
}
CoWrapper::~CoWrapper()
void CoWrapper::launch()
{
- if(d_cp)
- return;
-
- if(d_command.empty())
- throw ArgException("pipe-command is not specified");
-
- if(isUnixSocket(d_command)) {
- d_cp = std::unique_ptr<CoRemote>(new UnixRemote(d_command, d_timeout));
- }
- else {
- auto coprocess = std::unique_ptr<CoProcess>(new CoProcess(d_command, d_timeout));
- coprocess->launch();
- d_cp = std::move(coprocess);
- }
-
- d_cp->send("HELO\t"+std::to_string(d_abiVersion));
- string banner;
- d_cp->receive(banner);
- g_log<<Logger::Error<<"Backend launched with banner: "<<banner<<endl;
+ if (d_cp)
+ return;
+
+ if (d_command.empty())
+ throw ArgException("pipe-command is not specified");
+
+ if (isUnixSocket(d_command)) {
+ d_cp = std::unique_ptr<CoRemote>(new UnixRemote(d_command, d_timeout));
+ }
+ else {
+ auto coprocess = std::unique_ptr<CoProcess>(new CoProcess(d_command, d_timeout));
+ coprocess->launch();
+ d_cp = std::move(coprocess);
+ }
+
+ d_cp->send("HELO\t" + std::to_string(d_abiVersion));
+ string banner;
+ d_cp->receive(banner);
+ g_log << Logger::Error << "Backend launched with banner: " << banner << endl;
}
-void CoWrapper::send(const string &line)
+void CoWrapper::send(const string& line)
{
- launch();
- try {
- d_cp->send(line);
- return;
- }
- catch(PDNSException &ae) {
- d_cp.reset();
- throw;
- }
+ launch();
+ try {
+ d_cp->send(line);
+ return;
+ }
+ catch (PDNSException& ae) {
+ d_cp.reset();
+ throw;
+ }
}
-void CoWrapper::receive(string &line)
+void CoWrapper::receive(string& line)
{
- launch();
- try {
- d_cp->receive(line);
- return;
- }
- catch(PDNSException &ae) {
- g_log<<Logger::Warning<<kBackendId<<" Unable to receive data from coprocess. "<<ae.reason<<endl;
- d_cp.reset();
- throw;
- }
+ launch();
+ try {
+ d_cp->receive(line);
+ return;
+ }
+ catch (PDNSException& ae) {
+ g_log << Logger::Warning << kBackendId << " Unable to receive data from coprocess. " << ae.reason << endl;
+ d_cp.reset();
+ throw;
+ }
}
-PipeBackend::PipeBackend(const string &suffix)
+PipeBackend::PipeBackend(const string& suffix)
{
- d_disavow=false;
- signal(SIGCHLD, SIG_IGN);
- setArgPrefix("pipe"+suffix);
- try {
- launch();
- }
- catch(const ArgException &A) {
- g_log<<Logger::Error<<kBackendId<<" Unable to launch, fatal argument error: "<<A.reason<<endl;
- throw;
- }
- catch(...) {
- throw;
- }
+ d_disavow = false;
+ signal(SIGCHLD, SIG_IGN);
+ setArgPrefix("pipe" + suffix);
+ try {
+ launch();
+ }
+ catch (const ArgException& A) {
+ g_log << Logger::Error << kBackendId << " Unable to launch, fatal argument error: " << A.reason << endl;
+ throw;
+ }
+ catch (...) {
+ throw;
+ }
}
void PipeBackend::launch()
{
- if(d_coproc)
+ if (d_coproc)
return;
try {
if (!getArg("regex").empty()) {
d_regex = std::unique_ptr<Regex>(new Regex(getArg("regex")));
}
- d_regexstr=getArg("regex");
+ d_regexstr = getArg("regex");
d_abiVersion = getArgAsNum("abi-version");
- d_coproc=unique_ptr<CoWrapper> (new CoWrapper(getArg("command"), getArgAsNum("timeout"), getArgAsNum("abi-version")));
+ d_coproc = unique_ptr<CoWrapper>(new CoWrapper(getArg("command"), getArgAsNum("timeout"), getArgAsNum("abi-version")));
}
- catch(const ArgException &A) {
+ catch (const ArgException& A) {
cleanup();
throw;
}
d_abiVersion = 0;
}
-void PipeBackend::lookup(const QType& qtype,const DNSName& qname, int zoneId, DNSPacket *pkt_p)
+void PipeBackend::lookup(const QType& qtype, const DNSName& qname, int zoneId, DNSPacket* pkt_p)
{
try {
launch();
- d_disavow=false;
- if(d_regex && !d_regex->match(qname.toStringRootDot())) {
- if(::arg().mustDo("query-logging"))
- g_log<<Logger::Error<<"Query for '"<<qname<<"' failed regex '"<<d_regexstr<<"'"<<endl;
- d_disavow=true; // don't pass to backend
- } else {
+ d_disavow = false;
+ if (d_regex && !d_regex->match(qname.toStringRootDot())) {
+ if (::arg().mustDo("query-logging"))
+ g_log << Logger::Error << "Query for '" << qname << "' failed regex '" << d_regexstr << "'" << endl;
+ d_disavow = true; // don't pass to backend
+ }
+ else {
ostringstream query;
- string localIP="0.0.0.0";
- string remoteIP="0.0.0.0";
+ string localIP = "0.0.0.0";
+ string remoteIP = "0.0.0.0";
Netmask realRemote("0.0.0.0/0");
if (pkt_p) {
- localIP=pkt_p->getLocal().toString();
+ localIP = pkt_p->getLocal().toString();
realRemote = pkt_p->getRealRemote();
remoteIP = pkt_p->getRemote().toString();
}
// abi-version = 1
// type qname qclass qtype id remote-ip-address
- query<<"Q\t"<<qname.toStringRootDot()<<"\tIN\t"<<qtype.getName()<<"\t"<<zoneId<<"\t"<<remoteIP;
+ query << "Q\t" << qname.toStringRootDot() << "\tIN\t" << qtype.getName() << "\t" << zoneId << "\t" << remoteIP;
// add the local-ip-address if abi-version is set to 2
if (d_abiVersion >= 2)
- query<<"\t"<<localIP;
- if(d_abiVersion >= 3)
- query <<"\t"<<realRemote.toString();
+ query << "\t" << localIP;
+ if (d_abiVersion >= 3)
+ query << "\t" << realRemote.toString();
- if(::arg().mustDo("query-logging"))
- g_log<<Logger::Error<<"Query: '"<<query.str()<<"'"<<endl;
+ if (::arg().mustDo("query-logging"))
+ g_log << Logger::Error << "Query: '" << query.str() << "'" << endl;
d_coproc->send(query.str());
}
}
- catch(PDNSException &pe) {
- g_log<<Logger::Error<<kBackendId<<" Error from coprocess: "<<pe.reason<<endl;
+ catch (PDNSException& pe) {
+ g_log << Logger::Error << kBackendId << " Error from coprocess: " << pe.reason << endl;
d_disavow = true;
}
- d_qtype=qtype;
- d_qname=qname;
+ d_qtype = qtype;
+ d_qname = qname;
}
bool PipeBackend::list(const DNSName& target, int inZoneId, bool include_disabled)
{
try {
launch();
- d_disavow=false;
+ d_disavow = false;
ostringstream query;
// The question format:
// type qname qclass qtype id ip-address
if (d_abiVersion >= 4)
- query<<"AXFR\t"<<inZoneId<<"\t"<<target.toStringRootDot();
+ query << "AXFR\t" << inZoneId << "\t" << target.toStringRootDot();
else
- query<<"AXFR\t"<<inZoneId;
+ query << "AXFR\t" << inZoneId;
d_coproc->send(query.str());
}
- catch(PDNSException &ae) {
- g_log<<Logger::Error<<kBackendId<<" Error from coprocess: "<<ae.reason<<endl;
+ catch (PDNSException& ae) {
+ g_log << Logger::Error << kBackendId << " Error from coprocess: " << ae.reason << endl;
}
- d_qname=DNSName(itoa(inZoneId)); // why do we store a number here??
+ d_qname = DNSName(itoa(inZoneId)); // why do we store a number here??
return true;
}
-string PipeBackend::directBackendCmd(const string &query) {
+string PipeBackend::directBackendCmd(const string& query)
+{
if (d_abiVersion < 5)
return "not supported on ABI version " + std::to_string(d_abiVersion) + " (use ABI version 5 or later)\n";
try {
launch();
ostringstream oss;
- oss<<"CMD\t"<<query;
+ oss << "CMD\t" << query;
d_coproc->send(oss.str());
}
- catch(PDNSException &ae) {
- g_log<<Logger::Error<<kBackendId<<" Error from coprocess: "<<ae.reason<<endl;
+ catch (PDNSException& ae) {
+ g_log << Logger::Error << kBackendId << " Error from coprocess: " << ae.reason << endl;
cleanup();
}
ostringstream oss;
- while(true) {
+ while (true) {
string line;
d_coproc->receive(line);
- if (line == "END") break;
+ if (line == "END")
+ break;
oss << line << std::endl;
};
}
//! For the dynamic loader
-DNSBackend *PipeBackend::maker()
+DNSBackend* PipeBackend::maker()
{
- try {
- return new PipeBackend();
- }
- catch(...) {
- g_log<<Logger::Error<<kBackendId<<" Unable to instantiate a pipebackend!"<<endl;
- return nullptr;
- }
+ try {
+ return new PipeBackend();
+ }
+ catch (...) {
+ g_log << Logger::Error << kBackendId << " Unable to instantiate a pipebackend!" << endl;
+ return nullptr;
+ }
}
PipeBackend::~PipeBackend()
cleanup();
}
-bool PipeBackend::get(DNSResourceRecord &r)
+bool PipeBackend::get(DNSResourceRecord& r)
{
- if(d_disavow) // this query has been blocked
+ if (d_disavow) // this query has been blocked
return false;
string line;
// The answer format:
- // DATA qname qclass qtype ttl id content
+ // DATA qname qclass qtype ttl id content
unsigned int extraFields = 0;
- if(d_abiVersion >= 3)
+ if (d_abiVersion >= 3)
extraFields = 2;
- try{
+ try {
launch();
- for(;;) {
+ for (;;) {
d_coproc->receive(line);
- vector<string>parts;
- stringtok(parts,line,"\t");
- if(parts.empty()) {
- g_log<<Logger::Error<<kBackendId<<" Coprocess returned empty line in query for "<<d_qname<<endl;
+ vector<string> parts;
+ stringtok(parts, line, "\t");
+ if (parts.empty()) {
+ g_log << Logger::Error << kBackendId << " Coprocess returned empty line in query for " << d_qname << endl;
throw PDNSException("Format error communicating with coprocess");
}
- else if(parts[0]=="FAIL") {
+ else if (parts[0] == "FAIL") {
throw DBException("coprocess returned a FAIL");
}
- else if(parts[0]=="END") {
+ else if (parts[0] == "END") {
return false;
}
- else if(parts[0]=="LOG") {
- g_log<<Logger::Error<<"Coprocess: "<<line.substr(4)<<endl;
+ else if (parts[0] == "LOG") {
+ g_log << Logger::Error << "Coprocess: " << line.substr(4) << endl;
continue;
}
- else if(parts[0]=="DATA") { // yay
- if(parts.size() < 7 + extraFields) {
- g_log<<Logger::Error<<kBackendId<<" Coprocess returned incomplete or empty line in data section for query for "<<d_qname<<endl;
+ else if (parts[0] == "DATA") { // yay
+ if (parts.size() < 7 + extraFields) {
+ g_log << Logger::Error << kBackendId << " Coprocess returned incomplete or empty line in data section for query for " << d_qname << endl;
throw PDNSException("Format error communicating with coprocess in data section");
// now what?
}
- if(d_abiVersion >= 3) {
- r.scopeMask = std::stoi(parts[1]);
- r.auth = (parts[2] == "1");
- } else {
- r.scopeMask = 0;
- r.auth = true;
- }
- r.qname=DNSName(parts[1+extraFields]);
- r.qtype=parts[3+extraFields];
- r.ttl=pdns_stou(parts[4+extraFields]);
- r.domain_id=std::stoi(parts[5+extraFields]);
-
- if(r.qtype.getCode() != QType::MX && r.qtype.getCode() != QType::SRV) {
+ if (d_abiVersion >= 3) {
+ r.scopeMask = std::stoi(parts[1]);
+ r.auth = (parts[2] == "1");
+ }
+ else {
+ r.scopeMask = 0;
+ r.auth = true;
+ }
+ r.qname = DNSName(parts[1 + extraFields]);
+ r.qtype = parts[3 + extraFields];
+ r.ttl = pdns_stou(parts[4 + extraFields]);
+ r.domain_id = std::stoi(parts[5 + extraFields]);
+
+ if (r.qtype.getCode() != QType::MX && r.qtype.getCode() != QType::SRV) {
r.content.clear();
- for(unsigned int n= 6 + extraFields; n < parts.size(); ++n) {
- if(n!=6+extraFields)
- r.content.append(1,' ');
+ for (unsigned int n = 6 + extraFields; n < parts.size(); ++n) {
+ if (n != 6 + extraFields)
+ r.content.append(1, ' ');
r.content.append(parts[n]);
}
}
else {
- if(parts.size()< 8 + extraFields) {
- g_log<<Logger::Error<<kBackendId<<" Coprocess returned incomplete MX/SRV line in data section for query for "<<d_qname<<endl;
+ if (parts.size() < 8 + extraFields) {
+ g_log << Logger::Error << kBackendId << " Coprocess returned incomplete MX/SRV line in data section for query for " << d_qname << endl;
throw PDNSException("Format error communicating with coprocess in data section of MX/SRV record");
}
- r.content=parts[6+extraFields]+" "+parts[7+extraFields];
+ r.content = parts[6 + extraFields] + " " + parts[7 + extraFields];
}
break;
}
else
- throw PDNSException("Coprocess backend sent incorrect response '"+line+"'");
+ throw PDNSException("Coprocess backend sent incorrect response '" + line + "'");
}
}
- catch (DBException &dbe) {
- g_log<<Logger::Error<<kBackendId<<" "<<dbe.reason<<endl;
+ catch (DBException& dbe) {
+ g_log << Logger::Error << kBackendId << " " << dbe.reason << endl;
throw;
}
- catch (PDNSException &pe) {
- g_log<<Logger::Error<<kBackendId<<" "<<pe.reason<<endl;
+ catch (PDNSException& pe) {
+ g_log << Logger::Error << kBackendId << " " << pe.reason << endl;
cleanup();
throw;
}
class PipeFactory : public BackendFactory
{
- public:
- PipeFactory() : BackendFactory("pipe") {}
-
- void declareArguments(const string &suffix="") override
- {
- declare(suffix,"command","Command to execute for piping questions to","");
- declare(suffix,"timeout","Number of milliseconds to wait for an answer","2000");
- declare(suffix,"regex","Regular expression of queries to pass to coprocess","");
- declare(suffix,"abi-version","Version of the pipe backend ABI","1");
- }
+public:
+ PipeFactory() :
+ BackendFactory("pipe") {}
+
+ void declareArguments(const string& suffix = "") override
+ {
+ declare(suffix, "command", "Command to execute for piping questions to", "");
+ declare(suffix, "timeout", "Number of milliseconds to wait for an answer", "2000");
+ declare(suffix, "regex", "Regular expression of queries to pass to coprocess", "");
+ declare(suffix, "abi-version", "Version of the pipe backend ABI", "1");
+ }
- DNSBackend *make(const string &suffix="") override
- {
- return new PipeBackend(suffix);
- }
+ DNSBackend* make(const string& suffix = "") override
+ {
+ return new PipeBackend(suffix);
+ }
};
class PipeLoader
{
- public:
- PipeLoader()
- {
- BackendMakers().report(new PipeFactory);
- g_log << Logger::Info << kBackendId <<" This is the pipe backend version " VERSION
+public:
+ PipeLoader()
+ {
+ BackendMakers().report(new PipeFactory);
+ g_log << Logger::Info << kBackendId << " This is the pipe backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
- }
+ << " reporting" << endl;
+ }
};
static PipeLoader pipeloader;
-
#include "pdns/namespaces.hh"
#include "pdns/misc.hh"
-
/** The CoWrapper class wraps around a coprocess and restarts it if needed.
It may also send out pings and expect banners */
class CoWrapper
{
public:
- CoWrapper(const string &command, int timeout, int abiVersion);
+ CoWrapper(const string& command, int timeout, int abiVersion);
~CoWrapper();
- void send(const string &line);
- void receive(string &line);
+ void send(const string& line);
+ void receive(string& line);
+
private:
std::unique_ptr<CoRemote> d_cp;
string d_command;
class PipeBackend : public DNSBackend
{
public:
- PipeBackend(const string &suffix="");
+ PipeBackend(const string& suffix = "");
~PipeBackend();
- void lookup(const QType&, const DNSName& qdomain, int zoneId, DNSPacket *p=nullptr) override;
- bool list(const DNSName& target, int domain_id, bool include_disabled=false) override;
- bool get(DNSResourceRecord &r) override;
- string directBackendCmd(const string &query) override;
- static DNSBackend *maker();
-
+ void lookup(const QType&, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override;
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override;
+ bool get(DNSResourceRecord& r) override;
+ string directBackendCmd(const string& query) override;
+ static DNSBackend* maker();
+
private:
void launch();
void cleanup();
class RandomBackend : public DNSBackend
{
public:
- RandomBackend(const string &suffix="")
+ RandomBackend(const string& suffix = "")
{
- setArgPrefix("random"+suffix);
- d_ourname=DNSName(getArg("hostname"));
+ setArgPrefix("random" + suffix);
+ d_ourname = DNSName(getArg("hostname"));
d_ourdomain = d_ourname;
d_ourdomain.chopOff();
}
- bool list(const DNSName &target, int id, bool include_disabled) override {
+ bool list(const DNSName& target, int id, bool include_disabled) override
+ {
return false; // we don't support AXFR
}
- void lookup(const QType &type, const DNSName &qdomain, int zoneId, DNSPacket *p) override
+ void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p) override
{
- if(qdomain == d_ourdomain){
- if(type.getCode() == QType::SOA || type.getCode() == QType::ANY) {
- d_answer="ns1." + d_ourdomain.toString() + " hostmaster." + d_ourdomain.toString() + " 1234567890 86400 7200 604800 300";
- } else {
- d_answer.clear();;
+ if (qdomain == d_ourdomain) {
+ if (type.getCode() == QType::SOA || type.getCode() == QType::ANY) {
+ d_answer = "ns1." + d_ourdomain.toString() + " hostmaster." + d_ourdomain.toString() + " 1234567890 86400 7200 604800 300";
+ }
+ else {
+ d_answer.clear();
+ ;
}
- } else if (qdomain == d_ourname) {
- if(type.getCode() == QType::A || type.getCode() == QType::ANY) {
+ }
+ else if (qdomain == d_ourname) {
+ if (type.getCode() == QType::A || type.getCode() == QType::ANY) {
ostringstream os;
- os<<dns_random(256)<<"."<<dns_random(256)<<"."<<dns_random(256)<<"."<<dns_random(256);
- d_answer=os.str(); // our random ip address
- } else {
- d_answer="";
+ os << dns_random(256) << "." << dns_random(256) << "." << dns_random(256) << "." << dns_random(256);
+ d_answer = os.str(); // our random ip address
+ }
+ else {
+ d_answer = "";
}
- } else {
- d_answer="";
+ }
+ else {
+ d_answer = "";
}
}
- bool get(DNSResourceRecord &rr) override
+ bool get(DNSResourceRecord& rr) override
{
- if(d_answer.empty())
+ if (d_answer.empty())
return false;
- if(d_answer.find("ns1.") == 0){
- rr.qname=d_ourdomain;
- rr.qtype=QType::SOA;
- } else {
- rr.qname=d_ourname;
- rr.qtype=QType::A;
+ if (d_answer.find("ns1.") == 0) {
+ rr.qname = d_ourdomain;
+ rr.qtype = QType::SOA;
+ }
+ else {
+ rr.qname = d_ourname;
+ rr.qtype = QType::A;
}
- rr.qclass=QClass::IN; // Internet class randomness.
- rr.ttl=5; // 5 seconds
- rr.auth = true; // it may be random.. but it is auth!
+ rr.qclass = QClass::IN; // Internet class randomness.
+ rr.ttl = 5; // 5 seconds
+ rr.auth = true; // it may be random.. but it is auth!
rr.content = d_answer;
- d_answer.clear(); // this was the last answer
+ d_answer.clear(); // this was the last answer
return true;
}
class RandomFactory : public BackendFactory
{
public:
- RandomFactory() : BackendFactory("random") {}
- void declareArguments(const string &suffix="") override
+ RandomFactory() :
+ BackendFactory("random") {}
+ void declareArguments(const string& suffix = "") override
{
- declare(suffix,"hostname","Hostname which is to be random","random.example.com");
+ declare(suffix, "hostname", "Hostname which is to be random", "random.example.com");
}
- DNSBackend *make(const string &suffix="") override
+ DNSBackend* make(const string& suffix = "") override
{
return new RandomBackend(suffix);
}
BackendMakers().report(new RandomFactory);
g_log << Logger::Info << "[randombackend] This is the random backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
- }
+ << " reporting" << endl;
+ }
};
static RandomLoader randomLoader;
#define UNIX_PATH_MAX 108
#endif
-HTTPConnector::HTTPConnector(std::map<std::string,std::string> options): d_socket(nullptr) {
+HTTPConnector::HTTPConnector(std::map<std::string, std::string> options) :
+ d_socket(nullptr)
+{
- if (options.find("url") == options.end()) {
- throw PDNSException("Cannot find 'url' option in the remote backend HTTP connector's parameters");
+ if (options.find("url") == options.end()) {
+ throw PDNSException("Cannot find 'url' option in the remote backend HTTP connector's parameters");
+ }
+
+ this->d_url = options.find("url")->second;
+
+ try {
+ YaHTTP::URL url(d_url);
+ d_host = url.host;
+ d_port = url.port;
+ }
+ catch (const std::exception& e) {
+ throw PDNSException("Error parsing the 'url' option provided to the remote backend HTTP connector: " + std::string(e.what()));
+ }
+
+ if (options.find("url-suffix") != options.end()) {
+ this->d_url_suffix = options.find("url-suffix")->second;
+ }
+ else {
+ this->d_url_suffix = "";
+ }
+ this->timeout = 2;
+ this->d_post = false;
+ this->d_post_json = false;
+
+ if (options.find("timeout") != options.end()) {
+ this->timeout = std::stoi(options.find("timeout")->second) / 1000;
+ }
+ if (options.find("post") != options.end()) {
+ std::string val = options.find("post")->second;
+ if (val == "yes" || val == "true" || val == "on" || val == "1") {
+ this->d_post = true;
+ }
+ }
+ if (options.find("post_json") != options.end()) {
+ std::string val = options.find("post_json")->second;
+ if (val == "yes" || val == "true" || val == "on" || val == "1") {
+ this->d_post_json = true;
}
+ }
+}
+
+HTTPConnector::~HTTPConnector() {}
+
+void HTTPConnector::addUrlComponent(const Json& parameters, const string& element, std::stringstream& ss)
+{
+ std::string sparam;
+ if (parameters[element] != Json())
+ ss << "/" << YaHTTP::Utility::encodeURL(asString(parameters[element]), false);
+}
- this->d_url = options.find("url")->second;
+std::string HTTPConnector::buildMemberListArgs(std::string prefix, const Json& args)
+{
+ std::stringstream stream;
- try {
- YaHTTP::URL url(d_url);
- d_host = url.host;
- d_port = url.port;
+ for (const auto& pair : args.object_items()) {
+ if (pair.second.is_bool()) {
+ stream << (pair.second.bool_value() ? "1" : "0");
}
- catch(const std::exception& e) {
- throw PDNSException("Error parsing the 'url' option provided to the remote backend HTTP connector: " + std::string(e.what()));
+ else if (pair.second.is_null()) {
+ stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=";
}
-
- if (options.find("url-suffix") != options.end()) {
- this->d_url_suffix = options.find("url-suffix")->second;
- } else {
- this->d_url_suffix = "";
+ else {
+ stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=" << YaHTTP::Utility::encodeURL(this->asString(pair.second), false);
}
- this->timeout = 2;
- this->d_post = false;
- this->d_post_json = false;
+ stream << "&";
+ }
- if (options.find("timeout") != options.end()) {
- this->timeout = std::stoi(options.find("timeout")->second)/1000;
+ return stream.str().substr(0, stream.str().size() - 1); // snip the trailing &
+}
+
+// builds our request (near-restful)
+void HTTPConnector::restful_requestbuilder(const std::string& method, const Json& parameters, YaHTTP::Request& req)
+{
+ std::stringstream ss;
+ std::string sparam;
+ std::string verb;
+
+ // special names are qname, name, zonename, kind, others go to headers
+
+ ss << d_url;
+
+ ss << "/" << method;
+
+ // add the url components, if found, in following order.
+ // id must be first due to the fact that the qname/name can be empty
+
+ addUrlComponent(parameters, "id", ss);
+ addUrlComponent(parameters, "domain_id", ss);
+ addUrlComponent(parameters, "zonename", ss);
+ addUrlComponent(parameters, "qname", ss);
+ addUrlComponent(parameters, "name", ss);
+ addUrlComponent(parameters, "kind", ss);
+ addUrlComponent(parameters, "qtype", ss);
+
+ // set the correct type of request based on method
+ if (method == "activateDomainKey" || method == "deactivateDomainKey" || method == "publishDomainKey" || method == "unpublishDomainKey") {
+ // create an empty post
+ req.preparePost();
+ verb = "POST";
+ }
+ else if (method == "setTSIGKey") {
+ req.POST()["algorithm"] = parameters["algorithm"].string_value();
+ req.POST()["content"] = parameters["content"].string_value();
+ req.preparePost();
+ verb = "PATCH";
+ }
+ else if (method == "deleteTSIGKey") {
+ verb = "DELETE";
+ }
+ else if (method == "addDomainKey") {
+ const Json& param = parameters["key"];
+ req.POST()["flags"] = asString(param["flags"]);
+ req.POST()["active"] = (param["active"].bool_value() ? "1" : "0");
+ req.POST()["published"] = (param["published"].bool_value() ? "1" : "0");
+ req.POST()["content"] = param["content"].string_value();
+ req.preparePost();
+ verb = "PUT";
+ }
+ else if (method == "superMasterBackend") {
+ std::stringstream ss2;
+ addUrlComponent(parameters, "ip", ss);
+ addUrlComponent(parameters, "domain", ss);
+ // then we need to serialize rrset payload into POST
+ for (size_t index = 0; index < parameters["nsset"].array_items().size(); index++) {
+ ss2 << buildMemberListArgs("nsset[" + std::to_string(index) + "]", parameters["nsset"][index]) << "&";
}
- if (options.find("post") != options.end()) {
- std::string val = options.find("post")->second;
- if (val == "yes" || val == "true" || val == "on" || val == "1") {
- this->d_post = true;
- }
+ req.body = ss2.str().substr(0, ss2.str().size() - 1);
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "POST";
+ }
+ else if (method == "createSlaveDomain") {
+ addUrlComponent(parameters, "ip", ss);
+ addUrlComponent(parameters, "domain", ss);
+ if (parameters["account"].is_null() == false && parameters["account"].is_string()) {
+ req.POST()["account"] = parameters["account"].string_value();
+ }
+ req.preparePost();
+ verb = "PUT";
+ }
+ else if (method == "replaceRRSet") {
+ std::stringstream ss2;
+ for (size_t index = 0; index < parameters["rrset"].array_items().size(); index++) {
+ ss2 << buildMemberListArgs("rrset[" + std::to_string(index) + "]", parameters["rrset"][index]);
+ }
+ req.body = ss2.str();
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "PATCH";
+ }
+ else if (method == "feedRecord") {
+ addUrlComponent(parameters, "trxid", ss);
+ req.body = buildMemberListArgs("rr", parameters["rr"]);
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "PATCH";
+ }
+ else if (method == "feedEnts") {
+ std::stringstream ss2;
+ addUrlComponent(parameters, "trxid", ss);
+ for (const auto& param : parameters["nonterm"].array_items()) {
+ ss2 << "nonterm[]=" << YaHTTP::Utility::encodeURL(param.string_value(), false) << "&";
+ }
+ for (const auto& param : parameters["auth"].array_items()) {
+ ss2 << "auth[]=" << (param["auth"].bool_value() ? "1" : "0") << "&";
+ }
+ req.body = ss2.str().substr(0, ss2.str().size() - 1);
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "PATCH";
+ }
+ else if (method == "feedEnts3") {
+ std::stringstream ss2;
+ addUrlComponent(parameters, "domain", ss);
+ addUrlComponent(parameters, "trxid", ss);
+ ss2 << "times=" << parameters["times"].int_value() << "&salt=" << YaHTTP::Utility::encodeURL(parameters["salt"].string_value(), false) << "&narrow=" << (parameters["narrow"].bool_value() ? 1 : 0) << "&";
+ for (const auto& param : parameters["nonterm"].array_items()) {
+ ss2 << "nonterm[]=" << YaHTTP::Utility::encodeURL(param.string_value(), false) << "&";
}
- if (options.find("post_json") != options.end()) {
- std::string val = options.find("post_json")->second;
- if (val == "yes" || val == "true" || val == "on" || val == "1") {
- this->d_post_json = true;
+ for (const auto& param : parameters["auth"].array_items()) {
+ ss2 << "auth[]=" << (param["auth"].bool_value() ? "1" : "0") << "&";
+ }
+ req.body = ss2.str().substr(0, ss2.str().size() - 1);
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "PATCH";
+ }
+ else if (method == "startTransaction") {
+ addUrlComponent(parameters, "domain", ss);
+ addUrlComponent(parameters, "trxid", ss);
+ req.preparePost();
+ verb = "POST";
+ }
+ else if (method == "commitTransaction" || method == "abortTransaction") {
+ addUrlComponent(parameters, "trxid", ss);
+ req.preparePost();
+ verb = "POST";
+ }
+ else if (method == "setDomainMetadata") {
+ // copy all metadata values into post
+ std::stringstream ss2;
+ // this one has values too
+ if (parameters["value"].is_array()) {
+ for (const auto& val : parameters["value"].array_items()) {
+ ss2 << "value[]=" << YaHTTP::Utility::encodeURL(val.string_value(), false) << "&";
}
}
-}
+ req.body = ss2.str().substr(0, ss2.str().size() - 1);
+ req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
+ req.headers["content-length"] = std::to_string(req.body.size());
+ verb = "PATCH";
+ }
+ else if (method == "removeDomainKey") {
+ // this one is delete
+ verb = "DELETE";
+ }
+ else if (method == "setNotified") {
+ req.POST()["serial"] = std::to_string(parameters["serial"].number_value());
+ req.preparePost();
+ verb = "PATCH";
+ }
+ else if (method == "setFresh") {
+ req.preparePost();
+ verb = "PATCH";
+ }
+ else if (method == "directBackendCmd") {
+ req.POST()["query"] = parameters["query"].string_value();
+ req.preparePost();
+ verb = "POST";
+ }
+ else if (method == "searchRecords" || method == "searchComments") {
+ req.GET()["pattern"] = parameters["pattern"].string_value();
+ req.GET()["maxResults"] = std::to_string(parameters["maxResults"].int_value());
+ verb = "GET";
+ }
+ else if (method == "getAllDomains") {
+ req.GET()["includeDisabled"] = (parameters["include_disabled"].bool_value() ? "true" : "false");
+ verb = "GET";
+ }
+ else {
+ // perform normal get
+ verb = "GET";
+ }
+
+ // put everything else into headers
+ for (const auto& pair : parameters.object_items()) {
+ std::string member = pair.first;
+ // whitelist header parameters
+ if ((member == "trxid" || member == "local" || member == "remote" || member == "real-remote" || member == "zone-id")) {
+ std::string hdr = "x-remotebackend-" + member;
+ req.headers[hdr] = asString(pair.second);
+ }
+ };
-HTTPConnector::~HTTPConnector() { }
+ // finally add suffix and store url
+ ss << d_url_suffix;
-void HTTPConnector::addUrlComponent(const Json ¶meters, const string& element, std::stringstream& ss) {
- std::string sparam;
- if (parameters[element] != Json())
- ss << "/" << YaHTTP::Utility::encodeURL(asString(parameters[element]), false);
+ req.setup(verb, ss.str());
+ req.headers["accept"] = "application/json";
}
-std::string HTTPConnector::buildMemberListArgs(std::string prefix, const Json& args) {
- std::stringstream stream;
-
- for(const auto& pair: args.object_items()) {
- if (pair.second.is_bool()) {
- stream << (pair.second.bool_value()?"1":"0");
- } else if (pair.second.is_null()) {
- stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=";
- } else {
- stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=" << YaHTTP::Utility::encodeURL(this->asString(pair.second), false);
- }
- stream << "&";
- }
-
- return stream.str().substr(0, stream.str().size()-1); // snip the trailing &
+void HTTPConnector::post_requestbuilder(const Json& input, YaHTTP::Request& req)
+{
+ if (this->d_post_json) {
+ std::string out = input.dump();
+ req.setup("POST", d_url);
+ // simple case, POST JSON into url. nothing fancy.
+ req.headers["Content-Type"] = "text/javascript; charset=utf-8";
+ req.headers["Content-Length"] = std::to_string(out.size());
+ req.headers["accept"] = "application/json";
+ req.body = out;
+ }
+ else {
+ std::stringstream url, content;
+ // call url/method.suffix
+ url << d_url << "/" << input["method"].string_value() << d_url_suffix;
+ req.setup("POST", url.str());
+ // then build content
+ req.POST()["parameters"] = input["parameters"].dump();
+ req.preparePost();
+ req.headers["accept"] = "application/json";
+ }
}
-// builds our request (near-restful)
-void HTTPConnector::restful_requestbuilder(const std::string &method, const Json& parameters, YaHTTP::Request& req)
+int HTTPConnector::send_message(const Json& input)
{
- std::stringstream ss;
- std::string sparam;
- std::string verb;
-
- // special names are qname, name, zonename, kind, others go to headers
-
- ss << d_url;
-
- ss << "/" << method;
-
- // add the url components, if found, in following order.
- // id must be first due to the fact that the qname/name can be empty
-
- addUrlComponent(parameters, "id", ss);
- addUrlComponent(parameters, "domain_id", ss);
- addUrlComponent(parameters, "zonename", ss);
- addUrlComponent(parameters, "qname", ss);
- addUrlComponent(parameters, "name", ss);
- addUrlComponent(parameters, "kind", ss);
- addUrlComponent(parameters, "qtype", ss);
-
- // set the correct type of request based on method
- if (method == "activateDomainKey" || method == "deactivateDomainKey" || method == "publishDomainKey" || method == "unpublishDomainKey") {
- // create an empty post
- req.preparePost();
- verb = "POST";
- } else if (method == "setTSIGKey") {
- req.POST()["algorithm"] = parameters["algorithm"].string_value();
- req.POST()["content"] = parameters["content"].string_value();
- req.preparePost();
- verb = "PATCH";
- } else if (method == "deleteTSIGKey") {
- verb = "DELETE";
- } else if (method == "addDomainKey") {
- const Json& param = parameters["key"];
- req.POST()["flags"] = asString(param["flags"]);
- req.POST()["active"] = (param["active"].bool_value() ? "1" : "0");
- req.POST()["published"] = (param["published"].bool_value() ? "1" : "0");
- req.POST()["content"] = param["content"].string_value();
- req.preparePost();
- verb = "PUT";
- } else if (method == "superMasterBackend") {
- std::stringstream ss2;
- addUrlComponent(parameters, "ip", ss);
- addUrlComponent(parameters, "domain", ss);
- // then we need to serialize rrset payload into POST
- for(size_t index = 0; index < parameters["nsset"].array_items().size(); index++) {
- ss2 << buildMemberListArgs("nsset[" + std::to_string(index) + "]", parameters["nsset"][index]) << "&";
- }
- req.body = ss2.str().substr(0, ss2.str().size()-1);
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "POST";
- } else if (method == "createSlaveDomain") {
- addUrlComponent(parameters, "ip", ss);
- addUrlComponent(parameters, "domain", ss);
- if (parameters["account"].is_null() == false && parameters["account"].is_string()) {
- req.POST()["account"] = parameters["account"].string_value();
- }
- req.preparePost();
- verb = "PUT";
- } else if (method == "replaceRRSet") {
- std::stringstream ss2;
- for(size_t index = 0; index < parameters["rrset"].array_items().size(); index++) {
- ss2 << buildMemberListArgs("rrset[" + std::to_string(index) + "]", parameters["rrset"][index]);
- }
- req.body = ss2.str();
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "PATCH";
- } else if (method == "feedRecord") {
- addUrlComponent(parameters, "trxid", ss);
- req.body = buildMemberListArgs("rr", parameters["rr"]);
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "PATCH";
- } else if (method == "feedEnts") {
- std::stringstream ss2;
- addUrlComponent(parameters, "trxid", ss);
- for(const auto& param: parameters["nonterm"].array_items()) {
- ss2 << "nonterm[]=" << YaHTTP::Utility::encodeURL(param.string_value(), false) << "&";
- }
- for(const auto& param: parameters["auth"].array_items()) {
- ss2 << "auth[]=" << (param["auth"].bool_value()?"1":"0") << "&";
- }
- req.body = ss2.str().substr(0, ss2.str().size()-1);
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "PATCH";
- } else if (method == "feedEnts3") {
- std::stringstream ss2;
- addUrlComponent(parameters, "domain", ss);
- addUrlComponent(parameters, "trxid", ss);
- ss2 << "times=" << parameters["times"].int_value() << "&salt=" << YaHTTP::Utility::encodeURL(parameters["salt"].string_value(), false) << "&narrow=" << (parameters["narrow"].bool_value() ? 1 : 0) << "&";
- for(const auto& param: parameters["nonterm"].array_items()) {
- ss2 << "nonterm[]=" << YaHTTP::Utility::encodeURL(param.string_value(), false) << "&";
- }
- for(const auto& param: parameters["auth"].array_items()) {
- ss2 << "auth[]=" << (param["auth"].bool_value()?"1":"0") << "&";
- }
- req.body = ss2.str().substr(0, ss2.str().size()-1);
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "PATCH";
- } else if (method == "startTransaction") {
- addUrlComponent(parameters, "domain", ss);
- addUrlComponent(parameters, "trxid", ss);
- req.preparePost();
- verb = "POST";
- } else if (method == "commitTransaction" || method == "abortTransaction") {
- addUrlComponent(parameters, "trxid", ss);
- req.preparePost();
- verb = "POST";
- } else if (method == "setDomainMetadata") {
- // copy all metadata values into post
- std::stringstream ss2;
- // this one has values too
- if (parameters["value"].is_array()) {
- for(const auto& val: parameters["value"].array_items()) {
- ss2 << "value[]=" << YaHTTP::Utility::encodeURL(val.string_value(), false) << "&";
- }
- }
- req.body = ss2.str().substr(0, ss2.str().size()-1);
- req.headers["content-type"] = "application/x-www-form-urlencoded; charset=utf-8";
- req.headers["content-length"] = std::to_string(req.body.size());
- verb = "PATCH";
- } else if (method == "removeDomainKey") {
- // this one is delete
- verb = "DELETE";
- } else if (method == "setNotified") {
- req.POST()["serial"] = std::to_string(parameters["serial"].number_value());
- req.preparePost();
- verb = "PATCH";
- } else if (method == "setFresh") {
- req.preparePost();
- verb = "PATCH";
- } else if (method == "directBackendCmd") {
- req.POST()["query"] = parameters["query"].string_value();
- req.preparePost();
- verb = "POST";
- } else if (method == "searchRecords" || method == "searchComments") {
- req.GET()["pattern"] = parameters["pattern"].string_value();
- req.GET()["maxResults"] = std::to_string(parameters["maxResults"].int_value());
- verb = "GET";
- } else if (method == "getAllDomains") {
- req.GET()["includeDisabled"] = (parameters["include_disabled"].bool_value()?"true":"false");
- verb = "GET";
- } else {
- // perform normal get
- verb = "GET";
- }
+ int rv, ec, fd;
- // put everything else into headers
- for(const auto& pair: parameters.object_items()) {
- std::string member = pair.first;
- // whitelist header parameters
- if ((member == "trxid" ||
- member == "local" ||
- member == "remote" ||
- member == "real-remote" ||
- member == "zone-id")) {
- std::string hdr = "x-remotebackend-" + member;
- req.headers[hdr] = asString(pair.second);
- }
- };
+ std::vector<std::string> members;
+ std::string method;
+ std::ostringstream out;
- // finally add suffix and store url
- ss << d_url_suffix;
+ // perform request
+ YaHTTP::Request req;
- req.setup(verb, ss.str());
- req.headers["accept"] = "application/json";
-}
+ if (d_post)
+ post_requestbuilder(input, req);
+ else
+ restful_requestbuilder(input["method"].string_value(), input["parameters"], req);
-void HTTPConnector::post_requestbuilder(const Json& input, YaHTTP::Request& req) {
- if (this->d_post_json) {
- std::string out = input.dump();
- req.setup("POST", d_url);
- // simple case, POST JSON into url. nothing fancy.
- req.headers["Content-Type"] = "text/javascript; charset=utf-8";
- req.headers["Content-Length"] = std::to_string(out.size());
- req.headers["accept"] = "application/json";
- req.body = out;
- } else {
- std::stringstream url,content;
- // call url/method.suffix
- url << d_url << "/" << input["method"].string_value() << d_url_suffix;
- req.setup("POST", url.str());
- // then build content
- req.POST()["parameters"] = input["parameters"].dump();
- req.preparePost();
- req.headers["accept"] = "application/json";
- }
-}
+ rv = -1;
+ req.headers["connection"] = "Keep-Alive"; // see if we can streamline requests (not needed, strictly speaking)
-int HTTPConnector::send_message(const Json& input) {
- int rv,ec,fd;
-
- std::vector<std::string> members;
- std::string method;
- std::ostringstream out;
-
- // perform request
- YaHTTP::Request req;
-
- if (d_post)
- post_requestbuilder(input, req);
- else
- restful_requestbuilder(input["method"].string_value(), input["parameters"], req);
-
- rv = -1;
- req.headers["connection"] = "Keep-Alive"; // see if we can streamline requests (not needed, strictly speaking)
-
- out << req;
-
- // try sending with current socket, if it fails retry with new socket
- if (this->d_socket != nullptr) {
- fd = this->d_socket->getHandle();
- // there should be no data waiting
- if (waitForRWData(fd, true, 0, 1000) < 1) {
- try {
- d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
- rv = 1;
- } catch (NetworkError& ne) {
- g_log<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": "<<ne.what()<<std::endl;
- } catch (...) {
- g_log<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": exception caught"<<std::endl;
- }
- }
- }
+ out << req;
- if (rv == 1) return rv;
-
- this->d_socket.reset();
-
- // connect using tcp
- struct addrinfo *gAddr, *gAddrPtr, hints;
- std::string sPort = std::to_string(d_port);
- memset(&hints,0,sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_ADDRCONFIG;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- if ((ec = getaddrinfo(d_host.c_str(), sPort.c_str(), &hints, &gAddr)) == 0) {
- // try to connect to each address.
- gAddrPtr = gAddr;
-
- while(gAddrPtr) {
- try {
- d_socket = std::unique_ptr<Socket>(new Socket(gAddrPtr->ai_family, gAddrPtr->ai_socktype, gAddrPtr->ai_protocol));
- d_addr.setSockaddr(gAddrPtr->ai_addr, gAddrPtr->ai_addrlen);
- d_socket->connect(d_addr);
- d_socket->setNonBlocking();
- d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
- rv = 1;
- } catch (NetworkError& ne) {
- g_log<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": "<<ne.what()<<std::endl;
- } catch (...) {
- g_log<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": exception caught"<<std::endl;
- }
-
- if (rv > -1) break;
- d_socket.reset();
- gAddrPtr = gAddrPtr->ai_next;
+ // try sending with current socket, if it fails retry with new socket
+ if (this->d_socket != nullptr) {
+ fd = this->d_socket->getHandle();
+ // there should be no data waiting
+ if (waitForRWData(fd, true, 0, 1000) < 1) {
+ try {
+ d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
+ rv = 1;
+ }
+ catch (NetworkError& ne) {
+ g_log << Logger::Error << "While writing to HTTP endpoint " << d_addr.toStringWithPort() << ": " << ne.what() << std::endl;
+ }
+ catch (...) {
+ g_log << Logger::Error << "While writing to HTTP endpoint " << d_addr.toStringWithPort() << ": exception caught" << std::endl;
}
- freeaddrinfo(gAddr);
- } else {
- g_log<<Logger::Error<<"Unable to resolve " << d_host << ": " << gai_strerror(ec) << std::endl;
}
+ }
+ if (rv == 1)
return rv;
-}
-int HTTPConnector::recv_message(Json& output) {
- YaHTTP::AsyncResponseLoader arl;
- YaHTTP::Response resp;
-
- if (d_socket == nullptr ) return -1; // cannot receive :(
- char buffer[4096];
- int rd = -1;
- time_t t0;
-
- arl.initialize(&resp);
-
- try {
- t0 = time((time_t*)NULL);
- while(arl.ready() == false && (labs(time((time_t*)NULL) - t0) <= timeout)) {
- rd = d_socket->readWithTimeout(buffer, sizeof(buffer), timeout);
- if (rd==0)
- throw NetworkError("EOF while reading");
- if (rd<0)
- throw NetworkError(std::string(strerror(rd)));
- arl.feed(std::string(buffer, rd));
+ this->d_socket.reset();
+
+ // connect using tcp
+ struct addrinfo *gAddr, *gAddrPtr, hints;
+ std::string sPort = std::to_string(d_port);
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_ADDRCONFIG;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ if ((ec = getaddrinfo(d_host.c_str(), sPort.c_str(), &hints, &gAddr)) == 0) {
+ // try to connect to each address.
+ gAddrPtr = gAddr;
+
+ while (gAddrPtr) {
+ try {
+ d_socket = std::unique_ptr<Socket>(new Socket(gAddrPtr->ai_family, gAddrPtr->ai_socktype, gAddrPtr->ai_protocol));
+ d_addr.setSockaddr(gAddrPtr->ai_addr, gAddrPtr->ai_addrlen);
+ d_socket->connect(d_addr);
+ d_socket->setNonBlocking();
+ d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
+ rv = 1;
}
- // timeout occurred.
- if (arl.ready() == false)
- throw NetworkError("timeout");
- } catch (NetworkError &ne) {
- d_socket.reset();
- throw PDNSException("While reading from HTTP endpoint " + d_addr.toStringWithPort() + ": " + ne.what());
- } catch (...) {
+ catch (NetworkError& ne) {
+ g_log << Logger::Error << "While writing to HTTP endpoint " << d_addr.toStringWithPort() << ": " << ne.what() << std::endl;
+ }
+ catch (...) {
+ g_log << Logger::Error << "While writing to HTTP endpoint " << d_addr.toStringWithPort() << ": exception caught" << std::endl;
+ }
+
+ if (rv > -1)
+ break;
d_socket.reset();
- throw PDNSException("While reading from HTTP endpoint " + d_addr.toStringWithPort() + ": unknown error");
+ gAddrPtr = gAddrPtr->ai_next;
}
+ freeaddrinfo(gAddr);
+ }
+ else {
+ g_log << Logger::Error << "Unable to resolve " << d_host << ": " << gai_strerror(ec) << std::endl;
+ }
- arl.finalize();
+ return rv;
+}
- if ((resp.status < 200 || resp.status >= 400) && resp.status != 404) {
- // bad.
- throw PDNSException("Received unacceptable HTTP status code " + std::to_string(resp.status) + " from HTTP endpoint " + d_addr.toStringWithPort());
+int HTTPConnector::recv_message(Json& output)
+{
+ YaHTTP::AsyncResponseLoader arl;
+ YaHTTP::Response resp;
+
+ if (d_socket == nullptr)
+ return -1; // cannot receive :(
+ char buffer[4096];
+ int rd = -1;
+ time_t t0;
+
+ arl.initialize(&resp);
+
+ try {
+ t0 = time((time_t*)NULL);
+ while (arl.ready() == false && (labs(time((time_t*)NULL) - t0) <= timeout)) {
+ rd = d_socket->readWithTimeout(buffer, sizeof(buffer), timeout);
+ if (rd == 0)
+ throw NetworkError("EOF while reading");
+ if (rd < 0)
+ throw NetworkError(std::string(strerror(rd)));
+ arl.feed(std::string(buffer, rd));
}
-
- int rv = -1;
- std::string err;
- output = Json::parse(resp.body, err);
- if (output != nullptr) return resp.body.size();
- g_log<<Logger::Error<<"Cannot parse JSON reply: "<<err<<endl;
-
- return rv;
+ // timeout occurred.
+ if (arl.ready() == false)
+ throw NetworkError("timeout");
+ }
+ catch (NetworkError& ne) {
+ d_socket.reset();
+ throw PDNSException("While reading from HTTP endpoint " + d_addr.toStringWithPort() + ": " + ne.what());
+ }
+ catch (...) {
+ d_socket.reset();
+ throw PDNSException("While reading from HTTP endpoint " + d_addr.toStringWithPort() + ": unknown error");
+ }
+
+ arl.finalize();
+
+ if ((resp.status < 200 || resp.status >= 400) && resp.status != 404) {
+ // bad.
+ throw PDNSException("Received unacceptable HTTP status code " + std::to_string(resp.status) + " from HTTP endpoint " + d_addr.toStringWithPort());
+ }
+
+ int rv = -1;
+ std::string err;
+ output = Json::parse(resp.body, err);
+ if (output != nullptr)
+ return resp.body.size();
+ g_log << Logger::Error << "Cannot parse JSON reply: " << err << endl;
+
+ return rv;
}
#endif
#include "remotebackend.hh"
-PipeConnector::PipeConnector(std::map<std::string,std::string> optionsMap): d_pid(-1) {
+PipeConnector::PipeConnector(std::map<std::string, std::string> optionsMap) :
+ d_pid(-1)
+{
if (optionsMap.count("command") == 0) {
- g_log<<Logger::Error<<"Cannot find 'command' option in connection string"<<endl;
+ g_log << Logger::Error << "Cannot find 'command' option in connection string" << endl;
throw PDNSException();
}
this->command = optionsMap.find("command")->second;
this->options = optionsMap;
- d_timeout=2000;
+ d_timeout = 2000;
if (optionsMap.find("timeout") != optionsMap.end()) {
- d_timeout = std::stoi(optionsMap.find("timeout")->second);
+ d_timeout = std::stoi(optionsMap.find("timeout")->second);
}
d_fd1[0] = d_fd1[1] = -1;
d_fd2[0] = d_fd2[1] = -1;
}
-PipeConnector::~PipeConnector(){
+PipeConnector::~PipeConnector()
+{
int status;
// just in case...
- if (d_pid == -1) return;
+ if (d_pid == -1)
+ return;
- if(!waitpid(d_pid, &status, WNOHANG)) {
+ if (!waitpid(d_pid, &status, WNOHANG)) {
kill(d_pid, 9);
waitpid(d_pid, &status, 0);
}
}
}
-void PipeConnector::launch() {
+void PipeConnector::launch()
+{
// no relaunch
- if (d_pid > 0 && checkStatus()) return;
+ if (d_pid > 0 && checkStatus())
+ return;
- std::vector <std::string> v;
+ std::vector<std::string> v;
split(v, command, boost::is_any_of(" "));
- std::vector<const char *>argv(v.size()+1);
- argv[v.size()]=0;
+ std::vector<const char*> argv(v.size() + 1);
+ argv[v.size()] = 0;
for (size_t n = 0; n < v.size(); n++)
- argv[n]=v[n].c_str();
+ argv[n] = v[n].c_str();
signal(SIGPIPE, SIG_IGN);
- if(access(argv[0],X_OK)) // check before fork so we can throw
- throw PDNSException("Command '"+string(argv[0])+"' cannot be executed: "+stringerror());
+ if (access(argv[0], X_OK)) // check before fork so we can throw
+ throw PDNSException("Command '" + string(argv[0]) + "' cannot be executed: " + stringerror());
- if(pipe(d_fd1)<0 || pipe(d_fd2)<0)
- throw PDNSException("Unable to open pipe for coprocess: "+string(strerror(errno)));
+ if (pipe(d_fd1) < 0 || pipe(d_fd2) < 0)
+ throw PDNSException("Unable to open pipe for coprocess: " + string(strerror(errno)));
- if((d_pid=fork())<0)
- throw PDNSException("Unable to fork for coprocess: "+stringerror());
- else if(d_pid>0) { // parent speaking
+ if ((d_pid = fork()) < 0)
+ throw PDNSException("Unable to fork for coprocess: " + stringerror());
+ else if (d_pid > 0) { // parent speaking
close(d_fd1[0]);
setCloseOnExec(d_fd1[1]);
close(d_fd2[1]);
setCloseOnExec(d_fd2[0]);
- if(!(d_fp=std::unique_ptr<FILE, int(*)(FILE*)>(fdopen(d_fd2[0],"r"), fclose)))
- throw PDNSException("Unable to associate a file pointer with pipe: "+stringerror());
+ if (!(d_fp = std::unique_ptr<FILE, int (*)(FILE*)>(fdopen(d_fd2[0], "r"), fclose)))
+ throw PDNSException("Unable to associate a file pointer with pipe: " + stringerror());
if (d_timeout)
- setbuf(d_fp.get(),0); // no buffering please, confuses poll
+ setbuf(d_fp.get(), 0); // no buffering please, confuses poll
}
- else if(!d_pid) { // child
+ else if (!d_pid) { // child
signal(SIGCHLD, SIG_DFL); // silence a warning from perl
close(d_fd1[1]);
close(d_fd2[0]);
- if(d_fd1[0]!= 0) {
+ if (d_fd1[0] != 0) {
dup2(d_fd1[0], 0);
close(d_fd1[0]);
}
- if(d_fd2[1]!= 1) {
+ if (d_fd2[1] != 1) {
dup2(d_fd2[1], 1);
close(d_fd2[1]);
}
// stdin & stdout are now connected, fire up our coprocess!
- if(execv(argv[0], const_cast<char * const *>(argv.data()))<0) // now what
+ if (execv(argv[0], const_cast<char* const*>(argv.data())) < 0) // now what
exit(123);
/* not a lot we can do here. We shouldn't return because that will leave a forked process around.
Json::array parameters;
Json msg = Json(Json::object{
- { "method", "initialize" },
- { "parameters", Json(options) },
+ {"method", "initialize"},
+ {"parameters", Json(options)},
});
this->send(msg);
msg = nullptr;
- if (this->recv(msg)==false) {
- g_log<<Logger::Error<<"Failed to initialize coprocess"<<std::endl;
+ if (this->recv(msg) == false) {
+ g_log << Logger::Error << "Failed to initialize coprocess" << std::endl;
}
}
int PipeConnector::send_message(const Json& input)
{
- auto line = input.dump();
- launch();
+ auto line = input.dump();
+ launch();
- line.append(1,'\n');
+ line.append(1, '\n');
- unsigned int sent=0;
- int bytes;
+ unsigned int sent = 0;
+ int bytes;
- // writen routine - socket may not accept al data in one go
- while(sent<line.size()) {
- bytes=write(d_fd1[1],line.c_str()+sent,line.length()-sent);
- if(bytes<0)
- throw PDNSException("Writing to coprocess failed: "+std::string(strerror(errno)));
+ // writen routine - socket may not accept al data in one go
+ while (sent < line.size()) {
+ bytes = write(d_fd1[1], line.c_str() + sent, line.length() - sent);
+ if (bytes < 0)
+ throw PDNSException("Writing to coprocess failed: " + std::string(strerror(errno)));
- sent+=bytes;
- }
- return sent;
+ sent += bytes;
+ }
+ return sent;
}
int PipeConnector::recv_message(Json& output)
{
- std::string receive;
- std::string err;
- std::string s_output;
- launch();
-
- while(1) {
- receive.clear();
- if(d_timeout) {
- int ret=waitForData(fileno(d_fp.get()), 0, d_timeout * 1000);
- if(ret<0)
- throw PDNSException("Error waiting on data from coprocess: "+stringerror());
- if(!ret)
- throw PDNSException("Timeout waiting for data from coprocess");
- }
-
- if(!stringfgets(d_fp.get(), receive))
- throw PDNSException("Child closed pipe");
-
- s_output.append(receive);
- // see if it can be parsed
- output = Json::parse(s_output, err);
- if (output != nullptr) return s_output.size();
- }
- return 0;
+ std::string receive;
+ std::string err;
+ std::string s_output;
+ launch();
+
+ while (1) {
+ receive.clear();
+ if (d_timeout) {
+ int ret = waitForData(fileno(d_fp.get()), 0, d_timeout * 1000);
+ if (ret < 0)
+ throw PDNSException("Error waiting on data from coprocess: " + stringerror());
+ if (!ret)
+ throw PDNSException("Timeout waiting for data from coprocess");
+ }
+
+ if (!stringfgets(d_fp.get(), receive))
+ throw PDNSException("Child closed pipe");
+
+ s_output.append(receive);
+ // see if it can be parsed
+ output = Json::parse(s_output, err);
+ if (output != nullptr)
+ return s_output.size();
+ }
+ return 0;
}
bool PipeConnector::checkStatus()
{
int status;
- int ret=waitpid(d_pid, &status, WNOHANG);
- if(ret<0)
- throw PDNSException("Unable to ascertain status of coprocess "+itoa(d_pid)+" from "+itoa(getpid())+": "+string(strerror(errno)));
- else if(ret) {
- if(WIFEXITED(status)) {
- int exitStatus=WEXITSTATUS(status);
- throw PDNSException("Coprocess exited with code "+itoa(exitStatus));
+ int ret = waitpid(d_pid, &status, WNOHANG);
+ if (ret < 0)
+ throw PDNSException("Unable to ascertain status of coprocess " + itoa(d_pid) + " from " + itoa(getpid()) + ": " + string(strerror(errno)));
+ else if (ret) {
+ if (WIFEXITED(status)) {
+ int exitStatus = WEXITSTATUS(status);
+ throw PDNSException("Coprocess exited with code " + itoa(exitStatus));
}
- if(WIFSIGNALED(status)) {
- int sig=WTERMSIG(status);
- string reason="CoProcess died on receiving signal "+itoa(sig);
+ if (WIFSIGNALED(status)) {
+ int sig = WTERMSIG(status);
+ string reason = "CoProcess died on receiving signal " + itoa(sig);
#ifdef WCOREDUMP
- if(WCOREDUMP(status))
- reason+=". Dumped core";
+ if (WCOREDUMP(status))
+ reason += ". Dumped core";
#endif
throw PDNSException(reason);
#endif
#include "remotebackend.hh"
-static const char *kBackendId = "[RemoteBackend]";
+static const char* kBackendId = "[RemoteBackend]";
/**
* Forwarder for value. This is just in case
* we need to do some treatment to the value before
* sending it downwards.
*/
-bool Connector::send(Json& value) {
- return send_message(value)>0;
+bool Connector::send(Json& value)
+{
+ return send_message(value) > 0;
}
/**
* that the receiving happened ok, and extract
* result. Logging is performed here, too.
*/
-bool Connector::recv(Json& value) {
+bool Connector::recv(Json& value)
+{
if (recv_message(value) > 0) {
bool retval = true;
if (value["result"] == Json()) {
throw PDNSException("No 'result' field in response from remote process");
- } else if (value["result"].is_bool() && boolFromJson(value, "result", false) == false) {
+ }
+ else if (value["result"].is_bool() && boolFromJson(value, "result", false) == false) {
retval = false;
}
- for(const auto& message: value["log"].array_items()) {
- g_log<<Logger::Info<<"[remotebackend]: "<< message.string_value() <<std::endl;
+ for (const auto& message : value["log"].array_items()) {
+ g_log << Logger::Info << "[remotebackend]: " << message.string_value() << std::endl;
}
return retval;
}
throw PDNSException("Unknown error while receiving data");
}
-void RemoteBackend::makeErrorAndThrow(Json &value) {
+void RemoteBackend::makeErrorAndThrow(Json& value)
+{
std::string msg = "Remote process indicated a failure";
- for(const auto& message: value["log"].array_items()) {
+ for (const auto& message : value["log"].array_items()) {
msg += " '" + message.string_value() + "'";
}
throw PDNSException(msg);
/**
* Standard ctor and dtor
*/
-RemoteBackend::RemoteBackend(const std::string &suffix)
+RemoteBackend::RemoteBackend(const std::string& suffix)
{
- setArgPrefix("remote"+suffix);
+ setArgPrefix("remote" + suffix);
- this->d_connstr = getArg("connection-string");
- this->d_dnssec = mustDo("dnssec");
- this->d_index = -1;
- this->d_trxid = 0;
+ this->d_connstr = getArg("connection-string");
+ this->d_dnssec = mustDo("dnssec");
+ this->d_index = -1;
+ this->d_trxid = 0;
- build();
+ build();
}
-RemoteBackend::~RemoteBackend() { }
+RemoteBackend::~RemoteBackend() {}
-bool RemoteBackend::send(Json& value) {
+bool RemoteBackend::send(Json& value)
+{
try {
if (!connector->send(value)) {
// XXX does this work work even though we throw?
build();
throw DBException("Could not send a message to remote process");
}
- } catch (const PDNSException &ex) {
+ }
+ catch (const PDNSException& ex) {
throw DBException("Exception caught when sending: " + ex.reason);
}
return true;
}
-bool RemoteBackend::recv(Json& value) {
+bool RemoteBackend::recv(Json& value)
+{
try {
return connector->recv(value);
- } catch (const PDNSException &ex) {
+ }
+ catch (const PDNSException& ex) {
this->connector.reset();
build();
throw DBException("Exception caught when receiving: " + ex.reason);
- } catch (const std::exception &e) {
+ }
+ catch (const std::exception& e) {
this->connector.reset();
build();
throw DBException("Exception caught when receiving: " + std::string(e.what()));
}
}
-
/**
* Builds connector based on options
* Currently supports unix,pipe and http
*/
-int RemoteBackend::build() {
- std::vector<std::string> parts;
- std::string type;
- std::string opts;
- std::map<std::string, std::string> options;
-
- // connstr is of format "type:options"
- size_t pos;
- pos = d_connstr.find_first_of(":");
- if (pos == std::string::npos)
- throw PDNSException("Invalid connection string: malformed");
-
- type = d_connstr.substr(0, pos);
- opts = d_connstr.substr(pos+1);
-
- // tokenize the string on comma
- stringtok(parts, opts, ",");
-
- // find out some options and parse them while we're at it
- for(const auto& opt: parts) {
- std::string key,val;
- // make sure there is something else than air in the option...
- if (opt.find_first_not_of(" ") == std::string::npos) continue;
-
- // split it on '='. if not found, we treat it as "yes"
- pos = opt.find_first_of("=");
-
- if (pos == std::string::npos) {
- key = opt;
- val = "yes";
- } else {
- key = opt.substr(0,pos);
- val = opt.substr(pos+1);
- }
- options[key] = val;
- }
-
- // connectors know what they are doing
- if (type == "unix") {
- this->connector = std::unique_ptr<Connector>(new UnixsocketConnector(options));
- } else if (type == "http") {
- this->connector = std::unique_ptr<Connector>(new HTTPConnector(options));
- } else if (type == "zeromq") {
+int RemoteBackend::build()
+{
+ std::vector<std::string> parts;
+ std::string type;
+ std::string opts;
+ std::map<std::string, std::string> options;
+
+ // connstr is of format "type:options"
+ size_t pos;
+ pos = d_connstr.find_first_of(":");
+ if (pos == std::string::npos)
+ throw PDNSException("Invalid connection string: malformed");
+
+ type = d_connstr.substr(0, pos);
+ opts = d_connstr.substr(pos + 1);
+
+ // tokenize the string on comma
+ stringtok(parts, opts, ",");
+
+ // find out some options and parse them while we're at it
+ for (const auto& opt : parts) {
+ std::string key, val;
+ // make sure there is something else than air in the option...
+ if (opt.find_first_not_of(" ") == std::string::npos)
+ continue;
+
+ // split it on '='. if not found, we treat it as "yes"
+ pos = opt.find_first_of("=");
+
+ if (pos == std::string::npos) {
+ key = opt;
+ val = "yes";
+ }
+ else {
+ key = opt.substr(0, pos);
+ val = opt.substr(pos + 1);
+ }
+ options[key] = val;
+ }
+
+ // connectors know what they are doing
+ if (type == "unix") {
+ this->connector = std::unique_ptr<Connector>(new UnixsocketConnector(options));
+ }
+ else if (type == "http") {
+ this->connector = std::unique_ptr<Connector>(new HTTPConnector(options));
+ }
+ else if (type == "zeromq") {
#ifdef REMOTEBACKEND_ZEROMQ
- this->connector = std::unique_ptr<Connector>(new ZeroMQConnector(options));
+ this->connector = std::unique_ptr<Connector>(new ZeroMQConnector(options));
#else
- throw PDNSException("Invalid connection string: zeromq connector support not enabled. Recompile with --enable-remotebackend-zeromq");
+ throw PDNSException("Invalid connection string: zeromq connector support not enabled. Recompile with --enable-remotebackend-zeromq");
#endif
- } else if (type == "pipe") {
- this->connector = std::unique_ptr<Connector>(new PipeConnector(options));
- } else {
- throw PDNSException("Invalid connection string: unknown connector");
- }
+ }
+ else if (type == "pipe") {
+ this->connector = std::unique_ptr<Connector>(new PipeConnector(options));
+ }
+ else {
+ throw PDNSException("Invalid connection string: unknown connector");
+ }
- return -1;
+ return -1;
}
/**
* The functions here are just remote json stubs that send and receive the method call
* data is mainly left alone, some defaults are assumed.
*/
-void RemoteBackend::lookup(const QType &qtype, const DNSName& qdomain, int zoneId, DNSPacket *pkt_p) {
- if (d_index != -1)
- throw PDNSException("Attempt to lookup while one running");
-
- string localIP="0.0.0.0";
- string remoteIP="0.0.0.0";
- string realRemote="0.0.0.0/0";
-
- if (pkt_p) {
- localIP=pkt_p->getLocal().toString();
- realRemote = pkt_p->getRealRemote().toString();
- remoteIP = pkt_p->getRemote().toString();
- }
-
- Json query = Json::object{
- { "method", "lookup" },
- { "parameters", Json::object{
- { "qtype", qtype.getName() },
- { "qname", qdomain.toString() },
- { "remote", remoteIP },
- { "local", localIP },
- { "real-remote", realRemote },
- { "zone-id", zoneId }
- }}
- };
-
- if (this->send(query) == false || this->recv(d_result) == false) {
- return;
- }
-
- // OK. we have result parameters in result. do not process empty result.
- if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
- return;
-
- d_index = 0;
-}
+void RemoteBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p)
+{
+ if (d_index != -1)
+ throw PDNSException("Attempt to lookup while one running");
-bool RemoteBackend::list(const DNSName& target, int domain_id, bool include_disabled) {
- if (d_index != -1)
- throw PDNSException("Attempt to lookup while one running");
-
- Json query = Json::object{
- { "method", "list" },
- { "parameters", Json::object{
- { "zonename", target.toString() },
- { "domain_id", domain_id },
- { "include_disabled", include_disabled }
- }}
- };
-
- if (this->send(query) == false || this->recv(d_result) == false)
- return false;
- if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
- return false;
-
- d_index = 0;
- return true;
-}
+ string localIP = "0.0.0.0";
+ string remoteIP = "0.0.0.0";
+ string realRemote = "0.0.0.0/0";
-bool RemoteBackend::get(DNSResourceRecord &rr) {
- if (d_index == -1) return false;
-
- rr.qtype = stringFromJson(d_result["result"][d_index], "qtype");
- rr.qname = DNSName(stringFromJson(d_result["result"][d_index], "qname"));
- rr.qclass = QClass::IN;
- rr.content = stringFromJson(d_result["result"][d_index], "content");
- rr.ttl = d_result["result"][d_index]["ttl"].int_value();
- rr.domain_id = intFromJson(d_result["result"][d_index], "domain_id", -1);
- if (d_dnssec)
- rr.auth = intFromJson(d_result["result"][d_index], "auth", 1);
- else
- rr.auth = 1;
- rr.scopeMask = d_result["result"][d_index]["scopeMask"].int_value();
- d_index++;
-
- // id index is out of bounds, we know the results end here.
- if (d_index == static_cast<int>(d_result["result"].array_items().size())) {
- d_result = Json();
- d_index = -1;
- }
- return true;
+ if (pkt_p) {
+ localIP = pkt_p->getLocal().toString();
+ realRemote = pkt_p->getRealRemote().toString();
+ remoteIP = pkt_p->getRemote().toString();
+ }
+
+ Json query = Json::object{
+ {"method", "lookup"},
+ {"parameters", Json::object{{"qtype", qtype.getName()}, {"qname", qdomain.toString()}, {"remote", remoteIP}, {"local", localIP}, {"real-remote", realRemote}, {"zone-id", zoneId}}}};
+
+ if (this->send(query) == false || this->recv(d_result) == false) {
+ return;
+ }
+
+ // OK. we have result parameters in result. do not process empty result.
+ if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
+ return;
+
+ d_index = 0;
}
-bool RemoteBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
-
- Json query = Json::object{
- { "method", "getBeforeAndAfterNamesAbsolute" },
- { "parameters", Json::object {
- { "id", Json(static_cast<double>(id)) },
- { "qname", qname.toString() }
- }}
- };
- Json answer;
-
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- unhashed = DNSName(stringFromJson(answer["result"], "unhashed"));
- before.clear();
- after.clear();
- if (answer["result"]["before"] != Json())
- before = DNSName(stringFromJson(answer["result"], "before"));
- if (answer["result"]["after"] != Json())
- after = DNSName(stringFromJson(answer["result"], "after"));
-
- return true;
+bool RemoteBackend::list(const DNSName& target, int domain_id, bool include_disabled)
+{
+ if (d_index != -1)
+ throw PDNSException("Attempt to lookup while one running");
+
+ Json query = Json::object{
+ {"method", "list"},
+ {"parameters", Json::object{{"zonename", target.toString()}, {"domain_id", domain_id}, {"include_disabled", include_disabled}}}};
+
+ if (this->send(query) == false || this->recv(d_result) == false)
+ return false;
+ if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
+ return false;
+
+ d_index = 0;
+ return true;
}
-bool RemoteBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) {
- Json query = Json::object{
- { "method", "getAllDomainMetadata" },
- { "parameters", Json::object {
- { "name", name.toString() }
- }}
- };
-
- if (this->send(query) == false)
- return false;
-
- meta.clear();
-
- Json answer;
- // not mandatory to implement
- if (this->recv(answer) == false)
- return true;
-
- for(const auto& pair: answer["result"].object_items()) {
- if (pair.second.is_array()) {
- for(const auto& val: pair.second.array_items())
- meta[pair.first].push_back(asString(val));
- } else {
- meta[pair.first].push_back(asString(pair.second));
- }
- }
-
- return true;
+bool RemoteBackend::get(DNSResourceRecord& rr)
+{
+ if (d_index == -1)
+ return false;
+
+ rr.qtype = stringFromJson(d_result["result"][d_index], "qtype");
+ rr.qname = DNSName(stringFromJson(d_result["result"][d_index], "qname"));
+ rr.qclass = QClass::IN;
+ rr.content = stringFromJson(d_result["result"][d_index], "content");
+ rr.ttl = d_result["result"][d_index]["ttl"].int_value();
+ rr.domain_id = intFromJson(d_result["result"][d_index], "domain_id", -1);
+ if (d_dnssec)
+ rr.auth = intFromJson(d_result["result"][d_index], "auth", 1);
+ else
+ rr.auth = 1;
+ rr.scopeMask = d_result["result"][d_index]["scopeMask"].int_value();
+ d_index++;
+
+ // id index is out of bounds, we know the results end here.
+ if (d_index == static_cast<int>(d_result["result"].array_items().size())) {
+ d_result = Json();
+ d_index = -1;
+ }
+ return true;
}
-bool RemoteBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) {
- Json query = Json::object{
- { "method", "getDomainMetadata" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "kind", kind }
- }}
- };
-
- if (this->send(query) == false)
- return false;
-
- meta.clear();
-
- Json answer;
- // not mandatory to implement
- if (this->recv(answer) == false)
- return true;
-
- if (answer["result"].is_array()) {
- for(const auto& row: answer["result"].array_items())
- meta.push_back(row.string_value());
- } else if (answer["result"].is_string()) {
- meta.push_back(answer["result"].string_value());
- }
-
- return true;
+bool RemoteBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
+
+ Json query = Json::object{
+ {"method", "getBeforeAndAfterNamesAbsolute"},
+ {"parameters", Json::object{{"id", Json(static_cast<double>(id))}, {"qname", qname.toString()}}}};
+ Json answer;
+
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ unhashed = DNSName(stringFromJson(answer["result"], "unhashed"));
+ before.clear();
+ after.clear();
+ if (answer["result"]["before"] != Json())
+ before = DNSName(stringFromJson(answer["result"], "before"));
+ if (answer["result"]["after"] != Json())
+ after = DNSName(stringFromJson(answer["result"], "after"));
+
+ return true;
}
-bool RemoteBackend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) {
- Json query = Json::object{
- { "method", "setDomainMetadata" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "kind", kind },
- { "value", meta }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- return boolFromJson(answer, "result", false);
+bool RemoteBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
+{
+ Json query = Json::object{
+ {"method", "getAllDomainMetadata"},
+ {"parameters", Json::object{{"name", name.toString()}}}};
+
+ if (this->send(query) == false)
+ return false;
+
+ meta.clear();
+
+ Json answer;
+ // not mandatory to implement
+ if (this->recv(answer) == false)
+ return true;
+
+ for (const auto& pair : answer["result"].object_items()) {
+ if (pair.second.is_array()) {
+ for (const auto& val : pair.second.array_items())
+ meta[pair.first].push_back(asString(val));
+ }
+ else {
+ meta[pair.first].push_back(asString(pair.second));
+ }
+ }
+
+ return true;
}
+bool RemoteBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
+{
+ Json query = Json::object{
+ {"method", "getDomainMetadata"},
+ {"parameters", Json::object{{"name", name.toString()}, {"kind", kind}}}};
-bool RemoteBackend::getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+ if (this->send(query) == false)
+ return false;
- Json query = Json::object{
- { "method", "getDomainKeys" },
- { "parameters", Json::object{
- { "name", name.toString() }
- }}
- };
+ meta.clear();
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ // not mandatory to implement
+ if (this->recv(answer) == false)
+ return true;
- keys.clear();
+ if (answer["result"].is_array()) {
+ for (const auto& row : answer["result"].array_items())
+ meta.push_back(row.string_value());
+ }
+ else if (answer["result"].is_string()) {
+ meta.push_back(answer["result"].string_value());
+ }
- for(const auto& jsonKey: answer["result"].array_items()) {
- DNSBackend::KeyData key;
- key.id = intFromJson(jsonKey, "id");
- key.flags = intFromJson(jsonKey, "flags");
- key.active = asBool(jsonKey["active"]);
- key.published = boolFromJson(jsonKey, "published", true);
- key.content = stringFromJson(jsonKey, "content");
- keys.push_back(key);
- }
+ return true;
+}
+
+bool RemoteBackend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
+{
+ Json query = Json::object{
+ {"method", "setDomainMetadata"},
+ {"parameters", Json::object{{"name", name.toString()}, {"kind", kind}, {"value", meta}}}};
- return true;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ return boolFromJson(answer, "result", false);
}
-bool RemoteBackend::removeDomainKey(const DNSName& name, unsigned int id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "removeDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "id", static_cast<int>(id) }
- }}
- };
+ Json query = Json::object{
+ {"method", "getDomainKeys"},
+ {"parameters", Json::object{{"name", name.toString()}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- return true;
+ keys.clear();
+
+ for (const auto& jsonKey : answer["result"].array_items()) {
+ DNSBackend::KeyData key;
+ key.id = intFromJson(jsonKey, "id");
+ key.flags = intFromJson(jsonKey, "flags");
+ key.active = asBool(jsonKey["active"]);
+ key.published = boolFromJson(jsonKey, "published", true);
+ key.content = stringFromJson(jsonKey, "content");
+ keys.push_back(key);
+ }
+
+ return true;
}
-bool RemoteBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
-
- Json query = Json::object{
- { "method", "addDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "key", Json::object {
- { "flags", static_cast<int>(key.flags) },
- { "active", key.active },
- { "published", key.published },
- { "content", key.content }
- }}
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- id = answer["result"].int_value();
- return id >= 0;
+bool RemoteBackend::removeDomainKey(const DNSName& name, unsigned int id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
+
+ Json query = Json::object{
+ {"method", "removeDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast<int>(id)}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ return true;
}
-bool RemoteBackend::activateDomainKey(const DNSName& name, unsigned int id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "activateDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "id", static_cast<int>(id) }
- }}
- };
+ Json query = Json::object{
+ {"method", "addDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"key", Json::object{{"flags", static_cast<int>(key.flags)}, {"active", key.active}, {"published", key.published}, {"content", key.content}}}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- return true;
+ id = answer["result"].int_value();
+ return id >= 0;
}
-bool RemoteBackend::deactivateDomainKey(const DNSName& name, unsigned int id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::activateDomainKey(const DNSName& name, unsigned int id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "deactivateDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "id", static_cast<int>(id) }
- }}
- };
+ Json query = Json::object{
+ {"method", "activateDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast<int>(id)}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- return true;
+ return true;
}
-bool RemoteBackend::publishDomainKey(const DNSName& name, unsigned int id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::deactivateDomainKey(const DNSName& name, unsigned int id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "publishDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "id", static_cast<int>(id) }
- }}
- };
+ Json query = Json::object{
+ {"method", "deactivateDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast<int>(id)}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- return true;
+ return true;
}
-bool RemoteBackend::unpublishDomainKey(const DNSName& name, unsigned int id) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::publishDomainKey(const DNSName& name, unsigned int id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "unpublishDomainKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "id", static_cast<int>(id) }
- }}
- };
+ Json query = Json::object{
+ {"method", "publishDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast<int>(id)}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- return true;
+ return true;
}
+bool RemoteBackend::unpublishDomainKey(const DNSName& name, unsigned int id)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
+
+ Json query = Json::object{
+ {"method", "unpublishDomainKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast<int>(id)}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ return true;
+}
-bool RemoteBackend::doesDNSSEC() {
- return d_dnssec;
+bool RemoteBackend::doesDNSSEC()
+{
+ return d_dnssec;
}
-bool RemoteBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, std::string* content) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, std::string* content)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "getTSIGKey" },
- { "parameters", Json::object {
- { "name", name.toString() }
- }}
- };
+ Json query = Json::object{
+ {"method", "getTSIGKey"},
+ {"parameters", Json::object{{"name", name.toString()}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- (*algorithm) = DNSName(stringFromJson(answer["result"], "algorithm"));
- (*content) = stringFromJson(answer["result"], "content");
+ (*algorithm) = DNSName(stringFromJson(answer["result"], "algorithm"));
+ (*content) = stringFromJson(answer["result"], "content");
- return true;
+ return true;
}
-bool RemoteBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const std::string& content) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
+bool RemoteBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const std::string& content)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
- Json query = Json::object{
- { "method", "setTSIGKey" },
- { "parameters", Json::object {
- { "name", name.toString() },
- { "algorithm", algorithm.toString() },
- { "content", content }
- }}
- };
+ Json query = Json::object{
+ {"method", "setTSIGKey"},
+ {"parameters", Json::object{{"name", name.toString()}, {"algorithm", algorithm.toString()}, {"content", content}}}};
- Json answer;
- if (connector->send(query) == false || connector->recv(answer) == false)
- return false;
+ Json answer;
+ if (connector->send(query) == false || connector->recv(answer) == false)
+ return false;
- return true;
+ return true;
}
-bool RemoteBackend::deleteTSIGKey(const DNSName& name) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
- Json query = Json::object{
- { "method", "deleteTSIGKey" },
- { "parameters", Json::object {
- { "name", name.toString() }
- }}
- };
-
- Json answer;
- if (connector->send(query) == false || connector->recv(answer) == false)
- return false;
-
- return true;
+bool RemoteBackend::deleteTSIGKey(const DNSName& name)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
+ Json query = Json::object{
+ {"method", "deleteTSIGKey"},
+ {"parameters", Json::object{{"name", name.toString()}}}};
+
+ Json answer;
+ if (connector->send(query) == false || connector->recv(answer) == false)
+ return false;
+
+ return true;
}
-bool RemoteBackend::getTSIGKeys(std::vector<struct TSIGKey>& keys) {
- // no point doing dnssec if it's not supported
- if (d_dnssec == false) return false;
- Json query = Json::object{
- { "method", "getTSIGKeys" },
- { "parameters", Json::object {
- }}
- };
-
- Json answer;
- if (connector->send(query) == false || connector->recv(answer) == false)
- return false;
-
- for(const auto& jsonKey: answer["result"].array_items()) {
- struct TSIGKey key;
- key.name = DNSName(stringFromJson(jsonKey, "name"));
- key.algorithm = DNSName(stringFromJson(jsonKey, "algorithm"));
- key.key = stringFromJson(jsonKey, "content");
- keys.push_back(key);
- }
-
- return true;
+bool RemoteBackend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
+{
+ // no point doing dnssec if it's not supported
+ if (d_dnssec == false)
+ return false;
+ Json query = Json::object{
+ {"method", "getTSIGKeys"},
+ {"parameters", Json::object{}}};
+
+ Json answer;
+ if (connector->send(query) == false || connector->recv(answer) == false)
+ return false;
+
+ for (const auto& jsonKey : answer["result"].array_items()) {
+ struct TSIGKey key;
+ key.name = DNSName(stringFromJson(jsonKey, "name"));
+ key.algorithm = DNSName(stringFromJson(jsonKey, "algorithm"));
+ key.key = stringFromJson(jsonKey, "content");
+ keys.push_back(key);
+ }
+
+ return true;
}
-void RemoteBackend::parseDomainInfo(const Json &obj, DomainInfo &di)
+void RemoteBackend::parseDomainInfo(const Json& obj, DomainInfo& di)
{
- di.id = intFromJson(obj, "id", -1);
- di.zone = DNSName(stringFromJson(obj, "zone"));
- for(const auto& master: obj["masters"].array_items())
- di.masters.push_back(ComboAddress(master.string_value(), 53));
-
- di.notified_serial = static_cast<unsigned int>(doubleFromJson(obj, "notified_serial", 0));
- di.serial = static_cast<unsigned int>(obj["serial"].number_value());
- di.last_check = static_cast<time_t>(obj["last_check"].number_value());
-
- string kind = "";
- if (obj["kind"].is_string()) {
- kind = stringFromJson(obj, "kind");
- }
- if (kind == "master") {
- di.kind = DomainInfo::Master;
- } else if (kind == "slave") {
- di.kind = DomainInfo::Slave;
- } else {
- di.kind = DomainInfo::Native;
- }
- di.backend = this;
+ di.id = intFromJson(obj, "id", -1);
+ di.zone = DNSName(stringFromJson(obj, "zone"));
+ for (const auto& master : obj["masters"].array_items())
+ di.masters.push_back(ComboAddress(master.string_value(), 53));
+
+ di.notified_serial = static_cast<unsigned int>(doubleFromJson(obj, "notified_serial", 0));
+ di.serial = static_cast<unsigned int>(obj["serial"].number_value());
+ di.last_check = static_cast<time_t>(obj["last_check"].number_value());
+
+ string kind = "";
+ if (obj["kind"].is_string()) {
+ kind = stringFromJson(obj, "kind");
+ }
+ if (kind == "master") {
+ di.kind = DomainInfo::Master;
+ }
+ else if (kind == "slave") {
+ di.kind = DomainInfo::Slave;
+ }
+ else {
+ di.kind = DomainInfo::Native;
+ }
+ di.backend = this;
}
-bool RemoteBackend::getDomainInfo(const DNSName& domain, DomainInfo &di, bool getSerial) {
- if (domain.empty()) return false;
- Json query = Json::object{
- { "method", "getDomainInfo" },
- { "parameters", Json::object {
- { "name", domain.toString() }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- this->parseDomainInfo(answer["result"], di);
- return true;
+bool RemoteBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
+{
+ if (domain.empty())
+ return false;
+ Json query = Json::object{
+ {"method", "getDomainInfo"},
+ {"parameters", Json::object{{"name", domain.toString()}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ this->parseDomainInfo(answer["result"], di);
+ return true;
}
-void RemoteBackend::setNotified(uint32_t id, uint32_t serial) {
- Json query = Json::object{
- { "method", "setNotified" },
- { "parameters", Json::object {
- { "id", static_cast<double>(id) },
- { "serial", static_cast<double>(serial) }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false) {
- g_log<<Logger::Error<<kBackendId<<" Failed to execute RPC for RemoteBackend::setNotified("<<id<<","<<serial<<")"<<endl;
- }
+void RemoteBackend::setNotified(uint32_t id, uint32_t serial)
+{
+ Json query = Json::object{
+ {"method", "setNotified"},
+ {"parameters", Json::object{{"id", static_cast<double>(id)}, {"serial", static_cast<double>(serial)}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false) {
+ g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setNotified(" << id << "," << serial << ")" << endl;
+ }
}
-bool RemoteBackend::superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string* nameserver, string *account, DNSBackend **ddb)
+bool RemoteBackend::superMasterBackend(const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** ddb)
{
- Json::array rrset;
-
- for(const auto& ns: nsset) {
- rrset.push_back(Json::object{
- { "qtype", ns.qtype.getName() },
- { "qname", ns.qname.toString() },
- { "qclass", QClass::IN },
- { "content", ns.content },
- { "ttl", static_cast<int>(ns.ttl) },
- { "auth", ns.auth }
- });
- }
-
- Json query = Json::object{
- { "method", "superMasterBackend" },
- { "parameters", Json::object {
- { "ip", ip },
- { "domain", domain.toString() },
- { "nsset", rrset }
- }}
- };
-
- *ddb = 0;
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- // we are the backend
- *ddb = this;
-
- // we allow simple true as well...
- if (answer["result"].is_object()) {
- *account = stringFromJson(answer["result"], "account");
- *nameserver = stringFromJson(answer["result"], "nameserver");
- }
-
- return true;
+ Json::array rrset;
+
+ for (const auto& ns : nsset) {
+ rrset.push_back(Json::object{
+ {"qtype", ns.qtype.getName()},
+ {"qname", ns.qname.toString()},
+ {"qclass", QClass::IN},
+ {"content", ns.content},
+ {"ttl", static_cast<int>(ns.ttl)},
+ {"auth", ns.auth}});
+ }
+
+ Json query = Json::object{
+ {"method", "superMasterBackend"},
+ {"parameters", Json::object{{"ip", ip}, {"domain", domain.toString()}, {"nsset", rrset}}}};
+
+ *ddb = 0;
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ // we are the backend
+ *ddb = this;
+
+ // we allow simple true as well...
+ if (answer["result"].is_object()) {
+ *account = stringFromJson(answer["result"], "account");
+ *nameserver = stringFromJson(answer["result"], "nameserver");
+ }
+
+ return true;
}
-bool RemoteBackend::createSlaveDomain(const string &ip, const DNSName& domain, const string& nameserver, const string &account) {
- Json query = Json::object{
- { "method", "createSlaveDomain" },
- { "parameters", Json::object {
- { "ip", ip },
- { "domain", domain.toString() },
- { "nameserver", nameserver },
- { "account", account },
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true;
+bool RemoteBackend::createSlaveDomain(const string& ip, const DNSName& domain, const string& nameserver, const string& account)
+{
+ Json query = Json::object{
+ {"method", "createSlaveDomain"},
+ {"parameters", Json::object{
+ {"ip", ip},
+ {"domain", domain.toString()},
+ {"nameserver", nameserver},
+ {"account", account},
+ }}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true;
}
-bool RemoteBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qtype, const vector<DNSResourceRecord>& rrset) {
- Json::array json_rrset;
- for(const auto& rr: rrset) {
- json_rrset.push_back(Json::object{
- { "qtype", rr.qtype.getName() },
- { "qname", rr.qname.toString() },
- { "qclass", QClass::IN },
- { "content", rr.content },
- { "ttl", static_cast<int>(rr.ttl) },
- { "auth", rr.auth }
- });
- }
-
- Json query = Json::object{
- { "method", "replaceRRSet" },
- { "parameters", Json::object {
- { "domain_id", static_cast<double>(domain_id) },
- { "qname", qname.toString() },
- { "qtype", qtype.getName() },
- { "trxid", static_cast<double>(d_trxid) },
- { "rrset", json_rrset }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
-
- return true;
+bool RemoteBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qtype, const vector<DNSResourceRecord>& rrset)
+{
+ Json::array json_rrset;
+ for (const auto& rr : rrset) {
+ json_rrset.push_back(Json::object{
+ {"qtype", rr.qtype.getName()},
+ {"qname", rr.qname.toString()},
+ {"qclass", QClass::IN},
+ {"content", rr.content},
+ {"ttl", static_cast<int>(rr.ttl)},
+ {"auth", rr.auth}});
+ }
+
+ Json query = Json::object{
+ {"method", "replaceRRSet"},
+ {"parameters", Json::object{{"domain_id", static_cast<double>(domain_id)}, {"qname", qname.toString()}, {"qtype", qtype.getName()}, {"trxid", static_cast<double>(d_trxid)}, {"rrset", json_rrset}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+
+ return true;
}
-bool RemoteBackend::feedRecord(const DNSResourceRecord &rr, const DNSName &ordername, bool ordernameIsNSEC3) {
- Json query = Json::object{
- { "method", "feedRecord" },
- { "parameters", Json::object{
- { "rr", Json::object{
- { "qtype", rr.qtype.getName() },
- { "qname", rr.qname.toString() },
- { "qclass", QClass::IN },
- { "content", rr.content },
- { "ttl", static_cast<int>(rr.ttl) },
- { "auth", rr.auth },
- { "ordername", (ordername.empty()?Json():ordername.toString()) }
- }},
- { "trxid", static_cast<double>(d_trxid) },
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true; // XXX FIXME this API should not return 'true' I think -ahu
+bool RemoteBackend::feedRecord(const DNSResourceRecord& rr, const DNSName& ordername, bool ordernameIsNSEC3)
+{
+ Json query = Json::object{
+ {"method", "feedRecord"},
+ {"parameters", Json::object{
+ {"rr", Json::object{{"qtype", rr.qtype.getName()}, {"qname", rr.qname.toString()}, {"qclass", QClass::IN}, {"content", rr.content}, {"ttl", static_cast<int>(rr.ttl)}, {"auth", rr.auth}, {"ordername", (ordername.empty() ? Json() : ordername.toString())}}},
+ {"trxid", static_cast<double>(d_trxid)},
+ }}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true; // XXX FIXME this API should not return 'true' I think -ahu
}
-bool RemoteBackend::feedEnts(int domain_id, map<DNSName,bool>& nonterm) {
- Json::array nts;
-
- for(const auto& t: nonterm)
- nts.push_back(Json::object{
- { "nonterm", t.first.toString() },
- { "auth", t.second }
- });
-
- Json query = Json::object{
- { "method", "feedEnts" },
- { "parameters", Json::object{
- { "domain_id", domain_id },
- { "trxid", static_cast<double>(d_trxid) },
- { "nonterm", nts }
- }},
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true;
+bool RemoteBackend::feedEnts(int domain_id, map<DNSName, bool>& nonterm)
+{
+ Json::array nts;
+
+ for (const auto& t : nonterm)
+ nts.push_back(Json::object{
+ {"nonterm", t.first.toString()},
+ {"auth", t.second}});
+
+ Json query = Json::object{
+ {"method", "feedEnts"},
+ {"parameters", Json::object{{"domain_id", domain_id}, {"trxid", static_cast<double>(d_trxid)}, {"nonterm", nts}}},
+ };
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true;
}
-bool RemoteBackend::feedEnts3(int domain_id, const DNSName& domain, map<DNSName,bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) {
- Json::array nts;
-
- for(const auto& t: nonterm)
- nts.push_back(Json::object{
- { "nonterm", t.first.toString() },
- { "auth", t.second }
- });
-
- Json query = Json::object{
- { "method", "feedEnts3" },
- { "parameters", Json::object{
- { "domain_id", domain_id },
- { "domain", domain.toString() },
- { "times", ns3prc.d_iterations },
- { "salt", ns3prc.d_salt },
- { "narrow", narrow },
- { "trxid", static_cast<double>(d_trxid) },
- { "nonterm", nts }
- }},
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true;
+bool RemoteBackend::feedEnts3(int domain_id, const DNSName& domain, map<DNSName, bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow)
+{
+ Json::array nts;
+
+ for (const auto& t : nonterm)
+ nts.push_back(Json::object{
+ {"nonterm", t.first.toString()},
+ {"auth", t.second}});
+
+ Json query = Json::object{
+ {"method", "feedEnts3"},
+ {"parameters", Json::object{{"domain_id", domain_id}, {"domain", domain.toString()}, {"times", ns3prc.d_iterations}, {"salt", ns3prc.d_salt}, {"narrow", narrow}, {"trxid", static_cast<double>(d_trxid)}, {"nonterm", nts}}},
+ };
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true;
}
-bool RemoteBackend::startTransaction(const DNSName& domain, int domain_id) {
- this->d_trxid = time((time_t*)NULL);
-
- Json query = Json::object{
- { "method", "startTransaction" },
- { "parameters", Json::object{
- { "domain", domain.toString() },
- { "domain_id", domain_id },
- { "trxid", static_cast<double>(d_trxid) }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false) {
- d_trxid = -1;
- return false;
- }
- return true;
+bool RemoteBackend::startTransaction(const DNSName& domain, int domain_id)
+{
+ this->d_trxid = time((time_t*)NULL);
+
+ Json query = Json::object{
+ {"method", "startTransaction"},
+ {"parameters", Json::object{{"domain", domain.toString()}, {"domain_id", domain_id}, {"trxid", static_cast<double>(d_trxid)}}}};
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false) {
+ d_trxid = -1;
+ return false;
+ }
+ return true;
}
-bool RemoteBackend::commitTransaction() {
- if (d_trxid == -1) return false;
-
- Json query = Json::object{
- { "method", "commitTransaction" },
- { "parameters", Json::object{
- { "trxid", static_cast<double>(d_trxid) }
- }}
- };
-
- d_trxid = -1;
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true;
+bool RemoteBackend::commitTransaction()
+{
+ if (d_trxid == -1)
+ return false;
+
+ Json query = Json::object{
+ {"method", "commitTransaction"},
+ {"parameters", Json::object{{"trxid", static_cast<double>(d_trxid)}}}};
+
+ d_trxid = -1;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true;
}
-bool RemoteBackend::abortTransaction() {
- if (d_trxid == -1) return false;
-
- Json query = Json::object{
- { "method", "abortTransaction" },
- { "parameters", Json::object{
- { "trxid", static_cast<double>(d_trxid) }
- }}
- };
-
- d_trxid = -1;
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
- return true;
+bool RemoteBackend::abortTransaction()
+{
+ if (d_trxid == -1)
+ return false;
+
+ Json query = Json::object{
+ {"method", "abortTransaction"},
+ {"parameters", Json::object{{"trxid", static_cast<double>(d_trxid)}}}};
+
+ d_trxid = -1;
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
+ return true;
}
-string RemoteBackend::directBackendCmd(const string& querystr) {
- Json query = Json::object{
- { "method", "directBackendCmd" },
- { "parameters", Json::object{
- { "query", querystr }
- }}
- };
+string RemoteBackend::directBackendCmd(const string& querystr)
+{
+ Json query = Json::object{
+ {"method", "directBackendCmd"},
+ {"parameters", Json::object{{"query", querystr}}}};
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false)
- return "backend command failed";
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return "backend command failed";
- return asString(answer["result"]);
+ return asString(answer["result"]);
}
-bool RemoteBackend::searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result)
+bool RemoteBackend::searchRecords(const string& pattern, int maxResults, vector<DNSResourceRecord>& result)
{
Json query = Json::object{
- { "method", "searchRecords" },
- { "parameters", Json::object{
- { "pattern", pattern },
- { "maxResults", maxResults }
- }}
- };
+ {"method", "searchRecords"},
+ {"parameters", Json::object{{"pattern", pattern}, {"maxResults", maxResults}}}};
Json answer;
if (this->send(query) == false || this->recv(answer) == false)
if (answer["result"].is_array() == false)
return false;
- for(const auto& row: answer["result"].array_items()) {
+ for (const auto& row : answer["result"].array_items()) {
DNSResourceRecord rr;
rr.qtype = stringFromJson(row, "qtype");
rr.qname = DNSName(stringFromJson(row, "qname"));
return true;
}
-bool RemoteBackend::searchComments(const string &pattern, int maxResults, vector<Comment>& result)
+bool RemoteBackend::searchComments(const string& pattern, int maxResults, vector<Comment>& result)
{
// FIXME: Implement Comment API
return false;
}
-void RemoteBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabled)
+void RemoteBackend::getAllDomains(vector<DomainInfo>* domains, bool include_disabled)
{
Json query = Json::object{
- { "method", "getAllDomains" },
- { "parameters", Json::object{
- { "include_disabled", include_disabled }
- }}
- };
+ {"method", "getAllDomains"},
+ {"parameters", Json::object{{"include_disabled", include_disabled}}}};
Json answer;
if (this->send(query) == false || this->recv(answer) == false)
if (answer["result"].is_array() == false)
return;
-
- for(const auto& row: answer["result"].array_items()) {
+
+ for (const auto& row : answer["result"].array_items()) {
DomainInfo di;
this->parseDomainInfo(row, di);
domains->push_back(di);
}
}
-void RemoteBackend::alsoNotifies(const DNSName &domain, set<string> *ips)
+void RemoteBackend::alsoNotifies(const DNSName& domain, set<string>* ips)
{
std::vector<std::string> meta;
getDomainMetadata(domain, "ALSO-NOTIFY", meta);
void RemoteBackend::getUpdatedMasters(vector<DomainInfo>* domains)
{
Json query = Json::object{
- { "method", "getUpdatedMasters" },
- { "parameters", Json::object{ } },
+ {"method", "getUpdatedMasters"},
+ {"parameters", Json::object{}},
};
Json answer;
if (answer["result"].is_array() == false)
return;
- for(const auto& row: answer["result"].array_items()) {
+ for (const auto& row : answer["result"].array_items()) {
DomainInfo di;
this->parseDomainInfo(row, di);
domains->push_back(di);
}
}
-void RemoteBackend::getUnfreshSlaveInfos(vector<DomainInfo>* domains) {
+void RemoteBackend::getUnfreshSlaveInfos(vector<DomainInfo>* domains)
+{
Json query = Json::object{
- { "method", "getUnfreshSlaveInfos" },
- { "parameters", Json::object{ } },
+ {"method", "getUnfreshSlaveInfos"},
+ {"parameters", Json::object{}},
};
Json answer;
if (answer["result"].is_array() == false)
return;
- for(const auto& row: answer["result"].array_items()) {
+ for (const auto& row : answer["result"].array_items()) {
DomainInfo di;
this->parseDomainInfo(row, di);
domains->push_back(di);
}
}
-void RemoteBackend::setFresh(uint32_t domain_id) {
- Json query = Json::object{
- { "method", "setFresh" },
- { "parameters", Json::object {
- { "id", static_cast<double>(domain_id) }
- }}
- };
-
- Json answer;
- if (this->send(query) == false || this->recv(answer) == false) {
- g_log<<Logger::Error<<kBackendId<<" Failed to execute RPC for RemoteBackend::setFresh("<<domain_id<<")"<<endl;
- }
+void RemoteBackend::setFresh(uint32_t domain_id)
+{
+ Json query = Json::object{
+ {"method", "setFresh"},
+ {"parameters", Json::object{{"id", static_cast<double>(domain_id)}}}};
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false) {
+ g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setFresh(" << domain_id << ")" << endl;
+ }
}
-DNSBackend *RemoteBackend::maker()
+DNSBackend* RemoteBackend::maker()
{
- try {
- return new RemoteBackend();
- }
- catch(...) {
- g_log<<Logger::Error<<kBackendId<<" Unable to instantiate a remotebackend!"<<endl;
- return 0;
- };
+ try {
+ return new RemoteBackend();
+ }
+ catch (...) {
+ g_log << Logger::Error << kBackendId << " Unable to instantiate a remotebackend!" << endl;
+ return 0;
+ };
}
-
-
class RemoteBackendFactory : public BackendFactory
{
- public:
- RemoteBackendFactory() : BackendFactory("remote") {}
-
- void declareArguments(const std::string &suffix="") override
- {
- declare(suffix,"dnssec","Enable dnssec support","no");
- declare(suffix,"connection-string","Connection string","");
- }
-
- DNSBackend *make(const std::string &suffix="") override
- {
- return new RemoteBackend(suffix);
- }
+public:
+ RemoteBackendFactory() :
+ BackendFactory("remote") {}
+
+ void declareArguments(const std::string& suffix = "") override
+ {
+ declare(suffix, "dnssec", "Enable dnssec support", "no");
+ declare(suffix, "connection-string", "Connection string", "");
+ }
+
+ DNSBackend* make(const std::string& suffix = "") override
+ {
+ return new RemoteBackend(suffix);
+ }
};
class RemoteLoader
{
public:
- RemoteLoader();
+ RemoteLoader();
};
-
-RemoteLoader::RemoteLoader() {
- BackendMakers().report(new RemoteBackendFactory);
- g_log << Logger::Info << kBackendId << " This is the remote backend version " VERSION
+RemoteLoader::RemoteLoader()
+{
+ BackendMakers().report(new RemoteBackendFactory);
+ g_log << Logger::Info << kBackendId << " This is the remote backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
static RemoteLoader remoteloader;
using json11::Json;
-class Connector {
- public:
- virtual ~Connector() {};
- bool send(Json &value);
- bool recv(Json &value);
- virtual int send_message(const Json &input) = 0;
- virtual int recv_message(Json &output) = 0;
- protected:
- string asString(const Json& value) {
- if (value.is_number()) return std::to_string(value.int_value());
- if (value.is_bool()) return (value.bool_value()?"1":"0");
- if (value.is_string()) return value.string_value();
- throw JsonException("Json value not convertible to String");
- };
+class Connector
+{
+public:
+ virtual ~Connector(){};
+ bool send(Json& value);
+ bool recv(Json& value);
+ virtual int send_message(const Json& input) = 0;
+ virtual int recv_message(Json& output) = 0;
+
+protected:
+ string asString(const Json& value)
+ {
+ if (value.is_number())
+ return std::to_string(value.int_value());
+ if (value.is_bool())
+ return (value.bool_value() ? "1" : "0");
+ if (value.is_string())
+ return value.string_value();
+ throw JsonException("Json value not convertible to String");
+ };
};
// fwd declarations
-class UnixsocketConnector: public Connector {
- public:
- UnixsocketConnector(std::map<std::string,std::string> options);
- virtual ~UnixsocketConnector();
- virtual int send_message(const Json &input);
- virtual int recv_message(Json &output);
- private:
- ssize_t read(std::string &data);
- ssize_t write(const std::string &data);
- void reconnect();
- std::map<std::string,std::string> options;
- int fd;
- std::string path;
- bool connected;
- int timeout;
+class UnixsocketConnector : public Connector
+{
+public:
+ UnixsocketConnector(std::map<std::string, std::string> options);
+ virtual ~UnixsocketConnector();
+ virtual int send_message(const Json& input);
+ virtual int recv_message(Json& output);
+
+private:
+ ssize_t read(std::string& data);
+ ssize_t write(const std::string& data);
+ void reconnect();
+ std::map<std::string, std::string> options;
+ int fd;
+ std::string path;
+ bool connected;
+ int timeout;
};
-class HTTPConnector: public Connector {
- public:
-
- HTTPConnector(std::map<std::string,std::string> options);
+class HTTPConnector : public Connector
+{
+public:
+ HTTPConnector(std::map<std::string, std::string> options);
~HTTPConnector();
- virtual int send_message(const Json &input);
- virtual int recv_message(Json &output);
- private:
- std::string d_url;
- std::string d_url_suffix;
- std::string d_data;
- int timeout;
- bool d_post;
- bool d_post_json;
- void restful_requestbuilder(const std::string &method, const Json ¶meters, YaHTTP::Request& req);
- void post_requestbuilder(const Json &input, YaHTTP::Request& req);
- void addUrlComponent(const Json ¶meters, const string& element, std::stringstream& ss);
- std::string buildMemberListArgs(std::string prefix, const Json& args);
- std::unique_ptr<Socket> d_socket;
- ComboAddress d_addr;
- std::string d_host;
- uint16_t d_port;
+ virtual int send_message(const Json& input);
+ virtual int recv_message(Json& output);
+
+private:
+ std::string d_url;
+ std::string d_url_suffix;
+ std::string d_data;
+ int timeout;
+ bool d_post;
+ bool d_post_json;
+ void restful_requestbuilder(const std::string& method, const Json& parameters, YaHTTP::Request& req);
+ void post_requestbuilder(const Json& input, YaHTTP::Request& req);
+ void addUrlComponent(const Json& parameters, const string& element, std::stringstream& ss);
+ std::string buildMemberListArgs(std::string prefix, const Json& args);
+ std::unique_ptr<Socket> d_socket;
+ ComboAddress d_addr;
+ std::string d_host;
+ uint16_t d_port;
};
#ifdef REMOTEBACKEND_ZEROMQ
-class ZeroMQConnector: public Connector {
- public:
- ZeroMQConnector(std::map<std::string,std::string> options);
- virtual ~ZeroMQConnector();
- virtual int send_message(const Json &input);
- virtual int recv_message(Json &output);
- private:
- void connect();
- std::string d_endpoint;
- int d_timeout;
- int d_timespent;
- std::map<std::string,std::string> d_options;
- std::unique_ptr<void, int(*)(void*)> d_ctx;
- std::unique_ptr<void, int(*)(void*)> d_sock;
+class ZeroMQConnector : public Connector
+{
+public:
+ ZeroMQConnector(std::map<std::string, std::string> options);
+ virtual ~ZeroMQConnector();
+ virtual int send_message(const Json& input);
+ virtual int recv_message(Json& output);
+
+private:
+ void connect();
+ std::string d_endpoint;
+ int d_timeout;
+ int d_timespent;
+ std::map<std::string, std::string> d_options;
+ std::unique_ptr<void, int (*)(void*)> d_ctx;
+ std::unique_ptr<void, int (*)(void*)> d_sock;
};
#endif
-class PipeConnector: public Connector {
- public:
-
- PipeConnector(std::map<std::string,std::string> options);
+class PipeConnector : public Connector
+{
+public:
+ PipeConnector(std::map<std::string, std::string> options);
~PipeConnector();
- virtual int send_message(const Json &input);
- virtual int recv_message(Json &output);
-
- private:
+ virtual int send_message(const Json& input);
+ virtual int recv_message(Json& output);
+private:
void launch();
bool checkStatus();
std::string command;
- std::map<std::string,std::string> options;
-
+ std::map<std::string, std::string> options;
+
int d_fd1[2], d_fd2[2];
int d_pid;
int d_timeout;
- std::unique_ptr<FILE, int(*)(FILE*)> d_fp{nullptr, fclose};
+ std::unique_ptr<FILE, int (*)(FILE*)> d_fp{nullptr, fclose};
};
class RemoteBackend : public DNSBackend
{
- public:
- RemoteBackend(const std::string &suffix="");
+public:
+ RemoteBackend(const std::string& suffix = "");
~RemoteBackend();
- void lookup(const QType &qtype, const DNSName& qdomain, int zoneId=-1, DNSPacket *pkt_p=nullptr) override;
- bool get(DNSResourceRecord &rr) override;
- bool list(const DNSName& target, int domain_id, bool include_disabled=false) override;
+ void lookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr) override;
+ bool get(DNSResourceRecord& rr) override;
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override;
- bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override;
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta) override;
bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override;
bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) override;
bool getTSIGKey(const DNSName& name, DNSName* algorithm, std::string* content) override;
bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override;
- bool setDomainMetadata(const DNSName& name, const string& kind, const std::vector<std::basic_string<char> >& meta) override;
+ bool setDomainMetadata(const DNSName& name, const string& kind, const std::vector<std::basic_string<char>>& meta) override;
bool removeDomainKey(const DNSName& name, unsigned int id) override;
bool addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) override;
bool activateDomainKey(const DNSName& name, unsigned int id) override;
bool deactivateDomainKey(const DNSName& name, unsigned int id) override;
bool publishDomainKey(const DNSName& name, unsigned int id) override;
bool unpublishDomainKey(const DNSName& name, unsigned int id) override;
- bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial=true ) override;
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
void setNotified(uint32_t id, uint32_t serial) override;
bool doesDNSSEC() override;
- bool superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **ddb) override;
- bool createSlaveDomain(const string &ip, const DNSName& domain, const string& nameserver, const string &account) override;
+ bool superMasterBackend(const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** ddb) override;
+ bool createSlaveDomain(const string& ip, const DNSName& domain, const string& nameserver, const string& account) override;
bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) override;
- bool feedRecord(const DNSResourceRecord &r, const DNSName &ordername, bool ordernameIsNSEC3=false) override;
- bool feedEnts(int domain_id, map<DNSName,bool>& nonterm) override;
- bool feedEnts3(int domain_id, const DNSName& domain, map<DNSName,bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
+ bool feedRecord(const DNSResourceRecord& r, const DNSName& ordername, bool ordernameIsNSEC3 = false) override;
+ bool feedEnts(int domain_id, map<DNSName, bool>& nonterm) override;
+ bool feedEnts3(int domain_id, const DNSName& domain, map<DNSName, bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
bool startTransaction(const DNSName& domain, int domain_id) override;
bool commitTransaction() override;
bool abortTransaction() override;
bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) override;
bool deleteTSIGKey(const DNSName& name) override;
- bool getTSIGKeys(std::vector< struct TSIGKey > &keys) override;
+ bool getTSIGKeys(std::vector<struct TSIGKey>& keys) override;
string directBackendCmd(const string& querystr) override;
- bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result) override;
- bool searchComments(const string &pattern, int maxResults, vector<Comment>& result) override;
- void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
+ bool searchRecords(const string& pattern, int maxResults, vector<DNSResourceRecord>& result) override;
+ bool searchComments(const string& pattern, int maxResults, vector<Comment>& result) override;
+ void getAllDomains(vector<DomainInfo>* domains, bool include_disabled = false) override;
void getUpdatedMasters(vector<DomainInfo>* domains) override;
- void alsoNotifies(const DNSName &domain, set<string> *ips) override;
+ void alsoNotifies(const DNSName& domain, set<string>* ips) override;
void getUnfreshSlaveInfos(vector<DomainInfo>* domains) override;
void setFresh(uint32_t domain_id) override;
- static DNSBackend *maker();
-
- private:
- int build();
- std::unique_ptr<Connector> connector;
- bool d_dnssec;
- Json d_result;
- int d_index;
- int64_t d_trxid;
- std::string d_connstr;
-
- bool send(Json &value);
- bool recv(Json &value);
- void makeErrorAndThrow(Json &value);
-
- string asString(const Json& value) {
- if (value.is_number()) return std::to_string(value.int_value());
- if (value.is_bool()) return (value.bool_value()?"1":"0");
- if (value.is_string()) return value.string_value();
- throw JsonException("Json value not convertible to String");
- };
-
- bool asBool(const Json& value) {
- if (value.is_bool()) return value.bool_value();
- try {
- string val = asString(value);
- if (val == "0") return false;
- if (val == "1") return true;
- } catch (const JsonException&) {};
- throw JsonException("Json value not convertible to boolean");
+ static DNSBackend* maker();
+
+private:
+ int build();
+ std::unique_ptr<Connector> connector;
+ bool d_dnssec;
+ Json d_result;
+ int d_index;
+ int64_t d_trxid;
+ std::string d_connstr;
+
+ bool send(Json& value);
+ bool recv(Json& value);
+ void makeErrorAndThrow(Json& value);
+
+ string asString(const Json& value)
+ {
+ if (value.is_number())
+ return std::to_string(value.int_value());
+ if (value.is_bool())
+ return (value.bool_value() ? "1" : "0");
+ if (value.is_string())
+ return value.string_value();
+ throw JsonException("Json value not convertible to String");
+ };
+
+ bool asBool(const Json& value)
+ {
+ if (value.is_bool())
+ return value.bool_value();
+ try {
+ string val = asString(value);
+ if (val == "0")
+ return false;
+ if (val == "1")
+ return true;
+ }
+ catch (const JsonException&) {
};
+ throw JsonException("Json value not convertible to boolean");
+ };
- void parseDomainInfo(const json11::Json &obj, DomainInfo &di);
+ void parseDomainInfo(const json11::Json& obj, DomainInfo& di);
};
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/tuple/tuple.hpp>
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="http:url=http://localhost:62434/dns";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "http:url=http://localhost:62434/dns";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/tuple/tuple.hpp>
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="http:url=http://localhost:62434/dns/endpoint.json,post=1,post_json=1";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "http:url=http://localhost:62434/dns/endpoint.json,post=1,post_json=1";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-DNSBackend::KeyData k1 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: qpe9fxlN4dBT38cLPWtqljZhcJjbqRprj9XsYmf2/uFu4kA5sHYrlQY7H9lpzGJPRfOAfxShBpKs1AVaVInfJQ==\nPublicExponent: AQAB\nPrivateExponent: Ad3YogzXvVDLsWuAfioY571QlolbdTbzVlhLEMLD6dSRx+xcZgw6c27ak2HAH00iSKTvqK3AyeaK8Eqy/oJ5QQ==\nPrime1: wo8LZrdU2y0xLGCeLhwziQDDtTMi18NEIwlx8tUPnhs=\nPrime2: 4HcuFqgo7NOiXFvN+V2PT+QaIt2+oi6D2m8/qtTDS78=\nExponent1: GUdCoPbi9JM7l1t6Ud1iKMPLqchaF5SMTs0UXAuous8=\nExponent2: nzgKqimX9f1corTAEw0pddrwKyEtcu8ZuhzFhZCsAxM=\nCoefficient: YGNxbulf5GTNiIu0oNKmAF0khNtx9layjOPEI0R4/RY="), 1, 257, true, true };
+DNSBackend::KeyData k1 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: qpe9fxlN4dBT38cLPWtqljZhcJjbqRprj9XsYmf2/uFu4kA5sHYrlQY7H9lpzGJPRfOAfxShBpKs1AVaVInfJQ==\nPublicExponent: AQAB\nPrivateExponent: Ad3YogzXvVDLsWuAfioY571QlolbdTbzVlhLEMLD6dSRx+xcZgw6c27ak2HAH00iSKTvqK3AyeaK8Eqy/oJ5QQ==\nPrime1: wo8LZrdU2y0xLGCeLhwziQDDtTMi18NEIwlx8tUPnhs=\nPrime2: 4HcuFqgo7NOiXFvN+V2PT+QaIt2+oi6D2m8/qtTDS78=\nExponent1: GUdCoPbi9JM7l1t6Ud1iKMPLqchaF5SMTs0UXAuous8=\nExponent2: nzgKqimX9f1corTAEw0pddrwKyEtcu8ZuhzFhZCsAxM=\nCoefficient: YGNxbulf5GTNiIu0oNKmAF0khNtx9layjOPEI0R4/RY="), 1, 257, true, true};
-DNSBackend::KeyData k2 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: tY2TAMgL/whZdSbn2aci4wcMqohO24KQAaq5RlTRwQ33M8FYdW5fZ3DMdMsSLQUkjGnKJPKEdN3Qd4Z5b18f+w==\nPublicExponent: AQAB\nPrivateExponent: BB6xibPNPrBV0PUp3CQq0OdFpk9v9EZ2NiBFrA7osG5mGIZICqgOx/zlHiHKmX4OLmL28oU7jPKgogeuONXJQQ==\nPrime1: yjxe/iHQ4IBWpvCmuGqhxApWF+DY9LADIP7bM3Ejf3M=\nPrime2: 5dGWTyYEQRBVK74q1a64iXgaNuYm1pbClvvZ6ccCq1k=\nExponent1: TwM5RebmWeAqerzJFoIqw5IaQugJO8hM4KZR9A4/BTs=\nExponent2: bpV2HSmu3Fvuj7jWxbFoDIXlH0uJnrI2eg4/4hSnvSk=\nCoefficient: e2uDDWN2zXwYa2P6VQBWQ4mR1ZZjFEtO/+YqOJZun1Y="), 2, 256, true, true };
+DNSBackend::KeyData k2 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: tY2TAMgL/whZdSbn2aci4wcMqohO24KQAaq5RlTRwQ33M8FYdW5fZ3DMdMsSLQUkjGnKJPKEdN3Qd4Z5b18f+w==\nPublicExponent: AQAB\nPrivateExponent: BB6xibPNPrBV0PUp3CQq0OdFpk9v9EZ2NiBFrA7osG5mGIZICqgOx/zlHiHKmX4OLmL28oU7jPKgogeuONXJQQ==\nPrime1: yjxe/iHQ4IBWpvCmuGqhxApWF+DY9LADIP7bM3Ejf3M=\nPrime2: 5dGWTyYEQRBVK74q1a64iXgaNuYm1pbClvvZ6ccCq1k=\nExponent1: TwM5RebmWeAqerzJFoIqw5IaQugJO8hM4KZR9A4/BTs=\nExponent2: bpV2HSmu3Fvuj7jWxbFoDIXlH0uJnrI2eg4/4hSnvSk=\nCoefficient: e2uDDWN2zXwYa2P6VQBWQ4mR1ZZjFEtO/+YqOJZun1Y="), 2, 256, true, true};
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="pipe:command=unittest_pipe.rb";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "pipe:command=unittest_pipe.rb";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
+ // load few record types to help out
+ SOARecordContent::report();
+ NSRecordContent::report();
+ ARecordContent::report();
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
-
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/tuple/tuple.hpp>
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="http:url=http://localhost:62434/dns,post=1";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "http:url=http://localhost:62434/dns,post=1";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="unix:path=/tmp/remotebackend.sock";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "unix:path=/tmp/remotebackend.sock";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
+ // load few record types to help out
+ SOARecordContent::report();
+ NSRecordContent::report();
+ ARecordContent::report();
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
-
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
StatBag S;
AuthPacketCache PC;
AuthQueryCache QC;
-ArgvMap &arg()
+ArgvMap& arg()
{
static ArgvMap arg;
return arg;
class RemoteLoader
{
- public:
- RemoteLoader();
+public:
+ RemoteLoader();
};
-DNSBackend *be;
+DNSBackend* be;
#ifdef REMOTEBACKEND_ZEROMQ
#include <boost/test/unit_test.hpp>
-struct RemotebackendSetup {
- RemotebackendSetup() {
- be = 0;
- try {
- // setup minimum arguments
- ::arg().set("module-dir")="./.libs";
- new RemoteLoader();
- BackendMakers().launch("remote");
- // then get us a instance of it
- ::arg().set("remote-connection-string")="zeromq:endpoint=ipc:///tmp/remotebackend.0";
- ::arg().set("remote-dnssec")="yes";
- be = BackendMakers().all()[0];
- // load few record types to help out
- SOARecordContent::report();
- NSRecordContent::report();
- ARecordContent::report();
- } catch (PDNSException &ex) {
- BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason );
- };
+struct RemotebackendSetup
+{
+ RemotebackendSetup()
+ {
+ be = 0;
+ try {
+ // setup minimum arguments
+ ::arg().set("module-dir") = "./.libs";
+ new RemoteLoader();
+ BackendMakers().launch("remote");
+ // then get us a instance of it
+ ::arg().set("remote-connection-string") = "zeromq:endpoint=ipc:///tmp/remotebackend.0";
+ ::arg().set("remote-dnssec") = "yes";
+ be = BackendMakers().all()[0];
+ // load few record types to help out
+ SOARecordContent::report();
+ NSRecordContent::report();
+ ARecordContent::report();
}
- ~RemotebackendSetup() { }
+ catch (PDNSException& ex) {
+ BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason);
+ };
+ }
+ ~RemotebackendSetup() {}
};
-BOOST_GLOBAL_FIXTURE( RemotebackendSetup );
+BOOST_GLOBAL_FIXTURE(RemotebackendSetup);
#else
#include <iostream>
-int main(void) {
+int main(void)
+{
std::cout << "No HTTP support in remotebackend - skipping test" << std::endl;
return 0;
}
#include "test-remotebackend-keys.hh"
-extern DNSBackend *be;
+extern DNSBackend* be;
BOOST_AUTO_TEST_SUITE(test_remotebackend_so)
-BOOST_AUTO_TEST_CASE(test_method_lookup) {
- BOOST_TEST_MESSAGE("Testing lookup method");
- DNSResourceRecord rr;
- be->lookup(QType(QType::SOA), DNSName("unit.test."));
- // then try to get()
- BOOST_CHECK(be->get(rr)); // and this should be TRUE.
- // then we check rr contains what we expect
- BOOST_CHECK_EQUAL(rr.qname.toString(), "unit.test.");
- BOOST_CHECK_MESSAGE(rr.qtype == QType::SOA, "returned qtype was not SOA");
- BOOST_CHECK_EQUAL(rr.content, "ns.unit.test. hostmaster.unit.test. 1 2 3 4 5");
- BOOST_CHECK_EQUAL(rr.ttl, 300);
+BOOST_AUTO_TEST_CASE(test_method_lookup)
+{
+ BOOST_TEST_MESSAGE("Testing lookup method");
+ DNSResourceRecord rr;
+ be->lookup(QType(QType::SOA), DNSName("unit.test."));
+ // then try to get()
+ BOOST_CHECK(be->get(rr)); // and this should be TRUE.
+ // then we check rr contains what we expect
+ BOOST_CHECK_EQUAL(rr.qname.toString(), "unit.test.");
+ BOOST_CHECK_MESSAGE(rr.qtype == QType::SOA, "returned qtype was not SOA");
+ BOOST_CHECK_EQUAL(rr.content, "ns.unit.test. hostmaster.unit.test. 1 2 3 4 5");
+ BOOST_CHECK_EQUAL(rr.ttl, 300);
}
-BOOST_AUTO_TEST_CASE(test_method_lookup_empty) {
- BOOST_TEST_MESSAGE("Testing lookup method with empty result");
- DNSResourceRecord rr;
- be->lookup(QType(QType::SOA), DNSName("empty.unit.test."));
- // then try to get()
- BOOST_CHECK(!be->get(rr)); // and this should be FALSE
+BOOST_AUTO_TEST_CASE(test_method_lookup_empty)
+{
+ BOOST_TEST_MESSAGE("Testing lookup method with empty result");
+ DNSResourceRecord rr;
+ be->lookup(QType(QType::SOA), DNSName("empty.unit.test."));
+ // then try to get()
+ BOOST_CHECK(!be->get(rr)); // and this should be FALSE
}
-BOOST_AUTO_TEST_CASE(test_method_list) {
- int record_count = 0;
- DNSResourceRecord rr;
+BOOST_AUTO_TEST_CASE(test_method_list)
+{
+ int record_count = 0;
+ DNSResourceRecord rr;
- BOOST_TEST_MESSAGE("Testing list method");
- be->list(DNSName("unit.test."), -1);
- while(be->get(rr)) record_count++;
+ BOOST_TEST_MESSAGE("Testing list method");
+ be->list(DNSName("unit.test."), -1);
+ while (be->get(rr))
+ record_count++;
- BOOST_CHECK_EQUAL(record_count, 5); // number of records our test domain has
+ BOOST_CHECK_EQUAL(record_count, 5); // number of records our test domain has
}
-BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC) {
- BOOST_TEST_MESSAGE("Testing doesDNSSEC method");
- BOOST_CHECK(be->doesDNSSEC()); // should be true
+BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC)
+{
+ BOOST_TEST_MESSAGE("Testing doesDNSSEC method");
+ BOOST_CHECK(be->doesDNSSEC()); // should be true
}
-BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata) {
- std::vector<std::string> meta;
- meta.push_back("VALUE");
- BOOST_TEST_MESSAGE("Testing setDomainMetadata method");
- BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."),"TEST", meta));
+BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata)
+{
+ std::vector<std::string> meta;
+ meta.push_back("VALUE");
+ BOOST_TEST_MESSAGE("Testing setDomainMetadata method");
+ BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "TEST", meta));
}
-BOOST_AUTO_TEST_CASE(test_method_alsoNotifies) {
- BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."),"ALSO-NOTIFY", {"192.0.2.1"}));
- std::set<std::string> alsoNotifies;
- BOOST_TEST_MESSAGE("Testing alsoNotifies method");
- be->alsoNotifies(DNSName("unit.test."), &alsoNotifies);
- BOOST_CHECK_EQUAL(alsoNotifies.size(), 1);
- if (alsoNotifies.size() > 0)
- BOOST_CHECK_EQUAL(alsoNotifies.count("192.0.2.1"), 1);
- BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."),"ALSO-NOTIFY", std::vector<std::string>()));
+BOOST_AUTO_TEST_CASE(test_method_alsoNotifies)
+{
+ BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", {"192.0.2.1"}));
+ std::set<std::string> alsoNotifies;
+ BOOST_TEST_MESSAGE("Testing alsoNotifies method");
+ be->alsoNotifies(DNSName("unit.test."), &alsoNotifies);
+ BOOST_CHECK_EQUAL(alsoNotifies.size(), 1);
+ if (alsoNotifies.size() > 0)
+ BOOST_CHECK_EQUAL(alsoNotifies.count("192.0.2.1"), 1);
+ BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", std::vector<std::string>()));
}
-BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata) {
- std::vector<std::string> meta;
- BOOST_TEST_MESSAGE("Testing getDomainMetadata method");
- be->getDomainMetadata(DNSName("unit.test."),"TEST", meta);
- BOOST_CHECK_EQUAL(meta.size(), 1);
- // in case we got more than one value, which would be unexpected
- // but not fatal
- if (meta.size() > 0)
- BOOST_CHECK_EQUAL(meta[0], "VALUE");
+BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata)
+{
+ std::vector<std::string> meta;
+ BOOST_TEST_MESSAGE("Testing getDomainMetadata method");
+ be->getDomainMetadata(DNSName("unit.test."), "TEST", meta);
+ BOOST_CHECK_EQUAL(meta.size(), 1);
+ // in case we got more than one value, which would be unexpected
+ // but not fatal
+ if (meta.size() > 0)
+ BOOST_CHECK_EQUAL(meta[0], "VALUE");
}
-BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata) {
- std::map<std::string, std::vector<std::string> > meta;
- BOOST_TEST_MESSAGE("Testing getAllDomainMetadata method");
- be->getAllDomainMetadata(DNSName("unit.test."), meta);
- BOOST_CHECK_EQUAL(meta.size(), 1);
- // in case we got more than one value, which would be unexpected
- // but not fatal
- if (meta.size() > 0)
- BOOST_CHECK_EQUAL(meta["TEST"][0], "VALUE");
+BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata)
+{
+ std::map<std::string, std::vector<std::string>> meta;
+ BOOST_TEST_MESSAGE("Testing getAllDomainMetadata method");
+ be->getAllDomainMetadata(DNSName("unit.test."), meta);
+ BOOST_CHECK_EQUAL(meta.size(), 1);
+ // in case we got more than one value, which would be unexpected
+ // but not fatal
+ if (meta.size() > 0)
+ BOOST_CHECK_EQUAL(meta["TEST"][0], "VALUE");
}
-BOOST_AUTO_TEST_CASE(test_method_addDomainKey) {
- BOOST_TEST_MESSAGE("Testing addDomainKey method");
- int64_t id;
- be->addDomainKey(DNSName("unit.test."),k1,id);
- BOOST_CHECK_EQUAL(id, 1);
- be->addDomainKey(DNSName("unit.test."),k2,id);
- BOOST_CHECK_EQUAL(id, 2);
+BOOST_AUTO_TEST_CASE(test_method_addDomainKey)
+{
+ BOOST_TEST_MESSAGE("Testing addDomainKey method");
+ int64_t id;
+ be->addDomainKey(DNSName("unit.test."), k1, id);
+ BOOST_CHECK_EQUAL(id, 1);
+ be->addDomainKey(DNSName("unit.test."), k2, id);
+ BOOST_CHECK_EQUAL(id, 2);
}
-BOOST_AUTO_TEST_CASE(test_method_getDomainKeys) {
- std::vector<DNSBackend::KeyData> keys;
- BOOST_TEST_MESSAGE("Testing getDomainKeys method");
- // we expect to get two keys
- be->getDomainKeys(DNSName("unit.test."),keys);
- BOOST_CHECK_EQUAL(keys.size(), 2);
- // in case we got more than 2 keys, which would be unexpected
- // but not fatal
- if (keys.size() > 1) {
- // check that we have two keys
- for(DNSBackend::KeyData &kd : keys) {
- BOOST_CHECK(kd.id > 0);
- BOOST_CHECK(kd.flags == 256 || kd.flags == 257);
- BOOST_CHECK(kd.active == true);
- BOOST_CHECK(kd.published == true);
- BOOST_CHECK(kd.content.size() > 500);
- }
- }
+BOOST_AUTO_TEST_CASE(test_method_getDomainKeys)
+{
+ std::vector<DNSBackend::KeyData> keys;
+ BOOST_TEST_MESSAGE("Testing getDomainKeys method");
+ // we expect to get two keys
+ be->getDomainKeys(DNSName("unit.test."), keys);
+ BOOST_CHECK_EQUAL(keys.size(), 2);
+ // in case we got more than 2 keys, which would be unexpected
+ // but not fatal
+ if (keys.size() > 1) {
+ // check that we have two keys
+ for (DNSBackend::KeyData& kd : keys) {
+ BOOST_CHECK(kd.id > 0);
+ BOOST_CHECK(kd.flags == 256 || kd.flags == 257);
+ BOOST_CHECK(kd.active == true);
+ BOOST_CHECK(kd.published == true);
+ BOOST_CHECK(kd.content.size() > 500);
+ }
+ }
}
-BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey) {
- BOOST_TEST_MESSAGE("Testing deactivateDomainKey method");
- BOOST_CHECK(be->deactivateDomainKey(DNSName("unit.test."),1));
+BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey)
+{
+ BOOST_TEST_MESSAGE("Testing deactivateDomainKey method");
+ BOOST_CHECK(be->deactivateDomainKey(DNSName("unit.test."), 1));
}
-BOOST_AUTO_TEST_CASE(test_method_activateDomainKey) {
- BOOST_TEST_MESSAGE("Testing activateDomainKey method");
- BOOST_CHECK(be->activateDomainKey(DNSName("unit.test."),1));
+BOOST_AUTO_TEST_CASE(test_method_activateDomainKey)
+{
+ BOOST_TEST_MESSAGE("Testing activateDomainKey method");
+ BOOST_CHECK(be->activateDomainKey(DNSName("unit.test."), 1));
}
-BOOST_AUTO_TEST_CASE(test_method_removeDomainKey) {
- BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."),2));
- BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."),1));
+BOOST_AUTO_TEST_CASE(test_method_removeDomainKey)
+{
+ BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."), 2));
+ BOOST_CHECK(be->removeDomainKey(DNSName("unit.test."), 1));
}
-BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute) {
- DNSName unhashed, before, after;
- BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method");
-
- be->getBeforeAndAfterNamesAbsolute(-1, DNSName("middle.unit.test."), unhashed, before, after);
- BOOST_CHECK_EQUAL(unhashed.toString(), "middle.");
- BOOST_CHECK_EQUAL(before.toString(), "begin.");
- BOOST_CHECK_EQUAL(after.toString(), "stop.");
+BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute)
+{
+ DNSName unhashed, before, after;
+ BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method");
+
+ be->getBeforeAndAfterNamesAbsolute(-1, DNSName("middle.unit.test."), unhashed, before, after);
+ BOOST_CHECK_EQUAL(unhashed.toString(), "middle.");
+ BOOST_CHECK_EQUAL(before.toString(), "begin.");
+ BOOST_CHECK_EQUAL(after.toString(), "stop.");
}
-BOOST_AUTO_TEST_CASE(test_method_setTSIGKey) {
- std::string algorithm, content;
- BOOST_TEST_MESSAGE("Testing setTSIGKey method");
- BOOST_CHECK_MESSAGE(be->setTSIGKey(DNSName("unit.test."),DNSName("hmac-md5."),"kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys="), "did not return true");
+BOOST_AUTO_TEST_CASE(test_method_setTSIGKey)
+{
+ std::string algorithm, content;
+ BOOST_TEST_MESSAGE("Testing setTSIGKey method");
+ BOOST_CHECK_MESSAGE(be->setTSIGKey(DNSName("unit.test."), DNSName("hmac-md5."), "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys="), "did not return true");
}
-BOOST_AUTO_TEST_CASE(test_method_getTSIGKey) {
- DNSName algorithm;
- std::string content;
- BOOST_TEST_MESSAGE("Testing getTSIGKey method");
- be->getTSIGKey(DNSName("unit.test."),&algorithm,&content);
- BOOST_CHECK_EQUAL(algorithm.toString(), "hmac-md5.");
- BOOST_CHECK_EQUAL(content, "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=");
+BOOST_AUTO_TEST_CASE(test_method_getTSIGKey)
+{
+ DNSName algorithm;
+ std::string content;
+ BOOST_TEST_MESSAGE("Testing getTSIGKey method");
+ be->getTSIGKey(DNSName("unit.test."), &algorithm, &content);
+ BOOST_CHECK_EQUAL(algorithm.toString(), "hmac-md5.");
+ BOOST_CHECK_EQUAL(content, "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=");
}
-BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey) {
- std::string algorithm, content;
- BOOST_TEST_MESSAGE("Testing deleteTSIGKey method");
- BOOST_CHECK_MESSAGE(be->deleteTSIGKey(DNSName("unit.test.")), "did not return true");
+BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey)
+{
+ std::string algorithm, content;
+ BOOST_TEST_MESSAGE("Testing deleteTSIGKey method");
+ BOOST_CHECK_MESSAGE(be->deleteTSIGKey(DNSName("unit.test.")), "did not return true");
}
-BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys) {
- std::vector<struct TSIGKey> keys;
- BOOST_TEST_MESSAGE("Testing getTSIGKeys method");
- be->getTSIGKeys(keys);
- BOOST_CHECK(keys.size() > 0);
- if (keys.size() > 0) {
- BOOST_CHECK_EQUAL(keys[0].name.toString(), "test.");
- BOOST_CHECK_EQUAL(keys[0].algorithm.toString(), "NULL.");
- BOOST_CHECK_EQUAL(keys[0].key, "NULL");
- }
+BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys)
+{
+ std::vector<struct TSIGKey> keys;
+ BOOST_TEST_MESSAGE("Testing getTSIGKeys method");
+ be->getTSIGKeys(keys);
+ BOOST_CHECK(keys.size() > 0);
+ if (keys.size() > 0) {
+ BOOST_CHECK_EQUAL(keys[0].name.toString(), "test.");
+ BOOST_CHECK_EQUAL(keys[0].algorithm.toString(), "NULL.");
+ BOOST_CHECK_EQUAL(keys[0].key, "NULL");
+ }
}
-BOOST_AUTO_TEST_CASE(test_method_setNotified) {
- BOOST_TEST_MESSAGE("Testing setNotified method");
- be->setNotified(1, 2);
- BOOST_CHECK(true); // we check this on next step
+BOOST_AUTO_TEST_CASE(test_method_setNotified)
+{
+ BOOST_TEST_MESSAGE("Testing setNotified method");
+ be->setNotified(1, 2);
+ BOOST_CHECK(true); // we check this on next step
}
-BOOST_AUTO_TEST_CASE(test_method_getDomainInfo) {
- DomainInfo di;
- BOOST_TEST_MESSAGE("Testing getDomainInfo method");
- be->getDomainInfo(DNSName("unit.test."), di);
- BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
- BOOST_CHECK_EQUAL(di.serial, 2);
- BOOST_CHECK_EQUAL(di.notified_serial, 2);
- BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
- BOOST_CHECK_EQUAL(di.backend, be);
+BOOST_AUTO_TEST_CASE(test_method_getDomainInfo)
+{
+ DomainInfo di;
+ BOOST_TEST_MESSAGE("Testing getDomainInfo method");
+ be->getDomainInfo(DNSName("unit.test."), di);
+ BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
+ BOOST_CHECK_EQUAL(di.serial, 2);
+ BOOST_CHECK_EQUAL(di.notified_serial, 2);
+ BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
+ BOOST_CHECK_EQUAL(di.backend, be);
}
-BOOST_AUTO_TEST_CASE(test_method_getAllDomains) {
- DomainInfo di;
- BOOST_TEST_MESSAGE("Testing getAllDomains method");
- vector<DomainInfo> result;
+BOOST_AUTO_TEST_CASE(test_method_getAllDomains)
+{
+ DomainInfo di;
+ BOOST_TEST_MESSAGE("Testing getAllDomains method");
+ vector<DomainInfo> result;
- be->getAllDomains(&result, true);
+ be->getAllDomains(&result, true);
- di = result[0];
- BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
- BOOST_CHECK_EQUAL(di.serial, 2);
- BOOST_CHECK_EQUAL(di.notified_serial, 2);
- BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
- BOOST_CHECK_EQUAL(di.backend, be);
+ di = result[0];
+ BOOST_CHECK_EQUAL(di.zone.toString(), "unit.test.");
+ BOOST_CHECK_EQUAL(di.serial, 2);
+ BOOST_CHECK_EQUAL(di.notified_serial, 2);
+ BOOST_CHECK_EQUAL(di.kind, DomainInfo::Native);
+ BOOST_CHECK_EQUAL(di.backend, be);
}
-BOOST_AUTO_TEST_CASE(test_method_superMasterBackend) {
- DNSResourceRecord rr;
- std::vector<DNSResourceRecord> nsset;
- DNSBackend *dbd;
- BOOST_TEST_MESSAGE("Testing superMasterBackend method");
-
- rr.qname = DNSName("example.com.");
- rr.qtype = QType::NS;
- rr.qclass = QClass::IN;
- rr.ttl = 300;
- rr.content = "ns1.example.com.";
- nsset.push_back(rr);
- rr.qname = DNSName("example.com.");
- rr.qtype = QType::NS;
- rr.qclass = QClass::IN;
- rr.ttl = 300;
- rr.content = "ns2.example.com.";
- nsset.push_back(rr);
-
- BOOST_CHECK(be->superMasterBackend("10.0.0.1", DNSName("example.com."), nsset, NULL, NULL, &dbd));
-
- // let's see what we got
- BOOST_CHECK_EQUAL(dbd, be);
+BOOST_AUTO_TEST_CASE(test_method_superMasterBackend)
+{
+ DNSResourceRecord rr;
+ std::vector<DNSResourceRecord> nsset;
+ DNSBackend* dbd;
+ BOOST_TEST_MESSAGE("Testing superMasterBackend method");
+
+ rr.qname = DNSName("example.com.");
+ rr.qtype = QType::NS;
+ rr.qclass = QClass::IN;
+ rr.ttl = 300;
+ rr.content = "ns1.example.com.";
+ nsset.push_back(rr);
+ rr.qname = DNSName("example.com.");
+ rr.qtype = QType::NS;
+ rr.qclass = QClass::IN;
+ rr.ttl = 300;
+ rr.content = "ns2.example.com.";
+ nsset.push_back(rr);
+
+ BOOST_CHECK(be->superMasterBackend("10.0.0.1", DNSName("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", DNSName("pirate.unit.test."), "", ""));
+BOOST_AUTO_TEST_CASE(test_method_createSlaveDomain)
+{
+ BOOST_TEST_MESSAGE("Testing createSlaveDomain method");
+ BOOST_CHECK(be->createSlaveDomain("10.0.0.1", DNSName("pirate.unit.test."), "", ""));
}
-BOOST_AUTO_TEST_CASE(test_method_feedRecord) {
- DNSResourceRecord rr;
- BOOST_TEST_MESSAGE("Testing feedRecord method");
- be->startTransaction(DNSName("example.com."),2);
- rr.qname = DNSName("example.com.");
- rr.qtype = QType::SOA;
- rr.qclass = QClass::IN;
- rr.ttl = 300;
- rr.content = "ns1.example.com. hostmaster.example.com. 2013013441 7200 3600 1209600 300";
- BOOST_CHECK(be->feedRecord(rr, DNSName()));
- rr.qname = DNSName("replace.example.com.");
- rr.qtype = QType::A;
- rr.qclass = QClass::IN;
- rr.ttl = 300;
- rr.content = "127.0.0.1";
- BOOST_CHECK(be->feedRecord(rr, DNSName()));
- be->commitTransaction();
+BOOST_AUTO_TEST_CASE(test_method_feedRecord)
+{
+ DNSResourceRecord rr;
+ BOOST_TEST_MESSAGE("Testing feedRecord method");
+ be->startTransaction(DNSName("example.com."), 2);
+ rr.qname = DNSName("example.com.");
+ rr.qtype = QType::SOA;
+ rr.qclass = QClass::IN;
+ rr.ttl = 300;
+ rr.content = "ns1.example.com. hostmaster.example.com. 2013013441 7200 3600 1209600 300";
+ BOOST_CHECK(be->feedRecord(rr, DNSName()));
+ rr.qname = DNSName("replace.example.com.");
+ rr.qtype = QType::A;
+ rr.qclass = QClass::IN;
+ rr.ttl = 300;
+ rr.content = "127.0.0.1";
+ BOOST_CHECK(be->feedRecord(rr, DNSName()));
+ be->commitTransaction();
}
-BOOST_AUTO_TEST_CASE(test_method_replaceRRSet) {
- be->startTransaction(DNSName("example.com."),2);
- DNSResourceRecord rr;
- std::vector<DNSResourceRecord> rrset;
- BOOST_TEST_MESSAGE("Testing replaceRRSet method");
- rr.qname = DNSName("replace.example.com.");
- rr.qtype = QType::A;
- rr.qclass = QClass::IN;
- rr.ttl = 300;
- rr.content = "1.1.1.1";
- rrset.push_back(rr);
- BOOST_CHECK(be->replaceRRSet(2, DNSName("replace.example.com."), QType(QType::A), rrset));
- be->commitTransaction();
+BOOST_AUTO_TEST_CASE(test_method_replaceRRSet)
+{
+ be->startTransaction(DNSName("example.com."), 2);
+ DNSResourceRecord rr;
+ std::vector<DNSResourceRecord> rrset;
+ BOOST_TEST_MESSAGE("Testing replaceRRSet method");
+ rr.qname = DNSName("replace.example.com.");
+ rr.qtype = QType::A;
+ rr.qclass = QClass::IN;
+ rr.ttl = 300;
+ rr.content = "1.1.1.1";
+ rrset.push_back(rr);
+ BOOST_CHECK(be->replaceRRSet(2, DNSName("replace.example.com."), QType(QType::A), rrset));
+ be->commitTransaction();
}
-BOOST_AUTO_TEST_CASE(test_method_feedEnts) {
- BOOST_TEST_MESSAGE("Testing feedEnts method");
- be->startTransaction(DNSName("example.com."),2);
- map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
- BOOST_CHECK(be->feedEnts(2, nonterm));
- be->commitTransaction();
+BOOST_AUTO_TEST_CASE(test_method_feedEnts)
+{
+ BOOST_TEST_MESSAGE("Testing feedEnts method");
+ be->startTransaction(DNSName("example.com."), 2);
+ map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
+ BOOST_CHECK(be->feedEnts(2, nonterm));
+ be->commitTransaction();
}
-BOOST_AUTO_TEST_CASE(test_method_feedEnts3) {
- BOOST_TEST_MESSAGE("Testing feedEnts3 method");
- be->startTransaction(DNSName("example.com"),2);
- NSEC3PARAMRecordContent ns3prc;
- ns3prc.d_iterations=1;
- ns3prc.d_salt="\u00aa\u00bb\u00cc\u00dd";
- map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
- BOOST_CHECK(be->feedEnts3(2, DNSName("example.com."), nonterm, ns3prc, 0));
- be->commitTransaction();
+BOOST_AUTO_TEST_CASE(test_method_feedEnts3)
+{
+ BOOST_TEST_MESSAGE("Testing feedEnts3 method");
+ be->startTransaction(DNSName("example.com"), 2);
+ NSEC3PARAMRecordContent ns3prc;
+ ns3prc.d_iterations = 1;
+ ns3prc.d_salt = "\u00aa\u00bb\u00cc\u00dd";
+ map<DNSName, bool> nonterm = boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
+ BOOST_CHECK(be->feedEnts3(2, DNSName("example.com."), nonterm, ns3prc, 0));
+ be->commitTransaction();
}
-BOOST_AUTO_TEST_CASE(test_method_abortTransaction) {
- BOOST_TEST_MESSAGE("Testing abortTransaction method");
- be->startTransaction(DNSName("example.com."),2);
- BOOST_CHECK(be->abortTransaction());
+BOOST_AUTO_TEST_CASE(test_method_abortTransaction)
+{
+ BOOST_TEST_MESSAGE("Testing abortTransaction method");
+ be->startTransaction(DNSName("example.com."), 2);
+ BOOST_CHECK(be->abortTransaction());
}
-BOOST_AUTO_TEST_CASE(test_method_directBackendCmd) {
- BOOST_TEST_MESSAGE("Testing directBackendCmd method");
- BOOST_CHECK_EQUAL(be->directBackendCmd("PING 1234"), "PING 1234");
+BOOST_AUTO_TEST_CASE(test_method_directBackendCmd)
+{
+ BOOST_TEST_MESSAGE("Testing directBackendCmd method");
+ BOOST_CHECK_EQUAL(be->directBackendCmd("PING 1234"), "PING 1234");
}
-BOOST_AUTO_TEST_CASE(test_method_getUpdatedMasters) {
- DomainInfo di;
- BOOST_TEST_MESSAGE("Testing getUpdatedMasters method");
- vector<DomainInfo> result;
+BOOST_AUTO_TEST_CASE(test_method_getUpdatedMasters)
+{
+ DomainInfo di;
+ BOOST_TEST_MESSAGE("Testing getUpdatedMasters method");
+ vector<DomainInfo> result;
- be->getUpdatedMasters(&result);
+ be->getUpdatedMasters(&result);
- BOOST_CHECK(result.size() > 0);
+ BOOST_CHECK(result.size() > 0);
- di = result[0];
- BOOST_CHECK_EQUAL(di.zone.toString(), "master.test.");
- BOOST_CHECK_EQUAL(di.serial, 2);
- BOOST_CHECK_EQUAL(di.notified_serial, 2);
- BOOST_CHECK_EQUAL(di.kind, DomainInfo::Master);
- BOOST_CHECK_EQUAL(di.backend, be);
+ di = result[0];
+ BOOST_CHECK_EQUAL(di.zone.toString(), "master.test.");
+ BOOST_CHECK_EQUAL(di.serial, 2);
+ BOOST_CHECK_EQUAL(di.notified_serial, 2);
+ BOOST_CHECK_EQUAL(di.kind, DomainInfo::Master);
+ BOOST_CHECK_EQUAL(di.backend, be);
}
BOOST_AUTO_TEST_SUITE_END();
#include <sys/socket.h>
#include <sys/un.h>
#include "remotebackend.hh"
-#ifndef UNIX_PATH_MAX
+#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
#endif
-UnixsocketConnector::UnixsocketConnector(std::map<std::string,std::string> optionsMap) {
+UnixsocketConnector::UnixsocketConnector(std::map<std::string, std::string> optionsMap)
+{
if (optionsMap.count("path") == 0) {
- g_log<<Logger::Error<<"Cannot find 'path' option in connection string"<<endl;
+ g_log << Logger::Error << "Cannot find 'path' option in connection string" << endl;
throw PDNSException();
- }
+ }
this->timeout = 2000;
if (optionsMap.find("timeout") != optionsMap.end()) {
this->timeout = std::stoi(optionsMap.find("timeout")->second);
this->fd = -1;
}
-UnixsocketConnector::~UnixsocketConnector() {
+UnixsocketConnector::~UnixsocketConnector()
+{
if (this->connected) {
try {
- g_log<<Logger::Info<<"closing socket connection"<<endl;
+ g_log << Logger::Info << "closing socket connection" << endl;
}
catch (...) {
}
}
}
-int UnixsocketConnector::send_message(const Json& input) {
+int UnixsocketConnector::send_message(const Json& input)
+{
auto data = input.dump() + "\n";
int rv = this->write(data);
if (rv == -1)
return rv;
}
-int UnixsocketConnector::recv_message(Json& output) {
+int UnixsocketConnector::recv_message(Json& output)
+{
int rv;
- std::string s_output,err;
+ std::string s_output, err;
- struct timeval t0,t;
+ struct timeval t0, t;
gettimeofday(&t0, NULL);
- memcpy(&t,&t0,sizeof(t0));
- s_output = "";
+ memcpy(&t, &t0, sizeof(t0));
+ s_output = "";
- while((t.tv_sec - t0.tv_sec)*1000 + (t.tv_usec - t0.tv_usec)/1000 < this->timeout) {
+ while ((t.tv_sec - t0.tv_sec) * 1000 + (t.tv_usec - t0.tv_usec) / 1000 < this->timeout) {
int avail = waitForData(this->fd, 0, this->timeout * 500); // use half the timeout as poll timeout
if (avail < 0) // poll error
return -1;
}
rv = this->read(s_output);
- if (rv == -1)
+ if (rv == -1)
return -1;
- if (rv>0) {
+ if (rv > 0) {
// see if it can be parsed
output = Json::parse(s_output, err);
- if (output != nullptr) return s_output.size();
+ if (output != nullptr)
+ return s_output.size();
}
gettimeofday(&t, NULL);
}
return -1;
}
-ssize_t UnixsocketConnector::read(std::string &data) {
+ssize_t UnixsocketConnector::read(std::string& data)
+{
ssize_t nread;
char buf[1500] = {0};
reconnect();
- if (!connected) return -1;
+ if (!connected)
+ return -1;
nread = ::read(this->fd, buf, sizeof buf);
// just try again later...
- if (nread==-1 && errno == EAGAIN) return 0;
+ if (nread == -1 && errno == EAGAIN)
+ return 0;
- if (nread==-1 || nread==0) {
+ if (nread == -1 || nread == 0) {
connected = false;
close(fd);
return -1;
return nread;
}
-ssize_t UnixsocketConnector::write(const std::string &data) {
+ssize_t UnixsocketConnector::write(const std::string& data)
+{
size_t pos = 0;
reconnect();
- if (!connected) return -1;
+ if (!connected)
+ return -1;
- while(pos < data.size()) {
+ while (pos < data.size()) {
ssize_t written = ::write(fd, &data.at(pos), data.size() - pos);
if (written < 1) {
connected = false;
close(fd);
return -1;
- } else {
+ }
+ else {
pos = pos + static_cast<size_t>(written);
}
}
return pos;
}
-void UnixsocketConnector::reconnect() {
+void UnixsocketConnector::reconnect()
+{
struct sockaddr_un sock;
int rv;
- if (connected) return; // no point reconnecting if connected...
+ if (connected)
+ return; // no point reconnecting if connected...
connected = true;
- g_log<<Logger::Info<<"Reconnecting to backend" << std::endl;
+ g_log << Logger::Info << "Reconnecting to backend" << std::endl;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
- connected = false;
- g_log<<Logger::Error<<"Cannot create socket: " << strerror(errno) << std::endl;;
- return;
+ connected = false;
+ g_log << Logger::Error << "Cannot create socket: " << strerror(errno) << std::endl;
+ ;
+ return;
}
if (makeUNsockaddr(path, &sock)) {
- g_log<<Logger::Error<<"Unable to create UNIX domain socket: Path '"<<path<<"' is not a valid UNIX socket path."<<std::endl;
- return;
+ g_log << Logger::Error << "Unable to create UNIX domain socket: Path '" << path << "' is not a valid UNIX socket path." << std::endl;
+ return;
}
rv = connect(fd, reinterpret_cast<struct sockaddr*>(&sock), sizeof sock);
if (rv != 0 && errno != EISCONN && errno != 0) {
- g_log<<Logger::Error<<"Cannot connect to socket: " << strerror(errno) << std::endl;
- close(fd);
- connected = false;
- return;
+ g_log << Logger::Error << "Cannot connect to socket: " << strerror(errno) << std::endl;
+ close(fd);
+ connected = false;
+ return;
}
// send initialize
Json::array parameters;
Json msg = Json(Json::object{
- { "method", "initialize" },
- { "parameters", Json(options) },
+ {"method", "initialize"},
+ {"parameters", Json(options)},
});
this->send(msg);
msg = nullptr;
if (this->recv(msg) == false) {
- g_log<<Logger::Warning << "Failed to initialize backend" << std::endl;
- close(fd);
- this->connected = false;
+ g_log << Logger::Warning << "Failed to initialize backend" << std::endl;
+ close(fd);
+ this->connected = false;
}
}
#include "remotebackend.hh"
#ifdef REMOTEBACKEND_ZEROMQ
-ZeroMQConnector::ZeroMQConnector(std::map<std::string,std::string> options): d_ctx(std::unique_ptr<void, int(*)(void*)>(zmq_init(2), zmq_close)), d_sock(std::unique_ptr<void, int(*)(void*)>(zmq_socket(d_ctx.get(), ZMQ_REQ), zmq_close)) {
- int opt=0;
+ZeroMQConnector::ZeroMQConnector(std::map<std::string, std::string> options) :
+ d_ctx(std::unique_ptr<void, int (*)(void*)>(zmq_init(2), zmq_close)), d_sock(std::unique_ptr<void, int (*)(void*)>(zmq_socket(d_ctx.get(), ZMQ_REQ), zmq_close))
+{
+ int opt = 0;
// lookup timeout, target and stuff
if (options.count("endpoint") == 0) {
- g_log<<Logger::Error<<"Cannot find 'endpoint' option in connection string"<<endl;
+ g_log << Logger::Error << "Cannot find 'endpoint' option in connection string" << endl;
throw PDNSException("Cannot find 'endpoint' option in connection string");
}
this->d_endpoint = options.find("endpoint")->second;
this->d_options = options;
- this->d_timeout=2000;
+ this->d_timeout = 2000;
if (options.find("timeout") != options.end()) {
- this->d_timeout = std::stoi(options.find("timeout")->second);
+ this->d_timeout = std::stoi(options.find("timeout")->second);
}
zmq_setsockopt(d_sock.get(), ZMQ_LINGER, &opt, sizeof(opt));
- if(zmq_connect(this->d_sock.get(), this->d_endpoint.c_str()) < 0)
- {
- g_log<<Logger::Error<<"zmq_connect() failed"<< zmq_strerror(errno)<<std::endl;;
+ if (zmq_connect(this->d_sock.get(), this->d_endpoint.c_str()) < 0) {
+ g_log << Logger::Error << "zmq_connect() failed" << zmq_strerror(errno) << std::endl;
+ ;
throw PDNSException("Cannot find 'endpoint' option in connection string");
}
Json::array parameters;
Json msg = Json(Json::object{
- { "method", "initialize" },
- { "parameters", Json(options) },
+ {"method", "initialize"},
+ {"parameters", Json(options)},
});
this->send(msg);
msg = nullptr;
- if (this->recv(msg)==false) {
- g_log<<Logger::Error<<"Failed to initialize zeromq"<<std::endl;
+ if (this->recv(msg) == false) {
+ g_log << Logger::Error << "Failed to initialize zeromq" << std::endl;
throw PDNSException("Failed to initialize zeromq");
- }
+ }
};
ZeroMQConnector::~ZeroMQConnector() {}
-int ZeroMQConnector::send_message(const Json& input) {
- auto line = input.dump();
- zmq_msg_t message;
-
- zmq_msg_init_size(&message, line.size()+1);
- line.copy(reinterpret_cast<char*>(zmq_msg_data(&message)), line.size());
- ((char *)zmq_msg_data(&message))[line.size()] = '\0';
-
- try {
- zmq_pollitem_t item;
- item.socket = d_sock.get();
- item.events = ZMQ_POLLOUT;
- // poll until it's sent or timeout is spent. try to leave
- // leave few cycles for read. just in case.
- for(d_timespent = 0; d_timespent < d_timeout-5; d_timespent++) {
- if (zmq_poll(&item, 1, 1)>0) {
- if(zmq_msg_send(&message, this->d_sock.get(), 0) == -1) {
- // message was not sent
- g_log<<Logger::Error<<"Cannot send to " << this->d_endpoint << ": " << zmq_strerror(errno)<<std::endl;
- } else
- return line.size();
- }
- }
- } catch (std::exception &ex) {
- g_log<<Logger::Error<<"Cannot send to " << this->d_endpoint << ": " << ex.what()<<std::endl;
- throw PDNSException(ex.what());
- }
-
- return 0;
+int ZeroMQConnector::send_message(const Json& input)
+{
+ auto line = input.dump();
+ zmq_msg_t message;
+
+ zmq_msg_init_size(&message, line.size() + 1);
+ line.copy(reinterpret_cast<char*>(zmq_msg_data(&message)), line.size());
+ ((char*)zmq_msg_data(&message))[line.size()] = '\0';
+
+ try {
+ zmq_pollitem_t item;
+ item.socket = d_sock.get();
+ item.events = ZMQ_POLLOUT;
+ // poll until it's sent or timeout is spent. try to leave
+ // leave few cycles for read. just in case.
+ for (d_timespent = 0; d_timespent < d_timeout - 5; d_timespent++) {
+ if (zmq_poll(&item, 1, 1) > 0) {
+ if (zmq_msg_send(&message, this->d_sock.get(), 0) == -1) {
+ // message was not sent
+ g_log << Logger::Error << "Cannot send to " << this->d_endpoint << ": " << zmq_strerror(errno) << std::endl;
+ }
+ else
+ return line.size();
+ }
+ }
+ }
+ catch (std::exception& ex) {
+ g_log << Logger::Error << "Cannot send to " << this->d_endpoint << ": " << ex.what() << std::endl;
+ throw PDNSException(ex.what());
+ }
+
+ return 0;
}
-int ZeroMQConnector::recv_message(Json& output) {
- int rv = 0;
- // try to receive message
- zmq_pollitem_t item;
- zmq_msg_t message;
-
- item.socket = d_sock.get();
- item.events = ZMQ_POLLIN;
-
- try {
- // do zmq::poll few times
- // d_timespent should always be initialized by send_message, recv should never
- // be called without send first.
- for(; d_timespent < d_timeout; d_timespent++) {
- if (zmq_poll(&item, 1, 1)>0) {
- // we have an event
- if ((item.revents & ZMQ_POLLIN) == ZMQ_POLLIN) {
- string data;
- size_t msg_size;
- zmq_msg_init(&message);
- // read something
- if(zmq_msg_recv(&message, this->d_sock.get(), ZMQ_NOBLOCK)>0) {
- string err;
- msg_size = zmq_msg_size(&message);
- data.assign(reinterpret_cast<const char*>(zmq_msg_data(&message)), msg_size);
- zmq_msg_close(&message);
- output = Json::parse(data, err);
- if (output != nullptr)
- rv = msg_size;
- else
- g_log<<Logger::Error<<"Cannot parse JSON reply from " << this->d_endpoint << ": " << err << endl;
- break;
- } else if (errno == EAGAIN) { continue; // try again }
- } else {
- break;
- }
+int ZeroMQConnector::recv_message(Json& output)
+{
+ int rv = 0;
+ // try to receive message
+ zmq_pollitem_t item;
+ zmq_msg_t message;
+
+ item.socket = d_sock.get();
+ item.events = ZMQ_POLLIN;
+
+ try {
+ // do zmq::poll few times
+ // d_timespent should always be initialized by send_message, recv should never
+ // be called without send first.
+ for (; d_timespent < d_timeout; d_timespent++) {
+ if (zmq_poll(&item, 1, 1) > 0) {
+ // we have an event
+ if ((item.revents & ZMQ_POLLIN) == ZMQ_POLLIN) {
+ string data;
+ size_t msg_size;
+ zmq_msg_init(&message);
+ // read something
+ if (zmq_msg_recv(&message, this->d_sock.get(), ZMQ_NOBLOCK) > 0) {
+ string err;
+ msg_size = zmq_msg_size(&message);
+ data.assign(reinterpret_cast<const char*>(zmq_msg_data(&message)), msg_size);
+ zmq_msg_close(&message);
+ output = Json::parse(data, err);
+ if (output != nullptr)
+ rv = msg_size;
+ else
+ g_log << Logger::Error << "Cannot parse JSON reply from " << this->d_endpoint << ": " << err << endl;
+ break;
+ }
+ else if (errno == EAGAIN) {
+ continue; // try again }
+ }
+ else {
+ break;
}
}
- }
- } catch (std::exception &ex) {
- g_log<<Logger::Error<<"Cannot receive from " << this->d_endpoint << ": " << ex.what()<<std::endl;
- throw PDNSException(ex.what());
- }
+ }
+ }
+ }
+ catch (std::exception& ex) {
+ g_log << Logger::Error << "Cannot receive from " << this->d_endpoint << ": " << ex.what() << std::endl;
+ throw PDNSException(ex.what());
+ }
- return rv;
+ return rv;
}
#endif
#include "pdns/dnsrecords.hh"
#include <utility>
-static string backendname="[TinyDNSBackend] ";
+static string backendname = "[TinyDNSBackend] ";
uint32_t TinyDNSBackend::s_lastId;
std::mutex TinyDNSBackend::s_domainInfoLock;
TinyDNSBackend::TDI_suffix_t TinyDNSBackend::s_domainInfo;
{
vector<string> ret;
- if (! d_dnspacket) {
+ if (!d_dnspacket) {
return ret;
}
char key[6];
key[0] = '\000';
key[1] = '\045';
- key[2] = (addr )&0xff;
- key[3] = (addr >> 8)&0xff;
- key[4] = (addr >> 16)&0xff;
- key[5] = (addr >> 24)&0xff;
+ key[2] = (addr)&0xff;
+ key[3] = (addr >> 8) & 0xff;
+ key[4] = (addr >> 16) & 0xff;
+ key[5] = (addr >> 24) & 0xff;
- for (int i=4;i>=0;i--) {
- string searchkey(key, i+2);
+ for (int i = 4; i >= 0; i--) {
+ string searchkey(key, i + 2);
try {
auto reader = std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
ret = reader->findall(searchkey);
}
- catch(const std::exception& e) {
- g_log<<Logger::Error<<e.what()<<endl;
+ catch (const std::exception& e) {
+ g_log << Logger::Error << e.what() << endl;
throw PDNSException(e.what());
}
return ret;
}
-TinyDNSBackend::TinyDNSBackend(const string &suffix)
+TinyDNSBackend::TinyDNSBackend(const string& suffix)
{
- setArgPrefix("tinydns"+suffix);
+ setArgPrefix("tinydns" + suffix);
d_suffix = suffix;
d_locations = mustDo("locations");
d_ignorebogus = mustDo("ignore-bogus-records");
d_isWildcardQuery = false;
}
-void TinyDNSBackend::getUpdatedMasters(vector<DomainInfo>* retDomains) {
+void TinyDNSBackend::getUpdatedMasters(vector<DomainInfo>* retDomains)
+{
std::lock_guard<std::mutex> l(s_domainInfoLock); //TODO: We could actually lock less if we do it per suffix.
- if (! s_domainInfo.count(d_suffix)) {
+ if (!s_domainInfo.count(d_suffix)) {
TDI_t tmp;
- s_domainInfo.insert( make_pair(d_suffix,tmp) );
+ s_domainInfo.insert(make_pair(d_suffix, tmp));
}
- TDI_t *domains = &s_domainInfo[d_suffix];
+ TDI_t* domains = &s_domainInfo[d_suffix];
vector<DomainInfo> allDomains;
getAllDomains(&allDomains);
if (domains->size() == 0 && !mustDo("notify-on-startup")) {
- for (vector<DomainInfo>::iterator di=allDomains.begin(); di!=allDomains.end(); ++di) {
+ for (vector<DomainInfo>::iterator di = allDomains.begin(); di != allDomains.end(); ++di) {
di->notified_serial = 0;
}
}
- for(vector<DomainInfo>::iterator di=allDomains.begin(); di!=allDomains.end(); ++di) {
+ for (vector<DomainInfo>::iterator di = allDomains.begin(); di != allDomains.end(); ++di) {
TDIByZone_t& zone_index = domains->get<tag_zone>();
TDIByZone_t::iterator itByZone = zone_index.find(di->zone);
if (itByZone == zone_index.end()) {
if (di->notified_serial > 0) {
retDomains->push_back(*di);
}
- } else {
+ }
+ else {
if (itByZone->notified_serial < di->serial) {
di->id = itByZone->id;
retDomains->push_back(*di);
}
}
-void TinyDNSBackend::setNotified(uint32_t id, uint32_t serial) {
+void TinyDNSBackend::setNotified(uint32_t id, uint32_t serial)
+{
std::lock_guard<std::mutex> l(s_domainInfoLock);
if (!s_domainInfo.count(d_suffix)) {
throw PDNSException("Can't get list of domains to set the serial.");
}
- TDI_t *domains = &s_domainInfo[d_suffix];
+ TDI_t* domains = &s_domainInfo[d_suffix];
TDIById_t& domain_index = domains->get<tag_domainid>();
TDIById_t::iterator itById = domain_index.find(id);
if (itById == domain_index.end()) {
- g_log<<Logger::Error<<backendname<<"Received updated serial("<<serial<<"), but domain ID ("<<id<<") is not known in this backend."<<endl;
- } else {
- DLOG(g_log<<Logger::Debug<<backendname<<"Setting serial for "<<itById->zone<<" to "<<serial<<endl);
+ g_log << Logger::Error << backendname << "Received updated serial(" << serial << "), but domain ID (" << id << ") is not known in this backend." << endl;
+ }
+ else {
+ DLOG(g_log << Logger::Debug << backendname << "Setting serial for " << itById->zone << " to " << serial << endl);
domain_index.modify(itById, TDI_SerialModifier(serial));
}
s_domainInfo[d_suffix] = *domains;
}
-void TinyDNSBackend::getAllDomains(vector<DomainInfo> *domains, bool include_disabled) {
- d_isAxfr=true;
+void TinyDNSBackend::getAllDomains(vector<DomainInfo>* domains, bool include_disabled)
+{
+ d_isAxfr = true;
d_dnspacket = NULL;
try {
- d_cdbReader=std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
+ d_cdbReader = std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
}
catch (const std::exception& e) {
- g_log<<Logger::Error<<e.what()<<endl;
+ g_log << Logger::Error << e.what() << endl;
throw PDNSException(e.what());
}
DomainInfo di;
di.id = -1; //TODO: Check if this is ok.
- di.backend=this;
+ di.backend = this;
di.zone = rr.qname;
di.serial = sd.serial;
di.notified_serial = sd.serial;
}
}
-bool TinyDNSBackend::list(const DNSName &target, int domain_id, bool include_disabled) {
- d_isAxfr=true;
+bool TinyDNSBackend::list(const DNSName& target, int domain_id, bool include_disabled)
+{
+ d_isAxfr = true;
string key = target.toDNSStringLC();
try {
- d_cdbReader=std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
+ d_cdbReader = std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
}
catch (const std::exception& e) {
- g_log<<Logger::Error<<e.what()<<endl;
+ g_log << Logger::Error << e.what() << endl;
throw PDNSException(e.what());
}
return d_cdbReader->searchSuffix(key);
}
-void TinyDNSBackend::lookup(const QType &qtype, const DNSName &qdomain, int zoneId, DNSPacket *pkt_p) {
+void TinyDNSBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p)
+{
d_isAxfr = false;
string queryDomain = toLowerCanonic(qdomain.toString());
- string key=simpleCompress(queryDomain);
+ string key = simpleCompress(queryDomain);
- DLOG(g_log<<Logger::Debug<<backendname<<"[lookup] query for qtype ["<<qtype.getName()<<"] qdomain ["<<qdomain<<"]"<<endl);
- DLOG(g_log<<Logger::Debug<<"[lookup] key ["<<makeHexDump(key)<<"]"<<endl);
+ DLOG(g_log << Logger::Debug << backendname << "[lookup] query for qtype [" << qtype.getName() << "] qdomain [" << qdomain << "]" << endl);
+ DLOG(g_log << Logger::Debug << "[lookup] key [" << makeHexDump(key) << "]" << endl);
d_isWildcardQuery = false;
if (key[0] == '\001' && key[1] == '\052') {
d_isWildcardQuery = true;
- key.erase(0,2);
+ key.erase(0, 2);
}
- d_qtype=qtype;
+ d_qtype = qtype;
try {
- d_cdbReader=std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
+ d_cdbReader = std::unique_ptr<CDB>(new CDB(getArg("dbfile")));
}
catch (const std::exception& e) {
- g_log<<Logger::Error<<e.what()<<endl;
+ g_log << Logger::Error << e.what() << endl;
throw PDNSException(e.what());
}
d_dnspacket = pkt_p;
}
-
-bool TinyDNSBackend::get(DNSResourceRecord &rr)
+bool TinyDNSBackend::get(DNSResourceRecord& rr)
{
pair<string, string> record;
}
}
-
PacketReader pr(val, 0);
rr.qtype = QType(pr.get16BitInt());
- if(d_isAxfr || d_qtype.getCode() == QType::ANY || rr.qtype == d_qtype) {
+ if (d_isAxfr || d_qtype.getCode() == QType::ANY || rr.qtype == d_qtype) {
char locwild = pr.get8BitInt();
- if(locwild != '\075' && (locwild == '\076' || locwild == '\053')) {
+ if (locwild != '\075' && (locwild == '\076' || locwild == '\053')) {
if (d_isAxfr && d_locations) { // We skip records with a location in AXFR, unless we disable locations.
continue;
}
if (d_locations) {
bool foundLocation = false;
vector<string> locations = getLocations();
- while(locations.size() > 0) {
+ while (locations.size() > 0) {
string locId = locations.back();
locations.pop_back();
}
}
- if (d_isAxfr && (val[2] == '\052' || val[2] == '\053' )) { // Keys are not stored with wildcard character, with AXFR we need to add that.
+ if (d_isAxfr && (val[2] == '\052' || val[2] == '\053')) { // Keys are not stored with wildcard character, with AXFR we need to add that.
key.insert(0, 1, '\052');
key.insert(0, 1, '\001');
}
// rr.qname.clear();
- rr.qname=DNSName(key.c_str(), key.size(), 0, false);
- rr.domain_id=-1;
+ rr.qname = DNSName(key.c_str(), key.size(), 0, false);
+ rr.domain_id = -1;
// 11:13.21 <@ahu> IT IS ALWAYS AUTH --- well not really because we are just a backend :-)
// We could actually do NSEC3-NARROW DNSSEC according to Habbie, if we do, we need to change something here.
rr.auth = true;
uint64_t timestamp = pr.get32BitInt();
timestamp <<= 32;
timestamp += pr.get32BitInt();
- if(timestamp) {
+ if (timestamp) {
uint64_t now = d_taiepoch + time(NULL);
if (rr.ttl == 0) {
if (timestamp < now) {
continue;
}
rr.ttl = timestamp - now;
- if (rr.ttl <= 2) rr.ttl = 2;
- if (rr.ttl >= 3600) rr.ttl = 3600;
- } else if (now <= timestamp) {
+ if (rr.ttl <= 2)
+ rr.ttl = 2;
+ if (rr.ttl >= 3600)
+ rr.ttl = 3600;
+ }
+ else if (now <= timestamp) {
continue;
}
}
DNSRecord dr;
dr.d_class = 1;
dr.d_type = rr.qtype.getCode();
- dr.d_clen = val.size()-pr.getPosition();
+ dr.d_clen = val.size() - pr.getPosition();
auto drc = DNSRecordContent::mastermake(dr, pr);
rr.content = drc->getZoneRepresentation();
- DLOG(cerr<<"CONTENT: "<<rr.content<<endl);
+ DLOG(cerr << "CONTENT: " << rr.content << endl);
}
catch (...) {
- g_log<<Logger::Error<<backendname<<"Failed to parse record content for "<<rr.qname<<" with type "<<rr.qtype.getName();
+ g_log << Logger::Error << backendname << "Failed to parse record content for " << rr.qname << " with type " << rr.qtype.getName();
if (d_ignorebogus) {
- g_log<<". Ignoring!"<<endl;
+ g_log << ". Ignoring!" << endl;
continue;
- } else {
- g_log<<". Erroring out!"<<endl;
+ }
+ else {
+ g_log << ". Erroring out!" << endl;
throw;
}
}
-// DLOG(g_log<<Logger::Debug<<backendname<<"Returning ["<<rr.content<<"] for ["<<rr.qname<<"] of RecordType ["<<rr.qtype.getName()<<"]"<<endl;);
+ // DLOG(g_log<<Logger::Debug<<backendname<<"Returning ["<<rr.content<<"] for ["<<rr.qname<<"] of RecordType ["<<rr.qtype.getName()<<"]"<<endl;);
return true;
}
} // end of while
- DLOG(g_log<<Logger::Debug<<backendname<<"No more records to return."<<endl);
+ DLOG(g_log << Logger::Debug << backendname << "No more records to return." << endl);
d_cdbReader = nullptr;
return false;
}
// boilerplate
-class TinyDNSFactory: public BackendFactory
+class TinyDNSFactory : public BackendFactory
{
public:
- TinyDNSFactory() : BackendFactory("tinydns") {}
+ TinyDNSFactory() :
+ BackendFactory("tinydns") {}
- void declareArguments(const string &suffix="") override {
+ void declareArguments(const string& suffix = "") override
+ {
declare(suffix, "notify-on-startup", "Tell the TinyDNSBackend to notify all the slave nameservers on startup. Default is no.", "no");
declare(suffix, "dbfile", "Location of the cdb data file", "data.cdb");
declare(suffix, "tai-adjust", "This adjusts the TAI value if timestamps are used. These seconds will be added to the start point (1970) and will allow you to adjust for leap seconds. The default is 11.", "11");
declare(suffix, "ignore-bogus-records", "The data.cdb file might have some incorrect record data, this causes PowerDNS to fail, where tinydns would send out truncated data. This option makes powerdns ignore that data!", "no");
}
- DNSBackend *make(const string &suffix="") override {
+ DNSBackend* make(const string& suffix = "") override
+ {
return new TinyDNSBackend(suffix);
}
};
class TinyDNSLoader
{
public:
- TinyDNSLoader() {
+ TinyDNSLoader()
+ {
BackendMakers().report(new TinyDNSFactory);
g_log << Logger::Info << "[tinydnsbackend] This is the tinydns backend version " VERSION
#ifndef REPRODUCIBLE
- << " (" __DATE__ " " __TIME__ ")"
+ << " (" __DATE__ " " __TIME__ ")"
#endif
- << " reporting" << endl;
+ << " reporting" << endl;
}
};
using namespace ::boost;
using namespace ::boost::multi_index;
-struct TinyDomainInfo {
+struct TinyDomainInfo
+{
uint32_t id;
uint32_t notified_serial;
DNSName zone;
}
};
-struct TDI_SerialModifier {
- TDI_SerialModifier (const int newSerial) : d_newSerial(newSerial) {}
+struct TDI_SerialModifier
+{
+ TDI_SerialModifier(const int newSerial) :
+ d_newSerial(newSerial) {}
void operator()(TinyDomainInfo& tdi)
{
tdi.notified_serial = d_newSerial;
}
- private:
- int d_newSerial;
+private:
+ int d_newSerial;
};
-
class TinyDNSBackend : public DNSBackend
{
public:
// Methods for simple operation
- TinyDNSBackend(const string &suffix);
- void lookup(const QType &qtype, const DNSName &qdomain, int zoneId, DNSPacket *pkt_p=nullptr) override;
- bool list(const DNSName &target, int domain_id, bool include_disabled=false) override;
- bool get(DNSResourceRecord &rr) override;
- void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
+ TinyDNSBackend(const string& suffix);
+ void lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p = nullptr) override;
+ bool list(const DNSName& target, int domain_id, bool include_disabled = false) override;
+ bool get(DNSResourceRecord& rr) override;
+ void getAllDomains(vector<DomainInfo>* domains, bool include_disabled = false) override;
//Master mode operation
void getUpdatedMasters(vector<DomainInfo>* domains) override;
void setNotified(uint32_t id, uint32_t serial) override;
+
private:
vector<string> getLocations();
//TypeDefs
- struct tag_zone{};
- struct tag_domainid{};
+ struct tag_zone
+ {
+ };
+ struct tag_domainid
+ {
+ };
typedef multi_index_container<
TinyDomainInfo,
indexed_by<
- hashed_unique<tag<tag_zone>, member<TinyDomainInfo, DNSName, &TinyDomainInfo::zone> >,
- hashed_unique<tag<tag_domainid>, member<TinyDomainInfo, uint32_t, &TinyDomainInfo::id> >
- >
- > TDI_t;
+ hashed_unique<tag<tag_zone>, member<TinyDomainInfo, DNSName, &TinyDomainInfo::zone>>,
+ hashed_unique<tag<tag_domainid>, member<TinyDomainInfo, uint32_t, &TinyDomainInfo::id>>>>
+ TDI_t;
typedef map<string, TDI_t> TDI_suffix_t;
typedef TDI_t::index<tag_zone>::type TDIByZone_t;
typedef TDI_t::index<tag_domainid>::type TDIById_t;
uint64_t d_taiepoch;
QType d_qtype;
std::unique_ptr<CDB> d_cdbReader;
- DNSPacket *d_dnspacket; // used for location and edns-client support.
+ DNSPacket* d_dnspacket; // used for location and edns-client support.
bool d_isWildcardQuery; // Indicate if the query received was a wildcard query.
bool d_isAxfr; // Indicate if we received a list() and not a lookup().
bool d_locations;