mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 10:01:15 -04:00
add semantics to dns_nametree to support bitfields
name trees can now hold either boolean values or bit fields. the type is selected when the name tree is created. the behavior of dns_nametree_add() differs slightly beteween the types: in a boolean tree adding an existing name will return ISC_R_EXISTS, but in a bitfield tree it simply sets the specified bit in the bitfield and returns ISC_R_SUCCESS.
This commit is contained in:
parent
54fc02410e
commit
9ed1dba976
5 changed files with 273 additions and 96 deletions
|
|
@ -645,7 +645,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
|
|||
}
|
||||
}
|
||||
|
||||
dns_nametree_create(mctx, confname, ntp);
|
||||
dns_nametree_create(mctx, DNS_NAMETREE_BOOL, confname, ntp);
|
||||
|
||||
name = dns_fixedname_initname(&fixed);
|
||||
for (element = cfg_list_first(obj); element != NULL;
|
||||
|
|
|
|||
|
|
@ -40,16 +40,22 @@
|
|||
/* Define to 1 for detailed reference tracing */
|
||||
#undef DNS_NAMETREE_TRACE
|
||||
|
||||
typedef enum { DNS_NAMETREE_BOOL, DNS_NAMETREE_BITS } dns_nametree_type_t;
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
void
|
||||
dns_nametree_create(isc_mem_t *mctx, const char *name, dns_nametree_t **ntp);
|
||||
dns_nametree_create(isc_mem_t *mctx, dns_nametree_type_t type, const char *name,
|
||||
dns_nametree_t **ntp);
|
||||
/*%<
|
||||
* Create a nametree.
|
||||
*
|
||||
* If 'name' is not NULL, it will be saved as the name of the QP trie
|
||||
* for debugging purposes.
|
||||
*
|
||||
* 'type' indicates whether the tree will be used for storing boolean
|
||||
* values (DNS_NAMETREE_BOOL) or bitfields (DNS_NAMETREE_BITS).
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
|
|
@ -57,13 +63,22 @@ dns_nametree_create(isc_mem_t *mctx, const char *name, dns_nametree_t **ntp);
|
|||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name, bool value);
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
uint32_t value);
|
||||
/*%<
|
||||
* Add a node to 'nametree'.
|
||||
*
|
||||
* 'value' is a single boolean value, true or false. If the name already
|
||||
* If the nametree type was set to DNS_NAMETREE_BOOL, then 'value'
|
||||
* represents a single boolean value, true or false. If the name already
|
||||
* exists within the tree, then return ISC_R_EXISTS.
|
||||
*
|
||||
* If the nametree type was set to DNS_NAMETREE_BITS, then 'value' is
|
||||
* a bit number within a bit field, which is sized to accomodate at least
|
||||
* 'value' bits. If the name already exists, then that bit will be set
|
||||
* in the bitfield, other bits will be retained, and ISC_R_SUCCESS will be
|
||||
* returned. If 'value' excees the number of bits in the existing bit
|
||||
* field, the field will be expanded.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'nametree' points to a valid nametree.
|
||||
|
|
@ -116,13 +131,21 @@ dns_nametree_find(dns_nametree_t *nametree, const dns_name_t *name,
|
|||
*/
|
||||
|
||||
bool
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name);
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
uint32_t bit);
|
||||
/*%<
|
||||
* Indicates whether a 'name' is covered by 'nametree'.
|
||||
* Indicates whether a 'name' (with optional 'bit' value) is covered by
|
||||
* 'nametree'.
|
||||
*
|
||||
* This returns true if 'name' has a match or a closest ancestor in
|
||||
* 'nametree' with its value set to 'true'. If a name is not found, or if
|
||||
* 'nametree' is NULL, the default return value is false.
|
||||
* In DNS_NAMETREE_BOOL nametrees, this returns true if 'name' has a match
|
||||
* or a closest ancestor in 'nametree' with its value set to 'true'.
|
||||
* 'bit' is ignored.
|
||||
*
|
||||
* In DNS_NAMETREE_BITS trees, this returns true if 'name' has a match or
|
||||
* a closest ancestor in 'nametree' with the 'bit' set in its bitfield.
|
||||
*
|
||||
* If a name is not found, or if 'nametree' is NULL, the default return
|
||||
* value is false.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ struct dns_nametree {
|
|||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t references;
|
||||
dns_nametree_type_t type;
|
||||
dns_qpmulti_t *table;
|
||||
char name[64];
|
||||
};
|
||||
|
|
@ -41,10 +42,8 @@ struct dns_ntnode {
|
|||
isc_refcount_t references;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name;
|
||||
union {
|
||||
bool value;
|
||||
unsigned char *bits;
|
||||
};
|
||||
bool set;
|
||||
uint8_t *bits;
|
||||
};
|
||||
|
||||
/* QP trie methods */
|
||||
|
|
@ -67,6 +66,9 @@ static dns_qpmethods_t qpmethods = {
|
|||
static void
|
||||
destroy_ntnode(dns_ntnode_t *node) {
|
||||
isc_refcount_destroy(&node->references);
|
||||
if (node->bits != NULL) {
|
||||
isc_mem_cput(node->mctx, node->bits, 8, sizeof(uint32_t));
|
||||
}
|
||||
isc_mem_putanddetach(&node->mctx, node, sizeof(dns_ntnode_t));
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +79,8 @@ ISC_REFCOUNT_IMPL(dns_ntnode, destroy_ntnode);
|
|||
#endif
|
||||
|
||||
void
|
||||
dns_nametree_create(isc_mem_t *mctx, const char *name, dns_nametree_t **ntp) {
|
||||
dns_nametree_create(isc_mem_t *mctx, dns_nametree_type_t type, const char *name,
|
||||
dns_nametree_t **ntp) {
|
||||
dns_nametree_t *nametree = NULL;
|
||||
|
||||
REQUIRE(ntp != NULL && *ntp == NULL);
|
||||
|
|
@ -85,6 +88,7 @@ dns_nametree_create(isc_mem_t *mctx, const char *name, dns_nametree_t **ntp) {
|
|||
nametree = isc_mem_get(mctx, sizeof(*nametree));
|
||||
*nametree = (dns_nametree_t){
|
||||
.magic = NAMETREE_MAGIC,
|
||||
.type = type,
|
||||
};
|
||||
isc_mem_attach(mctx, &nametree->mctx);
|
||||
isc_refcount_init(&nametree->references, 1);
|
||||
|
|
@ -126,31 +130,69 @@ newnode(isc_mem_t *mctx, const dns_name_t *name) {
|
|||
return (node);
|
||||
}
|
||||
|
||||
static bool
|
||||
matchbit(unsigned char *bits, uint32_t val) {
|
||||
unsigned int len = val / 8;
|
||||
unsigned int mask = 1 << (val % 8);
|
||||
|
||||
if ((bits[len] & mask) != 0) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name, bool value) {
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
uint32_t value) {
|
||||
isc_result_t result;
|
||||
dns_qp_t *qp = NULL;
|
||||
unsigned int len, mask;
|
||||
dns_ntnode_t *old = NULL, *new = NULL;
|
||||
|
||||
REQUIRE(VALID_NAMETREE(nametree));
|
||||
REQUIRE(name != NULL);
|
||||
|
||||
dns_qpmulti_write(nametree->table, &qp);
|
||||
|
||||
result = dns_qp_getname(qp, name, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_EXISTS;
|
||||
} else {
|
||||
dns_ntnode_t *node = newnode(nametree->mctx, name);
|
||||
node->value = value;
|
||||
result = dns_qp_insert(qp, node, 0);
|
||||
switch (nametree->type) {
|
||||
case DNS_NAMETREE_BOOL:
|
||||
new = newnode(nametree->mctx, name);
|
||||
new->set = value;
|
||||
break;
|
||||
|
||||
/*
|
||||
* We detach the node here, so any dns_qp_deletename() will
|
||||
* destroy the node directly.
|
||||
*/
|
||||
dns_ntnode_detach(&node);
|
||||
case DNS_NAMETREE_BITS:
|
||||
result = dns_qp_getname(qp, name, (void **)&old, NULL);
|
||||
if (result == ISC_R_SUCCESS && matchbit(old->bits, value)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = value / 8;
|
||||
mask = 1 << (value % 8);
|
||||
|
||||
new = newnode(nametree->mctx, name);
|
||||
new->bits = isc_mem_cget(nametree->mctx, 8, sizeof(value));
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
INSIST(old != NULL);
|
||||
memmove(new->bits, old->bits, old->bits[0]);
|
||||
result = dns_qp_deletename(qp, name, NULL, NULL);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
new->bits[len] |= mask;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
result = dns_qp_insert(qp, new, 0);
|
||||
|
||||
/*
|
||||
* We detach the node here, so any dns_qp_deletename() will
|
||||
* destroy the node directly.
|
||||
*/
|
||||
dns_ntnode_detach(&new);
|
||||
|
||||
out:
|
||||
dns_qp_compact(qp, DNS_QPGC_MAYBE);
|
||||
dns_qpmulti_commit(nametree->table, &qp);
|
||||
return (result);
|
||||
|
|
@ -200,12 +242,12 @@ dns_nametree_find(dns_nametree_t *nametree, const dns_name_t *name,
|
|||
}
|
||||
|
||||
bool
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name) {
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
uint32_t bit) {
|
||||
isc_result_t result;
|
||||
dns_qpread_t qpr;
|
||||
dns_ntnode_t *ntnode = NULL;
|
||||
void *pval = NULL;
|
||||
bool value = false;
|
||||
dns_ntnode_t *node = NULL;
|
||||
bool ret = false;
|
||||
|
||||
REQUIRE(nametree == NULL || VALID_NAMETREE(nametree));
|
||||
|
||||
|
|
@ -214,14 +256,17 @@ dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name) {
|
|||
}
|
||||
|
||||
dns_qpmulti_query(nametree->table, &qpr);
|
||||
result = dns_qp_findname_ancestor(&qpr, name, 0, &pval, NULL);
|
||||
result = dns_qp_findname_ancestor(&qpr, name, 0, (void **)&node, NULL);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
ntnode = pval;
|
||||
value = ntnode->value;
|
||||
if (nametree->type == DNS_NAMETREE_BOOL) {
|
||||
ret = node->set;
|
||||
} else {
|
||||
ret = matchbit(node->bits, bit);
|
||||
}
|
||||
}
|
||||
|
||||
dns_qpread_destroy(nametree->table, &qpr);
|
||||
return (value);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -6752,7 +6752,7 @@ is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
|
|||
* If the owner name matches one in the exclusion list, either
|
||||
* exactly or partially, allow it.
|
||||
*/
|
||||
if (dns_nametree_covered(view->answeracl_exclude, name)) {
|
||||
if (dns_nametree_covered(view->answeracl_exclude, name, 0)) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
@ -6865,7 +6865,7 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
|
|||
* If the owner name matches one in the exclusion list, either
|
||||
* exactly or partially, allow it.
|
||||
*/
|
||||
if (dns_nametree_covered(view->answernames_exclude, qname)) {
|
||||
if (dns_nametree_covered(view->answernames_exclude, qname, 0)) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
@ -6885,7 +6885,7 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
|
|||
/*
|
||||
* Otherwise, apply filters.
|
||||
*/
|
||||
if (dns_nametree_covered(view->denyanswernames, tname)) {
|
||||
if (dns_nametree_covered(view->denyanswernames, tname, 0)) {
|
||||
char qnamebuf[DNS_NAME_FORMATSIZE];
|
||||
char tnamebuf[DNS_NAME_FORMATSIZE];
|
||||
char classbuf[64];
|
||||
|
|
@ -10887,7 +10887,8 @@ dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name,
|
|||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
if (resolver->mustbesecure == NULL) {
|
||||
dns_nametree_create(resolver->mctx, "dnssec-must-be-secure",
|
||||
dns_nametree_create(resolver->mctx, DNS_NAMETREE_BOOL,
|
||||
"dnssec-must-be-secure",
|
||||
&resolver->mustbesecure);
|
||||
}
|
||||
|
||||
|
|
@ -10899,7 +10900,7 @@ bool
|
|||
dns_resolver_getmustbesecure(dns_resolver_t *resolver, const dns_name_t *name) {
|
||||
REQUIRE(VALID_RESOLVER(resolver));
|
||||
|
||||
return (dns_nametree_covered(resolver->mustbesecure, name));
|
||||
return (dns_nametree_covered(resolver->mustbesecure, name, 0));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@
|
|||
|
||||
#include <tests/dns.h>
|
||||
|
||||
dns_nametree_t *nametree = NULL;
|
||||
dns_nametree_t *booltree = NULL;
|
||||
dns_nametree_t *bitstree = NULL;
|
||||
|
||||
/*
|
||||
* Test utilities. In general, these assume input parameters are valid
|
||||
|
|
@ -46,38 +47,49 @@ dns_nametree_t *nametree = NULL;
|
|||
* the test code concise.
|
||||
*/
|
||||
|
||||
/* Common setup: create a nametree to test with a few keys */
|
||||
/* Common setup: create a booltree to test with a few keys */
|
||||
static void
|
||||
create_tables(void) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
||||
dns_nametree_create(mctx, "test", &nametree);
|
||||
dns_nametree_create(mctx, DNS_NAMETREE_BOOL, "bool test", &booltree);
|
||||
dns_nametree_create(mctx, DNS_NAMETREE_BITS, "bits test", &bitstree);
|
||||
|
||||
/* Add a positive node */
|
||||
/* Add a positive boolean node */
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, name, true), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_add(booltree, name, true), ISC_R_SUCCESS);
|
||||
|
||||
/* Add a negative node below it */
|
||||
/* Add assorted bits to a bitfield node */
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 1), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 9), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 53), ISC_R_SUCCESS);
|
||||
|
||||
/* Add negative boolean nodes with and without parents */
|
||||
dns_test_namefromstring("negative.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, name, false),
|
||||
assert_int_equal(dns_nametree_add(booltree, name, false),
|
||||
ISC_R_SUCCESS);
|
||||
dns_test_namefromstring("negative.example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_add(booltree, name, false),
|
||||
ISC_R_SUCCESS);
|
||||
|
||||
/* Add a negative node with no parent */
|
||||
dns_test_namefromstring("negative.example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, name, false),
|
||||
ISC_R_SUCCESS);
|
||||
/* Add a bitfield nodes under a parent */
|
||||
dns_test_namefromstring("sub.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 2), ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_tables(void) {
|
||||
if (nametree != NULL) {
|
||||
dns_nametree_detach(&nametree);
|
||||
if (booltree != NULL) {
|
||||
dns_nametree_detach(&booltree);
|
||||
}
|
||||
if (bitstree != NULL) {
|
||||
dns_nametree_detach(&bitstree);
|
||||
}
|
||||
rcu_barrier();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(add) {
|
||||
ISC_RUN_TEST_IMPL(add_bool) {
|
||||
dns_ntnode_t *node = NULL;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
|
@ -88,15 +100,15 @@ ISC_RUN_TEST_IMPL(add) {
|
|||
* Getting the node for example.com should succeed.
|
||||
*/
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
/*
|
||||
* Try to add the same name. This should fail.
|
||||
*/
|
||||
assert_int_equal(dns_nametree_add(nametree, name, false), ISC_R_EXISTS);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_add(booltree, name, false), ISC_R_EXISTS);
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
|
|
@ -104,14 +116,133 @@ ISC_RUN_TEST_IMPL(add) {
|
|||
* Try to add a new name.
|
||||
*/
|
||||
dns_test_namefromstring("newname.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, name, true), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_add(booltree, name, true), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(add_bits) {
|
||||
dns_ntnode_t *node = NULL;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
||||
create_tables();
|
||||
|
||||
/*
|
||||
* Getting the node for example.com should succeed.
|
||||
*/
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
/*
|
||||
* Try to add the same name. This should succeed.
|
||||
*/
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 1), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 2), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 3), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
/*
|
||||
* Try to add a new name.
|
||||
*/
|
||||
dns_test_namefromstring("newname.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(booltree, name, true), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(covered_bool) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
const char *yesnames[] = { "example.com.", "sub.example.com.", NULL };
|
||||
const char *nonames[] = { "whatever.com.", "negative.example.com.",
|
||||
"example.org.", "negative.example.org.",
|
||||
NULL };
|
||||
create_tables();
|
||||
|
||||
for (const char **n = yesnames; *n != NULL; n++) {
|
||||
dns_test_namefromstring(*n, &fn);
|
||||
assert_true(dns_nametree_covered(booltree, name, 0));
|
||||
}
|
||||
for (const char **n = nonames; *n != NULL; n++) {
|
||||
dns_test_namefromstring(*n, &fn);
|
||||
assert_false(dns_nametree_covered(booltree, name, 0));
|
||||
}
|
||||
|
||||
/* If the nametree is NULL, dns_nametree_covered() returns false. */
|
||||
dns_test_namefromstring("anyname.example.", &fn);
|
||||
assert_false(dns_nametree_covered(NULL, name, 0));
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(covered_bits) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
||||
create_tables();
|
||||
|
||||
/* check existing bit values */
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_false(dns_nametree_covered(bitstree, name, 0));
|
||||
assert_true(dns_nametree_covered(bitstree, name, 1));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 2));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 3));
|
||||
assert_true(dns_nametree_covered(bitstree, name, 9));
|
||||
assert_true(dns_nametree_covered(bitstree, name, 53));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 288));
|
||||
|
||||
/* add a small bit value, test again */
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 3), ISC_R_SUCCESS);
|
||||
assert_true(dns_nametree_covered(bitstree, name, 3));
|
||||
|
||||
/* add a large bit value, test again */
|
||||
assert_int_equal(dns_nametree_add(bitstree, name, 615), ISC_R_SUCCESS);
|
||||
assert_true(dns_nametree_covered(bitstree, name, 615));
|
||||
|
||||
/* check existing bit values for subdomain */
|
||||
dns_test_namefromstring("sub.example.com.", &fn);
|
||||
assert_false(dns_nametree_covered(bitstree, name, 0));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 1));
|
||||
assert_true(dns_nametree_covered(bitstree, name, 2));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 3));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 9));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 53));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 288));
|
||||
|
||||
/* check nonexistent subdomain is all false */
|
||||
dns_test_namefromstring("other.example.com", &fn);
|
||||
assert_false(dns_nametree_covered(bitstree, name, 0));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 1));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 2));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 3));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 9));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 53));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 288));
|
||||
|
||||
/* check nonexistent domain is all false */
|
||||
dns_test_namefromstring("anyname.", &fn);
|
||||
assert_false(dns_nametree_covered(bitstree, name, 0));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 1));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 2));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 3));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 9));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 53));
|
||||
assert_false(dns_nametree_covered(bitstree, name, 288));
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(delete) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
|
@ -120,11 +251,11 @@ ISC_RUN_TEST_IMPL(delete) {
|
|||
|
||||
/* name doesn't match */
|
||||
dns_test_namefromstring("example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_NOTFOUND);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_NOTFOUND);
|
||||
|
||||
/* subdomain match is the same as no match */
|
||||
dns_test_namefromstring("sub.example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_NOTFOUND);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_NOTFOUND);
|
||||
|
||||
/*
|
||||
* delete requires exact match: this should return SUCCESS on
|
||||
|
|
@ -132,12 +263,12 @@ ISC_RUN_TEST_IMPL(delete) {
|
|||
* ancestor does exist.
|
||||
*/
|
||||
dns_test_namefromstring("negative.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_NOTFOUND);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_NOTFOUND);
|
||||
|
||||
dns_test_namefromstring("negative.example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_delete(nametree, name), ISC_R_NOTFOUND);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_NOTFOUND);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
|
@ -154,49 +285,26 @@ ISC_RUN_TEST_IMPL(find) {
|
|||
* that has a null key, too.
|
||||
*/
|
||||
dns_test_namefromstring("example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_NOTFOUND);
|
||||
dns_test_namefromstring("sub.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_NOTFOUND);
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
assert_int_equal(dns_nametree_find(booltree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(covered) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
const char *yesnames[] = { "example.com.", "sub.example.com.", NULL };
|
||||
const char *nonames[] = { "whatever.com.", "negative.example.com.",
|
||||
"example.org.", "negative.example.org.",
|
||||
NULL };
|
||||
create_tables();
|
||||
|
||||
for (const char **n = yesnames; *n != NULL; n++) {
|
||||
dns_test_namefromstring(*n, &fn);
|
||||
assert_true(dns_nametree_covered(nametree, name));
|
||||
}
|
||||
for (const char **n = nonames; *n != NULL; n++) {
|
||||
dns_test_namefromstring(*n, &fn);
|
||||
assert_false(dns_nametree_covered(nametree, name));
|
||||
}
|
||||
|
||||
/* If nametree is NULL, dns_nametree_covered() returns false. */
|
||||
dns_test_namefromstring("anyname.example.", &fn);
|
||||
assert_false(dns_nametree_covered(NULL, name));
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_TEST_LIST_START
|
||||
ISC_TEST_ENTRY(add)
|
||||
ISC_TEST_ENTRY(covered)
|
||||
ISC_TEST_ENTRY(find)
|
||||
ISC_TEST_ENTRY(add_bool)
|
||||
ISC_TEST_ENTRY(add_bits)
|
||||
ISC_TEST_ENTRY(covered_bool)
|
||||
ISC_TEST_ENTRY(covered_bits)
|
||||
ISC_TEST_ENTRY(delete)
|
||||
ISC_TEST_ENTRY(find)
|
||||
ISC_TEST_LIST_END
|
||||
|
||||
ISC_TEST_MAIN
|
||||
|
|
|
|||
Loading…
Reference in a new issue