diff --git a/README.md b/README.md index 0eb8bb2e5..d805e4d0a 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,21 @@ Unbound can be compiled and installed using: ./configure && make && make install ``` -You can use libevent if you want. libevent is useful when using many (10000) -outgoing ports. By default max 256 ports are opened at the same time and the -builtin alternative is equally capable and a little faster. - +You can use libevent if you want. libevent is useful when using many (e.g., +10000) outgoing ports. Use the `--with-libevent` configure option to compile Unbound with libevent support. +If not, the default builtin alternative opens max 256 ports at the same time +and is equally capable and a little faster. + + ## Unbound configuration -All of Unbound's configuration options are described in the man pages, which -will be installed and are available on the Unbound -[documentation page](https://unbound.docs.nlnetlabs.nl/). +All of Unbound's configuration options are described in the `unbound.conf(5)` +man page, which will be installed and is also available on the Unbound +[documentation page](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html) +for the latest version. -An example configuration file is located in +An example configuration file, with minimal documentation, is located in [doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in). diff --git a/acx_nlnetlabs.m4 b/acx_nlnetlabs.m4 index c8195f5e1..5a71c7cce 100644 --- a/acx_nlnetlabs.m4 +++ b/acx_nlnetlabs.m4 @@ -2,7 +2,9 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 50 +# Version 51 +# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints +# a warning for 'unknown attribute' when nonstring is used. # 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0) # check by ACX_FUNC_MALLOC. # 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE. @@ -535,6 +537,9 @@ dnl result in HAVE_ATTR_NONSTRING. dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also. AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE], [AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([ACX_CHECK_ERROR_FLAGS]) +BAKCFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $ERRFLAG" AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute) AC_CACHE_VAL(ac_cv_c_nonstring_attribute, [ac_cv_c_nonstring_attribute=no @@ -546,6 +551,7 @@ struct test { struct test t = { "1" }; (void) t; ]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"]) +CFLAGS="$BAKCFLAGS" ]) dnl Setup ATTR_NONSTRING config.h parts. diff --git a/cachedb/redis.c b/cachedb/redis.c index 9383f1c85..902497355 100644 --- a/cachedb/redis.c +++ b/cachedb/redis.c @@ -143,6 +143,12 @@ redis_connect(const char* host, int port, const char* path, { struct timeval now_val; redisContext* ctx; +#ifdef THREADS_DISABLED + /* Fix attribute unused warning. + * wait_lock is only used with lock_basic_* functions that are nop'ed + * when compiled without thread support. */ + (void)wait_lock; +#endif /* THREADS_DISABLED */ /* See if the redis server is down, and reconnect has to wait. */ if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) { diff --git a/configure b/configure index 06521bf9d..89026bd22 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for unbound 1.24.1. +# Generated by GNU Autoconf 2.71 for unbound 1.24.3. # # Report bugs to . # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.24.1' -PACKAGE_STRING='unbound 1.24.1' +PACKAGE_VERSION='1.24.3' +PACKAGE_STRING='unbound 1.24.3' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_URL='' @@ -1518,7 +1518,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures unbound 1.24.1 to adapt to many kinds of systems. +\`configure' configures unbound 1.24.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1584,7 +1584,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.24.1:";; + short | recursive ) echo "Configuration of unbound 1.24.3:";; esac cat <<\_ACEOF @@ -1839,7 +1839,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.24.1 +unbound configure 1.24.3 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2496,7 +2496,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.24.1, which was +It was created by unbound $as_me 1.24.3, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3260,11 +3260,11 @@ UNBOUND_VERSION_MAJOR=1 UNBOUND_VERSION_MINOR=24 -UNBOUND_VERSION_MICRO=1 +UNBOUND_VERSION_MICRO=3 LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=34 +LIBUNBOUND_REVISION=36 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -3366,6 +3366,8 @@ LIBUNBOUND_AGE=1 # 1.23.1 had 9:32:1 # 1.24.0 had 9:33:1 # 1.24.1 had 9:34:1 +# 1.24.2 had 9:35:1 +# 1.24.3 had 9:36:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -6955,6 +6957,9 @@ printf "%s\n" "#define HAVE_ATTR_UNUSED 1" >>confdefs.h fi + +BAKCFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $ERRFLAG" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute" >&5 printf %s "checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute... " >&6; } if test ${ac_cv_c_nonstring_attribute+y} @@ -6987,6 +6992,7 @@ else $as_nop ac_cv_c_nonstring_attribute="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +CFLAGS="$BAKCFLAGS" fi @@ -7065,7 +7071,14 @@ else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include -__attribute__((noreturn)) void f(int x) { printf("%d", x); } +#ifdef STDC_HEADERS +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); } int main (void) @@ -21526,7 +21539,7 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if openssl supports SHA2 and ECDSA with EVP" >&5 printf %s "checking if openssl supports SHA2 and ECDSA with EVP... " >&6; } if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then - if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then + if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } @@ -25366,7 +25379,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h -version=1.24.1 +version=1.24.3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 printf %s "checking for build time... " >&6; } @@ -25917,7 +25930,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.24.1, which was +This file was extended by unbound $as_me 1.24.3, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25985,7 +25998,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -unbound config.status 1.24.1 +unbound config.status 1.24.3 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index a84e05cae..7b7641800 100644 --- a/configure.ac +++ b/configure.ac @@ -12,14 +12,14 @@ sinclude(dnscrypt/dnscrypt.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MINOR],[24]) -m4_define([VERSION_MICRO],[1]) +m4_define([VERSION_MICRO],[3]) AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=34 +LIBUNBOUND_REVISION=36 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -121,6 +121,8 @@ LIBUNBOUND_AGE=1 # 1.23.1 had 9:32:1 # 1.24.0 had 9:33:1 # 1.24.1 had 9:34:1 +# 1.24.2 had 9:35:1 +# 1.24.3 had 9:36:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -360,7 +362,14 @@ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribu AC_CACHE_VAL(ac_cv_c_noreturn_attribute, [ac_cv_c_noreturn_attribute=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include -__attribute__((noreturn)) void f(int x) { printf("%d", x); } +#ifdef STDC_HEADERS +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); } ]], [[ f(1); ]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"]) @@ -1253,7 +1262,7 @@ case "$enable_ecdsa" in # see if OPENSSL 1.0.0 or later (has EVP MD and Verify independency) AC_MSG_CHECKING([if openssl supports SHA2 and ECDSA with EVP]) if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then - if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then + if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then AC_MSG_RESULT([no]) AC_DEFINE_UNQUOTED([USE_ECDSA_EVP_WORKAROUND], [1], [Define this to enable an EVP workaround for older openssl]) else diff --git a/daemon/remote.c b/daemon/remote.c index e48be8472..bcf0942af 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -801,6 +801,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) (unsigned long)s->svr.num_queries_cookie_invalid)) return 0; if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries_discard_timeout)) return 0; + if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm, + (unsigned long)s->svr.num_queries_replyaddr_limit)) return 0; if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries_wait_limit)) return 0; if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm, @@ -845,6 +847,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) (unsigned long)s->mesh_num_states)) return 0; if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm, (unsigned long)s->mesh_num_reply_states)) return 0; + if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm, + (unsigned long)s->mesh_num_reply_addrs)) return 0; #ifndef S_SPLINT_S sumwait.tv_sec = s->mesh_replies_sum_wait_sec; sumwait.tv_usec = s->mesh_replies_sum_wait_usec; @@ -6177,6 +6181,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg, COPY_VAR_ptr(ipset_name_v6); #endif COPY_VAR_int(ede); + COPY_VAR_int(iter_scrub_promiscuous); } #endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */ @@ -7611,6 +7616,41 @@ fr_worker_pickup_outside_network(struct worker* worker) } } +#ifdef USE_DNSTAP +/** Fast reload, the worker picks up changes to DNSTAP configuration. */ +static void +fr_worker_pickup_dnstap_changes(struct worker* worker) +{ + struct dt_env* w_dtenv = &worker->dtenv; + struct dt_env* d_dtenv = worker->daemon->dtenv; + log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap); + if(d_dtenv == NULL) { + /* There is no environment when DNSTAP was not enabled + * in the configuration. */ + return; + } + w_dtenv->identity = d_dtenv->identity; + w_dtenv->len_identity = d_dtenv->len_identity; + w_dtenv->version = d_dtenv->version; + w_dtenv->len_version = d_dtenv->len_version; + w_dtenv->log_resolver_query_messages = + d_dtenv->log_resolver_query_messages; + w_dtenv->log_resolver_response_messages = + d_dtenv->log_resolver_response_messages; + w_dtenv->log_client_query_messages = + d_dtenv->log_client_query_messages; + w_dtenv->log_client_response_messages = + d_dtenv->log_client_response_messages; + w_dtenv->log_forwarder_query_messages = + d_dtenv->log_forwarder_query_messages; + w_dtenv->log_forwarder_response_messages = + d_dtenv->log_forwarder_response_messages; + lock_basic_lock(&d_dtenv->sample_lock); + w_dtenv->sample_rate = d_dtenv->sample_rate; + lock_basic_unlock(&d_dtenv->sample_lock); +} +#endif /* USE_DNSTAP */ + void fast_reload_worker_pickup_changes(struct worker* worker) { @@ -7639,6 +7679,9 @@ fast_reload_worker_pickup_changes(struct worker* worker) worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled; #endif fr_worker_pickup_outside_network(worker); +#ifdef USE_DNSTAP + fr_worker_pickup_dnstap_changes(worker); +#endif } /** fast reload thread, handle reload_stop notification, send reload stop diff --git a/daemon/stats.c b/daemon/stats.c index 41c4656aa..43a9f7092 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -262,6 +262,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) s->svr = worker->stats; s->mesh_num_states = (long long)worker->env.mesh->all.count; s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states; + s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs; s->mesh_jostled = (long long)worker->env.mesh->stats_jostled; s->mesh_dropped = (long long)worker->env.mesh->stats_dropped; s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent; @@ -284,6 +285,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) NUM_BUCKETS_HIST); s->svr.num_queries_discard_timeout += (long long)worker->env.mesh->num_queries_discard_timeout; + s->svr.num_queries_replyaddr_limit += + (long long)worker->env.mesh->num_queries_replyaddr_limit; s->svr.num_queries_wait_limit += (long long)worker->env.mesh->num_queries_wait_limit; s->svr.num_dns_error_reports += @@ -448,6 +451,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid; total->svr.num_queries_discard_timeout += a->svr.num_queries_discard_timeout; + total->svr.num_queries_replyaddr_limit += + a->svr.num_queries_replyaddr_limit; total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit; total->svr.num_dns_error_reports += a->svr.num_dns_error_reports; total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache; @@ -519,6 +524,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->mesh_num_states += a->mesh_num_states; total->mesh_num_reply_states += a->mesh_num_reply_states; + total->mesh_num_reply_addrs += a->mesh_num_reply_addrs; total->mesh_jostled += a->mesh_jostled; total->mesh_dropped += a->mesh_dropped; total->mesh_replies_sent += a->mesh_replies_sent; diff --git a/daemon/worker.c b/daemon/worker.c index 0f0af7457..229905195 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1444,6 +1444,24 @@ check_ip_ratelimit(struct worker* worker, struct sockaddr_storage* addr, return 1; } +/* + * This is the callback function when a request arrives. It is passed + * the packet and user argument. Return true to send a reply. + * This is of type comm_point_callback_type. The struct comm_point contains + * more comments on the comm_point.callback member about the function. + * @param c: the comm_point where the request arrives on. + * @param arg: the user argument for the callback, the worker. + * @param error: This can be NETEVENT_NOERROR, NETEVENT_TIMEOUT, + * NETEVENT_CLOSED or other comm point callback error values. + * @param repinfo: The reply info, use it to send a reply. If the reply + * is immediate, return 1. If the reply is later on return 0 and save + * the repinfo, to call comm_point_send_reply on. + * @return 1 to sent a reply straight away, for like cache response so that + * no allocation needs to be done. And only internal preallocated buffers + * are used. Return 0 and save the repinfo to reply later, for responses + * that need to be looked up. Return 0 and call comm_point_drop_reply on + * the repinfo to drop the response. + */ int worker_handle_request(struct comm_point* c, void* arg, int error, struct comm_reply* repinfo) diff --git a/dns64/dns64.c b/dns64/dns64.c index 0de1ac422..9a407072e 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -366,22 +366,23 @@ static int dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg) { struct config_strlist* s; - verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix); - if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix : - DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr, + const char* dns64_prefix = cfg->dns64_prefix ? + cfg->dns64_prefix : DEFAULT_DNS64_PREFIX; + verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix); + if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr, &dns64_env->prefix_addrlen, &dns64_env->prefix_net)) { - log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix); + log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix); return 0; } if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) { - log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix); + log_err("dns64_prefix is not IPv6: %s", dns64_prefix); return 0; } if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 && dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 && dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) { - log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", - cfg->dns64_prefix); + log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s", + dns64_prefix); return 0; } for(s = cfg->dns64_ignore_aaaa; s; s = s->next) { diff --git a/doc/Changelog b/doc/Changelog index 02809011b..704424cf7 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,77 @@ +3 December 2025: Wouter + - Fix http2 drop handling to clear the postpone_drop state so that + other streams on the http2 session are not affected by a drop, + and can clean up properly if also dropped. Fix http2 send reply + so that when there is a send failure is does not recurse into + the mesh functions and also does not drop the connection due to + the condition of one stream. + +2 December 2025: Wouter + - Fix to remove http2 stream mesh state when mesh new request is + dropping the new request. + +1 December 2025: Wouter + - Fix to add EDNS CO flag to testbound and debug message log. + - Fix header comment about EDE reference in validator/val_sigcrypt.h. + +28 November 2025: Yorgos + - For #1375, there is no DNSTAP environment if it wasn't configured. + +26 November 2025: Yorgos + - Tag for 1.24.2 release. + The repository continues with version 1.24.3. + +13 November 2025: Wouter + - Merge #1374: Mesh reply counters. + This adds the statistics num.queries.replyaddr_limit and + requestlist.current.replies. + - Merge #1375: Copy DNSTAP changes from daemon to workers after + fast_reload. + +12 November 2025: Wouter + - Fix that when discard timeout drops packet, they are accounted as + less reply addresses in use in the mesh area. + - iana portlist updated. + +6 November 2025: Wouter + - Fix add comment to worker_handle_request function that explain it. + - Fix configure test for noreturn attribute so it compiles without + warning. + - Fix configure test for nonstring attribute so that it does not + accept when the compiler prints a warning about an unknown + attribute. + +4 November 2025: Wouter + - Fix dns64 log output to log the default instead of a null string. + +1 November 2025: Yorgos + - Fix #1366: Infra cache does not work correctly for NAT64, by + moving the NAT64 synthesis from the iterator when selecting a target + address, to the delegation point itself when adding target + addresses. + +27 October 2025: Yorgos + - Merge #1331 from Jitka Plesníková: Replace deprecated $function by + new $action, for SWIG. + - Fix #1165, document the possible circular dependency when using + host names instead of IP addresses for name servers in stub/forward + zones and log a warning when spotted in the configuration. + +24 October 2025: Yorgos + - unbound.conf man page updates to include a preview of the section + clauses and some reformatting around the use of "clause", "option" + and "attributes". Based on Havard Eidnes' suggestions on the + mailing list. + - Fix unused attribute warning in redis.c when threads are not + supported. + - For #1364, use OPENSSL_VERSION_TEXT instead of OPENSSL_VERSION_NUMBER + for part of the configure script. OPENSSL_VERSION_TEXT is more + consistent across versions. + +22 October 2025: Yorgos + - Tag for 1.24.1 release. + The repository continues with version 1.24.2. + 15 October 2025: Wouter - Fix to drop UDP for discard-timeout, but not stream connections. - Fix to reply with SERVFAIL when the wait-limit is exceeded. diff --git a/doc/example.conf.in b/doc/example.conf.in index 54adee889..296dabbd2 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -196,6 +196,10 @@ server: # Limit on upstream queries for an incoming query and its recursion. # max-global-quota: 200 + # Should the scrubber remove promiscuous NS from positive answers, + # protects against poison attempts. + # iter-scrub-promiscuous: yes + # msec for waiting for an unknown server to reply. Increase if you # are behind a slow satellite link, to eg. 1128. # unknown-server-time-limit: 376 @@ -922,6 +926,22 @@ server: # add a netblock specific override to a localzone, with zone type # local-zone-override: "example.com" 192.0.2.0/24 refuse + # Action to apply when the IP address in an AAAA or A RR in the answer + # section of a response matches the specified IP netblock. + # Requires use of the respip module. + # response-ip: 192.0.2.0/24 redirect + + # Redirect as specified by the "resource record string" when the IP + # address in an AAAA or A RR in the answer section of a response + # matches the specified IP netblock. + # Requires use of the respip module. + # response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1" + + # Apply tag(s) when the IP address in an AAAA or A RR in the answer + # section of a response matches the specified IP netblock. + # Requires use of the respip module. + # response-ip-tag: 192.0.2.0/24 "tag1 tag2" + # service clients over TLS (on the TCP sockets) with plain DNS inside # the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484. # Give the certificate to use and private key. @@ -1266,10 +1286,11 @@ remote-control: # zonefile: "example.org.zone" # Views -# Create named views. Name must be unique. Map views to requests using -# the access-control-view option. Views can contain zero or more local-zone -# and local-data options. Options from matching views will override global -# options. Global options will be used if no matching view is found. +# Create named views. Name must be unique. +# Map views to requests using the access-control-view/interface-view options. +# Views can contain zero or more local-zone and local-data options. +# Options from matching views will override global options. +# Global options will be used if no matching view is found. # With view-first yes, it will try to answer using the global local-zone and # local-data elements if there is no view specific match. # view: @@ -1277,6 +1298,8 @@ remote-control: # local-zone: "example.com" redirect # local-data: "example.com A 192.0.2.3" # local-data-ptr: "192.0.2.3 www.example.com" +# response-ip: 192.0.2.0/24 redirect +# response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1" # view-first: no # view: # name: "anotherview" diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index c05831e41..433b37354 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -167,6 +167,7 @@ ipset, \fI\%tcp\-reuse\-timeout\fP, \fI\%tcp\-auth\-query\-timeout\fP, \fI\%delay\-close\fP\&. +\fI\%iter\-scrub\-promiscuous\fP\&. .sp It does not work with \fI\%interface\fP and @@ -879,6 +880,11 @@ number of queries removed due to discard\-timeout by thread .UNINDENT .INDENT 0.0 .TP +.B threadX.num.queries_replyaddr_limit +number of queries removed due to replyaddr limits by thread +.UNINDENT +.INDENT 0.0 +.TP .B threadX.num.queries_wait_limit number of queries removed due to wait\-limit by thread .UNINDENT @@ -993,6 +999,13 @@ Current size of the request list, only the requests from client queries. .UNINDENT .INDENT 0.0 .TP +.B threadX.requestlist.current.replies +Current count of the number of reply entries waiting on request list +entries. Because a request list entry can send results to multiple reply +addresses, this number may be larger than the size of the request list. +.UNINDENT +.INDENT 0.0 +.TP .B threadX.recursion.time.avg Average time it took to answer queries that needed recursive processing. Note that queries that were answered from the cache are not in this average. @@ -1047,6 +1060,11 @@ summed over threads. .UNINDENT .INDENT 0.0 .TP +.B total.num.queries_replyaddr_limit +summed over threads. +.UNINDENT +.INDENT 0.0 +.TP .B total.num.queries_wait_limit summed over threads. .UNINDENT @@ -1137,6 +1155,16 @@ summed over threads. .UNINDENT .INDENT 0.0 .TP +.B total.requestlist.current.user +summed over threads. +.UNINDENT +.INDENT 0.0 +.TP +.B total.requestlist.current.replies +summed over threads. +.UNINDENT +.INDENT 0.0 +.TP .B total.recursion.time.median averaged over threads. .UNINDENT diff --git a/doc/unbound-control.rst b/doc/unbound-control.rst index bc548f51d..630f2e160 100644 --- a/doc/unbound-control.rst +++ b/doc/unbound-control.rst @@ -169,6 +169,7 @@ There are several commands that the server understands. :ref:`tcp-reuse-timeout`, :ref:`tcp-auth-query-timeout`, :ref:`delay-close`. + :ref:`iter-scrub-promiscuous`. It does not work with :ref:`interface` and @@ -814,6 +815,10 @@ number of statistic counters: number of queries removed due to discard-timeout by thread +@@UAHL@unbound-control.stats@threadX.num.queries_replyaddr_limit@@ + number of queries removed due to replyaddr limits by thread + + @@UAHL@unbound-control.stats@threadX.num.queries_wait_limit@@ number of queries removed due to wait-limit by thread @@ -909,6 +914,12 @@ number of statistic counters: Current size of the request list, only the requests from client queries. +@@UAHL@unbound-control.stats@threadX.requestlist.current.replies@@ + Current count of the number of reply entries waiting on request list + entries. Because a request list entry can send results to multiple reply + addresses, this number may be larger than the size of the request list. + + @@UAHL@unbound-control.stats@threadX.recursion.time.avg@@ Average time it took to answer queries that needed recursive processing. Note that queries that were answered from the cache are not in this average. @@ -954,6 +965,10 @@ number of statistic counters: summed over threads. +@@UAHL@unbound-control.stats@total.num.queries_replyaddr_limit@@ + summed over threads. + + @@UAHL@unbound-control.stats@total.num.queries_wait_limit@@ summed over threads. @@ -1026,6 +1041,14 @@ number of statistic counters: summed over threads. +@@UAHL@unbound-control.stats@total.requestlist.current.user@@ + summed over threads. + + +@@UAHL@unbound-control.stats@total.requestlist.current.replies@@ + summed over threads. + + @@UAHL@unbound-control.stats@total.recursion.time.median@@ averaged over threads. diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 08a926bd5..1a216d9b3 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -36,44 +36,49 @@ unbound.conf \- Unbound @version@ configuration file. .SH DESCRIPTION .sp \fBunbound.conf\fP is used to configure \fI\%unbound(8)\fP\&. -The file format has attributes and values. -Some attributes have attributes inside them. -The notation is: \fBattribute: value\fP\&. -.sp -Comments start with \fB#\fP and last to the end of line. -Empty lines are ignored as is whitespace at the beginning of a line. .sp The utility \fI\%unbound\-checkconf(8)\fP can be used to check \fBunbound.conf\fP prior to usage. +.SH FILE FORMAT +.sp +Whitespace is used to separate keywords. +Whitespace indentation is insignificant, but is still recommended for visual +clarity. +Comments start with \fB#\fP and last to the end of line. +Empty lines are ignored, as is whitespace at the beginning of a line. +.sp +Attribute keywords end with a colon (\fB:\fP) and they are either options or +section clauses (group options together). +.sp +The configuration file is logically divided into \fBsections\fP where each section +is introduced by a \fI\%section clause\fP\&. .SH EXAMPLE .sp -An example config file is shown below. -Copy this to \fB/etc/unbound/unbound.conf\fP and start the server with: +An example minimal config file is shown below; most settings are the defaults. +Copy this to \fB@ub_conf_file@\fP and start the server with: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -$ unbound \-c /etc/unbound/unbound.conf +$ unbound \-c @ub_conf_file@ .ft P .fi .UNINDENT .UNINDENT .sp -Most settings are the defaults. Stop the server with: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C -$ kill \(gacat /etc/unbound/unbound.pid\(ga +$ kill \(gacat @UNBOUND_PIDFILE@\(ga .ft P .fi .UNINDENT .UNINDENT .sp -Below is a minimal config file. The source distribution contains an extensive \fBexample.conf\fP file with all the options. .INDENT 0.0 @@ -83,15 +88,15 @@ all the options. .ft C # unbound.conf(5) config file for unbound(8). server: - directory: \(dq/etc/unbound\(dq + directory: \(dq@UNBOUND_RUN_DIR@\(dq username: unbound # make sure unbound can access entropy from inside the chroot. # e.g. on linux the use these commands (on BSD, devfs(8) is used): - # mount \-\-bind \-n /dev/urandom /etc/unbound/dev/urandom - # and mount \-\-bind \-n /dev/log /etc/unbound/dev/log - chroot: \(dq/etc/unbound\(dq - # logfile: \(dq/etc/unbound/unbound.log\(dq #uncomment to use logfile. - pidfile: \(dq/etc/unbound/unbound.pid\(dq + # mount \-\-bind \-n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom + # and mount \-\-bind \-n /dev/log @UNBOUND_RUN_DIR@/dev/log + chroot: \(dq@UNBOUND_CHROOT_DIR@\(dq + # logfile: \(dq@UNBOUND_RUN_DIR@/unbound.log\(dq #uncomment to use logfile. + pidfile: \(dq@UNBOUND_PIDFILE@\(dq # verbosity: 1 # uncomment and increase to get more logging. # listen on all interfaces, answer queries from the local subnet. interface: 0.0.0.0 @@ -102,14 +107,68 @@ server: .fi .UNINDENT .UNINDENT -.SH FILE FORMAT +.SH SECTION CLAUSES .sp -There must be whitespace between keywords. -Attribute keywords end with a colon \fB\(aq:\(aq\fP\&. -An attribute is followed by a value, or its containing attributes in which case -it is referred to as a clause. -Clauses can be repeated throughout the file (or included files) to group -attributes under the same clause. +The recognized section clauses are: +.INDENT 0.0 +.INDENT 3.5 +.INDENT 0.0 +.TP +.B \fI\%server:\fP +Most of the configuration is found in this section. +.TP +.B \fI\%remote\-control:\fP +Configuration for the facility used by +\fI\%unbound\-control(8)\fP\&. +.TP +.B \fI\%stub\-zone:\fP +Configuration for a zone that redirects to specific authoritative name +servers, e.g. for zones not generally available on the greater +Internet. +.TP +.B \fI\%forward\-zone:\fP +Configuration for a zone that forwards to specific DNS resolvers. +.TP +.B \fI\%auth\-zone:\fP +Configuration for local authoritative zones. +.TP +.B \fI\%view:\fP +Overriding a small subset of configuration for incoming requests. +Requests are mapped to views with +\fI\%access\-control\-view\fP and +\fI\%interface\-view\fP\&. +.TP +.B \fI\%python:\fP +Configuration for the optional \fBpython\fP script module. +.TP +.B \fI\%dynlib:\fP +Configuration for the optional \fBdynlib\fP module that loads dynamic +libraries into Unbound. +.TP +.B \fI\%dnscrypt:\fP +Configuration for the optional DNSCrypt feature. +.TP +.B \fI\%cachedb:\fP +Configuration for the optional \fBcachedb\fP module that can interface +with second level caches, currently Redis or Redis\-complatible +databases. +.TP +.B \fI\%dnstap:\fP +Configuration of the optional dnstap logging feature; a flexible, +structured binary log format for DNS software. +.TP +.B \fI\%rpz:\fP +Configuration for Response Policy Zones that allows for DNS filtering. +Requires the \fBrespip\fP module. +.UNINDENT +.UNINDENT +.UNINDENT +.sp +Section clauses can be repeated throughout the file (or included files) to +logically group options in one visually cohesive group. +This may be particularly useful for the \fBserver:\fP clause with its myriad of +options. +.SH INCLUDING FILES .sp Files can be included using the \fBinclude:\fP directive. It can appear anywhere, it accepts a single file name as argument. @@ -124,11 +183,11 @@ Wildcards can be used to include multiple files, see \fIglob(7)\fP\&. .sp For a more structural include option, the \fBinclude\-toplevel:\fP directive can be used. -This closes whatever clause is currently active (if any) and forces the use of -clauses in the included files and right after this directive. -.SS Server Options +This closes whatever section clause is currently active (if any) and forces the +use of section clauses in the included files and right after this directive. +.SH SERVER OPTIONS .sp -These options are part of the \fBserver:\fP clause. +These options are part of the \fBserver:\fP section. .INDENT 0.0 .TP .B verbosity: \fI\fP @@ -539,6 +598,9 @@ Default: 376 The wait time in msec where recursion requests are dropped. This is to stop a large number of replies from accumulating. They receive no reply, the work item continues to recurse. +For UDP the replies are dropped, for stream connections the reply +is not dropped if the stream connection is still open ready to receive +answers. It is nice to be a bit larger than \fI\%serve\-expired\-client\-timeout\fP if that is enabled. @@ -554,7 +616,7 @@ The number of replies that can wait for recursion, for an IP address. This makes a ratelimit per IP address of waiting replies for recursion. It stops very large amounts of queries waiting to be returned to one destination. -The value \fB0\fP disables wait limits. +The value \fB0\fP disables all wait limits. .sp Default: 1000 .UNINDENT @@ -563,7 +625,11 @@ Default: 1000 .B wait\-limit\-cookie: \fI\fP The number of replies that can wait for recursion, for an IP address that sent the query with a valid DNS Cookie. -Since the cookie validates the client address, this limit can be higher. +Since the cookie already validates the client address, this option allows +to override a configured +\fI\%wait\-limit\fP value usually with a higher one +for cookie validated queries. +The value \fB0\fP disables wait limits for cookie validated queries. .sp Default: 10000 .UNINDENT @@ -1153,8 +1219,8 @@ Default: no .INDENT 0.0 .TP .B tls\-system\-cert: \fI\fP -This the same attribute as the -\fI\%tls\-win\-cert\fP attribute, under a +This the same as the +\fI\%tls\-win\-cert\fP option, under a different name. Because it is not windows specific. .UNINDENT @@ -1607,8 +1673,8 @@ implicit default \(dqaccess\-control: 127.0.0.0/8 allow\(dq option. .INDENT 3.5 The interface needs to be already specified with \fI\%interface\fP and that any -\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP -attributes for targeted clients. +\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP +options for targeted clients. .UNINDENT .UNINDENT .UNINDENT @@ -1623,8 +1689,8 @@ for interfaces. .INDENT 3.5 The interface needs to be already specified with \fI\%interface\fP and that any -\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP -attributes for targeted clients. +\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP +options for targeted clients. .UNINDENT .UNINDENT .UNINDENT @@ -1640,8 +1706,8 @@ but for interfaces. .INDENT 3.5 The interface needs to be already specified with \fI\%interface\fP and that any -\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP -attributes for targeted clients. +\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP +options for targeted clients. .UNINDENT .UNINDENT .UNINDENT @@ -1657,8 +1723,8 @@ for interfaces. .INDENT 3.5 The interface needs to be already specified with \fI\%interface\fP and that any -\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP -attributes for targeted clients. +\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP +options for targeted clients. .UNINDENT .UNINDENT .UNINDENT @@ -1673,8 +1739,8 @@ but for interfaces. .INDENT 3.5 The interface needs to be already specified with \fI\%interface\fP and that any -\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP -attributes for targeted clients. +\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP +options for targeted clients. .UNINDENT .UNINDENT .UNINDENT @@ -1751,7 +1817,7 @@ The logfile is appended to, in the following format: .UNINDENT .sp If this option is given, the \fI\%use\-syslog\fP -attribute is internally set to \fBno\fP\&. +option is internally set to \fBno\fP\&. .sp The logfile is reopened (for append) when the config file is reread, on SIGHUP. @@ -1899,8 +1965,8 @@ Read the root hints from this file. Default is nothing, using builtin hints for the IN class. The file has the format of zone files, with root nameserver names and addresses only. -The default may become outdated, when servers change, therefore it is good -practice to use a root hints file. +The default may become outdated, when servers change, and then it is +possible to use a root hints file with specific servers. .sp Default: \(dq\(dq .UNINDENT @@ -3368,7 +3434,7 @@ This specifies the action data for \fI\%response\-ip\fP with action being to redirect as specified by \fI<\(dqresource record string\(dq>\fP\&. \fI<\(dqResource record string\(dq>\fP is similar to that of -\fI\%access\-control\-tag\-action\fP, +\fI\%access\-control\-tag\-data\fP, but it must be of either AAAA, A or CNAME types. If the \fI\fP is an IPv6/IPv4 prefix, the record must be AAAA/A respectively, unless it is a CNAME (which can be used for both versions of @@ -3689,6 +3755,15 @@ Default: 200 .UNINDENT .INDENT 0.0 .TP +.B iter\-scrub\-promiscuous: \fI\fP +Should the iterator scrubber remove promiscuous NS from positive answers. +This protects against poisonous contents, that could affect names in the +same zone as a spoofed packet. +.sp +Default: yes +.UNINDENT +.INDENT 0.0 +.TP .B fast\-server\-permil: \fI\fP Specify how many times out of 1000 to pick from the set of fastest servers. 0 turns the feature off. @@ -3829,17 +3904,18 @@ enabled to increase privacy on the outgoing reports. .sp Default: no .UNINDENT -.SS Remote Control Options +.SH REMOTE CONTROL OPTIONS +.sp +These options are part of the \fBremote\-control:\fP section and are the +declarations for the remote control facility. .sp -In the \fBremote\-control:\fP clause are the declarations for the remote control -facility. If this is enabled, the \fI\%unbound\-control(8)\fP utility can be used to send commands to the running Unbound server. -The server uses these clauses to setup TLSv1 security for the connection. -The \fI\%unbound\-control(8)\fP utility also reads the -\fBremote\-control:\fP section for options. +The server uses these options to setup TLS security for the connection. +The \fI\%unbound\-control(8)\fP utility also reads +this \fBremote\-control:\fP section for options. To setup the correct self\-signed certificates use the -\fIunbound\-control\-setup(8)\fP utility. +\fBunbound\-control\-setup(8)\fP utility. .INDENT 0.0 .TP .B control\-enable: \fI\fP @@ -3939,9 +4015,11 @@ This file is used by \fI\%unbound\-control(8)\fP\&. .sp Default: unbound_control.pem .UNINDENT -.SS Stub Zone Options +.SH STUB ZONE OPTIONS .sp -There may be multiple \fBstub\-zone:\fP clauses. +These options are part of the \fBstub\-zone:\fP section. +.sp +There may be multiple \fBstub\-zone:\fP sections. Each with a \fI\%name\fP and zero or more hostnames or IP addresses. For the stub zone this list of nameservers is used. @@ -3980,9 +4058,10 @@ Consider adding \fI\%server\fP statements for \fI\%domain\-insecure\fP and for \fI\%local\-zone: nodefault\fP for the zone if it is a locally served zone. -The insecure clause stops DNSSEC from invalidating the zone. +The \fI\%domain\-insecure\fP option stops DNSSEC +from invalidating the zone. The \fI\%local\-zone: nodefault\fP (or -\fI\%transparent\fP) clause makes the +\fI\%transparent\fP) option makes the (reverse\-) zone bypass Unbound\(aqs filtering of \fI\%RFC 1918\fP zones. .INDENT 0.0 .TP @@ -3996,6 +4075,23 @@ This is the full domain name of the zone. Name of stub zone nameserver. Is itself resolved before it is used. .sp +\fBCAUTION:\fP +.INDENT 7.0 +.INDENT 3.5 +If the domain (or a subdomain) from this zone is used as the host, it +will unavoidably introduce a circular dependency on retrieving the IP +addresses of the name server. +In that case, it is suggested to use +\fI\%stub\-addr\fP instead. +Alternatively, +\fI\%stub\-first: yes\fP can also work +around the circular dependency by trying resolution outside of this +zone. +However this has the caveat that it would allow escaping this zone when +any resolution attempt fails within this zone. +.UNINDENT +.UNINDENT +.sp To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the port number. .sp @@ -4036,9 +4132,9 @@ Default: no .INDENT 0.0 .TP .B stub\-first: \fI\fP -If enabled, a query is attempted without the stub clause if it fails. +If enabled, a query is attempted without this stub section if it fails. The data could not be retrieved and would have caused SERVFAIL because the -servers are unreachable, instead it is tried without this clause. +servers are unreachable, instead it is tried without this stub section. .sp Default: no .UNINDENT @@ -4071,9 +4167,11 @@ This is useful when you want immediate changes to be visible. .sp Default: no .UNINDENT -.SS Forward Zone Options +.SH FORWARD ZONE OPTIONS .sp -There may be multiple \fBforward\-zone:\fP clauses. +These options are part of the \fBforward\-zone:\fP section. +.sp +There may be multiple \fBforward\-zone:\fP sections. Each with a \fI\%name\fP and zero or more hostnames or IP addresses. For the forward zone this list of nameservers is used to forward the queries @@ -4104,6 +4202,23 @@ This is the full domain name of the zone. Name of server to forward to. Is itself resolved before it is used. .sp +\fBCAUTION:\fP +.INDENT 7.0 +.INDENT 3.5 +If the domain (or a subdomain) from this zone is used as the host, it +will unavoidably introduce a circular dependency on retrieving the IP +addresses of the name server. +In that case, it is suggested to use +\fI\%forward\-addr\fP instead. +Alternatively, +\fI\%forward\-first: yes\fP can also +work around the circular dependency by trying resolution outside of +this zone. +However this has the caveat that it would allow escaping this zone when +any resolution attempt fails within this zone. +.UNINDENT +.UNINDENT +.sp To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the port number. .sp @@ -4180,12 +4295,14 @@ This is useful when you want immediate changes to be visible. .sp Default: no .UNINDENT -.SS Authority Zone Options +.SH AUTHORITY ZONE OPTIONS +.sp +These options are part of the \fBauth\-zone:\fP section. .sp Authority zones are configured with \fBauth\-zone:\fP, and each one must have a \fI\%name\fP\&. -There can be multiple ones, by listing multiple auth\-zone clauses, each with a -different name, pertaining to that part of the namespace. +There can be multiple ones, by listing multiple \fBauth\-zone\fP section clauses, +each with a different name, pertaining to that part of the namespace. The authority zone with the name closest to the name looked up is used. Authority zones can be processed on two distinct, non\-exclusive, configurable stages. @@ -4216,7 +4333,7 @@ consult the local zone data while resolving. In this case, the aforementioned CNAME example will result in a thoroughly resolved answer. .sp -Authority zones can be read from zonefile. +Authority zones can be read from a zonefile. And can be kept updated via AXFR and IXFR. After update the zonefile is rewritten. The update mechanism uses the SOA timer values and performs SOA UDP queries to @@ -4401,18 +4518,20 @@ If not given then no zonefile is used. If the file does not exist or is empty, Unbound will attempt to fetch zone data (eg. from the primary servers). .UNINDENT -.SS View Options +.SH VIEW OPTIONS .sp -There may be multiple \fBview:\fP clauses. +These options are part of the \fBview:\fP section. +.sp +There may be multiple \fBview:\fP sections. Each with a \fI\%name\fP and zero or more \fI\%local\-zone\fP and -\fI\%local\-data\fP attributes. +\fI\%local\-data\fP options. Views can also contain \fI\%view\-first\fP, \fI\%response\-ip\fP, \fI\%response\-ip\-data\fP and -\fI\%local\-data\-ptr\fP attributes. +\fI\%local\-data\-ptr\fP options. View can be mapped to requests by specifying the view name in an -\fI\%access\-control\-view\fP attribute. +\fI\%access\-control\-view\fP option. Options from matching views will override global options. Global options will be used if no matching view is found, or when the matching view does not have the option specified. @@ -4422,7 +4541,7 @@ view does not have the option specified. Name of the view. Must be unique. This name is used in the -\fI\%access\-control\-view\fP attribute. +\fI\%access\-control\-view\fP option. .UNINDENT .INDENT 0.0 .TP @@ -4455,6 +4574,22 @@ Has the same behaviour as the global .UNINDENT .INDENT 0.0 .TP +.B response\-ip: \fI \fP +This requires use of the \fBrespip\fP module. +.sp +Similar to \fI\%response\-ip\fP but +only applies to this view. +.UNINDENT +.INDENT 0.0 +.TP +.B response\-ip\-data: \fI <\(dqresource record string\(dq>\fP +This requires use of the \fBrespip\fP module. +.sp +Similar to \fI\%response\-ip\-data\fP but +only applies to this view. +.UNINDENT +.INDENT 0.0 +.TP .B view\-first: \fI\fP If enabled, it attempts to use the global \fI\%local\-zone\fP and @@ -4463,9 +4598,11 @@ view specific options. .sp Default: no .UNINDENT -.SS Python Module Options +.SH PYTHON MODULE OPTIONS .sp -The \fBpython:\fP clause gives the settings for the \fIpython(1)\fP script module. +These options are part of the \fBpython:\fP section. +.sp +The \fBpython:\fP section gives the settings for the \fIpython(1)\fP script module. This module acts like the iterator and validator modules do, on queries and answers. To enable the script module it has to be compiled into the daemon, and the word @@ -4488,14 +4625,16 @@ The script file to load. Repeat this option for every python module instance added to the \fI\%module\-config\fP option. .UNINDENT -.SS Dynamic Library Module Options +.SH DYNAMIC LIBRARY MODULE OPTIONS .sp -The \fBdynlib:\fP clause gives the settings for the \fBdynlib\fP module. +These options are part of the \fBdynlib:\fP section. +.sp +The \fBdynlib:\fP section gives the settings for the \fBdynlib\fP module. This module is only a very small wrapper that allows dynamic modules to be loaded on runtime instead of being compiled into the application. To enable the dynlib module it has to be compiled into the daemon, and the word \fBdynlib\fP has to be put in the -\fI\%module\-config\fP attribute. +\fI\%module\-config\fP option. Multiple instances of dynamic libraries are supported by adding the word \fBdynlib\fP more than once. .sp @@ -4510,7 +4649,9 @@ The dynamic library file to load. Repeat this option for every dynlib module instance added to the \fI\%module\-config\fP option. .UNINDENT -.SS DNS64 Module Options +.SH DNS64 MODULE OPTIONS +.sp +These options are part of the \fBserver:\fP section. .sp The \fBdns64\fP module must be configured in the \fI\%module\-config\fP directive, e.g.: @@ -4530,7 +4671,11 @@ and be compiled into the daemon to be enabled. \fBNOTE:\fP .INDENT 0.0 .INDENT 3.5 -These settings go in the \fI\%server:\fP section. +If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module +needs to appear before the \fBdns64\fP module in the +\fI\%module\-config\fP +configuration option so that response IP and/or RPZ feeds can properly +filter responses regardless of DNS64 synthesis. .UNINDENT .UNINDENT .INDENT 0.0 @@ -4566,12 +4711,12 @@ Can be entered multiple times, list a new domain for which it applies, one per line. Applies also to names underneath the name given. .UNINDENT -.SS NAT64 Operation +.SH NAT64 OPTIONS +.sp +These options are part of the \fBserver:\fP section. .sp NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4\-only servers. -It is controlled by two options in the -\fI\%server:\fP section: .INDENT 0.0 .TP .B do\-nat64: \fI\fP @@ -4589,9 +4734,11 @@ The prefix length must be one of /32, /40, /48, /56, /64 or /96. .sp Default: 64:ff9b::/96 (same as \fI\%dns64\-prefix\fP) .UNINDENT -.SS DNSCrypt Options +.SH DNSCRYPT OPTIONS .sp -The \fBdnscrypt:\fP clause gives the settings of the dnscrypt channel. +These options are part of the \fBdnscrypt:\fP section. +.sp +The \fBdnscrypt:\fP section gives the settings of the dnscrypt channel. While those options are available, they are only meaningful if Unbound was compiled with \fB\-\-enable\-dnscrypt\fP\&. Currently certificate and secret/public keys cannot be generated by Unbound. @@ -4721,7 +4868,9 @@ If left unconfigured, it will be configured automatically to be a power of .sp Default: (unconfigured) .UNINDENT -.SS EDNS Client Subnet Module Options +.SH EDNS CLIENT SUBNET MODULE OPTIONS +.sp +These options are part of the \fBserver:\fP section. .sp The ECS module must be configured in the \fI\%module\-config\fP directive, e.g.: @@ -4738,13 +4887,6 @@ module\-config: \(dqsubnetcache validator iterator\(dq .sp and be compiled into the daemon to be enabled. .sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -These settings go in the \fI\%server:\fP section. -.UNINDENT -.UNINDENT -.sp If the destination address is allowed in the configuration Unbound will add the EDNS0 option to the query containing the relevant part of the client\(aqs address. When an answer contains the ECS option the response and the option are placed @@ -4866,7 +5008,9 @@ This number applies for each qname/qclass/qtype tuple. .sp Default: 100 .UNINDENT -.SS Opportunistic IPsec Support Module Options +.SH OPPORTUNISTIC IPSEC SUPPORT MODULE OPTIONS +.sp +These options are part of the \fBserver:\fP section. .sp The IPsec module must be configured in the \fI\%module\-config\fP directive, e.g.: @@ -4883,13 +5027,6 @@ module\-config: \(dqipsecmod validator iterator\(dq .sp and be compiled into Unbound by using \fB\-\-enable\-ipsecmod\fP to be enabled. .sp -\fBNOTE:\fP -.INDENT 0.0 -.INDENT 3.5 -These settings go in the \fI\%server:\fP section. -.UNINDENT -.UNINDENT -.sp When Unbound receives an A/AAAA query that is not in the cache and finds a valid answer, it will withhold returning the answer and instead will generate an IPSECKEY subquery for the same domain name. @@ -4987,7 +5124,9 @@ If the option is not specified, all domains are treated as being allowed .B ipsecmod\-whitelist: \fI\fP Alternate syntax for \fI\%ipsecmod\-allow\fP\&. .UNINDENT -.SS Cache DB Module Options +.SH CACHE DB MODULE OPTIONS +.sp +These options are part of the \fBcachedb:\fP section. .sp The Cache DB module must be configured in the \fI\%module\-config\fP directive, e.g.: @@ -5049,7 +5188,7 @@ If connection close or timeout happens too often, Unbound will be effectively unusable with this backend. It\(aqs the administrator\(aqs responsibility to make the assumption hold. .sp -The \fBcachedb:\fP clause gives custom settings of the cache DB module. +The \fBcachedb:\fP section gives custom settings of the cache DB module. .INDENT 0.0 .TP .B backend: \fI\fP @@ -5277,10 +5416,13 @@ for the Redis replica server. .sp Default: 0 .UNINDENT -.SS DNSTAP Logging Options +.SH DNSTAP OPTIONS .sp -DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fP, is enabled in -the \fBdnstap:\fP section. +These options are part of the \fBdnstap:\fP section. +.sp +DNSTAP is a flexible, structured binary log format for DNS software. +When compiled in by using \fB\-\-enable\-dnstap\fP, it can be enabled in the +\fBdnstap:\fP section. This starts an extra thread (when compiled with threading) that writes the log information to the destination. If Unbound is compiled without threading it does not spawn a thread, but @@ -5446,15 +5588,18 @@ Enable to log forwarder response messages. .sp Default: no .UNINDENT -.SS Response Policy Zone Options +.SH RESPONSE POLICY ZONE OPTIONS .sp -Response Policy Zones are configured with \fBrpz:\fP, and each one must have a -\fI\%name\fP attribute. -There can be multiple ones, by listing multiple RPZ clauses, each with a -different name. -RPZ clauses are applied in order of configuration and any match from an earlier -RPZ zone will terminate the RPZ lookup. +These options are part of the \fBrpz:\fP section. +.sp +Response Policy Zones are configured with \fBrpz:\fP section clauses, and each +one must have a \fI\%name\fP option. +There can be multiple ones, by listing multiple \fBrpz:\fP section clauses, each +with a different name. +RPZ sections are applied in order of configuration and any match from an +earlier RPZ zone will terminate the RPZ lookup. Note that a PASSTHRU action is still considered a match. +.sp The respip module needs to be added to the \fI\%module\-config\fP, e.g.: .INDENT 0.0 @@ -5468,6 +5613,17 @@ module\-config: \(dqrespip validator iterator\(dq .UNINDENT .UNINDENT .sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module +needs to appear before the \fBdns64\fP module in the +\fI\%module\-config\fP +configuration option so that response IP and/or RPZ feeds can properly +filter responses regardless of DNS64 synthesis. +.UNINDENT +.UNINDENT +.sp QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported. Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only and drop. @@ -5536,9 +5692,6 @@ A 192.0.2.1 answer with this IP address .sp Other records like AAAA, TXT and other CNAMEs (not rpz\-..) can also be used to answer queries with that content. -.sp -The RPZ zones can be configured in the config file with these settings in the -\fBrpz:\fP block. .INDENT 0.0 .TP .B name: \fI\fP @@ -5677,7 +5830,7 @@ Default: no .INDENT 0.0 .TP .B tags: \fI\(dq\(dq\fP -Limit the policies from this RPZ clause to clients with a matching tag. +Limit the policies from this RPZ section to clients with a matching tag. .sp Tags need to be defined in \fI\%define\-tag\fP and can be assigned to client addresses using @@ -5685,7 +5838,7 @@ can be assigned to client addresses using \fI\%interface\-tag\fP\&. Enclose list of tags in quotes (\fB\(dq\(dq\fP) and put spaces between tags. .sp -If no tags are specified the policies from this clause will be applied for +If no tags are specified the policies from this section will be applied for all clients. .UNINDENT .SH MEMORY CONTROL EXAMPLE diff --git a/doc/unbound.conf.rst b/doc/unbound.conf.rst index 00dadbc9b..8f78fb31d 100644 --- a/doc/unbound.conf.rst +++ b/doc/unbound.conf.rst @@ -46,34 +46,41 @@ Description ----------- **unbound.conf** is used to configure :doc:`unbound(8)`. -The file format has attributes and values. -Some attributes have attributes inside them. -The notation is: ``attribute: value``. - -Comments start with ``#`` and last to the end of line. -Empty lines are ignored as is whitespace at the beginning of a line. The utility :doc:`unbound-checkconf(8)` can be used to check ``unbound.conf`` prior to usage. +File Format +----------- + +Whitespace is used to separate keywords. +Whitespace indentation is insignificant, but is still recommended for visual +clarity. +Comments start with ``#`` and last to the end of line. +Empty lines are ignored, as is whitespace at the beginning of a line. + +Attribute keywords end with a colon (``:``) and they are either options or +section clauses (group options together). + +The configuration file is logically divided into **sections** where each section +is introduced by a :ref:`section clause`. + Example ------- -An example config file is shown below. -Copy this to :file:`/etc/unbound/unbound.conf` and start the server with: +An example minimal config file is shown below; most settings are the defaults. +Copy this to ``@ub_conf_file@`` and start the server with: .. code-block:: text - $ unbound -c /etc/unbound/unbound.conf + $ unbound -c @ub_conf_file@ -Most settings are the defaults. Stop the server with: .. code-block:: text - $ kill `cat /etc/unbound/unbound.pid` + $ kill `cat @UNBOUND_PIDFILE@` -Below is a minimal config file. The source distribution contains an extensive :file:`example.conf` file with all the options. @@ -81,15 +88,15 @@ all the options. # unbound.conf(5) config file for unbound(8). server: - directory: "/etc/unbound" + directory: "@UNBOUND_RUN_DIR@" username: unbound # make sure unbound can access entropy from inside the chroot. # e.g. on linux the use these commands (on BSD, devfs(8) is used): - # mount --bind -n /dev/urandom /etc/unbound/dev/urandom - # and mount --bind -n /dev/log /etc/unbound/dev/log - chroot: "/etc/unbound" - # logfile: "/etc/unbound/unbound.log" #uncomment to use logfile. - pidfile: "/etc/unbound/unbound.pid" + # mount --bind -n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom + # and mount --bind -n /dev/log @UNBOUND_RUN_DIR@/dev/log + chroot: "@UNBOUND_CHROOT_DIR@" + # logfile: "@UNBOUND_RUN_DIR@/unbound.log" #uncomment to use logfile. + pidfile: "@UNBOUND_PIDFILE@" # verbosity: 1 # uncomment and increase to get more logging. # listen on all interfaces, answer queries from the local subnet. interface: 0.0.0.0 @@ -97,19 +104,71 @@ all the options. access-control: 10.0.0.0/8 allow access-control: 2001:DB8::/64 allow -File Format ------------ +.. _unbound.conf.clauses: -There must be whitespace between keywords. -Attribute keywords end with a colon ``':'``. -An attribute is followed by a value, or its containing attributes in which case -it is referred to as a clause. -Clauses can be repeated throughout the file (or included files) to group -attributes under the same clause. +Section Clauses +--------------- + +The recognized section clauses are: + + :ref:`server:` + Most of the configuration is found in this section. + + :ref:`remote-control:` + Configuration for the facility used by + :doc:`unbound-control(8)`. + + :ref:`stub-zone:` + Configuration for a zone that redirects to specific authoritative name + servers, e.g. for zones not generally available on the greater + Internet. + + :ref:`forward-zone:` + Configuration for a zone that forwards to specific DNS resolvers. + + :ref:`auth-zone:` + Configuration for local authoritative zones. + + :ref:`view:` + Overriding a small subset of configuration for incoming requests. + Requests are mapped to views with + :ref:`access-control-view` and + :ref:`interface-view`. + + :ref:`python:` + Configuration for the optional ``python`` script module. + + :ref:`dynlib:` + Configuration for the optional ``dynlib`` module that loads dynamic + libraries into Unbound. + + :ref:`dnscrypt:` + Configuration for the optional DNSCrypt feature. + + :ref:`cachedb:` + Configuration for the optional ``cachedb`` module that can interface + with second level caches, currently Redis or Redis-complatible + databases. + + :ref:`dnstap:` + Configuration of the optional dnstap logging feature; a flexible, + structured binary log format for DNS software. + + :ref:`rpz:` + Configuration for Response Policy Zones that allows for DNS filtering. + Requires the ``respip`` module. + +Section clauses can be repeated throughout the file (or included files) to +logically group options in one visually cohesive group. +This may be particularly useful for the ``server:`` clause with its myriad of +options. .. _unbound.conf.include: -Files can be included using the **include:** directive. +Including Files +--------------- + +Files can be included using the ``include:`` directive. It can appear anywhere, it accepts a single file name as argument. Processing continues as if the text from the included file was copied into the config file at that point. @@ -122,17 +181,17 @@ Wildcards can be used to include multiple files, see *glob(7)*. .. _unbound.conf.include-toplevel: -For a more structural include option, the **include-toplevel:** directive can +For a more structural include option, the ``include-toplevel:`` directive can be used. -This closes whatever clause is currently active (if any) and forces the use of -clauses in the included files and right after this directive. +This closes whatever section clause is currently active (if any) and forces the +use of section clauses in the included files and right after this directive. .. _unbound.conf.server: Server Options -^^^^^^^^^^^^^^ +-------------- -These options are part of the **server:** clause. +These options are part of the ``server:`` section. @@UAHL@unbound.conf@verbosity@@: ** @@ -1056,8 +1115,8 @@ These options are part of the **server:** clause. @@UAHL@unbound.conf@tls-system-cert@@: ** - This the same attribute as the - :ref:`tls-win-cert` attribute, under a + This the same as the + :ref:`tls-win-cert` option, under a different name. Because it is not windows specific. @@ -1444,8 +1503,8 @@ These options are part of the **server:** clause. .. note:: The interface needs to be already specified with :ref:`interface` and that any - **access-control\*:** attribute overrides all **interface-\*:** - attributes for targeted clients. + **access-control\*:** option overrides all **interface-\*:** + options for targeted clients. @@UAHL@unbound.conf@interface-tag@@: * <"list of tags">* @@ -1455,8 +1514,8 @@ These options are part of the **server:** clause. .. note:: The interface needs to be already specified with :ref:`interface` and that any - **access-control\*:** attribute overrides all **interface-\*:** - attributes for targeted clients. + **access-control\*:** option overrides all **interface-\*:** + options for targeted clients. @@UAHL@unbound.conf@interface-tag-action@@: * * @@ -1467,8 +1526,8 @@ These options are part of the **server:** clause. .. note:: The interface needs to be already specified with :ref:`interface` and that any - **access-control\*:** attribute overrides all **interface-\*:** - attributes for targeted clients. + **access-control\*:** option overrides all **interface-\*:** + options for targeted clients. @@UAHL@unbound.conf@interface-tag-data@@: * <"resource record string">* @@ -1479,8 +1538,8 @@ These options are part of the **server:** clause. .. note:: The interface needs to be already specified with :ref:`interface` and that any - **access-control\*:** attribute overrides all **interface-\*:** - attributes for targeted clients. + **access-control\*:** option overrides all **interface-\*:** + options for targeted clients. @@UAHL@unbound.conf@interface-view@@: * * @@ -1490,8 +1549,8 @@ These options are part of the **server:** clause. .. note:: The interface needs to be already specified with :ref:`interface` and that any - **access-control\*:** attribute overrides all **interface-\*:** - attributes for targeted clients. + **access-control\*:** option overrides all **interface-\*:** + options for targeted clients. @@UAHL@unbound.conf@chroot@@: ** @@ -1556,7 +1615,7 @@ These options are part of the **server:** clause. [seconds since 1970] unbound[pid:tid]: type: message. If this option is given, the :ref:`use-syslog` - attribute is internally set to ``no``. + option is internally set to ``no``. The logfile is reopened (for append) when the config file is reread, on SIGHUP. @@ -2890,7 +2949,7 @@ These options are part of the **server:** clause. :ref:`response-ip` with action being to redirect as specified by *<"resource record string">*. *<"Resource record string">* is similar to that of - :ref:`access-control-tag-action`, + :ref:`access-control-tag-data`, but it must be of either AAAA, A or CNAME types. If the ** is an IPv6/IPv4 prefix, the record must be AAAA/A respectively, unless it is a CNAME (which can be used for both versions of @@ -3185,6 +3244,14 @@ These options are part of the **server:** clause. Default: 200 +@@UAHL@unbound.conf@iter-scrub-promiscuous@@: ** + Should the iterator scrubber remove promiscuous NS from positive answers. + This protects against poisonous contents, that could affect names in the + same zone as a spoofed packet. + + Default: yes + + @@UAHL@unbound.conf@fast-server-permil@@: ** Specify how many times out of 1000 to pick from the set of fastest servers. 0 turns the feature off. @@ -3311,17 +3378,18 @@ These options are part of the **server:** clause. .. _unbound.conf.remote: Remote Control Options -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- + +These options are part of the ``remote-control:`` section and are the +declarations for the remote control facility. -In the **remote-control:** clause are the declarations for the remote control -facility. If this is enabled, the :doc:`unbound-control(8)` utility can be used to send commands to the running Unbound server. -The server uses these clauses to setup TLSv1 security for the connection. -The :doc:`unbound-control(8)` utility also reads the -**remote-control:** section for options. +The server uses these options to setup TLS security for the connection. +The :doc:`unbound-control(8)` utility also reads +this ``remote-control:`` section for options. To setup the correct self-signed certificates use the -*unbound-control-setup(8)* utility. +``unbound-control-setup(8)`` utility. @@UAHL@unbound.conf.remote@control-enable@@: ** @@ -3413,9 +3481,11 @@ To setup the correct self-signed certificates use the .. _unbound.conf.stub: Stub Zone Options -^^^^^^^^^^^^^^^^^ +----------------- -There may be multiple **stub-zone:** clauses. +These options are part of the ``stub-zone:`` section. + +There may be multiple ``stub-zone:`` sections. Each with a :ref:`name` and zero or more hostnames or IP addresses. For the stub zone this list of nameservers is used. @@ -3448,9 +3518,10 @@ Consider adding :ref:`server` statements for :ref:`domain-insecure` and for :ref:`local-zone: \ nodefault` for the zone if it is a locally served zone. -The insecure clause stops DNSSEC from invalidating the zone. +The :ref:`domain-insecure` option stops DNSSEC +from invalidating the zone. The :ref:`local-zone: nodefault` (or -:ref:`transparent`) clause makes the +:ref:`transparent`) option makes the (reverse-) zone bypass Unbound's filtering of :rfc:`1918` zones. @@ -3463,6 +3534,19 @@ The :ref:`local-zone: nodefault` (or Name of stub zone nameserver. Is itself resolved before it is used. + .. caution:: + If the domain (or a subdomain) from this zone is used as the host, it + will unavoidably introduce a circular dependency on retrieving the IP + addresses of the name server. + In that case, it is suggested to use + :ref:`stub-addr` instead. + Alternatively, + :ref:`stub-first: yes` can also work + around the circular dependency by trying resolution outside of this + zone. + However this has the caveat that it would allow escaping this zone when + any resolution attempt fails within this zone. + To use a non-default port for DNS communication append ``'@'`` with the port number. @@ -3500,9 +3584,9 @@ The :ref:`local-zone: nodefault` (or @@UAHL@unbound.conf.stub@stub-first@@: ** - If enabled, a query is attempted without the stub clause if it fails. + If enabled, a query is attempted without this stub section if it fails. The data could not be retrieved and would have caused SERVFAIL because the - servers are unreachable, instead it is tried without this clause. + servers are unreachable, instead it is tried without this stub section. Default: no @@ -3534,9 +3618,11 @@ The :ref:`local-zone: nodefault` (or .. _unbound.conf.forward: Forward Zone Options -^^^^^^^^^^^^^^^^^^^^ +-------------------- -There may be multiple **forward-zone:** clauses. +These options are part of the ``forward-zone:`` section. + +There may be multiple ``forward-zone:`` sections. Each with a :ref:`name` and zero or more hostnames or IP addresses. For the forward zone this list of nameservers is used to forward the queries @@ -3566,6 +3652,19 @@ cache). Name of server to forward to. Is itself resolved before it is used. + .. caution:: + If the domain (or a subdomain) from this zone is used as the host, it + will unavoidably introduce a circular dependency on retrieving the IP + addresses of the name server. + In that case, it is suggested to use + :ref:`forward-addr` instead. + Alternatively, + :ref:`forward-first: yes` can also + work around the circular dependency by trying resolution outside of + this zone. + However this has the caveat that it would allow escaping this zone when + any resolution attempt fails within this zone. + To use a non-default port for DNS communication append ``'@'`` with the port number. @@ -3639,12 +3738,14 @@ cache). .. _unbound.conf.auth: Authority Zone Options -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- -Authority zones are configured with **auth-zone:**, and each one must have a +These options are part of the ``auth-zone:`` section. + +Authority zones are configured with ``auth-zone:``, and each one must have a :ref:`name`. -There can be multiple ones, by listing multiple auth-zone clauses, each with a -different name, pertaining to that part of the namespace. +There can be multiple ones, by listing multiple ``auth-zone`` section clauses, +each with a different name, pertaining to that part of the namespace. The authority zone with the name closest to the name looked up is used. Authority zones can be processed on two distinct, non-exclusive, configurable stages. @@ -3675,7 +3776,7 @@ consult the local zone data while resolving. In this case, the aforementioned CNAME example will result in a thoroughly resolved answer. -Authority zones can be read from zonefile. +Authority zones can be read from a zonefile. And can be kept updated via AXFR and IXFR. After update the zonefile is rewritten. The update mechanism uses the SOA timer values and performs SOA UDP queries to @@ -3711,9 +3812,11 @@ fallback activates to fetch from the upstream instead of the SERVFAIL. :ref:`url` to download the zonefile as a text file from a webserver that would work. - If you specify the hostname, you cannot use the domain from the zonefile, - because it may not have that when retrieving that data, instead use a plain - IP address to avoid a circular dependency on retrieving that IP address. + .. caution:: + If you specify the hostname, you cannot use the domain from the + zonefile, because it may not have that when retrieving that data, + instead use a plain IP address to avoid a circular dependency on + retrieving that IP address. @@UAHL@unbound.conf.auth@master@@: ** @@ -3844,18 +3947,20 @@ fallback activates to fetch from the upstream instead of the SERVFAIL. .. _unbound.conf.view: View Options -^^^^^^^^^^^^ +------------ -There may be multiple **view:** clauses. +These options are part of the ``view:`` section. + +There may be multiple ``view:`` sections. Each with a :ref:`name` and zero or more :ref:`local-zone` and -:ref:`local-data` attributes. +:ref:`local-data` options. Views can also contain :ref:`view-first`, :ref:`response-ip`, :ref:`response-ip-data` and -:ref:`local-data-ptr` attributes. +:ref:`local-data-ptr` options. View can be mapped to requests by specifying the view name in an -:ref:`access-control-view` attribute. +:ref:`access-control-view` option. Options from matching views will override global options. Global options will be used if no matching view is found, or when the matching view does not have the option specified. @@ -3865,7 +3970,7 @@ view does not have the option specified. Name of the view. Must be unique. This name is used in the - :ref:`access-control-view` attribute. + :ref:`access-control-view` option. @@UAHL@unbound.conf.view@local-zone@@: * * @@ -3894,6 +3999,20 @@ view does not have the option specified. :ref:`local-data-ptr` elements. +@@UAHL@unbound.conf.view@response-ip@@: * * + This requires use of the ``respip`` module. + + Similar to :ref:`response-ip` but + only applies to this view. + + +@@UAHL@unbound.conf.view@response-ip-data@@: * <"resource record string">* + This requires use of the ``respip`` module. + + Similar to :ref:`response-ip-data` but + only applies to this view. + + @@UAHL@unbound.conf.view@view-first@@: ** If enabled, it attempts to use the global :ref:`local-zone` and @@ -3902,10 +4021,14 @@ view does not have the option specified. Default: no -Python Module Options -^^^^^^^^^^^^^^^^^^^^^ +.. _unbound.conf.python: -The **python:** clause gives the settings for the *python(1)* script module. +Python Module Options +--------------------- + +These options are part of the ``python:`` section. + +The ``python:`` section gives the settings for the *python(1)* script module. This module acts like the iterator and validator modules do, on queries and answers. To enable the script module it has to be compiled into the daemon, and the word @@ -3928,15 +4051,19 @@ path to the working directory. Repeat this option for every python module instance added to the :ref:`module-config` option. -Dynamic Library Module Options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _unbound.conf.dynlib: -The **dynlib:** clause gives the settings for the ``dynlib`` module. +Dynamic Library Module Options +------------------------------ + +These options are part of the ``dynlib:`` section. + +The ``dynlib:`` section gives the settings for the ``dynlib`` module. This module is only a very small wrapper that allows dynamic modules to be loaded on runtime instead of being compiled into the application. To enable the dynlib module it has to be compiled into the daemon, and the word ``dynlib`` has to be put in the -:ref:`module-config` attribute. +:ref:`module-config` option. Multiple instances of dynamic libraries are supported by adding the word ``dynlib`` more than once. @@ -3952,7 +4079,9 @@ directory. :ref:`module-config` option. DNS64 Module Options -^^^^^^^^^^^^^^^^^^^^ +-------------------- + +These options are part of the ``server:`` section. The ``dns64`` module must be configured in the :ref:`module-config` directive, e.g.: @@ -3963,9 +4092,6 @@ The ``dns64`` module must be configured in the and be compiled into the daemon to be enabled. -.. note:: - These settings go in the :ref:`server:` section. - .. note:: If combining the ``respip`` and ``dns64`` modules, the ``respip`` module needs to appear before the ``dns64`` module in the @@ -3997,13 +4123,13 @@ and be compiled into the daemon to be enabled. per line. Applies also to names underneath the name given. -NAT64 Operation -^^^^^^^^^^^^^^^ +NAT64 Options +------------- + +These options are part of the ``server:`` section. NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4-only servers. -It is controlled by two options in the -:ref:`server:` section: @@UAHL@unbound.conf.nat64@do-nat64@@: ** @@ -4020,10 +4146,14 @@ It is controlled by two options in the Default: 64:ff9b::/96 (same as :ref:`dns64-prefix`) -DNSCrypt Options -^^^^^^^^^^^^^^^^ +.. _unbound.conf.dnscrypt: -The **dnscrypt:** clause gives the settings of the dnscrypt channel. +DNSCrypt Options +---------------- + +These options are part of the ``dnscrypt:`` section. + +The ``dnscrypt:`` section gives the settings of the dnscrypt channel. While those options are available, they are only meaningful if Unbound was compiled with ``--enable-dnscrypt``. Currently certificate and secret/public keys cannot be generated by Unbound. @@ -4130,7 +4260,9 @@ https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage Default: (unconfigured) EDNS Client Subnet Module Options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------------- + +These options are part of the ``server:`` section. The ECS module must be configured in the :ref:`module-config` directive, e.g.: @@ -4141,9 +4273,6 @@ The ECS module must be configured in the and be compiled into the daemon to be enabled. -.. note:: - These settings go in the :ref:`server:` section. - If the destination address is allowed in the configuration Unbound will add the EDNS0 option to the query containing the relevant part of the client's address. When an answer contains the ECS option the response and the option are placed @@ -4258,7 +4387,9 @@ This module does not interact with the Default: 100 Opportunistic IPsec Support Module Options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------------------ + +These options are part of the ``server:`` section. The IPsec module must be configured in the :ref:`module-config` directive, e.g.: @@ -4269,9 +4400,6 @@ The IPsec module must be configured in the and be compiled into Unbound by using ``--enable-ipsecmod`` to be enabled. -.. note:: - These settings go in the :ref:`server:` section. - When Unbound receives an A/AAAA query that is not in the cache and finds a valid answer, it will withhold returning the answer and instead will generate an IPSECKEY subquery for the same domain name. @@ -4361,8 +4489,12 @@ answer given from cache is still relevant for opportunistic IPsec. @@UAHL@unbound.conf@ipsecmod-whitelist@@: ** Alternate syntax for :ref:`ipsecmod-allow`. +.. _unbound.conf.cachedb: + Cache DB Module Options -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- + +These options are part of the ``cachedb:`` section. The Cache DB module must be configured in the :ref:`module-config` directive, e.g.: @@ -4414,7 +4546,7 @@ If connection close or timeout happens too often, Unbound will be effectively unusable with this backend. It's the administrator's responsibility to make the assumption hold. -The **cachedb:** clause gives custom settings of the cache DB module. +The ``cachedb:`` section gives custom settings of the cache DB module. @@UAHL@unbound.conf.cachedb@backend@@: ** @@ -4462,7 +4594,7 @@ The **cachedb:** clause gives custom settings of the cache DB module. Default: yes -The following **cachedb:** options are specific to the ``redis`` backend. +The following ``cachedb:`` options are specific to the ``redis`` backend. @@UAHL@unbound.conf.cachedb@redis-server-host@@: ** @@ -4621,11 +4753,14 @@ The following **cachedb:** options are specific to the ``redis`` backend. .. _unbound.conf.dnstap: -DNSTAP Logging Options -^^^^^^^^^^^^^^^^^^^^^^ +DNSTAP Options +-------------- -DNSTAP support, when compiled in by using ``--enable-dnstap``, is enabled in -the **dnstap:** section. +These options are part of the ``dnstap:`` section. + +DNSTAP is a flexible, structured binary log format for DNS software. +When compiled in by using ``--enable-dnstap``, it can be enabled in the +``dnstap:`` section. This starts an extra thread (when compiled with threading) that writes the log information to the destination. If Unbound is compiled without threading it does not spawn a thread, but @@ -4775,15 +4910,18 @@ connects per-process to the destination. .. _unbound.conf.rpz: Response Policy Zone Options -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +---------------------------- -Response Policy Zones are configured with **rpz:**, and each one must have a -:ref:`name` attribute. -There can be multiple ones, by listing multiple RPZ clauses, each with a -different name. -RPZ clauses are applied in order of configuration and any match from an earlier -RPZ zone will terminate the RPZ lookup. +These options are part of the ``rpz:`` section. + +Response Policy Zones are configured with ``rpz:`` section clauses, and each +one must have a :ref:`name` option. +There can be multiple ones, by listing multiple ``rpz:`` section clauses, each +with a different name. +RPZ sections are applied in order of configuration and any match from an +earlier RPZ zone will terminate the RPZ lookup. Note that a PASSTHRU action is still considered a match. + The respip module needs to be added to the :ref:`module-config`, e.g.: @@ -4849,9 +4987,6 @@ The actions are specified with the record on the right Other records like AAAA, TXT and other CNAMEs (not rpz-..) can also be used to answer queries with that content. -The RPZ zones can be configured in the config file with these settings in the -**rpz:** block. - @@UAHL@unbound.conf.rpz@name@@: ** Name of the authority zone. @@ -4967,7 +5102,7 @@ The RPZ zones can be configured in the config file with these settings in the @@UAHL@unbound.conf.rpz@tags@@: *""* - Limit the policies from this RPZ clause to clients with a matching tag. + Limit the policies from this RPZ section to clients with a matching tag. Tags need to be defined in :ref:`define-tag` and can be assigned to client addresses using @@ -4975,7 +5110,7 @@ The RPZ zones can be configured in the config file with these settings in the :ref:`interface-tag`. Enclose list of tags in quotes (``""``) and put spaces between tags. - If no tags are specified the policies from this clause will be applied for + If no tags are specified the policies from this section will be applied for all clients. Memory Control Example diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index 5d70c6664..4c1049bb6 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -228,6 +228,11 @@ read_fwds_host(struct config_stub* s, struct delegpt* dp) s->name, p->str); return 0; } + if(dname_subdomain_c(dname, dp->name)) { + log_warn("forward-host '%s' may have a circular " + "dependency on forward-zone '%s'", + p->str, s->name); + } #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) if(tls_auth_name) log_err("no name verification functionality in " diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 9faf155ab..a1fc86f58 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -231,6 +231,11 @@ read_stubs_host(struct config_stub* s, struct delegpt* dp) s->name, p->str); return 0; } + if(dname_subdomain_c(dname, dp->name)) { + log_warn("stub-host '%s' may have a circular " + "dependency on stub-zone '%s'", + p->str, s->name); + } #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) if(tls_auth_name) log_err("no name verification functionality in " diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index 49a5f5da1..8507a3fb6 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -418,12 +418,13 @@ shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count) * @param qinfo: original query. * @param region: where to allocate synthesized CNAMEs. * @param env: module env with config options. + * @param zonename: name of server zone. * @return 0 on error. */ static int scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, struct query_info* qinfo, struct regional* region, - struct module_env* env) + struct module_env* env, uint8_t* zonename) { uint8_t* sname = qinfo->qname; size_t snamelen = qinfo->qname_len; @@ -431,7 +432,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, int cname_length = 0; /* number of CNAMEs, or DNAMEs */ if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR && - FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN) + FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN && + FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_YXDOMAIN) return 1; /* For the ANSWER section, remove all "irrelevant" records and add @@ -470,6 +472,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, &aliaslen, pkt)) { verbose(VERB_ALGO, "synthesized CNAME " "too long"); + if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) { + prev = rrset; + rrset = rrset->rrset_all_next; + continue; + } return 0; } cname_length++; @@ -634,6 +641,45 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg, "RRset:", pkt, msg, prev, &rrset); continue; } + /* If the NS set is a promiscuous NS set, scrub that + * to remove potential for poisonous contents that + * affects other names in the same zone. Remove + * promiscuous NS sets in positive answers, that + * thus have records in the answer section. Nodata + * and nxdomain promiscuous NS sets have been removed + * already. Since the NS rrset is scrubbed, its + * address records are also not marked to be allowed + * and are removed later. */ + if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR && + msg->an_rrsets != 0 && + env->cfg->iter_scrub_promiscuous) { + remove_rrset("normalize: removing promiscuous " + "RRset:", pkt, msg, prev, &rrset); + continue; + } + /* Also delete promiscuous NS for other RCODEs */ + if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR + && env->cfg->iter_scrub_promiscuous) { + remove_rrset("normalize: removing promiscuous " + "RRset:", pkt, msg, prev, &rrset); + continue; + } + /* Also delete promiscuous NS for NOERROR with nodata + * for authoritative answers, not for delegations. + * NOERROR with an_rrsets!=0 already handled. + * Also NOERROR and soa_in_auth already handled. + * NOERROR with an_rrsets==0, and not a referral. + * referral is (NS not the zonename, noSOA). + */ + if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR + && msg->an_rrsets == 0 + && !(dname_pkt_compare(pkt, rrset->dname, + zonename) != 0 && !soa_in_auth(msg)) + && env->cfg->iter_scrub_promiscuous) { + remove_rrset("normalize: removing promiscuous " + "RRset:", pkt, msg, prev, &rrset); + continue; + } if(nsset == NULL) { nsset = rrset; } else { @@ -1044,7 +1090,8 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg, /* this is not required for basic operation but is a forgery * resistance (security) feature */ if((FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR || - FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN) && + FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN || + FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) && msg->qdcount == 0) return 0; @@ -1058,7 +1105,7 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg, } /* normalize the response, this cleans up the additional. */ - if(!scrub_normalize(pkt, msg, qinfo, region, env)) + if(!scrub_normalize(pkt, msg, qinfo, region, env, zonename)) return 0; /* delete all out-of-zone information */ if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate)) diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 1da21896c..fb419f9ab 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) return 1; } -/** filter out unsuitable targets +/** filter out unsuitable targets. + * Applies NAT64 if needed as well by replacing the IPv4 with the synthesized + * IPv6 address. * @param iter_env: iterator environment with ipv6-support flag. * @param env: module environment with infra cache. * @param name: zone name @@ -317,6 +319,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env, !addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip4 available */ } + if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) { + struct sockaddr_storage real_addr; + socklen_t real_addrlen; + addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr, + iter_env->nat64.nat64_prefix_addrlen, + iter_env->nat64.nat64_prefix_net, + &real_addr, &real_addrlen); + log_name_addr(VERB_QUERY, "NAT64 apply: from: ", + name, &a->addr, a->addrlen); + log_name_addr(VERB_QUERY, "NAT64 apply: to: ", + name, &real_addr, real_addrlen); + a->addr = real_addr; + a->addrlen = real_addrlen; + } /* check lameness - need zone , class info */ if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen, name, namelen, qtype, &lame, &dnsseclame, &reclame, diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index b17b091e6..f7f374742 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg); /** * Select a valid, nice target to send query to. * Sorting and removing unsuitable targets is combined. + * Adds records to the infra cache if not already there. * * @param iter_env: iterator module global state, with ip6 enabled and * do-not-query-addresses. diff --git a/iterator/iterator.c b/iterator/iterator.c index 071dd0827..836cb36e0 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -2436,8 +2436,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, int tf_policy; struct delegpt_addr* target; struct outbound_entry* outq; - struct sockaddr_storage real_addr; - socklen_t real_addrlen; int auth_fallback = 0; uint8_t* qout_orig = NULL; size_t qout_orig_len = 0; @@ -3060,17 +3058,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->dnssec_lame_query?" but lame_query anyway": ""); } - real_addr = target->addr; - real_addrlen = target->addrlen; - - if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) { - addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr, - ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net, - &real_addr, &real_addrlen); - log_name_addr(VERB_QUERY, "applied NAT64:", - iq->dp->name, &real_addr, real_addrlen); - } - fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); outq = (*qstate->env->send_query)(&iq->qinfo_out, iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), @@ -3082,7 +3069,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env, &iq->qinfo_out)||target->attempts==1)?0:BIT_CD), iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted( - ie, iq), sq_check_ratelimit, &real_addr, real_addrlen, + ie, iq), sq_check_ratelimit, &target->addr, target->addrlen, iq->dp->name, iq->dp->namelen, (iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream), (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), @@ -3099,7 +3086,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } log_addr(VERB_QUERY, "error sending query to auth server", - &real_addr, real_addrlen); + &target->addr, target->addrlen); if(qstate->env->cfg->qname_minimisation) iq->minimisation_state = SKIP_MINIMISE_STATE; return next_state(iq, QUERYTARGETS_STATE); diff --git a/libunbound/python/libunbound.i b/libunbound/python/libunbound.i index dc125146c..9ed1be90b 100644 --- a/libunbound/python/libunbound.i +++ b/libunbound/python/libunbound.i @@ -853,7 +853,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104'] %{ //printf("resolve_start(%lX)\n",(long unsigned int)arg1); Py_BEGIN_ALLOW_THREADS - $function + $action Py_END_ALLOW_THREADS //printf("resolve_stop()\n"); %} diff --git a/libunbound/unbound.h b/libunbound/unbound.h index c274f80ab..5a31f98e5 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -853,6 +853,8 @@ struct ub_server_stats { long long qquic; /** number of queries removed due to discard-timeout */ long long num_queries_discard_timeout; + /** number of queries removed due to replyaddr limit */ + long long num_queries_replyaddr_limit; /** number of queries removed due to wait-limit */ long long num_queries_wait_limit; /** number of dns error reports generated */ @@ -872,6 +874,8 @@ struct ub_stats_info { long long mesh_num_states; /** mesh stats: current number of reply (user) states */ long long mesh_num_reply_states; + /** mesh stats: current number of reply entries */ + long long mesh_num_reply_addrs; /** mesh stats: number of reply states overwritten with a new one */ long long mesh_jostled; /** mesh stats: number of incoming queries dropped */ diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index f7fcca194..e6c7de98d 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -2884,6 +2884,7 @@ submit_http_error: sldns_buffer_flip(h2_stream->qbuffer); h2_session->postpone_drop = 1; query_read_done = http2_query_read_done(h2_session, h2_stream); + h2_session->postpone_drop = 0; if(query_read_done < 0) return NGHTTP2_ERR_CALLBACK_FAILURE; else if(!query_read_done) { @@ -2893,11 +2894,9 @@ submit_http_error: * failure will result in reclaiming (and closing) * of comm point. */ verbose(VERB_QUERY, "http2 query dropped in worker cb"); - h2_session->postpone_drop = 0; return NGHTTP2_ERR_CALLBACK_FAILURE; } /* nothing to submit right now, query added to mesh. */ - h2_session->postpone_drop = 0; return 0; } if(!http2_submit_dns_response(h2_session)) { diff --git a/services/mesh.c b/services/mesh.c index af2172102..3a1cc2a78 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -231,6 +231,7 @@ mesh_create(struct module_stack* stack, struct module_env* env) mesh->ans_expired = 0; mesh->ans_cachedb = 0; mesh->num_queries_discard_timeout = 0; + mesh->num_queries_replyaddr_limit = 0; mesh->num_queries_wait_limit = 0; mesh->num_dns_error_reports = 0; mesh->max_reply_states = env->cfg->num_queries_per_thread; @@ -462,6 +463,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, if(!mesh_make_new_space(mesh, rep->c->buffer)) { verbose(VERB_ALGO, "Too many queries. dropping " "incoming query."); + if(rep->c->use_h2) + http2_stream_remove_mesh_state(rep->c->h2_stream); comm_point_drop_reply(rep); mesh->stats_dropped++; return; @@ -473,8 +476,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, if(mesh->num_reply_addrs > mesh->max_reply_states*16) { verbose(VERB_ALGO, "Too many requests queued. " "dropping incoming query."); + if(rep->c->use_h2) + http2_stream_remove_mesh_state(rep->c->h2_stream); comm_point_drop_reply(rep); - mesh->stats_dropped++; + mesh->num_queries_replyaddr_limit++; return; } } @@ -1765,6 +1770,8 @@ void mesh_query_done(struct mesh_state* mstate) http2_stream_remove_mesh_state(r->h2_stream); comm_point_drop_reply(&r->query_reply); mstate->reply_list = reply_list; + log_assert(mstate->s.env->mesh->num_reply_addrs > 0); + mstate->s.env->mesh->num_reply_addrs--; mstate->s.env->mesh->num_queries_discard_timeout++; continue; } @@ -1801,6 +1808,8 @@ void mesh_query_done(struct mesh_state* mstate) } comm_point_drop_reply(&r->query_reply); mstate->reply_list = reply_list; + log_assert(mstate->s.env->mesh->num_reply_addrs > 0); + mstate->s.env->mesh->num_reply_addrs--; } else { struct sldns_buffer* r_buffer = r->query_reply.c->buffer; if(r->query_reply.c->tcp_req_info) { @@ -2291,6 +2300,7 @@ mesh_stats_clear(struct mesh_area* mesh) memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM); mesh->ans_nodata = 0; mesh->num_queries_discard_timeout = 0; + mesh->num_queries_replyaddr_limit = 0; mesh->num_queries_wait_limit = 0; mesh->num_dns_error_reports = 0; } diff --git a/services/mesh.h b/services/mesh.h index 53a05b443..d2fac9d3c 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -141,6 +141,8 @@ struct mesh_area { size_t rpz_action[UB_STATS_RPZ_ACTION_NUM]; /** stats, number of queries removed due to discard-timeout */ size_t num_queries_discard_timeout; + /** stats, number of queries removed due to replyaddr limit */ + size_t num_queries_replyaddr_limit; /** stats, number of queries removed due to wait-limit */ size_t num_queries_wait_limit; /** stats, number of dns error reports generated */ diff --git a/sldns/rrdef.h b/sldns/rrdef.h index 529ef9a84..bbc3d5b86 100644 --- a/sldns/rrdef.h +++ b/sldns/rrdef.h @@ -486,6 +486,7 @@ enum sldns_enum_ede_code typedef enum sldns_enum_ede_code sldns_ede_code; #define LDNS_EDNS_MASK_DO_BIT 0x8000 +#define LDNS_EDNS_MASK_CO_BIT 0x4000 /** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */ #define LDNS_TSIG_ERROR_NOERROR 0 diff --git a/sldns/wire2str.c b/sldns/wire2str.c index f4b01b028..75b8f37b0 100644 --- a/sldns/wire2str.c +++ b/sldns/wire2str.c @@ -2486,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str, w += sldns_str_print(str, str_len, " flags:"); if((edns_bits & LDNS_EDNS_MASK_DO_BIT)) w += sldns_str_print(str, str_len, " do"); + if((edns_bits & LDNS_EDNS_MASK_CO_BIT)) + w += sldns_str_print(str, str_len, " co"); /* the extended rcode is the value set, shifted four bits, * and or'd with the original rcode */ if(ext_rcode) { diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 696750c19..bb1d5237e 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -236,6 +236,8 @@ static void pr_stats(const char* nm, struct ub_stats_info* s) s->svr.num_queries_cookie_invalid); PR_UL_NM("num.queries_discard_timeout", s->svr.num_queries_discard_timeout); + PR_UL_NM("num.queries_replyaddr_limit", + s->svr.num_queries_replyaddr_limit); PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit); PR_UL_NM("num.cachehits", s->svr.num_queries - s->svr.num_queries_missed_cache); @@ -263,6 +265,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s) PR_UL_NM("requestlist.exceeded", s->mesh_dropped); PR_UL_NM("requestlist.current.all", s->mesh_num_states); PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states); + PR_UL_NM("requestlist.current.replies", s->mesh_num_reply_addrs); #ifndef S_SPLINT_S sumwait.tv_sec = s->mesh_replies_sum_wait_sec; sumwait.tv_usec = s->mesh_replies_sum_wait_usec; diff --git a/testcode/testpkts.c b/testcode/testpkts.c index 612461063..8b92df2e7 100644 --- a/testcode/testpkts.c +++ b/testcode/testpkts.c @@ -135,6 +135,8 @@ static void matchline(char* line, struct entry* e) e->match_ttl = 1; } else if(str_keyword(&parse, "DO")) { e->match_do = 1; + } else if(str_keyword(&parse, "CO")) { + e->match_co = 1; } else if(str_keyword(&parse, "noedns")) { e->match_noedns = 1; } else if(str_keyword(&parse, "ednsdata")) { @@ -178,7 +180,7 @@ static void matchline(char* line, struct entry* e) /** parse REPLY line */ static void replyline(char* line, uint8_t* reply, size_t reply_len, - int* do_flag) + int* do_flag, int* co_flag) { char* parse = line; if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header"); @@ -236,6 +238,8 @@ static void replyline(char* line, uint8_t* reply, size_t reply_len, LDNS_AD_SET(reply); } else if(str_keyword(&parse, "DO")) { *do_flag = 1; + } else if(str_keyword(&parse, "CO")) { + *co_flag = 1; } else { error("could not parse REPLY: '%s'", parse); } @@ -289,6 +293,7 @@ static struct entry* new_entry(void) e->match_all_noedns = 0; e->match_ttl = 0; e->match_do = 0; + e->match_co = 0; e->match_noedns = 0; e->match_serial = 0; e->ixfr_soa_serial = 0; @@ -521,15 +526,17 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize, /* add EDNS 4096 opt record */ static void -add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata, - uint16_t ednslen, size_t* pktlen) +add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, int co_flag, + uint8_t *ednsdata, uint16_t ednslen, size_t* pktlen) { uint8_t edns[] = {0x00, /* root label */ 0x00, LDNS_RR_TYPE_OPT, /* type */ 0x04, 0xD0, /* class is UDPSIZE 1232 */ 0x00, /* TTL[0] is ext rcode */ 0x00, /* TTL[1] is edns version */ - (uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */ + (uint8_t)(do_flag?0x80:0x00) + | (uint8_t)(co_flag?0x40:0x00) + , 0x00, /* TTL[2-3] is edns flags, DO */ (uint8_t)((ednslen >> 8) & 0xff), (uint8_t)(ednslen & 0xff), /* rdatalength */ }; @@ -561,6 +568,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, uint8_t pktbuf[MAX_PACKETLEN]; size_t pktlen = LDNS_HEADER_SIZE; int do_flag = 0; /* DO flag in EDNS */ + int co_flag = 0; /* CO flag in EDNS */ memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */ while(fgets(line, (int)sizeof(line), in) != NULL) { @@ -598,7 +606,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, if(str_keyword(&parse, "MATCH")) { matchline(parse, current); } else if(str_keyword(&parse, "REPLY")) { - replyline(parse, pktbuf, pktlen, &do_flag); + replyline(parse, pktbuf, pktlen, &do_flag, &co_flag); } else if(str_keyword(&parse, "ADJUST")) { adjustline(parse, current, cur_reply); } else if(str_keyword(&parse, "EXTRA_PACKET")) { @@ -654,15 +662,16 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, if(hex_ednsdata_buffer) sldns_buffer_free(hex_ednsdata_buffer); if(pktlen != 0) { - if(do_flag || cur_reply->raw_ednsdata) { + if(do_flag || co_flag + || cur_reply->raw_ednsdata) { if(cur_reply->raw_ednsdata && sldns_buffer_limit(cur_reply->raw_ednsdata)) - add_edns(pktbuf, sizeof(pktbuf), do_flag, + add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag, sldns_buffer_begin(cur_reply->raw_ednsdata), (uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata), &pktlen); else - add_edns(pktbuf, sizeof(pktbuf), do_flag, + add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag, NULL, 0, &pktlen); } cur_reply->reply_pkt = memdup(pktbuf, pktlen); @@ -909,6 +918,22 @@ get_do_flag(uint8_t* pkt, size_t len) return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT); } +/** return true if the CO flag is set */ +static int +get_co_flag(uint8_t* pkt, size_t len) +{ + uint16_t edns_bits; + uint8_t* walk = pkt; + size_t walk_len = len; + if(!pkt_find_edns_opt(&walk, &walk_len)) { + return 0; + } + if(walk_len < 6) + return 0; /* malformed */ + edns_bits = sldns_read_uint16(walk+4); + return (int)(edns_bits&LDNS_EDNS_MASK_CO_BIT); +} + /** Snips the specified EDNS option out of the OPT record and puts it in the * provided buffer. The buffer should be able to hold any opt data ie 65535. * Returns the length of the option written, @@ -1654,6 +1679,10 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len, verbose(3, "no DO bit set\n"); continue; } + if(p->match_co && !get_co_flag(query_pkt, len)) { + verbose(3, "no CO bit set\n"); + continue; + } if(p->match_noedns && get_has_edns(query_pkt, len)) { verbose(3, "bad; EDNS OPT present\n"); continue; diff --git a/testcode/testpkts.h b/testcode/testpkts.h index c6a3725f3..e36802dbc 100644 --- a/testcode/testpkts.h +++ b/testcode/testpkts.h @@ -218,6 +218,8 @@ struct entry { uint8_t match_ttl; /** match DO bit */ uint8_t match_do; + /** match CO bit */ + uint8_t match_co; /** match absence of EDNS OPT record in query */ uint8_t match_noedns; /** match edns data field given in hex */ diff --git a/testdata/autotrust_init.rpl b/testdata/autotrust_init.rpl index d722273e0..d69e70b4b 100644 --- a/testdata/autotrust_init.rpl +++ b/testdata/autotrust_init.rpl @@ -5,6 +5,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/autotrust_init_ds.rpl b/testdata/autotrust_init_ds.rpl index ad4019ebe..9ffb4d4ba 100644 --- a/testdata/autotrust_init_ds.rpl +++ b/testdata/autotrust_init_ds.rpl @@ -5,6 +5,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/autotrust_init_sigs.rpl b/testdata/autotrust_init_sigs.rpl index d5d52f473..a7cb7963b 100644 --- a/testdata/autotrust_init_sigs.rpl +++ b/testdata/autotrust_init_sigs.rpl @@ -5,6 +5,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/autotrust_init_zsk.rpl b/testdata/autotrust_init_zsk.rpl index 56a5bc0b3..2d28d4340 100644 --- a/testdata/autotrust_init_zsk.rpl +++ b/testdata/autotrust_init_zsk.rpl @@ -5,6 +5,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/black_data.rpl b/testdata/black_data.rpl index e6ef1b79d..e928d630d 100644 --- a/testdata/black_data.rpl +++ b/testdata/black_data.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/black_prime.rpl b/testdata/black_prime.rpl index fbe92a721..0301c85b6 100644 --- a/testdata/black_prime.rpl +++ b/testdata/black_prime.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/disable_edns_do.rpl b/testdata/disable_edns_do.rpl index 82a16da06..45b4ffca8 100644 --- a/testdata/disable_edns_do.rpl +++ b/testdata/disable_edns_do.rpl @@ -5,6 +5,7 @@ server: qname-minimisation: "no" trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no disable-edns-do: yes stub-zone: diff --git a/testdata/dns64_lookup.rpl b/testdata/dns64_lookup.rpl index 327f7dfed..cec801232 100644 --- a/testdata/dns64_lookup.rpl +++ b/testdata/dns64_lookup.rpl @@ -7,6 +7,7 @@ server: dns64-ignore-aaaa: ip6ignore.example.com dns64-ignore-aaaa: ip6only.example.com minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/dns64_prefetch_cache.rpl b/testdata/dns64_prefetch_cache.rpl index a23b92f08..b28839c9a 100644 --- a/testdata/dns64_prefetch_cache.rpl +++ b/testdata/dns64_prefetch_cache.rpl @@ -5,6 +5,7 @@ server: module-config: "dns64 iterator" dns64-prefix: 64:ff9b::0/96 minimal-responses: no + iter-scrub-promiscuous: no prefetch: yes stub-zone: diff --git a/testdata/fetch_glue.rpl b/testdata/fetch_glue.rpl index 8860d85b0..daf687ad4 100644 --- a/testdata/fetch_glue.rpl +++ b/testdata/fetch_glue.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/fetch_glue_cname.rpl b/testdata/fetch_glue_cname.rpl index 64f00fb20..c786a417c 100644 --- a/testdata/fetch_glue_cname.rpl +++ b/testdata/fetch_glue_cname.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/fwd_cached.rpl b/testdata/fwd_cached.rpl index 2d6b0c2b8..4a00f8715 100644 --- a/testdata/fwd_cached.rpl +++ b/testdata/fwd_cached.rpl @@ -2,6 +2,7 @@ ; config options go here. server: minimal-responses: no + iter-scrub-promiscuous: no forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/fwd_compress_c00c.tdir/fwd_compress_c00c.conf b/testdata/fwd_compress_c00c.tdir/fwd_compress_c00c.conf index 5b2c8045a..7bc7408cd 100644 --- a/testdata/fwd_compress_c00c.tdir/fwd_compress_c00c.conf +++ b/testdata/fwd_compress_c00c.tdir/fwd_compress_c00c.conf @@ -10,6 +10,7 @@ server: username: "" do-not-query-localhost: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no forward-zone: name: "." diff --git a/testdata/fwd_minimal.rpl b/testdata/fwd_minimal.rpl index e85d7124b..ef1d7fc41 100644 --- a/testdata/fwd_minimal.rpl +++ b/testdata/fwd_minimal.rpl @@ -5,6 +5,7 @@ server: ; is fine for that, not removed by minimal-responses. access-control: 127.0.0.1 allow_snoop minimal-responses: yes + iter-scrub-promiscuous: no forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/ipsecmod_bogus_ipseckey.crpl b/testdata/ipsecmod_bogus_ipseckey.crpl index 094710b60..98bc454f2 100644 --- a/testdata/ipsecmod_bogus_ipseckey.crpl +++ b/testdata/ipsecmod_bogus_ipseckey.crpl @@ -9,6 +9,7 @@ server: qname-minimisation: "no" # test that default value of harden-dnssec-stripped is still yes. fake-sha1: yes + iter-scrub-promiscuous: no trust-anchor-signaling: no access-control: 127.0.0.1 allow_snoop module-config: "ipsecmod validator iterator" diff --git a/testdata/ipsecmod_enabled.crpl b/testdata/ipsecmod_enabled.crpl index 449842961..04e8cb1a1 100644 --- a/testdata/ipsecmod_enabled.crpl +++ b/testdata/ipsecmod_enabled.crpl @@ -11,6 +11,7 @@ server: ipsecmod-enabled: no qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/ipsecmod_ignore_bogus_ipseckey.crpl b/testdata/ipsecmod_ignore_bogus_ipseckey.crpl index a605c3445..4c4d80c10 100644 --- a/testdata/ipsecmod_ignore_bogus_ipseckey.crpl +++ b/testdata/ipsecmod_ignore_bogus_ipseckey.crpl @@ -18,6 +18,7 @@ server: ipsecmod-ignore-bogus: yes qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/ipsecmod_max_ttl.crpl b/testdata/ipsecmod_max_ttl.crpl index 592bae046..4dfeddfd9 100644 --- a/testdata/ipsecmod_max_ttl.crpl +++ b/testdata/ipsecmod_max_ttl.crpl @@ -10,6 +10,7 @@ server: ipsecmod-max-ttl: 200 qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/ipsecmod_strict.crpl b/testdata/ipsecmod_strict.crpl index f74e308bd..51cc11b53 100644 --- a/testdata/ipsecmod_strict.crpl +++ b/testdata/ipsecmod_strict.crpl @@ -10,6 +10,7 @@ server: ipsecmod-max-ttl: 200 qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/ipsecmod_whitelist.crpl b/testdata/ipsecmod_whitelist.crpl index 34108f3b1..350c2ad48 100644 --- a/testdata/ipsecmod_whitelist.crpl +++ b/testdata/ipsecmod_whitelist.crpl @@ -11,6 +11,7 @@ server: ipsecmod-whitelist: white.example.com qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_class_any.rpl b/testdata/iter_class_any.rpl index 6fb296e99..87e0db032 100644 --- a/testdata/iter_class_any.rpl +++ b/testdata/iter_class_any.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_cycle_noh.rpl b/testdata/iter_cycle_noh.rpl index eee26ca70..e551ac6e8 100644 --- a/testdata/iter_cycle_noh.rpl +++ b/testdata/iter_cycle_noh.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_domain_sale.rpl b/testdata/iter_domain_sale.rpl index 6110148a3..7c3cc1f2f 100644 --- a/testdata/iter_domain_sale.rpl +++ b/testdata/iter_domain_sale.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_domain_sale_nschange.rpl b/testdata/iter_domain_sale_nschange.rpl index 5664855d5..886ed51a3 100644 --- a/testdata/iter_domain_sale_nschange.rpl +++ b/testdata/iter_domain_sale_nschange.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_emptydp.rpl b/testdata/iter_emptydp.rpl index ecb49b6cd..3879a9b43 100644 --- a/testdata/iter_emptydp.rpl +++ b/testdata/iter_emptydp.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_emptydp_for_glue.rpl b/testdata/iter_emptydp_for_glue.rpl index 94dec2bc5..fc7933fbc 100644 --- a/testdata/iter_emptydp_for_glue.rpl +++ b/testdata/iter_emptydp_for_glue.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_fwdfirst.rpl b/testdata/iter_fwdfirst.rpl index 0f8a85f5a..509a1cdad 100644 --- a/testdata/iter_fwdfirst.rpl +++ b/testdata/iter_fwdfirst.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_fwdfirstequal.rpl b/testdata/iter_fwdfirstequal.rpl index dc648143c..abd25d149 100644 --- a/testdata/iter_fwdfirstequal.rpl +++ b/testdata/iter_fwdfirstequal.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_fwdfirstequaltcp.rpl b/testdata/iter_fwdfirstequaltcp.rpl index 72dd441f5..8c2040fce 100644 --- a/testdata/iter_fwdfirstequaltcp.rpl +++ b/testdata/iter_fwdfirstequaltcp.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no tcp-upstream: no #tls-upstream:no # same case but not testable in rpl. diff --git a/testdata/iter_fwdstub.rpl b/testdata/iter_fwdstub.rpl index ad5b57cb7..4c741a50f 100644 --- a/testdata/iter_fwdstub.rpl +++ b/testdata/iter_fwdstub.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_fwdstubroot.rpl b/testdata/iter_fwdstubroot.rpl index fa930430d..dd93ecdef 100644 --- a/testdata/iter_fwdstubroot.rpl +++ b/testdata/iter_fwdstubroot.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_ghost_grandchild_delegation.rpl b/testdata/iter_ghost_grandchild_delegation.rpl index d1e521b57..af6a570eb 100644 --- a/testdata/iter_ghost_grandchild_delegation.rpl +++ b/testdata/iter_ghost_grandchild_delegation.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_ghost_sub.rpl b/testdata/iter_ghost_sub.rpl index ccb736755..36767bb34 100644 --- a/testdata/iter_ghost_sub.rpl +++ b/testdata/iter_ghost_sub.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_ghost_timewindow.rpl b/testdata/iter_ghost_timewindow.rpl index 9e304628c..24390a09c 100644 --- a/testdata/iter_ghost_timewindow.rpl +++ b/testdata/iter_ghost_timewindow.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no discard-timeout: 86400 stub-zone: diff --git a/testdata/iter_got6only.rpl b/testdata/iter_got6only.rpl index 155228439..b0d20b3f4 100644 --- a/testdata/iter_got6only.rpl +++ b/testdata/iter_got6only.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0 " qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/iter_hint_lame.rpl b/testdata/iter_hint_lame.rpl index 2fb6dde72..26aa5dc73 100644 --- a/testdata/iter_hint_lame.rpl +++ b/testdata/iter_hint_lame.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_lame_noaa.rpl b/testdata/iter_lame_noaa.rpl index defaa5ca8..050866c65 100644 --- a/testdata/iter_lame_noaa.rpl +++ b/testdata/iter_lame_noaa.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_lame_nosoa.rpl b/testdata/iter_lame_nosoa.rpl index 3bf6ccc18..d55ff78d6 100644 --- a/testdata/iter_lame_nosoa.rpl +++ b/testdata/iter_lame_nosoa.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_mod.rpl b/testdata/iter_mod.rpl index 35b3a5af6..3d3d6789d 100644 --- a/testdata/iter_mod.rpl +++ b/testdata/iter_mod.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" module-config: "iterator" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_ns_badip.rpl b/testdata/iter_ns_badip.rpl index e0bf96674..481f47a0a 100644 --- a/testdata/iter_ns_badip.rpl +++ b/testdata/iter_ns_badip.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "3 2 1 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_ns_spoof.rpl b/testdata/iter_ns_spoof.rpl index f67457635..999ff05ff 100644 --- a/testdata/iter_ns_spoof.rpl +++ b/testdata/iter_ns_spoof.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/iter_nxns_fallback.rpl b/testdata/iter_nxns_fallback.rpl index a9436529a..b4e234130 100644 --- a/testdata/iter_nxns_fallback.rpl +++ b/testdata/iter_nxns_fallback.rpl @@ -8,6 +8,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_pc_a.rpl b/testdata/iter_pc_a.rpl index d9add0056..be73a796a 100644 --- a/testdata/iter_pc_a.rpl +++ b/testdata/iter_pc_a.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pc_aaaa.rpl b/testdata/iter_pc_aaaa.rpl index a28354306..a7ce1866f 100644 --- a/testdata/iter_pc_aaaa.rpl +++ b/testdata/iter_pc_aaaa.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pcdiff.rpl b/testdata/iter_pcdiff.rpl index 57fb109af..a462d333e 100644 --- a/testdata/iter_pcdiff.rpl +++ b/testdata/iter_pcdiff.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pcdirect.rpl b/testdata/iter_pcdirect.rpl index 0bd5dfe78..656ec7af4 100644 --- a/testdata/iter_pcdirect.rpl +++ b/testdata/iter_pcdirect.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pcname.rpl b/testdata/iter_pcname.rpl index e17c9102c..af53c901b 100644 --- a/testdata/iter_pcname.rpl +++ b/testdata/iter_pcname.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pcnamech.rpl b/testdata/iter_pcnamech.rpl index 32b3130c8..805cb18f7 100644 --- a/testdata/iter_pcnamech.rpl +++ b/testdata/iter_pcnamech.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_pcnamechrec.rpl b/testdata/iter_pcnamechrec.rpl index 8bf7ad879..bbb9c863d 100644 --- a/testdata/iter_pcnamechrec.rpl +++ b/testdata/iter_pcnamechrec.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_pcnamerec.rpl b/testdata/iter_pcnamerec.rpl index faee6d029..2ea0dada3 100644 --- a/testdata/iter_pcnamerec.rpl +++ b/testdata/iter_pcnamerec.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_pcttl.rpl b/testdata/iter_pcttl.rpl index 413f8cb88..a70201710 100644 --- a/testdata/iter_pcttl.rpl +++ b/testdata/iter_pcttl.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" do-ip6: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch.rpl b/testdata/iter_prefetch.rpl index bad92dc57..fdf595564 100644 --- a/testdata/iter_prefetch.rpl +++ b/testdata/iter_prefetch.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch_change.rpl b/testdata/iter_prefetch_change.rpl index 1be9e6abe..c1a1a710f 100644 --- a/testdata/iter_prefetch_change.rpl +++ b/testdata/iter_prefetch_change.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch_change2.rpl b/testdata/iter_prefetch_change2.rpl index 7a8370ff6..4a966fea0 100644 --- a/testdata/iter_prefetch_change2.rpl +++ b/testdata/iter_prefetch_change2.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch_childns.rpl b/testdata/iter_prefetch_childns.rpl index 00a91fcde..f234065e7 100644 --- a/testdata/iter_prefetch_childns.rpl +++ b/testdata/iter_prefetch_childns.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch_fail.rpl b/testdata/iter_prefetch_fail.rpl index 1d92a4c1c..d1e308305 100644 --- a/testdata/iter_prefetch_fail.rpl +++ b/testdata/iter_prefetch_fail.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_prefetch_ns.rpl b/testdata/iter_prefetch_ns.rpl index 93af21638..3192d31c0 100644 --- a/testdata/iter_prefetch_ns.rpl +++ b/testdata/iter_prefetch_ns.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" prefetch: "yes" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_primenoglue.rpl b/testdata/iter_primenoglue.rpl index b9808dd2c..f8c980350 100644 --- a/testdata/iter_primenoglue.rpl +++ b/testdata/iter_primenoglue.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_privaddr.rpl b/testdata/iter_privaddr.rpl index 0c87b4b9a..b7a6fde29 100644 --- a/testdata/iter_privaddr.rpl +++ b/testdata/iter_privaddr.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 diff --git a/testdata/iter_ranoaa_lame.rpl b/testdata/iter_ranoaa_lame.rpl index 8ee82415a..313192f10 100644 --- a/testdata/iter_ranoaa_lame.rpl +++ b/testdata/iter_ranoaa_lame.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_reclame_one.rpl b/testdata/iter_reclame_one.rpl index 4a6abfae5..d273e6056 100644 --- a/testdata/iter_reclame_one.rpl +++ b/testdata/iter_reclame_one.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_reclame_two.rpl b/testdata/iter_reclame_two.rpl index 76c310b28..e2b2bc126 100644 --- a/testdata/iter_reclame_two.rpl +++ b/testdata/iter_reclame_two.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/iter_recurse.rpl b/testdata/iter_recurse.rpl index be50b4af8..135287678 100644 --- a/testdata/iter_recurse.rpl +++ b/testdata/iter_recurse.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_resolve.rpl b/testdata/iter_resolve.rpl index ed051ff24..3ea56abe9 100644 --- a/testdata/iter_resolve.rpl +++ b/testdata/iter_resolve.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_resolve_minimised.rpl b/testdata/iter_resolve_minimised.rpl index 2c6f9ccf5..13f04d481 100644 --- a/testdata/iter_resolve_minimised.rpl +++ b/testdata/iter_resolve_minimised.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_resolve_minimised_nx.rpl b/testdata/iter_resolve_minimised_nx.rpl index 74e612ccb..c68f20ca8 100644 --- a/testdata/iter_resolve_minimised_nx.rpl +++ b/testdata/iter_resolve_minimised_nx.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_resolve_minimised_refused.rpl b/testdata/iter_resolve_minimised_refused.rpl index 66e8e631e..8dc76e258 100644 --- a/testdata/iter_resolve_minimised_refused.rpl +++ b/testdata/iter_resolve_minimised_refused.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_resolve_minimised_timeout.rpl b/testdata/iter_resolve_minimised_timeout.rpl index 86b932160..3740d79f4 100644 --- a/testdata/iter_resolve_minimised_timeout.rpl +++ b/testdata/iter_resolve_minimised_timeout.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_scrub_cname_an.rpl b/testdata/iter_scrub_cname_an.rpl index 9c5060af7..f81916b0c 100644 --- a/testdata/iter_scrub_cname_an.rpl +++ b/testdata/iter_scrub_cname_an.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_scrub_dname_insec.rpl b/testdata/iter_scrub_dname_insec.rpl index 826d89e29..82ff1d3da 100644 --- a/testdata/iter_scrub_dname_insec.rpl +++ b/testdata/iter_scrub_dname_insec.rpl @@ -4,6 +4,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_scrub_dname_rev.rpl b/testdata/iter_scrub_dname_rev.rpl index 9caca66c0..dfb21b8b6 100644 --- a/testdata/iter_scrub_dname_rev.rpl +++ b/testdata/iter_scrub_dname_rev.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_scrub_dname_sec.rpl b/testdata/iter_scrub_dname_sec.rpl index 34a7b324d..943b19ff5 100644 --- a/testdata/iter_scrub_dname_sec.rpl +++ b/testdata/iter_scrub_dname_sec.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_scrub_promiscuous.rpl b/testdata/iter_scrub_promiscuous.rpl new file mode 100644 index 000000000..febbee81c --- /dev/null +++ b/testdata/iter_scrub_promiscuous.rpl @@ -0,0 +1,457 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + qname-minimisation: no + iter-scrub-promiscuous: yes + +stub-zone: + name: "." + stub-addr: 1.2.3.0 # ns.root +CONFIG_END + +SCENARIO_BEGIN Test iterator with scrub of promiscuous records +; The test queries receive spoofed answers. The check queries see if +; the record is returned by the original server or by a spoofed source. +; The test domains are pollute1.mesa, pollute2.mesa and pollute3.mesa. +; The spoofed contents are ns.attacker.mesa and its IPs 5.6.7.8 and 5.6.7.9. +; The pollute1.mesa NS, ns.pollute2.mesa A, and test3.atkr.pollute3.mesa NS +; with ns.pollute3.mesa A records are tested for cache placement. +; pollute4.mesa uses YXDOMAIN. + +; ns.root +RANGE_BEGIN 0 400 + ADDRESS 1.2.3.0 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS NS.ROOT. +SECTION ADDITIONAL +NS.ROOT. IN A 1.2.3.0 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +mesa. IN NS +SECTION AUTHORITY +mesa. IN NS ns.mesa. +SECTION ADDITIONAL +ns.mesa. IN A 1.2.7.7 +ENTRY_END +RANGE_END + +; ns.mesa +RANGE_BEGIN 0 400 + ADDRESS 1.2.7.7 +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +pollute1.mesa. IN NS +SECTION AUTHORITY +pollute1.mesa. IN NS ns.pollute1.mesa. +SECTION ADDITIONAL +ns.pollute1.mesa. IN A 1.2.4.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +pollute2.mesa. IN NS +SECTION AUTHORITY +pollute2.mesa. IN NS ns.pollute2.mesa. +SECTION ADDITIONAL +ns.pollute2.mesa. IN A 1.2.4.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +pollute3.mesa. IN NS +SECTION AUTHORITY +pollute3.mesa. IN NS ns.pollute3.mesa. +SECTION ADDITIONAL +ns.pollute3.mesa. IN A 1.2.4.3 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +pollute4.mesa. IN NS +SECTION AUTHORITY +pollute4.mesa. IN NS ns.pollute4.mesa. +SECTION ADDITIONAL +ns.pollute4.mesa. IN A 1.2.4.4 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +attacker.mesa. IN NS +SECTION AUTHORITY +attacker.mesa. IN NS ns.attacker.mesa. +SECTION ADDITIONAL +ns.attacker.mesa. IN A 5.6.7.8 +ENTRY_END +RANGE_END + +; ns.pollute1.mesa +RANGE_BEGIN 0 400 + ADDRESS 1.2.4.1 + +; This is the spoofed answer that is returned. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +test1.atkr.pollute1.mesa. IN A +SECTION ANSWER +test1.atkr.pollute1.mesa. 86400 IN A 1.2.3.4 +SECTION AUTHORITY +pollute1.mesa. 86400 IN NS ns.attacker.mesa. +ENTRY_END + +; correct answer for the check query. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute1.mesa. IN A +SECTION ANSWER +check.pollute1.mesa. IN A 1.8.9.1 +ENTRY_END +RANGE_END + +; ns.pollute2.mesa +RANGE_BEGIN 0 400 + ADDRESS 1.2.4.2 + +; This is the spoofed answer that is returned. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +test2.atkr.pollute2.mesa. IN A +SECTION ANSWER +test2.atkr.pollute2.mesa. 86400 IN A 1.2.3.4 +SECTION AUTHORITY +pollute2.mesa. 86400 IN NS ns.pollute2.mesa. +SECTION ADDITIONAL +ns.pollute2.mesa. 86400 IN A 5.6.7.8 +ENTRY_END + +; correct answer for the check query. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute2.mesa. IN A +SECTION ANSWER +check.pollute2.mesa. IN A 1.8.9.2 +ENTRY_END +RANGE_END + +; ns.pollute3.mesa +RANGE_BEGIN 0 400 + ADDRESS 1.2.4.3 + +; This is the spoofed answer that is returned. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +test3.atkr.pollute3.mesa. IN A +SECTION ANSWER +test3.atkr.pollute3.mesa. 86400 IN A 1.2.3.4 +SECTION AUTHORITY +test3.atkr.pollute3.mesa. 86400 IN NS ns.pollute3.mesa. +SECTION ADDITIONAL +ns.pollute3.mesa. 86400 IN A 5.6.7.8 +ENTRY_END + +; correct answer for the check query. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute3.mesa. IN A +SECTION ANSWER +check.pollute3.mesa. IN A 1.8.9.3 +ENTRY_END +RANGE_END + +; ns.pollute4.mesa +RANGE_BEGIN 0 400 + ADDRESS 1.2.4.4 + +; This is the spoofed answer that is returned. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA YXDOMAIN +SECTION QUESTION +test4.atkr.pollute4.mesa. IN A +SECTION ANSWER +test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4 +SECTION AUTHORITY +pollute4.mesa. 86400 IN NS ns.attacker.mesa. +ENTRY_END + +; correct answer for the check query. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute4.mesa. IN A +SECTION ANSWER +check.pollute4.mesa. IN A 1.8.9.4 +ENTRY_END +RANGE_END + +; ns.attacker.mesa +RANGE_BEGIN 0 400 + ADDRESS 5.6.7.8 + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.attacker.mesa. IN A +SECTION ANSWER +ns.attacker.mesa. 86400 IN A 5.6.7.8 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.attacker.mesa. IN AAAA +SECTION AUTHORITY +attacker.mesa. 3600 IN SOA ns.attacker.mesa. root.attacker.mesa. 4 7200 3600 604800 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.attacker.mesa. IN A +SECTION ANSWER +ns.attacker.mesa. 86400 IN A 5.6.7.8 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute1.mesa. IN A +SECTION ANSWER +check.pollute1.mesa. 86400 IN A 5.6.7.9 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute2.mesa. IN A +SECTION ANSWER +check.pollute2.mesa. 86400 IN A 5.6.7.9 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +check.pollute3.mesa. IN A +SECTION ANSWER +check.pollute3.mesa. 86400 IN A 5.6.7.9 +ENTRY_END +RANGE_END + +; Test query 1 +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +test1.atkr.pollute1.mesa. IN A +ENTRY_END + +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +test1.atkr.pollute1.mesa. IN A +SECTION ANSWER +test1.atkr.pollute1.mesa. 86400 IN A 1.2.3.4 +ENTRY_END + +; Test query 2 +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +test2.atkr.pollute2.mesa. IN A +ENTRY_END + +STEP 30 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +test2.atkr.pollute2.mesa. IN A +SECTION ANSWER +test2.atkr.pollute2.mesa. 86400 IN A 1.2.3.4 +ENTRY_END + +; Test query 3 +STEP 40 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +test3.atkr.pollute3.mesa. IN A +ENTRY_END + +STEP 50 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +test3.atkr.pollute3.mesa. IN A +SECTION ANSWER +test3.atkr.pollute3.mesa. 86400 IN A 1.2.3.4 +ENTRY_END + +; Check the cache contents, for query 1. +STEP 60 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +check.pollute1.mesa. IN A +ENTRY_END + +STEP 70 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +check.pollute1.mesa. IN A +SECTION ANSWER +; good answer +check.pollute1.mesa. IN A 1.8.9.1 +; bad answer +;check.pollute1.mesa. IN A 5.6.7.9 +ENTRY_END + +; Check the cache contents, for query 2. +STEP 80 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +check.pollute2.mesa. IN A +ENTRY_END + +STEP 90 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +check.pollute2.mesa. IN A +SECTION ANSWER +; good answer +check.pollute2.mesa. IN A 1.8.9.2 +; bad answer +;check.pollute2.mesa. IN A 5.6.7.9 +ENTRY_END + +; Check the cache contents, for query 3. +STEP 100 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +check.pollute3.mesa. IN A +ENTRY_END + +STEP 110 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +check.pollute3.mesa. IN A +SECTION ANSWER +; good answer +check.pollute3.mesa. IN A 1.8.9.3 +; bad answer +;check.pollute3.mesa. IN A 5.6.7.9 +ENTRY_END + +; Test query 4 +STEP 120 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +test4.atkr.pollute4.mesa. IN A +ENTRY_END + +STEP 130 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA YXDOMAIN +SECTION QUESTION +test4.atkr.pollute4.mesa. IN A +SECTION ANSWER +test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4 +SECTION AUTHORITY +; removed record +;pollute4.mesa. 0 IN NS ns.attacker.mesa. +ENTRY_END + +; Check the cache contents, for query 4. +STEP 140 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +check.pollute4.mesa. IN A +ENTRY_END + +STEP 150 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +check.pollute4.mesa. IN A +SECTION ANSWER +; good answer +check.pollute4.mesa. IN A 1.8.9.4 +; bad answer +;check.pollute4.mesa. IN A 5.6.7.9 +ENTRY_END + +SCENARIO_END diff --git a/testdata/iter_scrub_rr_length.rpl b/testdata/iter_scrub_rr_length.rpl index ee7579f9c..143e0fc50 100644 --- a/testdata/iter_scrub_rr_length.rpl +++ b/testdata/iter_scrub_rr_length.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no ede: yes diff --git a/testdata/iter_soamin.rpl b/testdata/iter_soamin.rpl index 7e902601b..0facc3508 100644 --- a/testdata/iter_soamin.rpl +++ b/testdata/iter_soamin.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_stub_noroot.rpl b/testdata/iter_stub_noroot.rpl index ef306bd42..749462b6e 100644 --- a/testdata/iter_stub_noroot.rpl +++ b/testdata/iter_stub_noroot.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_stubfirst.rpl b/testdata/iter_stubfirst.rpl index 1a7112de4..7cd3305a9 100644 --- a/testdata/iter_stubfirst.rpl +++ b/testdata/iter_stubfirst.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_timeout_ra_aaaa.rpl b/testdata/iter_timeout_ra_aaaa.rpl index 126867ba4..9456f0420 100644 --- a/testdata/iter_timeout_ra_aaaa.rpl +++ b/testdata/iter_timeout_ra_aaaa.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/iter_unverified_glue.rpl b/testdata/iter_unverified_glue.rpl index 017f220b6..bc96bb14a 100644 --- a/testdata/iter_unverified_glue.rpl +++ b/testdata/iter_unverified_glue.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no do-ip6: no harden-unverified-glue: yes stub-zone: diff --git a/testdata/ratelimit.tdir/ratelimit.testns b/testdata/ratelimit.tdir/ratelimit.testns index 563c1db6a..5c22c292d 100644 --- a/testdata/ratelimit.tdir/ratelimit.testns +++ b/testdata/ratelimit.tdir/ratelimit.testns @@ -3,13 +3,31 @@ $ORIGIN example.com. $TTL 3600 ENTRY_BEGIN -MATCH opcode qtype +MATCH opcode qname qtype REPLY QR AA NOERROR -ADJUST copy_id copy_query +ADJUST copy_id SECTION QUESTION -wild IN A +www1 IN A SECTION ANSWER -wild IN A 10.20.30.40 -SECTION AUTHORITY -example.com. IN NS ns.example.com. +www1 IN A 1.1.1.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qname qtype +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www2 IN A +SECTION ANSWER +www2 IN A 2.2.2.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qname qtype +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www3 IN A +SECTION ANSWER +www3 IN A 3.3.3.3 ENTRY_END diff --git a/testdata/rrset_rettl.rpl b/testdata/rrset_rettl.rpl index 55dd62386..131a98e71 100644 --- a/testdata/rrset_rettl.rpl +++ b/testdata/rrset_rettl.rpl @@ -2,6 +2,7 @@ ; config options go here. server: minimal-responses: no + iter-scrub-promiscuous: no forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/rrset_untrusted.rpl b/testdata/rrset_untrusted.rpl index 6370ebf49..207275b56 100644 --- a/testdata/rrset_untrusted.rpl +++ b/testdata/rrset_untrusted.rpl @@ -2,6 +2,7 @@ ; config options go here. server: minimal-responses: no + iter-scrub-promiscuous: no forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/rrset_updated.rpl b/testdata/rrset_updated.rpl index 55da56bac..ba8e4924c 100644 --- a/testdata/rrset_updated.rpl +++ b/testdata/rrset_updated.rpl @@ -2,6 +2,7 @@ ; config options go here. server: minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/rrset_use_cached.rpl b/testdata/rrset_use_cached.rpl index 7af5c85d2..3fa1a9554 100644 --- a/testdata/rrset_use_cached.rpl +++ b/testdata/rrset_use_cached.rpl @@ -1,5 +1,6 @@ server: minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes # The value does not matter, we will not simulate delay. # We do not want only serve-expired because fetches from that diff --git a/testdata/serve_expired.rpl b/testdata/serve_expired.rpl index 4aa65e167..2fd7459c1 100644 --- a/testdata/serve_expired.rpl +++ b/testdata/serve_expired.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_expired_0ttl_nodata.rpl b/testdata/serve_expired_0ttl_nodata.rpl index a53df437a..6c2f6c92f 100644 --- a/testdata/serve_expired_0ttl_nodata.rpl +++ b/testdata/serve_expired_0ttl_nodata.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_expired_0ttl_nxdomain.rpl b/testdata/serve_expired_0ttl_nxdomain.rpl index 7dd27b8d5..8029a06dc 100644 --- a/testdata/serve_expired_0ttl_nxdomain.rpl +++ b/testdata/serve_expired_0ttl_nxdomain.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 ede: yes diff --git a/testdata/serve_expired_0ttl_servfail.rpl b/testdata/serve_expired_0ttl_servfail.rpl index 9e5a17a09..181f0b4a3 100644 --- a/testdata/serve_expired_0ttl_servfail.rpl +++ b/testdata/serve_expired_0ttl_servfail.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 ede: yes diff --git a/testdata/serve_expired_cached_servfail.rpl b/testdata/serve_expired_cached_servfail.rpl index eb115816e..e7cd5ca39 100644 --- a/testdata/serve_expired_cached_servfail.rpl +++ b/testdata/serve_expired_cached_servfail.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_expired_client_timeout.rpl b/testdata/serve_expired_client_timeout.rpl index c44543692..5d194ccdd 100644 --- a/testdata/serve_expired_client_timeout.rpl +++ b/testdata/serve_expired_client_timeout.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 1 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_expired_client_timeout_servfail.rpl b/testdata/serve_expired_client_timeout_servfail.rpl index 46fe032fb..8b77448aa 100644 --- a/testdata/serve_expired_client_timeout_servfail.rpl +++ b/testdata/serve_expired_client_timeout_servfail.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 1 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_expired_client_timeout_val_insecure_delegation.rpl b/testdata/serve_expired_client_timeout_val_insecure_delegation.rpl index 6654a2c68..08fc07158 100644 --- a/testdata/serve_expired_client_timeout_val_insecure_delegation.rpl +++ b/testdata/serve_expired_client_timeout_val_insecure_delegation.rpl @@ -9,6 +9,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no serve-expired: yes diff --git a/testdata/serve_expired_reply_ttl.rpl b/testdata/serve_expired_reply_ttl.rpl index c7859e00e..0fe0eb3d3 100644 --- a/testdata/serve_expired_reply_ttl.rpl +++ b/testdata/serve_expired_reply_ttl.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-reply-ttl: 123 serve-expired-client-timeout: 0 diff --git a/testdata/serve_expired_ttl.rpl b/testdata/serve_expired_ttl.rpl index 66acbdcf1..24cb34136 100644 --- a/testdata/serve_expired_ttl.rpl +++ b/testdata/serve_expired_ttl.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-ttl: 10 diff --git a/testdata/serve_expired_ttl_client_timeout.rpl b/testdata/serve_expired_ttl_client_timeout.rpl index d1aef32af..e893080cf 100644 --- a/testdata/serve_expired_ttl_client_timeout.rpl +++ b/testdata/serve_expired_ttl_client_timeout.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-ttl: 10 serve-expired-client-timeout: 1 diff --git a/testdata/serve_expired_zerottl.rpl b/testdata/serve_expired_zerottl.rpl index 50a50bb3b..f514ffc67 100644 --- a/testdata/serve_expired_zerottl.rpl +++ b/testdata/serve_expired_zerottl.rpl @@ -3,6 +3,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 diff --git a/testdata/serve_original_ttl.rpl b/testdata/serve_original_ttl.rpl index 30503c285..ee80b550f 100644 --- a/testdata/serve_original_ttl.rpl +++ b/testdata/serve_original_ttl.rpl @@ -4,6 +4,7 @@ server: module-config: "validator iterator" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no serve-original-ttl: yes cache-max-ttl: 1000 cache-min-ttl: 20 diff --git a/testdata/stat_values.tdir/stat_values.test b/testdata/stat_values.tdir/stat_values.test index 7dd71edd6..9156f95a9 100644 --- a/testdata/stat_values.tdir/stat_values.test +++ b/testdata/stat_values.tdir/stat_values.test @@ -468,8 +468,10 @@ bring_up_alternate_configuration ub_discard_wait_limit.conf teststep "Check discard-timeout and wait-limit" echo "> dig www.unresponsive" dig @127.0.0.1 -p $UNBOUND_PORT +retry=2 +timeout=1 www.unresponsive. | tee outfile -echo "> check answer" -if grep "no servers could be reached" outfile; then +# Wait for nonresponse servfail, that causes discards. +sleep 2 +if grep "no servers could be reached" outfile || + grep "Too many queries queued up and waiting" outfile; then echo "OK" else end 1 diff --git a/testdata/subnet_cached.crpl b/testdata/subnet_cached.crpl index 3cee6e978..c97bfbbe8 100644 --- a/testdata/subnet_cached.crpl +++ b/testdata/subnet_cached.crpl @@ -15,6 +15,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/subnet_cached_servfail.crpl b/testdata/subnet_cached_servfail.crpl index 1bcd05f2f..7eec28817 100644 --- a/testdata/subnet_cached_servfail.crpl +++ b/testdata/subnet_cached_servfail.crpl @@ -11,6 +11,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 prefetch: yes diff --git a/testdata/subnet_cached_size.crpl b/testdata/subnet_cached_size.crpl index d221d0d37..4a8c46449 100644 --- a/testdata/subnet_cached_size.crpl +++ b/testdata/subnet_cached_size.crpl @@ -15,6 +15,7 @@ server: access-control: 127.0.0.0/8 allow_snoop qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no ; the size for the edns subnet cache msg-cache-size: 1500 diff --git a/testdata/subnet_global_prefetch.crpl b/testdata/subnet_global_prefetch.crpl index 2f005d43b..7665015c0 100644 --- a/testdata/subnet_global_prefetch.crpl +++ b/testdata/subnet_global_prefetch.crpl @@ -12,6 +12,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no prefetch: yes stub-zone: diff --git a/testdata/subnet_global_prefetch_always_forward.crpl b/testdata/subnet_global_prefetch_always_forward.crpl index f2c8bdb60..a34a314af 100644 --- a/testdata/subnet_global_prefetch_always_forward.crpl +++ b/testdata/subnet_global_prefetch_always_forward.crpl @@ -16,6 +16,7 @@ server: minimal-responses: no ede: yes ede-serve-expired: yes + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/subnet_global_prefetch_expired.crpl b/testdata/subnet_global_prefetch_expired.crpl index a347550ba..500930f72 100644 --- a/testdata/subnet_global_prefetch_expired.crpl +++ b/testdata/subnet_global_prefetch_expired.crpl @@ -13,6 +13,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no serve-expired: yes serve-expired-client-timeout: 0 serve-expired-ttl: 1 diff --git a/testdata/subnet_global_prefetch_with_client_ecs.crpl b/testdata/subnet_global_prefetch_with_client_ecs.crpl index ddc832c47..8589db7e1 100644 --- a/testdata/subnet_global_prefetch_with_client_ecs.crpl +++ b/testdata/subnet_global_prefetch_with_client_ecs.crpl @@ -12,6 +12,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no prefetch: yes stub-zone: diff --git a/testdata/subnet_max_source.crpl b/testdata/subnet_max_source.crpl index f5c7464ed..f3f71e7fd 100644 --- a/testdata/subnet_max_source.crpl +++ b/testdata/subnet_max_source.crpl @@ -11,6 +11,7 @@ server: verbosity: 3 qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/subnet_prefetch.crpl b/testdata/subnet_prefetch.crpl index aaa6bf08c..243e40950 100644 --- a/testdata/subnet_prefetch.crpl +++ b/testdata/subnet_prefetch.crpl @@ -12,6 +12,7 @@ server: access-control: 127.0.0.1 allow_snoop qname-minimisation: no minimal-responses: no + iter-scrub-promiscuous: no prefetch: yes stub-zone: diff --git a/testdata/subnet_val_positive.crpl b/testdata/subnet_val_positive.crpl index 01456e58b..10996ada8 100644 --- a/testdata/subnet_val_positive.crpl +++ b/testdata/subnet_val_positive.crpl @@ -13,6 +13,7 @@ server: fake-dsa: yes qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/subnet_val_positive_client.crpl b/testdata/subnet_val_positive_client.crpl index b573742b7..1b51d52ef 100644 --- a/testdata/subnet_val_positive_client.crpl +++ b/testdata/subnet_val_positive_client.crpl @@ -14,6 +14,7 @@ server: fake-dsa: yes qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/trust_cname_chain.rpl b/testdata/trust_cname_chain.rpl index f8415ba23..e24f8c10d 100644 --- a/testdata/trust_cname_chain.rpl +++ b/testdata/trust_cname_chain.rpl @@ -2,6 +2,7 @@ server: target-fetch-policy: "0 0 0 0 0" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. diff --git a/testdata/ttl_max.rpl b/testdata/ttl_max.rpl index 325696321..b24eea383 100644 --- a/testdata/ttl_max.rpl +++ b/testdata/ttl_max.rpl @@ -4,6 +4,7 @@ server: cache-max-ttl: 10 qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/ttl_min.rpl b/testdata/ttl_min.rpl index 3c79ff5ed..94206c7c5 100644 --- a/testdata/ttl_min.rpl +++ b/testdata/ttl_min.rpl @@ -4,6 +4,7 @@ server: cache-min-ttl: 10 qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_adbit.rpl b/testdata/val_adbit.rpl index 7ce62de77..233c58bef 100644 --- a/testdata/val_adbit.rpl +++ b/testdata/val_adbit.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_adcopy.rpl b/testdata/val_adcopy.rpl index 604fd57f2..7bc31df23 100644 --- a/testdata/val_adcopy.rpl +++ b/testdata/val_adcopy.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_cnametocnamewctoposwc.rpl b/testdata/val_cnametocnamewctoposwc.rpl index 407666efc..9ea8b493e 100644 --- a/testdata/val_cnametocnamewctoposwc.rpl +++ b/testdata/val_cnametocnamewctoposwc.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes trust-anchor-signaling: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_ds_afterprime.rpl b/testdata/val_ds_afterprime.rpl index 3b1c0d614..301a1f6b6 100644 --- a/testdata/val_ds_afterprime.rpl +++ b/testdata/val_ds_afterprime.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_faildnskey_ok.rpl b/testdata/val_faildnskey_ok.rpl index 50f3184b4..f9196f35f 100644 --- a/testdata/val_faildnskey_ok.rpl +++ b/testdata/val_faildnskey_ok.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_keyprefetch_verify.rpl b/testdata/val_keyprefetch_verify.rpl index 9b901a8cb..6cf81848d 100644 --- a/testdata/val_keyprefetch_verify.rpl +++ b/testdata/val_keyprefetch_verify.rpl @@ -10,6 +10,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_noadwhennodo.rpl b/testdata/val_noadwhennodo.rpl index 46e1bad5a..dbdeb780e 100644 --- a/testdata/val_noadwhennodo.rpl +++ b/testdata/val_noadwhennodo.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_nsec3_b3_optout.rpl b/testdata/val_nsec3_b3_optout.rpl index 9d84be974..5d8a43a9b 100644 --- a/testdata/val_nsec3_b3_optout.rpl +++ b/testdata/val_nsec3_b3_optout.rpl @@ -7,6 +7,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/val_nsec3_b3_optout_negcache.rpl b/testdata/val_nsec3_b3_optout_negcache.rpl index 497a8591a..e7be762fb 100644 --- a/testdata/val_nsec3_b3_optout_negcache.rpl +++ b/testdata/val_nsec3_b3_optout_negcache.rpl @@ -7,6 +7,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/val_nsec3_b4_wild.rpl b/testdata/val_nsec3_b4_wild.rpl index 8bf3a5466..295932fad 100644 --- a/testdata/val_nsec3_b4_wild.rpl +++ b/testdata/val_nsec3_b4_wild.rpl @@ -6,6 +6,7 @@ server: qname-minimisation: "no" fake-sha1: yes trust-anchor-signaling: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/val_nsec3_cnametocnamewctoposwc.rpl b/testdata/val_nsec3_cnametocnamewctoposwc.rpl index 1651ae7dc..3e4c55a18 100644 --- a/testdata/val_nsec3_cnametocnamewctoposwc.rpl +++ b/testdata/val_nsec3_cnametocnamewctoposwc.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes trust-anchor-signaling: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_positive.rpl b/testdata/val_positive.rpl index daaf36089..c80851703 100644 --- a/testdata/val_positive.rpl +++ b/testdata/val_positive.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_positive_wc.rpl b/testdata/val_positive_wc.rpl index 5384acf63..591dcc603 100644 --- a/testdata/val_positive_wc.rpl +++ b/testdata/val_positive_wc.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes trust-anchor-signaling: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_qds_badanc.rpl b/testdata/val_qds_badanc.rpl index dc686153f..cb53136f6 100644 --- a/testdata/val_qds_badanc.rpl +++ b/testdata/val_qds_badanc.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_qds_oneanc.rpl b/testdata/val_qds_oneanc.rpl index f21ab422b..bda9f9032 100644 --- a/testdata/val_qds_oneanc.rpl +++ b/testdata/val_qds_oneanc.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_qds_twoanc.rpl b/testdata/val_qds_twoanc.rpl index 4e4f2e732..f801c023b 100644 --- a/testdata/val_qds_twoanc.rpl +++ b/testdata/val_qds_twoanc.rpl @@ -9,6 +9,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_refer_unsignadd.rpl b/testdata/val_refer_unsignadd.rpl index 4d073016f..22f15d21a 100644 --- a/testdata/val_refer_unsignadd.rpl +++ b/testdata/val_refer_unsignadd.rpl @@ -9,6 +9,7 @@ server: qname-minimisation: "no" fake-sha1: yes trust-anchor-signaling: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/val_referd.rpl b/testdata/val_referd.rpl index d475f835e..a25ca7b7d 100644 --- a/testdata/val_referd.rpl +++ b/testdata/val_referd.rpl @@ -10,6 +10,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_referglue.rpl b/testdata/val_referglue.rpl index 54b767156..3ca0c0e80 100644 --- a/testdata/val_referglue.rpl +++ b/testdata/val_referglue.rpl @@ -10,6 +10,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no stub-zone: diff --git a/testdata/val_rrsig.rpl b/testdata/val_rrsig.rpl index 0b672e0f2..69df344a5 100644 --- a/testdata/val_rrsig.rpl +++ b/testdata/val_rrsig.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_spurious_ns.rpl b/testdata/val_spurious_ns.rpl index cb0a6e529..8db94a108 100644 --- a/testdata/val_spurious_ns.rpl +++ b/testdata/val_spurious_ns.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_stub_noroot.rpl b/testdata/val_stub_noroot.rpl index 07113bef7..66c3d8e88 100644 --- a/testdata/val_stub_noroot.rpl +++ b/testdata/val_stub_noroot.rpl @@ -6,6 +6,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_ta_algo_dnskey.rpl b/testdata/val_ta_algo_dnskey.rpl index 03bac83aa..5b0b64d25 100644 --- a/testdata/val_ta_algo_dnskey.rpl +++ b/testdata/val_ta_algo_dnskey.rpl @@ -9,6 +9,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_ta_algo_dnskey_dp.rpl b/testdata/val_ta_algo_dnskey_dp.rpl index 2b3609be8..ae0c499ca 100644 --- a/testdata/val_ta_algo_dnskey_dp.rpl +++ b/testdata/val_ta_algo_dnskey_dp.rpl @@ -10,6 +10,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_ta_algo_missing_dp.rpl b/testdata/val_ta_algo_missing_dp.rpl index dc55a09da..14efdeccb 100644 --- a/testdata/val_ta_algo_missing_dp.rpl +++ b/testdata/val_ta_algo_missing_dp.rpl @@ -11,6 +11,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_twocname.rpl b/testdata/val_twocname.rpl index bc7c3bcb2..b4323644a 100644 --- a/testdata/val_twocname.rpl +++ b/testdata/val_twocname.rpl @@ -5,6 +5,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no rrset-roundrobin: no forward-zone: diff --git a/testdata/val_unalgo_anchor.rpl b/testdata/val_unalgo_anchor.rpl index fbbf288a5..a93520122 100644 --- a/testdata/val_unalgo_anchor.rpl +++ b/testdata/val_unalgo_anchor.rpl @@ -7,6 +7,7 @@ server: qname-minimisation: "no" fake-sha1: yes minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/val_wild_pos.rpl b/testdata/val_wild_pos.rpl index 624d8e07b..9fafa6554 100644 --- a/testdata/val_wild_pos.rpl +++ b/testdata/val_wild_pos.rpl @@ -8,6 +8,7 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no + iter-scrub-promiscuous: no stub-zone: name: "." diff --git a/testdata/views.rpl b/testdata/views.rpl index 6a9052fbe..a6026244b 100644 --- a/testdata/views.rpl +++ b/testdata/views.rpl @@ -3,6 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no + iter-scrub-promiscuous: no access-control: 10.10.10.0/24 allow access-control-view: 10.10.10.10/32 "view1" diff --git a/util/config_file.c b/util/config_file.c index 3db956262..8fd0abba9 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -422,6 +422,7 @@ config_create(void) cfg->dns_error_reporting = 0; cfg->iter_scrub_ns = 20; cfg->iter_scrub_cname = 11; + cfg->iter_scrub_promiscuous = 1; cfg->max_global_quota = 200; return cfg; error_exit: @@ -767,6 +768,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_YNO("dns-error-reporting:", dns_error_reporting) else S_NUMBER_OR_ZERO("iter-scrub-ns:", iter_scrub_ns) else S_NUMBER_OR_ZERO("iter-scrub-cname:", iter_scrub_cname) + else S_YNO("iter-scrub-promiscuous:", iter_scrub_promiscuous) else S_NUMBER_OR_ZERO("max-global-quota:", max_global_quota) else S_YNO("serve-original-ttl:", serve_original_ttl) else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations) @@ -1244,6 +1246,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "dns-error-reporting", dns_error_reporting) else O_DEC(opt, "iter-scrub-ns", iter_scrub_ns) else O_DEC(opt, "iter-scrub-cname", iter_scrub_cname) + else O_YNO(opt, "iter-scrub-promiscuous", iter_scrub_promiscuous) else O_DEC(opt, "max-global-quota", max_global_quota) else O_YNO(opt, "serve-original-ttl", serve_original_ttl) else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations) diff --git a/util/config_file.h b/util/config_file.h index 209d71247..ebdc1b34d 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -794,6 +794,9 @@ struct config_file { int iter_scrub_cname; /** limit on upstream queries for an incoming query and subqueries. */ int max_global_quota; + /** Should the iterator scrub promiscuous NS rrsets, from positive + * answers. */ + int iter_scrub_promiscuous; }; /** from cfg username, after daemonize setup performed */ diff --git a/util/configlexer.lex b/util/configlexer.lex index 8e38ef468..22f98e464 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -607,6 +607,7 @@ proxy-protocol-port{COLON} { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) } iter-scrub-ns{COLON} { YDVAR(1, VAR_ITER_SCRUB_NS) } iter-scrub-cname{COLON} { YDVAR(1, VAR_ITER_SCRUB_CNAME) } max-global-quota{COLON} { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) } +iter-scrub-promiscuous{COLON} { YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ diff --git a/util/configparser.y b/util/configparser.y index ced904669..bf9c196fc 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -216,6 +216,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED %token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME %token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO +%token VAR_ITER_SCRUB_PROMISCUOUS %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -358,7 +359,7 @@ content_server: server_num_threads | server_verbosity | server_port | server_harden_unknown_additional | server_disable_edns_do | server_log_destaddr | server_cookie_secret_file | server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota | - server_harden_unverified_glue | server_log_time_iso + server_harden_unverified_glue | server_log_time_iso | server_iter_scrub_promiscuous ; stub_clause: stubstart contents_stub { @@ -4251,6 +4252,16 @@ server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG free($2); } ; +server_iter_scrub_promiscuous: VAR_ITER_SCRUB_PROMISCUOUS STRING_ARG + { + OUTYY(("P(server_iter_scrub_promiscuous:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->iter_scrub_promiscuous = + (strcmp($2, "yes")==0); + free($2); + } + ; ipsetstart: VAR_IPSET { OUTYY(("\nP(ipset:)\n")); diff --git a/util/iana_ports.inc b/util/iana_ports.inc index 6d8cfd27b..a60f2307e 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -649,9 +649,6 @@ 828, 829, 830, -831, -832, -833, 847, 848, 853, @@ -5343,6 +5340,7 @@ 24465, 24554, 24577, +24601, 24676, 24677, 24678, diff --git a/util/net_help.c b/util/net_help.c index 426ace934..9ad9a3bb8 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -783,7 +783,7 @@ sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1, } int -addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) +addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len) { if(len == (socklen_t)sizeof(struct sockaddr_in6) && ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) diff --git a/util/net_help.h b/util/net_help.h index 7b8a20642..1f31a89c3 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -307,7 +307,7 @@ int sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1, * @param len: the length of addr. * @return: true if sockaddr is ip6. */ -int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len); +int addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len); /** * Make sure the sockaddr ends in zeroes. For tree insertion and subsequent diff --git a/util/netevent.c b/util/netevent.c index aedcb5e07..2943a50d0 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -6728,7 +6728,6 @@ comm_point_send_reply(struct comm_reply *repinfo) tcp_req_info_send_reply(repinfo->c->tcp_req_info); } else if(repinfo->c->use_h2) { if(!http2_submit_dns_response(repinfo->c->h2_session)) { - comm_point_drop_reply(repinfo); return; } repinfo->c->h2_stream = NULL; diff --git a/validator/val_sigcrypt.h b/validator/val_sigcrypt.h index 1fac8bde0..c1e2658e4 100644 --- a/validator/val_sigcrypt.h +++ b/validator/val_sigcrypt.h @@ -311,7 +311,7 @@ enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve, * pass false at start. pass old value only for same rrset and same * signature (but perhaps different key) for reuse. * @param reason: if bogus, a string returned, fixed or alloced in scratch. - * @param reason_bogus: EDE (8914) code paired with the reason of failure. + * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. * @return secure if this key signs this signature. unchecked on error or