#define StringView string
#endif
-void LMDBBackend::deleteDomainRecords(RecordsRWTransaction& txn, const std::string& match)
+void LMDBBackend::deleteDomainRecords(RecordsRWTransaction& txn, const std::string& match, QType qtype)
{
auto cursor = txn.txn->getCursor(txn.db->dbi);
MDBOutVal key{};
if (cursor.prefix(match, key, val) == 0) {
do {
- cursor.del(key);
+ if (qtype == QType::ANY || compoundOrdername::getQType(key.getNoStripHeader<StringView>()) == qtype) {
+ cursor.del(key);
+ }
} while (cursor.next(key, val) == 0);
}
}
return MDBDbi::d_creationCount != 0;
}
+// Hook for rectifyZone operation.
+// Before the operation starts, we forcibly remove all NSEC3 records from the
+// domain, since logic flaws in older versions may have left us with dangling
+// records. The appropriate records will be regenerated with
+// updateDNSSECOrderNameAndAuth() calls anyway.
+void LMDBBackend::rectifyZoneHook(domainid_t domain_id, bool before) const
+{
+ if (!before) {
+ return;
+ }
+
+ if (!d_rwtxn) {
+ throw DBException("rectifyZoneHook invoked outside of a transaction");
+ }
+
+ compoundOrdername order;
+ LMDBBackend::deleteDomainRecords(*d_rwtxn, order(domain_id), QType::NSEC3);
+}
+
class LMDBFactory : public BackendFactory
{
public:
bool hasCreatedLocalFiles() const override;
+ void rectifyZoneHook(domainid_t domain_id, bool before) const override;
+
// functions to use without constructing a backend object
static std::pair<uint32_t, uint32_t> getSchemaVersionAndShards(std::string& filename);
static bool upgradeToSchemav5(std::string& filename);
std::shared_ptr<RecordsROTransaction> getRecordsROTransaction(domainid_t id, const std::shared_ptr<LMDBBackend::RecordsRWTransaction>& rwtxn = nullptr);
bool genChangeDomain(const ZoneName& domain, const std::function<void(DomainInfo&)>& func);
bool genChangeDomain(domainid_t id, const std::function<void(DomainInfo&)>& func);
- static void deleteDomainRecords(RecordsRWTransaction& txn, const std::string& match);
+ static void deleteDomainRecords(RecordsRWTransaction& txn, const std::string& match, QType qtype = QType::ANY);
void getAllDomainsFiltered(vector<DomainInfo>* domains, const std::function<bool(DomainInfo&)>& allow);
if (doTransaction)
sd.db->startTransaction(zone, UnknownDomainID);
+ sd.db->rectifyZoneHook(sd.domain_id, true);
+
bool realrr=true;
bool doent=true;
int updates=0;
}
}
+ sd.db->rectifyZoneHook(sd.domain_id, false);
+
if (doTransaction)
sd.db->commitTransaction();