]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
enable modules to store data in qctx
authorEvan Hunt <each@isc.org>
Mon, 13 Aug 2018 08:18:09 +0000 (01:18 -0700)
committerEvan Hunt <each@isc.org>
Thu, 6 Dec 2018 18:29:11 +0000 (10:29 -0800)
- added a 'hookdata' array to qctx to store pointers to up to
  16 blobs of data which are allocated by modules as needed.
  each module is assigned an ID number as it's loaded, and this
  is the index into the hook data array. this is to be used for
  holding persistent state between calls to a hook module for a
  specific query.
- instead of using qctx->filter_aaaa, we now use qctx->hookdata.
  (this was the last piece of filter-aaaa specific code outside the
  module.)
- added hook points for qctx initialization and destruction. we get
  a filter-aaaa data pointer from the mempool when initializing and
  store it in the qctx->hookdata table; return to to the mempool
  when destroying the qctx.
- link the view to the qctx so that detaching the client doesn't cause
  hooks to fail
- added a qctx_destroy() function which must be called after qctx_init;
  this calls the QCTX_DESTROY hook and detaches the view
- general cleanup and comments

12 files changed:
bin/hooks/filter-aaaa.c
bin/named/server.c
doc/misc/options
lib/dns/include/dns/types.h
lib/ns/client.c
lib/ns/hooks.c
lib/ns/include/ns/client.h
lib/ns/include/ns/hooks.h
lib/ns/include/ns/query.h
lib/ns/query.c
lib/ns/tests/nstest.c
win32utils/Configure

index 6bd1cdc9d8c372325c38c8b2c98a5e024efcf6fb..fa964fab6997eb47c6b15972ccade6e5e22d3bc6 100644 (file)
@@ -23,8 +23,8 @@
 #include <isccfg/grammar.h>
 #include <isccfg/namedconf.h>
 
+#include <dns/acl.h>
 #include <dns/result.h>
-#include <dns/view.h>
 
 #include <ns/client.h>
 #include <ns/hooks.h>
                        goto cleanup; \
        } while (0)
 
-ns_hook_destroy_t hook_destroy;
-ns_hook_register_t hook_register;
-ns_hook_version_t hook_version;
+/*
+ * Set up in the register function.
+ */
+static int module_id;
+
+/*
+ * Hook data pool.
+ */
+static isc_mempool_t *datapool = NULL;
 
 /*
  * Per-client flags set by this module
@@ -48,56 +54,90 @@ ns_hook_version_t hook_version;
 #define FILTER_AAAA_RECURSING  0x0001  /* Recursing for A */
 #define FILTER_AAAA_FILTERED   0x0002  /* AAAA was removed from answer */
 
-
-/*% Want DNSSEC? */
-#define WANTDNSSEC(c)          (((c)->attributes & \
-                                 NS_CLIENTATTR_WANTDNSSEC) != 0)
-/*% Recursion OK? */
-#define RECURSIONOK(c)         (((c)->query.attributes & \
+/*
+ * Client attribute tests.
+ */
+#define WANTDNSSEC(c)  (((c)->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0)
+#define RECURSIONOK(c) (((c)->query.attributes & \
                                  NS_QUERYATTR_RECURSIONOK) != 0)
 
+/*
+ * Hook registration structures: pointers to these structures will
+ * be added to a hook table when this module is registered.
+ */
+static bool
+filter_qctx_initialize(void *hookdata, void *cbdata, isc_result_t *resp);
+static ns_hook_t filter_init = {
+       .callback = filter_qctx_initialize,
+};
+
 static bool
 filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp);
+static ns_hook_t filter_respbegin = {
+       .callback = filter_respond_begin,
+};
 
 static bool
 filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp);
+static ns_hook_t filter_respanyfound = {
+       .callback = filter_respond_any_found,
+};
 
 static bool
 filter_prep_response_begin(void *hookdata, void *cbdata, isc_result_t *resp);
+static ns_hook_t filter_prepresp = {
+       .callback = filter_prep_response_begin,
+};
 
 static bool
 filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp);
-
-ns_hook_t filter_respbegin = {
-       .callback = filter_respond_begin,
-};
-ns_hook_t filter_respanyfound = {
-       .callback = filter_respond_any_found,
-};
-ns_hook_t filter_prepresp = {
-       .callback = filter_prep_response_begin,
-};
-ns_hook_t filter_donesend = {
+static ns_hook_t filter_donesend = {
        .callback = filter_query_done_send,
 };
 
+static bool
+filter_qctx_destroy(void *hookdata, void *cbdata, isc_result_t *resp);
+ns_hook_t filter_destroy = {
+       .callback = filter_qctx_destroy,
+};
+
+/**
+ ** Support for parsing of parameters and configuration of the module.
+ **/
+
 /*
- * Configuration support.
+ * Possible values for the settings of filter-aaaa-on-v4 and
+ * filter-aaaa-on-v6: "no" is NONE, "yes" is FILTER, "break-dnssec"
+ * is BREAK_DNSSEC.
  */
+typedef enum {
+       NONE = 0,
+       FILTER = 1,
+       BREAK_DNSSEC = 2
+} filter_aaaa_t;
 
-static dns_aaaa_t v4_aaaa;
-static dns_aaaa_t v6_aaaa;
+/*
+ * Values configured when the module is loaded.
+ */
+static filter_aaaa_t v4_aaaa = NONE;
+static filter_aaaa_t v6_aaaa = NONE;
 static dns_acl_t *aaaa_acl = NULL;
 
+/*
+ * Support for parsing of parameters.
+ */
 static const char *filter_aaaa_enums[] = { "break-dnssec", NULL };
+
 static isc_result_t
 parse_filter_aaaa(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
        return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
 }
+
 static void
 doc_filter_aaaa(cfg_printer_t *pctx, const cfg_type_t *type) {
        cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
 }
+
 static cfg_type_t cfg_type_filter_aaaa = {
        "filter_aaaa", parse_filter_aaaa, cfg_print_ustring,
        doc_filter_aaaa, &cfg_rep_string, filter_aaaa_enums,
@@ -121,7 +161,7 @@ static cfg_type_t cfg_type_parameters = {
 
 static isc_result_t
 parse_filter_aaaa_on(const cfg_obj_t *param_obj, const char *param_name,
-                    dns_aaaa_t *dstp)
+                    filter_aaaa_t *dstp)
 {
        const cfg_obj_t *obj = NULL;
        isc_result_t result;
@@ -133,12 +173,12 @@ parse_filter_aaaa_on(const cfg_obj_t *param_obj, const char *param_name,
 
        if (cfg_obj_isboolean(obj)) {
                if (cfg_obj_asboolean(obj)) {
-                       *dstp = dns_aaaa_filter;
+                       *dstp = FILTER;
                } else {
-                       *dstp = dns_aaaa_ok;
+                       *dstp = NONE;
                }
        } else if (strcasecmp(cfg_obj_asstring(obj), "break-dnssec") == 0) {
-               *dstp = dns_aaaa_break_dnssec;
+               *dstp = BREAK_DNSSEC;
        } else {
                result = ISC_R_UNEXPECTED;
        }
@@ -187,16 +227,33 @@ parse_parameters(const char *parameters, const void *cfg,
        return (result);
 }
 
+/**
+ ** Mandatory hook API functions.
+ **/
+
+/*
+ * Prototypes for the hook module API functions defined below.
+ */
+ns_hook_destroy_t hook_destroy;
+ns_hook_register_t hook_register;
+ns_hook_version_t hook_version;
+
 /*
- * Mandatory hook API functions.
+ * Called by ns_hookmodule_load() to register hook functions into
+ * a hook table.
  */
 isc_result_t
-hook_register(const char *parameters, const char *file, unsigned long line,
-             const void *cfg, void *actx, ns_hookctx_t *hctx,
-             ns_hooktable_t *hooktable, void **instp)
+hook_register(const unsigned int modid, const char *parameters,
+             const char *file, unsigned long line,
+             const void *cfg, void *actx,
+             ns_hookctx_t *hctx, ns_hooktable_t *hooktable, void **instp)
 {
+       isc_result_t result;
+
        UNUSED(instp);
 
+       module_id = modid;
+
        if (parameters != NULL) {
                isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL,
                              NS_LOGMODULE_HOOKS, ISC_LOG_INFO,
@@ -204,7 +261,7 @@ hook_register(const char *parameters, const char *file, unsigned long line,
                              "module from %s:%lu",
                              file, line);
 
-               parse_parameters(parameters, cfg, actx, hctx);
+               CHECK(parse_parameters(parameters, cfg, actx, hctx));
        } else {
                isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL,
                              NS_LOGMODULE_HOOKS, ISC_LOG_INFO,
@@ -213,28 +270,50 @@ hook_register(const char *parameters, const char *file, unsigned long line,
                              file, line);
        }
 
-       ns_hook_add(hooktable, NS_QUERY_RESPOND_BEGIN,
-                   &filter_respbegin);
+       ns_hook_add(hooktable, NS_QUERY_QCTX_INITIALIZED, &filter_init);
+       ns_hook_add(hooktable, NS_QUERY_RESPOND_BEGIN, &filter_respbegin);
        ns_hook_add(hooktable, NS_QUERY_RESPOND_ANY_FOUND,
                    &filter_respanyfound);
-       ns_hook_add(hooktable, NS_QUERY_PREP_RESPONSE_BEGIN,
-                   &filter_prepresp);
-       ns_hook_add(hooktable, NS_QUERY_DONE_SEND,
-                   &filter_donesend);
+       ns_hook_add(hooktable, NS_QUERY_PREP_RESPONSE_BEGIN, &filter_prepresp);
+       ns_hook_add(hooktable, NS_QUERY_DONE_SEND, &filter_donesend);
+       ns_hook_add(hooktable, NS_QUERY_QCTX_DESTROYED, &filter_destroy);
+
+       CHECK(isc_mempool_create(hctx->mctx, sizeof(filter_aaaa_t),
+                                &datapool));
 
        /*
-        * TODO:
-        * Set up a serial number that can be used for accessing
-        * data blobs in qctx, client, view;
-        * return an instance pointer for later destruction
+        * Fill the mempool with 1K filter_aaaa state objects at
+        * a time; ideally after a single allocation, the mempool will
+        * have enough to handle all the simultaneous queries the system
+        * requires and it won't be necessary to allocate more.
+        *
+        * We don't set any limit on the number of free state objects
+        * so that they'll always be returned to the pool and not
+        * freed until the pool is destroyed on shutdown.
         */
-       return (ISC_R_SUCCESS);
+       isc_mempool_setfillcount(datapool, 1024);
+       isc_mempool_setfreemax(datapool, UINT_MAX);
+
+ cleanup:
+       if (result != ISC_R_SUCCESS) {
+               if (datapool != NULL) {
+                       isc_mempool_destroy(&datapool);
+               }
+       }
+       return (result);
 }
 
+/*
+ * Called by ns_hookmodule_cleanup(); frees memory allocated by
+ * the module when it was registered.
+ */
 void
 hook_destroy(void **instp) {
        UNUSED(instp);
 
+       if (datapool != NULL) {
+               isc_mempool_destroy(&datapool);
+       }
        if (aaaa_acl != NULL) {
                dns_acl_detach(&aaaa_acl);
        }
@@ -242,6 +321,9 @@ hook_destroy(void **instp) {
        return;
 }
 
+/*
+ * Returns hook module API version for compatibility checks.
+ */
 int
 hook_version(unsigned int *flags) {
        UNUSED(flags);
@@ -249,6 +331,10 @@ hook_version(unsigned int *flags) {
        return (NS_HOOK_VERSION);
 }
 
+/**
+ ** "filter-aaaa" feature implementation begins here
+ **/
+
 /*
  * Check whether this is a V4 client.
  */
@@ -279,31 +365,55 @@ is_v6_client(ns_client_t *client) {
 }
 
 /*
- * The filter-aaaa-on-v4 option suppresses AAAAs for IPv4
- * clients if there is an A; filter-aaaa-on-v6 option does
- * the same for IPv6 clients.
+ * Shorthand to refer to the persistent data stored by this module in
+ * the query context structure.
+ */
+#define FILTER_MODE(qctx) ((filter_aaaa_t **) &qctx->hookdata[module_id])
+
+/*
+ * Initialize hook data in the query context, fetching from a memory
+ * pool.
+ */
+static bool
+filter_qctx_initialize(void *hookdata, void *cbdata, isc_result_t *resp) {
+       query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
+
+       UNUSED(cbdata);
+
+       *mode = isc_mempool_get(datapool);
+       **mode = NONE;
+
+       *resp = ISC_R_UNSET;
+       return (false);
+}
+
+/*
+ * Determine whether this client should have AAAA filtered nor not,
+ * based on the client address family and the settings of
+ * filter-aaaa-on-v4 and filter-aaaa-on-v6.
  */
 static bool
 filter_prep_response_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
        query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
        isc_result_t result;
 
        UNUSED(cbdata);
 
-       qctx->filter_aaaa = dns_aaaa_ok;
-       if (v4_aaaa != dns_aaaa_ok || v6_aaaa != dns_aaaa_ok) {
+       if (v4_aaaa != NONE || v6_aaaa != NONE) {
                result = ns_client_checkaclsilent(qctx->client, NULL,
                                                  aaaa_acl, true);
                if (result == ISC_R_SUCCESS &&
-                   v4_aaaa != dns_aaaa_ok &&
+                   v4_aaaa != NONE &&
                    is_v4_client(qctx->client))
                {
-                       qctx->filter_aaaa = v4_aaaa;
+                       **mode = v4_aaaa;
                } else if (result == ISC_R_SUCCESS &&
-                          v6_aaaa != dns_aaaa_ok &&
+                          v6_aaaa != NONE &&
                           is_v6_client(qctx->client))
                {
-                       qctx->filter_aaaa = v6_aaaa;
+                       **mode = v6_aaaa;
                }
        }
 
@@ -312,19 +422,22 @@ filter_prep_response_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
 }
 
 /*
- * Optionally hide AAAA rrsets if there is a matching A.
+ * Hide AAAA rrsets if there is a matching A. Trigger recursion if
+ * necessary to find out whether an A exists.
+ *
  * (This version is for processing answers to explicit AAAA
  * queries; ANY queries are handled in query_filter_aaaa_any().)
  */
 static bool
 filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
        query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
        isc_result_t result = ISC_R_UNSET;
 
        UNUSED(cbdata);
 
-       if (qctx->filter_aaaa != dns_aaaa_break_dnssec &&
-           (qctx->filter_aaaa != dns_aaaa_filter ||
+       if (**mode != BREAK_DNSSEC &&
+           (**mode != FILTER ||
             (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
              dns_rdataset_isassociated(qctx->sigrdataset))))
        {
@@ -368,7 +481,8 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
                                qctx->sigrdataset->attributes |=
                                        DNS_RDATASETATTR_RENDERED;
                        }
-                       qctx->client->hookflags |= FILTER_AAAA_FILTERED;
+                       qctx->client->hookflags[module_id] |=
+                               FILTER_AAAA_FILTERED;
                } else if (!qctx->authoritative &&
                           RECURSIONOK(qctx->client) &&
                           (result == DNS_R_DELEGATION ||
@@ -387,14 +501,15 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
                                                  qctx->client->query.qname,
                                                  NULL, NULL, qctx->resuming);
                        if (result == ISC_R_SUCCESS) {
-                               qctx->client->hookflags |=
+                               qctx->client->hookflags[module_id] |=
                                        FILTER_AAAA_RECURSING;
                                qctx->client->query.attributes |=
                                        NS_QUERYATTR_RECURSING;
                        }
                }
        } else if (qctx->qtype == dns_rdatatype_a &&
-                  ((qctx->client->hookflags & FILTER_AAAA_RECURSING) != 0))
+                  ((qctx->client->hookflags[module_id] &
+                    FILTER_AAAA_RECURSING) != 0))
        {
 
                dns_rdataset_t *mrdataset = NULL;
@@ -417,22 +532,26 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) {
                        sigrdataset->attributes |= DNS_RDATASETATTR_RENDERED;
                }
 
-               qctx->client->hookflags &= ~FILTER_AAAA_RECURSING;
+               qctx->client->hookflags[module_id] &= ~FILTER_AAAA_RECURSING;
 
                result = ns_query_done(qctx);
 
                *resp = result;
-               return (true);
 
+               return (true);
        }
 
        *resp = result;
        return (false);
 }
 
+/*
+ * When answering an ANY query, remove AAAA if A is present.
+ */
 static bool
 filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) {
        query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
        dns_name_t *name = NULL;
        dns_rdataset_t *aaaa = NULL, *aaaa_sig = NULL;
        dns_rdataset_t *a = NULL;
@@ -440,7 +559,7 @@ filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) {
 
        UNUSED(cbdata);
 
-       if (qctx->filter_aaaa == dns_aaaa_ok) {
+       if (**mode == NONE) {
                *resp = ISC_R_UNSET;
                return (false);
        }
@@ -472,7 +591,7 @@ filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) {
 
        if (have_a && aaaa != NULL &&
            (aaaa_sig == NULL || !WANTDNSSEC(qctx->client) ||
-            qctx->filter_aaaa == dns_aaaa_break_dnssec))
+            **mode == BREAK_DNSSEC))
        {
                aaaa->attributes |= DNS_RDATASETATTR_RENDERED;
                if (aaaa_sig != NULL) {
@@ -492,11 +611,12 @@ filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) {
 static bool
 filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp) {
        query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
        isc_result_t result;
 
        UNUSED(cbdata);
 
-       if (qctx->filter_aaaa == dns_aaaa_ok) {
+       if (**mode == NONE) {
                *resp = ISC_R_UNSET;
                return (false);
        }
@@ -530,7 +650,7 @@ filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp) {
                                     dns_rdatatype_aaaa, &aaaa_sig);
 
                if (aaaa_sig == NULL || !WANTDNSSEC(qctx->client) ||
-                    qctx->filter_aaaa == dns_aaaa_break_dnssec)
+                   **mode == BREAK_DNSSEC)
                {
                        aaaa->attributes |= DNS_RDATASETATTR_RENDERED;
                        if (aaaa_sig != NULL) {
@@ -540,7 +660,7 @@ filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp) {
                }
        }
 
-       if ((qctx->client->hookflags & FILTER_AAAA_FILTERED) != 0) {
+       if ((qctx->client->hookflags[module_id] & FILTER_AAAA_FILTERED) != 0) {
                result = dns_message_firstname(qctx->client->message,
                                               DNS_SECTION_AUTHORITY);
                while (result == ISC_R_SUCCESS) {
@@ -572,3 +692,22 @@ filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp) {
        *resp = ISC_R_UNSET;
        return (false);
 }
+
+/*
+ * Return hook data to the mempool.
+ */
+static bool
+filter_qctx_destroy(void *hookdata, void *cbdata, isc_result_t *resp) {
+       query_ctx_t *qctx = (query_ctx_t *) hookdata;
+       filter_aaaa_t **mode = FILTER_MODE(qctx);
+
+       UNUSED(cbdata);
+
+       if (*mode != NULL) {
+               isc_mempool_put(datapool, *mode);
+               *mode = NULL;
+       }
+
+       *resp = ISC_R_UNSET;
+       return (false);
+}
index a6a55bd11be722dcb9c5a88555b1c2cd45060c7e..0fa0f7da31c0b2c833e1d6054085e585745e13d5 100644 (file)
@@ -1537,7 +1537,8 @@ configure_dyndb(const cfg_obj_t *dyndb, isc_mem_t *mctx,
 }
 
 static isc_result_t
-configure_hook(ns_hooktable_t *hooktable, const cfg_obj_t *hook,
+configure_hook(ns_hooktable_t *hooktable, const unsigned int modid,
+              const cfg_obj_t *hook,
               const cfg_obj_t *config, ns_hookctx_t *hctx)
 {
        isc_result_t result = ISC_R_SUCCESS;
@@ -1559,7 +1560,7 @@ configure_hook(ns_hooktable_t *hooktable, const cfg_obj_t *hook,
 
        obj = cfg_tuple_get(hook, "parameters");
        if (obj != NULL && cfg_obj_isstring(obj)) {
-               result = ns_hookmodule_load(library,
+               result = ns_hookmodule_load(library, modid,
                                            cfg_obj_asstring(obj),
                                            cfg_obj_file(obj),
                                            cfg_obj_line(obj),
@@ -1567,7 +1568,7 @@ configure_hook(ns_hooktable_t *hooktable, const cfg_obj_t *hook,
                                            named_g_aclconfctx,
                                            hctx, hooktable);
        } else {
-               result = ns_hookmodule_load(library, NULL,
+               result = ns_hookmodule_load(library, modid, NULL,
                                            cfg_obj_file(hook),
                                            cfg_obj_line(hook),
                                            config,
@@ -3768,6 +3769,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
        unsigned int resolver_param;
        dns_ntatable_t *ntatable = NULL;
        const char *qminmode = NULL;
+       unsigned int module_counter = 0;
 
        REQUIRE(DNS_VIEW_VALID(view));
 
@@ -5332,7 +5334,10 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
                        CHECK(ns_hook_createctx(mctx, &hctx));
                }
 
-               CHECK(configure_hook(view->hooktable, hook, config, hctx));
+               CHECK(configure_hook(view->hooktable, module_counter,
+                                    hook, config, hctx));
+
+               module_counter++;
        }
 #endif
 
index 371ae556647e345c8e4f7d89dab3f45d06aca9a7..1b54aeda1920825cac5461e4c9d0de119489fd2d 100644 (file)
@@ -24,6 +24,9 @@ dlz <string> {
 dyndb <string> <quoted_string> {
     <unspecified-text> }; // may occur multiple times
 
+hook ( query ) <string> [ { <unspecified-text> }
+    ]; // may occur multiple times
+
 key <string> {
         algorithm <string>;
         secret <string>;
@@ -172,9 +175,9 @@ options {
         fetches-per-server <integer> [ ( drop | fail ) ];
         fetches-per-zone <integer> [ ( drop | fail ) ];
         files ( default | unlimited | <sizeval> );
-        filter-aaaa { <address_match_element>; ... };
-        filter-aaaa-on-v4 ( break-dnssec | <boolean> );
-        filter-aaaa-on-v6 ( break-dnssec | <boolean> );
+        filter-aaaa { <address_match_element>; ... }; // obsolete
+        filter-aaaa-on-v4 <boolean>; // obsolete
+        filter-aaaa-on-v6 <boolean>; // obsolete
         flush-zones-on-shutdown <boolean>;
         forward ( first | only );
         forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
@@ -533,13 +536,15 @@ view <string> [ <class> ] {
         fetch-quota-params <integer> <fixedpoint> <fixedpoint> <fixedpoint>;
         fetches-per-server <integer> [ ( drop | fail ) ];
         fetches-per-zone <integer> [ ( drop | fail ) ];
-        filter-aaaa { <address_match_element>; ... };
-        filter-aaaa-on-v4 ( break-dnssec | <boolean> );
-        filter-aaaa-on-v6 ( break-dnssec | <boolean> );
+        filter-aaaa { <address_match_element>; ... }; // obsolete
+        filter-aaaa-on-v4 <boolean>; // obsolete
+        filter-aaaa-on-v6 <boolean>; // obsolete
         forward ( first | only );
         forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
             | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
         glue-cache <boolean>;
+        hook ( query ) <string> [ {
+            <unspecified-text> } ]; // may occur multiple times
         inline-signing <boolean>;
         ixfr-from-differences ( primary | master | secondary | slave |
             <boolean> );
index c2e64287c12f131a237a5a5441fda0b6e9a26e59..17c605e69a513ecb61d6398b922b0b4d1c2e2508 100644 (file)
@@ -216,12 +216,6 @@ typedef enum {
        dns_masterformat_map = 3
 } dns_masterformat_t;
 
-typedef enum {
-       dns_aaaa_ok = 0,
-       dns_aaaa_filter = 1,
-       dns_aaaa_break_dnssec = 2
-} dns_aaaa_t;
-
 /*
  * These are generated by gen.c.
  */
index 525cad499db4f3852c673f30232c6e372f3ddcb5..7739905d04406909cecb9832553250503933257e 100644 (file)
@@ -3047,7 +3047,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
        ISC_QLINK_INIT(client, ilink);
        client->keytag = NULL;
        client->keytag_len = 0;
-       client->hookflags = 0;
+       memset(client->hookflags, 0, sizeof(client->hookflags));
 
        /*
         * We call the init routines for the various kinds of client here,
index 6835617b4ce52d4abeabfaecde8ebd4a37e9c3e2..7f0ab4d4a264a3716ec6728d40b9e392a2f34513 100644 (file)
@@ -328,7 +328,8 @@ unload_library(ns_hook_module_t **hmodp) {
 #endif /* HAVE_DLFCN_H */
 
 isc_result_t
-ns_hookmodule_load(const char *libname, const char *parameters,
+ns_hookmodule_load(const char *libname, const unsigned int modid,
+                  const char *parameters,
                   const char *file, unsigned long line,
                   const void *cfg, void *actx,
                   ns_hookctx_t *hctx, ns_hooktable_t *hooktable)
@@ -343,7 +344,7 @@ ns_hookmodule_load(const char *libname, const char *parameters,
                      "loading module '%s'", libname);
 
        CHECK(load_library(hctx->mctx, libname, &module));
-       CHECK(module->register_func(parameters, file, line,
+       CHECK(module->register_func(modid, parameters, file, line,
                                    cfg, actx, hctx, hooktable,
                                    &module->inst));
 
index 12845141fb917081e2e69fadb24cd95255bd389b..ea209d6b5f58f583b07f7d394fd091b6ea09dfee 100644 (file)
@@ -175,7 +175,7 @@ struct ns_client {
         * Allows a hook module to set flags
         * that persist across recursion.
         */
-       uint32_t                hookflags;
+       uint32_t                hookflags[NS_MAX_MODULES];
 };
 
 typedef ISC_QUEUE(ns_client_t) client_queue_t;
index f89201a48b991c308fb8b6a1c9e60e748dfd954c..95f9aca1838efe98d3ad539060ca2f3d961321b0 100644 (file)
  */
 
 typedef enum {
-       NS_QUERY_SETUP_QCTX_INITIALIZED,
+       NS_QUERY_QCTX_INITIALIZED,
+       NS_QUERY_QCTX_DESTROYED,
        NS_QUERY_START_BEGIN,
        NS_QUERY_LOOKUP_BEGIN,
        NS_QUERY_RESUME_BEGIN,
@@ -235,7 +236,8 @@ typedef struct ns_hookctx {
 #define NS_HOOK_AGE 0
 #endif
 
-typedef isc_result_t ns_hook_register_t(const char *parameters,
+typedef isc_result_t ns_hook_register_t(const unsigned int modid,
+                                       const char *parameters,
                                        const char *file,
                                        unsigned long line,
                                        const void *cfg,
@@ -312,7 +314,8 @@ void
 ns_hook_destroyctx(ns_hookctx_t **hctxp);
 
 isc_result_t
-ns_hookmodule_load(const char *libname, const char *parameters,
+ns_hookmodule_load(const char *libname, const unsigned int modid,
+                  const char *parameters,
                   const char *file, unsigned long line,
                   const void *cfg, void *actx,
                   ns_hookctx_t *hctx, ns_hooktable_t *hooktable);
index 853c7e5a90f1d8fe8074955984a596949b5e58dc..987dfe804dd8f2a8d8b53ae6281a39511562634d 100644 (file)
 
 #include <ns/types.h>
 
+/*
+ * Maximum number of query hook modules that can be configured;
+ * more than this will overflow qctx->hookdata.
+ */
+#define NS_MAX_MODULES 16
+
 /*% nameserver database version structure */
 typedef struct ns_dbversion {
        dns_db_t                        *db;
        dns_dbversion_t                 *version;
-       bool                    acl_checked;
-       bool                    queryok;
+       bool                            acl_checked;
+       bool                            queryok;
        ISC_LINK(struct ns_dbversion)   link;
 } ns_dbversion_t;
 
@@ -52,7 +58,7 @@ typedef struct ns_query_recparam {
 struct ns_query {
        unsigned int                    attributes;
        unsigned int                    restarts;
-       bool                    timerset;
+       bool                            timerset;
        dns_name_t *                    qname;
        dns_name_t *                    origqname;
        dns_rdatatype_t                 qtype;
@@ -61,8 +67,8 @@ struct ns_query {
        dns_db_t *                      gluedb;
        dns_db_t *                      authdb;
        dns_zone_t *                    authzone;
-       bool                    authdbset;
-       bool                    isreferral;
+       bool                            authdbset;
+       bool                            isreferral;
        isc_mutex_t                     fetchlock;
        dns_fetch_t *                   fetch;
        dns_fetch_t *                   prefetch;
@@ -72,7 +78,7 @@ struct ns_query {
        ISC_LIST(ns_dbversion_t)        freeversions;
        dns_rdataset_t *                dns64_aaaa;
        dns_rdataset_t *                dns64_sigaaaa;
-       bool *                  dns64_aaaaok;
+       bool *                          dns64_aaaaok;
        unsigned int                    dns64_aaaaoklen;
        unsigned int                    dns64_options;
        unsigned int                    dns64_ttl;
@@ -87,8 +93,8 @@ struct ns_query {
                isc_result_t            result;
                dns_rdataset_t *        rdataset;
                dns_rdataset_t *        sigrdataset;
-               bool            authoritative;
-               bool            is_zone;
+               bool                    authoritative;
+               bool                    is_zone;
        } redirect;
 
        ns_query_recparam_t             recparam;
@@ -166,7 +172,9 @@ struct query_ctx {
        dns_rpz_st_t *rpz_st;                   /* RPZ state */
        dns_zone_t *zone;                       /* zone to search */
 
-       dns_aaaa_t filter_aaaa;                 /* AAAA filtering */
+       dns_view_t *view;                       /* client view */
+
+       void *hookdata[NS_MAX_MODULES];         /* data used by query hooks */
 
        isc_result_t result;                    /* query result */
        int line;                               /* line to report error */
@@ -254,12 +262,4 @@ ns__query_start(query_ctx_t *qctx);
  * (Must not be used outside this module and its associated unit tests.)
  */
 
-void
-ns__query_inithooks(void);
-/*
- * XXX:
- * Temporary function used to initialize the filter-aaaa hooks,
- * which are currently hard-coded rather than loaded as a module.
- */
-
 #endif /* NS_QUERY_H */
index a83730c362e89bbef77a1ba98f40c44f879ead48..dcfa5cc3688d8f2abaeaea7800bf35bb4cd98254 100644 (file)
@@ -243,11 +243,10 @@ log_noexistnodata(void *val, int level, const char *fmt, ...)
                ns_hooktable_t *_tab = ns__hook_table;                  \
                query_ctx_t *_q = (_qctx);                              \
                if (_q != NULL &&                                       \
-                   _q->client != NULL &&                               \
-                   _q->client->view != NULL &&                         \
-                   _q->client->view->hooktable != NULL)                \
+                   _q->view != NULL &&                                 \
+                   _q->view->hooktable != NULL)                        \
                {                                                       \
-                       _tab = _q->client->view->hooktable;             \
+                       _tab = _q->view->hooktable;                     \
                }                                                       \
                NS_PROCESS_HOOK(_tab, _id, _q, __VA_ARGS__);            \
        } while (false)
@@ -257,11 +256,10 @@ log_noexistnodata(void *val, int level, const char *fmt, ...)
                ns_hooktable_t *_tab = ns__hook_table;                  \
                query_ctx_t *_q = (_qctx);                              \
                if (_q != NULL &&                                       \
-                   _q->client != NULL &&                               \
-                   _q->client->view != NULL &&                         \
-                   _q->client->view->hooktable != NULL)                \
+                   _q->view != NULL &&                                 \
+                   _q->view->hooktable != NULL)                        \
                {                                                       \
-                       _tab = _q->client->view->hooktable;             \
+                       _tab = _q->view->hooktable;                     \
                }                                                       \
                NS_PROCESS_HOOK_VOID(_tab, _id, _q, __VA_ARGS__);       \
        } while (false)
@@ -329,7 +327,8 @@ log_noexistnodata(void *val, int level, const char *fmt, ...)
  *     return it to the client.
  *
  * (XXX: This description omits several special cases including
- * DNS64, filter-aaaa, RPZ, RRL, and the SERVFAIL cache.)
+ * DNS64, RPZ, RRL, and the SERVFAIL cache. It also doesn't discuss
+ * query hook modules.)
  */
 
 static void
@@ -1460,7 +1459,7 @@ query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
         * If we want only minimal responses and are here, then it must
         * be for glue.
         */
-       if (client->view->minimalresponses == dns_minimal_yes) {
+       if (qctx->view->minimalresponses == dns_minimal_yes) {
                goto try_glue;
        }
 
@@ -1517,7 +1516,7 @@ query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
         */
 
  try_cache:
-       if (!client->view->recursion) {
+       if (!qctx->view->recursion) {
                goto try_glue;
        }
 
@@ -1546,7 +1545,7 @@ query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
                                client->now, &node, fname, &cm, &ci,
                                rdataset, sigrdataset);
 
-       dns_cache_updatestats(client->view->cache, result);
+       dns_cache_updatestats(qctx->view->cache, result);
        if (!WANTDNSSEC(client)) {
                ns_client_putrdataset(client, &sigrdataset);
        }
@@ -1892,9 +1891,11 @@ query_setorder(query_ctx_t *qctx, dns_name_t *name, dns_rdataset_t *rdataset) {
 
        CTRACE(ISC_LOG_DEBUG(3), "query_setorder");
 
-       if (client->view->order != NULL) {
+       UNUSED(client);
+
+       if (qctx->view->order != NULL) {
                rdataset->attributes |=
-                       dns_order_find(qctx->client->view->order,
+                       dns_order_find(qctx->view->order,
                                       name, rdataset->type,
                                       rdataset->rdclass);
        }
@@ -1917,7 +1918,7 @@ query_additional(query_ctx_t *qctx, dns_rdataset_t *rdataset) {
        /*
         * Try to process glue directly.
         */
-       if (client->view->use_glue_cache &&
+       if (qctx->view->use_glue_cache &&
            (rdataset->type == dns_rdatatype_ns) &&
            (client->query.gluedb != NULL) &&
            dns_db_iszone(client->query.gluedb))
@@ -4800,6 +4801,9 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
  * Initialize query context 'qctx'. Run by query_setup() when
  * first handling a client query, and by query_resume() when
  * returning from recursion.
+ *
+ * Whenever this function is called, qctx_destroy() must be called
+ * when leaving the scope or freeing the qctx.
  */
 static void
 qctx_init(ns_client_t *client, dns_fetchevent_t *event,
@@ -4808,10 +4812,13 @@ qctx_init(ns_client_t *client, dns_fetchevent_t *event,
        REQUIRE(qctx != NULL);
        REQUIRE(client != NULL);
 
+       memset(qctx, 0, sizeof(query_ctx_t));
+
        /* Set this first so CCTRACE will work */
        qctx->client = client;
+       dns_view_attach(client->view, &qctx->view);
 
-       CCTRACE(ISC_LOG_DEBUG(3), "qctx_create");
+       CCTRACE(ISC_LOG_DEBUG(3), "qctx_init");
 
        qctx->event = event;
        qctx->qtype = qctx->type = qtype;
@@ -4835,12 +4842,13 @@ qctx_init(ns_client_t *client, dns_fetchevent_t *event,
        qctx->options = 0;
        qctx->resuming = false;
        qctx->is_zone = false;
-       qctx->findcoveringnsec = client->view->synthfromdnssec;
+       qctx->findcoveringnsec = qctx->view->synthfromdnssec;
        qctx->is_staticstub_zone = false;
        qctx->nxrewrite = false;
        qctx->answer_has_ns = false;
        qctx->authoritative = false;
-       qctx->filter_aaaa = dns_aaaa_ok;
+
+       PROCESS_HOOK_VOID(NS_QUERY_QCTX_INITIALIZED, qctx);
 }
 
 /*%
@@ -4903,6 +4911,12 @@ qctx_freedata(query_ctx_t *qctx) {
        }
 }
 
+static void
+qctx_destroy(query_ctx_t *qctx) {
+       PROCESS_HOOK_VOID(NS_QUERY_QCTX_DESTROYED, qctx);
+       dns_view_detach(&qctx->view);
+}
+
 /*%
  * Log detailed information about the query immediately after
  * the client request or a return from recursion.
@@ -4962,17 +4976,18 @@ query_setup(ns_client_t *client, dns_rdatatype_t qtype) {
                qctx.type = dns_rdatatype_any;
        }
 
-       PROCESS_HOOK(NS_QUERY_SETUP_QCTX_INITIALIZED, &qctx);
-
        /*
         * Check SERVFAIL cache
         */
        result = ns__query_sfcache(&qctx);
        if (result != ISC_R_COMPLETE) {
+               qctx_destroy(&qctx);
                return (result);
        }
 
-       return (ns__query_start(&qctx));
+       result = ns__query_start(&qctx);
+       qctx_destroy(&qctx);
+       return (result);
 }
 
 static bool
@@ -5061,7 +5076,7 @@ ns__query_start(query_ctx_t *qctx) {
         * If we require a server cookie then send back BADCOOKIE
         * before we have done too much work.
         */
-       if (!TCP(qctx->client) && qctx->client->view->requireservercookie &&
+       if (!TCP(qctx->client) && qctx->view->requireservercookie &&
            WANTCOOKIE(qctx->client) && !HAVECOOKIE(qctx->client))
        {
                qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AA;
@@ -5070,7 +5085,7 @@ ns__query_start(query_ctx_t *qctx) {
                return (ns_query_done(qctx));
        }
 
-       if (qctx->client->view->checknames &&
+       if (qctx->view->checknames &&
            !dns_rdata_checkowner(qctx->client->query.qname,
                                  qctx->client->message->rdclass,
                                  qctx->qtype, false))
@@ -5095,7 +5110,7 @@ ns__query_start(query_ctx_t *qctx) {
        /*
         * Setup for root key sentinel processing.
         */
-       if (qctx->client->view->root_key_sentinel &&
+       if (qctx->view->root_key_sentinel &&
            qctx->client->query.restarts == 0 &&
            (qctx->qtype == dns_rdatatype_a ||
             qctx->qtype == dns_rdatatype_aaaa) &&
@@ -5340,7 +5355,7 @@ query_lookup(query_ctx_t *qctx) {
        }
 
        if (!qctx->is_zone) {
-               dns_cache_updatestats(qctx->client->view->cache, result);
+               dns_cache_updatestats(qctx->view->cache, result);
        }
 
        if ((qctx->client->query.dboptions & DNS_DBFIND_STALEOK) != 0) {
@@ -5351,8 +5366,7 @@ query_lookup(query_ctx_t *qctx) {
                if (dns_rdataset_isassociated(qctx->rdataset) &&
                    dns_rdataset_count(qctx->rdataset) > 0 &&
                    STALE(qctx->rdataset)) {
-                       qctx->rdataset->ttl =
-                                        qctx->client->view->staleanswerttl;
+                       qctx->rdataset->ttl = qctx->view->staleanswerttl;
                        success = true;
                } else {
                        success = false;
@@ -5443,6 +5457,10 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
        } else {
                query_ctx_t qctx;
 
+               /*
+                * Initalize a new qctx and use it to resume
+                * from recursion.
+                */
                qctx_init(client, devent, 0, &qctx);
                query_trace(&qctx);
 
@@ -5460,6 +5478,8 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
                                                      errorloglevel, false);
                        }
                }
+
+               qctx_destroy(&qctx);
        }
 
        dns_resolver_destroyfetch(&fetch);
@@ -5802,7 +5822,7 @@ query_resume(query_ctx_t *qctx) {
                /*
                 * Has response policy changed out from under us?
                 */
-               if (qctx->rpz_st->rpz_ver != qctx->client->view->rpzs->rpz_ver)
+               if (qctx->rpz_st->rpz_ver != qctx->view->rpzs->rpz_ver)
                {
                        ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
                                      NS_LOGMODULE_QUERY,
@@ -5810,7 +5830,7 @@ query_resume(query_ctx_t *qctx) {
                                      "query_resume: RPZ settings "
                                      "out of date "
                                      "(rpz_ver %d, expected %d)",
-                                     qctx->client->view->rpzs->rpz_ver,
+                                     qctx->view->rpzs->rpz_ver,
                                      qctx->rpz_st->rpz_ver);
                        QUERY_ERROR(qctx, DNS_R_SERVFAIL);
                        return (ns_query_done(qctx));
@@ -5896,13 +5916,13 @@ ns__query_sfcache(query_ctx_t *qctx) {
                failcache = false;
        } else {
                failcache =
-                       dns_badcache_find(qctx->client->view->failcache,
+                       dns_badcache_find(qctx->view->failcache,
                                          qctx->client->query.qname,
                                          qctx->qtype, &flags,
                                          &qctx->client->tnow);
        }
 #else
-       failcache = dns_badcache_find(qctx->client->view->failcache,
+       failcache = dns_badcache_find(qctx->view->failcache,
                                      qctx->client->query.qname,
                                      qctx->qtype, &flags,
                                      &qctx->client->tnow);
@@ -5959,20 +5979,26 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
         * is set when we are called the second time preventing the
         * response being dropped.
         */
-       ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL, NS_LOGMODULE_QUERY,
-                     ISC_LOG_DEBUG(99), "rrl=%p, HAVECOOKIE=%u, result=%s, "
+       ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL,
+                     NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(99),
+                     "rrl=%p, HAVECOOKIE=%u, result=%s, "
                      "fname=%p(%u), is_zone=%u, RECURSIONOK=%u, "
                      "query.rpz_st=%p(%u), RRL_CHECKED=%u\n",
                      qctx->client->view->rrl, HAVECOOKIE(qctx->client),
                      isc_result_toid(result), qctx->fname,
-                     qctx->fname?dns_name_isabsolute(qctx->fname) : 0,
+                     qctx->fname != NULL
+                      ? dns_name_isabsolute(qctx->fname)
+                      : 0,
                      qctx->is_zone, RECURSIONOK(qctx->client),
                      qctx->client->query.rpz_st,
-                     qctx->client->query.rpz_st ?
-                       (qctx->client->query.rpz_st->state & DNS_RPZ_REWRITTEN) != 0 : 0,
-                     (qctx->client->query.attributes & NS_QUERYATTR_RRL_CHECKED) != 0);
-
-       if (qctx->client->view->rrl != NULL &&
+                     qctx->client->query.rpz_st != NULL
+                      ? ((qctx->client->query.rpz_st->state &
+                          DNS_RPZ_REWRITTEN) != 0)
+                      : 0,
+                     (qctx->client->query.attributes &
+                      NS_QUERYATTR_RRL_CHECKED) != 0);
+
+       if (qctx->view->rrl != NULL &&
            !HAVECOOKIE(qctx->client) &&
            ((qctx->fname != NULL && dns_name_isabsolute(qctx->fname)) ||
             (result == ISC_R_NOTFOUND && !RECURSIONOK(qctx->client))) &&
@@ -6043,7 +6069,7 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
                        resp_result = ISC_R_SUCCESS;
                }
 
-               rrl_result = dns_rrl(qctx->client->view,
+               rrl_result = dns_rrl(qctx->view,
                                     &qctx->client->peeraddr,
                                     TCP(qctx->client),
                                     qctx->client->message->rdclass,
@@ -6068,7 +6094,7 @@ query_checkrrl(query_ctx_t *qctx, isc_result_t result) {
                                              "%s", log_buf);
                        }
 
-                       if (!qctx->client->view->rrl->log_only) {
+                       if (!qctx->view->rrl->log_only) {
                                if (rrl_result == DNS_RRL_RESULT_DROP) {
                                        /*
                                         * These will also be counted in
@@ -6370,7 +6396,7 @@ has_ta(query_ctx_t *qctx) {
        dns_keynode_t *keynode = NULL;
        isc_result_t result;
 
-       result = dns_view_getsecroots(qctx->client->view, &keytable);
+       result = dns_view_getsecroots(qctx->view, &keytable);
        if (result != ISC_R_SUCCESS) {
                return (false);
        }
@@ -6739,7 +6765,7 @@ query_respond_any(query_ctx_t *qctx) {
                         * ANY queries.
                         */
                        dns_rdataset_disassociate(qctx->rdataset);
-               } else if (qctx->client->view->minimal_any &&
+               } else if (qctx->view->minimal_any &&
                           !TCP(qctx->client) && !WANTDNSSEC(qctx->client) &&
                           qctx->qtype == dns_rdatatype_any &&
                           (qctx->rdataset->type == dns_rdatatype_sig ||
@@ -6748,7 +6774,7 @@ query_respond_any(query_ctx_t *qctx) {
                        CCTRACE(ISC_LOG_DEBUG(5), "query_respond_any: "
                               "minimal-any skip signature");
                        dns_rdataset_disassociate(qctx->rdataset);
-               } else if (qctx->client->view->minimal_any &&
+               } else if (qctx->view->minimal_any &&
                           !TCP(qctx->client) && onetype != 0 &&
                           qctx->rdataset->type != onetype &&
                           qctx->rdataset->covers != onetype)
@@ -6996,7 +7022,7 @@ query_respond(query_ctx_t *qctx) {
        INSIST(qctx->client->query.dns64_aaaaok == NULL);
 
        if (qctx->qtype == dns_rdatatype_aaaa && !qctx->dns64_exclude &&
-           !ISC_LIST_EMPTY(qctx->client->view->dns64) &&
+           !ISC_LIST_EMPTY(qctx->view->dns64) &&
            qctx->client->message->rdclass == dns_rdataclass_in &&
            !dns64_aaaaok(qctx->client, qctx->rdataset, qctx->sigrdataset))
        {
@@ -7473,14 +7499,14 @@ query_notfound(query_ctx_t *qctx) {
         * If the cache doesn't even have the root NS,
         * try to get that from the hints DB.
         */
-       if (qctx->client->view->hints != NULL) {
+       if (qctx->view->hints != NULL) {
                dns_clientinfomethods_t cm;
                dns_clientinfo_t ci;
 
                dns_clientinfomethods_init(&cm, ns_client_sourceip);
                dns_clientinfo_init(&ci, qctx->client, NULL);
 
-               dns_db_attach(qctx->client->view->hints, &qctx->db);
+               dns_db_attach(qctx->view->hints, &qctx->db);
                result = dns_db_findext(qctx->db, dns_rootname,
                                        NULL, dns_rdatatype_ns,
                                        0, qctx->client->now, &qctx->node,
@@ -7665,7 +7691,7 @@ query_zone_delegation(query_ctx_t *qctx) {
                SAVE(qctx->zversion, qctx->version);
                SAVE(qctx->zrdataset, qctx->rdataset);
                SAVE(qctx->zsigrdataset, qctx->sigrdataset);
-               dns_db_attach(qctx->client->view->cachedb, &qctx->db);
+               dns_db_attach(qctx->view->cachedb, &qctx->db);
                qctx->is_zone = false;
 
                return (query_lookup(qctx));
@@ -7986,7 +8012,7 @@ query_nodata(query_ctx_t *qctx, isc_result_t result) {
 #endif
        } else if ((result == DNS_R_NXRRSET ||
                    result == DNS_R_NCACHENXRRSET) &&
-                  !ISC_LIST_EMPTY(qctx->client->view->dns64) &&
+                  !ISC_LIST_EMPTY(qctx->view->dns64) &&
                   qctx->client->message->rdclass == dns_rdataclass_in &&
                   qctx->qtype == dns_rdatatype_aaaa)
        {
@@ -8530,7 +8556,7 @@ query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
        dns_name_t *name = NULL;
        isc_buffer_t *dbuf, b;
        isc_result_t result;
-       dns_rdataset_t *clone = NULL, *sigclone = NULL;
+       dns_rdataset_t *cloneset = NULL, *clonesigset = NULL;
        dns_rdataset_t **sigrdatasetp;
 
        /*
@@ -8556,29 +8582,29 @@ query_synthwildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
        }
        dns_name_copy(qctx->client->query.qname, name, NULL);
 
-       clone = ns_client_newrdataset(qctx->client);
-       if (clone == NULL) {
+       cloneset = ns_client_newrdataset(qctx->client);
+       if (cloneset == NULL) {
                result = ISC_R_NOMEMORY;
                goto cleanup;
        }
-       dns_rdataset_clone(rdataset, clone);
+       dns_rdataset_clone(rdataset, cloneset);
 
        /*
         * Add answer RRset. Omit the RRSIG if DNSSEC was not requested.
         */
        if (WANTDNSSEC(qctx->client)) {
-               sigclone = ns_client_newrdataset(qctx->client);
-               if (sigclone == NULL) {
+               clonesigset = ns_client_newrdataset(qctx->client);
+               if (clonesigset == NULL) {
                        result = ISC_R_NOMEMORY;
                        goto cleanup;
                }
-               dns_rdataset_clone(sigrdataset, sigclone);
-               sigrdatasetp = &sigclone;
+               dns_rdataset_clone(sigrdataset, clonesigset);
+               sigrdatasetp = &clonesigset;
        } else {
                sigrdatasetp = NULL;
        }
 
-       query_addrrset(qctx, &name, &clone, sigrdatasetp,
+       query_addrrset(qctx, &name, &cloneset, sigrdatasetp,
                       dbuf, DNS_SECTION_ANSWER);
 
        if (WANTDNSSEC(qctx->client)) {
@@ -8597,11 +8623,11 @@ cleanup:
        if (name != NULL) {
                ns_client_releasename(qctx->client, &name);
        }
-       if (clone != NULL) {
-               ns_client_putrdataset(qctx->client, &clone);
+       if (cloneset != NULL) {
+               ns_client_putrdataset(qctx->client, &cloneset);
        }
-       if (sigclone != NULL) {
-               ns_client_putrdataset(qctx->client, &sigclone);
+       if (clonesigset != NULL) {
+               ns_client_putrdataset(qctx->client, &clonesigset);
        }
        return (result);
 }
@@ -8684,7 +8710,7 @@ query_synthnxdomain(query_ctx_t *qctx,
        dns_ttl_t ttl;
        isc_buffer_t *dbuf, b;
        isc_result_t result;
-       dns_rdataset_t *clone = NULL, *sigclone = NULL;
+       dns_rdataset_t *cloneset = NULL, *clonesigset = NULL;
 
        /*
         * Detemine the correct TTL to use for the SOA and RRSIG
@@ -8749,20 +8775,20 @@ query_synthnxdomain(query_ctx_t *qctx,
 
                dns_name_copy(nowild, name, NULL);
 
-               clone = ns_client_newrdataset(qctx->client);
-               sigclone = ns_client_newrdataset(qctx->client);
-               if (clone == NULL || sigclone == NULL) {
+               cloneset = ns_client_newrdataset(qctx->client);
+               clonesigset = ns_client_newrdataset(qctx->client);
+               if (cloneset == NULL || clonesigset == NULL) {
                        result = ISC_R_NOMEMORY;
                        goto cleanup;
                }
 
-               dns_rdataset_clone(nowildrdataset, clone);
-               dns_rdataset_clone(signowildrdataset, sigclone);
+               dns_rdataset_clone(nowildrdataset, cloneset);
+               dns_rdataset_clone(signowildrdataset, clonesigset);
 
                /*
                 * Add NOWILDCARD proof.
                 */
-               query_addrrset(qctx, &name, &clone, &sigclone,
+               query_addrrset(qctx, &name, &cloneset, &clonesigset,
                               dbuf, DNS_SECTION_AUTHORITY);
        }
 
@@ -8774,11 +8800,11 @@ cleanup:
        if (name != NULL) {
                ns_client_releasename(qctx->client, &name);
        }
-       if (clone != NULL) {
-               ns_client_putrdataset(qctx->client, &clone);
+       if (cloneset != NULL) {
+               ns_client_putrdataset(qctx->client, &cloneset);
        }
-       if (sigclone != NULL) {
-               ns_client_putrdataset(qctx->client, &sigclone);
+       if (clonesigset != NULL) {
+               ns_client_putrdataset(qctx->client, &clonesigset);
        }
        return (result);
 }
@@ -8895,7 +8921,7 @@ query_coveringnsec(query_ctx_t *qctx) {
                if (qctx->type == dns_rdatatype_any) {  /* XXX not yet */
                        goto cleanup;
                }
-               if (!ISC_LIST_EMPTY(qctx->client->view->dns64) &&
+               if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
                    (qctx->type == dns_rdatatype_a ||
                     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
                {
@@ -8959,7 +8985,7 @@ query_coveringnsec(query_ctx_t *qctx) {
                if (qctx->type == dns_rdatatype_any) {  /* XXX not yet */
                        goto cleanup;
                }
-               if (!ISC_LIST_EMPTY(qctx->client->view->dns64) &&
+               if (!ISC_LIST_EMPTY(qctx->view->dns64) &&
                    (qctx->type == dns_rdatatype_a ||
                     qctx->type == dns_rdatatype_aaaa)) /* XXX not yet */
                {
@@ -10452,7 +10478,7 @@ ns_query_done(query_ctx_t *qctx) {
        query_glueanswer(qctx);
 
        if (qctx->client->message->rcode == dns_rcode_nxdomain &&
-           qctx->client->view->auth_nxdomain == true)
+           qctx->view->auth_nxdomain == true)
        {
                qctx->client->message->flags |= DNS_MESSAGEFLAG_AA;
        }
index c6311ec39b37c5e4123d17afcb39e272b26c724a..355d1758650fcce55cba6678519c96424d0a30e7 100644 (file)
@@ -691,7 +691,7 @@ create_qctx_for_client(ns_client_t *client, query_ctx_t **qctxp) {
         */
 
        ns_hooktable_init(&query_hooks);
-       ns_hook_add(&query_hooks, NS_QUERY_SETUP_QCTX_INITIALIZED, &hook);
+       ns_hook_add(&query_hooks, NS_QUERY_QCTX_INITIALIZED, &hook);
 
        saved_hook_table = ns__hook_table;
        ns__hook_table = &query_hooks;
index 40cddb97087912da7159035d27b1e8af2b129e6f..568386bafaf489c4ebb75487e95c89a4b347f0c4 100644 (file)
@@ -360,7 +360,6 @@ my @enablelist = ("developer",
                   "isc-spnego",
                   "native-pkcs11",
                   "openssl-hash",
-                  "filter-aaaa",
                   "querytrace",
                   "rpz-nsdname",
                   "rpz-nsip");