mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 23:02:05 -04:00
Merge branch 'ondrej/convert-dns_acl-rwlock-to-rcu' into 'main'
Convert rwlock in dns_acl to RCU See merge request isc-projects/bind9!8378
This commit is contained in:
commit
7a3ba34475
14 changed files with 180 additions and 333 deletions
|
|
@ -3878,10 +3878,7 @@ create_mapped_acl(void) {
|
|||
|
||||
isc_netaddr_fromin6(&addr, &in6);
|
||||
|
||||
result = dns_acl_create(named_g_mctx, 1, &acl);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
dns_acl_create(named_g_mctx, 1, &acl);
|
||||
|
||||
result = dns_iptable_addprefix(acl->iptable, &addr, 96, true);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
|
|
|
|||
229
lib/dns/acl.c
229
lib/dns/acl.c
|
|
@ -19,6 +19,7 @@
|
|||
#include <isc/mem.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/urcu.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
|
|
@ -32,51 +33,24 @@
|
|||
* for 'n' ACL elements. The elements are uninitialized and the
|
||||
* length is 0.
|
||||
*/
|
||||
isc_result_t
|
||||
void
|
||||
dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) {
|
||||
isc_result_t result;
|
||||
dns_acl_t *acl;
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
/*
|
||||
* Work around silly limitation of isc_mem_get().
|
||||
*/
|
||||
if (n == 0) {
|
||||
n = 1;
|
||||
}
|
||||
dns_acl_t *acl = isc_mem_get(mctx, sizeof(*acl));
|
||||
*acl = (dns_acl_t){
|
||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||
.nextincache = ISC_LINK_INITIALIZER,
|
||||
.elements = isc_mem_cget(mctx, n, sizeof(acl->elements[0])),
|
||||
.alloc = n,
|
||||
.ports_and_transports = ISC_LIST_INITIALIZER,
|
||||
.magic = DNS_ACL_MAGIC,
|
||||
};
|
||||
|
||||
acl = isc_mem_get(mctx, sizeof(*acl));
|
||||
|
||||
acl->mctx = NULL;
|
||||
isc_mem_attach(mctx, &acl->mctx);
|
||||
|
||||
acl->name = NULL;
|
||||
|
||||
isc_refcount_init(&acl->refcount, 1);
|
||||
|
||||
result = dns_iptable_create(mctx, &acl->iptable);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_mem_put(mctx, acl, sizeof(*acl));
|
||||
return (result);
|
||||
}
|
||||
|
||||
acl->elements = NULL;
|
||||
acl->alloc = 0;
|
||||
acl->length = 0;
|
||||
acl->has_negatives = false;
|
||||
|
||||
ISC_LINK_INIT(acl, nextincache);
|
||||
/*
|
||||
* Must set magic early because we use dns_acl_detach() to clean up.
|
||||
*/
|
||||
acl->magic = DNS_ACL_MAGIC;
|
||||
|
||||
acl->elements = isc_mem_cget(mctx, n, sizeof(acl->elements[0]));
|
||||
acl->alloc = n;
|
||||
ISC_LIST_INIT(acl->ports_and_transports);
|
||||
acl->port_proto_entries = 0;
|
||||
dns_iptable_create(acl->mctx, &acl->iptable);
|
||||
|
||||
*target = acl;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -90,10 +64,7 @@ dns_acl_anyornone(isc_mem_t *mctx, bool neg, dns_acl_t **target) {
|
|||
isc_result_t result;
|
||||
dns_acl_t *acl = NULL;
|
||||
|
||||
result = dns_acl_create(mctx, 0, &acl);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
dns_acl_create(mctx, 0, &acl);
|
||||
|
||||
result = dns_iptable_addprefix(acl->iptable, NULL, 0, !neg);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -432,26 +403,18 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
|||
if (env == NULL) {
|
||||
return (false);
|
||||
}
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localhost == NULL) {
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
return (false);
|
||||
}
|
||||
dns_acl_attach(env->localhost, &inner);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
rcu_read_lock();
|
||||
dns_acl_attach(rcu_dereference(env->localhost), &inner);
|
||||
rcu_read_unlock();
|
||||
break;
|
||||
|
||||
case dns_aclelementtype_localnets:
|
||||
if (env == NULL) {
|
||||
return (false);
|
||||
}
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localnets == NULL) {
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
return (false);
|
||||
}
|
||||
dns_acl_attach(env->localnets, &inner);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
rcu_read_lock();
|
||||
dns_acl_attach(rcu_dereference(env->localnets), &inner);
|
||||
rcu_read_unlock();
|
||||
break;
|
||||
|
||||
#if defined(HAVE_GEOIP2)
|
||||
|
|
@ -495,16 +458,8 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
|||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
|
||||
REQUIRE(DNS_ACL_VALID(source));
|
||||
|
||||
isc_refcount_increment(&source->refcount);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy(dns_acl_t *dacl) {
|
||||
dns__acl_destroy(dns_acl_t *dacl) {
|
||||
unsigned int i;
|
||||
dns_acl_port_transports_t *port_proto;
|
||||
|
||||
|
|
@ -539,21 +494,16 @@ destroy(dns_acl_t *dacl) {
|
|||
port_proto = next;
|
||||
}
|
||||
|
||||
isc_refcount_destroy(&dacl->refcount);
|
||||
isc_refcount_destroy(&dacl->references);
|
||||
dacl->magic = 0;
|
||||
isc_mem_putanddetach(&dacl->mctx, dacl, sizeof(*dacl));
|
||||
}
|
||||
|
||||
void
|
||||
dns_acl_detach(dns_acl_t **aclp) {
|
||||
REQUIRE(aclp != NULL && DNS_ACL_VALID(*aclp));
|
||||
dns_acl_t *acl = *aclp;
|
||||
*aclp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&acl->refcount) == 1) {
|
||||
destroy(acl);
|
||||
}
|
||||
}
|
||||
#if DNS_ACL_TRACE
|
||||
ISC_REFCOUNT_TRACE_IMPL(dns_acl, dns__acl_destroy);
|
||||
#else
|
||||
ISC_REFCOUNT_IMPL(dns_acl, dns__acl_destroy);
|
||||
#endif
|
||||
|
||||
static isc_once_t insecure_prefix_once = ISC_ONCE_INIT;
|
||||
static isc_mutex_t insecure_prefix_lock;
|
||||
|
|
@ -686,74 +636,65 @@ dns_acl_allowed(isc_netaddr_t *addr, const dns_name_t *signer, dns_acl_t *acl,
|
|||
/*
|
||||
* Initialize ACL environment, setting up localhost and localnets ACLs
|
||||
*/
|
||||
isc_result_t
|
||||
void
|
||||
dns_aclenv_create(isc_mem_t *mctx, dns_aclenv_t **envp) {
|
||||
isc_result_t result;
|
||||
dns_aclenv_t *env = isc_mem_get(mctx, sizeof(*env));
|
||||
*env = (dns_aclenv_t){ 0 };
|
||||
*env = (dns_aclenv_t){
|
||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||
.magic = DNS_ACLENV_MAGIC,
|
||||
};
|
||||
|
||||
isc_mem_attach(mctx, &env->mctx);
|
||||
isc_refcount_init(&env->references, 1);
|
||||
isc_rwlock_init(&env->rwlock);
|
||||
|
||||
result = dns_acl_create(mctx, 0, &env->localhost);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_rwlock;
|
||||
}
|
||||
result = dns_acl_create(mctx, 0, &env->localnets);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_localhost;
|
||||
}
|
||||
env->match_mapped = false;
|
||||
#if defined(HAVE_GEOIP2)
|
||||
env->geoip = NULL;
|
||||
#endif /* if defined(HAVE_GEOIP2) */
|
||||
|
||||
env->magic = DNS_ACLENV_MAGIC;
|
||||
dns_acl_create(mctx, 0, &env->localhost);
|
||||
dns_acl_create(mctx, 0, &env->localnets);
|
||||
|
||||
*envp = env;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_localhost:
|
||||
dns_acl_detach(&env->localhost);
|
||||
cleanup_rwlock:
|
||||
isc_rwlock_destroy(&env->rwlock);
|
||||
isc_mem_putanddetach(&env->mctx, env, sizeof(*env));
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_set(dns_aclenv_t *env, dns_acl_t *localhost, dns_acl_t *localnets) {
|
||||
REQUIRE(VALID_ACLENV(env));
|
||||
REQUIRE(DNS_ACL_VALID(localhost));
|
||||
REQUIRE(DNS_ACL_VALID(localnets));
|
||||
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_write);
|
||||
dns_acl_detach(&env->localhost);
|
||||
dns_acl_attach(localhost, &env->localhost);
|
||||
dns_acl_detach(&env->localnets);
|
||||
dns_acl_attach(localnets, &env->localnets);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_write);
|
||||
rcu_read_lock();
|
||||
localhost = rcu_xchg_pointer(&env->localhost, dns_acl_ref(localhost));
|
||||
localnets = rcu_xchg_pointer(&env->localnets, dns_acl_ref(localnets));
|
||||
rcu_read_unlock();
|
||||
|
||||
dns_acl_detach(&localhost);
|
||||
dns_acl_detach(&localnets);
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s) {
|
||||
REQUIRE(VALID_ACLENV(s));
|
||||
REQUIRE(VALID_ACLENV(t));
|
||||
dns_aclenv_copy(dns_aclenv_t *target, dns_aclenv_t *source) {
|
||||
REQUIRE(VALID_ACLENV(source));
|
||||
REQUIRE(VALID_ACLENV(target));
|
||||
|
||||
RWLOCK(&t->rwlock, isc_rwlocktype_write);
|
||||
RWLOCK(&s->rwlock, isc_rwlocktype_read);
|
||||
dns_acl_detach(&t->localhost);
|
||||
dns_acl_attach(s->localhost, &t->localhost);
|
||||
dns_acl_detach(&t->localnets);
|
||||
dns_acl_attach(s->localnets, &t->localnets);
|
||||
rcu_read_lock();
|
||||
|
||||
t->match_mapped = s->match_mapped;
|
||||
dns_acl_t *localhost = rcu_dereference(source->localhost);
|
||||
INSIST(DNS_ACL_VALID(localhost));
|
||||
|
||||
dns_acl_t *localnets = rcu_dereference(source->localnets);
|
||||
INSIST(DNS_ACL_VALID(localnets));
|
||||
|
||||
localhost = rcu_xchg_pointer(&target->localhost,
|
||||
dns_acl_ref(localhost));
|
||||
localnets = rcu_xchg_pointer(&target->localnets,
|
||||
dns_acl_ref(localnets));
|
||||
|
||||
target->match_mapped = source->match_mapped;
|
||||
#if defined(HAVE_GEOIP2)
|
||||
t->geoip = s->geoip;
|
||||
target->geoip = source->geoip;
|
||||
#endif /* if defined(HAVE_GEOIP2) */
|
||||
|
||||
RWUNLOCK(&s->rwlock, isc_rwlocktype_read);
|
||||
RWUNLOCK(&t->rwlock, isc_rwlocktype_write);
|
||||
rcu_read_unlock();
|
||||
|
||||
dns_acl_detach(&localhost);
|
||||
dns_acl_detach(&localnets);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -762,36 +703,26 @@ dns__aclenv_destroy(dns_aclenv_t *aclenv) {
|
|||
|
||||
aclenv->magic = 0;
|
||||
|
||||
isc_refcount_destroy(&aclenv->references);
|
||||
dns_acl_detach(&aclenv->localhost);
|
||||
dns_acl_detach(&aclenv->localnets);
|
||||
isc_rwlock_destroy(&aclenv->rwlock);
|
||||
rcu_read_lock();
|
||||
dns_acl_t *localhost = rcu_xchg_pointer(&aclenv->localhost, NULL);
|
||||
INSIST(DNS_ACL_VALID(localhost));
|
||||
|
||||
dns_acl_t *localnets = rcu_xchg_pointer(&aclenv->localnets, NULL);
|
||||
INSIST(DNS_ACL_VALID(localnets));
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
dns_acl_detach(&localhost);
|
||||
dns_acl_detach(&localnets);
|
||||
|
||||
isc_mem_putanddetach(&aclenv->mctx, aclenv, sizeof(*aclenv));
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_attach(dns_aclenv_t *source, dns_aclenv_t **targetp) {
|
||||
REQUIRE(VALID_ACLENV(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
isc_refcount_increment(&source->references);
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_aclenv_detach(dns_aclenv_t **aclenvp) {
|
||||
dns_aclenv_t *aclenv = NULL;
|
||||
|
||||
REQUIRE(aclenvp != NULL && VALID_ACLENV(*aclenvp));
|
||||
|
||||
aclenv = *aclenvp;
|
||||
*aclenvp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&aclenv->references) == 1) {
|
||||
dns__aclenv_destroy(aclenv);
|
||||
}
|
||||
}
|
||||
#if DNS_ACL_TRACE
|
||||
ISC_REFCOUNT_TRACE_IMPL(dns_aclenv, dns__aclenv_destroy);
|
||||
#else
|
||||
ISC_REFCOUNT_IMPL(dns_aclenv, dns__aclenv_destroy);
|
||||
#endif
|
||||
|
||||
void
|
||||
dns_acl_add_port_transports(dns_acl_t *acl, const in_port_t port,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
* Address match list handling.
|
||||
*/
|
||||
|
||||
/* Add -DDNS_ACL_TRACE=1 to CFLAGS for detailed reference tracing */
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
***/
|
||||
|
|
@ -32,7 +34,6 @@
|
|||
#include <isc/magic.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/rwlock.h>
|
||||
|
||||
#include <dns/geoip.h>
|
||||
#include <dns/iptable.h>
|
||||
|
|
@ -84,7 +85,7 @@ struct dns_aclelement {
|
|||
struct dns_acl {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t refcount;
|
||||
isc_refcount_t references;
|
||||
dns_iptable_t *iptable;
|
||||
dns_aclelement_t *elements;
|
||||
bool has_negatives;
|
||||
|
|
@ -101,9 +102,8 @@ struct dns_aclenv {
|
|||
isc_mem_t *mctx;
|
||||
isc_refcount_t references;
|
||||
|
||||
isc_rwlock_t rwlock; /*%< Locks localhost and localnets */
|
||||
dns_acl_t *localhost;
|
||||
dns_acl_t *localnets;
|
||||
dns_acl_t *localhost;
|
||||
dns_acl_t *localnets;
|
||||
|
||||
bool match_mapped;
|
||||
#if defined(HAVE_GEOIP2)
|
||||
|
|
@ -120,7 +120,7 @@ struct dns_aclenv {
|
|||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target);
|
||||
/*%<
|
||||
* Create a new ACL, including an IP table and an array with room
|
||||
|
|
@ -164,28 +164,16 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, bool pos);
|
|||
* an unexpected positive match in the parent ACL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_acl_attach(dns_acl_t *source, dns_acl_t **target);
|
||||
/*%<
|
||||
* Attach to acl 'source'.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'source' to be a valid acl.
|
||||
*\li 'target' to be non NULL and '*target' to be NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_acl_detach(dns_acl_t **aclp);
|
||||
/*%<
|
||||
* Detach the acl. On final detach the acl must not be linked on any
|
||||
* list.
|
||||
*
|
||||
* Requires:
|
||||
*\li '*aclp' to be a valid acl.
|
||||
*
|
||||
* Insists:
|
||||
*\li '*aclp' is not linked on final detach.
|
||||
*/
|
||||
#if DNS_ACL_TRACE
|
||||
#define dns_acl_ref(ptr) dns_acl__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_acl_unref(ptr) dns_acl__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_acl_attach(ptr, ptrp) \
|
||||
dns_acl__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_acl_detach(ptrp) dns_acl__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||
ISC_REFCOUNT_TRACE_DECL(dns_acl);
|
||||
#else
|
||||
ISC_REFCOUNT_DECL(dns_acl);
|
||||
#endif
|
||||
|
||||
bool
|
||||
dns_acl_isinsecure(const dns_acl_t *a);
|
||||
|
|
@ -206,7 +194,7 @@ dns_acl_allowed(isc_netaddr_t *addr, const dns_name_t *signer, dns_acl_t *acl,
|
|||
* permitted by 'acl' in environment 'aclenv'.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
dns_aclenv_create(isc_mem_t *mctx, dns_aclenv_t **envp);
|
||||
/*%<
|
||||
* Create ACL environment, setting up localhost and localnets ACLs
|
||||
|
|
@ -227,24 +215,18 @@ dns_aclenv_set(dns_aclenv_t *env, dns_acl_t *localhost, dns_acl_t *localnets);
|
|||
* Attach the 'localhost' and 'localnets' arguments to 'env' ACL environment
|
||||
*/
|
||||
|
||||
void
|
||||
dns_aclenv_attach(dns_aclenv_t *source, dns_aclenv_t **targetp);
|
||||
/*%<
|
||||
* Attach '*targetp' to ACL environment 'source'.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'source' is a valid ACL environment.
|
||||
*\li 'targetp' is not NULL and '*targetp' is NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_aclenv_detach(dns_aclenv_t **aclenvp);
|
||||
/*%<
|
||||
* Detach an ACL environment; on final detach, destroy it.
|
||||
*
|
||||
* Requires:
|
||||
*\li '*aclenvp' to be a valid ACL environment
|
||||
*/
|
||||
#if DNS_ACL_TRACE
|
||||
#define dns_aclenv_ref(ptr) dns_aclenv__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_aclenv_unref(ptr) \
|
||||
dns_aclenv__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_aclenv_attach(ptr, ptrp) \
|
||||
dns_aclenv__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_aclenv_detach(ptrp) \
|
||||
dns_aclenv__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||
ISC_REFCOUNT_TRACE_DECL(dns_aclenv);
|
||||
#else
|
||||
ISC_REFCOUNT_DECL(dns_aclenv);
|
||||
#endif
|
||||
|
||||
isc_result_t
|
||||
dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
|
||||
|
|
|
|||
|
|
@ -19,17 +19,20 @@
|
|||
#include <isc/lang.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/radix.h>
|
||||
#include <isc/refcount.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
struct dns_iptable {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t refcount;
|
||||
isc_refcount_t references;
|
||||
isc_radix_tree_t *radix;
|
||||
ISC_LINK(dns_iptable_t) nextincache;
|
||||
};
|
||||
|
||||
/* Add -DDNS_IPTABLE_TRACE=1 to CFLAGS for detailed reference tracing */
|
||||
|
||||
#define DNS_IPTABLE_MAGIC ISC_MAGIC('T', 'a', 'b', 'l')
|
||||
#define DNS_IPTABLE_VALID(a) ISC_MAGIC_VALID(a, DNS_IPTABLE_MAGIC)
|
||||
|
||||
|
|
@ -39,7 +42,7 @@ struct dns_iptable {
|
|||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target);
|
||||
/*
|
||||
* Create a new IP table and the underlying radix structure
|
||||
|
|
@ -58,10 +61,17 @@ dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, bool pos);
|
|||
* Merge one IP table into another one.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target);
|
||||
|
||||
void
|
||||
dns_iptable_detach(dns_iptable_t **tabp);
|
||||
#if DNS_IPTABLE_TRACE
|
||||
#define dns_iptable_ref(ptr) dns_iptable__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_iptable_unref(ptr) \
|
||||
dns_iptable__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_iptable_attach(ptr, ptrp) \
|
||||
dns_iptable__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_iptable_detach(ptrp) \
|
||||
dns_iptable__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||
ISC_REFCOUNT_TRACE_DECL(dns_iptable);
|
||||
#else
|
||||
ISC_REFCOUNT_DECL(dns_iptable);
|
||||
#endif
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -20,35 +20,21 @@
|
|||
|
||||
#include <dns/acl.h>
|
||||
|
||||
static void
|
||||
destroy_iptable(dns_iptable_t *dtab);
|
||||
|
||||
/*
|
||||
* Create a new IP table and the underlying radix structure
|
||||
*/
|
||||
isc_result_t
|
||||
void
|
||||
dns_iptable_create(isc_mem_t *mctx, dns_iptable_t **target) {
|
||||
isc_result_t result;
|
||||
dns_iptable_t *tab;
|
||||
|
||||
tab = isc_mem_get(mctx, sizeof(*tab));
|
||||
tab->mctx = NULL;
|
||||
dns_iptable_t *tab = isc_mem_get(mctx, sizeof(*tab));
|
||||
*tab = (dns_iptable_t){
|
||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||
.magic = DNS_IPTABLE_MAGIC,
|
||||
};
|
||||
isc_mem_attach(mctx, &tab->mctx);
|
||||
isc_refcount_init(&tab->refcount, 1);
|
||||
tab->radix = NULL;
|
||||
tab->magic = DNS_IPTABLE_MAGIC;
|
||||
|
||||
result = isc_radix_create(mctx, &tab->radix, RADIX_MAXBITS);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
isc_radix_create(mctx, &tab->radix, RADIX_MAXBITS);
|
||||
|
||||
*target = tab;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
dns_iptable_detach(&tab);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static bool dns_iptable_neg = false;
|
||||
|
|
@ -141,34 +127,22 @@ dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, bool pos) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_iptable_attach(dns_iptable_t *source, dns_iptable_t **target) {
|
||||
REQUIRE(DNS_IPTABLE_VALID(source));
|
||||
isc_refcount_increment(&source->refcount);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_iptable_detach(dns_iptable_t **tabp) {
|
||||
REQUIRE(tabp != NULL && DNS_IPTABLE_VALID(*tabp));
|
||||
dns_iptable_t *tab = *tabp;
|
||||
*tabp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&tab->refcount) == 1) {
|
||||
isc_refcount_destroy(&tab->refcount);
|
||||
destroy_iptable(tab);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_iptable(dns_iptable_t *dtab) {
|
||||
dns__iptable_destroy(dns_iptable_t *dtab) {
|
||||
REQUIRE(DNS_IPTABLE_VALID(dtab));
|
||||
|
||||
dtab->magic = 0;
|
||||
|
||||
if (dtab->radix != NULL) {
|
||||
isc_radix_destroy(dtab->radix, NULL);
|
||||
dtab->radix = NULL;
|
||||
}
|
||||
|
||||
dtab->magic = 0;
|
||||
isc_mem_putanddetach(&dtab->mctx, dtab, sizeof(*dtab));
|
||||
}
|
||||
|
||||
#if DNS_IPTABLE_TRACE
|
||||
ISC_REFCOUNT_TRACE_IMPL(dns_iptable, dns__iptable_destroy);
|
||||
#else
|
||||
ISC_REFCOUNT_IMPL(dns_iptable, dns__iptable_destroy);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -367,10 +367,11 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
|
|||
if (!dns_name_issubdomain(name, rule->name)) {
|
||||
continue;
|
||||
}
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
dns_acl_match(addr, NULL, env->localhost, NULL, &match,
|
||||
rcu_read_lock();
|
||||
dns_acl_t *localhost = rcu_dereference(env->localhost);
|
||||
dns_acl_match(addr, NULL, localhost, NULL, &match,
|
||||
NULL);
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
rcu_read_unlock();
|
||||
if (match == 0) {
|
||||
if (signer != NULL) {
|
||||
isc_log_write(dns_lctx,
|
||||
|
|
|
|||
|
|
@ -157,10 +157,7 @@ dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispatchmgr,
|
|||
goto cleanup_order;
|
||||
}
|
||||
|
||||
result = dns_aclenv_create(view->mctx, &view->aclenv);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_peerlist;
|
||||
}
|
||||
dns_aclenv_create(view->mctx, &view->aclenv);
|
||||
|
||||
dns_nametree_create(view->mctx, DNS_NAMETREE_COUNT, "sfd", &view->sfd);
|
||||
|
||||
|
|
@ -169,11 +166,6 @@ dns_view_create(isc_mem_t *mctx, dns_dispatchmgr_t *dispatchmgr,
|
|||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_peerlist:
|
||||
if (view->peers != NULL) {
|
||||
dns_peerlist_detach(&view->peers);
|
||||
}
|
||||
|
||||
cleanup_order:
|
||||
if (view->order != NULL) {
|
||||
dns_order_detach(&view->order);
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ typedef struct isc_radix_node {
|
|||
* nodes */
|
||||
} isc_radix_node_t;
|
||||
|
||||
#define RADIX_TREE_MAGIC ISC_MAGIC('R', 'd', 'x', 'T');
|
||||
#define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC);
|
||||
#define RADIX_TREE_MAGIC ISC_MAGIC('R', 'd', 'x', 'T')
|
||||
#define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC)
|
||||
|
||||
typedef struct isc_radix_tree {
|
||||
unsigned int magic;
|
||||
|
|
@ -157,7 +157,7 @@ isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node);
|
|||
* \li 'node' to be valid.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits);
|
||||
/*%<
|
||||
* Create a radix tree with a maximum depth of 'maxbits';
|
||||
|
|
|
|||
|
|
@ -131,24 +131,18 @@ _comp_with_mask(void *addr, void *dest, u_int mask) {
|
|||
return (0);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) {
|
||||
isc_radix_tree_t *radix;
|
||||
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
RUNTIME_CHECK(maxbits <= RADIX_MAXBITS);
|
||||
|
||||
radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t));
|
||||
|
||||
radix->mctx = NULL;
|
||||
isc_radix_tree_t *radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t));
|
||||
*radix = (isc_radix_tree_t){
|
||||
.maxbits = maxbits,
|
||||
.magic = RADIX_TREE_MAGIC,
|
||||
};
|
||||
isc_mem_attach(mctx, &radix->mctx);
|
||||
radix->maxbits = maxbits;
|
||||
radix->head = NULL;
|
||||
radix->num_active_node = 0;
|
||||
radix->num_added_node = 0;
|
||||
RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */
|
||||
radix->magic = RADIX_TREE_MAGIC;
|
||||
*target = radix;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -685,10 +685,7 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
|
|||
nelem = cfg_list_length(caml, false);
|
||||
}
|
||||
|
||||
result = dns_acl_create(mctx, nelem, &dacl);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
dns_acl_create(mctx, nelem, &dacl);
|
||||
}
|
||||
|
||||
if (is_tuple) {
|
||||
|
|
@ -771,12 +768,8 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
|
|||
iptab = dacl->iptable;
|
||||
|
||||
if (nest_level != 0) {
|
||||
result = dns_acl_create(mctx,
|
||||
cfg_list_length(ce, false),
|
||||
&de->nestedacl);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
dns_acl_create(mctx, cfg_list_length(ce, false),
|
||||
&de->nestedacl);
|
||||
iptab = de->nestedacl->iptable;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -308,10 +308,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||
}
|
||||
ns_listenlist_attach(mgr->listenon4, &mgr->listenon6);
|
||||
|
||||
result = dns_aclenv_create(mctx, &mgr->aclenv);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_listenon;
|
||||
}
|
||||
dns_aclenv_create(mctx, &mgr->aclenv);
|
||||
#if defined(HAVE_GEOIP2)
|
||||
mgr->aclenv->geoip = geoip;
|
||||
#else /* if defined(HAVE_GEOIP2) */
|
||||
|
|
@ -347,9 +344,6 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
|
|||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_listenon:
|
||||
ns_listenlist_detach(&mgr->listenon4);
|
||||
ns_listenlist_detach(&mgr->listenon6);
|
||||
cleanup_lock:
|
||||
isc_mutex_destroy(&mgr->lock);
|
||||
ns_server_detach(&mgr->sctx);
|
||||
|
|
@ -1104,14 +1098,8 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
result = dns_acl_create(mgr->mctx, 0, &localhost);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_iter;
|
||||
}
|
||||
result = dns_acl_create(mgr->mctx, 0, &localnets);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_localhost;
|
||||
}
|
||||
dns_acl_create(mgr->mctx, 0, &localhost);
|
||||
dns_acl_create(mgr->mctx, 0, &localnets);
|
||||
|
||||
clearlistenon(mgr);
|
||||
|
||||
|
|
@ -1292,13 +1280,9 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
|
|||
|
||||
dns_aclenv_set(mgr->aclenv, localhost, localnets);
|
||||
|
||||
/* cleanup_localnets: */
|
||||
dns_acl_detach(&localnets);
|
||||
|
||||
cleanup_localhost:
|
||||
dns_acl_detach(&localhost);
|
||||
|
||||
cleanup_iter:
|
||||
isc_interfaceiter_destroy(&iter);
|
||||
return (result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,30 +84,25 @@ ns_sortlist_setup(dns_acl_t *acl, dns_aclenv_t *env, isc_netaddr_t *clientaddr,
|
|||
}
|
||||
|
||||
if (order_elt->type == dns_aclelementtype_localhost) {
|
||||
dns_acl_t *inner = NULL;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localhost != NULL) {
|
||||
dns_acl_attach(env->localhost, &inner);
|
||||
}
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
|
||||
rcu_read_lock();
|
||||
dns_acl_t *inner = rcu_dereference(env->localhost);
|
||||
if (inner != NULL) {
|
||||
*argp = inner;
|
||||
*argp = dns_acl_ref(inner);
|
||||
rcu_read_unlock();
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (order_elt->type == dns_aclelementtype_localnets) {
|
||||
dns_acl_t *inner = NULL;
|
||||
RWLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
if (env->localnets != NULL) {
|
||||
dns_acl_attach(env->localnets, &inner);
|
||||
}
|
||||
RWUNLOCK(&env->rwlock, isc_rwlocktype_read);
|
||||
rcu_read_lock();
|
||||
dns_acl_t *inner = rcu_dereference(env->localhost);
|
||||
if (inner != NULL) {
|
||||
*argp = inner;
|
||||
*argp = dns_acl_ref(inner);
|
||||
rcu_read_unlock();
|
||||
return (NS_SORTLISTTYPE_2ELEMENT);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -56,11 +56,9 @@ ISC_RUN_TEST_IMPL(dns_acl_isinsecure) {
|
|||
result = dns_acl_none(mctx, &none);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = dns_acl_create(mctx, 1, ¬none);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
dns_acl_create(mctx, 1, ¬none);
|
||||
|
||||
result = dns_acl_create(mctx, 1, ¬any);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
dns_acl_create(mctx, 1, ¬any);
|
||||
|
||||
result = dns_acl_merge(notnone, none, false);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
|
@ -69,8 +67,7 @@ ISC_RUN_TEST_IMPL(dns_acl_isinsecure) {
|
|||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
#if defined(HAVE_GEOIP2)
|
||||
result = dns_acl_create(mctx, 1, &geoip);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
dns_acl_create(mctx, 1, &geoip);
|
||||
|
||||
de = geoip->elements;
|
||||
assert_non_null(de);
|
||||
|
|
@ -84,8 +81,7 @@ ISC_RUN_TEST_IMPL(dns_acl_isinsecure) {
|
|||
de->node_num = dns_acl_node_count(geoip);
|
||||
geoip->length++;
|
||||
|
||||
result = dns_acl_create(mctx, 1, ¬geoip);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
dns_acl_create(mctx, 1, ¬geoip);
|
||||
|
||||
result = dns_acl_merge(notgeoip, geoip, false);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ ISC_RUN_TEST_IMPL(isc_radix_remove) {
|
|||
|
||||
UNUSED(state);
|
||||
|
||||
result = isc_radix_create(mctx, &radix, 32);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_radix_create(mctx, &radix, 32);
|
||||
|
||||
in_addr.s_addr = inet_addr("1.1.1.1");
|
||||
isc_netaddr_fromin(&netaddr, &in_addr);
|
||||
|
|
@ -90,8 +89,7 @@ ISC_RUN_TEST_IMPL(isc_radix_search) {
|
|||
|
||||
UNUSED(state);
|
||||
|
||||
result = isc_radix_create(mctx, &radix, 32);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_radix_create(mctx, &radix, 32);
|
||||
|
||||
in_addr.s_addr = inet_addr("3.3.3.0");
|
||||
isc_netaddr_fromin(&netaddr, &in_addr);
|
||||
|
|
|
|||
Loading…
Reference in a new issue