From: JINMEI Tatuya Date: Wed, 16 Sep 2020 20:19:03 +0000 (-0700) Subject: ns_query refactoring for hook-based recursion X-Git-Tag: v9.17.8~29^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c8dae041daaf3d4a9c40f52185839abe5bead0b;p=thirdparty%2Fbind9.git ns_query refactoring for hook-based recursion several small changes to query processing to make it easier to use hook-based recursion (and other asynchronous functionlity) later. - recursion quota check is now a separate function, check_recursionquota(), which is called by ns_query_recurse(). - pass isc_result to query_nxdomain() instead of bool. the value of 'empty_wild' will be determined in the function based on the passed result. this is similar to query_nodata(), and makes the signatures of the two functions more consistent. - pass the current 'result' value into plugin hooks. --- diff --git a/lib/ns/query.c b/lib/ns/query.c index e329b55e4cf..11e0ddc6b62 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -185,7 +185,7 @@ client_trace(ns_client_t *client, int level, const char *message) { * These have the same semantics as: * * foo_attach(b, a); - * foo_detach(&a); + * foo_detach(&b); * * without the locking and magic testing. * @@ -249,7 +249,7 @@ get_hooktab(query_ctx_t *qctx) { */ #define CALL_HOOK(_id, _qctx) \ do { \ - isc_result_t _res; \ + isc_result_t _res = result; \ ns_hooktable_t *_tab = get_hooktab(_qctx); \ ns_hook_t *_hook; \ _hook = ISC_LIST_HEAD((*_tab)[_id]); \ @@ -436,7 +436,7 @@ static void query_addnxrrsetnsec(query_ctx_t *qctx); static isc_result_t -query_nxdomain(query_ctx_t *qctx, bool empty_wild); +query_nxdomain(query_ctx_t *qctx, isc_result_t res); static isc_result_t query_redirect(query_ctx_t *qctx); @@ -5203,7 +5203,7 @@ query_trace(query_ctx_t *qctx) { */ static isc_result_t query_setup(ns_client_t *client, dns_rdatatype_t qtype) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; query_ctx_t qctx; qctx_init(client, NULL, qtype, &qctx); @@ -5306,7 +5306,7 @@ root_key_sentinel_detect(query_ctx_t *qctx) { */ isc_result_t ns__query_start(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "ns__query_start"); qctx->want_restart = false; qctx->authoritative = false; @@ -5518,7 +5518,7 @@ cleanup: static isc_result_t query_lookup(query_ctx_t *qctx) { isc_buffer_t b; - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_clientinfomethods_t cm; dns_clientinfo_t ci; dns_name_t *rpzqname = NULL; @@ -5873,31 +5873,12 @@ last_init(void) { } #endif /* ifdef ISC_MUTEX_ATOMICS */ -isc_result_t -ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, - dns_name_t *qdomain, dns_rdataset_t *nameservers, - bool resuming) { - isc_result_t result; - dns_rdataset_t *rdataset, *sigrdataset; - isc_sockaddr_t *peeraddr = NULL; - - CTRACE(ISC_LOG_DEBUG(3), "ns_query_recurse"); - - /* - * Check recursion parameters from the previous query to see if they - * match. If not, update recursion parameters and proceed. - */ - if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, - ISC_LOG_INFO, "recursion loop detected"); - return (ISC_R_FAILURE); - } - - recparam_update(&client->query.recparam, qtype, qname, qdomain); - - if (!resuming) { - inc_stats(client, ns_statscounter_recursion); - } +/*% + * Check recursion quota before making the current client "recursing". + */ +static isc_result_t +check_recursionquota(ns_client_t *client) { + isc_result_t result = ISC_R_SUCCESS; /* * We are about to recurse, which means that this client will @@ -5984,6 +5965,40 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, ns_statscounter_recursclients); } + return (result); +} + +isc_result_t +ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, + dns_name_t *qdomain, dns_rdataset_t *nameservers, + bool resuming) { + isc_result_t result; + dns_rdataset_t *rdataset, *sigrdataset; + isc_sockaddr_t *peeraddr = NULL; + + CTRACE(ISC_LOG_DEBUG(3), "ns_query_recurse"); + + /* + * Check recursion parameters from the previous query to see if they + * match. If not, update recursion parameters and proceed. + */ + if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY, + ISC_LOG_INFO, "recursion loop detected"); + return (ISC_R_FAILURE); + } + + recparam_update(&client->query.recparam, qtype, qname, qdomain); + + if (!resuming) { + inc_stats(client, ns_statscounter_recursion); + } + + result = check_recursionquota(client); + if (result != ISC_R_SUCCESS) { + return (result); + } + /* * Invoke the resolver. */ @@ -6042,7 +6057,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, */ static isc_result_t query_resume(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_name_t *tname; isc_buffer_t b; #ifdef WANT_QUERYTRACE @@ -6947,15 +6962,12 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) { return (query_delegation(qctx)); case DNS_R_EMPTYNAME: - return (query_nodata(qctx, DNS_R_EMPTYNAME)); case DNS_R_NXRRSET: - return (query_nodata(qctx, DNS_R_NXRRSET)); + return (query_nodata(qctx, result)); case DNS_R_EMPTYWILD: - return (query_nxdomain(qctx, true)); - case DNS_R_NXDOMAIN: - return (query_nxdomain(qctx, false)); + return (query_nxdomain(qctx, result)); case DNS_R_COVERINGNSEC: return (query_coveringnsec(qctx)); @@ -7090,7 +7102,7 @@ static isc_result_t query_respond_any(query_ctx_t *qctx) { bool found = false, hidden = false; dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_rdatatype_t onetype = 0; /* type to use for minimal-any */ isc_buffer_t b; @@ -7365,7 +7377,7 @@ query_getexpire(query_ctx_t *qctx) { static isc_result_t query_addanswer(query_ctx_t *qctx) { dns_rdataset_t **sigrdatasetp = NULL; - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "query_addanswer"); @@ -7427,7 +7439,7 @@ cleanup: */ static isc_result_t query_respond(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "query_respond"); @@ -7884,7 +7896,7 @@ cleanup: */ static isc_result_t query_notfound(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "query_notfound"); @@ -7970,7 +7982,7 @@ cleanup: */ static isc_result_t query_prepare_delegation_response(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_rdataset_t **sigrdatasetp = NULL; bool detach = false; @@ -8026,7 +8038,7 @@ cleanup: */ static isc_result_t query_zone_delegation(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CALL_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx); @@ -8124,7 +8136,7 @@ cleanup: */ static isc_result_t query_delegation(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "query_delegation"); @@ -8198,7 +8210,7 @@ cleanup: */ static isc_result_t query_delegation_recurse(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_name_t *qname = qctx->client->query.qname; CCTRACE(ISC_LOG_DEBUG(3), "query_delegation_recurse"); @@ -8721,10 +8733,11 @@ query_addnxrrsetnsec(query_ctx_t *qctx) { * Handle NXDOMAIN and empty wildcard responses. */ static isc_result_t -query_nxdomain(query_ctx_t *qctx, bool empty_wild) { +query_nxdomain(query_ctx_t *qctx, isc_result_t res) { dns_section_t section; uint32_t ttl; - isc_result_t result; + isc_result_t result = res; + bool empty_wild = (res == DNS_R_EMPTYWILD); CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain"); @@ -9656,7 +9669,7 @@ cleanup: */ static isc_result_t query_cname(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; dns_name_t *tname; dns_rdataset_t *trdataset; dns_rdataset_t **sigrdatasetp = NULL; @@ -9769,7 +9782,7 @@ query_dname(query_ctx_t *qctx) { dns_namereln_t namereln; isc_buffer_t b; int order; - isc_result_t result; + isc_result_t result = ISC_R_UNSET; unsigned int nlabels; CCTRACE(ISC_LOG_DEBUG(3), "query_dname"); @@ -9998,7 +10011,7 @@ query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) { */ static isc_result_t query_prepresponse(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; CCTRACE(ISC_LOG_DEBUG(3), "query_prepresponse"); @@ -10926,7 +10939,7 @@ query_glueanswer(query_ctx_t *qctx) { isc_result_t ns_query_done(query_ctx_t *qctx) { - isc_result_t result; + isc_result_t result = ISC_R_UNSET; const dns_namelist_t *secs = qctx->client->message->sections; CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done");