Browse Source

unbound: Vendor import 1.16.2

Security update to unbound.

PR:             265645
Security:       CVE-2022-30698, CVE-2022-30699
Security:       bc43a578-14ec-11ed-856e-d4c9ef517024
MFC after:      3 days

Merge commit '9b76d32f2310b735dbeb896cbf2776cad61f23e8' into main
main
Cy Schubert 6 days ago
parent
commit
790c6b2451
  1. 31
      contrib/unbound/SECURITY.md
  2. 2
      contrib/unbound/cachedb/cachedb.c
  3. 25
      contrib/unbound/configure
  4. 5
      contrib/unbound/configure.ac
  5. 5
      contrib/unbound/daemon/cachedump.c
  6. 2
      contrib/unbound/daemon/worker.c
  7. 4
      contrib/unbound/dns64/dns64.c
  8. 30
      contrib/unbound/doc/Changelog
  9. 2
      contrib/unbound/doc/README
  10. 8
      contrib/unbound/doc/example.conf.in
  11. 4
      contrib/unbound/doc/libunbound.3.in
  12. 2
      contrib/unbound/doc/unbound-anchor.8.in
  13. 2
      contrib/unbound/doc/unbound-checkconf.8.in
  14. 2
      contrib/unbound/doc/unbound-control.8.in
  15. 2
      contrib/unbound/doc/unbound-host.1.in
  16. 4
      contrib/unbound/doc/unbound.8.in
  17. 15
      contrib/unbound/doc/unbound.conf.5.in
  18. 2
      contrib/unbound/ipsecmod/ipsecmod.c
  19. 6
      contrib/unbound/iterator/iter_utils.c
  20. 3
      contrib/unbound/iterator/iter_utils.h
  21. 23
      contrib/unbound/iterator/iterator.c
  22. 12
      contrib/unbound/iterator/iterator.h
  23. 1
      contrib/unbound/services/authzone.c
  24. 111
      contrib/unbound/services/cache/dns.c
  25. 18
      contrib/unbound/services/cache/dns.h
  26. 6
      contrib/unbound/services/cache/infra.c
  27. 17
      contrib/unbound/services/listen_dnsport.c
  28. 1
      contrib/unbound/services/mesh.c
  29. 4
      contrib/unbound/sldns/rrdef.c
  30. 2
      contrib/unbound/sldns/wire2str.c
  31. 309
      contrib/unbound/testdata/iter_ghost_sub.rpl
  32. 391
      contrib/unbound/testdata/iter_ghost_timewindow.rpl
  33. 15
      contrib/unbound/util/config_file.c
  34. 4
      contrib/unbound/util/config_file.h
  35. 1
      contrib/unbound/util/configlexer.lex
  36. 13
      contrib/unbound/util/configparser.y
  37. 2
      contrib/unbound/util/data/msgreply.c
  38. 1
      contrib/unbound/util/iana_ports.inc
  39. 6
      contrib/unbound/util/module.h
  40. 3
      contrib/unbound/util/rtt.c
  41. 2
      contrib/unbound/util/rtt.h
  42. 1
      contrib/unbound/validator/val_utils.c
  43. 7
      contrib/unbound/validator/validator.c

31
contrib/unbound/SECURITY.md

@ -0,0 +1,31 @@
# Security Policy
## Supported Versions
NLnet Labs adheres to the straightforward, semantic versioning scheme that is
commonly used in the software industry.
Support is provided in respect of the latest release, i.e. releases with the
highest minor and patch version level. We do not backport security fixes to
older (minor) versions. In the event a new major version is released (e.g. from
3.2.18 to 4.0.0), support will also be provided on the latest minor version of
the previous major version (3.2.18) for a period of one year from the release of
the new major version (4.0.0).
In the event that, during this period, a new patch or minor version of the
previous major version is released, then support on these versions will only be
provided for the remainder of the one-year-period.
You can find detailed information on our software support policy here:
https://www.nlnetlabs.nl/support/software-support-policy/
## Reporting a Vulnerability
We take security very seriously. If you have discovered a security vulnerability
in one of our projects and you would like to report it to us, you can send an
encrypted message to our Security Entry Point.
Details are described here:
https://www.nlnetlabs.nl/security-report/

2
contrib/unbound/cachedb/cachedb.c

@ -662,7 +662,7 @@ cachedb_intcache_store(struct module_qstate* qstate)
return;
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
qstate->region, store_flags);
qstate->region, store_flags, qstate->qstarttime);
}
/**

25
contrib/unbound/configure vendored

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.16.1.
# Generated by GNU Autoconf 2.69 for unbound 1.16.2.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.16.1'
PACKAGE_STRING='unbound 1.16.1'
PACKAGE_VERSION='1.16.2'
PACKAGE_STRING='unbound 1.16.2'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@ -1477,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.16.1 to adapt to many kinds of systems.
\`configure' configures unbound 1.16.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1543,7 +1543,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.16.1:";;
short | recursive ) echo "Configuration of unbound 1.16.2:";;
esac
cat <<\_ACEOF
@ -1785,7 +1785,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.16.1
unbound configure 1.16.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2494,7 +2494,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.16.1, which was
It was created by unbound $as_me 1.16.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2846,11 +2846,11 @@ UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=16
UNBOUND_VERSION_MICRO=1
UNBOUND_VERSION_MICRO=2
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=17
LIBUNBOUND_REVISION=18
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -2935,6 +2935,7 @@ LIBUNBOUND_AGE=1
# 1.15.0 had 9:15:1
# 1.16.0 had 9:16:1
# 1.16.1 had 9:17:1
# 1.16.2 had 9:18:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -22013,7 +22014,7 @@ _ACEOF
version=1.16.1
version=1.16.2
date=`date +'%b %e, %Y'`
@ -22532,7 +22533,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.16.1, which was
This file was extended by unbound $as_me 1.16.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -22598,7 +22599,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
unbound config.status 1.16.1
unbound config.status 1.16.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

5
contrib/unbound/configure.ac

@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[16])
m4_define([VERSION_MICRO],[1])
m4_define([VERSION_MICRO],[2])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=17
LIBUNBOUND_REVISION=18
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -103,6 +103,7 @@ LIBUNBOUND_AGE=1
# 1.15.0 had 9:15:1
# 1.16.0 had 9:16:1
# 1.16.1 had 9:17:1
# 1.16.2 had 9:18:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary

5
contrib/unbound/daemon/cachedump.c

@ -679,7 +679,8 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
if(!go_on)
return 1; /* skip this one, not all references satisfied */
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags,
*worker->env.now)) {
log_warn("error out of memory");
return 0;
}
@ -850,7 +851,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
while(1) {
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
qinfo.qtype, qinfo.qclass, region, &msg,
*worker->env.now);
*worker->env.now, 0, NULL, 0);
if(!dp) {
return ssl_printf(ssl, "no delegation from "
"cache; goes to configured roots\n");

2
contrib/unbound/daemon/worker.c

@ -459,7 +459,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
dp = dns_cache_find_delegation(&worker->env, qinfo->qname,
qinfo->qname_len, qinfo->qtype, qinfo->qclass,
worker->scratchpad, &msg, timenow);
worker->scratchpad, &msg, timenow, 0, NULL, 0);
if(!dp) { /* no delegation, need to reprime */
return 0;
}

4
contrib/unbound/dns64/dns64.c

@ -652,7 +652,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
if ( (!iq || !iq->started_no_cache_store) &&
qstate->return_msg && qstate->return_msg->rep &&
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, 0, 0, NULL, qstate->query_flags))
0, 0, 0, NULL, qstate->query_flags, qstate->qstarttime))
log_err("out of memory");
/* do nothing */
@ -991,7 +991,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
/* Store the generated response in cache. */
if ( (!super_dq || !super_dq->started_no_cache_store) &&
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
0, 0, 0, NULL, super->query_flags))
0, 0, 0, NULL, super->query_flags, qstate->qstarttime))
log_err("out of memory");
}

30
contrib/unbound/doc/Changelog

@ -1,3 +1,30 @@
1 August 2022: Wouter
- Fix the novel ghost domain issues CVE-2022-30698 and CVE-2022-30699.
- Tests for ghost domain fixes.
19 July 2022: George
- Update documentation for 'outbound-msg-retry:'.
19 July 2022: Wouter
- Merge #718: Introduce infra-cache-max-rtt option to config max
retransmit timeout.
15 July 2022: Wouter
- Merge PR 714: Avoid treat normal hosts as unresponsive servers.
And fixup the lock code.
- iana portlist update.
12 July 2022: George
- For windows crosscompile, fix setting the IPV6_MTU socket option
equivalent (IPV6_USER_MTU); allows cross compiling with latest
cross-compiler versions.
12 July 2022: Wouter
- Fix dname count in sldns parse type descriptor for SVCB and HTTPS.
11 July 2022: Wouter
- Fix verbose EDE error printout.
4 July 2022: George
- Fix bug introduced in 'improve val_sigcrypt.c::algo_needs_missing for
one loop pass'.
@ -5,7 +32,8 @@
outbound tcp sockets.
4 July 2022: Wouter
- Tag for 1.16.1rc1 release.
- Tag for 1.16.1rc1 release. This became 1.16.1 on 11 July 2022.
The code repo continues with version 1.16.2 under development.
3 July 2022: George
- Merge PR #671 from Petr Menšík: Disable ED25519 and ED448 in FIPS

2
contrib/unbound/doc/README

@ -1,4 +1,4 @@
README for Unbound 1.16.1
README for Unbound 1.16.2
Copyright 2007 NLnet Labs
http://unbound.net

8
contrib/unbound/doc/example.conf.in

@ -1,7 +1,7 @@
#
# Example configuration file.
#
# See unbound.conf(5) man page, version 1.16.1.
# See unbound.conf(5) man page, version 1.16.2.
#
# this is a comment.
@ -168,7 +168,8 @@ server:
# perform connect for UDP sockets to mitigate ICMP side channel.
# udp-connect: yes
# The number of retries when a non-positive response is received.
# The number of retries, per upstream nameserver in a delegation, when
# a throwaway response (also timeouts) is received.
# outbound-msg-retry: 5
# msec for waiting for an unknown server to reply. Increase if you
@ -202,6 +203,9 @@ server:
# minimum wait time for responses, increase if uplink is long. In msec.
# infra-cache-min-rtt: 50
# maximum wait time for responses. In msec.
# infra-cache-max-rtt: 120000
# enable to make server probe down hosts more frequently.
# infra-keep-probing: no

4
contrib/unbound/doc/libunbound.3.in

@ -1,4 +1,4 @@
.TH "libunbound" "3" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "libunbound" "3" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
@ -44,7 +44,7 @@
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
\- Unbound DNS validating resolver 1.16.1 functions.
\- Unbound DNS validating resolver 1.16.2 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP

2
contrib/unbound/doc/unbound-anchor.8.in

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound-anchor" "8" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"

2
contrib/unbound/doc/unbound-checkconf.8.in

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound-checkconf" "8" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"

2
contrib/unbound/doc/unbound-control.8.in

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound-control" "8" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"

2
contrib/unbound/doc/unbound-host.1.in

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound\-host" "1" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"

4
contrib/unbound/doc/unbound.8.in

@ -1,4 +1,4 @@
.TH "unbound" "8" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound" "8" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound.8 -- unbound manual
.\"
@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver 1.16.1.
\- Unbound DNS validating resolver 1.16.2.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]

15
contrib/unbound/doc/unbound.conf.5.in

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "Jul 11, 2022" "NLnet Labs" "unbound 1.16.1"
.TH "unbound.conf" "5" "Aug 1, 2022" "NLnet Labs" "unbound 1.16.2"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@ -395,6 +395,10 @@ Lower limit for dynamic retransmit timeout calculation in infrastructure
cache. Default is 50 milliseconds. Increase this value if using forwarders
needing more time to do recursive name resolution.
.TP
.B infra\-cache\-max\-rtt: \fI<msec>
Upper limit for dynamic retransmit timeout calculation in infrastructure
cache. Default is 2 minutes.
.TP
.B infra\-keep\-probing: \fI<yes or no>
If enabled the server keeps probing hosts that are down, in the one probe
at a time regime. Default is no. Hosts that are down, eg. they did
@ -1758,9 +1762,12 @@ set ip\-ratelimit to a suspicious rate to aggressively limit unusually high
traffic. Default is off.
.TP 5
.B outbound\-msg\-retry: \fI<number>
The number of retries Unbound will do in case of a non positive response is
received. If a forward nameserver is used, this is the number of retries per
forward nameserver in case of throwaway response.
The number of retries, per upstream nameserver in a delegation, that Unbound
will attempt in case a throwaway response is received.
No response (timeout) contributes to the retry counter.
If a forward/stub zone is used, this is the number of retries per nameserver in
the zone.
Default is 5.
.TP 5
.B fast\-server\-permil: \fI<number>
Specify how many times out of 1000 to pick from the set of fastest servers.

2
contrib/unbound/ipsecmod/ipsecmod.c

@ -456,7 +456,7 @@ ipsecmod_handle_query(struct module_qstate* qstate,
/* Store A/AAAA in cache. */
if(!dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway,
0, qstate->region, qstate->query_flags)) {
0, qstate->region, qstate->query_flags, qstate->qstarttime)) {
log_err("ipsecmod: out of memory caching record");
}
qstate->ext_state[id] = module_finished;

6
contrib/unbound/iterator/iter_utils.c

@ -70,8 +70,6 @@
/** time when nameserver glue is said to be 'recent' */
#define SUSPICION_RECENT_EXPIRY 86400
/** penalty to validation failed blacklisted IPs */
#define BLACKLIST_PENALTY (USEFUL_SERVER_TOP_TIMEOUT*4)
/** fillup fetch policy array */
static void
@ -661,10 +659,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
void
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint16_t flags)
struct regional* region, uint16_t flags, time_t qstarttime)
{
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
pside, region, flags))
pside, region, flags, qstarttime))
log_err("out of memory: cannot store data in cache");
}

3
contrib/unbound/iterator/iter_utils.h

@ -132,6 +132,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
* can be prefetch-updates.
* @param region: to copy modified (cache is better) rrs back to.
* @param flags: with BIT_CD for dns64 AAAA translated queries.
* @param qstarttime: time of query start.
* return void, because we are not interested in alloc errors,
* the iterator and validator can operate on the results in their
* scratch space (the qstate.region) and are not dependent on the cache.
@ -140,7 +141,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
*/
void iter_dns_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region, uint16_t flags);
struct regional* region, uint16_t flags, time_t qstarttime);
/**
* Select randomly with n/m probability.

23
contrib/unbound/iterator/iterator.c

@ -71,6 +71,10 @@
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
/* in msec */
int USEFUL_SERVER_TOP_TIMEOUT = 120000;
/* Equals USEFUL_SERVER_TOP_TIMEOUT*4 */
int BLACKLIST_PENALTY = (120000*4);
static void target_count_increase_nx(struct iter_qstate* iq, int num);
@ -371,7 +375,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
err.security = sec_status_indeterminate;
verbose(VERB_ALGO, "store error response in message cache");
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
qstate->query_flags);
qstate->query_flags, qstate->qstarttime);
}
return error_response(qstate, id, rcode);
}
@ -1485,7 +1489,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg,
*qstate->env->now+qstate->prefetch_leeway);
*qstate->env->now+qstate->prefetch_leeway, 1,
dpname, dpnamelen);
else iq->dp = NULL;
/* If the cache has returned nothing, then we have a
@ -1777,7 +1782,8 @@ generate_parentside_target_query(struct module_qstate* qstate,
subiq->dp = dns_cache_find_delegation(qstate->env,
name, namelen, qtype, qclass, subq->region,
&subiq->deleg_msg,
*qstate->env->now+subq->prefetch_leeway);
*qstate->env->now+subq->prefetch_leeway,
1, NULL, 0);
/* if no dp, then it's from root, refetch unneeded */
if(subiq->dp) {
subiq->dnssec_expected = iter_indicates_dnssec(
@ -2943,7 +2949,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qchase.qtype != iq->response->qinfo.qtype,
qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region, qstate->query_flags);
qstate->region, qstate->query_flags,
qstate->qstarttime);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
@ -3032,7 +3039,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Store the referral under the current query */
/* no prefetch-leeway, since its not the answer */
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, 0, 0, NULL, 0);
iq->response->rep, 1, 0, 0, NULL, 0,
qstate->qstarttime);
if(iq->store_parent_NS)
iter_store_parentside_NS(qstate->env,
iq->response->rep);
@ -3146,7 +3154,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS, NULL,
qstate->query_flags);
qstate->query_flags, qstate->qstarttime);
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
@ -3752,7 +3760,8 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region, qstate->query_flags);
qstate->region, qstate->query_flags,
qstate->qstarttime);
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;

12
contrib/unbound/iterator/iterator.h

@ -94,15 +94,17 @@ struct rbtree_type;
extern int UNKNOWN_SERVER_NICENESS;
/** maximum timeout before a host is deemed unsuitable, in msec.
* After host_ttl this will be timed out and the host will be tried again.
* Equals RTT_MAX_TIMEOUT
*/
#define USEFUL_SERVER_TOP_TIMEOUT 120000
* Equals RTT_MAX_TIMEOUT, and thus when RTT_MAX_TIMEOUT is overwritten by
* config infra_cache_max_rtt, it will be overwritten as well. */
extern int USEFUL_SERVER_TOP_TIMEOUT;
/** penalty to validation failed blacklisted IPs
* Equals USEFUL_SERVER_TOP_TIMEOUT*4, and thus when RTT_MAX_TIMEOUT is
* overwritten by config infra_cache_max_rtt, it will be overwritten as well. */
extern int BLACKLIST_PENALTY;
/** RTT band, within this amount from the best, servers are chosen randomly.
* Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a
* fast server, this causes server exploration as a side benefit. msec. */
#define RTT_BAND 400
/** Start value for blacklisting a host, 2*USEFUL_SERVER_TOP_TIMEOUT in sec */
#define INFRA_BACKOFF_INITIAL 240
/**
* Global state for the iterator.

1
contrib/unbound/services/authzone.c

@ -8189,7 +8189,6 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY);
keystorage->rk.rrset_class = htons(z->dclass);
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
// @TODO add EDE here? we currently just pass NULL
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
why_bogus, NULL, NULL);
regional_free_all(env->scratch);

111
contrib/unbound/services/cache/dns.c vendored

@ -68,11 +68,16 @@
* in a prefetch situation to be updated (without becoming sticky).
* @param qrep: update rrsets here if cache is better
* @param region: for qrep allocs.
* @param qstarttime: time when delegations were looked up, this is perhaps
* earlier than the time in now. The time is used to determine if RRsets
* of type NS have expired, so that they can only be updated using
* lookups of delegation points that did not use them, since they had
* expired then.
*/
static void
store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
time_t leeway, int pside, struct reply_info* qrep,
struct regional* region)
struct regional* region, time_t qstarttime)
{
size_t i;
/* see if rrset already exists in cache, if not insert it. */
@ -81,8 +86,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
rep->ref[i].id = rep->rrsets[i]->id;
/* update ref if it was in the cache */
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
env->alloc, ((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?qstarttime:now + leeway))) {
case 0: /* ref unchanged, item inserted */
break;
case 2: /* ref updated, cache is superior */
@ -155,7 +160,8 @@ msg_del_servfail(struct module_env* env, struct query_info* qinfo,
void
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
struct reply_info* qrep, uint32_t flags, struct regional* region)
struct reply_info* qrep, uint32_t flags, struct regional* region,
time_t qstarttime)
{
struct msgreply_entry* e;
time_t ttl = rep->ttl;
@ -170,7 +176,8 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
/* there was a reply_info_sortref(rep) here but it seems to be
* unnecessary, because the cache gets locked per rrset. */
reply_info_set_ttls(rep, *env->now);
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region);
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
qstarttime);
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
/* we do not store the message, but we did store the RRs,
* which could be useful for delegation information */
@ -194,10 +201,51 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc);
}
/** see if an rrset is expired above the qname, return upper qname. */
static int
rrset_expired_above(struct module_env* env, uint8_t** qname, size_t* qnamelen,
uint16_t searchtype, uint16_t qclass, time_t now, uint8_t* expiretop,
size_t expiretoplen)
{
struct ub_packed_rrset_key *rrset;
uint8_t lablen;
while(*qnamelen > 0) {
/* look one label higher */
lablen = **qname;
*qname += lablen + 1;
*qnamelen -= lablen + 1;
if(*qnamelen <= 0)
break;
/* looks up with a time of 0, to see expired entries */
if((rrset = rrset_cache_lookup(env->rrset_cache, *qname,
*qnamelen, searchtype, qclass, 0, 0, 0))) {
struct packed_rrset_data* data =
(struct packed_rrset_data*)rrset->entry.data;
if(now > data->ttl) {
/* it is expired, this is not wanted */
lock_rw_unlock(&rrset->entry.lock);
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
return 1;
}
/* it is not expired, continue looking */
lock_rw_unlock(&rrset->entry.lock);
}
/* do not look above the expiretop. */
if(expiretop && *qnamelen == expiretoplen &&
query_dname_compare(*qname, expiretop)==0)
break;
}
return 0;
}
/** find closest NS or DNAME and returns the rrset (locked) */
static struct ub_packed_rrset_key*
find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
uint16_t qclass, time_t now, uint16_t searchtype, int stripfront)
uint16_t qclass, time_t now, uint16_t searchtype, int stripfront,
int noexpiredabove, uint8_t* expiretop, size_t expiretoplen)
{
struct ub_packed_rrset_key *rrset;
uint8_t lablen;
@ -212,8 +260,40 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
/* snip off front part of qname until the type is found */
while(qnamelen > 0) {
if((rrset = rrset_cache_lookup(env->rrset_cache, qname,
qnamelen, searchtype, qclass, 0, now, 0)))
return rrset;
qnamelen, searchtype, qclass, 0, now, 0))) {
uint8_t* origqname = qname;
size_t origqnamelen = qnamelen;
if(!noexpiredabove)
return rrset;
/* if expiretop set, do not look above it, but
* qname is equal, so the just found result is also
* the nonexpired above part. */
if(expiretop && qnamelen == expiretoplen &&
query_dname_compare(qname, expiretop)==0)
return rrset;
/* check for expiry, but we have to let go of the rrset
* for the lock ordering */
lock_rw_unlock(&rrset->entry.lock);
/* the expired_above function always takes off one
* label (if qnamelen>0) and returns the final qname
* where it searched, so we can continue from there
* turning the O N*N search into O N. */
if(!rrset_expired_above(env, &qname, &qnamelen,
searchtype, qclass, now, expiretop,
expiretoplen)) {
/* we want to return rrset, but it may be
* gone from cache, if so, just loop like
* it was not in the cache in the first place.
*/
if((rrset = rrset_cache_lookup(env->
rrset_cache, origqname, origqnamelen,
searchtype, qclass, 0, now, 0))) {
return rrset;
}
}
log_nametypeclass(VERB_ALGO, "ignoring rrset because expired rrsets exist above it", origqname, searchtype, qclass);
continue;
}
/* snip off front label */
lablen = *qname;
@ -462,7 +542,8 @@ dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
struct delegpt*
dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct dns_msg** msg, time_t now)
struct regional* region, struct dns_msg** msg, time_t now,
int noexpiredabove, uint8_t* expiretop, size_t expiretoplen)
{
/* try to find closest NS rrset */
struct ub_packed_rrset_key* nskey;
@ -470,7 +551,7 @@ dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
struct delegpt* dp;
nskey = find_closest_of_type(env, qname, qnamelen, qclass, now,
LDNS_RR_TYPE_NS, 0);
LDNS_RR_TYPE_NS, 0, noexpiredabove, expiretop, expiretoplen);
if(!nskey) /* hope the caller has hints to prime or something */
return NULL;
nsdata = (struct packed_rrset_data*)nskey->entry.data;
@ -840,7 +921,7 @@ dns_cache_lookup(struct module_env* env,
* consistent with the DNAME */
if(!no_partial &&
(rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
LDNS_RR_TYPE_DNAME, 1))) {
LDNS_RR_TYPE_DNAME, 1, 0, NULL, 0))) {
/* synthesize a DNAME+CNAME message based on this */
enum sec_status sec_status = sec_status_unchecked;
struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k,
@ -973,7 +1054,7 @@ dns_cache_lookup(struct module_env* env,
int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags)
struct regional* region, uint32_t flags, time_t qstarttime)
{
struct reply_info* rep = NULL;
/* alloc, malloc properly (not in region, like msg is) */
@ -996,9 +1077,9 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
/*ignore ret: it was in the cache, ref updated */
/* no leeway for typeNS */
(void)rrset_cache_update(env->rrset_cache, &ref,
env->alloc, *env->now +
env->alloc,
((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS
&& !pside) ? 0:leeway));
&& !pside) ? qstarttime:*env->now + leeway));
}
free(rep);
return 1;
@ -1020,7 +1101,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
rep->flags &= ~(BIT_AA | BIT_CD);
h = query_info_hash(&qinf, (uint16_t)flags);
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
flags, region);
flags, region, qstarttime);
/* qname is used inside query_info_entrysetup, and set to
* NULL. If it has not been used, free it. free(0) is safe. */
free(qinf.qname);

18
contrib/unbound/services/cache/dns.h vendored

@ -88,11 +88,13 @@ struct dns_msg {
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* The higher 16 bits are used internally to customize the cache policy.
* (See DNSCACHE_STORE_xxx flags).
* @param qstarttime: time when the query was started, and thus when the
* delegations were looked up.
* @return 0 on alloc error (out of memory).
*/
int dns_cache_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags);
struct regional* region, uint32_t flags, time_t qstarttime);
/**
* Store message in the cache. Stores in message cache and rrset cache.
@ -112,11 +114,14 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
* can be updated to full TTL even in prefetch situations.
* @param qrep: message that can be altered with better rrs from cache.
* @param flags: customization flags for the cache policy.
* @param qstarttime: time when the query was started, and thus when the
* delegations were looked up.
* @param region: to allocate into for qmsg.
*/
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
struct reply_info* qrep, uint32_t flags, struct regional* region);
struct reply_info* qrep, uint32_t flags, struct regional* region,
time_t qstarttime);
/**
* Find a delegation from the cache.
@ -129,11 +134,18 @@ void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
* @param msg: if not NULL, delegation message is returned here, synthesized
* from the cache.
* @param timenow: the time now, for checking if TTL on cache entries is OK.
* @param noexpiredabove: if set, no expired NS rrsets above the one found
* are tolerated. It only returns delegations where the delegations above
* it are valid.
* @param expiretop: if not NULL, name where check for expiry ends for
* noexpiredabove.
* @param expiretoplen: length of expiretop dname.
* @return new delegation or NULL on error or if not found in cache.
*/
struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct dns_msg** msg, time_t timenow);
struct regional* region, struct dns_msg** msg, time_t timenow,
int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
/**
* generate dns_msg from cached message

6
contrib/unbound/services/cache/infra.c vendored

@ -721,13 +721,13 @@ infra_get_lame_rtt(struct infra_cache* infra,
else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
}
}
/* expired entry */
if(timenow > host->ttl) {
/* expired entry */
/* see if this can be a re-probe of an unresponsive server */
/* minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen */
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT ||
infra->infra_keep_probing) {
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
lock_rw_unlock(&e->lock);
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
*lame = 0;

17
contrib/unbound/services/listen_dnsport.c

@ -490,6 +490,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
return -1;
}
# elif defined(IPV6_MTU)
# ifndef USE_WINSOCK
/*
* On Linux, to send no larger than 1280, the PMTUD is
* disabled by default for datagrams anyway, so we set
@ -497,13 +498,27 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*/
if (setsockopt(s, IPPROTO_IPV6, IPV6_MTU,
(void*)&mtu, (socklen_t)sizeof(mtu)) < 0) {
log_err("setsockopt(..., IPV6_MTU, ...) failed: %s",
log_err("setsockopt(..., IPV6_MTU, ...) failed: %s",
sock_strerror(errno));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
}
# elif defined(IPV6_USER_MTU)
/* As later versions of the mingw crosscompiler define
* IPV6_MTU, do the same for windows but use IPV6_USER_MTU
* instead which is writable; IPV6_MTU is readonly there. */
if (setsockopt(s, IPPROTO_IPV6, IPV6_USER_MTU,
(void*)&mtu, (socklen_t)sizeof(mtu)) < 0) {
log_err("setsockopt(..., IPV6_USER_MTU, ...) failed: %s",
wsa_strerror(WSAGetLastError()));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
}
# endif /* USE_WINSOCK */
# endif /* IPv6 MTU */
# if defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
# if defined(IP_PMTUDISC_OMIT)

1
contrib/unbound/services/mesh.c

@ -954,6 +954,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
mstate->s.no_cache_store = 0;
mstate->s.need_refetch = 0;
mstate->s.was_ratelimited = 0;
mstate->s.qstarttime = *env->now;
/* init modules */
for(i=0; i<env->mesh->mods.num; i++) {

4
contrib/unbound/sldns/rrdef.c

@ -381,9 +381,9 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
/* 63 */
{LDNS_RR_TYPE_ZONEMD, "ZONEMD", 4, 4, type_zonemd_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 64 */
{LDNS_RR_TYPE_SVCB, "SVCB", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_SVCB, "SVCB", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 1 },
/* 65 */
{LDNS_RR_TYPE_HTTPS, "HTTPS", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 0 },
{LDNS_RR_TYPE_HTTPS, "HTTPS", 2, 2, type_svcb_wireformat, LDNS_RDF_TYPE_SVCPARAM, LDNS_RR_NO_COMPRESS, 1 },
{(enum sldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{(enum sldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
{(enum sldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },

2
contrib/unbound/sldns/wire2str.c

@ -1071,7 +1071,7 @@ static int sldns_wire2str_svcparam_mandatory2str(char** s,
assert(data_len > 0);
if (data_len % sizeof(uint16_t))
return -1; // wireformat error, data_len must be multiple of shorts
return -1; /* wireformat error, data_len must be multiple of shorts */
w += sldns_str_print(s, slen, "=");
w += sldns_print_svcparamkey(s, slen, sldns_read_uint16(data));
data += 2;

309
contrib/unbound/testdata/iter_ghost_sub.rpl vendored

@ -0,0 +1,309 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
minimal-responses: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ghost subdomain of another subdomain.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. 86400 IN NS
SECTION ANSWER
. 86400 IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. 86400 IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION AUTHORITY
com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
; this is the one where example.com is delegated.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; a.gtld-servers.net.
; this is the one where example.com is no longer delegated.
RANGE_BEGIN 100 200
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NXDOMAIN
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
com. 86400 IN SOA a. b. 1 2 3 4 5
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
s.example.com. IN A
SECTION ANSWER
s.example.com. IN A 1.2.3.4
SECTION AUTHORITY
s.example.com. IN NS s.example.com.
SECTION ADDITIONAL
s.example.com IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
s.s.example.com. IN A
SECTION ANSWER
s.s.example.com. IN A 1.2.3.4
SECTION AUTHORITY
s.s.example.com. IN NS s.s.example.com.
SECTION ADDITIONAL
s.s.example.com IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; get the delegation in cache
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com IN A 1.2.3.4
ENTRY_END
; time passes
STEP 25 TIME_PASSES ELAPSE 1800
; get another delegation in cache
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
s.example.com. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
s.example.com. IN A
SECTION ANSWER
s.example.com. IN A 1.2.3.4
SECTION AUTHORITY
s.example.com. IN NS s.example.com.
ENTRY_END
; time passes, 1800 + 1000 = 2800 of 3600 TTL on NS of s.example.com. and
; example.com.
STEP 45 TIME_PASSES ELAPSE 1000
; get another delegation in cache
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
s.s.example.com. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
s.s.example.com. IN A
SECTION ANSWER
s.s.example.com. IN A 1.2.3.4
SECTION AUTHORITY
s.s.example.com. IN NS s.s.example.com.
ENTRY_END
; time passes, 1800 + 2000 = 3800 of 3600 TTL on NS of s.example.com. and
; example.com.
STEP 75 TIME_PASSES ELAPSE 1000
; domain no longer delegated
; is the domain still up?
STEP 100 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.s.example.com. IN A
ENTRY_END
STEP 110 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
www.s.example.com. IN A
SECTION AUTHORITY
com. 86400 IN SOA a. b. 1 2 3 4 5
ENTRY_END
STEP 120 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.s.s.example.com. IN A
ENTRY_END
STEP 130 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
www.s.s.example.com. IN A
SECTION AUTHORITY
com. 86400 IN SOA a. b. 1 2 3 4 5
ENTRY_END
STEP 140 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 150 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. 86400 IN SOA a. b. 1 2 3 4 5
ENTRY_END
SCENARIO_END

391
contrib/unbound/testdata/iter_ghost_timewindow.rpl vendored