mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
add dns_nametree structure for policy match lookups
this is a QP trie of boolean values to indicate whether a name is included in or excluded from some policy. this can be used for synth-from-dnssec, deny-answer-aliases, etc.
This commit is contained in:
@@ -91,6 +91,7 @@ libdns_la_HEADERS = \
|
||||
include/dns/masterdump.h \
|
||||
include/dns/message.h \
|
||||
include/dns/name.h \
|
||||
include/dns/nametree.h \
|
||||
include/dns/ncache.h \
|
||||
include/dns/nsec.h \
|
||||
include/dns/nsec3.h \
|
||||
@@ -196,6 +197,7 @@ libdns_la_SOURCES = \
|
||||
masterdump.c \
|
||||
message.c \
|
||||
name.c \
|
||||
nametree.c \
|
||||
ncache.c \
|
||||
nsec.c \
|
||||
nsec3.c \
|
||||
|
154
lib/dns/include/dns/nametree.h
Normal file
154
lib/dns/include/dns/nametree.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* A nametree module is a tree of DNS names containing boolean values
|
||||
* or bitfields, allowing a quick lookup to see whether a name is included
|
||||
* in or excluded from some policy.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/stdtime.h>
|
||||
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
|
||||
/* Define to 1 for detailed reference tracing */
|
||||
#undef DNS_NAMETREE_TRACE
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
void
|
||||
dns_nametree_create(isc_mem_t *mctx, 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.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*\li ntp != NULL && *ntp == NULL
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name, bool value);
|
||||
/*%<
|
||||
* Add a node to 'nametree'.
|
||||
*
|
||||
* 'value' is a single boolean value, true or false. If the name already
|
||||
* exists within the tree, then return ISC_R_EXISTS.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'nametree' points to a valid nametree.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li ISC_R_SUCCESS
|
||||
*\li ISC_R_EXISTS
|
||||
*
|
||||
*\li Any other result indicates failure.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_delete(dns_nametree_t *nametree, const dns_name_t *name);
|
||||
/*%<
|
||||
* Delete 'name' from 'nametree'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'nametree' points to a valid nametree.
|
||||
*\li 'name' is not NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li ISC_R_SUCCESS
|
||||
*
|
||||
*\li Any other result indicates failure.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_find(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
dns_ntnode_t **ntp);
|
||||
/*%<
|
||||
* Retrieve the node that exactly matches 'name' from 'nametree'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'nametree' is a valid nametree.
|
||||
*
|
||||
*\li 'name' is a valid name.
|
||||
*
|
||||
*\li ntp != NULL && *ntp == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li ISC_R_SUCCESS
|
||||
*\li ISC_R_NOTFOUND
|
||||
*
|
||||
*\li Any other result indicates an error.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name);
|
||||
/*%<
|
||||
* Indicates whether a 'name' 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.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'nametree' is a valid nametree, or is NULL.
|
||||
*/
|
||||
|
||||
#if DNS_NAMETREE_TRACE
|
||||
#define dns_nametree_ref(ptr) \
|
||||
dns_nametree__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_nametree_unref(ptr) \
|
||||
dns_nametree__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_nametree_attach(ptr, ptrp) \
|
||||
dns_nametree__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_nametree_detach(ptrp) \
|
||||
dns_nametree__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_ntnode_ref(ptr) dns_ntnode__ref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_ntnode_unref(ptr) \
|
||||
dns_ntnode__unref(ptr, __func__, __FILE__, __LINE__)
|
||||
#define dns_ntnode_attach(ptr, ptrp) \
|
||||
dns_ntnode__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
||||
#define dns_ntnode_detach(ptrp) \
|
||||
dns_ntnode__detach(ptrp, __func__, __FILE__, __LINE__)
|
||||
ISC_REFCOUNT_TRACE_DECL(dns_nametree);
|
||||
ISC_REFCOUNT_TRACE_DECL(dns_ntnode);
|
||||
#else
|
||||
ISC_REFCOUNT_DECL(dns_nametree);
|
||||
ISC_REFCOUNT_DECL(dns_ntnode);
|
||||
#endif
|
||||
ISC_LANG_ENDDECLS
|
@@ -116,8 +116,10 @@ typedef struct dns_message dns_message_t;
|
||||
typedef uint16_t dns_messageid_t;
|
||||
typedef isc_region_t dns_label_t;
|
||||
typedef struct dns_name dns_name_t;
|
||||
typedef struct dns_nametree dns_nametree_t;
|
||||
typedef ISC_LIST(dns_name_t) dns_namelist_t;
|
||||
typedef struct dns_ntatable dns_ntatable_t;
|
||||
typedef struct dns_ntnode dns_ntnode_t;
|
||||
typedef uint16_t dns_opcode_t;
|
||||
typedef struct dns_order dns_order_t;
|
||||
typedef struct dns_peer dns_peer_t;
|
||||
|
252
lib/dns/nametree.c
Normal file
252
lib/dns/nametree.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/nametree.h>
|
||||
#include <dns/qp.h>
|
||||
|
||||
#define NAMETREE_MAGIC ISC_MAGIC('N', 'T', 'r', 'e')
|
||||
#define VALID_NAMETREE(kt) ISC_MAGIC_VALID(kt, NAMETREE_MAGIC)
|
||||
|
||||
struct dns_nametree {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t references;
|
||||
dns_qpmulti_t *table;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct dns_ntnode {
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t references;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name;
|
||||
union {
|
||||
bool value;
|
||||
unsigned char *bits;
|
||||
};
|
||||
};
|
||||
|
||||
/* QP trie methods */
|
||||
static void
|
||||
qp_attach(void *uctx, void *pval, uint32_t ival);
|
||||
static void
|
||||
qp_detach(void *uctx, void *pval, uint32_t ival);
|
||||
static size_t
|
||||
qp_makekey(dns_qpkey_t key, void *uctx, void *pval, uint32_t ival);
|
||||
static void
|
||||
qp_triename(void *uctx, char *buf, size_t size);
|
||||
|
||||
static dns_qpmethods_t qpmethods = {
|
||||
qp_attach,
|
||||
qp_detach,
|
||||
qp_makekey,
|
||||
qp_triename,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_ntnode(dns_ntnode_t *node) {
|
||||
isc_refcount_destroy(&node->references);
|
||||
isc_mem_putanddetach(&node->mctx, node, sizeof(dns_ntnode_t));
|
||||
}
|
||||
|
||||
#if DNS_NAMETREE_TRACE
|
||||
ISC_REFCOUNT_TRACE_IMPL(dns_ntnode, destroy_ntnode);
|
||||
#else
|
||||
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_t *nametree = NULL;
|
||||
|
||||
REQUIRE(ntp != NULL && *ntp == NULL);
|
||||
|
||||
nametree = isc_mem_get(mctx, sizeof(*nametree));
|
||||
*nametree = (dns_nametree_t){
|
||||
.magic = NAMETREE_MAGIC,
|
||||
};
|
||||
isc_mem_attach(mctx, &nametree->mctx);
|
||||
isc_refcount_init(&nametree->references, 1);
|
||||
|
||||
if (name != NULL) {
|
||||
strlcpy(nametree->name, name, sizeof(nametree->name));
|
||||
}
|
||||
|
||||
dns_qpmulti_create(mctx, &qpmethods, nametree, &nametree->table);
|
||||
*ntp = nametree;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_nametree(dns_nametree_t *nametree) {
|
||||
nametree->magic = 0;
|
||||
|
||||
dns_qpmulti_destroy(&nametree->table);
|
||||
isc_refcount_destroy(&nametree->references);
|
||||
|
||||
isc_mem_putanddetach(&nametree->mctx, nametree, sizeof(*nametree));
|
||||
}
|
||||
|
||||
#if DNS_NAMETREE_TRACE
|
||||
ISC_REFCOUNT_TRACE_IMPL(dns_nametree, destroy_nametree);
|
||||
#else
|
||||
ISC_REFCOUNT_IMPL(dns_nametree, destroy_nametree);
|
||||
#endif
|
||||
|
||||
static dns_ntnode_t *
|
||||
newnode(isc_mem_t *mctx, const dns_name_t *name) {
|
||||
dns_ntnode_t *node = isc_mem_get(mctx, sizeof(*node));
|
||||
*node = (dns_ntnode_t){ 0 };
|
||||
isc_mem_attach(mctx, &node->mctx);
|
||||
isc_refcount_init(&node->references, 1);
|
||||
|
||||
node->name = dns_fixedname_initname(&node->fn);
|
||||
dns_name_copy(name, node->name);
|
||||
|
||||
return (node);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name, bool value) {
|
||||
isc_result_t result;
|
||||
dns_qp_t *qp = 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);
|
||||
|
||||
/*
|
||||
* We detach the node here, so any dns_qp_deletename() will
|
||||
* destroy the node directly.
|
||||
*/
|
||||
dns_ntnode_detach(&node);
|
||||
}
|
||||
|
||||
dns_qp_compact(qp, DNS_QPGC_MAYBE);
|
||||
dns_qpmulti_commit(nametree->table, &qp);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_delete(dns_nametree_t *nametree, const dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_qp_t *qp = NULL;
|
||||
void *pval = NULL;
|
||||
|
||||
REQUIRE(VALID_NAMETREE(nametree));
|
||||
REQUIRE(name != NULL);
|
||||
|
||||
dns_qpmulti_write(nametree->table, &qp);
|
||||
result = dns_qp_deletename(qp, name, &pval, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_ntnode_t *n = pval;
|
||||
dns_ntnode_detach(&n);
|
||||
}
|
||||
dns_qp_compact(qp, DNS_QPGC_MAYBE);
|
||||
dns_qpmulti_commit(nametree->table, &qp);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_nametree_find(dns_nametree_t *nametree, const dns_name_t *name,
|
||||
dns_ntnode_t **ntnodep) {
|
||||
isc_result_t result;
|
||||
dns_qpread_t qpr;
|
||||
void *pval = NULL;
|
||||
|
||||
REQUIRE(VALID_NAMETREE(nametree));
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(ntnodep != NULL && *ntnodep == NULL);
|
||||
|
||||
dns_qpmulti_query(nametree->table, &qpr);
|
||||
result = dns_qp_getname(&qpr, name, &pval, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_ntnode_t *knode = pval;
|
||||
dns_ntnode_attach(knode, ntnodep);
|
||||
}
|
||||
dns_qpread_destroy(nametree->table, &qpr);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_qpread_t qpr;
|
||||
dns_ntnode_t *ntnode = NULL;
|
||||
void *pval = NULL;
|
||||
bool value = false;
|
||||
|
||||
REQUIRE(nametree == NULL || VALID_NAMETREE(nametree));
|
||||
|
||||
if (nametree == NULL) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
dns_qpmulti_query(nametree->table, &qpr);
|
||||
result = dns_qp_findname_ancestor(&qpr, name, 0, &pval, NULL);
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
|
||||
ntnode = pval;
|
||||
value = ntnode->value;
|
||||
}
|
||||
|
||||
dns_qpread_destroy(nametree->table, &qpr);
|
||||
return (value);
|
||||
}
|
||||
|
||||
static void
|
||||
qp_attach(void *uctx ISC_ATTR_UNUSED, void *pval,
|
||||
uint32_t ival ISC_ATTR_UNUSED) {
|
||||
dns_ntnode_t *ntnode = pval;
|
||||
dns_ntnode_ref(ntnode);
|
||||
}
|
||||
|
||||
static void
|
||||
qp_detach(void *uctx ISC_ATTR_UNUSED, void *pval,
|
||||
uint32_t ival ISC_ATTR_UNUSED) {
|
||||
dns_ntnode_t *ntnode = pval;
|
||||
dns_ntnode_detach(&ntnode);
|
||||
}
|
||||
|
||||
static size_t
|
||||
qp_makekey(dns_qpkey_t key, void *uctx ISC_ATTR_UNUSED, void *pval,
|
||||
uint32_t ival ISC_ATTR_UNUSED) {
|
||||
dns_ntnode_t *ntnode = pval;
|
||||
return (dns_qpkey_fromname(key, ntnode->name));
|
||||
}
|
||||
|
||||
static void
|
||||
qp_triename(void *uctx, char *buf, size_t size) {
|
||||
dns_nametree_t *nametree = uctx;
|
||||
snprintf(buf, size, "%s nametree", nametree->name);
|
||||
}
|
@@ -29,6 +29,7 @@ check_PROGRAMS = \
|
||||
dst_test \
|
||||
keytable_test \
|
||||
name_test \
|
||||
nametree_test \
|
||||
nsec3_test \
|
||||
nsec3param_test \
|
||||
private_test \
|
||||
|
202
tests/dns/nametree_test.c
Normal file
202
tests/dns/nametree_test.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sched.h> /* IWYU pragma: keep */
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UNIT_TESTING
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <isc/base64.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/nametree.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
|
||||
#include <tests/dns.h>
|
||||
|
||||
dns_nametree_t *nametree = NULL;
|
||||
|
||||
/*
|
||||
* Test utilities. In general, these assume input parameters are valid
|
||||
* (checking with assert_int_equal, thus aborting if not) and unlikely run time
|
||||
* errors (such as memory allocation failure) won't happen. This helps keep
|
||||
* the test code concise.
|
||||
*/
|
||||
|
||||
/* Common setup: create a nametree 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);
|
||||
|
||||
/* Add a positive node */
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, name, true), ISC_R_SUCCESS);
|
||||
|
||||
/* Add a negative node below it */
|
||||
dns_test_namefromstring("negative.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_add(nametree, 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);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_tables(void) {
|
||||
if (nametree != NULL) {
|
||||
dns_nametree_detach(&nametree);
|
||||
}
|
||||
rcu_barrier();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(add) {
|
||||
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(nametree, 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),
|
||||
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(nametree, name, true), ISC_R_SUCCESS);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
ISC_R_SUCCESS);
|
||||
dns_ntnode_detach(&node);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(delete) {
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
||||
create_tables();
|
||||
|
||||
/* name doesn't match */
|
||||
dns_test_namefromstring("example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_delete(nametree, 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);
|
||||
|
||||
/*
|
||||
* delete requires exact match: this should return SUCCESS on
|
||||
* the first try, then NOTFOUND on the second even though an
|
||||
* 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);
|
||||
|
||||
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);
|
||||
|
||||
destroy_tables();
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(find) {
|
||||
dns_ntnode_t *node = NULL;
|
||||
dns_fixedname_t fn;
|
||||
dns_name_t *name = dns_fixedname_name(&fn);
|
||||
|
||||
create_tables();
|
||||
|
||||
/*
|
||||
* dns_nametree_find() requires exact name match. It matches node
|
||||
* that has a null key, too.
|
||||
*/
|
||||
dns_test_namefromstring("example.org.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
ISC_R_NOTFOUND);
|
||||
dns_test_namefromstring("sub.example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, name, &node),
|
||||
ISC_R_NOTFOUND);
|
||||
dns_test_namefromstring("example.com.", &fn);
|
||||
assert_int_equal(dns_nametree_find(nametree, 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(delete)
|
||||
ISC_TEST_LIST_END
|
||||
|
||||
ISC_TEST_MAIN
|
Reference in New Issue
Block a user