]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add a 'foundname' argument to dns_nametree_covered()
authorEvan Hunt <each@isc.org>
Thu, 17 Aug 2023 06:51:56 +0000 (23:51 -0700)
committerOndřej Surý <ondrej@isc.org>
Mon, 4 Sep 2023 08:19:48 +0000 (10:19 +0200)
when checking whether a name is covered, the ancestor name that
was found can be set into a name object passed in.

lib/dns/include/dns/nametree.h
lib/dns/nametree.c
lib/dns/resolver.c
tests/dns/nametree_test.c

index bae8dcefb3e26369bc1a1d39d44d6849a6272990..3c5ac518935fda331d91dbf33a84c3194a7014a2 100644 (file)
@@ -147,7 +147,7 @@ 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,
-                    uint32_t bit);
+                    dns_name_t *found, uint32_t bit);
 /*%<
  * Indicates whether a 'name' (with optional 'bit' value) is covered by
  * 'nametree'.
@@ -162,6 +162,9 @@ dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name,
  * If a name is not found, or if 'nametree' is NULL, the default return
  * value is false.
  *
+ * If 'found' is not NULL, the name or ancestor name that was found in
+ * the tree is copied into it.
+ *
  * Requires:
  *
  *\li  'nametree' is a valid nametree, or is NULL.
index bbca177aea283988be86057355b5c3f60915550e..af7cfbddf7ab677341381b8e56e2c4a03202039a 100644 (file)
@@ -19,6 +19,7 @@
 #include <isc/refcount.h>
 #include <isc/result.h>
 #include <isc/string.h>
+#include <isc/urcu.h>
 #include <isc/util.h>
 
 #include <dns/fixedname.h>
@@ -281,7 +282,7 @@ 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,
-                    uint32_t bit) {
+                    dns_name_t *found, uint32_t bit) {
        isc_result_t result;
        dns_qpread_t qpr;
        dns_ntnode_t *node = NULL;
@@ -296,6 +297,10 @@ 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, (void **)&node, NULL);
        if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+               if (found != NULL) {
+                       dns_name_copy(node->name, found);
+               }
+
                switch (nametree->type) {
                case DNS_NAMETREE_BOOL:
                        ret = node->set;
index 7984b3e4b5ec7e3fd0256311456b398a0d306cc1..02a578c261df80ec75e0728a6fd11b899c39b50d 100644 (file)
@@ -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, 0)) {
+       if (dns_nametree_covered(view->answeracl_exclude, name, NULL, 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, 0)) {
+       if (dns_nametree_covered(view->answernames_exclude, qname, NULL, 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, 0)) {
+       if (dns_nametree_covered(view->denyanswernames, tname, NULL, 0)) {
                char qnamebuf[DNS_NAME_FORMATSIZE];
                char tnamebuf[DNS_NAME_FORMATSIZE];
                char classbuf[64];
@@ -10778,7 +10778,7 @@ dns_resolver_algorithm_supported(dns_resolver_t *resolver,
                return (false);
        }
 
-       if (dns_nametree_covered(resolver->algorithms, name, alg)) {
+       if (dns_nametree_covered(resolver->algorithms, name, NULL, alg)) {
                return (false);
        }
 
@@ -10791,7 +10791,7 @@ dns_resolver_ds_digest_supported(dns_resolver_t *resolver,
                                 unsigned int digest_type) {
        REQUIRE(VALID_RESOLVER(resolver));
 
-       if (dns_nametree_covered(resolver->digests, name, digest_type)) {
+       if (dns_nametree_covered(resolver->digests, name, NULL, digest_type)) {
                return (false);
        }
 
@@ -10828,7 +10828,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, 0));
+       return (dns_nametree_covered(resolver->mustbesecure, name, NULL, 0));
 }
 
 void
index 23df32f7e67b9accc0e9feab5a3320e1a51cabf7..39ac4467c12071d591c830d7d01b589a2692a03c 100644 (file)
@@ -48,9 +48,9 @@ dns_nametree_t *counttree = NULL;
  * the test code concise.
  */
 
-/* Common setup: create a booltree to test with a few keys */
-static void
-create_tables(void) {
+/* Common setup: create trees of each type with a few keys */
+static int
+setup(void **state ISC_ATTR_UNUSED) {
        dns_fixedname_t fn;
        dns_name_t *name = dns_fixedname_name(&fn);
 
@@ -78,20 +78,17 @@ create_tables(void) {
        /* Add a bitfield node under a parent */
        dns_test_namefromstring("sub.example.com.", &fn);
        assert_int_equal(dns_nametree_add(bitstree, name, 2), ISC_R_SUCCESS);
+
+       return (0);
 }
 
-static void
-destroy_tables(void) {
-       if (booltree != NULL) {
-               dns_nametree_detach(&booltree);
-       }
-       if (bitstree != NULL) {
-               dns_nametree_detach(&bitstree);
-       }
-       if (counttree != NULL) {
-               dns_nametree_detach(&counttree);
-       }
+static int
+teardown(void **state ISC_ATTR_UNUSED) {
+       dns_nametree_detach(&booltree);
+       dns_nametree_detach(&bitstree);
+       dns_nametree_detach(&counttree);
        rcu_barrier();
+       return (0);
 }
 
 ISC_RUN_TEST_IMPL(add_bool) {
@@ -99,8 +96,6 @@ ISC_RUN_TEST_IMPL(add_bool) {
        dns_fixedname_t fn;
        dns_name_t *name = dns_fixedname_name(&fn);
 
-       create_tables();
-
        /*
         * Getting the node for example.com should succeed.
         */
@@ -125,8 +120,6 @@ ISC_RUN_TEST_IMPL(add_bool) {
        assert_int_equal(dns_nametree_find(booltree, name, &node),
                         ISC_R_SUCCESS);
        dns_ntnode_detach(&node);
-
-       destroy_tables();
 }
 
 ISC_RUN_TEST_IMPL(add_bits) {
@@ -134,8 +127,6 @@ ISC_RUN_TEST_IMPL(add_bits) {
        dns_fixedname_t fn;
        dns_name_t *name = dns_fixedname_name(&fn);
 
-       create_tables();
-
        /*
         * Getting the node for example.com should succeed.
         */
@@ -162,16 +153,12 @@ ISC_RUN_TEST_IMPL(add_bits) {
        assert_int_equal(dns_nametree_find(booltree, name, &node),
                         ISC_R_SUCCESS);
        dns_ntnode_detach(&node);
-
-       destroy_tables();
 }
 
 ISC_RUN_TEST_IMPL(add_count) {
        dns_fixedname_t fn;
        dns_name_t *name = dns_fixedname_name(&fn);
 
-       create_tables();
-
        /* add a counter node five times */
        dns_test_namefromstring("example.com.", &fn);
        assert_int_equal(dns_nametree_add(counttree, name, 0), ISC_R_SUCCESS);
@@ -181,115 +168,116 @@ ISC_RUN_TEST_IMPL(add_count) {
        assert_int_equal(dns_nametree_add(counttree, name, 0), ISC_R_SUCCESS);
 
        /* delete it five times, checking coverage each time */
-       assert_true(dns_nametree_covered(counttree, name, 0));
+       assert_true(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_SUCCESS);
 
-       assert_true(dns_nametree_covered(counttree, name, 0));
+       assert_true(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_SUCCESS);
 
-       assert_true(dns_nametree_covered(counttree, name, 0));
+       assert_true(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_SUCCESS);
 
-       assert_true(dns_nametree_covered(counttree, name, 0));
+       assert_true(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_SUCCESS);
 
-       assert_true(dns_nametree_covered(counttree, name, 0));
+       assert_true(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_SUCCESS);
 
-       assert_false(dns_nametree_covered(counttree, name, 0));
+       assert_false(dns_nametree_covered(counttree, name, NULL, 0));
        assert_int_equal(dns_nametree_delete(counttree, name), ISC_R_NOTFOUND);
-
-       destroy_tables();
 }
 
 ISC_RUN_TEST_IMPL(covered_bool) {
-       dns_fixedname_t fn;
-       dns_name_t *name = dns_fixedname_name(&fn);
+       dns_fixedname_t fn, fn2;
+       dns_name_t *name = dns_fixedname_initname(&fn);
+       dns_name_t *found = dns_fixedname_initname(&fn2);
+       char buf[DNS_NAME_FORMATSIZE];
        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));
+               assert_true(dns_nametree_covered(booltree, name, NULL, 0));
        }
        for (const char **n = nonames; *n != NULL; n++) {
                dns_test_namefromstring(*n, &fn);
-               assert_false(dns_nametree_covered(booltree, name, 0));
+               assert_false(dns_nametree_covered(booltree, name, NULL, 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));
+       assert_false(dns_nametree_covered(NULL, name, NULL, 0));
 
-       destroy_tables();
+       /* Check that the found name is as expected */
+       dns_test_namefromstring("other.example.com.", &fn);
+       assert_true(dns_nametree_covered(booltree, name, found, 0));
+       dns_name_format(found, buf, sizeof(buf));
+       assert_string_equal(buf, "example.com");
 }
 
 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));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 0));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 1));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 2));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 3));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 9));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 53));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 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));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 3));
 
        /* add a large bit value, test again */
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 615));
        assert_int_equal(dns_nametree_add(bitstree, name, 615), ISC_R_SUCCESS);
-       assert_true(dns_nametree_covered(bitstree, name, 615));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 615));
+       assert_int_equal(dns_nametree_add(bitstree, name, 999), ISC_R_SUCCESS);
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 999));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 998));
 
        /* 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));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 0));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 1));
+       assert_true(dns_nametree_covered(bitstree, name, NULL, 2));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 3));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 9));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 53));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 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));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 0));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 1));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 2));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 3));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 9));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 53));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 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();
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 0));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 1));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 2));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 3));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 9));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 53));
+       assert_false(dns_nametree_covered(bitstree, name, NULL, 288));
 }
 
 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(booltree, name), ISC_R_NOTFOUND);
@@ -310,8 +298,6 @@ ISC_RUN_TEST_IMPL(delete) {
        dns_test_namefromstring("negative.example.org.", &fn);
        assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_SUCCESS);
        assert_int_equal(dns_nametree_delete(booltree, name), ISC_R_NOTFOUND);
-
-       destroy_tables();
 }
 
 ISC_RUN_TEST_IMPL(find) {
@@ -319,8 +305,6 @@ ISC_RUN_TEST_IMPL(find) {
        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.
@@ -335,18 +319,16 @@ ISC_RUN_TEST_IMPL(find) {
        assert_int_equal(dns_nametree_find(booltree, name, &node),
                         ISC_R_SUCCESS);
        dns_ntnode_detach(&node);
-
-       destroy_tables();
 }
 
 ISC_TEST_LIST_START
-ISC_TEST_ENTRY(add_bool)
-ISC_TEST_ENTRY(add_bits)
-ISC_TEST_ENTRY(add_count)
-ISC_TEST_ENTRY(covered_bool)
-ISC_TEST_ENTRY(covered_bits)
-ISC_TEST_ENTRY(delete)
-ISC_TEST_ENTRY(find)
+ISC_TEST_ENTRY_CUSTOM(add_bool, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(add_bits, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(add_count, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(covered_bool, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(covered_bits, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(delete, setup, teardown)
+ISC_TEST_ENTRY_CUSTOM(find, setup, teardown)
 ISC_TEST_LIST_END
 
 ISC_TEST_MAIN