From 83561799536ff7792d25e78b41e56f8be48d28e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 14 Nov 2024 11:18:00 +0100 Subject: [PATCH 1/3] Rename the qpzone and qpcache methods that implement DB api All the database implementations share the same names for the methods implementing the database. That has some advantages like knowing what to expect, but it turns out that any time such method shows up in any kind of tracing - be it perf record, backtrace or anything else that uses symbol names, it is very hard to distinguish whether the find() belongs to qpcache, qpzone, builtin or sdlz implementation. Make at least the names for qpzone and qpcache unique. --- lib/dns/qpcache.c | 82 +++++++++++++++++++----------------- lib/dns/qpzone.c | 105 ++++++++++++++++++++++++---------------------- 2 files changed, 99 insertions(+), 88 deletions(-) diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index aadfaf2bb8..5781e6b96f 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -1530,10 +1530,11 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name, } static isc_result_t -find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { qpcnode_t *node = NULL; isc_result_t result; qpc_search_t search; @@ -1975,10 +1976,11 @@ tree_exit: } static isc_result_t -findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_name_t *dcname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpcache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options, + isc_stdtime_t now, dns_dbnode_t **nodep, + dns_name_t *foundname, dns_name_t *dcname, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { qpcnode_t *node = NULL; isc_rwlock_t *lock = NULL; isc_result_t result; @@ -2150,10 +2152,10 @@ tree_exit: } static isc_result_t -findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + dns_rdatatype_t type, dns_rdatatype_t covers, + isc_stdtime_t now, dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *qpnode = (qpcnode_t *)node; dns_slabheader_t *header = NULL, *header_next = NULL; @@ -2552,7 +2554,7 @@ free_qpdb(qpcache_t *qpdb, bool log) { } static void -qpdb_destroy(dns_db_t *arg) { +qpcache_destroy(dns_db_t *arg) { qpcache_t *qpdb = (qpcache_t *)arg; bool want_free = false; unsigned int i; @@ -2680,8 +2682,8 @@ new_qpcnode(qpcache_t *qpdb, const dns_name_t *name) { } static isc_result_t -findnode(dns_db_t *db, const dns_name_t *name, bool create, - dns_dbnode_t **nodep DNS__DB_FLARG) { +qpcache_findnode(dns_db_t *db, const dns_name_t *name, bool create, + dns_dbnode_t **nodep DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *node = NULL; isc_result_t result; @@ -2716,8 +2718,8 @@ unlock: } static void -attachnode(dns_db_t *db, dns_dbnode_t *source, - dns_dbnode_t **targetp DNS__DB_FLARG) { +qpcache_attachnode(dns_db_t *db, dns_dbnode_t *source, + dns_dbnode_t **targetp DNS__DB_FLARG) { REQUIRE(VALID_QPDB((qpcache_t *)db)); REQUIRE(targetp != NULL && *targetp == NULL); @@ -2731,7 +2733,7 @@ attachnode(dns_db_t *db, dns_dbnode_t *source, } static void -detachnode(dns_db_t *db, dns_dbnode_t **targetp DNS__DB_FLARG) { +qpcache_detachnode(dns_db_t *db, dns_dbnode_t **targetp DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *node = NULL; bool want_free = false; @@ -2786,8 +2788,8 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp DNS__DB_FLARG) { } static isc_result_t -createiterator(dns_db_t *db, unsigned int options ISC_ATTR_UNUSED, - dns_dbiterator_t **iteratorp) { +qpcache_createiterator(dns_db_t *db, unsigned int options ISC_ATTR_UNUSED, + dns_dbiterator_t **iteratorp) { qpcache_t *qpdb = (qpcache_t *)db; qpc_dbit_t *qpdbiter = NULL; @@ -2809,9 +2811,9 @@ createiterator(dns_db_t *db, unsigned int options ISC_ATTR_UNUSED, } static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - unsigned int options, isc_stdtime_t now, - dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) { +qpcache_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + unsigned int options, isc_stdtime_t now, + dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *qpnode = (qpcnode_t *)node; qpc_rditer_t *iterator = NULL; @@ -3386,9 +3388,10 @@ expire_ttl_headers(qpcache_t *qpdb, unsigned int locknum, isc_stdtime_t now, bool cache_is_overmem DNS__DB_FLARG); static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset DNS__DB_FLARG) { +qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + isc_stdtime_t now, dns_rdataset_t *rdataset, + unsigned int options, + dns_rdataset_t *addedrdataset DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *qpnode = (qpcnode_t *)node; isc_region_t region; @@ -3569,8 +3572,9 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, } static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers DNS__DB_FLARG) { +qpcache_deleterdataset(dns_db_t *db, dns_dbnode_t *node, + dns_dbversion_t *version, dns_rdatatype_t type, + dns_rdatatype_t covers DNS__DB_FLARG) { qpcache_t *qpdb = (qpcache_t *)db; qpcnode_t *qpnode = (qpcnode_t *)node; isc_result_t result; @@ -4378,17 +4382,17 @@ setmaxtypepername(dns_db_t *db, uint32_t value) { } static dns_dbmethods_t qpdb_cachemethods = { - .destroy = qpdb_destroy, - .findnode = findnode, - .find = find, - .findzonecut = findzonecut, - .attachnode = attachnode, - .detachnode = detachnode, - .createiterator = createiterator, - .findrdataset = findrdataset, - .allrdatasets = allrdatasets, - .addrdataset = addrdataset, - .deleterdataset = deleterdataset, + .destroy = qpcache_destroy, + .findnode = qpcache_findnode, + .find = qpcache_find, + .findzonecut = qpcache_findzonecut, + .attachnode = qpcache_attachnode, + .detachnode = qpcache_detachnode, + .createiterator = qpcache_createiterator, + .findrdataset = qpcache_findrdataset, + .allrdatasets = qpcache_allrdatasets, + .addrdataset = qpcache_addrdataset, + .deleterdataset = qpcache_deleterdataset, .nodecount = nodecount, .getoriginnode = getoriginnode, .getrrsetstats = getrrsetstats, diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 875c39920f..7847d260f1 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -1545,10 +1545,11 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, } static isc_result_t -findrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, - dns_rdatatype_t type, dns_rdatatype_t covers, - isc_stdtime_t now ISC_ATTR_UNUSED, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpzone_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode, + dns_dbversion_t *dbversion, dns_rdatatype_t type, + dns_rdatatype_t covers, isc_stdtime_t now ISC_ATTR_UNUSED, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = (qpznode_t *)dbnode; dns_slabheader_t *header = NULL, *header_next = NULL; @@ -2546,8 +2547,8 @@ findnodeintree(qpzonedb_t *qpdb, const dns_name_t *name, bool create, } static isc_result_t -findnode(dns_db_t *db, const dns_name_t *name, bool create, - dns_dbnode_t **nodep DNS__DB_FLARG) { +qpzone_findnode(dns_db_t *db, const dns_name_t *name, bool create, + dns_dbnode_t **nodep DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; REQUIRE(VALID_QPZONE(qpdb)); @@ -2557,8 +2558,8 @@ findnode(dns_db_t *db, const dns_name_t *name, bool create, } static isc_result_t -findnsec3node(dns_db_t *db, const dns_name_t *name, bool create, - dns_dbnode_t **nodep DNS__DB_FLARG) { +qpzone_findnsec3node(dns_db_t *db, const dns_name_t *name, bool create, + dns_dbnode_t **nodep DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; REQUIRE(VALID_QPZONE(qpdb)); @@ -2606,9 +2607,9 @@ matchparams(dns_slabheader_t *header, qpz_search_t *search) { } static isc_result_t -setup_delegation(qpz_search_t *search, dns_dbnode_t **nodep, - dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpzone_setup_delegation(qpz_search_t *search, dns_dbnode_t **nodep, + dns_name_t *foundname, dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { dns_name_t *zcname = NULL; dns_typepair_t type; qpznode_t *node = NULL; @@ -3202,7 +3203,7 @@ again: } static isc_result_t -check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) { +qpzone_check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) { qpz_search_t *search = arg; dns_slabheader_t *header = NULL, *header_next = NULL; dns_slabheader_t *dname_header = NULL, *sigdname_header = NULL; @@ -3329,11 +3330,11 @@ check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) { } static isc_result_t -find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, - isc_stdtime_t now ISC_ATTR_UNUSED, dns_dbnode_t **nodep, - dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset DNS__DB_FLARG) { +qpzone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, + isc_stdtime_t now ISC_ATTR_UNUSED, dns_dbnode_t **nodep, + dns_name_t *foundname, dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset DNS__DB_FLARG) { isc_result_t result; qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = NULL; @@ -3403,7 +3404,7 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, isc_result_t tresult; dns_qpchain_node(&search.chain, i, NULL, (void **)&n, NULL); - tresult = check_zonecut(n, &search DNS__DB_FLARG_PASS); + tresult = qpzone_check_zonecut(n, &search DNS__DB_FLARG_PASS); if (tresult != DNS_R_CONTINUE) { result = tresult; search.chain.len = i - 1; @@ -3415,7 +3416,7 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, if (result == DNS_R_PARTIALMATCH) { partial_match: if (search.zonecut != NULL) { - result = setup_delegation( + result = qpzone_setup_delegation( &search, nodep, foundname, rdataset, sigrdataset DNS__DB_FLARG_PASS); goto tree_exit; @@ -3705,7 +3706,7 @@ found: * Return the delegation. */ NODE_UNLOCK(lock, &nlocktype); - result = setup_delegation( + result = qpzone_setup_delegation( &search, nodep, foundname, rdataset, sigrdataset DNS__DB_FLARG_PASS); goto tree_exit; @@ -3853,9 +3854,10 @@ tree_exit: } static isc_result_t -allrdatasets(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, - unsigned int options, isc_stdtime_t now ISC_ATTR_UNUSED, - dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) { +qpzone_allrdatasets(dns_db_t *db, dns_dbnode_t *dbnode, + dns_dbversion_t *dbversion, unsigned int options, + isc_stdtime_t now ISC_ATTR_UNUSED, + dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = (qpznode_t *)dbnode; qpz_version_t *version = (qpz_version_t *)dbversion; @@ -4589,8 +4591,8 @@ dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { } static isc_result_t -createiterator(dns_db_t *db, unsigned int options, - dns_dbiterator_t **iteratorp) { +qpzone_createiterator(dns_db_t *db, unsigned int options, + dns_dbiterator_t **iteratorp) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpdb_dbiterator_t *iter = NULL; @@ -4628,9 +4630,11 @@ createiterator(dns_db_t *db, unsigned int options, } static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, - isc_stdtime_t now ISC_ATTR_UNUSED, dns_rdataset_t *rdataset, - unsigned int options, dns_rdataset_t *addedrdataset DNS__DB_FLARG) { +qpzone_addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, + dns_dbversion_t *dbversion, + isc_stdtime_t now ISC_ATTR_UNUSED, dns_rdataset_t *rdataset, + unsigned int options, + dns_rdataset_t *addedrdataset DNS__DB_FLARG) { isc_result_t result; qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = (qpznode_t *)dbnode; @@ -4757,9 +4761,10 @@ addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, } static isc_result_t -subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, - dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *newrdataset DNS__DB_FLARG) { +qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode, + dns_dbversion_t *dbversion, dns_rdataset_t *rdataset, + unsigned int options, + dns_rdataset_t *newrdataset DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = (qpznode_t *)dbnode; qpz_version_t *version = (qpz_version_t *)dbversion; @@ -4948,8 +4953,9 @@ unlock: } static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, - dns_rdatatype_t type, dns_rdatatype_t covers DNS__DB_FLARG) { +qpzone_deleterdataset(dns_db_t *db, dns_dbnode_t *dbnode, + dns_dbversion_t *dbversion, dns_rdatatype_t type, + dns_rdatatype_t covers DNS__DB_FLARG) { qpzonedb_t *qpdb = (qpzonedb_t *)db; qpznode_t *node = (qpznode_t *)dbnode; qpz_version_t *version = (qpz_version_t *)dbversion; @@ -5061,9 +5067,10 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype, dns_rdataset_init(&rdataset_aaaa); dns_rdataset_init(&sigrdataset_aaaa); - result = find(ctx->db, name, ctx->version, dns_rdatatype_a, - DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_a, name_a, - &rdataset_a, &sigrdataset_a DNS__DB_FLARG_PASS); + result = qpzone_find(ctx->db, name, ctx->version, dns_rdatatype_a, + DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_a, + name_a, &rdataset_a, + &sigrdataset_a DNS__DB_FLARG_PASS); if (result == DNS_R_GLUE) { glue = new_glue(ctx->db->mctx, name_a); @@ -5079,10 +5086,10 @@ glue_nsdname_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype, } } - result = find(ctx->db, name, ctx->version, dns_rdatatype_aaaa, - DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_aaaa, - name_aaaa, &rdataset_aaaa, - &sigrdataset_aaaa DNS__DB_FLARG_PASS); + result = qpzone_find(ctx->db, name, ctx->version, dns_rdatatype_aaaa, + DNS_DBFIND_GLUEOK, 0, (dns_dbnode_t **)&node_aaaa, + name_aaaa, &rdataset_aaaa, + &sigrdataset_aaaa DNS__DB_FLARG_PASS); if (result == DNS_R_GLUE) { if (glue == NULL) { glue = new_glue(ctx->db->mctx, name_aaaa); @@ -5348,22 +5355,22 @@ static dns_dbmethods_t qpdb_zonemethods = { .newversion = newversion, .attachversion = attachversion, .closeversion = closeversion, - .findnode = findnode, - .find = find, + .findnode = qpzone_findnode, + .find = qpzone_find, .attachnode = attachnode, .detachnode = detachnode, - .createiterator = createiterator, - .findrdataset = findrdataset, - .allrdatasets = allrdatasets, - .addrdataset = addrdataset, - .subtractrdataset = subtractrdataset, - .deleterdataset = deleterdataset, + .createiterator = qpzone_createiterator, + .findrdataset = qpzone_findrdataset, + .allrdatasets = qpzone_allrdatasets, + .addrdataset = qpzone_addrdataset, + .subtractrdataset = qpzone_subtractrdataset, + .deleterdataset = qpzone_deleterdataset, .issecure = issecure, .nodecount = nodecount, .setloop = setloop, .getoriginnode = getoriginnode, .getnsec3parameters = getnsec3parameters, - .findnsec3node = findnsec3node, + .findnsec3node = qpzone_findnsec3node, .setsigningtime = setsigningtime, .getsigningtime = getsigningtime, .getsize = getsize, From e51d4d3b88af00d6667f2055087ebfc47fb3107c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 7 Jan 2025 15:22:40 +0100 Subject: [PATCH 2/3] Isolate using the -T noaa flag only for part of the resolver test Instead of running the whole resolver/ns4 server with -T noaa flag, use it only for the part where it is actually needed. The -T noaa could interfere with other parts of the test because the answers don't have the authoritative-answer bit set, and we could have false positives (or false negatives) in the test because the authoritative server doesn't follow the DNS protocol for all the tests in the resolver system test. --- bin/tests/system/resolver/ns4/named.noaa | 12 ------------ bin/tests/system/resolver/tests.sh | 8 ++++++++ 2 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 bin/tests/system/resolver/ns4/named.noaa diff --git a/bin/tests/system/resolver/ns4/named.noaa b/bin/tests/system/resolver/ns4/named.noaa deleted file mode 100644 index be78cc2c94..0000000000 --- a/bin/tests/system/resolver/ns4/named.noaa +++ /dev/null @@ -1,12 +0,0 @@ -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. - -Add -T noaa. diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index ab94c17c10..026fd60c9f 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -221,6 +221,10 @@ done if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +stop_server ns4 +touch ns4/named.noaa +start_server --noclean --restart --port ${PORT} ns4 || ret=1 + n=$((n + 1)) echo_i "RT21594 regression test check setup ($n)" ret=0 @@ -257,6 +261,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +stop_server ns4 +rm ns4/named.noaa +start_server --noclean --restart --port ${PORT} ns4 || ret=1 + n=$((n + 1)) echo_i "check that replacement of additional data by a negative cache no data entry clears the additional RRSIGs ($n)" ret=0 From a1982cf1bb95c818aa7b58988b5611dec80f2408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 14 Nov 2024 10:37:29 +0100 Subject: [PATCH 3/3] Limit the additional processing for large RDATA sets Limit the number of records appended to ADDITIONAL section to the names that have less than 14 records in the RDATA. This limits the number of the lookups into the database(s) during single client query. Also don't append any additional data to ANY queries. The answer to ANY is already big enough. --- lib/dns/include/dns/rdataset.h | 10 +++++++++- lib/dns/qpzone.c | 2 +- lib/dns/rdataset.c | 7 ++++++- lib/dns/resolver.c | 17 ++++++++++------- lib/ns/query.c | 5 +++-- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index ae835b961d..89518b0ebf 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -53,6 +53,8 @@ #include #include +#define DNS_RDATASET_MAXADDITIONAL 13 + /* Fixed RRSet helper macros */ #define DNS_RDATASET_LENGTH 2; @@ -503,7 +505,8 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset, isc_result_t dns_rdataset_additionaldata(dns_rdataset_t *rdataset, const dns_name_t *owner_name, - dns_additionaldatafunc_t add, void *arg); + dns_additionaldatafunc_t add, void *arg, + size_t limit); /*%< * For each rdata in rdataset, call 'add' for each name and type in the * rdata which is subject to additional section processing. @@ -522,10 +525,15 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset, *\li If a call to dns_rdata_additionaldata() is not successful, the * result returned will be the result of dns_rdataset_additionaldata(). * + *\li If the 'limit' is non-zero and the number of the rdatasets is larger + * than the 'limit', no additional data will be generated. + * * Returns: * *\li #ISC_R_SUCCESS * + *\li #DNS_R_TOOMANYRECORDS in case rdataset count is larger than 'limit' + * *\li Any error that dns_rdata_additionaldata() can return. */ diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 7847d260f1..fadc3bc9c2 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -5261,7 +5261,7 @@ create_gluelist(qpzonedb_t *qpdb, qpz_version_t *version, qpznode_t *node, */ (void)dns_rdataset_additionaldata(rdataset, dns_rootname, - glue_nsdname_cb, &ctx); + glue_nsdname_cb, &ctx, 0); CMM_STORE_SHARED(gluelist->glue, ctx.glue); diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index b09ff3cf29..dc6fc4d867 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -479,7 +479,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name, isc_result_t dns_rdataset_additionaldata(dns_rdataset_t *rdataset, const dns_name_t *owner_name, - dns_additionaldatafunc_t add, void *arg) { + dns_additionaldatafunc_t add, void *arg, + size_t limit) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; @@ -491,6 +492,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset, REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0); + if (limit != 0 && dns_rdataset_count(rdataset) > limit) { + return DNS_R_TOOMANYRECORDS; + } + result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) { return result; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 70900c4cc0..6497582bea 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -8576,9 +8576,6 @@ rctx_answer_any(respctx_t *rctx) { rdataset->attributes |= DNS_RDATASETATTR_ANSWER; rdataset->attributes |= DNS_RDATASETATTR_CACHE; rdataset->trust = rctx->trust; - - (void)dns_rdataset_additionaldata(rdataset, rctx->aname, - check_related, rctx); } return ISC_R_SUCCESS; @@ -8626,7 +8623,8 @@ rctx_answer_match(respctx_t *rctx) { rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE; rctx->ardataset->trust = rctx->trust; (void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname, - check_related, rctx); + check_related, rctx, + DNS_RDATASET_MAXADDITIONAL); for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list); sigrdataset != NULL; @@ -8833,7 +8831,8 @@ rctx_authority_positive(respctx_t *rctx) { */ (void)dns_rdataset_additionaldata( rdataset, name, check_related, - rctx); + rctx, + DNS_RDATASET_MAXADDITIONAL); done = true; } } @@ -9340,8 +9339,11 @@ rctx_referral(respctx_t *rctx) { */ INSIST(rctx->ns_rdataset != NULL); FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING); + /* + * We want to append **all** the GLUE records here. + */ (void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name, - check_related, rctx); + check_related, rctx, 0); #if CHECK_FOR_GLUE_IN_ANSWER /* * Look in the answer section for "glue" that is incorrectly @@ -9456,7 +9458,8 @@ again: if (CHASE(rdataset)) { rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; (void)dns_rdataset_additionaldata( - rdataset, name, check_related, rctx); + rdataset, name, check_related, rctx, + DNS_RDATASET_MAXADDITIONAL); rescan = true; } } diff --git a/lib/ns/query.c b/lib/ns/query.c index 8464e782d9..9757a25622 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -2143,7 +2143,8 @@ addname: if (trdataset != NULL && dns_rdatatype_followadditional(type)) { if (client->additionaldepth++ < client->view->max_restarts) { eresult = dns_rdataset_additionaldata( - trdataset, fname, query_additional_cb, qctx); + trdataset, fname, query_additional_cb, qctx, + DNS_RDATASET_MAXADDITIONAL); } client->additionaldepth--; } @@ -2240,7 +2241,7 @@ regular: * We don't care if dns_rdataset_additionaldata() fails. */ (void)dns_rdataset_additionaldata(rdataset, name, query_additional_cb, - qctx); + qctx, DNS_RDATASET_MAXADDITIONAL); CTRACE(ISC_LOG_DEBUG(3), "query_additional: done"); }