mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 04:02:04 -04:00
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
This commit is contained in:
parent
055bf2665c
commit
427e9ca357
23 changed files with 340 additions and 267 deletions
|
|
@ -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@
|
||||
|
||||
|
|
|
|||
|
|
@ -13,29 +13,45 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/lib.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <isccfg/aclconf.h>
|
||||
#include <isccfg/cfg.h>
|
||||
#include <isccfg/grammar.h>
|
||||
#include <isccfg/namedconf.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
#include <dns/result.h>
|
||||
|
||||
#include <ns/client.h>
|
||||
#include <ns/hooks.h>
|
||||
#include <ns/log.h>
|
||||
#include <ns/query.h>
|
||||
#include <ns/types.h>
|
||||
|
||||
#define CHECK(r) \
|
||||
do { \
|
||||
result = (r); \
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
#include <dns/acl.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/enumtype.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
to omit some IPv6 addresses when responding to clients.
|
||||
</para>
|
||||
<para>
|
||||
Until BIND 9.12, this feature was impleented natively in
|
||||
Until BIND 9.12, this feature was implemented natively in
|
||||
<command>named</command> and enabled with the
|
||||
<command>filter-aaaa</command> ACL and the
|
||||
<command>filter-aaaa-on-v4</command> and
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'"
|
||||
|
|
|
|||
|
|
@ -38,3 +38,5 @@ controls {
|
|||
};
|
||||
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
|
|||
|
|
@ -38,3 +38,5 @@ controls {
|
|||
};
|
||||
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
|
|||
|
|
@ -38,3 +38,5 @@ controls {
|
|||
};
|
||||
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
|
|||
|
|
@ -38,3 +38,5 @@ controls {
|
|||
};
|
||||
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
|
|||
|
|
@ -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'"
|
||||
|
|
|
|||
|
|
@ -43,3 +43,5 @@ controls {
|
|||
};
|
||||
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
include "trusted.conf";
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
182
lib/ns/hooks.c
182
lib/ns/hooks.c
|
|
@ -21,33 +21,40 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <isc/list.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
#include <ns/hooks.h>
|
||||
#include <ns/log.h>
|
||||
#include <ns/query.h>
|
||||
|
||||
#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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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.)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue