From 427e9ca35725ffd03ef88391b90cd40c43c81eac Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Fri, 14 Sep 2018 12:32:36 -0700 Subject: [PATCH] clear AD flag when altering response messages - the AD flag was not being cleared correctly when filtering - enabled dnssec valdiation in the filter-aaaa test to confirm this works correctly now --- bin/hooks/Makefile.in | 12 -- bin/hooks/filter-aaaa.c | 90 +++++---- bin/hooks/filter-aaaa.docbook | 2 +- bin/named/server.c | 39 ++-- bin/tests/system/filter-aaaa/clean.sh | 3 + bin/tests/system/filter-aaaa/ns1/sign.sh | 15 +- .../system/filter-aaaa/ns2/named1.conf.in | 2 + .../system/filter-aaaa/ns2/named2.conf.in | 2 + .../system/filter-aaaa/ns3/named1.conf.in | 2 + .../system/filter-aaaa/ns3/named2.conf.in | 2 + bin/tests/system/filter-aaaa/ns4/sign.sh | 10 +- .../system/filter-aaaa/ns5/named.conf.in | 2 + bin/tests/system/filter-aaaa/tests.sh | 39 +++- lib/dns/adb.c | 2 +- lib/dns/include/dns/dyndb.h | 2 +- lib/isccfg/parser.c | 7 +- lib/ns/client.c | 1 + lib/ns/hooks.c | 182 ++++++++++-------- lib/ns/include/ns/client.h | 20 +- lib/ns/include/ns/hooks.h | 76 ++++++-- lib/ns/include/ns/query.h | 4 +- lib/ns/query.c | 91 ++++----- lib/ns/win32/libns.def | 2 +- 23 files changed, 340 insertions(+), 267 deletions(-) diff --git a/bin/hooks/Makefile.in b/bin/hooks/Makefile.in index 69e571d199..c6c8a915ad 100644 --- a/bin/hooks/Makefile.in +++ b/bin/hooks/Makefile.in @@ -11,16 +11,6 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -VERSION=@BIND9_VERSION@ - -@BIND9_PRODUCT@ - -@BIND9_DESCRIPTION@ - -@BIND9_SRCID@ - -@BIND9_CONFIGARGS@ - @BIND9_MAKE_INCLUDES@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ @@ -40,8 +30,6 @@ TARGETS = @SO_TARGETS@ SO_OBJS = filter-aaaa.@O@ SO_SRCS = filter-aaaa.c -OBJS = - CFLAGS = @CFLAGS@ @SO_CFLAGS@ SO_LDFLAGS = @LDFLAGS@ @SO_LDFLAGS@ diff --git a/bin/hooks/filter-aaaa.c b/bin/hooks/filter-aaaa.c index 174725eac2..e70c6c2bb9 100644 --- a/bin/hooks/filter-aaaa.c +++ b/bin/hooks/filter-aaaa.c @@ -13,29 +13,45 @@ #include +#include +#include +#include + +#include #include #include +#include #include +#include #include +#include #include #include +#include #include -#include - -#include -#include #include #include #include #include +#include -#define CHECK(r) \ - do { \ - result = (r); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHECK(op) \ + do { \ + result = (op); \ + if (result != ISC_R_SUCCESS) { \ + goto cleanup; \ + } \ } while (0) /* @@ -228,23 +244,20 @@ parse_parameters(const char *parameters, const void *cfg, } /** - ** Mandatory hook API functions. + ** Mandatory hook API functions: + ** + ** - hook_destroy + ** - hook_register + ** - hook_version **/ -/* - * 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 unsigned int modid, const char *parameters, - const char *file, unsigned long line, + const char *cfg_file, unsigned long cfg_line, const void *cfg, void *actx, ns_hookctx_t *hctx, ns_hooktable_t *hooktable, void **instp) { @@ -254,20 +267,14 @@ hook_register(const unsigned int modid, const char *parameters, module_id = modid; - if (parameters != NULL) { - isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_HOOKS, ISC_LOG_INFO, - "loading params for 'filter-aaaa' " - "module from %s:%lu", - file, line); + isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_HOOKS, ISC_LOG_INFO, + "loading 'filter-aaaa' " + "module from %s:%lu, %s parameters", + cfg_file, cfg_line, parameters != NULL ? "with" : "no"); + if (parameters != NULL) { CHECK(parse_parameters(parameters, cfg, actx, hctx)); - } else { - isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_HOOKS, ISC_LOG_INFO, - "loading 'filter-aaaa' " - "module from %s:%lu, no parameters", - file, line); } ns_hook_add(hooktable, NS_QUERY_QCTX_INITIALIZED, &filter_init); @@ -304,7 +311,7 @@ hook_register(const unsigned int modid, const char *parameters, } /* - * Called by ns_hookmodule_cleanup(); frees memory allocated by + * Called by ns_hookmodule_unload_all(); frees memory allocated by * the module when it was registered. */ void @@ -325,18 +332,16 @@ hook_destroy(void **instp) { * Returns hook module API version for compatibility checks. */ int -hook_version(unsigned int *flags) { - UNUSED(flags); - +hook_version(void) { return (NS_HOOK_VERSION); } /** - ** "filter-aaaa" feature implementation begins here + ** "filter-aaaa" feature implementation begins here. **/ /* - * Check whether this is a V4 client. + * Check whether this is an IPv4 client. */ static bool is_v4_client(ns_client_t *client) { @@ -352,7 +357,7 @@ is_v4_client(ns_client_t *client) { } /* - * Check whether this is a V6 client. + * Check whether this is an IPv6 client. */ static bool is_v6_client(ns_client_t *client) { @@ -389,7 +394,7 @@ filter_qctx_initialize(void *hookdata, void *cbdata, isc_result_t *resp) { } /* - * Determine whether this client should have AAAA filtered nor not, + * Determine whether this client should have AAAA filtered or not, * based on the client address family and the settings of * filter-aaaa-on-v4 and filter-aaaa-on-v6. */ @@ -474,6 +479,7 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) { * cached an A if it existed. */ if (result == ISC_R_SUCCESS) { + qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; qctx->rdataset->attributes |= DNS_RDATASETATTR_RENDERED; if (qctx->sigrdataset != NULL && dns_rdataset_isassociated(qctx->sigrdataset)) @@ -511,7 +517,6 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) { ((qctx->client->hookflags[module_id] & FILTER_AAAA_RECURSING) != 0)) { - dns_rdataset_t *mrdataset = NULL; dns_rdataset_t *sigrdataset = NULL; @@ -520,6 +525,7 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) { dns_rdatatype_aaaa, 0, NULL, &mrdataset); if (result == ISC_R_SUCCESS) { + qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; mrdataset->attributes |= DNS_RDATASETATTR_RENDERED; } @@ -529,6 +535,7 @@ filter_respond_begin(void *hookdata, void *cbdata, isc_result_t *resp) { dns_rdatatype_aaaa, NULL, &sigrdataset); if (result == ISC_R_SUCCESS) { + qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; sigrdataset->attributes |= DNS_RDATASETATTR_RENDERED; } @@ -593,6 +600,7 @@ filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) { (aaaa_sig == NULL || !WANTDNSSEC(qctx->client) || **mode == BREAK_DNSSEC)) { + qctx->client->message->flags &= ~DNS_MESSAGEFLAG_AD; aaaa->attributes |= DNS_RDATASETATTR_RENDERED; if (aaaa_sig != NULL) { aaaa_sig->attributes |= DNS_RDATASETATTR_RENDERED; @@ -605,7 +613,7 @@ filter_respond_any_found(void *hookdata, void *cbdata, isc_result_t *resp) { /* * Hide AAAA rrsets in the additional section if there is a matching A, - * and hide NS in the additional section if AAAA was filtered in the answer + * and hide NS in the authority section if AAAA was filtered in the answer * section. */ static bool @@ -674,6 +682,8 @@ filter_query_done_send(void *hookdata, void *cbdata, isc_result_t *resp) { result = dns_message_findtype(name, dns_rdatatype_ns, 0, &ns); if (result == ISC_R_SUCCESS) { + qctx->client->message->flags &= + ~DNS_MESSAGEFLAG_AD; ns->attributes |= DNS_RDATASETATTR_RENDERED; } diff --git a/bin/hooks/filter-aaaa.docbook b/bin/hooks/filter-aaaa.docbook index 3a0581e9cd..3a12e144c6 100644 --- a/bin/hooks/filter-aaaa.docbook +++ b/bin/hooks/filter-aaaa.docbook @@ -50,7 +50,7 @@ to omit some IPv6 addresses when responding to clients. - Until BIND 9.12, this feature was impleented natively in + Until BIND 9.12, this feature was implemented natively in named and enabled with the filter-aaaa ACL and the filter-aaaa-on-v4 and diff --git a/bin/named/server.c b/bin/named/server.c index 0fa0f7da31..cd9ceb55ae 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -1544,6 +1544,7 @@ configure_hook(ns_hooktable_t *hooktable, const unsigned int modid, isc_result_t result = ISC_R_SUCCESS; const cfg_obj_t *obj; const char *type, *library; + const char *parameters = NULL; /* Get the path to the hook module. */ obj = cfg_tuple_get(hook, "type"); @@ -1560,22 +1561,12 @@ configure_hook(ns_hooktable_t *hooktable, const unsigned int modid, obj = cfg_tuple_get(hook, "parameters"); if (obj != NULL && cfg_obj_isstring(obj)) { - result = ns_hookmodule_load(library, modid, - cfg_obj_asstring(obj), - cfg_obj_file(obj), - cfg_obj_line(obj), - config, - named_g_aclconfctx, - hctx, hooktable); - } else { - result = ns_hookmodule_load(library, modid, NULL, - cfg_obj_file(hook), - cfg_obj_line(hook), - config, - named_g_aclconfctx, - hctx, hooktable); + parameters = cfg_obj_asstring(obj); } - + result = ns_hookmodule_load(library, modid, parameters, + cfg_obj_file(obj), cfg_obj_line(obj), + config, named_g_aclconfctx, + hctx, hooktable); if (result != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR, @@ -5318,6 +5309,16 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, } #ifdef HAVE_DLOPEN + if (hook_list != NULL) { + const void *hashinit = isc_hash_get_initializer(); + CHECK(ns_hook_createctx(mctx, hashinit, &hctx)); + + INSIST(view->hooktable == NULL); + CHECK(ns_hooktable_create(view->mctx, + (ns_hooktable_t **) &view->hooktable)); + view->hooktable_free = ns_hooktable_free; + } + for (element = cfg_list_first(hook_list); element != NULL; element = cfg_list_next(element)) @@ -5325,8 +5326,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, const cfg_obj_t *hook = cfg_listelt_value(element); if (view->hooktable == NULL) { - ns_hooktable_create(view->mctx, - (ns_hooktable_t **) &view->hooktable); + CHECK(ns_hooktable_create(view->mctx, + (ns_hooktable_t **) &view->hooktable)); view->hooktable_free = ns_hooktable_free; } @@ -8080,7 +8081,7 @@ load_configuration(const char *filename, named_server_t *server, * Shut down all dyndb and hook module instances. */ dns_dyndb_cleanup(false); - ns_hookmodule_cleanup(); + ns_hookmodule_unload_all(); /* * Parse the global default pseudo-config file. @@ -9565,7 +9566,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { * Shut down all dyndb and hook module instances. */ dns_dyndb_cleanup(true); - ns_hookmodule_cleanup(); + ns_hookmodule_unload_all(); while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) { ISC_LIST_UNLINK(server->cachelist, nsc, link); diff --git a/bin/tests/system/filter-aaaa/clean.sh b/bin/tests/system/filter-aaaa/clean.sh index a282093ff2..852010f519 100644 --- a/bin/tests/system/filter-aaaa/clean.sh +++ b/bin/tests/system/filter-aaaa/clean.sh @@ -26,3 +26,6 @@ rm -f ns4/dsset-* rm -f dig.out.* rm -f ns*/named.lock rm -f ns*/managed-keys.bind* + +rm -f ns*/trusted.conf +rm -f ns*/keygen.out diff --git a/bin/tests/system/filter-aaaa/ns1/sign.sh b/bin/tests/system/filter-aaaa/ns1/sign.sh index 2b75296ec1..71da6a751e 100755 --- a/bin/tests/system/filter-aaaa/ns1/sign.sh +++ b/bin/tests/system/filter-aaaa/ns1/sign.sh @@ -21,10 +21,15 @@ infile=signed.db.in zonefile=signed.db.signed outfile=signed.db.signed -keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` +$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 > /dev/null | cat_i +$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 > keygen.out | cat_i +keyname=`cat keygen.out` +rm -f keygen.out -cat $infile $keyname1.key $keyname2.key >$zonefile +keyfile_to_trusted_keys $keyname > trusted.conf +cp trusted.conf ../ns2/trusted.conf +cp trusted.conf ../ns3/trusted.conf +cp trusted.conf ../ns5/trusted.conf -$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err -echo_i "signed $zone" +$SIGNER -S -o $zone -f $outfile $infile > /dev/null 2> signer.err || cat signer.err +echo_i "signed zone '$zone'" diff --git a/bin/tests/system/filter-aaaa/ns2/named1.conf.in b/bin/tests/system/filter-aaaa/ns2/named1.conf.in index 5d9aeec8a4..0f48645932 100644 --- a/bin/tests/system/filter-aaaa/ns2/named1.conf.in +++ b/bin/tests/system/filter-aaaa/ns2/named1.conf.in @@ -38,3 +38,5 @@ controls { }; zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns2/named2.conf.in b/bin/tests/system/filter-aaaa/ns2/named2.conf.in index a313403c98..18399cf08a 100644 --- a/bin/tests/system/filter-aaaa/ns2/named2.conf.in +++ b/bin/tests/system/filter-aaaa/ns2/named2.conf.in @@ -38,3 +38,5 @@ controls { }; zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns3/named1.conf.in b/bin/tests/system/filter-aaaa/ns3/named1.conf.in index 7c24809a0c..2433c80d85 100644 --- a/bin/tests/system/filter-aaaa/ns3/named1.conf.in +++ b/bin/tests/system/filter-aaaa/ns3/named1.conf.in @@ -38,3 +38,5 @@ controls { }; zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns3/named2.conf.in b/bin/tests/system/filter-aaaa/ns3/named2.conf.in index cd5df44938..479d437980 100644 --- a/bin/tests/system/filter-aaaa/ns3/named2.conf.in +++ b/bin/tests/system/filter-aaaa/ns3/named2.conf.in @@ -38,3 +38,5 @@ controls { }; zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/ns4/sign.sh b/bin/tests/system/filter-aaaa/ns4/sign.sh index 2b75296ec1..20cc4a3f1b 100755 --- a/bin/tests/system/filter-aaaa/ns4/sign.sh +++ b/bin/tests/system/filter-aaaa/ns4/sign.sh @@ -21,10 +21,8 @@ infile=signed.db.in zonefile=signed.db.signed outfile=signed.db.signed -keyname1=`$KEYGEN -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` -keyname2=`$KEYGEN -f KSK -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone 2> /dev/null` +$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 > /dev/null | cat_i +$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 > /dev/null | cat_i -cat $infile $keyname1.key $keyname2.key >$zonefile - -$SIGNER -o $zone -f $outfile $zonefile > /dev/null 2> signer.err || cat signer.err -echo_i "signed $zone" +$SIGNER -S -o $zone -f $outfile $infile > /dev/null 2> signer.err || cat signer.err +echo_i "signed zone '$zone'" diff --git a/bin/tests/system/filter-aaaa/ns5/named.conf.in b/bin/tests/system/filter-aaaa/ns5/named.conf.in index df507b3016..b97ab1cafd 100644 --- a/bin/tests/system/filter-aaaa/ns5/named.conf.in +++ b/bin/tests/system/filter-aaaa/ns5/named.conf.in @@ -43,3 +43,5 @@ controls { }; zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff --git a/bin/tests/system/filter-aaaa/tests.sh b/bin/tests/system/filter-aaaa/tests.sh index 86d0c7cb7b..4ff2ebe3a2 100644 --- a/bin/tests/system/filter-aaaa/tests.sh +++ b/bin/tests/system/filter-aaaa/tests.sh @@ -199,7 +199,6 @@ else echo_i "skipped." fi - # # Authoritative tests against: # filter-aaaa-on-v4 break-dnssec; @@ -380,6 +379,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" ret=0 $DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::2 dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -397,6 +397,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -406,6 +407,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -414,6 +416,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" ret=0 $DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::3 dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -423,6 +426,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -461,6 +465,7 @@ echo_i "checking that both A and AAAA are returned when both AAAA and A records ret=0 $DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::3 dig.out.ns2.test$n > /dev/null || ret=1 grep "1.0.0.3" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -509,7 +514,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" +echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive ($n)" ret=0 $DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 && ret=1 @@ -517,15 +522,21 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" +echo_i "checking that AAAA is included in additional section, qtype=MX, signed, recursive ($n)" ret=0 +# we need to prime the cache with addresses for the MX, since additional +# section data won't be included unless it's validated, and that doesn't +# necessarily happen otherwise. +$DIG $DIGOPTS +dnssec mx.signed @10.53.0.2 > /dev/null +$DIG $DIGOPTS +dnssec mx.signed aaaa @10.53.0.2 > /dev/null $DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 grep "^mx.signed.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6 ($n)" +echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, recursive, over IPv6 ($n)" if $TESTSOCK6 fd92:7065:b8e:ffff::2 then ret=0 @@ -537,7 +548,6 @@ else echo_i "skipped." fi - # # Recursive tests against: # filter-aaaa-on-v4 break-dnssec; @@ -547,6 +557,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" ret=0 $DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null || ret=1 grep ::2 dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -564,6 +575,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -573,6 +585,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -582,6 +595,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -590,6 +604,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -688,6 +703,7 @@ echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, ret=0 $DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.3 @10.53.0.3 > dig.out.ns3.test$n || ret=1 grep "^mx.signed.*AAAA" dig.out.ns3.test$n > /dev/null 2>&1 && ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1047,6 +1063,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" ret=0 $DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::2 dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1064,6 +1081,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1073,6 +1091,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1081,6 +1100,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" ret=0 $DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::3 dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1090,6 +1110,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 grep "ANSWER: 0" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1128,6 +1149,7 @@ echo_i "checking that both A and AAAA are returned when both AAAA and A records ret=0 $DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 grep ::3 dig.out.ns2.test$n > /dev/null || ret=1 grep "1.0.0.3" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi @@ -1183,6 +1205,7 @@ echo_i "checking that AAAA is included in additional section, qtype=MX, signed ( ret=0 $DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 > dig.out.ns2.test$n || ret=1 grep "^mx.signed.*AAAA" dig.out.ns2.test$n > /dev/null 2>&1 || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1204,6 +1227,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" ret=0 $DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null || ret=1 grep ::2 dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1221,6 +1245,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1230,6 +1255,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1239,6 +1265,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1247,6 +1274,7 @@ echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records ex ret=0 $DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null && ret=1 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` @@ -1339,6 +1367,7 @@ n=`expr $n + 1` echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)" ret=0 $DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 > dig.out.ns3.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns3.test$n > /dev/null || ret=1 grep "^mx.signed.*AAAA" dig.out.ns3.test$n > /dev/null 2>&1 && ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` diff --git a/lib/dns/adb.c b/lib/dns/adb.c index ac0ab18fc5..b3a124fb03 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -2589,7 +2589,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl); if (result != ISC_R_SUCCESS) { DP(DEF_LEVEL, "adb: task-exclusive mode unavailable, " - "intializing table sizes to %u\n", + "initializing table sizes to %u\n", nbuckets[11]); adb->nentries = nbuckets[11]; adb->nnames = nbuckets[11]; diff --git a/lib/dns/include/dns/dyndb.h b/lib/dns/include/dns/dyndb.h index d5faf92069..015f8efab8 100644 --- a/lib/dns/include/dns/dyndb.h +++ b/lib/dns/include/dns/dyndb.h @@ -22,7 +22,7 @@ ISC_LANG_BEGINDECLS /*! * \brief - * Context for intializing a dyndb module. + * Context for initializing a dyndb module. * * This structure passes global server data to which a dyndb * module will need access -- the server memory context, hash diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 5af9ae2228..eea80b2789 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -1326,10 +1326,6 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bracketed_text = { &cfg_rep_string, NULL }; -/*% - * A bracketed address match list - */ - static cfg_type_t cfg_type_addrmatchelt; static cfg_type_t cfg_type_negated; @@ -1416,6 +1412,9 @@ static cfg_type_t cfg_type_addrmatchelt = { NULL, NULL }; +/*% + * A bracketed address match list + */ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_bracketed_aml = { "bracketed_aml", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_addrmatchelt diff --git a/lib/ns/client.c b/lib/ns/client.c index 7739905d04..1c45094833 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -4044,6 +4044,7 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) { REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0); CTRACE("ns_client_newname"); + name = NULL; result = dns_message_gettempname(client->message, &name); if (result != ISC_R_SUCCESS) { diff --git a/lib/ns/hooks.c b/lib/ns/hooks.c index 7f0ab4d4a2..d94cfdfdcd 100644 --- a/lib/ns/hooks.c +++ b/lib/ns/hooks.c @@ -21,33 +21,40 @@ #include #endif +#include +#include #include #include #include -#include +#include #include +#include #include #include +#include #define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ + do { \ + result = (op); \ + if (result != ISC_R_SUCCESS) { \ + goto cleanup; \ + } \ } while (0) typedef struct ns_hook_module ns_hook_module_t; struct ns_hook_module { isc_mem_t *mctx; void *handle; - char *filename; + char *modpath; ns_hook_register_t *register_func; ns_hook_destroy_t *destroy_func; void *inst; LINK(ns_hook_module_t) link; }; -static ns_hooklist_t hooktab[NS_QUERY_HOOKS_COUNT]; -LIBNS_EXTERNAL_DATA ns_hooktable_t *ns__hook_table = &hooktab; +static ns_hooklist_t default_hooktable[NS_HOOKPOINTS_COUNT]; +LIBNS_EXTERNAL_DATA ns_hooktable_t *ns__hook_table = &default_hooktable; /* * List of hook modules. @@ -55,40 +62,40 @@ LIBNS_EXTERNAL_DATA ns_hooktable_t *ns__hook_table = &hooktab; * These are stored here so they can be cleaned up on shutdown. * (The order in which they are stored is not important.) */ -static LIST(ns_hook_module_t) hook_modules; - -static isc_once_t once = ISC_ONCE_INIT; - -static void -init_modules(void) { - INIT_LIST(hook_modules); -} +static ISC_LIST(ns_hook_module_t) hook_modules; +static bool hook_modules_initialized = false; #if HAVE_DLFCN_H && HAVE_DLOPEN static isc_result_t -load_symbol(void *handle, const char *filename, +load_symbol(void *handle, const char *modpath, const char *symbol_name, void **symbolp) { - const char *errmsg; void *symbol; REQUIRE(handle != NULL); REQUIRE(symbolp != NULL && *symbolp == NULL); + /* + * Clear any pre-existing error conditions before running dlsym(). + * (In this case, we expect dlsym() to return non-NULL values + * and will always return an error if it returns NULL, but + * this ensures that we'll report the correct error condition + * if there is one.) + */ + dlerror(); symbol = dlsym(handle, symbol_name); if (symbol == NULL) { - errmsg = dlerror(); + const char *errmsg = dlerror(); if (errmsg == NULL) { errmsg = "returned function pointer is NULL"; } isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, - "failed to look upsymbol %s in " + "failed to look up symbol %s in " "hook module '%s': %s", - symbol_name, filename, errmsg); + symbol_name, modpath, errmsg); return (ISC_R_FAILURE); } - dlerror(); *symbolp = symbol; @@ -96,7 +103,7 @@ load_symbol(void *handle, const char *filename, } static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { +load_library(isc_mem_t *mctx, const char *modpath, ns_hook_module_t **hmodp) { isc_result_t result; void *handle = NULL; ns_hook_module_t *hmod = NULL; @@ -107,45 +114,50 @@ load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { REQUIRE(hmodp != NULL && *hmodp == NULL); - flags = RTLD_NOW|RTLD_LOCAL; + flags = RTLD_NOW | RTLD_LOCAL; #ifdef RTLD_DEEPBIND flags |= RTLD_DEEPBIND; #endif - handle = dlopen(filename, flags); + handle = dlopen(modpath, flags); if (handle == NULL) { - CHECK(ISC_R_FAILURE); + const char *errmsg = dlerror(); + if (errmsg == NULL) { + errmsg = "unknown error"; + } + isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, + "failed to dlopen() hook module '%s': %s", + modpath, errmsg); + return (ISC_R_FAILURE); } - /* Clear dlerror */ - dlerror(); - - CHECK(load_symbol(handle, filename, "hook_version", + CHECK(load_symbol(handle, modpath, "hook_version", (void **)&version_func)); - version = version_func(NULL); + version = version_func(); if (version < (NS_HOOK_VERSION - NS_HOOK_AGE) || version > NS_HOOK_VERSION) { isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, - "driver API version mismatch: %d/%d", + "hook API version mismatch: %d/%d", version, NS_HOOK_VERSION); CHECK(ISC_R_FAILURE); } - CHECK(load_symbol(handle, filename, "hook_register", + CHECK(load_symbol(handle, modpath, "hook_register", (void **)®ister_func)); - CHECK(load_symbol(handle, filename, "hook_destroy", + CHECK(load_symbol(handle, modpath, "hook_destroy", (void **)&destroy_func)); hmod = isc_mem_get(mctx, sizeof(*hmod)); hmod->mctx = NULL; isc_mem_attach(mctx, &hmod->mctx); hmod->handle = handle; + hmod->modpath = isc_mem_strdup(hmod->mctx, modpath); hmod->register_func = register_func; hmod->destroy_func = destroy_func; - hmod->inst = NULL; ISC_LINK_INIT(hmod, link); @@ -158,16 +170,15 @@ cleanup: isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, "failed to dynamically load " - "module '%s': %s (%s)", filename, - dlerror(), isc_result_totext(result)); + "module '%s': %s", modpath, + isc_result_totext(result)); if (hmod != NULL) { - isc_mem_putanddetach(&hmod->mctx, hmod, - sizeof(*hmod)); + isc_mem_putanddetach(&hmod->mctx, hmod, sizeof(*hmod)); } if (handle != NULL) { - dlclose(handle); + (void) dlclose(handle); } } @@ -184,17 +195,17 @@ unload_library(ns_hook_module_t **hmodp) { *hmodp = NULL; if (hmod->handle != NULL) { - dlclose(hmod->handle); + (void) dlclose(hmod->handle); } - if (hmod->filename != NULL) { - isc_mem_free(hmod->mctx, hmod->filename); + if (hmod->modpath != NULL) { + isc_mem_free(hmod->mctx, hmod->modpath); } isc_mem_putanddetach(&hmod->mctx, hmod, sizeof(*hmod)); } #elif _WIN32 static isc_result_t -load_symbol(HMODULE handle, const char *filename, +load_symbol(HMODULE handle, const char *modpath, const char *symbol_name, void **symbolp) { void *symbol; @@ -209,7 +220,7 @@ load_symbol(HMODULE handle, const char *filename, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, "failed to look up symbol %s in " "module '%s': %d", - symbol_name, filename, errstatus); + symbol_name, modpath, errstatus); return (ISC_R_FAILURE); } @@ -219,7 +230,7 @@ load_symbol(HMODULE handle, const char *filename, } static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { +load_library(isc_mem_t *mctx, const char *modpath, ns_hook_module_t **hmodp) { isc_result_t result; HMODULE handle; ns_hook_module_t *hmod = NULL; @@ -230,12 +241,12 @@ load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { REQUIRE(hmodp != NULL && *hmodp == NULL); - handle = LoadLibraryA(filename); + handle = LoadLibraryA(modpath); if (handle == NULL) { CHECK(ISC_R_FAILURE); } - CHECK(load_symbol(handle, filename, "hook_version", + CHECK(load_symbol(handle, modpath, "hook_version", (void **)&version_func)); version = version_func(NULL); @@ -244,23 +255,23 @@ load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { { isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, - "driver API version mismatch: %d/%d", + "hook API version mismatch: %d/%d", version, NS_HOOK_VERSION); CHECK(ISC_R_FAILURE); } - CHECK(load_symbol(handle, filename, "hook_register", + CHECK(load_symbol(handle, modpath, "hook_register", (void **)®ister_func)); - CHECK(load_symbol(handle, filename, "hook_destroy", + CHECK(load_symbol(handle, modpath, "hook_destroy", (void **)&destroy_func)); hmod = isc_mem_get(mctx, sizeof(*hmod)); hmod->mctx = NULL; isc_mem_attach(mctx, &hmod->mctx); hmod->handle = handle; + hmod->modpath = isc_mem_strdup(hmod->mctx, modpath); hmod->register_func = register_func; hmod->destroy_func = destroy_func; - hmod->inst = NULL; ISC_LINK_INIT(hmod, link); @@ -273,11 +284,11 @@ cleanup: isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, "failed to dynamically load " - "hook module '%s': %d (%s)", filename, + "hook module '%s': %d (%s)", modpath, GetLastError(), isc_result_totext(result)); + if (hmod != NULL) { - isc_mem_putanddetach(&hmod->mctx, hmod, - sizeof(*hmod)); + isc_mem_putanddetach(&hmod->mctx, hmod, sizeof(*hmod)); } if (handle != NULL) { @@ -301,22 +312,22 @@ unload_library(ns_hook_module_t **hmodp) { FreeLibrary(hmod->handle); } - if (hmod->filename != NULL) { - isc_mem_free(hmod->mctx, hmod->filename); + if (hmod->modpath != NULL) { + isc_mem_free(hmod->mctx, hmod->modpath); } isc_mem_putanddetach(&hmod->mctx, hmod, sizeof(*hmod)); } #else /* HAVE_DLFCN_H || _WIN32 */ static isc_result_t -load_library(isc_mem_t *mctx, const char *filename, ns_hook_module_t **hmodp) { +load_library(isc_mem_t *mctx, const char *modpath, ns_hook_module_t **hmodp) { UNUSED(mctx); - UNUSED(filename); + UNUSED(modpath); UNUSED(hmodp); isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_ERROR, - "hook module support is not hmodlemented"); + "hook module support is not implemented"); return (ISC_R_NOTIMPLEMENTED); } @@ -328,50 +339,53 @@ unload_library(ns_hook_module_t **hmodp) { #endif /* HAVE_DLFCN_H */ isc_result_t -ns_hookmodule_load(const char *libname, const unsigned int modid, +ns_hookmodule_load(const char *modpath, const unsigned int modid, const char *parameters, - const char *file, unsigned long line, + const char *cfg_file, unsigned long cfg_line, const void *cfg, void *actx, ns_hookctx_t *hctx, ns_hooktable_t *hooktable) { isc_result_t result; - ns_hook_module_t *module = NULL; + ns_hook_module_t *hmod = NULL; + REQUIRE(hook_modules_initialized); REQUIRE(NS_HOOKCTX_VALID(hctx)); + REQUIRE(hooktable != NULL); isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, - "loading module '%s'", libname); + "loading module '%s'", modpath); - CHECK(load_library(hctx->mctx, libname, &module)); - CHECK(module->register_func(modid, parameters, file, line, - cfg, actx, hctx, hooktable, - &module->inst)); + CHECK(load_library(hctx->mctx, modpath, &hmod)); + CHECK(hmod->register_func(modid, parameters, cfg_file, cfg_line, + cfg, actx, hctx, hooktable, + &hmod->inst)); - APPEND(hook_modules, module, link); - result = ISC_R_SUCCESS; + ISC_LIST_APPEND(hook_modules, hmod, link); cleanup: - if (result != ISC_R_SUCCESS && module != NULL) { - unload_library(&module); + if (result != ISC_R_SUCCESS && hmod != NULL) { + unload_library(&hmod); } return (result); } void -ns_hookmodule_cleanup(void) { +ns_hookmodule_unload_all(void) { ns_hook_module_t *hmod, *prev; - RUNTIME_CHECK(isc_once_do(&once, init_modules) == ISC_R_SUCCESS); + if (!hook_modules_initialized) { + return; + } hmod = ISC_LIST_TAIL(hook_modules); while (hmod != NULL) { - prev = PREV(hmod, link); - UNLINK(hook_modules, hmod, link); + prev = ISC_LIST_PREV(hmod, link); + ISC_LIST_UNLINK(hook_modules, hmod, link); isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, - "unloading module '%s'", hmod->filename); + "unloading module '%s'", hmod->modpath); hmod->destroy_func(&hmod->inst); ENSURE(hmod->inst == NULL); unload_library(&hmod); @@ -408,8 +422,6 @@ ns_hook_destroyctx(ns_hookctx_t **hctxp) { hctx->magic = 0; - hctx->lctx = NULL; - isc_mem_putanddetach(&hctx->mctx, hctx, sizeof(*hctx)); } @@ -417,9 +429,12 @@ void ns_hooktable_init(ns_hooktable_t *hooktable) { int i; - RUNTIME_CHECK(isc_once_do(&once, init_modules) == ISC_R_SUCCESS); + if (!hook_modules_initialized) { + ISC_LIST_INIT(hook_modules); + hook_modules_initialized = true; + } - for (i = 0; i < NS_QUERY_HOOKS_COUNT; i++) { + for (i = 0; i < NS_HOOKPOINTS_COUNT; i++) { ISC_LIST_INIT((*hooktable)[i]); } } @@ -430,7 +445,7 @@ ns_hooktable_create(isc_mem_t *mctx, ns_hooktable_t **tablep) { REQUIRE(tablep != NULL && *tablep == NULL); - hooktable = isc_mem_get(mctx, sizeof(ns_hooktable_t)); + hooktable = isc_mem_get(mctx, sizeof(*hooktable)); ns_hooktable_init(hooktable); @@ -441,17 +456,20 @@ ns_hooktable_create(isc_mem_t *mctx, ns_hooktable_t **tablep) { void ns_hooktable_free(isc_mem_t *mctx, void **tablep) { + ns_hooktable_t *table; + REQUIRE(tablep != NULL && *tablep != NULL); - isc_mem_put(mctx, *tablep, sizeof(ns_hooktable_t)); + table = *tablep; *tablep = NULL; + isc_mem_put(mctx, table, sizeof(*table)); } void ns_hook_add(ns_hooktable_t *hooktable, ns_hookpoint_t hookpoint, ns_hook_t *hook) { - REQUIRE(hookpoint < NS_QUERY_HOOKS_COUNT); + REQUIRE(hookpoint < NS_HOOKPOINTS_COUNT); REQUIRE(hook != NULL); if (hooktable == NULL) { diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index ea209d6b5f..6d030c3180 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -191,7 +191,7 @@ typedef ISC_LIST(ns_client_t) client_list_t; #define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */ #define NS_CLIENTATTR_WANTNSID 0x00020 /*%< include nameserver ID */ /* Obsolete: NS_CLIENTATTR_FILTER_AAAA 0x00040 */ -/* Obsolete: define NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */ +/* Obsolete: NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */ #define NS_CLIENTATTR_WANTAD 0x00100 /*%< want AD in response if possible */ #define NS_CLIENTATTR_WANTCOOKIE 0x00200 /*%< return a COOKIE */ #define NS_CLIENTATTR_HAVECOOKIE 0x00400 /*%< has a valid COOKIE */ @@ -438,39 +438,39 @@ ns_client_newrdataset(ns_client_t *client); void ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp); -/*% +/*%< * Get and release temporary rdatasets in the client message; * used in query.c and in hook modules. */ isc_result_t ns_client_newnamebuf(ns_client_t *client); -/*% +/*%< * Allocate a name buffer for the client message. */ dns_name_t * ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf); -/*% +/*%< * Get a temporary name for the client message. */ isc_buffer_t * ns_client_getnamebuf(ns_client_t *client); -/*% +/*%< * Get a name buffer from the pool, or allocate a new one if needed. */ void ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf); -/*% +/*%< * Adjust buffer 'dbuf' to reflect that 'name' is using space in it, * and set client attributes appropriately. */ void ns_client_releasename(ns_client_t *client, dns_name_t **namep); -/*% +/*%< * Release 'name' back to the pool of temporary names for the client * message. If it is using a name buffer, relinquish its exclusive * rights on the buffer. @@ -478,20 +478,20 @@ ns_client_releasename(ns_client_t *client, dns_name_t **namep); isc_result_t ns_client_newdbversion(ns_client_t *client, unsigned int n); -/*% +/*%< * Allocate 'n' new database versions for use by client queries. */ ns_dbversion_t * ns_client_getdbversion(ns_client_t *client); -/*% +/*%< * Get a free database version for use by a client query, allocating * a new one if necessary. */ ns_dbversion_t * ns_client_findversion(ns_client_t *client, dns_db_t *db); -/*% +/*%< * Find the correct database version to use with a client query. * If we have already done a query related to the database 'db', * make sure subsequent queries are from the same version; diff --git a/lib/ns/include/ns/hooks.h b/lib/ns/include/ns/hooks.h index 760292f0cc..10c68d2a95 100644 --- a/lib/ns/include/ns/hooks.h +++ b/lib/ns/include/ns/hooks.h @@ -162,7 +162,14 @@ * called this time and foo_bar() will return ISC_R_SUCCESS. */ +/*! + * Currently-defined hook points. So long as these are unique, + * the order in which they are declared is unimportant, but + * currently matches the order in which they are referenced in + * query.c. + */ typedef enum { + /* hookpoints from query.c */ NS_QUERY_QCTX_INITIALIZED, NS_QUERY_QCTX_DESTROYED, NS_QUERY_SETUP, @@ -186,7 +193,9 @@ typedef enum { NS_QUERY_DONE_BEGIN, NS_QUERY_DONE_SEND, - NS_QUERY_HOOKS_COUNT /* MUST BE LAST */ + /* XXX other files could be added later */ + + NS_HOOKPOINTS_COUNT /* MUST BE LAST */ } ns_hookpoint_t; typedef bool @@ -199,16 +208,16 @@ typedef struct ns_hook { } ns_hook_t; typedef ISC_LIST(ns_hook_t) ns_hooklist_t; -typedef ns_hooklist_t ns_hooktable_t[NS_QUERY_HOOKS_COUNT]; +typedef ns_hooklist_t ns_hooktable_t[NS_HOOKPOINTS_COUNT]; -/* +/*% * ns__hook_table is a global hook table, which is used if view->hooktable * is NULL. It's intended only for use by unit tests. */ LIBNS_EXTERNAL_DATA extern ns_hooktable_t *ns__hook_table; /*! - * Context for intializing a hook module. + * Context for initializing a hook module. * * This structure passes data to which a hook module will need * access -- server memory context, hash initializer, log context, etc. @@ -223,7 +232,8 @@ typedef struct ns_hookctx { } ns_hookctx_t; #define NS_HOOKCTX_MAGIC ISC_MAGIC('H', 'k', 'c', 'x') -#define NS_HOOKCTX_VALID(d) ISC_MAGIC_VALID(d, NS_HOOKCTX_MAGIC) +#define NS_HOOKCTX_VALID(h) ISC_MAGIC_VALID(h, NS_HOOKCTX_MAGIC) + /* * API version * @@ -246,7 +256,7 @@ typedef isc_result_t ns_hook_register_t(const unsigned int modid, ns_hookctx_t *hctx, ns_hooktable_t *hooktable, void **instp); -/*% +/*%< * Called when registering a new module. * * 'parameters' contains the module configuration text. @@ -261,43 +271,68 @@ typedef isc_result_t ns_hook_register_t(const unsigned int modid, */ typedef void ns_hook_destroy_t(void **instp); -/*% +/*%< * Destroy a module instance. * * '*instp' must be set to NULL by the function before it returns. */ -typedef int ns_hook_version_t(unsigned int *flags); -/*% +typedef int ns_hook_version_t(void); +/*%< * Return the API version number a hook module was compiled with. * - * If the returned version number is no greater than than + * If the returned version number is no greater than * NS_HOOK_VERSION, and no less than NS_HOOK_VERSION - NS_HOOK_AGE, * then the module is API-compatible with named. - * - * 'flags' is currently unused and may be NULL, but could be used in - * the future to pass back driver capabilities or other information. */ +/*% + * Prototypes for API functions to be defined in each module. + */ +ns_hook_destroy_t hook_destroy; +ns_hook_register_t hook_register; +ns_hook_version_t hook_version; + isc_result_t ns_hook_createctx(isc_mem_t *mctx, ns_hookctx_t **hctxp); void ns_hook_destroyctx(ns_hookctx_t **hctxp); +/*%< + * Create/destroy a hook module context. + */ isc_result_t -ns_hookmodule_load(const char *libname, const unsigned int modid, +ns_hookmodule_load(const char *modpath, const unsigned int modid, const char *parameters, - const char *file, unsigned long line, + const char *cfg_file, unsigned long cfg_line, const void *cfg, void *actx, ns_hookctx_t *hctx, ns_hooktable_t *hooktable); +/*%< + * Load the hook module specified from the file 'modpath', using + * parameters 'parameters'. + * + * 'cfg_file' and 'cfg_line' specify the location of the hook module + * declaration in the configuration file. + * + * 'cfg' and 'actx' are the configuration context and ACL configuration + * context, respectively; they are passed as void * here in order to + * prevent this library from having a dependency on libisccfg). + * + * 'hctx' is the hook context and 'hooktable' is the hook table + * into which hook points should be registered. + */ + void -ns_hookmodule_cleanup(void); +ns_hookmodule_unload_all(void); +/*%< + * Unload all currently loaded hook modules. + */ void ns_hook_add(ns_hooktable_t *hooktable, ns_hookpoint_t hookpoint, ns_hook_t *hook); -/*% +/*%< * Append hook function 'hook' to the list of hooks at 'hookpoint' in * 'hooktable'. * @@ -310,21 +345,20 @@ ns_hook_add(ns_hooktable_t *hooktable, ns_hookpoint_t hookpoint, void ns_hooktable_init(ns_hooktable_t *hooktable); -/*% +/*%< * Initialize a hook table. */ isc_result_t ns_hooktable_create(isc_mem_t *mctx, ns_hooktable_t **tablep); -/*% +/*%< * Allocate and initialize a hook table. */ void ns_hooktable_free(isc_mem_t *mctx, void **tablep); -/*% +/*%< * Free a hook table. */ - #endif /* NS_HOOKS_H */ diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h index 987dfe804d..b3fc3a742c 100644 --- a/lib/ns/include/ns/query.h +++ b/lib/ns/include/ns/query.h @@ -252,13 +252,13 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, isc_result_t ns__query_sfcache(query_ctx_t *qctx); -/*% +/*%< * (Must not be used outside this module and its associated unit tests.) */ isc_result_t ns__query_start(query_ctx_t *qctx); -/*% +/*%< * (Must not be used outside this module and its associated unit tests.) */ diff --git a/lib/ns/query.c b/lib/ns/query.c index 5de1f2b1f2..fd41929ba5 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -264,7 +264,7 @@ get_hooktab(query_ctx_t *qctx) { * is a macro instead of an inline function; it needs to be able to use * 'goto cleanup' regardless of the return value.) */ -#define PROCESS_HOOK(_id, _qctx) \ +#define CALL_HOOK(_id, _qctx) \ do { \ isc_result_t _res; \ ns_hooktable_t *_tab = get_hooktab(_qctx); \ @@ -290,9 +290,9 @@ get_hooktab(query_ctx_t *qctx) { * destruction calls which *must* run in every configured module. * * (This could be implemented as an inline void function, but is left as a - * macro for symmetry with PROCESS_HOOK above.) + * macro for symmetry with CALL_HOOK above.) */ -#define PROCESS_ALL_HOOKS(_id, _qctx) \ +#define CALL_HOOK_NORETURN(_id, _qctx) \ do { \ isc_result_t _res; \ ns_hooktable_t *_tab = get_hooktab(_qctx); \ @@ -1931,22 +1931,22 @@ query_addtoname(dns_name_t *name, dns_rdataset_t *rdataset) { static void query_setorder(query_ctx_t *qctx, dns_name_t *name, dns_rdataset_t *rdataset) { ns_client_t *client = qctx->client; + dns_order_t *order = client->view->order; CTRACE(ISC_LOG_DEBUG(3), "query_setorder"); UNUSED(client); - if (qctx->view->order != NULL) { - rdataset->attributes |= - dns_order_find(qctx->view->order, - name, rdataset->type, - rdataset->rdclass); + if (order != NULL) { + rdataset->attributes |= dns_order_find(order, name, + rdataset->type, + rdataset->rdclass); } rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; }; /* - * Handle glue and fetch any other needed additional data for 'rdataset' + * Handle glue and fetch any other needed additional data for 'rdataset'. */ static void query_additional(query_ctx_t *qctx, dns_rdataset_t *rdataset) { @@ -4855,7 +4855,7 @@ qctx_init(ns_client_t *client, dns_fetchevent_t *event, REQUIRE(qctx != NULL); REQUIRE(client != NULL); - memset(qctx, 0, sizeof(query_ctx_t)); + memset(qctx, 0, sizeof(*qctx)); /* Set this first so CCTRACE will work */ qctx->client = client; @@ -4866,32 +4866,9 @@ qctx_init(ns_client_t *client, dns_fetchevent_t *event, qctx->event = event; qctx->qtype = qctx->type = qtype; qctx->result = ISC_R_SUCCESS; - qctx->fname = NULL; - qctx->zfname = NULL; - qctx->rdataset = NULL; - qctx->zrdataset = NULL; - qctx->sigrdataset = NULL; - qctx->zsigrdataset = NULL; - qctx->zversion = NULL; - qctx->node = NULL; - qctx->znode = NULL; - qctx->db = NULL; - qctx->zdb = NULL; - qctx->version = NULL; - qctx->zone = NULL; - qctx->need_wildcardproof = false; - qctx->redirected = false; - qctx->dns64_exclude = qctx->dns64 = qctx->rpz = false; - qctx->options = 0; - qctx->resuming = false; - qctx->is_zone = false; qctx->findcoveringnsec = qctx->view->synthfromdnssec; - qctx->is_staticstub_zone = false; - qctx->nxrewrite = false; - qctx->answer_has_ns = false; - qctx->authoritative = false; - PROCESS_ALL_HOOKS(NS_QUERY_QCTX_INITIALIZED, qctx); + CALL_HOOK_NORETURN(NS_QUERY_QCTX_INITIALIZED, qctx); } /*% @@ -4956,7 +4933,7 @@ qctx_freedata(query_ctx_t *qctx) { static void qctx_destroy(query_ctx_t *qctx) { - PROCESS_ALL_HOOKS(NS_QUERY_QCTX_DESTROYED, qctx); + CALL_HOOK_NORETURN(NS_QUERY_QCTX_DESTROYED, qctx); dns_view_detach(&qctx->view); } @@ -5011,7 +4988,7 @@ query_setup(ns_client_t *client, dns_rdatatype_t qtype) { qctx_init(client, NULL, qtype, &qctx); query_trace(&qctx); - PROCESS_HOOK(NS_QUERY_SETUP, &qctx); + CALL_HOOK(NS_QUERY_SETUP, &qctx); /* * If it's a SIG query, we'll iterate the node. @@ -5118,7 +5095,7 @@ ns__query_start(query_ctx_t *qctx) { qctx->need_wildcardproof = false; qctx->rpz = false; - PROCESS_HOOK(NS_QUERY_START_BEGIN, qctx); + CALL_HOOK(NS_QUERY_START_BEGIN, qctx); /* * If we require a server cookie then send back BADCOOKIE @@ -5332,7 +5309,7 @@ query_lookup(query_ctx_t *qctx) { CCTRACE(ISC_LOG_DEBUG(3), "query_lookup"); - PROCESS_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx); + CALL_HOOK(NS_QUERY_LOOKUP_BEGIN, qctx); dns_clientinfomethods_init(&cm, ns_client_sourceip); dns_clientinfo_init(&ci, qctx->client, NULL); @@ -5512,7 +5489,7 @@ fetch_callback(isc_task_t *task, isc_event_t *event) { query_ctx_t qctx; /* - * Initalize a new qctx and use it to resume + * Initialize a new qctx and use it to resume * from recursion. */ qctx_init(client, devent, 0, &qctx); @@ -5753,7 +5730,7 @@ query_resume(query_ctx_t *qctx) { char tbuf[DNS_RDATATYPE_FORMATSIZE]; #endif - PROCESS_HOOK(NS_QUERY_RESUME_BEGIN, qctx); + CALL_HOOK(NS_QUERY_RESUME_BEGIN, qctx); qctx->want_restart = false; @@ -6587,7 +6564,7 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t res) { CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer"); - PROCESS_HOOK(NS_QUERY_GOT_ANSWER_BEGIN, qctx); + CALL_HOOK(NS_QUERY_GOT_ANSWER_BEGIN, qctx); if (query_checkrrl(qctx, result) != ISC_R_SUCCESS) { return (ns_query_done(qctx)); @@ -6772,7 +6749,7 @@ query_respond_any(query_ctx_t *qctx) { isc_result_t result; dns_rdatatype_t onetype = 0; /* type to use for minimal-any */ - PROCESS_HOOK(NS_QUERY_RESPOND_ANY_BEGIN, qctx); + CALL_HOOK(NS_QUERY_RESPOND_ANY_BEGIN, qctx); result = dns_db_allrdatasets(qctx->db, qctx->node, qctx->version, 0, &rdsiter); @@ -6925,14 +6902,14 @@ query_respond_any(query_ctx_t *qctx) { } if (found) { - PROCESS_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx); + CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx); if (qctx->fname != NULL) { dns_message_puttempname(qctx->client->message, &qctx->fname); } } else { - PROCESS_HOOK(NS_QUERY_RESPOND_ANY_NOT_FOUND, qctx); + CALL_HOOK(NS_QUERY_RESPOND_ANY_NOT_FOUND, qctx); if (qctx->fname != NULL) { dns_message_puttempname(qctx->client->message, @@ -7112,7 +7089,7 @@ query_respond(query_ctx_t *qctx) { * other way to prevent that assertion, since the order in * which hook modules are configured can't be enforced.) */ - PROCESS_HOOK(NS_QUERY_RESPOND_BEGIN, qctx); + CALL_HOOK(NS_QUERY_RESPOND_BEGIN, qctx); if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) { sigrdatasetp = &qctx->sigrdataset; @@ -7555,7 +7532,7 @@ static isc_result_t query_notfound(query_ctx_t *qctx) { isc_result_t result; - PROCESS_HOOK(NS_QUERY_NOTFOUND_BEGIN, qctx); + CALL_HOOK(NS_QUERY_NOTFOUND_BEGIN, qctx); INSIST(!qctx->is_zone); @@ -7637,7 +7614,7 @@ query_prepare_delegation_response(query_ctx_t *qctx) { dns_rdataset_t **sigrdatasetp = NULL; bool detach = false; - PROCESS_HOOK(NS_QUERY_PREP_DELEGATION_BEGIN, qctx); + CALL_HOOK(NS_QUERY_PREP_DELEGATION_BEGIN, qctx); /* * qctx->fname could be released in query_addrrset(), so save a copy of @@ -7691,7 +7668,7 @@ static isc_result_t query_zone_delegation(query_ctx_t *qctx) { isc_result_t result; - PROCESS_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx); + CALL_HOOK(NS_QUERY_ZONE_DELEGATION_BEGIN, qctx); /* * If the query type is DS, look to see if we are @@ -7789,7 +7766,7 @@ static isc_result_t query_delegation(query_ctx_t *qctx) { isc_result_t result; - PROCESS_HOOK(NS_QUERY_DELEGATION_BEGIN, qctx); + CALL_HOOK(NS_QUERY_DELEGATION_BEGIN, qctx); qctx->authoritative = false; @@ -8046,7 +8023,7 @@ static isc_result_t query_nodata(query_ctx_t *qctx, isc_result_t res) { isc_result_t result = res; - PROCESS_HOOK(NS_QUERY_NODATA_BEGIN, qctx); + CALL_HOOK(NS_QUERY_NODATA_BEGIN, qctx); #ifdef dns64_bis_return_excluded_addresses if (qctx->dns64) @@ -8363,7 +8340,7 @@ query_nxdomain(query_ctx_t *qctx, bool empty_wild) { uint32_t ttl; isc_result_t result; - PROCESS_HOOK(NS_QUERY_NXDOMAIN_BEGIN, qctx); + CALL_HOOK(NS_QUERY_NXDOMAIN_BEGIN, qctx); INSIST(qctx->is_zone || REDIRECT(qctx->client)); @@ -9259,7 +9236,7 @@ query_cname(query_ctx_t *qctx) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; - PROCESS_HOOK(NS_QUERY_CNAME_BEGIN, qctx); + CALL_HOOK(NS_QUERY_CNAME_BEGIN, qctx); /* * If we have a zero ttl from the cache refetch it. @@ -9392,7 +9369,7 @@ query_dname(query_ctx_t *qctx) { isc_result_t result; unsigned int nlabels; - PROCESS_HOOK(NS_QUERY_DNAME_BEGIN, qctx); + CALL_HOOK(NS_QUERY_DNAME_BEGIN, qctx); /* * Compare the current qname to the found name. We need @@ -9605,9 +9582,9 @@ query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) { */ static isc_result_t query_prepresponse(query_ctx_t *qctx) { - isc_result_t result = ISC_R_SUCCESS; + isc_result_t result; - PROCESS_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx); + CALL_HOOK(NS_QUERY_PREP_RESPONSE_BEGIN, qctx); if (WANTDNSSEC(qctx->client) && (qctx->fname->attributes & DNS_NAMEATTR_WILDCARD) != 0) @@ -10500,7 +10477,7 @@ ns_query_done(query_ctx_t *qctx) { CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done"); - PROCESS_HOOK(NS_QUERY_DONE_BEGIN, qctx); + CALL_HOOK(NS_QUERY_DONE_BEGIN, qctx); /* * General cleanup. @@ -10595,7 +10572,7 @@ ns_query_done(query_ctx_t *qctx) { qctx->result = ISC_R_FAILURE; } - PROCESS_HOOK(NS_QUERY_DONE_SEND, qctx); + CALL_HOOK(NS_QUERY_DONE_SEND, qctx); query_send(qctx->client); diff --git a/lib/ns/win32/libns.def b/lib/ns/win32/libns.def index ab5efa25dd..e870f859f1 100644 --- a/lib/ns/win32/libns.def +++ b/lib/ns/win32/libns.def @@ -46,8 +46,8 @@ ns_clientmgr_destroy ns_hook_add ns_hook_createctx ns_hook_destroyctx -ns_hookmodule_cleanup ns_hookmodule_load +ns_hookmodule_unload_all ns_hooktable_create ns_hooktable_free ns_hooktable_init