summaryrefslogtreecommitdiff
path: root/testdata
diff options
context:
space:
mode:
Diffstat (limited to 'testdata')
-rw-r--r--testdata/09-unbound-control.tdir/09-unbound-control.conf1
-rw-r--r--testdata/09-unbound-control.tdir/09-unbound-control.test24
-rw-r--r--testdata/09-unbound-control.tdir/09-unbound-control.testns29
-rw-r--r--testdata/acl_interface.tdir/acl_interface.conf14
-rw-r--r--testdata/acl_interface.tdir/acl_interface.test.scenario15
-rw-r--r--testdata/auth_tls.tdir/auth_tls.pre1
-rw-r--r--testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre1
-rw-r--r--testdata/cachedb_expired.crpl1
-rw-r--r--testdata/cachedb_expired_reply_ttl.crpl1
-rw-r--r--testdata/cachedb_servfail_cname.crpl2
-rw-r--r--testdata/cachedb_val_expired.crpl1
-rw-r--r--testdata/common.sh6
-rw-r--r--testdata/dns_error_reporting.rpl200
-rw-r--r--testdata/dnstap.tdir/dnstap.conf5
-rw-r--r--testdata/fast_reload_fwd.tdir/auth1.zone2
-rw-r--r--testdata/fast_reload_fwd.tdir/auth2.zone2
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf107
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2108
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc16
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1339
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2285
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.post27
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre56
-rw-r--r--testdata/fast_reload_fwd.tdir/fast_reload_fwd.test320
-rw-r--r--testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone3
-rw-r--r--testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf143
-rw-r--r--testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc16
-rw-r--r--testdata/fast_reload_most_options.tdir/fast_reload_most_options.post11
-rw-r--r--testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre33
-rw-r--r--testdata/fast_reload_most_options.tdir/fast_reload_most_options.test42
-rw-r--r--testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone5
-rw-r--r--testdata/fast_reload_thread.tdir/fast_reload_thread.conf20
-rw-r--r--testdata/fast_reload_thread.tdir/fast_reload_thread.dsc16
-rw-r--r--testdata/fast_reload_thread.tdir/fast_reload_thread.post11
-rw-r--r--testdata/fast_reload_thread.tdir/fast_reload_thread.pre34
-rw-r--r--testdata/fast_reload_thread.tdir/fast_reload_thread.test38
-rw-r--r--testdata/fwd_0ttlservfail.rpl1
-rw-r--r--testdata/iter_failreply.rpl1
-rw-r--r--testdata/iter_fwdstubauth.rpl155
-rw-r--r--testdata/iter_scrub_rr_length.rpl1
-rw-r--r--testdata/log_servfail.tdir/log_servfail.conf27
-rw-r--r--testdata/log_servfail.tdir/log_servfail.dsc16
-rw-r--r--testdata/log_servfail.tdir/log_servfail.post10
-rw-r--r--testdata/log_servfail.tdir/log_servfail.pre21
-rw-r--r--testdata/log_servfail.tdir/log_servfail.test47
-rw-r--r--testdata/redis_replica.tdir/after.zone2
-rw-r--r--testdata/redis_replica.tdir/before.zone2
-rw-r--r--testdata/redis_replica.tdir/redis.conf583
-rw-r--r--testdata/redis_replica.tdir/redis_replica.conf31
-rw-r--r--testdata/redis_replica.tdir/redis_replica.dsc16
-rw-r--r--testdata/redis_replica.tdir/redis_replica.post18
-rw-r--r--testdata/redis_replica.tdir/redis_replica.pre46
-rw-r--r--testdata/redis_replica.tdir/redis_replica.test78
-rw-r--r--testdata/redis_replica.tdir/unbound_control.key39
-rw-r--r--testdata/redis_replica.tdir/unbound_control.pem22
-rw-r--r--testdata/redis_replica.tdir/unbound_server.key39
-rw-r--r--testdata/redis_replica.tdir/unbound_server.pem22
-rw-r--r--testdata/rpz_nsdname.rpl2
-rw-r--r--testdata/rpz_val_block.rpl1
-rw-r--r--testdata/serve_expired.rpl1
-rw-r--r--testdata/serve_expired_0ttl_nodata.rpl2
-rw-r--r--testdata/serve_expired_0ttl_nxdomain.rpl2
-rw-r--r--testdata/serve_expired_0ttl_servfail.rpl2
-rw-r--r--testdata/serve_expired_cached_servfail.rpl2
-rw-r--r--testdata/serve_expired_cached_servfail_refresh.rpl2
-rw-r--r--testdata/serve_expired_client_timeout_servfail.rpl49
-rw-r--r--testdata/serve_expired_client_timeout_val_bogus.rpl83
-rw-r--r--testdata/serve_expired_reply_ttl.rpl1
-rw-r--r--testdata/serve_expired_ttl.rpl1
-rw-r--r--testdata/serve_expired_ttl_reset.rpl23
-rw-r--r--testdata/serve_expired_val_bogus.rpl141
-rw-r--r--testdata/serve_expired_zerottl.rpl1
-rw-r--r--testdata/serve_original_ttl.rpl1
-rw-r--r--testdata/stat_values.tdir/stat_values.conf20
-rw-r--r--testdata/stat_values.tdir/stat_values.pre1
-rw-r--r--testdata/stat_values.tdir/stat_values.test164
-rw-r--r--testdata/stat_values.tdir/stat_values.testns49
-rw-r--r--testdata/stat_values.tdir/stat_values_cachedb.conf12
-rw-r--r--testdata/stat_values.tdir/stat_values_discard_wait_limit.conf36
-rw-r--r--testdata/subnet_cached_servfail.crpl1
-rw-r--r--testdata/subnet_global_prefetch_always_forward.crpl1
-rw-r--r--testdata/subnet_global_prefetch_expired.crpl1
-rw-r--r--testdata/test_ldnsrr.43
-rw-r--r--testdata/test_ldnsrr.52
-rw-r--r--testdata/test_ldnsrr.c34
-rw-r--r--testdata/test_ldnsrr.c44
-rw-r--r--testdata/test_ldnsrr.c54
-rw-r--r--testdata/val_failure_dnskey.rpl1
-rw-r--r--testdata/val_scrub_rr_length.rpl1
89 files changed, 3550 insertions, 180 deletions
diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.conf b/testdata/09-unbound-control.tdir/09-unbound-control.conf
index 719e92309513..be65336eaf5e 100644
--- a/testdata/09-unbound-control.tdir/09-unbound-control.conf
+++ b/testdata/09-unbound-control.tdir/09-unbound-control.conf
@@ -13,6 +13,7 @@ server:
msg-cache-size: 4m
rrset-cache-size: 4m
minimal-responses: yes
+ trust-anchor: "always.empty. 3600 IN DS 50602 8 2 FA8EE175C47325F4BD46D8A4083C3EBEB11C977D689069F2B41F1A29 B22446B1" # This is nonsense, just to kick the validator
view:
name: testview
view-first: yes # Allow falling back to global local data
diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.test b/testdata/09-unbound-control.tdir/09-unbound-control.test
index 8bd2220f3429..da284c2c0ccd 100644
--- a/testdata/09-unbound-control.tdir/09-unbound-control.test
+++ b/testdata/09-unbound-control.tdir/09-unbound-control.test
@@ -68,9 +68,12 @@ fail_answer () {
# Issue an unbound-control command
# $@: command arguments
-control_command () {
+control_command() {
echo "$PRE/unbound-control $@"
$PRE/unbound-control $@ > outfile
+ exitstatus=$?
+ cat outfile
+ return $exitstatus
}
# Reload the server and check the reload has finished processing
@@ -249,6 +252,25 @@ expect_exit_value 1
teststep "clean reload"
clean_reload
+# The flush negative only works if the server is either on 1 thread,
+# or there is threading enabled. Multiple processes does not work for the
+# test, since the printout does not have the stats of a global cache.
+if test $num_threads -le 1 -o "$have_threads" = "yes"; then
+teststep "Check negative flushing"
+query always.empty.
+expect_answer "SERVFAIL"
+query always.empty. DNSKEY
+expect_answer "SERVFAIL"
+control_command -c ub.conf flush_negative
+expect_exit_value 0
+expect_answer "^ok removed .*, 3 messages and 1 key entries"
+control_command -c ub.conf flush_negative
+expect_exit_value 0
+expect_answer "^ok removed .*, 0 messages and 0 key entries"
+else
+ echo "> skip Check negative flushing, because no threads"
+fi
+
teststep "create a new local zone"
control_command -c ub.conf local_zone example.net static
expect_exit_value 0
diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.testns b/testdata/09-unbound-control.tdir/09-unbound-control.testns
index 9a5192fabc4f..311af0f7e771 100644
--- a/testdata/09-unbound-control.tdir/09-unbound-control.testns
+++ b/testdata/09-unbound-control.tdir/09-unbound-control.testns
@@ -1,5 +1,4 @@
; nameserver test file
-$ORIGIN example.com.
$TTL 3600
ENTRY_BEGIN
@@ -7,9 +6,9 @@ MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
-www IN A
+www.example.com. IN A
SECTION ANSWER
-www IN A 10.20.30.40
+www.example.com. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
@@ -19,3 +18,27 @@ ADJUST copy_id
SECTION QUESTION
www.example.net. IN A
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+always.empty. IN A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+always.empty. IN DNSKEY
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+_ta-c5aa.always.empty. IN NULL
+ENTRY_END
diff --git a/testdata/acl_interface.tdir/acl_interface.conf b/testdata/acl_interface.tdir/acl_interface.conf
index 1d9f8c9aae09..b1d94857317f 100644
--- a/testdata/acl_interface.tdir/acl_interface.conf
+++ b/testdata/acl_interface.tdir/acl_interface.conf
@@ -139,6 +139,20 @@ server:
interface-view: @INTERFACE@@@PORT_VIEW_EXT@ "ext"
interface-view: @INTERFACE@@@PORT_VIEW_INTEXT@ "intext"
+# Interface with scope_id
+ interface: @INTERFACE@vlan50@@PORT_ALLOW@
+ interface: @INTERFACE@vlan51@@PORT_ALLOW@
+ interface-tag: @INTERFACE@vlan50@@PORT_ALLOW@ "one"
+ interface-tag: @INTERFACE@vlan51@@PORT_ALLOW@ "two"
+ interface-action: @INTERFACE@vlan50@@PORT_ALLOW@ allow
+ interface-action: @INTERFACE@vlan51@@PORT_ALLOW@ allow
+ local-zone: one.vtest. static
+ local-data: "one.vtest. A 1.1.1.1"
+ local-zone-tag: one.vtest. "one"
+ local-zone: two.vtest. static
+ local-data: "two.vtest. A 2.2.2.2"
+ local-zone-tag: two.vtest. "two"
+
# Local zones configuration
local-zone: local. transparent
local-data: "local. A 0.0.0.0"
diff --git a/testdata/acl_interface.tdir/acl_interface.test.scenario b/testdata/acl_interface.tdir/acl_interface.test.scenario
index 4ae0a42f0602..6348d2ef4a1a 100644
--- a/testdata/acl_interface.tdir/acl_interface.test.scenario
+++ b/testdata/acl_interface.tdir/acl_interface.test.scenario
@@ -17,6 +17,15 @@ ip addr add $INTERFACE_ADDR_3 dev $INTERFACE
ip addr add $INTERFACE_ADDR_4 dev $INTERFACE
ip link set $INTERFACE up
+ip link add ${INTERFACE}vlan50 type dummy
+ip addr add fe80::2/64 dev ${INTERFACE}vlan50
+ip link add ${INTERFACE}vlan51 type dummy
+ip addr add fe80::2/64 dev ${INTERFACE}vlan51
+ip link set ${INTERFACE}vlan50 up
+ip link set ${INTERFACE}vlan51 up
+
+ip addr show
+
# start the forwarder in the background
get_ldns_testns
$LDNS_TESTNS -p $FORWARD_PORT acl_interface.testns >fwd.log 2>&1 &
@@ -250,4 +259,10 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
expect_external_answer
done
+query_addr fe80::2%${INTERFACE}vlan50 $PORT_ALLOW "one.vtest."
+expect_tag_one_answer
+
+query_addr fe80::2%${INTERFACE}vlan51 $PORT_ALLOW "two.vtest."
+expect_tag_two_answer
+
end 0
diff --git a/testdata/auth_tls.tdir/auth_tls.pre b/testdata/auth_tls.tdir/auth_tls.pre
index ebeee24c5658..cf652b1dc541 100644
--- a/testdata/auth_tls.tdir/auth_tls.pre
+++ b/testdata/auth_tls.tdir/auth_tls.pre
@@ -5,6 +5,7 @@
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
+#skip_test "Skip test due to no UDP service for SOA query"
PRE="../.."
if test -n "$NSD"; then
:
diff --git a/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre b/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre
index 519c363dbb7a..56da4af739e4 100644
--- a/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre
+++ b/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre
@@ -5,6 +5,7 @@
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
+#skip_test "Skip test due to no UDP service for SOA query"
PRE="../.."
if test -n "$NSD"; then
:
diff --git a/testdata/cachedb_expired.crpl b/testdata/cachedb_expired.crpl
index 9f9ff677c6d1..d3bf06fe1a1b 100644
--- a/testdata/cachedb_expired.crpl
+++ b/testdata/cachedb_expired.crpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
module-config: "cachedb iterator"
cachedb:
diff --git a/testdata/cachedb_expired_reply_ttl.crpl b/testdata/cachedb_expired_reply_ttl.crpl
index b5f34050594e..03fd01add476 100644
--- a/testdata/cachedb_expired_reply_ttl.crpl
+++ b/testdata/cachedb_expired_reply_ttl.crpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 30
module-config: "cachedb iterator"
diff --git a/testdata/cachedb_servfail_cname.crpl b/testdata/cachedb_servfail_cname.crpl
index 221f00d4df54..99b3d51f9135 100644
--- a/testdata/cachedb_servfail_cname.crpl
+++ b/testdata/cachedb_servfail_cname.crpl
@@ -3,7 +3,7 @@ server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: no
- ;serve-expired: yes
+ serve-expired: no
module-config: "cachedb iterator"
cachedb:
diff --git a/testdata/cachedb_val_expired.crpl b/testdata/cachedb_val_expired.crpl
index 4a51e8272379..741445ce8515 100644
--- a/testdata/cachedb_val_expired.crpl
+++ b/testdata/cachedb_val_expired.crpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: no
minimal-responses: yes
serve-expired: yes
+ serve-expired-client-timeout: 0
;module-config: "subnetcache validator cachedb iterator"
module-config: "validator cachedb iterator"
diff --git a/testdata/common.sh b/testdata/common.sh
index bf2d301eb815..48b8204d2c51 100644
--- a/testdata/common.sh
+++ b/testdata/common.sh
@@ -1,7 +1,8 @@
# common.sh - an include file for commonly used functions for test code.
# BSD licensed (see LICENSE file).
#
-# Version 6
+# Version 7
+# 2025-04-04: speed up kill_pid.
# 2023-12-06: list wait_for_soa_serial in overview
# 2023-12-06: get_ldns_notify, skip_test and teststep, and previous changes
# also included are wait_logfile, cpu_count, process_cpu_list, and
@@ -309,6 +310,7 @@ kill_pid () {
local WAIT_THRES=30
local try
kill $1
+ sleep .001
for (( try=0 ; try <= $MAX_DOWN_TRY ; try++ )) ; do
if kill -0 $1 >/dev/null 2>&1; then
:
@@ -322,6 +324,8 @@ kill_pid () {
fi
if test $try -ge $WAIT_THRES; then
sleep 1
+ else
+ sleep .01
fi
# re-send the signal
kill $1 >/dev/null 2>&1
diff --git a/testdata/dns_error_reporting.rpl b/testdata/dns_error_reporting.rpl
new file mode 100644
index 000000000000..f1fac12a2284
--- /dev/null
+++ b/testdata/dns_error_reporting.rpl
@@ -0,0 +1,200 @@
+; Test DNS Error Reporting.
+
+server:
+ module-config: "validator iterator"
+ trust-anchor-signaling: no
+ target-fetch-policy: "0 0 0 0 0"
+ verbosity: 4
+ qname-minimisation: no
+ minimal-responses: no
+ rrset-roundrobin: no
+ trust-anchor: "a.domain DS 50602 8 2 FA8EE175C47325F4BD46D8A4083C3EBEB11C977D689069F2B41F1A29B22446B1"
+ ede: no # It is not needed for dns-error-reporting; only for clients to receive EDEs
+ dns-error-reporting: yes
+ do-ip6: no
+
+stub-zone:
+ name: domain
+ stub-addr: 0.0.0.0
+stub-zone:
+ name: an.agent
+ stub-addr: 0.0.0.2
+CONFIG_END
+
+SCENARIO_BEGIN Test DNS Error Reporting
+
+; domain
+RANGE_BEGIN 0 100
+ ADDRESS 0.0.0.0
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.domain. IN A
+ SECTION AUTHORITY
+ a.domain. IN NS ns.a.domain.
+ SECTION ADDITIONAL
+ ns.a.domain. IN A 0.0.0.1
+ HEX_EDNSDATA_BEGIN
+ 00 12 ; opt-code (Report-Channel)
+ 00 0A ; opt-len
+ 02 61 6E 05 61 67 65 6E 74 00 ; an.agent.
+ HEX_EDNSDATA_END
+ ENTRY_END
+RANGE_END
+
+; a.domain
+RANGE_BEGIN 0 9
+ ADDRESS 0.0.0.1
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.domain. IN DNSKEY
+ ENTRY_END
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.domain. IN A
+ SECTION ANSWER
+ a.domain. 5 IN A 0.0.0.0
+ ; No RRSIG to trigger validation error (and EDE)
+ SECTION ADDITIONAL
+ ; No Report-Channel here
+ ENTRY_END
+RANGE_END
+
+; a.domain
+RANGE_BEGIN 10 100
+ ADDRESS 0.0.0.1
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.domain. IN DNSKEY
+ ENTRY_END
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ a.domain. IN A
+ SECTION ANSWER
+ a.domain. 5 IN A 0.0.0.0
+ ; No RRSIG to trigger validator error and EDE
+ SECTION ADDITIONAL
+ HEX_EDNSDATA_BEGIN
+ 00 12 ; opt-code (Report-Channel)
+ 00 0A ; opt-len
+ 02 61 6E 05 61 67 65 6E 74 00 ; an.agent.
+ HEX_EDNSDATA_END
+ ENTRY_END
+RANGE_END
+
+; an.agent
+RANGE_BEGIN 10 20
+ ADDRESS 0.0.0.2
+ ENTRY_BEGIN
+ MATCH opcode qtype qname
+ ADJUST copy_id
+ REPLY QR NOERROR
+ SECTION QUESTION
+ _er.1.a.domain.9._er.an.agent. IN TXT
+ SECTION ANSWER
+ _er.1.a.domain.9._er.an.agent. IN TXT "OK"
+ ENTRY_END
+RANGE_END
+
+; Query
+STEP 0 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; Check that validation failed (no DNS error reporting at this state;
+; 'domain' did give an error reporting agent, but the latest upstream
+; 'a.domain' did not)
+STEP 1 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; Wait for the a.domain query to expire (TTL 5)
+STEP 3 TIME_PASSES ELAPSE 6
+
+; Query again
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; Check that validation failed
+; (a DNS Error Report query should have been generated)
+STEP 11 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; Check explicitly that the DNS Error Report query is cached.
+STEP 20 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+_er.1.a.domain.9._er.an.agent. IN TXT
+ENTRY_END
+
+; At this range there are no configured agents to answer this.
+; If the DNS Error Report query is not answered from the cache the test will
+; fail with pending messages.
+STEP 21 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY RD QR RA NOERROR
+SECTION QUESTION
+_er.1.a.domain.9._er.an.agent. IN TXT
+SECTION ANSWER
+_er.1.a.domain.9._er.an.agent. IN TXT "OK"
+ENTRY_END
+
+; Wait for the a.domain query to expire (5 TTL).
+; The DNS Error Report query should still be cached (SOA negative).
+STEP 30 TIME_PASSES ELAPSE 6
+
+; Force a DNS Error Report query generation again.
+STEP 31 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; Check that validation failed
+STEP 32 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA SERVFAIL
+SECTION QUESTION
+a.domain. IN A
+ENTRY_END
+
+; The same DNS Error Report query will be generated as above.
+; No agent is configured at this range to answer the DNS Error Report query.
+; If the DNS Error Report query is not used from the cache the test will fail
+; with pending messages.
+
+SCENARIO_END
diff --git a/testdata/dnstap.tdir/dnstap.conf b/testdata/dnstap.tdir/dnstap.conf
index fc382ccfd4e0..b5497bfebe86 100644
--- a/testdata/dnstap.tdir/dnstap.conf
+++ b/testdata/dnstap.tdir/dnstap.conf
@@ -12,8 +12,9 @@ server:
do-not-query-localhost: no
local-zone: "example.net." redirect
local-data: "example.net. IN A 10.20.30.41"
- serve-expired: yes
- serve-expired-reply-ttl: 30
+ serve-expired: yes
+ serve-expired-client-timeout: 0
+ serve-expired-reply-ttl: 30
remote-control:
control-enable: yes
control-interface: 127.0.0.1
diff --git a/testdata/fast_reload_fwd.tdir/auth1.zone b/testdata/fast_reload_fwd.tdir/auth1.zone
new file mode 100644
index 000000000000..b6b551a42dd5
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/auth1.zone
@@ -0,0 +1,2 @@
+@ SOA ns root 1 3600 300 7200 3600
+www A 1.2.3.4
diff --git a/testdata/fast_reload_fwd.tdir/auth2.zone b/testdata/fast_reload_fwd.tdir/auth2.zone
new file mode 100644
index 000000000000..fc59810c9a85
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/auth2.zone
@@ -0,0 +1,2 @@
+@ SOA ns root 1 3600 300 7200 3600
+www A 1.2.3.5
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf
new file mode 100644
index 000000000000..dca76342f172
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf
@@ -0,0 +1,107 @@
+server:
+ verbosity: 4
+ num-threads: 1
+ interface: 127.0.0.1
+ port: @PORT@
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+ trust-anchor: "ta1.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ trust-anchor: "ta2.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ trust-anchor: "ta3.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ domain-insecure: "insec1.ta1.example.com"
+ domain-insecure: "insec2.ta1.example.com"
+ domain-insecure: "insec3.ta1.example.com"
+
+forward-zone:
+ name: "."
+ forward-addr: "127.0.0.1@12345"
+
+remote-control:
+ control-enable: yes
+ control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
+ control-use-cert: no
+
+forward-zone:
+ name: "example1.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+forward-zone:
+ name: "example2.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+forward-zone:
+ name: "example3.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+forward-zone:
+ name: "example4.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+forward-zone:
+ name: "example5.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+forward-zone:
+ name: "example6.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+stub-zone:
+ name: "stub1.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub2.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub3.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub4.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub5.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub6.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+auth-zone:
+ name: "auth1.org"
+ zonefile: "auth1.zone"
+
+auth-zone:
+ name: "auth2.org"
+ zonefile: "auth1.zone"
+
+auth-zone:
+ name: "auth3.org"
+ zonefile: "auth1.zone"
+
+auth-zone:
+ name: "auth5.org"
+ zonefile: "auth5.zone"
+ primary: 127.0.0.1@@NS1_PORT@
+
+auth-zone:
+ name: "auth6.org"
+ zonefile: "auth6.zone"
+ primary: 127.0.0.1@@NS1_PORT@
+
+auth-zone:
+ name: "auth7.org"
+ zonefile: "auth7.zone"
+ primary: 127.0.0.1@@NS1_PORT@
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2
new file mode 100644
index 000000000000..dbe6e4ffa821
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2
@@ -0,0 +1,108 @@
+server:
+ verbosity: 4
+ num-threads: 1
+ interface: 127.0.0.1
+ port: @PORT@
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+ trust-anchor: "ta1.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ trust-anchor: "ta3.example.com DS 55567 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ trust-anchor: "ta4.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af"
+ domain-insecure: "insec1.ta1.example.com"
+ domain-insecure: "insec3.ta1.example.com"
+ domain-insecure: "insec4.ta1.example.com"
+
+forward-zone:
+ name: "."
+ # No addresses makes the server return SERVFAIL for deleted zones.
+ #forward-addr: "127.0.0.1@12345"
+
+remote-control:
+ control-enable: yes
+ control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
+ control-use-cert: no
+
+forward-zone:
+ name: "example1.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+forward-zone:
+ name: "example2.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+forward-zone:
+ name: "example3.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+forward-zone:
+ name: "example4.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+forward-zone:
+ name: "example5.org"
+ forward-addr: "127.0.0.1@@NS2_PORT@"
+
+forward-zone:
+ name: "example6.org"
+ forward-addr: "127.0.0.1@@NS1_PORT@"
+
+stub-zone:
+ name: "stub1.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub2.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub3.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub4.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub5.org"
+ stub-addr: "127.0.0.1@@NS2_PORT@"
+ stub-prime: no
+
+stub-zone:
+ name: "stub6.org"
+ stub-addr: "127.0.0.1@@NS1_PORT@"
+ stub-prime: no
+
+auth-zone:
+ name: "auth1.org"
+ zonefile: "auth1.zone"
+
+auth-zone:
+ name: "auth3.org"
+ zonefile: "auth2.zone"
+
+auth-zone:
+ name: "auth4.org"
+ zonefile: "auth2.zone"
+
+auth-zone:
+ name: "auth5.org"
+ zonefile: "auth5.zone"
+ primary: 127.0.0.1@@NS1_PORT@
+
+auth-zone:
+ name: "auth7.org"
+ zonefile: "auth7.zone"
+ primary: 127.0.0.1@@NS2_PORT@
+
+auth-zone:
+ name: "auth8.org"
+ zonefile: "auth8.zone"
+ primary: 127.0.0.1@@NS1_PORT@
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc
new file mode 100644
index 000000000000..422cdee4660c
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc
@@ -0,0 +1,16 @@
+BaseName: fast_reload_fwd
+Version: 1.0
+Description: Test fast reload change of forwards and stubs.
+CreationDate: Thu Jan 22 11:55:55 CET 2024
+Maintainer: dr. W.C.A. Wijngaards
+Category:
+Component:
+CmdDepends:
+Depends:
+Help:
+Pre: fast_reload_fwd.pre
+Post: fast_reload_fwd.post
+Test: fast_reload_fwd.test
+AuxFiles:
+Passed:
+Failure:
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1
new file mode 100644
index 000000000000..d9644414b8e7
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1
@@ -0,0 +1,339 @@
+; match A records and return a reply indicating it is this server.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example1.org. IN A
+SECTION ANSWER
+www.example1.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example2.org. IN A
+SECTION ANSWER
+www.example2.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example3.org. IN A
+SECTION ANSWER
+www.example3.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example4.org. IN A
+SECTION ANSWER
+www.example4.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example5.org. IN A
+SECTION ANSWER
+www.example5.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example6.org. IN A
+SECTION ANSWER
+www.example6.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example1.org. IN A
+SECTION ANSWER
+www2.example1.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example2.org. IN A
+SECTION ANSWER
+www2.example2.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example3.org. IN A
+SECTION ANSWER
+www2.example3.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example4.org. IN A
+SECTION ANSWER
+www2.example4.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example5.org. IN A
+SECTION ANSWER
+www2.example5.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example6.org. IN A
+SECTION ANSWER
+www2.example6.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub1.org. IN A
+SECTION ANSWER
+www.stub1.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub2.org. IN A
+SECTION ANSWER
+www.stub2.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub3.org. IN A
+SECTION ANSWER
+www.stub3.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub4.org. IN A
+SECTION ANSWER
+www.stub4.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub5.org. IN A
+SECTION ANSWER
+www.stub5.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub6.org. IN A
+SECTION ANSWER
+www.stub6.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub1.org. IN A
+SECTION ANSWER
+www2.stub1.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub2.org. IN A
+SECTION ANSWER
+www2.stub2.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub3.org. IN A
+SECTION ANSWER
+www2.stub3.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub4.org. IN A
+SECTION ANSWER
+www2.stub4.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub5.org. IN A
+SECTION ANSWER
+www2.stub5.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub6.org. IN A
+SECTION ANSWER
+www2.stub6.org. IN A 1.2.3.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth5.org. IN SOA
+SECTION ANSWER
+auth5.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth5.org. IN AXFR
+SECTION ANSWER
+auth5.org. SOA ns root 1 3600 300 7200 3600
+www.auth5.org. A 1.2.3.4
+auth5.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth6.org. IN SOA
+SECTION ANSWER
+auth6.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth6.org. IN AXFR
+SECTION ANSWER
+auth6.org. SOA ns root 1 3600 300 7200 3600
+www.auth6.org. A 1.2.3.4
+auth6.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth7.org. IN SOA
+SECTION ANSWER
+auth7.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth7.org. IN AXFR
+SECTION ANSWER
+auth7.org. SOA ns root 1 3600 300 7200 3600
+www.auth7.org. A 1.2.3.4
+auth7.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth8.org. IN SOA
+SECTION ANSWER
+auth8.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth8.org. IN AXFR
+SECTION ANSWER
+auth8.org. SOA ns root 1 3600 300 7200 3600
+www.auth8.org. A 1.2.3.4
+auth8.org. SOA ns root 1 3600 300 7200 3600
+ENTRY_END
+
+; match anything and return a reply
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.org. IN SOA
+SECTION AUTHORITY
+example.org. IN SOA ns1.example.org. hostmaster.example.org. 1 3600 900 86400 3600
+ENTRY_END
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2
new file mode 100644
index 000000000000..8e7eb60c81e5
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2
@@ -0,0 +1,285 @@
+; match A records and return a reply indicating it is this server.
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example1.org. IN A
+SECTION ANSWER
+www.example1.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example2.org. IN A
+SECTION ANSWER
+www.example2.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example3.org. IN A
+SECTION ANSWER
+www.example3.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example4.org. IN A
+SECTION ANSWER
+www.example4.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example5.org. IN A
+SECTION ANSWER
+www.example5.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example6.org. IN A
+SECTION ANSWER
+www.example6.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example1.org. IN A
+SECTION ANSWER
+www2.example1.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example2.org. IN A
+SECTION ANSWER
+www2.example2.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example3.org. IN A
+SECTION ANSWER
+www2.example3.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example4.org. IN A
+SECTION ANSWER
+www2.example4.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example5.org. IN A
+SECTION ANSWER
+www2.example5.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.example6.org. IN A
+SECTION ANSWER
+www2.example6.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub1.org. IN A
+SECTION ANSWER
+www.stub1.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub2.org. IN A
+SECTION ANSWER
+www.stub2.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub3.org. IN A
+SECTION ANSWER
+www.stub3.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub4.org. IN A
+SECTION ANSWER
+www.stub4.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub5.org. IN A
+SECTION ANSWER
+www.stub5.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.stub6.org. IN A
+SECTION ANSWER
+www.stub6.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub1.org. IN A
+SECTION ANSWER
+www2.stub1.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub2.org. IN A
+SECTION ANSWER
+www2.stub2.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub3.org. IN A
+SECTION ANSWER
+www2.stub3.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub4.org. IN A
+SECTION ANSWER
+www2.stub4.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub5.org. IN A
+SECTION ANSWER
+www2.stub5.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www2.stub6.org. IN A
+SECTION ANSWER
+www2.stub6.org. IN A 1.2.3.2
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth7.org. IN SOA
+SECTION ANSWER
+auth7.org. SOA ns root 2 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth7.org. IN AXFR
+SECTION ANSWER
+auth7.org. SOA ns root 2 3600 300 7200 3600
+www.auth7.org. A 1.2.3.5
+auth7.org. SOA ns root 2 3600 300 7200 3600
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+auth7.org. IN IXFR
+SECTION ANSWER
+auth7.org. SOA ns root 2 3600 300 7200 3600
+www.auth7.org. A 1.2.3.5
+auth7.org. SOA ns root 2 3600 300 7200 3600
+ENTRY_END
+
+; match anything and return a reply
+ENTRY_BEGIN
+MATCH opcode
+ADJUST copy_id copy_query
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.org. IN SOA
+SECTION AUTHORITY
+example.org. IN SOA ns1.example.org. hostmaster.example.org. 1 3600 900 86400 3600
+ENTRY_END
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post
new file mode 100644
index 000000000000..969d0080df63
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post
@@ -0,0 +1,27 @@
+# #-- fast_reload_fwd.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+PRE="../.."
+. ../common.sh
+kill_pid $NS1_PID
+kill_pid $NS2_PID
+if test -f unbound.pid; then
+ if kill -0 $UNBOUND_PID >/dev/null 2>&1; then
+ kill_pid $UNBOUND_PID
+ fi
+fi
+rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID
+echo
+echo "> ns1.log"
+cat ns1.log
+echo
+echo "> ns2.log"
+cat ns2.log
+echo
+echo "> unbound.log"
+cat unbound.log
+exit 0
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre
new file mode 100644
index 000000000000..42e680d8f041
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre
@@ -0,0 +1,56 @@
+# #-- fast_reload_fwd.pre--#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+# if no threads; exit
+if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then
+ echo "have threads"
+else
+ skip_test "no threads"
+fi
+if grep -e "define ENABLE_LOCK_CHECKS 1" $PRE/config.h; then
+ get_make
+ echo "> (cd $PRE ; $MAKE lock-verify)"
+ (cd $PRE ; $MAKE lock-verify)
+fi
+
+get_random_port 3
+UNBOUND_PORT=$RND_PORT
+NS1_PORT=$(($RND_PORT + 1))
+NS2_PORT=$(($RND_PORT + 2))
+echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
+echo "NS1_PORT=$NS1_PORT" >> .tpkg.var.test
+echo "NS2_PORT=$NS2_PORT" >> .tpkg.var.test
+
+# make config files
+CONTROL_PATH=/tmp
+CONTROL_PID=$$
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@NS1_PORT\@/'$NS1_PORT'/' -e 's/@NS2_PORT\@/'$NS2_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_fwd.conf > ub.conf
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@NS1_PORT\@/'$NS1_PORT'/' -e 's/@NS2_PORT\@/'$NS2_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_fwd.conf2 > ub.conf2
+
+# start forwarders
+get_ldns_testns
+$LDNS_TESTNS -p $NS1_PORT fast_reload_fwd.ns1 >ns1.log 2>&1 &
+NS1_PID=$!
+echo "NS1_PID=$NS1_PID" >> .tpkg.var.test
+
+$LDNS_TESTNS -p $NS2_PORT fast_reload_fwd.ns2 >ns2.log 2>&1 &
+NS2_PID=$!
+echo "NS2_PID=$NS2_PID" >> .tpkg.var.test
+
+# start unbound in the background
+PRE="../.."
+$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test
+echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test
+
+cat .tpkg.var.test
+wait_ldns_testns_up ns1.log
+wait_ldns_testns_up ns2.log
+wait_unbound_up unbound.log
diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test
new file mode 100644
index 000000000000..9248593c75b2
--- /dev/null
+++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test
@@ -0,0 +1,320 @@
+# #-- fast_reload_fwd.test --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+
+echo "> unbound-control status"
+$PRE/unbound-control -c ub.conf status
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+# test that the forwards and stubs point to the right upstream.
+for x in example1.org example2.org example3.org stub1.org stub2.org stub3.org; do
+ echo ""
+ echo "dig www.$x [upstream is NS1]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.1" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+for x in example4.org example5.org example6.org stub4.org stub5.org stub6.org; do
+ echo ""
+ echo "dig www.$x [upstream is NS2]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.2" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+for x in auth1.org auth2.org auth3.org auth5.org auth6.org auth7.org; do
+ echo ""
+ echo "dig www.$x [auth is 1.2.3.4]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.4" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+echo ""
+echo "> list_insecure"
+$PRE/unbound-control -c ub.conf list_insecure 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+fi
+if grep "insec1.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "insec2.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "insec3.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+echo ""
+echo "> trustanchor.unbound"
+dig @127.0.0.1 -p $UNBOUND_PORT trustanchor.unbound CH TXT 2>&1 | tee outfile
+if grep "ta1.example.com. 55566" outfile >/dev/null; then :; else
+ echo "wrong output ta1"
+ exit 1
+fi
+if grep "ta2.example.com. 55566" outfile >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "ta3.example.com. 55566" outfile >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+
+echo ""
+echo "> replace config file ub.conf"
+mv ub.conf ub.conf.orig
+mv ub.conf2 ub.conf
+echo ""
+echo "> unbound-control fast_reload"
+$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+# for the previous digs to www.x the cached value should remain the same
+# but for new lookups, to www2.x the new upstream should be used.
+for x in example1.org example2.org example3.org stub1.org stub2.org stub3.org; do
+ echo ""
+ echo "dig www.$x [upstream is NS1]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.1" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+for x in example4.org example5.org example6.org stub4.org stub5.org stub6.org; do
+ echo ""
+ echo "dig www.$x [upstream is NS2]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.2" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+# new lookups for www2 go to the upstream.
+for x in example2.org example4.org example6.org stub2.org stub4.org stub6.org; do
+ echo ""
+ echo "dig www2.$x [upstream is NS1]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www2.$x A 2>&1 | tee outfile
+ if grep "1.2.3.1" outfile; then
+ echo "response OK"
+ else
+ echo "www2.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+for x in example1.org example3.org example5.org stub1.org stub3.org stub5.org; do
+ echo ""
+ echo "dig www2.$x [upstream is NS2]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www2.$x A 2>&1 | tee outfile
+ if grep "1.2.3.2" outfile; then
+ echo "response OK"
+ else
+ echo "www2.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+# auth is unchanged, or at ns1.
+for x in auth1.org auth5.org auth8.org; do
+ echo ""
+ echo "dig www.$x [auth is 1.2.3.4]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.4" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+# deleted auth
+for x in auth2.org auth6.org; do
+ echo ""
+ echo "dig www.$x [auth is deleted]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "SERVFAIL" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+# changed and added auth
+for x in auth3.org auth4.org auth7.org; do
+ echo ""
+ echo "dig www.$x [auth is 1.2.3.5]"
+ dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile
+ if grep "1.2.3.5" outfile; then
+ echo "response OK"
+ else
+ echo "www.$x got the wrong answer"
+ exit 1
+ fi
+done
+
+echo ""
+echo "> list_insecure"
+$PRE/unbound-control -c ub.conf list_insecure 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+fi
+if grep "insec1.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "insec2.ta1.example.com" output >/dev/null; then
+ echo "wrong output"
+ exit 1
+fi
+if grep "insec3.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "insec4.ta1.example.com" output >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+echo ""
+echo "> trustanchor.unbound"
+dig @127.0.0.1 -p $UNBOUND_PORT trustanchor.unbound CH TXT 2>&1 | tee outfile
+if grep "ta1.example.com. 55566" outfile >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "ta2.example.com. 55566" outfile >/dev/null; then
+ echo "wrong output"
+ exit 1
+fi
+if grep "ta3.example.com. 55566" outfile >/dev/null; then
+ echo "wrong output"
+ exit 1
+fi
+if grep "ta3.example.com. 55567" outfile >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+if grep "ta4.example.com. 55566" outfile >/dev/null; then :; else
+ echo "wrong output"
+ exit 1
+fi
+
+echo ""
+echo "> test change: add tag1 tag2"
+cp ub.conf ub.conf.orig2
+echo "server:" >> ub.conf
+echo ' define-tag: "tag1 tag2"' >> ub.conf
+echo "> unbound-control fast_reload"
+$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+echo ""
+echo "> test change: change to tag2 tag3"
+cp ub.conf.orig2 ub.conf
+echo "server:" >> ub.conf
+echo ' define-tag: "tag2 tag3"' >> ub.conf
+echo "> unbound-control fast_reload"
+$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+if grep "tags have changed" output; then
+ echo "output OK"
+else
+ echo "wrong output"
+ exit 1
+fi
+
+echo ""
+echo "> test change: change cache size"
+cp ub.conf.orig2 ub.conf
+echo "server:" >> ub.conf
+echo " msg-cache-size: 10m" >> ub.conf
+echo " rrset-cache-size: 5m" >> ub.conf
+echo "> unbound-control fast_reload"
+$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+echo ""
+echo "> test change: change nothing, +p too"
+$PRE/unbound-control -c ub.conf fast_reload +vv +p 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+echo ""
+echo "> stop unbound"
+kill_pid $UNBOUND_PID
+if test -f unbound.pid; then sleep 1; fi
+if test -f unbound.pid; then sleep 1; fi
+if test -f unbound.pid; then sleep 1; fi
+if test -f unbound.pid; then echo "unbound.pid still there"; fi
+# check the locks.
+function locktest() {
+ if test -x $PRE/lock-verify -a -f ublocktrace.0; then
+ $PRE/lock-verify ublocktrace.*
+ if test $? -ne 0; then
+ echo "lock-verify error"
+ exit 1
+ fi
+ fi
+}
+locktest
+
+exit 0
diff --git a/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone b/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone
new file mode 100644
index 000000000000..55b8d34a9e4e
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone
@@ -0,0 +1,3 @@
+$ORIGIN auth.nlnetlabs.nl.
+$TTL 60
+@ IN SOA a b 1 2 3 4 5
diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf
new file mode 100644
index 000000000000..eda3d6763a41
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf
@@ -0,0 +1,143 @@
+# Try to define values for options that don't have "default" options that would
+# trigger fast-reload functionality.
+server:
+ verbosity: 4
+ num-threads: 4
+ interface: 127.0.0.1
+ interface: lo
+ port: @PORT@
+ interface-action: lo allow
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+
+ module-config: "respip validator iterator"
+
+ outgoing-interface: 127.0.0.1
+ outgoing-port-avoid: "3200-3208"
+
+ define-tag: "tag1 tag2 tag3"
+
+ do-nat64: yes
+ nat64-prefix: 64:ff9b::0/96
+ dns64-prefix: 64:ff9b::0/96
+ dns64-ignore-aaaa: "ignore-aaaa.nlnetlabs.nl"
+
+ edns-tcp-keepalive: yes
+
+ response-ip: 192.0.2.0 always_refuse
+ access-control: 127.0.0.0/8 allow
+ access-control: ::1 allow
+ access-control-tag: 192.0.2.0/24 "tag2 tag3"
+ interface-tag: lo "tag2 tag3"
+ access-control-tag-action: 192.0.2.0/24 tag3 always_refuse
+ interface-tag-action: lo tag3 always_refuse
+ access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1"
+ interface-tag-data: lo tag2 "A 127.0.0.1"
+ access-control-view: 192.0.2.0/24 viewname
+ interface-view: lo viewname
+
+ nsid: "ascii_something"
+
+ http-user-agent: "httpuseragent"
+
+ caps-exempt: "nlnetlabs.nl"
+
+ private-address: 10.0.0.0/8
+ private-address: 172.16.0.0/12
+ private-address: 192.168.0.0/16
+ private-address: 169.254.0.0/16
+ private-address: fd00::/8
+ private-address: fe80::/10
+ private-address: ::ffff:0:0/96
+
+ private-domain: "nlnetlabs.nl"
+
+ unwanted-reply-threshold: 10000000
+
+ do-not-query-address: 1.1.1.1
+ do-not-query-address: 8.8.8.8
+ do-not-query-address: 9.9.9.9
+
+ do-not-query-localhost: no
+
+ trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
+
+ domain-insecure: "nlnetlabs.nl"
+
+ serve-expired: yes
+ serve-expired-client-timeout: 1800
+
+ val-log-level: 2
+
+ local-zone: refuse.nlnetlabs.nl. refuse
+ local-zone: override.nlnetlabs.nl. deny
+ local-zone: tag.nlnetlabs.nl. transparent
+ local-data: "data.nlnetlabs.nl. TXT localdata"
+ local-data-ptr: "192.0.2.3 reverse.nlnetlabs.nl."
+ local-zone-tag: "tag.nlnetlabs.nl" "tag2 tag3"
+ local-zone-override: "override.nlnetlabs.nl" 192.0.2.0/24 refuse
+
+
+ ratelimit: 100
+ ratelimit-below-domain: ratelimit.nlnetlabs.nl 1000
+ ip-ratelimit: 100
+
+ tcp-connection-limit: 192.0.2.0/24 12
+
+ answer-cookie: yes
+ cookie-secret: "000102030405060708090a0b0c0d0e0f"
+
+ ede: yes
+ ede-serve-expired: yes
+
+remote-control:
+ control-enable: yes
+ control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
+ control-use-cert: no
+
+stub-zone:
+ name: "stub.nlnetlabs.nl"
+ stub-addr: 192.0.2.68
+ stub-prime: no
+ stub-first: no
+ stub-tcp-upstream: no
+ stub-tls-upstream: no
+ stub-no-cache: no
+
+forward-zone:
+ name: "forward.nlnetlabs.nl"
+ forward-addr: 192.0.2.68
+ forward-first: no
+ forward-tcp-upstream: no
+ forward-tls-upstream: no
+ forward-no-cache: no
+
+auth-zone:
+ name: "auth.nlnetlabs.nl"
+ for-downstream: yes
+ for-upstream: yes
+ zonemd-check: no
+ zonemd-reject-absence: no
+ zonefile: "auth.nlnetlabs.nl.zone"
+
+view:
+ name: "viewname"
+ local-zone: "view.nlnetlabs.nl" redirect
+ local-data: "view.nlnetlabs.nl A 192.0.2.3"
+ local-data-ptr: "192.0.2.3 view.nlnetlabs.nl"
+ view-first: no
+
+rpz:
+ name: "rpz.nlnetlabs.nl"
+ zonefile: "rpz.nlnetlabs.nl.zone"
+ rpz-action-override: cname
+ rpz-cname-override: www.example.org
+ rpz-log: yes
+ rpz-log-name: "example policy"
+ rpz-signal-nxdomain-ra: no
+ for-downstream: no
+ tags: "tag3"
diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc
new file mode 100644
index 000000000000..e0e8e9fd206e
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc
@@ -0,0 +1,16 @@
+BaseName: fast_reload_most_options
+Version: 1.0
+Description: Test fast reload on high verbosity with most options.
+CreationDate: Fri 28 Feb 2025 15:55:15 CET
+Maintainer: Yorgos Thessalonikefs
+Category:
+Component:
+CmdDepends:
+Depends:
+Help:
+Pre: fast_reload_most_options.pre
+Post: fast_reload_most_options.post
+Test: fast_reload_most_options.test
+AuxFiles:
+Passed:
+Failure:
diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post
new file mode 100644
index 000000000000..7fd25e3648d0
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post
@@ -0,0 +1,11 @@
+# #-- fast_reload_most_options.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+. ../common.sh
+kill_pid $UNBOUND_PID
+rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID
+cat unbound.log
diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre
new file mode 100644
index 000000000000..47e3642c65c4
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre
@@ -0,0 +1,33 @@
+# #-- fast_reload_most_options.pre--#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+# if no threads; exit
+if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then
+ echo "have threads"
+else
+ skip_test "no threads"
+fi
+
+get_random_port 1
+UNBOUND_PORT=$RND_PORT
+echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
+
+# make config file
+CONTROL_PATH=/tmp
+CONTROL_PID=$$
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_most_options.conf > ub.conf
+# start unbound in the background
+PRE="../.."
+$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test
+echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test
+
+cat .tpkg.var.test
+wait_unbound_up unbound.log
diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test
new file mode 100644
index 000000000000..20799986071a
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test
@@ -0,0 +1,42 @@
+# #-- fast_reload_most_options.test --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+
+echo "> unbound-control status"
+$PRE/unbound-control -c ub.conf status
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+for i in {1..10}
+do
+
+ echo "> unbound-control fast_reload +vvdp ($i)"
+ $PRE/unbound-control -c ub.conf fast_reload +vvdp 2>&1 | tee output
+ if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+ else
+ echo "exit value: OK"
+ fi
+ wait_logfile unbound.log "start fast reload thread" 60
+ wait_logfile unbound.log "stop fast reload thread" 60
+ wait_logfile unbound.log "joined with fastreload thread" 60
+
+ if grep "ok" output; then
+ echo "OK"
+ else
+ echo "output not correct"
+ exit 1
+ fi
+done
+
+exit 0
diff --git a/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone b/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone
new file mode 100644
index 000000000000..71b37150692e
--- /dev/null
+++ b/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone
@@ -0,0 +1,5 @@
+$ORIGIN rpz.nlnetlabs.nl.
+$TTL 60
+@ IN SOA a b 1 2 3 4 5
+nxdomain.nlnetlabs.nl IN CNAME .
+rpzdata.nlnetlabs.nl IN A 0.0.0.0
diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.conf b/testdata/fast_reload_thread.tdir/fast_reload_thread.conf
new file mode 100644
index 000000000000..719f4a00eaab
--- /dev/null
+++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.conf
@@ -0,0 +1,20 @@
+server:
+ verbosity: 4
+ num-threads: 1
+ interface: 127.0.0.1
+ port: @PORT@
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+
+forward-zone:
+ name: "."
+ forward-addr: "127.0.0.1@12345"
+
+remote-control:
+ control-enable: yes
+ control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
+ control-use-cert: no
diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc b/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc
new file mode 100644
index 000000000000..ec3437b695c0
--- /dev/null
+++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc
@@ -0,0 +1,16 @@
+BaseName: fast_reload_thread
+Version: 1.0
+Description: Test fast reload thread output.
+CreationDate: Thu Jan 4 09:25:55 CET 2024
+Maintainer: dr. W.C.A. Wijngaards
+Category:
+Component:
+CmdDepends:
+Depends:
+Help:
+Pre: fast_reload_thread.pre
+Post: fast_reload_thread.post
+Test: fast_reload_thread.test
+AuxFiles:
+Passed:
+Failure:
diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.post b/testdata/fast_reload_thread.tdir/fast_reload_thread.post
new file mode 100644
index 000000000000..569a17f852ba
--- /dev/null
+++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.post
@@ -0,0 +1,11 @@
+# #-- fast_reload_thread.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+. ../common.sh
+kill_pid $UNBOUND_PID
+rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID
+cat unbound.log
diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.pre b/testdata/fast_reload_thread.tdir/fast_reload_thread.pre
new file mode 100644
index 000000000000..5521742fa318
--- /dev/null
+++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.pre
@@ -0,0 +1,34 @@
+# #-- fast_reload_thread.pre--#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+# if no threads; exit
+if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then
+ echo "have threads"
+else
+ skip_test "no threads"
+fi
+
+get_random_port 1
+UNBOUND_PORT=$RND_PORT
+echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
+
+# make config file
+CONTROL_PATH=/tmp
+CONTROL_PID=$$
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_thread.conf > ub.conf
+# start unbound in the background
+PRE="../.."
+$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test
+echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test
+
+cat .tpkg.var.test
+wait_unbound_up unbound.log
+
diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.test b/testdata/fast_reload_thread.tdir/fast_reload_thread.test
new file mode 100644
index 000000000000..d2ef258802f7
--- /dev/null
+++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.test
@@ -0,0 +1,38 @@
+# #-- fast_reload_thread.test --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+
+echo "> unbound-control status"
+$PRE/unbound-control -c ub.conf status
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+
+echo "> unbound-control fast_reload"
+$PRE/unbound-control -c ub.conf fast_reload 2>&1 | tee output
+if test $? -ne 0; then
+ echo "wrong exit value."
+ exit 1
+else
+ echo "exit value: OK"
+fi
+wait_logfile unbound.log "start fast reload thread" 60
+wait_logfile unbound.log "stop fast reload thread" 60
+wait_logfile unbound.log "joined with fastreload thread" 60
+
+if grep "ok" output; then
+ echo "OK"
+else
+ echo "output not correct"
+ exit 1
+fi
+
+exit 0
diff --git a/testdata/fwd_0ttlservfail.rpl b/testdata/fwd_0ttlservfail.rpl
index ed912c73bf2f..d50d386d4137 100644
--- a/testdata/fwd_0ttlservfail.rpl
+++ b/testdata/fwd_0ttlservfail.rpl
@@ -2,6 +2,7 @@
; config options go here.
server:
serve-expired: yes
+ serve-expired-client-timeout: 0
prefetch: yes
forward-zone: name: "." forward-addr: 216.0.0.1
CONFIG_END
diff --git a/testdata/iter_failreply.rpl b/testdata/iter_failreply.rpl
index 393714196d89..e8ad4dd26e31 100644
--- a/testdata/iter_failreply.rpl
+++ b/testdata/iter_failreply.rpl
@@ -3,7 +3,6 @@ server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
minimal-responses: no
- log-servfail: yes
stub-zone:
name: "."
diff --git a/testdata/iter_fwdstubauth.rpl b/testdata/iter_fwdstubauth.rpl
new file mode 100644
index 000000000000..fefb6369c864
--- /dev/null
+++ b/testdata/iter_fwdstubauth.rpl
@@ -0,0 +1,155 @@
+; config options
+server:
+ target-fetch-policy: "0 0 0 0 0"
+
+auth-zone:
+ name: "example.tld."
+ for-upstream: yes
+ for-downstream: no
+ fallback-enabled: no
+ ## this line generates zonefile: "/tmp/xxx.example.tld"
+ zonefile:
+TEMPFILE_NAME example.tld
+ ## this is the inline file /tmp/xxx.example.tld
+ ## the tempfiles are deleted when the testrun is over.
+TEMPFILE_CONTENTS example.tld
+$ORIGIN tld.
+example 3600 IN SOA a b 1 2 3 4 5
+ 3600 IN NS ns.example.tld.
+$ORIGIN example.tld.
+ns 3600 IN A 1.2.3.4
+www 3600 IN A 3.3.3.3
+more 3600 IN NS ns.more.tld.
+TEMPFILE_END
+
+forward-zone:
+ name: "."
+ forward-addr: 9.9.9.9
+
+stub-zone:
+ name: "tld"
+ stub-addr: 2.3.4.5
+stub-zone:
+ name: "more.example.tld"
+ stub-addr: 2.3.4.7
+CONFIG_END
+
+SCENARIO_BEGIN Test iterator's ability to route the request to the correct, configured delegation point
+; Preference should be auth-zone > stub-zone > forward-zone
+; But configuration-wise, since everything is an entry on the forwards tree
+; (or a hole in the case of stub/auth), forwards cannot be replaced by
+; stubs/auth.
+; Also stub/auth zones end the part of the tree that gets forwarded, e.g.,
+; delegations from an auth/stub cannot be caught by a higher forwarder, it will
+; be recursively resolved instead.
+
+; '.' forwarder
+RANGE_BEGIN 0 100
+ ADDRESS 9.9.9.9
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.deleg.tld. IN A
+SECTION ANSWER
+www.deleg.tld. IN A 3.3.3.3
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; 'tld.' stub server
+RANGE_BEGIN 0 100
+ ADDRESS 2.3.4.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.tld. IN A
+SECTION ANSWER
+www.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; 'more.example.tld.' stub server
+RANGE_BEGIN 0 100
+ ADDRESS 2.3.4.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+RANGE_END
+
+; query www.tld ...
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'tld.' stub zone
+STEP 2 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.tld. IN A
+SECTION ANSWER
+www.tld. IN A 3.3.3.3
+ENTRY_END
+
+; query www.example.tld ...
+STEP 3 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'example.tld.' auth zone
+STEP 4 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.tld. IN A
+SECTION ANSWER
+www.example.tld. IN A 3.3.3.3
+ENTRY_END
+
+; query www.more.example.tld ...
+STEP 5 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.more.example.tld. IN A
+ENTRY_END
+
+; ... answer should come from 'more.example.tld.' stub zone
+STEP 6 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.more.example.tld. IN A
+SECTION ANSWER
+www.more.example.tld. IN A 3.3.3.3
+ENTRY_END
+
+SCENARIO_END
diff --git a/testdata/iter_scrub_rr_length.rpl b/testdata/iter_scrub_rr_length.rpl
index 2ef73c2fe152..ee7579f9c246 100644
--- a/testdata/iter_scrub_rr_length.rpl
+++ b/testdata/iter_scrub_rr_length.rpl
@@ -5,7 +5,6 @@ server:
minimal-responses: no
rrset-roundrobin: no
ede: yes
- log-servfail: yes
stub-zone:
name: "."
diff --git a/testdata/log_servfail.tdir/log_servfail.conf b/testdata/log_servfail.tdir/log_servfail.conf
new file mode 100644
index 000000000000..2d7c34e68c84
--- /dev/null
+++ b/testdata/log_servfail.tdir/log_servfail.conf
@@ -0,0 +1,27 @@
+server:
+ verbosity: 0
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+ use-caps-for-id: no
+ port: @SERVER_PORT@
+ interface: 127.0.0.1
+ outbound-msg-retry: 0
+
+ log-servfail: yes
+
+forward-zone:
+ name: "a.servfail"
+ forward-addr: 127.0.0.1@@SERVER_PORT@
+
+forward-zone:
+ name: "b.servfail"
+ forward-addr: 127.0.0.1@@SERVER_PORT@
+
+remote-control:
+ control-enable: yes
+ control-port: @CONTROL_PORT@
+ control-use-cert: no
diff --git a/testdata/log_servfail.tdir/log_servfail.dsc b/testdata/log_servfail.tdir/log_servfail.dsc
new file mode 100644
index 000000000000..cf4f455aadf4
--- /dev/null
+++ b/testdata/log_servfail.tdir/log_servfail.dsc
@@ -0,0 +1,16 @@
+BaseName: log_servfail
+Version: 1.0
+Description: Check the log_servfail option
+CreationDate: Fri 29 Nov 11:00:00 CEST 2024
+Maintainer:
+Category:
+Component:
+CmdDepends:
+Depends:
+Help:
+Pre: log_servfail.pre
+Post: log_servfail.post
+Test: log_servfail.test
+AuxFiles:
+Passed:
+Failure:
diff --git a/testdata/log_servfail.tdir/log_servfail.post b/testdata/log_servfail.tdir/log_servfail.post
new file mode 100644
index 000000000000..a7bd0e88f4bb
--- /dev/null
+++ b/testdata/log_servfail.tdir/log_servfail.post
@@ -0,0 +1,10 @@
+# #-- log_servfail.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+. ../common.sh
+kill_from_pidfile "unbound.pid"
+cat unbound.log
diff --git a/testdata/log_servfail.tdir/log_servfail.pre b/testdata/log_servfail.tdir/log_servfail.pre
new file mode 100644
index 000000000000..54059480824d
--- /dev/null
+++ b/testdata/log_servfail.tdir/log_servfail.pre
@@ -0,0 +1,21 @@
+# #-- log_servfail.pre--#
+PRE="../.."
+. ../common.sh
+
+get_random_port 2
+SERVER_PORT=$RND_PORT
+CONTROL_PORT=$(($RND_PORT + 1))
+echo "SERVER_PORT=$SERVER_PORT" >> .tpkg.var.test
+echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
+
+# make config file
+sed \
+ -e 's/@SERVER_PORT\@/'$SERVER_PORT'/' \
+ -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' \
+ < log_servfail.conf > ub.conf
+
+# start unbound in the background
+$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
+
+cat .tpkg.var.test
+wait_unbound_up unbound.log
diff --git a/testdata/log_servfail.tdir/log_servfail.test b/testdata/log_servfail.tdir/log_servfail.test
new file mode 100644
index 000000000000..1d19e5ca3b22
--- /dev/null
+++ b/testdata/log_servfail.tdir/log_servfail.test
@@ -0,0 +1,47 @@
+# #-- log_servfail.test --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+PRE="../.."
+. ../common.sh
+
+outfile=dig.out
+
+teststep "Check if log-servfail logs to output for iterator error"
+dig a.servfail @127.0.0.1 -p $SERVER_PORT > $outfile
+if ! grep "SERVFAIL" $outfile
+then
+ cat $outfile
+ echo "Did not get a SERVFAIL response"
+ exit 1
+fi
+if ! grep "SERVFAIL <a\.servfail\. " unbound.log
+then
+ echo "No log-servfail in output"
+ exit 1
+fi
+
+teststep "Enable serve expired"
+$PRE/unbound-control -c ub.conf set_option serve-expired: yes
+if test $? -ne 0
+then
+ echo "unbound-control command exited with non-zero error code"
+ exit 1
+fi
+
+teststep "Check if log-servfail logs to output for iterator error (with serve-expired)"
+dig b.servfail @127.0.0.1 -p $SERVER_PORT > $outfile
+if ! grep "SERVFAIL" $outfile
+then
+ cat $outfile
+ echo "Did not get a SERVFAIL response"
+ exit 1
+fi
+if ! grep "SERVFAIL <b\.servfail\. " unbound.log
+then
+ echo "No log-servfail in output"
+ exit 1
+fi
+
+exit 0
diff --git a/testdata/redis_replica.tdir/after.zone b/testdata/redis_replica.tdir/after.zone
new file mode 100644
index 000000000000..11c268f81497
--- /dev/null
+++ b/testdata/redis_replica.tdir/after.zone
@@ -0,0 +1,2 @@
+redis.com. IN SOA server. ma.il 1 2 3 4 5
+redis.com. IN A 2.2.2.2
diff --git a/testdata/redis_replica.tdir/before.zone b/testdata/redis_replica.tdir/before.zone
new file mode 100644
index 000000000000..8e50c6267516
--- /dev/null
+++ b/testdata/redis_replica.tdir/before.zone
@@ -0,0 +1,2 @@
+redis.com. IN SOA server. ma.il 1 2 3 4 5
+redis.com. IN A 1.1.1.1
diff --git a/testdata/redis_replica.tdir/redis.conf b/testdata/redis_replica.tdir/redis.conf
new file mode 100644
index 000000000000..3b80736e2438
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis.conf
@@ -0,0 +1,583 @@
+###
+### Settings for this test ###################################################
+###
+
+# Accept connections on the specified port, default is 6379 (IANA #815344).
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 0
+
+# Unix socket.
+#
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+unixsocket @SOCKET@
+# unixsocketperm 700
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+# When Redis is supervised by upstart or systemd, this parameter has no impact.
+daemonize no
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+# nothing (nothing is logged)
+loglevel notice
+
+# Specify the log file name. Also the empty string can be used to force
+# Redis to log on the standard output. Note that if you use standard
+# output for logging but daemonize, logs will be sent to /dev/null
+logfile @LOGFILE@
+
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+syslog-enabled no
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 2
+
+# Snapshotting can be completely disabled with a single empty string argument
+# as in following example:
+#
+save ""
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir .
+
+###
+### Rest of the default Redis settings #######################################
+###
+
+bind 127.0.0.1 -::1
+
+# When protected mode is on and the default user has no password, the server
+# only accepts local connections from the IPv4 address (127.0.0.1), IPv6 address
+# (::1) or Unix domain sockets.
+protected-mode yes
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need a high backlog in order
+# to avoid slow clients connection issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+# A reasonable value for this option is 300 seconds, which is the new
+# Redis default starting with Redis 3.2.1.
+tcp-keepalive 300
+
+# By default Redis shows an ASCII art logo only when started to log to the
+# standard output and if the standard output is a TTY and syslog logging is
+# disabled. Basically this means that normally a logo is displayed only in
+# interactive sessions.
+#
+# However it is possible to force the pre-4.0 behavior and always show a
+# ASCII art logo in startup logs by setting the following option to yes.
+always-show-logo no
+
+# By default, Redis modifies the process title (as seen in 'top' and 'ps') to
+# provide some runtime information. It is possible to disable this and leave
+# the process name as executed by setting the following to no.
+set-proc-title yes
+
+# When changing the process title, Redis uses the following template to construct
+# the modified title.
+#
+# Template variables are specified in curly brackets. The following variables are
+# supported:
+#
+# {title} Name of process as executed if parent, or type of child process.
+# {listen-addr} Bind address or '*' followed by TCP or TLS port listening on, or
+# Unix socket if only that's available.
+# {server-mode} Special mode, i.e. "[sentinel]" or "[cluster]".
+# {port} TCP port listening on, or 0.
+# {tls-port} TLS port listening on, or 0.
+# {unixsocket} Unix domain socket listening on, or "".
+# {config-file} Name of configuration file used.
+#
+proc-title-template "{title} {listen-addr} {server-mode}"
+
+# Set the local environment which is used for string comparison operations, and
+# also affect the performance of Lua scripts. Empty String indicates the locale
+# is derived from the environment variables.
+#locale-collate ""
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error yes
+
+# Compress string objects using LZF when dump .rdb databases?
+# By default compression is enabled as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename redis.rdb
+
+# Remove RDB files used by replication in instances without persistence
+# enabled. By default this option is disabled, however there are environments
+# where for regulations or other security concerns, RDB files persisted on
+# disk by masters in order to feed replicas, or stored on disk by replicas
+# in order to load them for the initial synchronization, should be deleted
+# ASAP. Note that this option ONLY WORKS in instances that have both AOF
+# and RDB persistence disabled, otherwise is completely ignored.
+#
+# An alternative (and sometimes better) way to obtain the same effect is
+# to use diskless replication on both master and replicas instances. However
+# in the case of replicas, diskless is not always an option.
+rdb-del-sync-files no
+
+# When a replica loses its connection with the master, or when the replication
+# is still in progress, the replica can act in two different ways:
+#
+# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will
+# still reply to client requests, possibly with out of date data, or the
+# data set may just be empty if this is the first synchronization.
+#
+# 2) If replica-serve-stale-data is set to 'no' the replica will reply with error
+# "MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to 'no'"
+# to all data access commands, excluding commands such as:
+# INFO, REPLICAOF, AUTH, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE,
+# UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST,
+# HOST and LATENCY.
+#
+replica-serve-stale-data yes
+
+# You can configure a replica instance to accept writes or not. Writing against
+# a replica instance may be useful to store some ephemeral data (because data
+# written on a replica will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default replicas are read-only.
+#
+# Note: read only replicas are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only replica exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only replicas using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+replica-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# New replicas and reconnecting replicas that are not able to continue the
+# replication process just receiving differences, need to do what is called a
+# "full synchronization". An RDB file is transmitted from the master to the
+# replicas.
+#
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+# file on disk. Later the file is transferred by the parent
+# process to the replicas incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+# RDB file to replica sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more replicas
+# can be queued and served with the RDB file as soon as the current child
+# producing the RDB file finishes its work. With diskless replication instead
+# once the transfer starts, new replicas arriving will be queued and a new
+# transfer will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple
+# replicas will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync yes
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the replicas.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new replicas arriving, that will be queued for the next RDB transfer, so the
+# server waits a delay in order to let more replicas arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# When diskless replication is enabled with a delay, it is possible to let
+# the replication start before the maximum delay is reached if the maximum
+# number of replicas expected have connected. Default of 0 means that the
+# maximum is not defined and Redis will wait the full delay.
+#repl-diskless-sync-max-replicas 0
+
+# -----------------------------------------------------------------------------
+# WARNING: Since in this setup the replica does not immediately store an RDB on
+# disk, it may cause data loss during failovers. RDB diskless load + Redis
+# modules not handling I/O reads may cause Redis to abort in case of I/O errors
+# during the initial synchronization stage with the master.
+# -----------------------------------------------------------------------------
+#
+# Replica can load the RDB it reads from the replication link directly from the
+# socket, or store the RDB to a file and read that file after it was completely
+# received from the master.
+#
+# In many cases the disk is slower than the network, and storing and loading
+# the RDB file may increase replication time (and even increase the master's
+# Copy on Write memory and replica buffers).
+# However, when parsing the RDB file directly from the socket, in order to avoid
+# data loss it's only safe to flush the current dataset when the new dataset is
+# fully loaded in memory, resulting in higher memory usage.
+# For this reason we have the following options:
+#
+# "disabled" - Don't use diskless load (store the rdb file to the disk first)
+# "swapdb" - Keep current db contents in RAM while parsing the data directly
+# from the socket. Replicas in this mode can keep serving current
+# dataset while replication is in progress, except for cases where
+# they can't recognize master as having a data set from same
+# replication history.
+# Note that this requires sufficient memory, if you don't have it,
+# you risk an OOM kill.
+# "on-empty-db" - Use diskless load only when current dataset is empty. This is
+# safer and avoid having old and new dataset loaded side by side
+# during replication.
+repl-diskless-load disabled
+
+# Master send PINGs to its replicas in a predefined interval. It's possible to
+# change this interval with the repl_ping_replica_period option. The default
+# value is 10 seconds.
+#
+# repl-ping-replica-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of replica.
+# 2) Master timeout from the point of view of replicas (data, pings).
+# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-replica-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the replica. The default
+# value is 60 seconds.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the replica socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to replicas. But this can add a delay for
+# the data to appear on the replica side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the replica side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and replicas are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# The replica priority is an integer number published by Redis in the INFO
+# output. It is used by Redis Sentinel in order to select a replica to promote
+# into a master if the master is no longer working correctly.
+#
+# A replica with a low priority number is considered better for promotion, so
+# for instance if there are three replicas with priority 10, 100, 25 Sentinel
+# will pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the replica as not able to perform the
+# role of master, so a replica with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+replica-priority 100
+
+# ACL LOG
+#
+# The ACL Log tracks failed commands and authentication events associated
+# with ACLs. The ACL Log is useful to troubleshoot failed commands blocked
+# by ACLs. The ACL Log is stored in memory. You can reclaim memory with
+# ACL LOG RESET. Define the maximum entry length of the ACL Log below.
+acllog-max-len 128
+
+lazyfree-lazy-eviction no
+lazyfree-lazy-expire no
+lazyfree-lazy-server-del no
+replica-lazy-flush no
+
+# It is also possible, for the case when to replace the user code DEL calls
+# with UNLINK calls is not easy, to modify the default behavior of the DEL
+# command to act exactly like UNLINK, using the following configuration
+# directive:
+lazyfree-lazy-user-del no
+
+# FLUSHDB, FLUSHALL, SCRIPT FLUSH and FUNCTION FLUSH support both asynchronous and synchronous
+# deletion, which can be controlled by passing the [SYNC|ASYNC] flags into the
+# commands. When neither flag is passed, this directive will be used to determine
+# if the data should be deleted asynchronously.
+lazyfree-lazy-user-flush no
+
+# On Linux, it is possible to hint the kernel OOM killer on what processes
+# should be killed first when out of memory.
+#
+# Enabling this feature makes Redis actively control the oom_score_adj value
+# for all its processes, depending on their role. The default scores will
+# attempt to have background child processes killed before all others, and
+# replicas killed before masters.
+#
+# Redis supports these options:
+#
+# no: Don't make changes to oom-score-adj (default).
+# yes: Alias to "relative" see below.
+# absolute: Values in oom-score-adj-values are written as is to the kernel.
+# relative: Values are used relative to the initial value of oom_score_adj when
+# the server starts and are then clamped to a range of -1000 to 1000.
+# Because typically the initial value is 0, they will often match the
+# absolute values.
+oom-score-adj no
+
+# When oom-score-adj is used, this directive controls the specific values used
+# for master, replica and background child processes. Values range -2000 to
+# 2000 (higher means more likely to be killed).
+#
+# Unprivileged processes (not root, and without CAP_SYS_RESOURCE capabilities)
+# can freely increase their value, but not decrease it below its initial
+# settings. This means that setting oom-score-adj to "relative" and setting the
+# oom-score-adj-values to positive values will always succeed.
+oom-score-adj-values 0 200 800
+
+# Usually the kernel Transparent Huge Pages control is set to "madvise" or
+# or "never" by default (/sys/kernel/mm/transparent_hugepage/enabled), in which
+# case this config has no effect. On systems in which it is set to "always",
+# redis will attempt to disable it specifically for the redis process in order
+# to avoid latency problems specifically with fork(2) and CoW.
+# If for some reason you prefer to keep it enabled, you can set this config to
+# "no" and the kernel global to "always".
+disable-thp yes
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check https://redis.io/topics/persistence for more information.
+appendonly no
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+# By default all notifications are disabled because most users don't need
+# this feature and the feature has some overhead. Note that if you don't
+# specify at least one of K or E, no events will be delivered.
+notify-keyspace-events ""
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+#hash-max-listpack-entries 512
+#hash-max-listpack-value 64
+
+# Lists are also encoded in a special way to save a lot of space.
+# The number of entries allowed per internal list node can be specified
+# as a fixed maximum size or a maximum number of elements.
+# For a fixed maximum size, use -5 through -1, meaning:
+# -5: max size: 64 Kb <-- not recommended for normal workloads
+# -4: max size: 32 Kb <-- not recommended
+# -3: max size: 16 Kb <-- probably not recommended
+# -2: max size: 8 Kb <-- good
+# -1: max size: 4 Kb <-- good
+# Positive numbers mean store up to _exactly_ that number of elements
+# per list node.
+# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
+# but if your use case is unique, adjust the settings as necessary.
+#list-max-listpack-size -2
+
+# Lists may also be compressed.
+# Compress depth is the number of quicklist ziplist nodes from *each* side of
+# the list to *exclude* from compression. The head and tail of the list
+# are always uncompressed for fast push/pop operations. Settings are:
+# 0: disable all list compression
+# 1: depth 1 means "don't start compressing until after 1 node into the list,
+# going from either the head or tail"
+# So: [head]->node->node->...->node->[tail]
+# [head], [tail] will always be uncompressed; inner nodes will compress.
+# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
+# 2 here means: don't compress head or head->next or tail->prev or tail,
+# but compress all nodes between them.
+# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
+# etc.
+list-compress-depth 0
+
+# Sets have a special encoding when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Sets containing non-integer values are also encoded using a memory efficient
+# data structure when they have a small number of entries, and the biggest entry
+# does not exceed a given threshold. These thresholds can be configured using
+# the following directives.
+#set-max-listpack-entries 128
+#set-max-listpack-value 64
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+#zset-max-listpack-entries 128
+#zset-max-listpack-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When a HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Streams macro node max size / items. The stream data structure is a radix
+# tree of big nodes that encode multiple items inside. Using this configuration
+# it is possible to configure how big a single node can be in bytes, and the
+# maximum number of items it may contain before switching to a new node when
+# appending new stream entries. If any of the following settings are set to
+# zero, the limit is ignored, so for instance it is possible to set just a
+# max entries limit by setting max-bytes to 0 and max-entries to the desired
+# value.
+stream-node-max-bytes 4096
+stream-node-max-entries 100
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit replica 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeout, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are performed with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When dynamic HZ is enabled, the actual configured HZ will be used
+# as a baseline, but multiples of the configured HZ value will be actually
+# used as needed once more clients are connected. In this way an idle
+# instance will use very little CPU time while a busy instance will be
+# more responsive.
+dynamic-hz yes
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 4 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes
+
+# When redis saves RDB file, if the following option is enabled
+# the file will be fsync-ed every 4 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+rdb-save-incremental-fsync yes
+
+# Jemalloc background thread for purging will be enabled by default
+jemalloc-bg-thread yes
diff --git a/testdata/redis_replica.tdir/redis_replica.conf b/testdata/redis_replica.tdir/redis_replica.conf
new file mode 100644
index 000000000000..3a558e2337b8
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis_replica.conf
@@ -0,0 +1,31 @@
+server:
+ verbosity: 7
+ num-threads: 1
+ interface: 127.0.0.1
+ port: @PORT@
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ module-config: "cachedb iterator"
+ root-key-sentinel: no
+ trust-anchor-signaling: no
+cachedb:
+ backend: redis
+ redis-server-path: @REDIS_SOCKET@
+ redis-replica-server-path: @REDIS_REPLICA_SOCKET@
+auth-zone:
+ name: "redis.com"
+ for-upstream: yes
+ for-downstream: no
+ zonefile: "redis.zone"
+remote-control:
+ control-enable: yes
+ control-interface: 127.0.0.1
+ # control-interface: ::1
+ control-port: @CONTROL_PORT@
+ server-key-file: "unbound_server.key"
+ server-cert-file: "unbound_server.pem"
+ control-key-file: "unbound_control.key"
+ control-cert-file: "unbound_control.pem"
diff --git a/testdata/redis_replica.tdir/redis_replica.dsc b/testdata/redis_replica.tdir/redis_replica.dsc
new file mode 100644
index 000000000000..03321f11b2b4
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis_replica.dsc
@@ -0,0 +1,16 @@
+BaseName: redis_replica
+Version: 1.0
+Description: Test redis replica operation
+CreationDate: Fri 01 Mar 15:29:09 CET 2024
+Maintainer: Yorgos Thessalonikefs
+Category:
+Component:
+CmdDepends:
+Depends:
+Help:
+Pre: redis_replica.pre
+Post: redis_replica.post
+Test: redis_replica.test
+AuxFiles:
+Passed:
+Failure:
diff --git a/testdata/redis_replica.tdir/redis_replica.post b/testdata/redis_replica.tdir/redis_replica.post
new file mode 100644
index 000000000000..35f11651808f
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis_replica.post
@@ -0,0 +1,18 @@
+# #-- redis_replica.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+. ../common.sh
+kill_pid $REDIS_PID
+kill_pid $REDIS_REPLICA_PID
+kill_pid $UNBOUND_PID
+echo "> cat logfiles"
+echo "redis server.log"
+cat server.log
+echo "redis replica.log"
+cat replica.log
+echo "unbound.log"
+cat unbound.log
diff --git a/testdata/redis_replica.tdir/redis_replica.pre b/testdata/redis_replica.tdir/redis_replica.pre
new file mode 100644
index 000000000000..28ccd7b86d6c
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis_replica.pre
@@ -0,0 +1,46 @@
+# #-- redis_replica.pre--#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+. ../common.sh
+
+if grep "define USE_REDIS 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
+
+get_random_port 2
+UNBOUND_PORT=$RND_PORT
+CONTROL_PORT=$(($RND_PORT + 1))
+echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
+echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
+
+REDIS_SOCKET=server.sock
+REDIS_REPLICA_SOCKET=replica.sock
+echo "REDIS_SOCKET=$REDIS_SOCKET" >> .tpkg.var.test
+echo "REDIS_REPLICA_SOCKET=$REDIS_REPLICA_SOCKET" >> .tpkg.var.test
+
+# start redis
+sed -e 's/@SOCKET\@/'$REDIS_SOCKET'/' -e 's/@LOGFILE\@/server.log/' < redis.conf > server.conf
+redis-server server.conf &
+REDIS_PID=$!
+echo "REDIS_PID=$REDIS_PID" >> .tpkg.var.test
+
+# start redis replica
+sed -e 's/@SOCKET\@/'$REDIS_REPLICA_SOCKET'/' -e 's/@LOGFILE\@/replica.log/' < redis.conf > replica.conf
+redis-server replica.conf &
+REDIS_REPLICA_PID=$!
+echo "REDIS_REPLICA_PID=$REDIS_REPLICA_PID" >> .tpkg.var.test
+
+# Copy initial zonefile
+cp before.zone redis.zone
+
+# make config file
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@REDIS_SOCKET\@/'$REDIS_SOCKET'/' -e 's/@REDIS_REPLICA_SOCKET\@/'$REDIS_REPLICA_SOCKET'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < redis_replica.conf > ub.conf
+# start unbound in the background
+$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+
+cat .tpkg.var.test
+wait_unbound_up unbound.log
diff --git a/testdata/redis_replica.tdir/redis_replica.test b/testdata/redis_replica.tdir/redis_replica.test
new file mode 100644
index 000000000000..a9f15b8094f8
--- /dev/null
+++ b/testdata/redis_replica.tdir/redis_replica.test
@@ -0,0 +1,78 @@
+# #-- redis_replica.test --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# use .tpkg.var.test for in test variable passing
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+
+PRE="../.."
+# do the test
+
+# Check number of keys in the db
+# $1: socket to connect to
+# $2: expected number of keys
+redis_cli_check_keys () {
+ echo "> redis-cli connecting to $1 to check number of keys; expecting $2"
+ keys=$(redis-cli --no-raw -s $1 keys "*" | grep -vF empty | wc -l)
+ if test $keys -ne $2
+ then
+ echo "Expected $2 keys, got $keys"
+ exit 1
+ fi
+ echo "OK"
+}
+
+# Query and check the expected result
+# $1: query
+# $2: expected answer
+expect_answer () {
+ echo "> dig @127.0.0.1 -p $UNBOUND_PORT $1"
+ dig @127.0.0.1 -p $UNBOUND_PORT $1 > tmp.answer
+ if ! grep -F $2 tmp.answer
+ then
+ echo "Expected $2 in the answer, got:"
+ cat tmp.answer
+ exit 1
+ fi
+ echo "OK"
+}
+
+# Start test
+
+# check Redis server has no keys
+redis_cli_check_keys $REDIS_SOCKET 0
+
+# check Redis replica server has no keys
+redis_cli_check_keys $REDIS_REPLICA_SOCKET 0
+
+# query and check answer
+expect_answer redis.com 1.1.1.1
+
+# check Redis server has 1 key
+redis_cli_check_keys $REDIS_SOCKET 1
+
+# check Redis replica server has no keys
+redis_cli_check_keys $REDIS_REPLICA_SOCKET 0
+
+# change auth zone and reload
+cp after.zone redis.zone
+echo "$PRE/unbound-control -c ub.conf reload"
+$PRE/unbound-control -c ub.conf reload
+if test $? -ne 0; then
+ echo "wrong exit value after success"
+ exit 1
+fi
+
+# query and check answer
+# we are writing to server but reading from replica; which is not actually
+# replicating so the new answer will come through while overwriting the record
+# in the server.
+expect_answer redis.com 2.2.2.2
+
+# check Redis server has 1 key
+redis_cli_check_keys $REDIS_SOCKET 1
+
+# check Redis replica server has no keys
+redis_cli_check_keys $REDIS_REPLICA_SOCKET 0
+
+echo "> OK"
+exit 0
diff --git a/testdata/redis_replica.tdir/unbound_control.key b/testdata/redis_replica.tdir/unbound_control.key
new file mode 100644
index 000000000000..753a4ef6162e
--- /dev/null
+++ b/testdata/redis_replica.tdir/unbound_control.key
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA
+1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ
+F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR
+ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm
+vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb
+IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL
+cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr
+lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov
+15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf
+LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+
+Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57
+YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9
+whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c
+lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax
+tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ
+U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9
+Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc
+Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3
+ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+
+1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN
+b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz
+ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C
+TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF
+tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y
+aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0
+A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU
+LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U
+R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy
+7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj
+7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw
+jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1
+BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar
+kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR
+qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3
+VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9
+MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa
+C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g=
+-----END RSA PRIVATE KEY-----
diff --git a/testdata/redis_replica.tdir/unbound_control.pem b/testdata/redis_replica.tdir/unbound_control.pem
new file mode 100644
index 000000000000..a1edf7017f1d
--- /dev/null
+++ b/testdata/redis_replica.tdir/unbound_control.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
+EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
+WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
+A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
+OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
+1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
+NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
+A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
+Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
+TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
+nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
++i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
+4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
+hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
+9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
+ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
+pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
+72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
+muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
+uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
+-----END CERTIFICATE-----
diff --git a/testdata/redis_replica.tdir/unbound_server.key b/testdata/redis_replica.tdir/unbound_server.key
new file mode 100644
index 000000000000..370a7bbb2f22
--- /dev/null
+++ b/testdata/redis_replica.tdir/unbound_server.key
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI
+0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq
+GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z
+uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K
+WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5
+FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP
+q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL
+A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP
+7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf
+XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6
+iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7
+2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo
+MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj
+WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz
+O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI
+IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN
+qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU
+dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs
+bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr
+YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km
+7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr
+gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z
+5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG
+ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN
+oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+
+s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW
+zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx
+ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1
+oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3
+BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS
+mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8
+kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93
+7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8
+RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O
+jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp
+O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre
+MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A==
+-----END RSA PRIVATE KEY-----
diff --git a/testdata/redis_replica.tdir/unbound_server.pem b/testdata/redis_replica.tdir/unbound_server.pem
new file mode 100644
index 000000000000..986807310f2b
--- /dev/null
+++ b/testdata/redis_replica.tdir/unbound_server.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
+EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
+WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
+igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
+a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
+4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
+aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
+TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
+uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
++nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
+XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
+dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
+84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
+JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
+fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
+XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
+qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
+sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
+yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
+CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
+-----END CERTIFICATE-----
diff --git a/testdata/rpz_nsdname.rpl b/testdata/rpz_nsdname.rpl
index a4e9bb31d30e..661f5da2c345 100644
--- a/testdata/rpz_nsdname.rpl
+++ b/testdata/rpz_nsdname.rpl
@@ -32,7 +32,7 @@ stub-zone:
stub-addr: 1.1.1.1
CONFIG_END
-SCENARIO_BEGIN Test RPZ nsip triggers
+SCENARIO_BEGIN Test RPZ nsdname triggers
; . --------------------------------------------------------------------------
RANGE_BEGIN 0 100
diff --git a/testdata/rpz_val_block.rpl b/testdata/rpz_val_block.rpl
index acde15294adb..d2cd897e09e7 100644
--- a/testdata/rpz_val_block.rpl
+++ b/testdata/rpz_val_block.rpl
@@ -6,7 +6,6 @@ server:
trust-anchor: "org. DS 1444 8 2 5224fb17d630a2e3efdc863a05a4032c5db415b5de3f32472ee9abed42e10146"
val-override-date: "20070916134226"
trust-anchor-signaling: no
- log-servfail: yes
val-log-level: 2
ede: yes
diff --git a/testdata/serve_expired.rpl b/testdata/serve_expired.rpl
index 3f61019fa89f..990a562c7191 100644
--- a/testdata/serve_expired.rpl
+++ b/testdata/serve_expired.rpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
access-control: 127.0.0.1/32 allow_snoop
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_0ttl_nodata.rpl b/testdata/serve_expired_0ttl_nodata.rpl
index 7f1b5a565853..8ca461be2c7b 100644
--- a/testdata/serve_expired_0ttl_nodata.rpl
+++ b/testdata/serve_expired_0ttl_nodata.rpl
@@ -4,7 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
- log-servfail: yes
+ serve-expired-client-timeout: 0
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_0ttl_nxdomain.rpl b/testdata/serve_expired_0ttl_nxdomain.rpl
index 4adb4b839a69..7cf26aedda0a 100644
--- a/testdata/serve_expired_0ttl_nxdomain.rpl
+++ b/testdata/serve_expired_0ttl_nxdomain.rpl
@@ -4,7 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
- log-servfail: yes
+ serve-expired-client-timeout: 0
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_0ttl_servfail.rpl b/testdata/serve_expired_0ttl_servfail.rpl
index 6833af17b827..e9d4c4884e9f 100644
--- a/testdata/serve_expired_0ttl_servfail.rpl
+++ b/testdata/serve_expired_0ttl_servfail.rpl
@@ -4,7 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
- log-servfail: yes
+ serve-expired-client-timeout: 0
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_cached_servfail.rpl b/testdata/serve_expired_cached_servfail.rpl
index edec7447940f..eb115816ec1d 100644
--- a/testdata/serve_expired_cached_servfail.rpl
+++ b/testdata/serve_expired_cached_servfail.rpl
@@ -4,8 +4,8 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
- log-servfail: yes
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_cached_servfail_refresh.rpl b/testdata/serve_expired_cached_servfail_refresh.rpl
index 4d14dd948ffb..63277f25f15e 100644
--- a/testdata/serve_expired_cached_servfail_refresh.rpl
+++ b/testdata/serve_expired_cached_servfail_refresh.rpl
@@ -4,8 +4,8 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
- log-servfail: yes
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_client_timeout_servfail.rpl b/testdata/serve_expired_client_timeout_servfail.rpl
index cea216d4c60f..3c5b35e1793a 100644
--- a/testdata/serve_expired_client_timeout_servfail.rpl
+++ b/testdata/serve_expired_client_timeout_servfail.rpl
@@ -6,11 +6,9 @@ server:
serve-expired: yes
serve-expired-client-timeout: 1
serve-expired-reply-ttl: 123
- log-servfail: yes
ede: yes
ede-serve-expired: yes
-
stub-zone:
name: "example.com"
stub-addr: 1.2.3.4
@@ -26,8 +24,10 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and a SERVFAIL upstream re
; - check that we get the expired cached answer
; - query again (the answer is available on the upstream server now)
; - check that we get the immediate expired answer back instead
-; - (the upstream query does happen after the expired reply and updates the cache)
-; - query again (the upstream has no answer)
+; - query again (the answer is available on the upstream server now)
+; - check that we *still* get the immediate expired answer back instead, recursion is blocked for NORR_TTL(5)
+; - wait for NORR_TTL(5) to expire
+; - query again
; - check that we get the freshly cached answer
; ns.example.com.
@@ -74,7 +74,7 @@ RANGE_BEGIN 30 40
RANGE_END
; ns.example.com.
-RANGE_BEGIN 50 60
+RANGE_BEGIN 50 100
ADDRESS 1.2.3.4
; response to A query
ENTRY_BEGIN
@@ -149,12 +149,8 @@ ENTRY_BEGIN
example.com. IN A
ENTRY_END
-; Allow for upstream query to resolve.
-STEP 51 TRAFFIC
-
; Check that we got an immediate stale answer because of the previous failure,
-; regardless if upstream has the answer already in this range. The query will
-; be resolved after the immediate cached answer and will cache the result.
+; regardless if upstream has the answer already in this range.
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
@@ -172,15 +168,42 @@ ENTRY_END
; Query again
STEP 70 QUERY
ENTRY_BEGIN
- REPLY RD
+ REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
-; Check that we got the cached updated answer from the previous step since
-; there is no upstream in this range.
+; Check that we still get the immediate stale answer because of the previous failure,
+; regardless if upstream has the answer already in this range. NORR_TTL(5) blocks us from
+; recursion.
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
+ MATCH all ttl ede=3
+ REPLY QR RD RA DO NOERROR
+ SECTION QUESTION
+ example.com. IN A
+ SECTION ANSWER
+ example.com. 123 IN A 5.6.7.8
+ SECTION AUTHORITY
+ example.com. 123 IN NS ns.example.com.
+ SECTION ADDITIONAL
+ ns.example.com. 123 IN A 1.2.3.4
+ENTRY_END
+
+; Let NORR_TTL(5) expire
+STEP 81 TIME_PASSES ELAPSE 5
+
+; Query again
+STEP 90 QUERY
+ENTRY_BEGIN
+ REPLY RD
+ SECTION QUESTION
+ example.com. IN A
+ENTRY_END
+
+; Check fresh reply
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
diff --git a/testdata/serve_expired_client_timeout_val_bogus.rpl b/testdata/serve_expired_client_timeout_val_bogus.rpl
index f4937a16c538..47a6545a4035 100644
--- a/testdata/serve_expired_client_timeout_val_bogus.rpl
+++ b/testdata/serve_expired_client_timeout_val_bogus.rpl
@@ -30,13 +30,22 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and bogus answer
; - wait for the record to expire
; - (upstream now has a bogus response)
; - query again for www.example.com. IN A
-; - check that we get the expired valid response instead
-; - query once more
+; - check that we get the expired valid response instead; recursion is blocked for NORR_TTL(5) because of the failure
; - (upstream has the valid response again)
+; - query once more
; - check that we get the immediate expired valid response
-; - (the prefetch query updates the cache with the valid response)
+; - let NORR_TTL(5) expire
; - query one last time
-; - check that we get the immediate valid cache response; upstream does not have an answer at this moment
+; - check that we get the immediate valid cache response
+
+; The example.com NS and ns.example.com A record are commented out.
+; This to make the test succeed. It then keeps the dnssec valid lookup.
+; Otherwise, the relookup of the referral would overwrite the example.com NS
+; the serve expired response would no longer be valid. But this record must
+; be cached, for keeping the current delegation information.
+; Also the DNSKEY lookup authority and additional are cleaned to stop overwrite
+; of the NS and A record. This is more likely to keep the serve expired
+; information intact.
;;
;; K.ROOT-SERVERS.NET.
@@ -150,12 +159,12 @@ RANGE_BEGIN 0 10
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
@@ -174,12 +183,12 @@ RANGE_BEGIN 20 30
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
;; (valid signature)
;; www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
;; (bogus signature)
@@ -190,7 +199,7 @@ RANGE_END
;;
;; ns.example.com. with valid data again
;;
-RANGE_BEGIN 40 60
+RANGE_BEGIN 40 70
ADDRESS 1.2.3.4
; response to query of interest
ENTRY_BEGIN
@@ -201,12 +210,12 @@ RANGE_BEGIN 40 60
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
@@ -229,11 +238,11 @@ SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. IN NS ns.example.com.
-example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. IN A 1.2.3.4
-ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
STEP 11 TIME_PASSES ELAPSE 3601
@@ -256,11 +265,11 @@ SECTION ANSWER
www.example.com. 123 IN A 10.20.30.40
www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. 123 IN NS ns.example.com.
-example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. 123 IN A 1.2.3.4
-ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
STEP 40 QUERY
@@ -270,7 +279,7 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
-; immediate cached answer because upstream is valid again
+; immediate cached answer; although upstream is valid again
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
@@ -281,14 +290,16 @@ SECTION ANSWER
www.example.com. 123 IN A 10.20.30.40
www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. 123 IN NS ns.example.com.
-example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. 123 IN A 1.2.3.4
-ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
-; upstream query is resolved before this query comes in
+STEP 51 TIME_PASSES ELAPSE 5
+
+; query one last time
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD DO
@@ -296,7 +307,7 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
-; prefetch query updated the cache, since there is no upstream response in this range
+; this is the fresh valid response
STEP 70 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
@@ -307,11 +318,11 @@ SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. IN NS ns.example.com.
-example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. IN A 1.2.3.4
-ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
SCENARIO_END
diff --git a/testdata/serve_expired_reply_ttl.rpl b/testdata/serve_expired_reply_ttl.rpl
index 124fb874df0e..e76976bde07d 100644
--- a/testdata/serve_expired_reply_ttl.rpl
+++ b/testdata/serve_expired_reply_ttl.rpl
@@ -5,6 +5,7 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 123
+ serve-expired-client-timeout: 0
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_expired_ttl.rpl b/testdata/serve_expired_ttl.rpl
index df4ecb89d48a..66acbdcf1fe1 100644
--- a/testdata/serve_expired_ttl.rpl
+++ b/testdata/serve_expired_ttl.rpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-ttl: 10
stub-zone:
diff --git a/testdata/serve_expired_ttl_reset.rpl b/testdata/serve_expired_ttl_reset.rpl
index 521d5a0f04ca..9f215c96bcd1 100644
--- a/testdata/serve_expired_ttl_reset.rpl
+++ b/testdata/serve_expired_ttl_reset.rpl
@@ -4,6 +4,7 @@ server:
serve-expired-ttl: 1
serve-expired-ttl-reset: yes
serve-expired-reply-ttl: 123
+ serve-expired-client-timeout: 0
ede: yes
ede-serve-expired: yes
forward-zone: name: "." forward-addr: 216.0.0.1
@@ -15,11 +16,11 @@ SCENARIO_BEGIN Serve expired ttl with reset on forwarder with a timeout on upstr
; - Wait for it to expire (+ serve-expired-ttl)
; - Send query again
; - Upstream timeouts
-; - Error response from iterator SERVFAIL, resets expired-ttl on cache
-; - Check we are getting the SERVFAIL response
+; - Error response from iterator SERVFAIL, resets expired-ttl on cache and sets norec_ttl blocking recursion
+; - Check we are getting the cached response because it was expired-ttl-reset
; - Query again
-; - Check we are getting the expired answer
-; - Upstream still timeouts
+; - Check we are getting the expired answer; prefetching is blocked by norec_ttl
+; - If there was prefetching the test would fail with the pending upstream query
STEP 1 QUERY
ENTRY_BEGIN
@@ -53,7 +54,7 @@ STEP 4 TIME_PASSES ELAPSE 12
STEP 5 QUERY
ENTRY_BEGIN
-REPLY RD
+REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -66,14 +67,16 @@ STEP 8 TIMEOUT
STEP 9 TIMEOUT
STEP 10 TIMEOUT
-; Returns servfail
+; Returns
; but error response from iterator resets the expired ttl
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
-MATCH all ttl
-REPLY QR RA RD SERVFAIL
+MATCH all ttl ede=3
+REPLY QR RA RD DO NOERROR
SECTION QUESTION
www.example.com. IN A
+SECTION ANSWER
+www.example.com. 123 IN A 0.0.0.0
ENTRY_END
; Query again
@@ -95,8 +98,4 @@ SECTION ANSWER
www.example.com. 123 IN A 0.0.0.0
ENTRY_END
-; But the pending query times out!
-; Only one because RTT reached the limit.
-STEP 16 TIMEOUT
-
SCENARIO_END
diff --git a/testdata/serve_expired_val_bogus.rpl b/testdata/serve_expired_val_bogus.rpl
index 35365beef973..54b66fe98800 100644
--- a/testdata/serve_expired_val_bogus.rpl
+++ b/testdata/serve_expired_val_bogus.rpl
@@ -10,6 +10,7 @@ server:
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
@@ -30,12 +31,27 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and bogus answer
; - (upstream now has a bogus response)
; - query again for www.example.com. IN A
; - check that we get the immediate expired valid response
-; - (prefetch response is bogus and is not cached)
+; - (prefetch response is bogus and is not cached; recursion is blocked for NORR_TTL(5) because of the failure)
+; - (upstream has a valid response again)
; - query once more
-; - check that we still get the immediate expired valid response and not the fresh bogus one
-; - (upstream has a valid response again; prefetch will update the cache)
+; - check that we still get the immediate expired valid response (prefetch will not trigger because of NORR_TTL(5))
+; - query and check that cache was not updated
+; - let NORR_TTL(5) expire
+; - query once more
+; - check that we still get the immediate expired valid response
+; - (prefetch should be allowed to refresh the record at this point)
+; - (upstream does not have the answer anymore)
; - query one last time
-; - check that we get an immediate valid cache response
+; - check that we get the immediate valid cache response
+
+; The example.com NS and ns.example.com A record are commented out.
+; This to make the test succeed. It then keeps the dnssec valid lookup.
+; Otherwise, the relookup of the referral would overwrite the example.com NS
+; the serve expired response would no longer be valid. But this record must
+; be cached, for keeping the current delegation information.
+; Also the DNSKEY lookup authority and additional are cleaned to stop overwrite
+; of the NS and A record. This is more likely to keep the serve expired
+; information intact.
;;
;; K.ROOT-SERVERS.NET.
@@ -149,12 +165,12 @@ RANGE_BEGIN 0 10
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
@@ -173,12 +189,12 @@ RANGE_BEGIN 20 40
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
;; (valid signature)
;; www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
;; (bogus signature)
@@ -200,12 +216,12 @@ RANGE_BEGIN 50 100
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
- ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
SECTION AUTHORITY
- example.com. IN NS ns.example.com.
- example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+ ;example.com. IN NS ns.example.com.
+ ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
- ns.example.com. IN A 1.2.3.4
+ ;ns.example.com. IN A 1.2.3.4
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
@@ -229,11 +245,11 @@ SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. IN NS ns.example.com.
-example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. IN A 1.2.3.4
-ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
STEP 11 TIME_PASSES ELAPSE 3601
@@ -256,13 +272,14 @@ SECTION ANSWER
www.example.com. 123 IN A 10.20.30.40
www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. 123 IN NS ns.example.com.
-example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. 123 IN A 1.2.3.4
-ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
+; query with response available on the server
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD DO
@@ -270,7 +287,8 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
-; this is still the immediate cache response because the previous upstream response was bogus
+; this is still the immediate expired cache response because the previous upstream response was bogus
+; upstream query did not go out because of the previous failure NORR_TTL(5).
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
@@ -281,13 +299,14 @@ SECTION ANSWER
www.example.com. 123 IN A 10.20.30.40
www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. 123 IN NS ns.example.com.
-example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. 123 IN A 1.2.3.4
-ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
+; query with response available
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD DO
@@ -295,9 +314,63 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
-; this is the immediate cache response because the previous upstream response was valid
+; this is still the immediate expired cache response because resolution is blocked for NORR_TTL(5)
STEP 70 CHECK_ANSWER
ENTRY_BEGIN
+MATCH all ttl ede=3
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 123 IN A 10.20.30.40
+www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+; expire NORR_TTL(5)
+STEP 71 TIME_PASSES ELAPSE 5
+
+; query again
+STEP 80 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; this is still the immediate expired cache response but prefetching will be allowed to update the cache
+STEP 90 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl ede=3
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 123 IN A 10.20.30.40
+www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+SECTION AUTHORITY
+;example.com. 123 IN NS ns.example.com.
+;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+;ns.example.com. 123 IN A 1.2.3.4
+;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+ENTRY_END
+
+STEP 100 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; this is the immediate cache response because the previous upstream response was valid
+STEP 110 CHECK_ANSWER
+ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
@@ -306,11 +379,11 @@ SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
-example.com. IN NS ns.example.com.
-example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+;example.com. IN NS ns.example.com.
+;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
-ns.example.com. IN A 1.2.3.4
-ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+;ns.example.com. IN A 1.2.3.4
+;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
SCENARIO_END
diff --git a/testdata/serve_expired_zerottl.rpl b/testdata/serve_expired_zerottl.rpl
index 0239b4a19440..1411cb8e77a5 100644
--- a/testdata/serve_expired_zerottl.rpl
+++ b/testdata/serve_expired_zerottl.rpl
@@ -4,6 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
diff --git a/testdata/serve_original_ttl.rpl b/testdata/serve_original_ttl.rpl
index 24d01b6fee1e..30503c285ccd 100644
--- a/testdata/serve_original_ttl.rpl
+++ b/testdata/serve_original_ttl.rpl
@@ -8,6 +8,7 @@ server:
cache-max-ttl: 1000
cache-min-ttl: 20
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
diff --git a/testdata/stat_values.tdir/stat_values.conf b/testdata/stat_values.tdir/stat_values.conf
index dc4553920635..312a7e17494f 100644
--- a/testdata/stat_values.tdir/stat_values.conf
+++ b/testdata/stat_values.tdir/stat_values.conf
@@ -14,6 +14,10 @@ server:
outbound-msg-retry: 0
root-key-sentinel: no
trust-anchor-signaling: no
+ serve-expired-client-timeout: 0
+ dns-error-reporting: yes
+
+ trust-anchor: "bogusdnssec. DS 1444 8 2 5224fb17d630a2e3efdc863a05a4032c5db415b5de3f32472ee9abed42e10146"
local-zone: local.zone static
local-data: "www.local.zone A 192.0.2.1"
@@ -26,9 +30,15 @@ remote-control:
server-cert-file: "unbound_server.pem"
control-key-file: "unbound_control.key"
control-cert-file: "unbound_control.pem"
-forward-zone:
- name: "."
- forward-addr: "127.0.0.1@@TOPORT@"
-forward-zone:
+stub-zone:
+ name: "example.com."
+ stub-addr: "127.0.0.1@@TOPORT@"
+stub-zone:
+ name: "bogusdnssec."
+ stub-addr: "127.0.0.1@@TOPORT@"
+stub-zone:
+ name: "an.agent."
+ stub-addr: "127.0.0.1@@TOPORT@"
+stub-zone:
name: "expired."
- forward-addr: "127.0.0.1@@EXPIREDPORT@"
+ stub-addr: "127.0.0.1@@EXPIREDPORT@"
diff --git a/testdata/stat_values.tdir/stat_values.pre b/testdata/stat_values.tdir/stat_values.pre
index 7b6eefdfaa49..81f94d8d10be 100644
--- a/testdata/stat_values.tdir/stat_values.pre
+++ b/testdata/stat_values.tdir/stat_values.pre
@@ -38,6 +38,7 @@ echo "FWD_EXPIRED_PID=$FWD_EXPIRED_PID" >> .tpkg.var.test
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values.conf > ub.conf
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_cachedb.conf > ub_cachedb.conf
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_downstream_cookies.conf > ub_downstream_cookies.conf
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_discard_wait_limit.conf > ub_discard_wait_limit.conf
# start unbound in the background
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
diff --git a/testdata/stat_values.tdir/stat_values.test b/testdata/stat_values.tdir/stat_values.test
index 814ecd1168d3..d538e4d60ec2 100644
--- a/testdata/stat_values.tdir/stat_values.test
+++ b/testdata/stat_values.tdir/stat_values.test
@@ -3,7 +3,6 @@
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
-# We need kill_pid for the serve-expired-client-timeout test
. ../common.sh
PRE="../.."
@@ -154,6 +153,19 @@ set_ub_option () {
fi
}
+# Convenient function to kill current Unbound and bring up one with an alternate configuration.
+bring_up_alternate_configuration () {
+ conf_file=$1
+ kill_pid $UNBOUND_PID # kill current Unbound
+ echo ""
+ cat unbound.log
+ echo ""
+ $PRE/unbound -d -c $conf_file >unbound.log 2>&1 &
+ UNBOUND_PID=$!
+ echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+ wait_unbound_up unbound.log
+}
+
# Convenient function to exit the test.
end () {
echo "> cat logfiles"
@@ -180,8 +192,8 @@ else
end 1
fi
-echo
-echo "[ Check initial stats based on first query. ]"
+
+teststep "Check initial stats based on first query."
check_stats "\
total.num.queries=1
total.num.cachemiss=1
@@ -198,16 +210,15 @@ rrset.cache.count=1
infra.cache.count=1
num.answer.rcode.NOERROR=1"
-echo
-echo "[ Check stat reset. ]"
+
+teststep "Check stat reset."
check_stats "\
msg.cache.count=1
rrset.cache.count=1
infra.cache.count=1"
-echo
-echo "[ Enable serve-expired and check. ]"
+teststep "Enable serve-expired and check."
set_ub_option serve-expired yes
sleep 2 # make sure the TTL has expired.
echo "> dig 1ttl.example.com."
@@ -236,8 +247,7 @@ rrset.cache.count=1
infra.cache.count=1"
-echo
-echo "[ Enable serve-expired-client-timeout and check. ]"
+teststep "Enable serve-expired-client-timeout and check."
set_ub_option serve-expired-client-timeout 1
echo "> dig servfail.expired."
dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile
@@ -295,8 +305,7 @@ infra.cache.count=2"
set_ub_option serve-expired no
-echo
-echo "[ Check REFUSED; try without RD flag. ]"
+teststep "Check REFUSED; try without RD flag."
echo "> dig somethingelse.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT +nordflag somethingelse.example.com. | tee outfile
echo "> check answer"
@@ -319,8 +328,7 @@ rrset.cache.count=2
infra.cache.count=2"
-echo
-echo "[ Check the AD flag. ]"
+teststep "Check the AD flag."
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT +noadflag www.example.com. | tee outfile
echo "> check answer"
@@ -345,8 +353,8 @@ msg.cache.count=3
rrset.cache.count=3
infra.cache.count=2"
-echo
-echo "[ Check local zone. ]"
+
+teststep "Check local zone."
echo "> dig www.local.zone."
dig @127.0.0.1 -p $UNBOUND_PORT www.local.zone. | tee outfile
echo "> check answer"
@@ -370,8 +378,7 @@ rrset.cache.count=3
infra.cache.count=2"
-echo
-echo "[ Check NXDOMAIN (with local data). ]"
+teststep "Check NXDOMAIN (with local data)."
echo "> dig mail.local.zone."
dig @127.0.0.1 -p $UNBOUND_PORT mail.local.zone. | tee outfile
echo "> check answer"
@@ -395,8 +402,7 @@ rrset.cache.count=3
infra.cache.count=2"
-echo
-echo "[ Check CHAOS. ]"
+teststep "Check CHAOS."
echo "> dig id.server. ch txt"
dig @127.0.0.1 -p $UNBOUND_PORT id.server. ch txt | tee outfile
echo "> check answer"
@@ -420,18 +426,79 @@ rrset.cache.count=3
infra.cache.count=2"
+teststep "Check dns-error-reporting."
+echo "> dig www.bogusdnssec."
+dig @127.0.0.1 -p $UNBOUND_PORT www.bogusdnssec. | tee outfile
+echo "> check answer"
+if grep "SERVFAIL" outfile; then
+ echo "OK"
+else
+ end 1
+fi
+check_stats "\
+infra.cache.count=4
+key.cache.count=1
+msg.cache.count=7
+num.answer.bogus=1
+num.answer.rcode.SERVFAIL=1
+num.query.class.IN=1
+num.query.edns.present=1
+num.query.flags.AD=1
+num.query.flags.RD=1
+num.query.opcode.QUERY=1
+num.query.type.A=1
+num.query.udpout=9
+rrset.cache.count=4
+total.num.cachemiss=1
+total.num.dns_error_reports=1
+total.num.queries=1
+total.num.recursivereplies=1"
+
+
+###
+#
+# Bring the discard-timeout, wait-limit configured Unbound up
+#
+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
+ echo "OK"
+else
+ end 1
+fi
+check_stats "\
+infra.cache.count=1
+msg.cache.count=1
+num.query.class.IN=3
+num.query.edns.present=3
+num.query.flags.AD=3
+num.query.flags.RD=3
+num.query.opcode.QUERY=3
+num.query.type.A=3
+num.query.udpout=1
+total.num.cachemiss=3
+total.num.queries=3
+total.num.queries_discard_timeout=2
+total.num.queries_wait_limit=1"
+
+
+###
+#
# Bring the downstream DNS Cookies configured Unbound up
-kill_pid $UNBOUND_PID # kill current Unbound
-echo ""
-cat unbound.log
-echo ""
-$PRE/unbound -d -c ub_downstream_cookies.conf >unbound.log 2>&1 &
-UNBOUND_PID=$!
-echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
-wait_unbound_up unbound.log
+#
+bring_up_alternate_configuration ub_downstream_cookies.conf
+#
+###
+
-echo
-echo "[ Get a DNS Cookie. ]"
+teststep "Get a DNS Cookie."
echo "> dig www.local.zone +tcp $nocookie +ednsopt=10:0102030405060708"
dig @127.0.0.1 -p $UNBOUND_PORT +tcp $nocookie +ednsopt=10:0102030405060708 +retry=0 +time=1 www.local.zone. | tee outfile
echo "> check answer"
@@ -456,8 +523,8 @@ num.query.edns.present=1
num.query.tcp=1
num.answer.rcode.NOERROR=1"
-echo
-echo "[ Present the valid DNS Cookie. ]"
+
+teststep "Present the valid DNS Cookie."
echo "> dig www.local.zone $nocookie +ednsopt=10:valid_cookie"
dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$valid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
echo "> check answer"
@@ -478,8 +545,8 @@ num.query.flags.AD=1
num.query.edns.present=1
num.answer.rcode.NOERROR=1"
-echo
-echo "[ Present an invalid DNS Cookie. ]"
+
+teststep "Present an invalid DNS Cookie."
echo "> dig www.local.zone $nocookie +ednsopt=10:invalid_cookie"
dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$invalid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
echo "> check answer"
@@ -497,8 +564,8 @@ total.num.queries_cookie_invalid=1
total.num.cachehits=1
num.answer.rcode.YXRRSET=1"
-echo
-echo "[ Present no DNS Cookie. ]"
+
+teststep "Present no DNS Cookie."
echo "> dig www.local.zone +ignore"
dig @127.0.0.1 -p $UNBOUND_PORT +ignore $nocookie +retry=0 +time=1 www.local.zone. | tee outfile
echo "> check answer"
@@ -516,18 +583,17 @@ num.answer.rcode.REFUSED=1"
if test x$USE_CACHEDB = "x1"; then
+
+###
+#
# Bring the cachedb configured Unbound up
-kill_pid $UNBOUND_PID # kill current Unbound
-echo ""
-cat unbound.log
-echo ""
-$PRE/unbound -d -c ub_cachedb.conf >unbound.log 2>&1 &
-UNBOUND_PID=$!
-echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
-wait_unbound_up unbound.log
+#
+bring_up_alternate_configuration ub_cachedb.conf
+#
+###
+
-echo
-echo "[ Check cachedb cache miss. ]"
+teststep "Check cachedb cache miss."
echo "> dig www.example.com."
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
@@ -554,8 +620,8 @@ rrset.cache.count=1
infra.cache.count=1
num.answer.rcode.NOERROR=1"
-echo
-echo "[ Check cachedb cache hit. ]"
+
+teststep "Check cachedb cache hit."
echo "> dig www.example.com."
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
@@ -582,8 +648,8 @@ rrset.cache.count=1
infra.cache.count=1
num.answer.rcode.NOERROR=1"
-echo
-echo "[ Check cachedb cache hit with stat reset ]"
+
+teststep "Check cachedb cache hit with stat reset."
echo "> dig www.example.com."
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
diff --git a/testdata/stat_values.tdir/stat_values.testns b/testdata/stat_values.tdir/stat_values.testns
index 12df8a93905a..a5c0ae92b599 100644
--- a/testdata/stat_values.tdir/stat_values.testns
+++ b/testdata/stat_values.tdir/stat_values.testns
@@ -31,3 +31,52 @@ SECTION QUESTION
SECTION ANSWER
0ttl 0 IN A 0.0.0.1
ENTRY_END
+
+
+
+$ORIGIN bogusdnssec.
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+@ IN DNSKEY
+SECTION ANSWER
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+www IN A
+SECTION ANSWER
+www 0 IN A 10.20.30.40
+; bogus signature to not trigger LAME DNSSEC and continue with validation
+www 0 IN RRSIG A 8 2 240 20250429005000 20250401005000 42393 bogusdnssec. ob6ddTJkdeOUn92cxx1NPGneV7rhOp2zKBv8FXQjJ/Wso8LJJnzRHW9p 3sTatlzi+UdRi7BOrcxwjUG38lgO+TS5vRFGAiTRmOezm6xJVNTg8lIb RJGCD5bRtRRstwt31Qt6Gda+6sAyvDebpUB/opkQpevv6xohdrhr0g8+ Q4w=
+SECTION ADDITIONAL
+; dns error reporting agent
+HEX_EDNSDATA_BEGIN
+ 00 12 ; opt-code (Report-Channel)
+ 00 0A ; opt-len
+ 02 61 6E 05 61 67 65 6E 74 00 ; an.agent.
+HEX_EDNSDATA_END
+ENTRY_END
+
+
+
+$ORIGIN an.agent.
+;just give an answer back to anything
+ENTRY_BEGIN
+MATCH opcode subdomain
+REPLY QR AA NXDOMAIN
+ADJUST copy_id copy_query
+SECTION QUESTION
+an.agent. IN ANY
+ENTRY_END
+
+
+
+$ORIGIN unresponsive.
+;; no entry for 'unresponsive.', we rely on timeouts.
diff --git a/testdata/stat_values.tdir/stat_values_cachedb.conf b/testdata/stat_values.tdir/stat_values_cachedb.conf
index b5e9b0e02932..b7b375b36ef1 100644
--- a/testdata/stat_values.tdir/stat_values_cachedb.conf
+++ b/testdata/stat_values.tdir/stat_values_cachedb.conf
@@ -1,7 +1,6 @@
server:
verbosity: 5
module-config: "cachedb iterator"
- serve-expired: yes
num-threads: 1
interface: 127.0.0.1
port: @PORT@
@@ -17,8 +16,6 @@ server:
root-key-sentinel: no
trust-anchor-signaling: no
- local-zone: local.zone static
- local-data: "www.local.zone A 192.0.2.1"
remote-control:
control-enable: yes
control-interface: 127.0.0.1
@@ -28,9 +25,6 @@ remote-control:
server-cert-file: "unbound_server.pem"
control-key-file: "unbound_control.key"
control-cert-file: "unbound_control.pem"
-forward-zone:
- name: "."
- forward-addr: "127.0.0.1@@TOPORT@"
-forward-zone:
- name: "expired."
- forward-addr: "127.0.0.1@@EXPIREDPORT@"
+stub-zone:
+ name: "example.com."
+ stub-addr: "127.0.0.1@@TOPORT@"
diff --git a/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf b/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf
new file mode 100644
index 000000000000..b6f63cf17cfd
--- /dev/null
+++ b/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf
@@ -0,0 +1,36 @@
+server:
+ verbosity: 5
+ num-threads: 1
+ interface: 127.0.0.1
+ module-config: "validator iterator"
+ port: @PORT@
+ use-syslog: no
+ directory: ""
+ pidfile: "unbound.pid"
+ chroot: ""
+ username: ""
+ do-not-query-localhost: no
+ extended-statistics: yes
+ identity: "stat_values"
+ outbound-msg-retry: 0
+ root-key-sentinel: no
+ trust-anchor-signaling: no
+
+ discard-timeout: 800
+ wait-limit: 1
+ wait-limit-netblock: 127.0.0.0/8 1
+ wait-limit-netblock: ::1/128 1
+ infra-cache-min-rtt: 3000 # This is for the discard-timeout test
+
+remote-control:
+ control-enable: yes
+ control-interface: 127.0.0.1
+ # control-interface: ::1
+ control-port: @CONTROL_PORT@
+ server-key-file: "unbound_server.key"
+ server-cert-file: "unbound_server.pem"
+ control-key-file: "unbound_control.key"
+ control-cert-file: "unbound_control.pem"
+stub-zone:
+ name: "unresponsive."
+ stub-addr: "127.0.0.1@@TOPORT@"
diff --git a/testdata/subnet_cached_servfail.crpl b/testdata/subnet_cached_servfail.crpl
index 9c746d579124..f1a66159c4ee 100644
--- a/testdata/subnet_cached_servfail.crpl
+++ b/testdata/subnet_cached_servfail.crpl
@@ -12,6 +12,7 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
prefetch: yes
stub-zone:
diff --git a/testdata/subnet_global_prefetch_always_forward.crpl b/testdata/subnet_global_prefetch_always_forward.crpl
index ccfe5dfd6ea1..775474cbcfeb 100644
--- a/testdata/subnet_global_prefetch_always_forward.crpl
+++ b/testdata/subnet_global_prefetch_always_forward.crpl
@@ -6,6 +6,7 @@ server:
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
serve-expired: yes
+ serve-expired-client-timeout: 0
client-subnet-always-forward: yes
module-config: "subnetcache iterator"
verbosity: 3
diff --git a/testdata/subnet_global_prefetch_expired.crpl b/testdata/subnet_global_prefetch_expired.crpl
index de1b780553a9..374bf3e693aa 100644
--- a/testdata/subnet_global_prefetch_expired.crpl
+++ b/testdata/subnet_global_prefetch_expired.crpl
@@ -14,6 +14,7 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
+ serve-expired-client-timeout: 0
serve-expired-ttl: 1
prefetch: yes
diff --git a/testdata/test_ldnsrr.4 b/testdata/test_ldnsrr.4
index 07c9960d5053..b20a317289b3 100644
--- a/testdata/test_ldnsrr.4
+++ b/testdata/test_ldnsrr.4
@@ -35,7 +35,8 @@ all.rr.org. IN LOC 42N 71 06 18.3W -24m 30m
; EID
; NIMLOC
_http._tcp.all.rr.org. IN SRV 0 5 80 ns1.example.com.
-; ATMA
+atma0 IN ATMA 39.246f.00.0e7c9c.0312.0001.0001.000012345678.00
+atma1 IN ATMA +1.908.555.1212
all.rr.org. IN NAPTR 100 10 "" "" "!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i" .
all.rr.org. IN KX 2 rt1.example.com.
all.rr.org. IN CERT 6 0 0 FFsAyW1dVK7hIGuvhN56r26UwJx/
diff --git a/testdata/test_ldnsrr.5 b/testdata/test_ldnsrr.5
index 2762ca82d327..1f2837a67098 100644
--- a/testdata/test_ldnsrr.5
+++ b/testdata/test_ldnsrr.5
@@ -174,3 +174,5 @@ root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 ( f1ca0ccd91bd5573d9f43
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.1m 0.1m 0.1m
; from ldns issue #147, fix #148, tab between quoted strings.
foo 12345 IN HINFO "hohum" "weirdo"
+0.0.3.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. IN NSAP-PTR foo.bar.com.
+0.0.4.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. IN NSAP-PTR host.school.de.
diff --git a/testdata/test_ldnsrr.c3 b/testdata/test_ldnsrr.c3
index 3adb7b5069ff..0ce9340dfc31 100644
--- a/testdata/test_ldnsrr.c3
+++ b/testdata/test_ldnsrr.c3
@@ -169,7 +169,7 @@ dname03.types-signed.wb.sidnlabs.nl. 3600 IN NSEC gpos.types-signed.wb.sidnlabs.
07646E616D6530330C74797065732D7369676E6564027762087369646E6C616273026E6C00002E000100000E1000AF002F080500000E1052EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C00CFCE6808CE405CC73016F9685E75C161BEAA5869D2A6C9B584F4C22BD0CFE199C44F2F8C68BC7CEEF64DAEA444A78C9BB78271C487CD3A76885F757E5D98CEC0B35D173FE21040453AA59C34A6155199A9E1D8FACC67A36646021298D2F9CAEE31E2E022AB152BF32981795D796FC5532F017A091FD7928996BA1E5EF2E665DC
dname03.types-signed.wb.sidnlabs.nl. 3600 IN RRSIG NSEC 8 5 3600 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. z85oCM5AXMcwFvloXnXBYb6qWGnSpsm1hPTCK9DP4ZnETy+MaLx87vZNrqREp4ybt4JxxIfNOnaIX3V+XZjOwLNdFz/iEEBFOqWcNKYVUZmp4dj6zGejZkYCEpjS+cruMeLgIqsVK/MpgXldeW/FUy8Begkf15KJlroeXvLmZdw= ;{id = 62298}
0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00001B00010000003C00120532332E36370532332E36370532332E3637
-gpos.types-signed.wb.sidnlabs.nl. 60 IN GPOS "23.67" "23.67" "23.67"
+gpos.types-signed.wb.sidnlabs.nl. 60 IN GPOS 23.67 23.67 23.67
0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00002E00010000003C00AF001B08050000003C52EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C0049CBABEED1B9089695C552489294378669AE1B934A81076F364E3D3E68F239E34AC106D4554F009A39A7813B1C8E02076B0A0737DACE4CCC7BF3CD20F4DFF9C19934DAAD81F23FB743C89CA941387CFC6B1506525634206D4918FA9CBE9707A88B25B0F6FF10E295551E4643488EA87FE7E051BD9E6D8AEF42F01574BB56BEE4
gpos.types-signed.wb.sidnlabs.nl. 60 IN RRSIG GPOS 8 5 60 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. Scur7tG5CJaVxVJIkpQ3hmmuG5NKgQdvNk49PmjyOeNKwQbUVU8AmjmngTscjgIHawoHN9rOTMx7880g9N/5wZk02q2B8j+3Q8icqUE4fPxrFQZSVjQgbUkY+py+lweoiyWw9v8Q4pVVHkZDSI6of+fgUb2ebYrvQvAVdLtWvuQ= ;{id = 62298}
0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00002F000100000E10002B0568696E666F0C74797065732D7369676E6564027762087369646E6C616273026E6C000006000000100003
@@ -859,7 +859,7 @@ type26.types-signed.wb.sidnlabs.nl. 3600 IN NSEC type27.types-signed.wb.sidnlabs
067479706532360C74797065732D7369676E6564027762087369646E6C616273026E6C00002E000100000E1000AF002F080500000E1052EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C00B37F1C2B73BB1D6A5EE4A53E2E9E8F893F0A4E20FD62BC7C1C56D2A40D59AC7CD25157555FC677BB9DCAA76C3F07710B381DBB61EEF2A8896A67F1AF40107DFC5BD74B62593ACFFBE407DEA015E12D72294725BDC7B8218FDC5E991A5676CC9BAC59B8A2D743F3A3A479226167D54973C7DAE32267D2AD6DE873CC8ABDCFA07E
type26.types-signed.wb.sidnlabs.nl. 3600 IN RRSIG NSEC 8 5 3600 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. s38cK3O7HWpe5KU+Lp6PiT8KTiD9Yrx8HFbSpA1ZrHzSUVdVX8Z3u53Kp2w/B3ELOB27Ye7yqIlqZ/GvQBB9/FvXS2JZOs/75AfeoBXhLXIpRyW9x7ghj9xemRpWdsybrFm4otdD86OkeSJhZ9VJc8fa4yJn0q1t6HPMir3PoH4= ;{id = 62298}
067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00001B00010000003C00120532332E36370532332E36370532332E3637
-type27.types-signed.wb.sidnlabs.nl. 60 IN GPOS "23.67" "23.67" "23.67"
+type27.types-signed.wb.sidnlabs.nl. 60 IN GPOS 23.67 23.67 23.67
067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00002E00010000003C00AF001B08050000003C52EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C0013BF8CA0C46CABE234D3A0D55A9D4D2A30449E21A25E889DBAE3499A2C567B8F652C2CB2F67A83767D6B5963205F7FBF83A79318E702C558E30688507E062029FCF4EBD2EC5DEE7DFEB6C3C2F326131920401A05444AAA326CC9D118139C43A4A0DC834ECE3ECF883DAC78B03031F15432A5ACD4331587F43B22176CBA0A6E14
type27.types-signed.wb.sidnlabs.nl. 60 IN RRSIG GPOS 8 5 60 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. E7+MoMRsq+I006DVWp1NKjBEniGiXoiduuNJmixWe49lLCyy9nqDdn1rWWMgX3+/g6eTGOcCxVjjBohQfgYgKfz069LsXe59/rbDwvMmExkgQBoFREqqMmzJ0RgTnEOkoNyDTs4+z4g9rHiwMDHxVDKlrNQzFYf0OyIXbLoKbhQ= ;{id = 62298}
067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00002F000100000E10002C067479706532380C74797065732D7369676E6564027762087369646E6C616273026E6C000006000000100003
diff --git a/testdata/test_ldnsrr.c4 b/testdata/test_ldnsrr.c4
index 56b87fbcbbf4..93e7617f6a80 100644
--- a/testdata/test_ldnsrr.c4
+++ b/testdata/test_ldnsrr.c4
@@ -46,6 +46,10 @@ all.rr.org. 3600 IN LOC 42 21 54.500 N 71 06 18.300 W -24m 30m 10000m 10m
all.rr.org. 3600 IN LOC 42 00 00.000 N 71 06 18.300 W -24m 30m 10000m 10m
055F68747470045F74637003616C6C027272036F7267000021000100000E100017000000050050036E7331076578616D706C6503636F6D00
_http._tcp.all.rr.org. 3600 IN SRV 0 5 80 ns1.example.com.
+0561746D6130000022000100000E1000150039246F000E7C9C03120001000100001234567800
+atma0. 3600 IN ATMA 39246F000E7C9C03120001000100001234567800
+0561746D6131000022000100000E10000C013139303835353531323132
+atma1. 3600 IN ATMA +19085551212
03616C6C027272036F7267000023000100000E1000290064000A000021215E75726E3A6369643A2E2B40285B5E5C2E5D2B5C2E29282E2A2924215C32216900
all.rr.org. 3600 IN NAPTR 100 10 "" "" "!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i" .
03616C6C027272036F7267000024000100000E100013000203727431076578616D706C6503636F6D00
diff --git a/testdata/test_ldnsrr.c5 b/testdata/test_ldnsrr.c5
index e86532c3433e..72d7b69d62bc 100644
--- a/testdata/test_ldnsrr.c5
+++ b/testdata/test_ldnsrr.c5
@@ -214,3 +214,7 @@ root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 F1CA0CCD91BD5573D9F431C00EE01
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.10m 0.10m 0.10m
03666F6F00000D000100003039000D05686F68756D0677656972646F
foo. 12345 IN HINFO "hohum" "weirdo"
+0130013001330136013101300130013001660166016601660166016601330133013101650131013001300130013001300130013001300130016101350130013001300138013501300130013001370134044E53415003494E54000017000100000E10000D0C666F6F2E6261722E636F6D2E
+0.0.3.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. 3600 IN NSAP-PTR foo.bar.com.
+0130013001340136013101300130013001660166016601660166016601330133013101650131013001300130013001300130013001300130016101350130013001300138013501300130013001370134044E53415003494E54000017000100000E1000100F686F73742E7363686F6F6C2E64652E
+0.0.4.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. 3600 IN NSAP-PTR host.school.de.
diff --git a/testdata/val_failure_dnskey.rpl b/testdata/val_failure_dnskey.rpl
index 3f25f15b2062..c5f1af2ff349 100644
--- a/testdata/val_failure_dnskey.rpl
+++ b/testdata/val_failure_dnskey.rpl
@@ -9,7 +9,6 @@ server:
fake-sha1: yes
trust-anchor-signaling: no
minimal-responses: no
- log-servfail: yes
val-log-level: 2
ede: yes
diff --git a/testdata/val_scrub_rr_length.rpl b/testdata/val_scrub_rr_length.rpl
index 0219b918e421..f83157ff04c3 100644
--- a/testdata/val_scrub_rr_length.rpl
+++ b/testdata/val_scrub_rr_length.rpl
@@ -9,7 +9,6 @@ server:
minimal-responses: no
rrset-roundrobin: no
ede: yes
- log-servfail: yes
stub-zone:
name: "."