]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
ns_query refactoring for hook-based recursion
authorJINMEI Tatuya <jtatuya@infoblox.com>
Wed, 16 Sep 2020 20:19:03 +0000 (13:19 -0700)
committerEvan Hunt <each@isc.org>
Tue, 24 Nov 2020 23:11:39 +0000 (15:11 -0800)
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.

lib/ns/query.c

index e329b55e4cf69fb8c36adf20c11588539903d013..11e0ddc6b62c0374bcb73a344e4a8147fd9a291e 100644 (file)
@@ -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");