d_isWildcardQuery = false;
}
+TinyDNSBackend::TDI_t::iterator TinyDNSBackend::updateState(DomainInfo& domain, TDI_t* state)
+{
+ TDIByZone_t& zone_index = state->get<tag_zone>();
+ TDIByZone_t::iterator itByZone = zone_index.find(domain.zone);
+ if (itByZone != zone_index.end()) {
+ return itByZone;
+ }
+
+ TinyDomainInfo tmp;
+ s_lastId++;
+ tmp.zone = domain.zone;
+ tmp.id = s_lastId;
+ tmp.notified_serial = domain.serial;
+ return state->insert(tmp).first;
+}
+
void TinyDNSBackend::getUpdatedPrimaries(vector<DomainInfo>& retDomains, std::unordered_set<DNSName>& /* catalogs */, CatalogHashMap& /* catalogHashes */)
{
+ bool alwaysNotify{false};
auto domainInfo = s_domainInfo.lock(); //TODO: We could actually lock less if we do it per suffix.
- if (!domainInfo->count(d_suffix)) {
+ if (domainInfo->count(d_suffix) == 0) {
+ // If we don't have any state yet, this is startup, check whether we need
+ // to always notify.
+ alwaysNotify = mustDo("notify-on-startup");
TDI_t tmp;
domainInfo->emplace(d_suffix, tmp);
}
- TDI_t* domains = &(*domainInfo)[d_suffix];
+ TDI_t* state = &(*domainInfo)[d_suffix];
vector<DomainInfo> allDomains;
- getAllDomains(&allDomains, true, false);
- if (domains->size() == 0 && !mustDo("notify-on-startup")) {
- 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) {
- TDIByZone_t& zone_index = domains->get<tag_zone>();
- TDIByZone_t::iterator itByZone = zone_index.find(di->zone);
- if (itByZone == zone_index.end()) {
- s_lastId++;
-
- TinyDomainInfo tmp;
- tmp.zone = di->zone;
- tmp.id = s_lastId;
- tmp.notified_serial = di->serial;
- domains->insert(tmp);
-
- di->id = s_lastId;
- if (di->notified_serial > 0) {
- retDomains.push_back(*di);
- }
- }
- else {
- if (itByZone->notified_serial < di->serial) {
- di->id = itByZone->id;
- retDomains.push_back(*di);
- }
+ getAllDomains_locked(&allDomains, true);
+
+ for (auto& domain : allDomains) {
+ auto iter = updateState(domain, state);
+ // Keep domain id in sync with our current state.
+ domain.id = iter->id;
+ if (alwaysNotify || iter->notified_serial < domain.serial) {
+ retDomains.push_back(domain);
}
}
}
if (!domainInfo->count(d_suffix)) {
throw PDNSException("Can't get list of domains to set the serial.");
}
- TDI_t* domains = &(*domainInfo)[d_suffix];
- TDIById_t& domain_index = domains->get<tag_domainid>();
+ TDI_t* state = &(*domainInfo)[d_suffix];
+ TDIById_t& domain_index = state->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;
DLOG(g_log << Logger::Debug << backendname << "Setting serial for " << itById->zone << " to " << serial << endl);
domain_index.modify(itById, TDI_SerialModifier(serial));
}
- (*domainInfo)[d_suffix] = *domains;
+ (*domainInfo)[d_suffix] = *state;
}
-void TinyDNSBackend::getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool /* include_disabled */)
+void TinyDNSBackend::getAllDomains_locked(vector<DomainInfo>* domains, bool getSerial)
{
d_isAxfr = true;
d_isGetDomains = true;
while (get(rr)) {
if (rr.qtype.getCode() == QType::SOA && dupcheck.insert(rr.qname).second) {
DomainInfo di;
- di.id = -1; //TODO: Check if this is ok.
+ di.id = -1; // Will be overridden by caller
di.backend = this;
di.zone = rr.qname;
di.kind = DomainInfo::Primary;
}
}
+void TinyDNSBackend::getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool /* include_disabled */)
+{
+ auto domainInfo = s_domainInfo.lock(); //TODO: We could actually lock less if we do it per suffix.
+ if (domainInfo->count(d_suffix) == 0) {
+ TDI_t tmp;
+ domainInfo->emplace(d_suffix, tmp);
+ }
+
+ TDI_t* state = &(*domainInfo)[d_suffix];
+
+ getAllDomains_locked(domains, getSerial);
+
+ for (auto& domain : *domains) {
+ auto iter = updateState(domain, state);
+ // Keep domain id in sync with our current state.
+ domain.id = iter->id;
+ }
+}
+
+//NOLINTNEXTLINE(readability-identifier-length)
+bool TinyDNSBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial)
+{
+ auto domainInfo = s_domainInfo.lock(); //TODO: We could actually lock less if we do it per suffix.
+ if (domainInfo->count(d_suffix) == 0) {
+ TDI_t tmp;
+ domainInfo->emplace(d_suffix, tmp);
+ }
+
+ TDI_t* state = &(*domainInfo)[d_suffix];
+
+ vector<DomainInfo> allDomains;
+ getAllDomains_locked(&allDomains, getSerial);
+
+ bool found{false};
+ for (auto& oneDomain : allDomains) {
+ auto iter = updateState(oneDomain, state);
+ if (oneDomain.zone == domain) {
+ // Keep domain id in sync with our current state.
+ oneDomain.id = iter->id;
+ di = oneDomain;
+ found = true;
+ }
+ }
+ return found;
+}
+
bool TinyDNSBackend::list(const DNSName& target, int /* domain_id */, bool /* include_disabled */)
{
d_isAxfr = true;
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;
+ bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial = true) override;
void getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool include_disabled) override;
// Primary mode operation
void setNotified(uint32_t id, uint32_t serial) override;
private:
- vector<string> getLocations();
-
//TypeDefs
struct tag_zone
{
typedef TDI_t::index<tag_zone>::type TDIByZone_t;
typedef TDI_t::index<tag_domainid>::type TDIById_t;
+ vector<string> getLocations();
+ static TDI_t::iterator updateState(DomainInfo& domain, TDI_t* state);
+ void getAllDomains_locked(vector<DomainInfo>* domains, bool getSerial);
+
//data member variables
uint64_t d_taiepoch;
QType d_qtype;