From 81f58e2ea2640bd010ddc8f5e0dca0740455966b Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 13 Aug 2018 01:18:09 -0700 Subject: [PATCH] enable modules to store data in qctx - 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 --- bin/hooks/filter-aaaa.c | 275 +++++++++++++++++++++++++++--------- bin/named/server.c | 13 +- doc/misc/options | 17 ++- lib/dns/include/dns/types.h | 6 - lib/ns/client.c | 2 +- lib/ns/hooks.c | 5 +- lib/ns/include/ns/client.h | 2 +- lib/ns/include/ns/hooks.h | 9 +- lib/ns/include/ns/query.h | 34 ++--- lib/ns/query.c | 176 +++++++++++++---------- lib/ns/tests/nstest.c | 2 +- win32utils/Configure | 1 - 12 files changed, 357 insertions(+), 185 deletions(-) diff --git a/bin/hooks/filter-aaaa.c b/bin/hooks/filter-aaaa.c index 6bd1cdc9d8..fa964fab69 100644 --- a/bin/hooks/filter-aaaa.c +++ b/bin/hooks/filter-aaaa.c @@ -23,8 +23,8 @@ #include #include +#include #include -#include #include #include @@ -38,9 +38,15 @@ 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, }; -/* - * Configuration support. - */ +static bool +filter_qctx_destroy(void *hookdata, void *cbdata, isc_result_t *resp); +ns_hook_t filter_destroy = { + .callback = filter_qctx_destroy, +}; -static dns_aaaa_t v4_aaaa; -static dns_aaaa_t v6_aaaa; +/** + ** Support for parsing of parameters and configuration of the module. + **/ + +/* + * 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; + +/* + * 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. + **/ + /* - * 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; + +/* + * 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); +} diff --git a/bin/named/server.c b/bin/named/server.c index a6a55bd11b..0fa0f7da31 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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 diff --git a/doc/misc/options b/doc/misc/options index 371ae55664..1b54aeda19 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -24,6 +24,9 @@ dlz { dyndb { }; // may occur multiple times +hook ( query ) [ { } + ]; // may occur multiple times + key { algorithm ; secret ; @@ -172,9 +175,9 @@ options { fetches-per-server [ ( drop | fail ) ]; fetches-per-zone [ ( drop | fail ) ]; files ( default | unlimited | ); - filter-aaaa { ; ... }; - filter-aaaa-on-v4 ( break-dnssec | ); - filter-aaaa-on-v6 ( break-dnssec | ); + filter-aaaa { ; ... }; // obsolete + filter-aaaa-on-v4 ; // obsolete + filter-aaaa-on-v6 ; // obsolete flush-zones-on-shutdown ; forward ( first | only ); forwarders [ port ] [ dscp ] { ( @@ -533,13 +536,15 @@ view [ ] { fetch-quota-params ; fetches-per-server [ ( drop | fail ) ]; fetches-per-zone [ ( drop | fail ) ]; - filter-aaaa { ; ... }; - filter-aaaa-on-v4 ( break-dnssec | ); - filter-aaaa-on-v6 ( break-dnssec | ); + filter-aaaa { ; ... }; // obsolete + filter-aaaa-on-v4 ; // obsolete + filter-aaaa-on-v6 ; // obsolete forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; glue-cache ; + hook ( query ) [ { + } ]; // may occur multiple times inline-signing ; ixfr-from-differences ( primary | master | secondary | slave | ); diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index c2e64287c1..17c605e69a 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -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. */ diff --git a/lib/ns/client.c b/lib/ns/client.c index 525cad499d..7739905d04 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -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, diff --git a/lib/ns/hooks.c b/lib/ns/hooks.c index 6835617b4c..7f0ab4d4a2 100644 --- a/lib/ns/hooks.c +++ b/lib/ns/hooks.c @@ -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)); diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index 12845141fb..ea209d6b5f 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -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; diff --git a/lib/ns/include/ns/hooks.h b/lib/ns/include/ns/hooks.h index f89201a48b..95f9aca183 100644 --- a/lib/ns/include/ns/hooks.h +++ b/lib/ns/include/ns/hooks.h @@ -163,7 +163,8 @@ */ 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); diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h index 853c7e5a90..987dfe804d 100644 --- a/lib/ns/include/ns/query.h +++ b/lib/ns/include/ns/query.h @@ -27,12 +27,18 @@ #include +/* + * 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 */ diff --git a/lib/ns/query.c b/lib/ns/query.c index a83730c362..dcfa5cc368 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -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); + 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->client->view->rrl != NULL && + 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; } diff --git a/lib/ns/tests/nstest.c b/lib/ns/tests/nstest.c index c6311ec39b..355d175865 100644 --- a/lib/ns/tests/nstest.c +++ b/lib/ns/tests/nstest.c @@ -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; diff --git a/win32utils/Configure b/win32utils/Configure index 40cddb9708..568386bafa 100644 --- a/win32utils/Configure +++ b/win32utils/Configure @@ -360,7 +360,6 @@ my @enablelist = ("developer", "isc-spnego", "native-pkcs11", "openssl-hash", - "filter-aaaa", "querytrace", "rpz-nsdname", "rpz-nsip");