#include <isc/hex.h>
#include <isc/mem.h>
#include <isc/print.h>
+#include <isc/rwlock.h>
#include <isc/serial.h>
#include <isc/stats.h>
#include <isc/util.h>
CTRACE(ISC_LOG_DEBUG(3), "rpz_rrset_find");
- dns_clientinfomethods_init(&cm, ns_client_sourceip);
- dns_clientinfo_init(&ci, client, NULL);
-
st = client->query.rpz_st;
if ((st->state & DNS_RPZ_RECURSING) != 0) {
INSIST(st->r.r_type == type);
break;
zbits &= (DNS_RPZ_ZMASK(rpz_num) >> 1);
- /*
- * In case num_zones has changed since zbits was
- * originally calculated
- */
- if (rpz_num >= rpzs->p.num_zones) {
- CTRACE(ISC_LOG_ERROR,
- "rpz_rewrite_ip: rpz_num is higher than "
- "number of zones");
- rpz_clean(&p_zone, &p_db, &p_node, p_rdatasetp);
- st->m.policy = DNS_RPZ_POLICY_ERROR;
- return (DNS_R_SERVFAIL);
- }
-
/*
* Do not try applying policy zones that cannot replace a
* previously found policy zone.
if ((zbits & 1) == 0)
continue;
- /*
- * In case num_zones has changed since the 'have'
- * originally calculated
- */
- if (rpz_num >= rpzs->p.num_zones) {
- CTRACE(ISC_LOG_ERROR,
- "rpz_rewrite_name: rpz_num is higher than "
- "number of zones");
- rpz_clean(&p_zone, &p_db, &p_node, rdatasetp);
- st->m.policy = DNS_RPZ_POLICY_ERROR;
- return (DNS_R_SERVFAIL);
- }
-
/*
* Do not check policy zones that cannot replace a previously
* found policy.
(st != NULL && (st->state & DNS_RPZ_REWRITTEN) != 0))
return (DNS_R_DISALLOWED);
- LOCK(&rpzs->maint_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
if (rpzs->p.num_zones == 0 ||
(!RECURSIONOK(client) && rpzs->p.no_rd_ok == 0) ||
!rpz_ck_dnssec(client, qresult, ordataset, osigset))
{
- UNLOCK(&rpzs->maint_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
return (DNS_R_DISALLOWED);
}
have = rpzs->have;
popt = rpzs->p;
rpz_ver = rpzs->rpz_ver;
- UNLOCK(&rpzs->maint_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
if (st == NULL) {
st = isc_mem_get(client->mctx, sizeof(*st));
if (st == NULL)
return (ISC_R_NOMEMORY);
st->state = 0;
+ }
+ if (st->state == 0) {
+ st->state |= DNS_RPZ_ACTIVE;
memset(&st->m, 0, sizeof(st->m));
st->m.type = DNS_RPZ_TYPE_BAD;
st->m.policy = DNS_RPZ_POLICY_MISS;
#include <isc/net.h>
#include <isc/netaddr.h>
#include <isc/print.h>
+#include <isc/rwlock.h>
#include <isc/stdlib.h>
#include <isc/string.h>
#include <isc/util.h>
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof(*new));
- result = isc_mutex_init(&new->search_lock);
+ result = isc_rwlock_init(&new->search_lock, 0, 0);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, new, sizeof(*new));
return (result);
result = isc_mutex_init(&new->maint_lock);
if (result != ISC_R_SUCCESS) {
- DESTROYLOCK(&new->search_lock);
+ isc_rwlock_destroy(&new->search_lock);
isc_mem_put(mctx, new, sizeof(*new));
return (result);
}
result = isc_refcount_init(&new->refs, 1);
if (result != ISC_R_SUCCESS) {
DESTROYLOCK(&new->maint_lock);
- DESTROYLOCK(&new->search_lock);
+ isc_rwlock_destroy(&new->search_lock);
isc_mem_put(mctx, new, sizeof(*new));
return (result);
}
isc_refcount_decrement(&new->refs, NULL);
isc_refcount_destroy(&new->refs);
DESTROYLOCK(&new->maint_lock);
- DESTROYLOCK(&new->search_lock);
+ isc_rwlock_destroy(&new->search_lock);
isc_mem_put(mctx, new, sizeof(*new));
return (result);
}
cidr_free(rpzs);
dns_rbt_destroy(&rpzs->rbt);
DESTROYLOCK(&rpzs->maint_lock);
- DESTROYLOCK(&rpzs->search_lock);
+ isc_rwlock_destroy(&rpzs->search_lock);
isc_refcount_destroy(&rpzs->refs);
isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
}
*/
tgt = DNS_RPZ_ZBIT(rpz_num);
LOCK(&rpzs->maint_lock);
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
if ((rpzs->load_begun & tgt) == 0) {
/*
* There is no existing version of the target zone.
isc_refcount_increment(&rpz->refs, NULL);
}
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
UNLOCK(&rpzs->maint_lock);
return (ISC_R_SUCCESS);
/*
* This function updates "have" bits and also the qname_skip_recurse
- * mask. It must be called when holding rpzs->search_lock.
+ * mask. It must be called when holding a write lock on rpzs->search_lock.
*/
static void
fix_triggers(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
* This is a successful initial zone loading, perhaps
* for a new instance of a view.
*/
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
fix_triggers(rpzs, rpz_num);
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
UNLOCK(&rpzs->maint_lock);
dns_rpz_detach_rpzs(load_rpzsp);
return (ISC_R_SUCCESS);
}
LOCK(&load_rpzs->maint_lock);
- LOCK(&load_rpzs->search_lock);
+ RWLOCK(&load_rpzs->search_lock, isc_rwlocktype_write);
/*
* Unless there is only one policy zone, copy the other policy zones
/*
* Exchange the summary databases.
*/
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
rpzs->triggers[rpz_num] = load_rpzs->triggers[rpz_num];
fix_triggers(rpzs, rpz_num);
rpzs->rbt = load_rpzs->rbt;
load_rpzs->rbt = rbt;
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
result = ISC_R_SUCCESS;
unlock_and_detach:
UNLOCK(&rpzs->maint_lock);
- UNLOCK(&load_rpzs->search_lock);
+ RWUNLOCK(&load_rpzs->search_lock, isc_rwlocktype_write);
UNLOCK(&load_rpzs->maint_lock);
dns_rpz_detach_rpzs(load_rpzsp);
return (result);
rpz_type = type_from_name(rpz, src_name);
LOCK(&rpzs->maint_lock);
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
switch (rpz_type) {
case DNS_RPZ_TYPE_QNAME:
break;
}
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
UNLOCK(&rpzs->maint_lock);
return (result);
}
rpz_type = type_from_name(rpz, src_name);
LOCK(&rpzs->maint_lock);
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
switch (rpz_type) {
case DNS_RPZ_TYPE_QNAME:
break;
}
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
UNLOCK(&rpzs->maint_lock);
}
return (DNS_RPZ_INVALID_NUM);
make_addr_set(&tgt_set, zbits, rpz_type);
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
result = search(rpzs, &tgt_ip, 128, &tgt_set, ISC_FALSE, &found);
if (result == ISC_R_NOTFOUND) {
/*
* There are no eligible zones for this IP address.
*/
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
return (DNS_RPZ_INVALID_NUM);
}
break;
}
result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name);
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
if (result != ISC_R_SUCCESS) {
/*
* bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
found_zbits = 0;
- LOCK(&rpzs->search_lock);
+ RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
nmnode = NULL;
result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, NULL,
break;
}
- UNLOCK(&rpzs->search_lock);
+ RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
return (zbits & found_zbits);
}
/*
* Co-ordinates the starting of routine jobs.
*/
-
void
dns_zone_maintenance(dns_zone_t *zone) {
const char me[] = "dns_zone_maintenance";
isc_time_t next;
isc_result_t result;
- ENTER;
REQUIRE(DNS_ZONE_VALID(zone));
+ ENTER;
+
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
return;
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
- INSIST(!isc_time_isepoch(&zone->refreshtime));
- if (isc_time_isepoch(&next) ||
- isc_time_compare(&zone->refreshtime, &next) < 0)
- next = zone->refreshtime;
- }
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
+ !isc_time_isepoch(&zone->refreshtime) &&
+ (isc_time_isepoch(&next) ||
+ isc_time_compare(&zone->refreshtime, &next) < 0))
+ next = zone->refreshtime;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
!isc_time_isepoch(&zone->expiretime)) {
if (isc_time_isepoch(&next) ||