};
typedef struct rpz_update {
- dns_rpz_zone_t *rpz;
- dns_db_t *db;
+ dns_rpz_zone_t *rpz;
+ dns_db_t *db;
dns_dbversion_t *dbversion;
} rpz_update_t;
} while (cnode != NULL);
}
-/* Caller must hold rpzs->maint_lock */
+/* Caller must hold rpzs->data_lock. */
static void
fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) {
dns_rpz_zbits_t mask;
};
isc_rwlock_init(&rpzs->search_lock);
- isc_mutex_init(&rpzs->maint_lock);
+ isc_mutex_init(&rpzs->data_lock);
+ atomic_init(&rpzs->shuttingdown, false);
isc_refcount_init(&rpzs->references, 1);
dns_qpmulti_create(mctx, &qpmethods, view, &rpzs->table);
.magic = DNS_RPZ_ZONE_MAGIC,
.rpzs = rpzs,
};
+ isc_mutex_init(&rpz->update_lock);
/*
* This will never be used, but costs us nothing and
REQUIRE(DNS_DB_VALID(db));
REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->update_lock);
- if (rpz->rpzs->shuttingdown) {
+ if (atomic_load(&rpz->rpzs->shuttingdown)) {
result = ISC_R_SHUTTINGDOWN;
goto unlock;
}
}
unlock:
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->update_lock);
return result;
}
REQUIRE(DNS_DB_VALID(db));
REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->update_lock);
dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback, rpz);
if (rpz->processed) {
rpz->processed = false;
INSIST(atomic_fetch_sub_acq_rel(&rpz->rpzs->zones_registered,
1) > 0);
}
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->update_lock);
}
void
REQUIRE(DNS_DB_VALID(db));
REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->update_lock);
if (!rpz->dbregistered) {
rpz->dbregistered = true;
atomic_fetch_add_acq_rel(&rpz->rpzs->zones_registered, 1);
}
dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback, rpz);
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->update_lock);
}
static void
REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->update_lock);
rpz->updaterunning = false;
dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE);
- if (rpz->updatepending && !rpz->rpzs->shuttingdown) {
+ if (rpz->updatepending && !atomic_load(&rpz->rpzs->shuttingdown)) {
/* Restart the timer */
dns__rpz_timer_start(rpz);
}
atomic_fetch_add_acq_rel(&rpz->rpzs->zones_processed, 1);
}
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->update_lock);
isc_log_write(DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_RPZ, ISC_LOG_INFO,
"rpz: %s: reload done: %s", dname,
}
static isc_result_t
-update_nodes(dns_rpz_zone_t *rpz, dns_db_t *db,
- dns_dbversion_t *dbversion, isc_ht_t *newnodes) {
+update_nodes(dns_rpz_zone_t *rpz, dns_db_t *db, dns_dbversion_t *dbversion,
+ isc_ht_t *newnodes) {
isc_result_t result;
dns_dbiterator_t *updbit = NULL;
dns_name_t *name = NULL;
goto cleanup;
}
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->rpzs->data_lock);
slow_mode = rpz->rpzs->p.slow_mode;
dns_qp_t *qp = NULL;
dns_rdatasetiter_t *rdsiter = NULL;
dns_dbnode_t *node = NULL;
- if (rpz->rpzs->shuttingdown) {
+ if (atomic_load(&rpz->rpzs->shuttingdown)) {
result = ISC_R_SHUTTINGDOWN;
goto done;
}
done:
dns_qp_compact(qp, DNS_QPGC_MAYBE);
dns_qpmulti_commit(rpz->rpzs->table, &qp);
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->rpzs->data_lock);
cleanup:
dns_dbiterator_destroy(&updbit);
name = dns_fixedname_initname(&fixname);
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->rpzs->data_lock);
dns_qpmulti_write(rpz->rpzs->table, &qp);
isc_ht_iter_create(rpz->nodes, &iter);
unsigned char *key = NULL;
size_t keysize;
- if (rpz->rpzs->shuttingdown) {
- result = ISC_R_SHUTTINGDOWN;
+ result = dns__rpz_shuttingdown(rpz->rpzs);
+ if (result != ISC_R_SUCCESS) {
break;
}
isc_ht_iter_destroy(&iter);
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->rpzs->data_lock);
return result;
}
static isc_result_t
dns__rpz_shuttingdown(dns_rpz_zones_t *rpzs) {
- bool shuttingdown = false;
-
- LOCK(&rpzs->maint_lock);
- shuttingdown = rpzs->shuttingdown;
- UNLOCK(&rpzs->maint_lock);
-
- if (shuttingdown) {
+ if (atomic_load(&rpzs->shuttingdown)) {
return ISC_R_SHUTTINGDOWN;
}
rpz_update_t *update = NULL;
REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
- REQUIRE(DNS_DB_VALID(rpz->db));
- LOCK(&rpz->rpzs->maint_lock);
+ LOCK(&rpz->update_lock);
- if (rpz->rpzs->shuttingdown) {
+ if (atomic_load(&rpz->rpzs->shuttingdown)) {
goto unlock;
}
+ REQUIRE(DNS_DB_VALID(rpz->db));
rpz->updatepending = false;
rpz->updaterunning = true;
rpz->lastupdated = isc_time_now();
unlock:
- UNLOCK(&rpz->rpzs->maint_lock);
+ UNLOCK(&rpz->update_lock);
}
/*
static void
dns__rpz_shutdown(dns_rpz_zone_t *rpz) {
- /* maint_lock must be locked */
+ /* update_lock must be locked. */
if (rpz->updatetimer != NULL) {
/* Don't wait for timer to trigger for shutdown */
INSIST(rpz->loop != NULL);
INSIST(!rpz->updaterunning);
isc_ht_destroy(&rpz->nodes);
+ isc_mutex_destroy(&rpz->update_lock);
isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
}
static void
dns__rpz_zones_destroy(dns_rpz_zones_t *rpzs) {
- REQUIRE(rpzs->shuttingdown);
+ REQUIRE(atomic_load(&rpzs->shuttingdown));
for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num)
{
dns_qpmulti_destroy(&rpzs->table);
}
- isc_mutex_destroy(&rpzs->maint_lock);
+ isc_mutex_destroy(&rpzs->data_lock);
isc_rwlock_destroy(&rpzs->search_lock);
isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
}
* Forget the last of the view's rpz machinery when shutting down.
*/
- LOCK(&rpzs->maint_lock);
- if (rpzs->shuttingdown) {
- UNLOCK(&rpzs->maint_lock);
+ if (!atomic_compare_exchange_strong(&rpzs->shuttingdown,
+ &(bool){ false }, true))
+ {
return;
}
- rpzs->shuttingdown = true;
-
for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num)
{
if (rpzs->zones[rpz_num] == NULL) {
continue;
}
+ LOCK(&rpzs->zones[rpz_num]->update_lock);
dns__rpz_shutdown(rpzs->zones[rpz_num]);
+ UNLOCK(&rpzs->zones[rpz_num]->update_lock);
}
- UNLOCK(&rpzs->maint_lock);
}
#ifdef DNS_RPZ_TRACE