#include <isc/result.h>
#include <isc/util.h>
+#include <isccfg/aclconf.h>
+#include <isccfg/grammar.h>
+#include <isccfg/namedconf.h>
+
#include <dns/result.h>
#include <dns/view.h>
#include <ns/log.h>
#include <ns/query.h>
+#define CHECK(r) \
+ do { \
+ result = (r); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
ns_hook_destroy_t hook_destroy;
ns_hook_register_t hook_register;
ns_hook_version_t hook_version;
.callback = filter_query_done_send,
};
+/*
+ * Configuration support.
+ */
+
+static dns_aaaa_t v4_aaaa;
+static dns_aaaa_t v6_aaaa;
+static dns_acl_t *aaaa_acl = NULL;
+
+static const char *filter_aaaa_enums[] = { "break-dnssec", NULL };
+static isc_result_t
+parse_filter_aaaa(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+}
+static void
+doc_filter_aaaa(cfg_printer_t *pctx, const cfg_type_t *type) {
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
+}
+static cfg_type_t cfg_type_filter_aaaa = {
+ "filter_aaaa", parse_filter_aaaa, cfg_print_ustring,
+ doc_filter_aaaa, &cfg_rep_string, filter_aaaa_enums,
+};
+
+static cfg_clausedef_t param_clauses[] = {
+ { "filter-aaaa", &cfg_type_bracketed_aml, 0 },
+ { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 },
+ { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 },
+};
+
+static cfg_clausedef_t *param_clausesets[] = {
+ param_clauses,
+ NULL
+};
+
+static cfg_type_t cfg_type_parameters = {
+ "filter-aaaa-params", cfg_parse_mapbody, cfg_print_mapbody,
+ cfg_doc_mapbody, &cfg_rep_map, param_clausesets
+};
+
+static isc_result_t
+parse_filter_aaaa_on(const cfg_obj_t *param_obj, const char *param_name,
+ dns_aaaa_t *dstp)
+{
+ const cfg_obj_t *obj = NULL;
+ isc_result_t result;
+
+ result = cfg_map_get(param_obj, param_name, &obj);
+ if (result != ISC_R_SUCCESS) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj)) {
+ *dstp = dns_aaaa_filter;
+ } else {
+ *dstp = dns_aaaa_ok;
+ }
+ } else if (strcasecmp(cfg_obj_asstring(obj), "break-dnssec") == 0) {
+ *dstp = dns_aaaa_break_dnssec;
+ } else {
+ result = ISC_R_UNEXPECTED;
+ }
+
+ return (result);
+}
+
+static isc_result_t
+parse_parameters(const char *parameters, const void *cfg,
+ void *actx, ns_hookctx_t *hctx)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ cfg_parser_t *parser = NULL;
+ cfg_obj_t *param_obj = NULL;
+ const cfg_obj_t *obj = NULL;
+ isc_buffer_t b;
+
+ CHECK(cfg_parser_create(hctx->mctx, hctx->lctx, &parser));
+
+ isc_buffer_constinit(&b, parameters, strlen(parameters));
+ isc_buffer_add(&b, strlen(parameters));
+ CHECK(cfg_parse_buffer(parser, &b, &cfg_type_parameters,
+ ¶m_obj));
+
+ CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4", &v4_aaaa));
+ CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v6", &v6_aaaa));
+
+ obj = NULL;
+ result = cfg_map_get(param_obj, "filter-aaaa", &obj);
+ if (result == ISC_R_SUCCESS) {
+ CHECK(cfg_acl_fromconfig(obj, (const cfg_obj_t *) cfg,
+ hctx->lctx,
+ (cfg_aclconfctx_t *) actx,
+ hctx->mctx, 0, &aaaa_acl));
+ } else {
+ CHECK(dns_acl_any(hctx->mctx, &aaaa_acl));
+ }
+
+ cleanup:
+ if (param_obj != NULL) {
+ cfg_obj_destroy(parser, ¶m_obj);
+ }
+ if (parser != NULL) {
+ cfg_parser_destroy(&parser);
+ }
+ return (result);
+}
+
+/*
+ * Mandatory hook API functions.
+ */
isc_result_t
hook_register(const char *parameters, const char *file, unsigned long line,
- ns_hookctx_t *hctx, ns_hooktable_t *hooktable, void **instp)
+ const void *cfg, void *actx, ns_hookctx_t *hctx,
+ ns_hooktable_t *hooktable, void **instp)
{
- UNUSED(parameters);
UNUSED(instp);
if (parameters != NULL) {
"loading params for 'filter-aaaa' "
"module from %s:%lu",
file, line);
+
+ parse_parameters(parameters, cfg, actx, hctx);
} else {
isc_log_write(hctx->lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_HOOKS, ISC_LOG_INFO,
file, line);
}
- /*
- * TODO:
- * configure with parameters here
- */
-
ns_hook_add(hooktable, NS_QUERY_RESPOND_BEGIN,
&filter_respbegin);
ns_hook_add(hooktable, NS_QUERY_RESPOND_ANY_FOUND,
hook_destroy(void **instp) {
UNUSED(instp);
+ if (aaaa_acl != NULL) {
+ dns_acl_detach(&aaaa_acl);
+ }
+
return;
}
UNUSED(cbdata);
qctx->filter_aaaa = dns_aaaa_ok;
- if (qctx->client->view->v4_aaaa != dns_aaaa_ok ||
- qctx->client->view->v6_aaaa != dns_aaaa_ok)
- {
+ if (v4_aaaa != dns_aaaa_ok || v6_aaaa != dns_aaaa_ok) {
result = ns_client_checkaclsilent(qctx->client, NULL,
- qctx->client->view->aaaa_acl,
- true);
+ aaaa_acl, true);
if (result == ISC_R_SUCCESS &&
- qctx->client->view->v4_aaaa != dns_aaaa_ok &&
+ v4_aaaa != dns_aaaa_ok &&
is_v4_client(qctx->client))
{
- qctx->filter_aaaa = qctx->client->view->v4_aaaa;
+ qctx->filter_aaaa = v4_aaaa;
} else if (result == ISC_R_SUCCESS &&
- qctx->client->view->v6_aaaa != dns_aaaa_ok &&
+ v6_aaaa != dns_aaaa_ok &&
is_v6_client(qctx->client))
{
- qctx->filter_aaaa = qctx->client->view->v6_aaaa;
+ qctx->filter_aaaa = v6_aaaa;
}
}
# fetch-glue <obsolete>;\n\
fetch-quota-params 100 0.1 0.3 0.7;\n\
fetches-per-server 0;\n\
- fetches-per-zone 0;\n\
- filter-aaaa-on-v4 no;\n\
- filter-aaaa-on-v6 no;\n\
- filter-aaaa { any; };\n"
+ fetches-per-zone 0;\n"
#ifdef HAVE_GEOIP
" geoip-use-ecs yes;\n"
#endif
static isc_result_t
configure_hook(ns_hooktable_t *hooktable, const cfg_obj_t *hook,
- ns_hookctx_t *hctx)
+ const cfg_obj_t *config, ns_hookctx_t *hctx)
{
isc_result_t result = ISC_R_SUCCESS;
const cfg_obj_t *obj;
cfg_obj_asstring(obj),
cfg_obj_file(obj),
cfg_obj_line(obj),
+ config,
+ named_g_aclconfctx,
hctx, hooktable);
} else {
result = ns_hookmodule_load(library, NULL,
cfg_obj_file(hook),
cfg_obj_line(hook),
+ config,
+ named_g_aclconfctx,
hctx, hooktable);
}
dns_quotatype_zone, r);
}
- obj = NULL;
- result = named_config_get(maps, "filter-aaaa-on-v4", &obj);
- INSIST(result == ISC_R_SUCCESS);
- if (cfg_obj_isboolean(obj)) {
- if (cfg_obj_asboolean(obj))
- view->v4_aaaa = dns_aaaa_filter;
- else
- view->v4_aaaa = dns_aaaa_ok;
- } else {
- const char *v4_aaaastr = cfg_obj_asstring(obj);
- if (strcasecmp(v4_aaaastr, "break-dnssec") == 0) {
- view->v4_aaaa = dns_aaaa_break_dnssec;
- } else {
- INSIST(0);
- ISC_UNREACHABLE();
- }
- }
-
- obj = NULL;
- result = named_config_get(maps, "filter-aaaa-on-v6", &obj);
- INSIST(result == ISC_R_SUCCESS);
- if (cfg_obj_isboolean(obj)) {
- if (cfg_obj_asboolean(obj))
- view->v6_aaaa = dns_aaaa_filter;
- else
- view->v6_aaaa = dns_aaaa_ok;
- } else {
- const char *v6_aaaastr = cfg_obj_asstring(obj);
- if (strcasecmp(v6_aaaastr, "break-dnssec") == 0) {
- view->v6_aaaa = dns_aaaa_break_dnssec;
- } else {
- INSIST(0);
- ISC_UNREACHABLE();
- }
- }
-
- CHECK(configure_view_acl(vconfig, config, named_g_config,
- "filter-aaaa", NULL, actx,
- named_g_mctx, &view->aaaa_acl));
-
obj = NULL;
result = named_config_get(maps, "prefetch", &obj);
if (result == ISC_R_SUCCESS) {
CHECK(ns_hook_createctx(mctx, &hctx));
}
- CHECK(configure_hook(view->hooktable, hook, hctx));
+ CHECK(configure_hook(view->hooktable, hook, config, hctx));
}
#endif
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 yes;
- filter-aaaa { none; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- /*
- * While this matches the defaults, it is not a good configuration
- * to have in named.conf as the two options contradict each other
- * indicating a error on behalf of the operator.
- *
- * The default is to have filter-aaaa-on-v4 off, but if it is turned
- * on then it applies to all IPv4 queries. This results in
- * contradictory defaults.
- */
- filter-aaaa-on-v4 no;
- filter-aaaa { any; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 no;
-};
-
-view myview {
- filter-aaaa { any; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa { any; };
-};
-
-view myview {
- filter-aaaa-on-v4 no;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa { none; };
-};
-
-view myview {
- filter-aaaa-on-v4 yes;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 yes;
-};
-
-view myview {
- filter-aaaa { none; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 yes;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 break-dnssec;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 break-dnssec;
- filter-aaaa { 1.0.0.0/8; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 yes;
- filter-aaaa { 1.0.0.0/8; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 yes;
-};
-
-view myview {
- filter-aaaa { 1.0.0.0/8; };
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa { 1.0.0.0/8; };
-};
-
-view myview {
- filter-aaaa-on-v4 yes;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
-};
-
-view myview {
- filter-aaaa { 1.0.0.0/8; };
- filter-aaaa-on-v4 yes;
-};
+++ /dev/null
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-options {
- filter-aaaa-on-v4 no;
-};
-
-view myview {
- filter-aaaa { 1.0.0.0/8; };
- filter-aaaa-on-v4 yes;
-};
recursion no;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v4 yes;
- filter-aaaa { 10.53.0.1; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+acl filterees { 10.53.0.1; };
+
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v4 yes;
+ filter-aaaa { filterees; };
+};
key rndc_key {
secret "1234abcd8765";
recursion no;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v6 yes;
- filter-aaaa { fd92:7065:b8e:ffff::1; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v6 yes;
+ filter-aaaa { fd92:7065:b8e:ffff::1; };
+};
key rndc_key {
secret "1234abcd8765";
recursion yes;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v4 yes;
- filter-aaaa { 10.53.0.2; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v4 yes;
+ filter-aaaa { 10.53.0.2; };
+};
key rndc_key {
secret "1234abcd8765";
recursion yes;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v6 yes;
- filter-aaaa { fd92:7065:b8e:ffff::2; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v6 yes;
+ filter-aaaa { fd92:7065:b8e:ffff::2; };
+};
key rndc_key {
secret "1234abcd8765";
recursion yes;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v4 break-dnssec;
- filter-aaaa { 10.53.0.3; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v4 break-dnssec;
+ filter-aaaa { 10.53.0.3; };
+};
key rndc_key {
secret "1234abcd8765";
recursion yes;
dnssec-validation yes;
notify yes;
- filter-aaaa-on-v6 break-dnssec;
- filter-aaaa { fd92:7065:b8e:ffff::3; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v6 break-dnssec;
+ filter-aaaa { fd92:7065:b8e:ffff::3; };
+};
key rndc_key {
secret "1234abcd8765";
recursion no;
dnssec-validation no;
notify yes;
- filter-aaaa-on-v4 break-dnssec;
- filter-aaaa { 10.53.0.4; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v4 break-dnssec;
+ filter-aaaa { 10.53.0.4; };
+};
key rndc_key {
secret "1234abcd8765";
recursion no;
dnssec-validation no;
notify yes;
- filter-aaaa-on-v6 break-dnssec;
- filter-aaaa { fd92:7065:b8e:ffff::4; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v6 break-dnssec;
+ filter-aaaa { fd92:7065:b8e:ffff::4; };
+};
key rndc_key {
secret "1234abcd8765";
exclude { any; };
mapped { any; };
};
- filter-aaaa-on-v4 break-dnssec;
- filter-aaaa { any; };
minimal-responses no;
};
-hook query "../../../../hooks/lib/filter-aaaa.so";
+hook query "../../../../hooks/lib/filter-aaaa.so" {
+ filter-aaaa-on-v4 break-dnssec;
+ filter-aaaa { any; };
+};
key rndc_key {
secret "1234abcd8765";
DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p ${PORT}"
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
-for conf in conf/good*.conf
-do
- n=`expr $n + 1`
- echo_i "checking that $conf is accepted ($n)"
- ret=0
- $CHECKCONF "$conf" || ret=1
- if [ $ret != 0 ]; then echo_i "failed"; fi
- status=`expr $status + $ret`
-done
-
-for conf in conf/bad*.conf
-do
- n=`expr $n + 1`
- echo_i "checking that $conf is rejected ($n)"
- ret=0
- $CHECKCONF "$conf" >/dev/null && ret=1
- if [ $ret != 0 ]; then echo_i "failed"; fi
- status=`expr $status + $ret`
-done
-
#
# Authoritative tests against:
# filter-aaaa-on-v4 yes;
static const char *acls[] = { "allow-query", "allow-query-on",
"allow-query-cache", "allow-query-cache-on",
"blackhole", "keep-response-order", "match-clients",
- "match-destinations", "sortlist", "filter-aaaa", NULL };
+ "match-destinations", "sortlist", NULL };
while (acls[i] != NULL) {
tresult = checkacl(acls[i++], actx, NULL, voptions, config,
return (result);
}
-static isc_result_t
-check_filteraaaa(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
- const char *viewname, const cfg_obj_t *config,
- isc_log_t *logctx, isc_mem_t *mctx)
-{
- const cfg_obj_t *options, *aclobj, *obj;
- dns_acl_t *acl = NULL;
- isc_result_t result = ISC_R_SUCCESS;
- dns_aaaa_t filter4, filter6;
- const char *forview = " for view ";
-
- if (viewname == NULL) {
- viewname = "";
- forview = "";
- }
-
- aclobj = options = NULL;
- acl = NULL;
-
- if (voptions != NULL)
- cfg_map_get(voptions, "filter-aaaa", &aclobj);
- if (config != NULL && aclobj == NULL) {
- options = NULL;
- cfg_map_get(config, "options", &options);
- if (options != NULL)
- cfg_map_get(options, "filter-aaaa", &aclobj);
- }
- if (aclobj == NULL)
- return (result);
-
- result = cfg_acl_fromconfig(aclobj, config, logctx,
- actx, mctx, 0, &acl);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- obj = NULL;
- if (voptions != NULL)
- cfg_map_get(voptions, "filter-aaaa-on-v4", &obj);
- if (obj == NULL && config != NULL) {
- options = NULL;
- cfg_map_get(config, "options", &options);
- if (options != NULL)
- cfg_map_get(options, "filter-aaaa-on-v4", &obj);
- }
-
- if (obj == NULL)
- filter4 = dns_aaaa_ok; /* default */
- else if (cfg_obj_isboolean(obj))
- filter4 = cfg_obj_asboolean(obj) ? dns_aaaa_filter :
- dns_aaaa_ok;
- else
- filter4 = dns_aaaa_break_dnssec; /* break-dnssec */
-
- obj = NULL;
- if (voptions != NULL)
- cfg_map_get(voptions, "filter-aaaa-on-v6", &obj);
- if (obj == NULL && config != NULL) {
- options = NULL;
- cfg_map_get(config, "options", &options);
- if (options != NULL)
- cfg_map_get(options, "filter-aaaa-on-v6", &obj);
- }
-
- if (obj == NULL)
- filter6 = dns_aaaa_ok; /* default */
- else if (cfg_obj_isboolean(obj))
- filter6 = cfg_obj_asboolean(obj) ? dns_aaaa_filter :
- dns_aaaa_ok;
- else
- filter6 = dns_aaaa_break_dnssec; /* break-dnssec */
-
- if ((filter4 != dns_aaaa_ok || filter6 != dns_aaaa_ok) &&
- dns_acl_isnone(acl))
- {
- cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
- "\"filter-aaaa\" is 'none;' but "
- "either filter-aaaa-on-v4 or filter-aaaa-on-v6 "
- "is enabled%s%s", forview, viewname);
- result = ISC_R_FAILURE;
- } else if (filter4 == dns_aaaa_ok && filter6 == dns_aaaa_ok &&
- !dns_acl_isnone(acl))
- {
- cfg_obj_log(aclobj, logctx, ISC_LOG_WARNING,
- "\"filter-aaaa\" is set but "
- "neither filter-aaaa-on-v4 or filter-aaaa-on-v6 "
- "is enabled%s%s", forview, viewname);
- result = ISC_R_FAILURE;
- }
-
- failure:
- if (acl != NULL)
- dns_acl_detach(&acl);
-
- return (result);
-}
-
typedef struct {
const char *name;
unsigned int scale;
if (tresult != ISC_R_SUCCESS)
result = tresult;
- tresult = check_filteraaaa(actx, voptions, viewname, config,
- logctx, mctx);
- if (tresult != ISC_R_SUCCESS)
- result = tresult;
-
tresult = check_dns64(actx, voptions, config, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
uint16_t padding;
dns_acl_t * pad_acl;
unsigned int maxbits;
- dns_aaaa_t v4_aaaa;
- dns_aaaa_t v6_aaaa;
- dns_acl_t * aaaa_acl;
dns_dns64list_t dns64;
unsigned int dns64cnt;
dns_rpz_zones_t *rpzs;
view->padding = 0;
view->pad_acl = NULL;
view->maxbits = 0;
- view->v4_aaaa = dns_aaaa_ok;
- view->v6_aaaa = dns_aaaa_ok;
- view->aaaa_acl = NULL;
view->rpzs = NULL;
view->catzs = NULL;
dns_fixedname_init(&view->dlv_fixed);
dns_acl_detach(&view->upfwdacl);
if (view->denyansweracl != NULL)
dns_acl_detach(&view->denyansweracl);
- if (view->aaaa_acl != NULL)
- dns_acl_detach(&view->aaaa_acl);
if (view->pad_acl != NULL)
dns_acl_detach(&view->pad_acl);
if (view->answeracl_exclude != NULL)
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_aml;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_bracketed_text;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_optional_bracketed_text;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr;
void
cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type);
+isc_result_t
+cfg_parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype, cfg_obj_t **ret);
+
+void
+cfg_doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype);
+
void
cfg_print_chars(cfg_printer_t *pctx, const char *text, int len);
/*%< Print 'len' characters at 'text' */
* Forward declarations of static functions.
*/
-static isc_result_t
-parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
- const cfg_type_t *othertype, cfg_obj_t **ret);
-
-static void
-doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
- const cfg_type_t *othertype);
-
static isc_result_t
parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
#endif /* HAVE_GEOIP */
static cfg_type_t cfg_type_acl;
-static cfg_type_t cfg_type_addrmatchelt;
-static cfg_type_t cfg_type_bracketed_aml;
static cfg_type_t cfg_type_bracketed_dscpsockaddrlist;
static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
static cfg_type_t cfg_type_bracketed_netaddrlist;
static cfg_type_t cfg_type_dnstap;
static cfg_type_t cfg_type_dnstapoutput;
static cfg_type_t cfg_type_dyndb;
-static cfg_type_t cfg_type_filter_aaaa;
static cfg_type_t cfg_type_hook;
static cfg_type_t cfg_type_ixfrdifftype;
static cfg_type_t cfg_type_key;
static cfg_type_t cfg_type_maxttl;
static cfg_type_t cfg_type_minimal;
static cfg_type_t cfg_type_nameportiplist;
-static cfg_type_t cfg_type_negated;
static cfg_type_t cfg_type_notifytype;
static cfg_type_t cfg_type_optional_allow;
static cfg_type_t cfg_type_optional_class;
static const char *zonestat_enums[] = { "full", "terse", "none", NULL };
static isc_result_t
parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_zonestat(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_zonestat = {
"zonestat", parse_zonestat, cfg_print_ustring, doc_zonestat,
parse_optional_enum(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_void, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_void, ret));
}
static void
{ "fetch-quota-params", &cfg_type_fetchquota, 0 },
{ "fetches-per-server", &cfg_type_fetchesper, 0 },
{ "fetches-per-zone", &cfg_type_fetchesper, 0 },
- { "filter-aaaa", &cfg_type_bracketed_aml, 0 },
- { "filter-aaaa-on-v4", &cfg_type_filter_aaaa, 0 },
- { "filter-aaaa-on-v6", &cfg_type_filter_aaaa, 0 },
+ { "filter-aaaa", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_OBSOLETE },
+ { "filter-aaaa-on-v4", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
+ { "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "glue-cache", &cfg_type_boolean, 0 },
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
{ "lame-ttl", &cfg_type_ttlval, 0 },
};
static isc_result_t
parse_printtime(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_printtime(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_printtime = {
"printtime", parse_printtime, cfg_print_ustring, doc_printtime,
static isc_result_t
parse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret));
}
static void
doc_size(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_sizeval);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_sizeval);
}
static const char *size_enums[] = { "default", "unlimited", NULL };
parse_size_or_percent(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_sizeval_percent,
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_sizeval_percent,
ret));
}
static void
doc_parse_size_or_percent(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_sizeval_percent);
+ UNUSED(type);
+ cfg_print_cstr(pctx, "( default | unlimited | ");
+ cfg_doc_terminal(pctx, &cfg_type_sizeval);
+ cfg_print_cstr(pctx, " | ");
+ cfg_doc_terminal(pctx, &cfg_type_percentage);
+ cfg_print_cstr(pctx, " )");
}
static const char *sizeorpercent_enums[] = { "default", "unlimited", NULL };
return (result);
}
-static isc_result_t
-parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
- const cfg_type_t *othertype, cfg_obj_t **ret)
-{
- isc_result_t result;
- CHECK(cfg_peektoken(pctx, 0));
- if (pctx->token.type == isc_tokentype_string &&
- cfg_is_enum(TOKEN_STRING(pctx), enumtype->of)) {
- CHECK(cfg_parse_enum(pctx, enumtype, ret));
- } else {
- CHECK(cfg_parse_obj(pctx, othertype, ret));
- }
- cleanup:
- return (result);
-}
-
-static void
-doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
- const cfg_type_t *othertype)
-{
- const char * const *p;
- bool first = true;
-
- /*
- * If othertype is cfg_type_void, it means that enumtype is
- * optional.
- */
-
- if (othertype == &cfg_type_void)
- cfg_print_cstr(pctx, "[ ");
- cfg_print_cstr(pctx, "( ");
- for (p = enumtype->of; *p != NULL; p++) {
- if (!first)
- cfg_print_cstr(pctx, " | ");
- first = false;
- cfg_print_cstr(pctx, *p);
- }
- if (othertype == &cfg_type_sizeval_percent) {
- if (!first)
- cfg_print_cstr(pctx, " | ");
- cfg_doc_terminal(pctx, &cfg_type_sizeval);
- cfg_print_cstr(pctx, " | ");
- cfg_doc_terminal(pctx, &cfg_type_percentage);
- } else if (othertype != &cfg_type_void) {
- if (!first)
- cfg_print_cstr(pctx, " | ");
- cfg_doc_terminal(pctx, othertype);
- }
- cfg_print_cstr(pctx, " )");
- if (othertype == &cfg_type_void)
- cfg_print_cstr(pctx, " ]");
-}
-
static isc_result_t
parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
return (parse_maybe_optional_keyvalue(pctx, type, false, ret));
parse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_dialup_type(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_dialuptype = {
"dialuptype", parse_dialup_type, cfg_print_ustring, doc_dialup_type,
parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_notify_type(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_notifytype = {
"notifytype", parse_notify_type, cfg_print_ustring, doc_notify_type,
static const char *minimal_enums[] = { "no-auth", "no-auth-recursive", NULL };
static isc_result_t
parse_minimal(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_minimal(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_minimal = {
"mimimal", parse_minimal, cfg_print_ustring, doc_minimal,
parse_ixfrdiff_type(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
}
static void
doc_ixfrdiff_type(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
}
static cfg_type_t cfg_type_ixfrdifftype = {
"ixfrdiff", parse_ixfrdiff_type, cfg_print_ustring, doc_ixfrdiff_type,
&cfg_rep_string, ixfrdiff_enums,
};
-static const char *filter_aaaa_enums[] = { "break-dnssec", NULL };
-static isc_result_t
-parse_filter_aaaa(cfg_parser_t *pctx, const cfg_type_t *type,
- cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));
-}
-static void
-doc_filter_aaaa(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_boolean);
-}
-static cfg_type_t cfg_type_filter_aaaa = {
- "filter_aaaa", parse_filter_aaaa, cfg_print_ustring,
- doc_filter_aaaa, &cfg_rep_string, filter_aaaa_enums,
-};
-
static keyword_type_t key_kw = { "key", &cfg_type_astring };
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = {
"querysource", NULL, print_querysource, NULL, &cfg_rep_sockaddr, NULL
};
-/*% addrmatchelt */
-
-static isc_result_t
-parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type,
- cfg_obj_t **ret)
-{
- isc_result_t result;
- UNUSED(type);
-
- CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
-
- if (pctx->token.type == isc_tokentype_string ||
- pctx->token.type == isc_tokentype_qstring) {
- if (pctx->token.type == isc_tokentype_string &&
- (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) {
- CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret));
- } else if (pctx->token.type == isc_tokentype_string &&
- (strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) {
-#ifdef HAVE_GEOIP
- CHECK(cfg_gettoken(pctx, 0));
- CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret));
-#else
- cfg_parser_error(pctx, CFG_LOG_NEAR, "'geoip' "
- "not supported in this build");
- return (ISC_R_UNEXPECTEDTOKEN);
-#endif
- } else {
- if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK |
- CFG_ADDR_V4PREFIXOK |
- CFG_ADDR_V6OK))
- {
- CHECK(cfg_parse_netprefix(pctx, NULL, ret));
- } else {
- CHECK(cfg_parse_astring(pctx, NULL, ret));
- }
- }
- } else if (pctx->token.type == isc_tokentype_special) {
- if (pctx->token.value.as_char == '{') {
- /* Nested match list. */
- CHECK(cfg_parse_obj(pctx,
- &cfg_type_bracketed_aml, ret));
- } else if (pctx->token.value.as_char == '!') {
- CHECK(cfg_gettoken(pctx, 0)); /* read "!" */
- CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret));
- } else {
- goto bad;
- }
- } else {
- bad:
- cfg_parser_error(pctx, CFG_LOG_NEAR,
- "expected IP match list element");
- return (ISC_R_UNEXPECTEDTOKEN);
- }
- cleanup:
- return (result);
-}
-
-/*%
- * A negated address match list element (like "! 10.0.0.1").
- * Somewhat sneakily, the caller is expected to parse the
- * "!", but not to print it.
- */
-
-static cfg_tuplefielddef_t negated_fields[] = {
- { "negated", &cfg_type_addrmatchelt, 0 },
- { NULL, NULL, 0 }
-};
-
-static void
-print_negated(cfg_printer_t *pctx, const cfg_obj_t *obj) {
- cfg_print_cstr(pctx, "!");
- cfg_print_tuple(pctx, obj);
-}
-
-static cfg_type_t cfg_type_negated = {
- "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple,
- &negated_fields
-};
-
-/*% An address match list element */
-
-static cfg_type_t cfg_type_addrmatchelt = {
- "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal,
- NULL, NULL
-};
-
-/*% A bracketed address match list */
-
-static 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
-};
-
/*%
* The socket address syntax in the "controls" statement is silly.
* It allows both socket address families, but also allows "*",
parse_logversions(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
- return (parse_enum_or_other(pctx, type, &cfg_type_uint32, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_uint32, ret));
}
static void
doc_logversions(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_uint32);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_uint32);
}
static cfg_type_t cfg_type_logversions = {
static isc_result_t
parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (parse_enum_or_other(pctx, type, &cfg_type_ttlval, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_ttlval, ret));
}
static void
doc_maxttl(cfg_printer_t *pctx, const cfg_type_t *type) {
- doc_enum_or_other(pctx, type, &cfg_type_ttlval);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_ttlval);
}
/*%
cfg_print_cstr(pctx, " )");
}
+isc_result_t
+cfg_parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype, cfg_obj_t **ret)
+{
+ isc_result_t result;
+ CHECK(cfg_peektoken(pctx, 0));
+ if (pctx->token.type == isc_tokentype_string &&
+ cfg_is_enum(TOKEN_STRING(pctx), enumtype->of))
+ {
+ CHECK(cfg_parse_enum(pctx, enumtype, ret));
+ } else {
+ CHECK(cfg_parse_obj(pctx, othertype, ret));
+ }
+ cleanup:
+ return (result);
+}
+
+void
+cfg_doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *enumtype,
+ const cfg_type_t *othertype)
+{
+ const char * const *p;
+ bool first = true;
+
+ /*
+ * If othertype is cfg_type_void, it means that enumtype is
+ * optional.
+ */
+
+ if (othertype == &cfg_type_void) {
+ cfg_print_cstr(pctx, "[ ");
+ }
+ cfg_print_cstr(pctx, "( ");
+ for (p = enumtype->of; *p != NULL; p++) {
+ if (!first) {
+ cfg_print_cstr(pctx, " | ");
+ }
+ first = false;
+ cfg_print_cstr(pctx, *p);
+ }
+ if (othertype != &cfg_type_void) {
+ if (!first) {
+ cfg_print_cstr(pctx, " | ");
+ }
+ cfg_doc_terminal(pctx, othertype);
+ }
+ cfg_print_cstr(pctx, " )");
+ if (othertype == &cfg_type_void) {
+ cfg_print_cstr(pctx, " ]");
+ }
+}
+
void
cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
REQUIRE(pctx != NULL);
&cfg_rep_string, NULL
};
+/*%
+ * A bracketed address match list
+ */
+
+static cfg_type_t cfg_type_addrmatchelt;
+static cfg_type_t cfg_type_negated;
+
+static isc_result_t
+parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret)
+{
+ isc_result_t result;
+ UNUSED(type);
+
+ CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
+
+ if (pctx->token.type == isc_tokentype_string ||
+ pctx->token.type == isc_tokentype_qstring) {
+ if (pctx->token.type == isc_tokentype_string &&
+ (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) {
+ CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret));
+ } else if (pctx->token.type == isc_tokentype_string &&
+ (strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) {
+#ifdef HAVE_GEOIP
+ CHECK(cfg_gettoken(pctx, 0));
+ CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret));
+#else
+ cfg_parser_error(pctx, CFG_LOG_NEAR, "'geoip' "
+ "not supported in this build");
+ return (ISC_R_UNEXPECTEDTOKEN);
+#endif
+ } else {
+ if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK |
+ CFG_ADDR_V4PREFIXOK |
+ CFG_ADDR_V6OK))
+ {
+ CHECK(cfg_parse_netprefix(pctx, NULL, ret));
+ } else {
+ CHECK(cfg_parse_astring(pctx, NULL, ret));
+ }
+ }
+ } else if (pctx->token.type == isc_tokentype_special) {
+ if (pctx->token.value.as_char == '{') {
+ /* Nested match list. */
+ CHECK(cfg_parse_obj(pctx,
+ &cfg_type_bracketed_aml, ret));
+ } else if (pctx->token.value.as_char == '!') {
+ CHECK(cfg_gettoken(pctx, 0)); /* read "!" */
+ CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret));
+ } else {
+ goto bad;
+ }
+ } else {
+ bad:
+ cfg_parser_error(pctx, CFG_LOG_NEAR,
+ "expected IP match list element");
+ return (ISC_R_UNEXPECTEDTOKEN);
+ }
+ cleanup:
+ return (result);
+}
+
+/*%
+ * A negated address match list element (like "! 10.0.0.1").
+ * Somewhat sneakily, the caller is expected to parse the
+ * "!", but not to print it.
+ */
+static cfg_tuplefielddef_t negated_fields[] = {
+ { "negated", &cfg_type_addrmatchelt, 0 },
+ { NULL, NULL, 0 }
+};
+
+static void
+print_negated(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ cfg_print_cstr(pctx, "!");
+ cfg_print_tuple(pctx, obj);
+}
+
+static cfg_type_t cfg_type_negated = {
+ "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple,
+ &negated_fields
+};
+
+/*% An address match list element */
+
+static cfg_type_t cfg_type_addrmatchelt = {
+ "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal,
+ NULL, NULL
+};
+
+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
+};
+
/*
* Optional bracketed text
*/
{ CFG_CLAUSEFLAG_MULTI, "may occur multiple times" },
{ CFG_CLAUSEFLAG_EXPERIMENTAL, "experimental" },
{ CFG_CLAUSEFLAG_NOOP, "non-operational" },
+ { CFG_CLAUSEFLAG_DEPRECATED, "deprecated" },
{ 0, NULL }
};
cfg_create_tuple
cfg_doc_bracketed_list
cfg_doc_enum
+cfg_doc_enum_or_other
cfg_doc_map
cfg_doc_mapbody
cfg_doc_obj
cfg_parse_buffer4
cfg_parse_dscp
cfg_parse_enum
+cfg_parse_enum_or_other
cfg_parse_file
cfg_parse_fixedpoint
cfg_parse_listelt
isc_result_t
ns_hookmodule_load(const char *libname, const char *parameters,
const char *file, unsigned long line,
+ const void *cfg, void *actx,
ns_hookctx_t *hctx, ns_hooktable_t *hooktable)
{
isc_result_t result;
"loading module '%s'", libname);
CHECK(load_library(hctx->mctx, libname, &module));
- CHECK(module->register_func(parameters, file, line, hctx,
- hooktable, &module->inst));
+ CHECK(module->register_func(parameters, file, line,
+ cfg, actx, hctx, hooktable,
+ &module->inst));
APPEND(hook_modules, module, link);
result = ISC_R_SUCCESS;
typedef isc_result_t ns_hook_register_t(const char *parameters,
const char *file,
unsigned long line,
+ const void *cfg,
+ void *actx,
ns_hookctx_t *hctx,
ns_hooktable_t *hooktable,
void **instp);
isc_result_t
ns_hookmodule_load(const char *libname, const char *parameters,
const char *file, unsigned long line,
+ const void *cfg, void *actx,
ns_hookctx_t *hctx, ns_hooktable_t *hooktable);
void
ns_hookmodule_cleanup(void);
dns_rdataset_t **sigrdatasetp = NULL;
isc_result_t result;
- PROCESS_HOOK(NS_QUERY_RESPOND_BEGIN, qctx);
-
/*
* If we have a zero ttl from the cache, refetch.
*/
return (query_lookup(qctx));
}
+ /*
+ * XXX: This hook is meant to be at the top of this function,
+ * but is postponed until after DNS64 in order to avoid an
+ * assertion if the hook causes recursion. (When DNS64 also
+ * becomes a hook module, it will be necessary to find some
+ * 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);
+
if (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL) {
sigrdatasetp = &qctx->sigrdataset;
}