Merge branch 'master' into xfr-tsig

This commit is contained in:
W.C.A. Wijngaards
2025-10-01 15:52:40 +02:00
85 changed files with 2121 additions and 742 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/109262826617293067?domain=https%3A%2F%2Ffosstodon.org&style=social)](https://fosstodon.org/@nlnetlabs)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/114692612288811644?domain=social.nlnetlabs.nl&style=social)](https://social.nlnetlabs.nl/@nlnetlabs)
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
fast and lean and incorporates modern features based on open standards. If you
+59 -12
View File
@@ -2,7 +2,10 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 48
# Version 50
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
# check by ACX_FUNC_MALLOC.
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
# and check for getaddrinfo with only header.
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
@@ -71,6 +74,7 @@
# ACX_DEPFLAG - find cc dependency flags.
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax.
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
@@ -92,6 +96,7 @@
# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably.
# ACX_FUNC_MALLOC - check malloc, define replacement .
# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format.
# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring.
# AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused.
# AHX_CONFIG_FSEEKO - define fseeko, ftello fallback.
# AHX_CONFIG_RAND_MAX - define RAND_MAX if needed.
@@ -490,7 +495,7 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
])
dnl Check how to mark function arguments as unused.
dnl result in HAVE_ATTR_UNUSED.
dnl result in HAVE_ATTR_UNUSED.
dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
@@ -525,6 +530,45 @@ if test $ac_cv_c_unused_attribute = yes; then
fi
])dnl
dnl Check how to mark function arguments as nonstring.
dnl result in HAVE_ATTR_NONSTRING.
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
[ac_cv_c_nonstring_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
struct test {
char __attribute__((nonstring)) s[1];
};
]], [[
struct test t = { "1" };
(void) t;
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
])
dnl Setup ATTR_NONSTRING config.h parts.
dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also.
AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE],
[
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
])
AC_MSG_RESULT($ac_cv_c_nonstring_attribute)
if test $ac_cv_c_nonstring_attribute = yes; then
AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute])
fi
])dnl
dnl Pre-fun for ACX_LIBTOOL_C_ONLY
AC_DEFUN([ACX_LIBTOOL_C_PRE], [
# skip these tests, we do not need them.
@@ -1190,8 +1234,9 @@ dnl detect malloc and provide malloc compat prototype.
dnl $1: unique name for compat code
AC_DEFUN([ACX_FUNC_MALLOC],
[
AC_MSG_CHECKING([for GNU libc compatible malloc])
AC_RUN_IFELSE([AC_LANG_PROGRAM(
AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull],
[
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
#include <stdlib.h>
#else
@@ -1199,14 +1244,16 @@ char *malloc ();
#endif
]], [ if(malloc(0) != 0) return 1;])
],
[AC_MSG_RESULT([no])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
[AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[AC_MSG_RESULT([no (crosscompile)])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
[ac_cv_func_malloc_0_nonnull=no],
[ac_cv_func_malloc_0_nonnull=yes],
[ac_cv_func_malloc_0_nonnull="no (crosscompile)"])
])
AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes],
[AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
])
])
dnl Define fallback for fseeko and ftello if needed.
+51 -42
View File
@@ -401,12 +401,9 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
/* We don't store the reply if its TTL is 0 unless serve-expired is
* enabled. Such a reply won't be reusable and simply be a waste for
* the backend. It's also compatible with the default behavior of
* dns_cache_store_msg(). */
if(qstate->return_msg->rep->ttl == 0 &&
!qstate->env->cfg->serve_expired)
/* We don't store the reply if its TTL is 0. This is probably coming
* from upstream and it is not meant to be stored. */
if(qstate->return_msg->rep->ttl == 0)
return 0;
/* The EDE is added to the out-list so it is encoded in the cached message */
@@ -460,7 +457,7 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
* - serve_expired needs to be set
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
* than that. */
if((time_t)expiry < *qstate->env->now &&
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now) &&
(!qstate->env->cfg->serve_expired ||
(SERVE_EXPIRED_TTL &&
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
@@ -472,7 +469,8 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
* negative, set the TTL to 0. */
static void
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract,
time_t timestamp)
{
size_t i;
size_t total = data->count + data->rrsig_count;
@@ -484,13 +482,13 @@ packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0;
}
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
data->ttl_add = timestamp;
}
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
* negative, set the TTLs to 0. */
static void
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
adjust_msg_ttl(struct dns_msg* msg, time_t adjust, time_t timestamp)
{
size_t i;
if(adjust >= 0 && msg->rep->ttl > adjust)
@@ -502,13 +500,13 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, adjust);
rep->rrsets[i]->entry.data, adjust, timestamp);
}
}
/* Set the TTL of the given RRset to fixed value. */
static void
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl, time_t timestamp)
{
size_t i;
size_t total = data->count + data->rrsig_count;
@@ -516,12 +514,12 @@ packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
for(i=0; i<total; i++) {
data->rr_ttl[i] = ttl;
}
data->ttl_add = 0;
data->ttl_add = timestamp;
}
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
static void
set_msg_ttl(struct dns_msg* msg, time_t ttl)
set_msg_ttl(struct dns_msg* msg, time_t ttl, time_t timestamp)
{
size_t i;
msg->rep->ttl = ttl;
@@ -530,14 +528,14 @@ set_msg_ttl(struct dns_msg* msg, time_t ttl)
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, ttl);
rep->rrsets[i]->entry.data, ttl, timestamp);
}
}
/** convert dns message in buffer to return_msg */
static int
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
int* msg_expired)
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
{
struct msg_parse* prs;
struct edns_data edns;
@@ -554,6 +552,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
&timestamp, sizeof(timestamp));
expiry = be64toh(expiry);
timestamp = be64toh(timestamp);
log_assert(timestamp <= expiry);
*msg_expiry = (time_t)expiry;
*msg_timestamp = (time_t)timestamp;
/* parse DNS packet */
regional_free_all(qstate->env->scratch);
@@ -605,11 +606,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
return 1; /* message from the future (clock skew?) */
}
adjust = *qstate->env->now - (time_t)timestamp;
if(qstate->return_msg->rep->ttl < adjust) {
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now)) {
verbose(VERB_ALGO, "cachedb msg expired");
*msg_expired = 1;
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
if(!qstate->env->cfg->serve_expired ||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NOERROR &&
@@ -618,23 +617,21 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */
else
adjust = -1;
/* If serve-expired is enabled, we still use an expired message.
* Set the TTL to 0 now and it will be handled specially later
* when we need to store it internally. */
adjust = -1;
}
adjust_msg_ttl(qstate->return_msg, adjust, timestamp);
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(qstate->return_msg);
}
/* Similar to the unbound worker, if serve-expired is enabled and
* the msg would be considered to be expired, mark the state so a
* refetch will be scheduled. The comparison between 'expiry' and
* 'now' should be redundant given how these values were calculated,
* but we check it just in case as does good_expiry_and_qinfo(). */
if(qstate->env->cfg->serve_expired &&
!qstate->env->cfg->serve_expired_client_timeout &&
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
* refetch will be scheduled. */
if(*msg_expired && !qstate->env->cfg->serve_expired_client_timeout) {
qstate->need_refetch = 1;
}
@@ -647,7 +644,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
*/
static int
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
int* msg_expired)
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
@@ -664,7 +661,8 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
}
/* parse dns message into return_msg */
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired) ) {
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired,
msg_timestamp, msg_expiry) ) {
return 0;
}
return 1;
@@ -736,20 +734,24 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
* Store query into the internal cache of unbound.
*/
static void
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
time_t msg_timestamp, time_t msg_expiry)
{
uint32_t store_flags = qstate->query_flags;
int serve_expired = qstate->env->cfg->serve_expired;
if(qstate->env->cfg->serve_expired)
store_flags |= DNSCACHE_STORE_ZEROTTL;
if(!qstate->return_msg)
return;
if(serve_expired && msg_expired) {
/* Set TTLs to a value such that value + *env->now is
* going to be now-3 seconds. Making it expired
* in the cache. */
set_msg_ttl(qstate->return_msg, (time_t)-3);
time_t original_ttl = msg_expiry - msg_timestamp;
store_flags |= DNSCACHE_STORE_EXPIRED_MSG_CACHEDB;
/* Pass the original TTL of the expired message and signal with
* the DNSCACHE_STORE_EXPIRED_MSG_CACHEDB flag that
* dns_cache_store_msg() needs to set absolute expired TTLs
* based on the original message TTL.
* Results as expired message in the cache */
set_msg_ttl(qstate->return_msg, original_ttl, 0);
verbose(VERB_ALGO, "cachedb expired msg set to be expired now "
"(original ttl: %d)", (int)original_ttl);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
@@ -767,12 +769,14 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
* of cache. */
return;
}
/* set TTLs to zero again */
adjust_msg_ttl(qstate->return_msg, -1);
/* Send serve expired responses based on the cachedb
* returned message, that was just stored in the cache.
* It can then continue to work on this query. */
mesh_respond_serve_expired(qstate->mesh_info);
/* set TTLs as expired for this return_msg in case it is used
* later on */
set_msg_ttl(qstate->return_msg,
EXPIRED_REPLY_TTL_CALC(msg_expiry, msg_timestamp), 0);
}
}
@@ -790,6 +794,7 @@ cachedb_handle_query(struct module_qstate* qstate,
struct cachedb_env* ie, int id)
{
int msg_expired = 0;
time_t msg_timestamp, msg_expiry;
qstate->is_cachedb_answer = 0;
/* check if we are enabled, and skip if so */
if(!ie->enabled) {
@@ -824,13 +829,15 @@ cachedb_handle_query(struct module_qstate* qstate,
}
/* ask backend cache to see if we have data */
if(cachedb_extcache_lookup(qstate, ie, &msg_expired)) {
if(cachedb_extcache_lookup(qstate, ie, &msg_expired, &msg_timestamp,
&msg_expiry)) {
if(verbosity >= VERB_ALGO)
log_dns_msg(ie->backend->name,
&qstate->return_msg->qinfo,
qstate->return_msg->rep);
/* store this result in internal cache */
cachedb_intcache_store(qstate, msg_expired);
cachedb_intcache_store(qstate,
msg_expired, msg_timestamp, msg_expiry);
/* In case we have expired data but there is a client timer for expired
* answers, pass execution to next module in order to try updating the
* data first.
@@ -850,6 +857,8 @@ cachedb_handle_query(struct module_qstate* qstate,
qstate->ext_state[id] = module_wait_module;
return;
}
/* No 0TTL answers escaping from external cache. */
log_assert(qstate->return_msg->rep->ttl > 0);
qstate->is_cachedb_answer = 1;
/* we are done with the query */
qstate->ext_state[id] = module_finished;
+14
View File
@@ -66,6 +66,9 @@
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "nonstring" attribute */
#undef HAVE_ATTR_NONSTRING
/* Whether the C compiler accepts the "noreturn" attribute */
#undef HAVE_ATTR_NORETURN
@@ -1390,6 +1393,17 @@
#endif /* !HAVE_ATTR_UNUSED */
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
#ifndef HAVE_FSEEKO
#define fseeko fseek
#define ftello ftell
Vendored
+100 -39
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for unbound 1.24.0.
# Generated by GNU Autoconf 2.71 for unbound 1.24.1.
#
# Report bugs to <[email protected] or https://github.com/NLnetLabs/unbound/issues>.
#
@@ -622,8 +622,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.24.0'
PACKAGE_STRING='unbound 1.24.0'
PACKAGE_VERSION='1.24.1'
PACKAGE_STRING='unbound 1.24.1'
PACKAGE_BUGREPORT='[email protected] or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@@ -1513,7 +1513,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.24.0 to adapt to many kinds of systems.
\`configure' configures unbound 1.24.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1579,7 +1579,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.24.0:";;
short | recursive ) echo "Configuration of unbound 1.24.1:";;
esac
cat <<\_ACEOF
@@ -1832,7 +1832,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.24.0
unbound configure 1.24.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2489,7 +2489,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.24.0, which was
It was created by unbound $as_me 1.24.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3253,11 +3253,11 @@ UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=24
UNBOUND_VERSION_MICRO=0
UNBOUND_VERSION_MICRO=1
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=33
LIBUNBOUND_REVISION=34
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -3358,6 +3358,7 @@ LIBUNBOUND_AGE=1
# 1.23.0 had 9:31:1
# 1.23.1 had 9:32:1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -6947,6 +6948,53 @@ printf "%s\n" "#define HAVE_ATTR_UNUSED 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute" >&5
printf %s "checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute... " >&6; }
if test ${ac_cv_c_nonstring_attribute+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_cv_c_nonstring_attribute=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
struct test {
char __attribute__((nonstring)) s[1];
};
int
main (void)
{
struct test t = { "1" };
(void) t;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_c_nonstring_attribute="yes"
else $as_nop
ac_cv_c_nonstring_attribute="no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_nonstring_attribute" >&5
printf "%s\n" "$ac_cv_c_nonstring_attribute" >&6; }
if test $ac_cv_c_nonstring_attribute = yes; then
printf "%s\n" "#define HAVE_ATTR_NONSTRING 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"weak\" attribute" >&5
@@ -17972,7 +18020,9 @@ if test x_$enable_alloc_nonregional = x_yes; then
printf "%s\n" "#define UNBOUND_ALLOC_NONREGIONAL 1" >>confdefs.h
fi
if test x_$enable_alloc_checks = x_yes; then
if test x_$enable_alloc_checks = x_yes
then :
printf "%s\n" "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h
@@ -17980,28 +18030,29 @@ printf "%s\n" "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h
ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
else
if test x_$enable_alloc_lite = x_yes; then
else $as_nop
if test x_$enable_alloc_lite = x_yes
then :
printf "%s\n" "#define UNBOUND_ALLOC_LITE 1" >>confdefs.h
else
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
printf %s "checking for GNU libc compatible malloc... " >&6; }
if test "$cross_compiling" = yes
if test ${ac_cv_func_malloc_0_nonnull+y}
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (crosscompile)" >&5
printf "%s\n" "no (crosscompile)" >&6; }
case " $LIBOBJS " in
*" malloc.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS malloc.$ac_objext"
;;
esac
printf "%s\n" "#define malloc rpl_malloc_unbound" >>confdefs.h
printf %s "(cached) " >&6
else $as_nop
if test "$cross_compiling" = yes
then :
ac_cv_func_malloc_0_nonnull="no (crosscompile)"
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -18022,9 +18073,26 @@ main (void)
_ACEOF
if ac_fn_c_try_run "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
case " $LIBOBJS " in
ac_cv_func_malloc_0_nonnull=no
else $as_nop
ac_cv_func_malloc_0_nonnull=yes
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
printf "%s\n" "$ac_cv_func_malloc_0_nonnull" >&6; }
if test "$ac_cv_func_malloc_0_nonnull" = yes
then :
printf "%s\n" "#define HAVE_MALLOC 1" >>confdefs.h
else $as_nop
case " $LIBOBJS " in
*" malloc.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS malloc.$ac_objext"
;;
@@ -18033,19 +18101,12 @@ esac
printf "%s\n" "#define malloc rpl_malloc_unbound" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_MALLOC 1" >>confdefs.h
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
fi
# check windows threads (we use them, not pthreads, on windows).
@@ -25309,7 +25370,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.24.0
version=1.24.1
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
printf %s "checking for build time... " >&6; }
@@ -25839,7 +25900,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.24.0, which was
This file was extended by unbound $as_me 1.24.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25907,7 +25968,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
unbound config.status 1.24.0
unbound config.status 1.24.1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+11 -8
View File
@@ -12,14 +12,14 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[24])
m4_define([VERSION_MICRO],[0])
m4_define([VERSION_MICRO],[1])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[[email protected] 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=33
LIBUNBOUND_REVISION=34
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -120,6 +120,7 @@ LIBUNBOUND_AGE=1
# 1.23.0 had 9:31:1
# 1.23.1 had 9:32:1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -328,6 +329,7 @@ fi
AC_C_INLINE
ACX_CHECK_FORMAT_ATTRIBUTE
ACX_CHECK_UNUSED_ATTRIBUTE
ACX_CHECK_NONSTRING_ATTRIBUTE
AC_DEFUN([CHECK_WEAK_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
@@ -633,19 +635,19 @@ AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ e
if test x_$enable_alloc_nonregional = x_yes; then
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
fi
if test x_$enable_alloc_checks = x_yes; then
AS_IF([test x_$enable_alloc_checks = x_yes],[
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
else
if test x_$enable_alloc_lite = x_yes; then
],[
AS_IF([test x_$enable_alloc_lite = x_yes],[
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
else
],[
ACX_FUNC_MALLOC([unbound])
fi
fi
])
])
# check windows threads (we use them, not pthreads, on windows).
if test "$on_mingw" = "yes"; then
@@ -2291,6 +2293,7 @@ dnl includes
AHX_CONFIG_FORMAT_ATTRIBUTE
AHX_CONFIG_UNUSED_ATTRIBUTE
AHX_CONFIG_NONSTRING_ATTRIBUTE
AHX_CONFIG_FSEEKO
AHX_CONFIG_MAXHOSTNAMELEN
#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
+1 -1
View File
@@ -59,7 +59,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+1 -1
View File
@@ -26,7 +26,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+2 -1
View File
@@ -154,7 +154,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
log_crypto_err("could not SSL_CTX_new");
return 0;
}
if(!listen_sslctx_setup(rc->ctx)) {
if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
return 0;
}
@@ -5895,6 +5895,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(tls_ciphers);
COPY_VAR_ptr(tls_ciphersuites);
COPY_VAR_int(tls_use_sni);
COPY_VAR_int(tls_use_system_policy_versions);
COPY_VAR_int(https_port);
COPY_VAR_ptr(http_endpoint);
COPY_VAR_uint32_t(http_max_streams);
+1 -1
View File
@@ -473,7 +473,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
cfg->tls_ciphers, cfg->tls_ciphersuites,
(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0),
is_dot, is_doh))) {
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen SSL_CTX");
}
}
+5 -5
View File
@@ -747,7 +747,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
*partial_repp = NULL; /* avoid accidental further pass */
/* Check TTL */
if(rep->ttl < timenow) {
if(TTL_IS_EXPIRED(rep->ttl, timenow)) {
/* Check if we need to serve expired now */
if(worker->env.cfg->serve_expired &&
/* if serve-expired-client-timeout is set, serve
@@ -1967,11 +1967,11 @@ lookup_cache:
if((worker->env.cfg->prefetch &&
rep->prefetch_ttl <= *worker->env.now) ||
(worker->env.cfg->serve_expired &&
rep->ttl < *worker->env.now &&
TTL_IS_EXPIRED(rep->ttl, *worker->env.now) &&
!(*worker->env.now < rep->serve_expired_norec_ttl))) {
time_t leeway = rep->ttl - *worker->env.now;
if(rep->ttl < *worker->env.now)
leeway = 0;
time_t leeway =
TTL_IS_EXPIRED(rep->ttl, *worker->env.now)
? 0 : rep->ttl - *worker->env.now;
lock_rw_unlock(&e->lock);
reply_and_prefetch(worker, lookup_qinfo,
+4 -4
View File
@@ -496,8 +496,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
/* Create the new sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
&subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
return module_error;
if (subq) {
subq->curmod = id;
@@ -522,8 +522,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
/* Start the sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
0, &subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
{
verbose(VERB_ALGO, "dns64: sub-query creation failed");
return module_error;
+1 -1
View File
@@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
s->ev_cb = ev_cb;
s->data = data;
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
NULL, NULL, 0, 0, 0);
NULL, NULL, 0, 0, 0, 0);
if(!s->sslctx) {
log_err("could not create ssl context");
free(s->ip);
+70
View File
@@ -1,3 +1,73 @@
30 September 2025: Wouter
- Fix for #1344: Fix that respip and dns64 can be enabled at the
same time, the client info is copied for attach_sub and add_sub
calls. That makes respip work on dns64 synthesized answers, and
also makes RPZ work with DNS64. The order for the modules is
module-config: "respip dns64 validator iterator".
29 September 2025: Wouter
- Rebuild configure script from its sources.
- Fix modstack_call_init to use the original string when it has
changed, to call modstack_config with. And skip the changed name
in the string correctly. Thanks to Jan Komissar.
- Neaten up the change in acx_nlnetlabs.m4 to version 49.
- Fix fr_atomic_copy_cfg.
- Rebuild configure script from its sources.
- Fix #1353: auth-zone can not use empty label for $ORIGIN when
http download.
- Fix #1344: module conf 'respip dns64 validator cachedb iterator'
is not known to work.
29 September 2025: Yorgos
- Merge #1349: Fix #1346: [FR] Please allow back TLS 1.2.
- Merge #1351: ac_cv_func_malloc_0_nonnull for malloc(0) check.
26 September 2025: Yorgos
- Test for nonstring attribute in configure and add
nonstring attribute annotations.
24 September 2025: Yorgos
- Avoid calling mesh_detect_cycle_found() when there is no mesh state
to begin with.
23 September 2025: Yorgos
- Merge #1352 from Petr Vaganov: pythonmod: fix HANDLE_LEAK on
pythonmod_init.
- For #1352, align with the current Python<3 code.
- Merge #1350 from Maryse47: unbound.service.in: allow CAP_NET_ADMIN.
- For #1350, same CAP_NET_ADMIN change for unbound_portable.service.in
as well.
19 September 2025: Wouter
- Fix to remove configure~ from release tarballs.
19 September 2025: Yorgos
- Update README.man with clearer text.
- Merge #1337: 0 TTL cached replies and some TTL behavior changes.
- TTL change: Cached records that reach TTL 0 are expired.
- TTL change: TTL 0 upstream answers are no longer cached by
cachedb, as they should.
- TTL change: 'serve-expired-reply-ttl' is now capped by the original
TTL value of the record to try and make some sense when replying
with expired records.
- TTL change: TTL decoding was updated to adhere to RFC8767 section 4
where a 'set high-order bit' means the value is positive instead of
0.
- unbound.conf manpage: explicitly mention RFC6891.
18 September 2025: Wouter
- Tag for 1.24.0 release. Includes the fixes below after rc1.
The repository continues with version 1.24.1.
17 September 2025: Yorgos
- Too many quotes for the EDE message debug printout.
15 September 2025: Yorgos
- Small debug output improvement when attaching an EDE.
15 September 2025: Wouter
- Fix to print warning for when so-sndbuf setsockopt is not granted.
11 September 2025: Wouter
- version set to 1.24.0 for release.
- tag for 1.24.0rc1.
+8 -3
View File
@@ -6,11 +6,16 @@ and makes it easier to maintain and contribute to the documentation.
The templated man pages (*.in) are still part of the code repository as to not
alter current procedures that could be in place by users/packagers.
These man pages (*.in) are still the ones being used when
configuring/installing Unbound.
Packagers/users do not have to generate any man pages themselves, this is done
by the core developers during development and upon releasing new versions.
The templated man pages (*.in) are generated by Sphinx (used for the online
documentation).
The online documentation has its own repository at
https://github.com/NLnetLabs/unbound-manual.
In the README.md there (branch test-auto for now), there are further simple
instructions on how to generate the templated man pages there and update them
in this repository.
In that README.md (https://github.com/NLnetLabs/unbound-manual/README.md)
there are further simple instructions on how to generate the templated man
pages there and update them in this repository.
+18 -9
View File
@@ -752,6 +752,7 @@ server:
# serve-expired-ttl-reset: no
#
# TTL value to use when replying with expired data.
# Capped by the original TTL of the record.
# serve-expired-reply-ttl: 30
#
# Time in milliseconds before replying to the client with expired data.
@@ -931,21 +932,26 @@ server:
# https-port: 443
# quic-port: 853
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers.
# cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
# cipher setting for TLSv1.3
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload.
# tls-use-sni: yes
# Allow general-purpose version-flexible TLS server configuration that
# may be further restricted by the system's policy.
# Use only if you want to support legacy TLS client connections.
# Default is no and Unbound will only use the latest available TLS
# version.
# Changing the value requires a reload.
# tls-use-system-policy-versions: no
# Add the secret file for TLS Session Ticket.
# Secret file must be 80 bytes of random data.
# First key use to encrypt and decrypt TLS session tickets.
@@ -966,15 +972,18 @@ server:
# and on other systems, the default openssl certificates
# tls-system-cert: no
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Pad queries over TLS upstreams
# pad-queries: yes
# Padded queries will be padded to the closest multiple of this size.
# pad-queries-block-size: 128
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers.
# HTTP endpoint to provide DNS-over-HTTPS service on.
# http-endpoint: "/dns-query"
+48 -15
View File
@@ -1218,6 +1218,47 @@ Default: \(dq\(dq
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-sni: \fI<yes or no>\fP
Enable or disable sending the SNI extension on TLS connections.
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: yes
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP
Enable or disable general\-puspose version\-flexible TLS server configuration
when serving TLS.
This will allow the whole list of available TLS versions provided by the
crypto library, which may have been further restricted by the system\(aqs
crypto policy.
.sp
By default Unbound only uses the latest available TLS version.
.sp
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
Use only if you want to support legacy TLS client connections.
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: no
.UNINDENT
.INDENT 0.0
.TP
.B pad\-responses: \fI<yes or no>\fP
If enabled, TLS serviced queries that contained an EDNS Padding option will
cause responses padded to the closest multiple of the size specified in
@@ -1251,20 +1292,6 @@ Default: 128
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-sni: \fI<yes or no>\fP
Enable or disable sending the SNI extension on TLS connections.
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: yes
.UNINDENT
.INDENT 0.0
.TP
.B https\-port: \fI<number>\fP
The port number on which to provide DNS\-over\-HTTPS service.
Only interfaces configured with that port number as @number get the HTTPS
@@ -1969,7 +1996,7 @@ Default: \(dq3 2 1 0 0\(dq
.B harden\-short\-bufsize: \fI<yes or no>\fP
Very small EDNS buffer sizes from queries are ignored.
.sp
Default: yes (as described in the standard)
Default: yes (per \fI\%RFC 6891\fP)
.UNINDENT
.INDENT 0.0
.TP
@@ -2600,6 +2627,12 @@ If
\fI\%serve\-expired\-client\-timeout\fP
is also used then it is RECOMMENDED to use 30 as the value (\fI\%RFC 8767\fP).
.sp
This value is capped by the original TTL of the record.
This means that records with higher original TTL than this value will use
this value for expired replies.
Records with lower original TTL than this value will use their original TTL
for expired replies.
.sp
Default: 30
.UNINDENT
.INDENT 0.0
+31 -9
View File
@@ -1103,6 +1103,30 @@ These options are part of the **server:** clause.
Default: ""
@@[email protected]@tls-use-sni@@: *<yes or no>*
Enable or disable sending the SNI extension on TLS connections.
.. note:: Changing the value requires a reload.
Default: yes
@@[email protected]@tls-use-system-policy-versions@@: *<yes or no>*
Enable or disable general-puspose version-flexible TLS server configuration
when serving TLS.
This will allow the whole list of available TLS versions provided by the
crypto library, which may have been further restricted by the system's
crypto policy.
By default Unbound only uses the latest available TLS version.
.. caution:: Use only if you want to support legacy TLS client connections.
.. note:: Changing the value requires a reload.
Default: no
@@[email protected]@pad-responses@@: *<yes or no>*
If enabled, TLS serviced queries that contained an EDNS Padding option will
cause responses padded to the closest multiple of the size specified in
@@ -1132,14 +1156,6 @@ These options are part of the **server:** clause.
Default: 128
@@[email protected]@tls-use-sni@@: *<yes or no>*
Enable or disable sending the SNI extension on TLS connections.
.. note:: Changing the value requires a reload.
Default: yes
@@[email protected]@https-port@@: *<number>*
The port number on which to provide DNS-over-HTTPS service.
Only interfaces configured with that port number as @number get the HTTPS
@@ -1744,7 +1760,7 @@ These options are part of the **server:** clause.
@@[email protected]@harden-short-bufsize@@: *<yes or no>*
Very small EDNS buffer sizes from queries are ignored.
Default: yes (as described in the standard)
Default: yes (per :rfc:`6891`)
@@[email protected]@harden-large-queries@@: *<yes or no>*
@@ -2306,6 +2322,12 @@ These options are part of the **server:** clause.
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
is also used then it is RECOMMENDED to use 30 as the value (:rfc:`8767`).
This value is capped by the original TTL of the record.
This means that records with higher original TTL than this value will use
this value for expired replies.
Records with lower original TTL than this value will use their original TTL
for expired replies.
Default: 30
+2 -2
View File
@@ -567,8 +567,8 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
&subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, qstate->client_info,
qflags, prime, valrec, &subq)) {
return 0;
}
if(subq) {
+1 -1
View File
@@ -163,7 +163,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
if(!(*qstate->env->attach_sub)(qstate, &ask, NULL,
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
log_err("Could not generate request: out of memory");
return 0;
+3 -3
View File
@@ -829,7 +829,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
struct mesh_state* sub = NULL;
fptr_ok(fptr_whitelist_modenv_add_sub(
qstate->env->add_sub));
if(!(*qstate->env->add_sub)(qstate, &qinf,
if(!(*qstate->env->add_sub)(qstate, &qinf, NULL,
qflags, prime, valrec, &subq, &sub)){
return 0;
}
@@ -838,8 +838,8 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
/* attach subquery, lookup existing or make a new one */
fptr_ok(fptr_whitelist_modenv_attach_sub(
qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
valrec, &subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, NULL, qflags,
prime, valrec, &subq)) {
return 0;
}
}
+3
View File
@@ -440,6 +440,7 @@ if [ "$DOWIN" = "yes" ]; then
autoheader -f || error_cleanup "Autoheader failed."
rm -r autom4te* || echo "ignored"
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
fi
if test "`uname`" = "Linux"; then
@@ -621,6 +622,7 @@ autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
info "Building lexer and parser."
echo "#include \"config.h\"" > util/configlexer.c || error_cleanup "Failed to create configlexer"
@@ -666,6 +668,7 @@ if [ "$RECONFIGURE" = "yes" ]; then
autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
fi
replace_all doc/README
+2 -2
View File
@@ -732,8 +732,8 @@ struct module_env {
char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
void (*kill_sub)(struct module_qstate* newq);
int (*detect_cycle)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t flags, int prime,
+15 -32
View File
@@ -454,7 +454,7 @@ int pythonmod_init(struct module_env* env, int id)
if(PyDict_SetItemString(pe->data, "script", fname) < 0) {
log_err("pythonmod: could not add item to dictionary");
Py_XDECREF(fname);
goto python_init_fail;
goto fail_close_file;
}
Py_XDECREF(fname);
Py_XINCREF(pe->data); /* reference will be stolen below */
@@ -462,7 +462,7 @@ int pythonmod_init(struct module_env* env, int id)
log_err("pythonmod: could not add mod_env object");
Py_XDECREF(pe->data); /* 2 times, here and on python_init_fail; */
/* on failure the reference is not stolen */
goto python_init_fail;
goto fail_close_file;
}
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
@@ -493,31 +493,15 @@ int pythonmod_init(struct module_env* env, int id)
flen = (size_t)ftell(script_py);
fstr = malloc(flen+1);
if(!fstr) {
log_err("malloc failure to print parse error");
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
goto python_init_fail;
log_err("malloc failure to print parse error");
goto fail_close_file;
}
fseek(script_py, 0, SEEK_SET);
if(fread(fstr, flen, 1, script_py) < 1) {
log_err("file read failed to print parse error: %s: %s",
log_err("file read failed to print parse error: %s: %s",
pe->fname, strerror(errno));
free(fstr);
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
goto python_init_fail;
free(fstr);
goto fail_close_file;
}
fstr[flen] = 0;
/* we compile the string, but do not run it, to stop side-effects */
@@ -527,21 +511,13 @@ int pythonmod_init(struct module_env* env, int id)
#endif
log_py_err();
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
/* no cleanup needed for python before 3.9 */
#else
/* cleanup for python 3.9 and newer */
free(fstr);
#endif
goto python_init_fail;
goto fail_close_file;
}
/* close the file */
@@ -602,6 +578,13 @@ int pythonmod_init(struct module_env* env, int id)
PyGILState_Release(gil);
return 1;
fail_close_file:
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
python_init_fail:
Py_XDECREF(pe->module);
Py_XDECREF(pe->dict);
+4 -2
View File
@@ -1074,7 +1074,8 @@ generate_cname_request(struct module_qstate* qstate,
subqi.qtype = qstate->qinfo.qtype;
subqi.qclass = qstate->qinfo.qclass;
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq);
return (*qstate->env->attach_sub)(qstate, &subqi,
qstate->client_info, BIT_RD, 0, 0, &subq);
}
void
@@ -1233,7 +1234,8 @@ respip_inform_super(struct module_qstate* qstate, int id,
struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id];
struct reply_info* new_rep = NULL;
rq->state = RESPIP_SUBQUERY_FINISHED;
if(rq)
rq->state = RESPIP_SUBQUERY_FINISHED;
/* respip subquery should have always been created with a valid reply
* in super. */
+23 -22
View File
@@ -172,7 +172,7 @@ get_rrset_ttl(struct ub_packed_rrset_key* k)
/** Copy rrset into region from domain-datanode and packet rrset */
static struct ub_packed_rrset_key*
auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
struct auth_rrset* rrset, struct regional* region, time_t adjust)
struct auth_rrset* rrset, struct regional* region)
{
struct ub_packed_rrset_key key;
memset(&key, 0, sizeof(key));
@@ -183,7 +183,7 @@ auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
key.rk.type = htons(rrset->type);
key.rk.rrset_class = htons(z->dclass);
key.entry.hash = rrset_key_hash(&key.rk);
return packed_rrset_copy_region(&key, region, adjust);
return packed_rrset_copy_region(&key, region, 0);
}
/** fix up msg->rep TTL and prefetch ttl */
@@ -237,7 +237,7 @@ msg_add_rrset_an(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->an_numrrsets++;
@@ -261,7 +261,7 @@ msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->ns_numrrsets++;
@@ -284,7 +284,7 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->ar_numrrsets++;
@@ -4651,6 +4651,23 @@ http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
return 0;
}
/** remove newlines from collated line */
static void
chunkline_newline_removal(sldns_buffer* buf)
{
size_t i, end=sldns_buffer_limit(buf);
for(i=0; i<end; i++) {
char c = (char)sldns_buffer_read_u8_at(buf, i);
if(c == '\n' && i==end-1) {
sldns_buffer_write_u8_at(buf, i, 0);
sldns_buffer_set_limit(buf, end-1);
return;
}
if(c == '\n')
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
}
}
/** find noncomment RR line in chunks, collates lines if ( ) format */
static int
chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
@@ -4658,6 +4675,7 @@ chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
{
int ret;
while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
chunkline_newline_removal(buf);
if(chunkline_is_comment_line_or_empty(buf)) {
/* a comment, go to next line */
continue;
@@ -4733,23 +4751,6 @@ chunklist_sum(struct auth_chunk* list)
return s;
}
/** remove newlines from collated line */
static void
chunkline_newline_removal(sldns_buffer* buf)
{
size_t i, end=sldns_buffer_limit(buf);
for(i=0; i<end; i++) {
char c = (char)sldns_buffer_read_u8_at(buf, i);
if(c == '\n' && i==end-1) {
sldns_buffer_write_u8_at(buf, i, 0);
sldns_buffer_set_limit(buf, end-1);
return;
}
if(c == '\n')
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
}
}
/** for http download, parse and add RR to zone */
static int
http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z,
+59 -27
View File
@@ -60,10 +60,10 @@
* @param rep: contains list of rrsets to store.
* @param now: current time.
* @param leeway: during prefetch how much leeway to update TTLs.
* This makes rrsets (other than type NS) timeout sooner so they get
* updated with a new full TTL.
* Type NS does not get this, because it must not be refreshed from the
* child domain, but keep counting down properly.
* This makes rrsets expire sooner so they get updated with a new full
* TTL.
* Child side type NS does get this but TTL checks are done using the time
* the query was created rather than the time the answer was received.
* @param pside: if from parentside discovered NS, so that its NS is okay
* in a prefetch situation to be updated (without becoming sticky).
* @param qrep: update rrsets here if cache is better
@@ -100,11 +100,20 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
rep->ref[i].id != rep->ref[i].key->id)
ck = NULL;
else ck = packed_rrset_copy_region(
rep->ref[i].key, region, now);
rep->ref[i].key, region,
((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?qstarttime:now));
lock_rw_unlock(&rep->ref[i].key->entry.lock);
if(ck) {
/* use cached copy if memory allows */
qrep->rrsets[i] = ck;
ttl = ((struct packed_rrset_data*)
ck->entry.data)->ttl;
if(ttl < qrep->ttl) {
qrep->ttl = ttl;
qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl);
qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL;
}
}
}
/* no break: also copy key item */
@@ -169,10 +178,12 @@ 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);
if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) {
reply_info_absolute_ttls(rep, *env->now, *env->now - ttl);
} else reply_info_set_ttls(rep, *env->now);
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
qstarttime);
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
if(ttl == 0) {
/* we do not store the message, but we did store the RRs,
* which could be useful for delegation information */
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
@@ -272,8 +283,10 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
{
if((msg->rep->rrsets[msg->rep->rrset_count] =
packed_rrset_copy_region(rrset, region, now))) {
struct packed_rrset_data* d = rrset->entry.data;
msg->rep->ar_numrrsets++;
msg->rep->rrset_count++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
}
@@ -456,8 +469,10 @@ find_add_ds(struct module_env* env, struct regional* region,
/* add it to auth section. This is the second rrset. */
if((msg->rep->rrsets[msg->rep->rrset_count] =
packed_rrset_copy_region(rrset, region, now))) {
struct packed_rrset_data* d = rrset->entry.data;
msg->rep->ns_numrrsets++;
msg->rep->rrset_count++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
lock_rw_unlock(&rrset->entry.lock);
}
@@ -487,6 +502,8 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
return NULL; /* integer overflow protection */
msg->rep->flags = BIT_QR; /* with QR, no AA */
msg->rep->qdcount = 1;
msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add
* rrsets to the message */
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->rrsets = (struct ub_packed_rrset_key**)
regional_alloc(region,
@@ -497,24 +514,28 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
}
int
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now)
{
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
struct packed_rrset_data* d = rrset->entry.data;
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
packed_rrset_copy_region(rrset, region, now)))
return 0;
msg->rep->ns_numrrsets++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
return 1;
}
int
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now)
{
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
struct packed_rrset_data* d = rrset->entry.data;
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
packed_rrset_copy_region(rrset, region, now)))
return 0;
msg->rep->an_numrrsets++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
return 1;
}
@@ -585,6 +606,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
sizeof(struct reply_info) - sizeof(struct rrset_ref));
if(!msg->rep)
return NULL;
msg->rep->ttl = MAX_TTL;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->reason_bogus_str = NULL;
if(num > RR_COUNT_MAX)
@@ -606,13 +628,13 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
size_t i;
int is_expired = 0;
time_t now_control = now;
if(now > r->ttl) {
if(TTL_IS_EXPIRED(r->ttl, now)) {
/* Check if we are allowed to serve expired */
if(!allow_expired || !reply_info_can_answer_expired(r, now))
return NULL;
/* Change the current time so we can pass the below TTL checks when
* serving expired data. */
now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
/* Change the current time so we can pass the below TTL checks
* when serving expired data. */
now_control = 0;
is_expired = 1;
}
@@ -620,15 +642,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
if(!msg) return NULL;
msg->rep->flags = r->flags;
msg->rep->qdcount = r->qdcount;
msg->rep->ttl = is_expired
?SERVE_EXPIRED_REPLY_TTL
:r->ttl - now;
if(r->prefetch_ttl > now)
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
else
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
msg->rep->security = r->security;
msg->rep->an_numrrsets = r->an_numrrsets;
msg->rep->ns_numrrsets = r->ns_numrrsets;
@@ -656,13 +669,30 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
return NULL;
}
for(i=0; i<msg->rep->rrset_count; i++) {
struct packed_rrset_data* d;
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
region, now);
if(!msg->rep->rrsets[i]) {
rrset_array_unlock(r->ref, r->rrset_count);
return NULL;
}
d = msg->rep->rrsets[i]->entry.data;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
if(msg->rep->rrset_count < 1) {
msg->rep->ttl = is_expired
?SERVE_EXPIRED_REPLY_TTL
:r->ttl - now;
if(r->prefetch_ttl > now)
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
else
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
} else {
/* msg->rep->ttl has been updated through the RRSets above */
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
}
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
if(env)
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
r->rrset_count);
@@ -701,7 +731,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
struct dns_msg* msg;
struct packed_rrset_data* d = (struct packed_rrset_data*)
rrset->entry.data;
if(now > d->ttl)
if(TTL_IS_EXPIRED(d->ttl, now))
return NULL;
msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */
if(!msg)
@@ -736,7 +766,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
rrset->entry.data;
uint8_t* newname, *dtarg = NULL;
size_t newlen, dtarglen;
if(now > d->ttl)
if(TTL_IS_EXPIRED(d->ttl, now))
return NULL;
/* only allow validated (with DNSSEC) DNAMEs used from cache
* for insecure DNAMEs, query again. */
@@ -844,6 +874,8 @@ fill_any(struct module_env* env,
/* set NOTIMPL for RFC 8482 */
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
msg->rep->security = sec_status_indeterminate;
msg->rep->ttl = 1; /* empty NOTIMPL response will never be
* updated with rrsets, set TTL to 1 */
return msg;
}
@@ -1069,7 +1101,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
msgqinf->qclass, flags, 0, 1);
if(e) {
struct reply_info* cached = e->entry.data;
if(cached->ttl < *env->now
if(TTL_IS_EXPIRED(cached->ttl, *env->now)
&& reply_info_could_use_expired(cached, *env->now)
/* If we are validating make sure only
* validating modules can update such messages.
+1 -1
View File
@@ -53,7 +53,7 @@ struct delegpt;
* Must be an unsigned 32-bit value larger than 0xffff */
/** Allow caching a DNS message with a zero TTL. */
#define DNSCACHE_STORE_ZEROTTL 0x100000
#define DNSCACHE_STORE_EXPIRED_MSG_CACHEDB 0x100000
/**
* Region allocated message reply
+10 -9
View File
@@ -131,7 +131,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
/* o if new data is expired, cached data is better */
if( newd->ttl < timenow && timenow <= cached->ttl)
if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow))
return 0;
/* o store if rrset has been validated
* everything better than bogus data
@@ -146,13 +146,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if( newd->trust > cached->trust ) {
/* if the cached rrset is bogus, and new is equal,
* do not update the TTL - let it expire. */
if(equal && cached->ttl >= timenow &&
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
cached->security == sec_status_bogus)
return 0;
return 1;
}
/* o item in cache has expired */
if( cached->ttl < timenow )
if( TTL_IS_EXPIRED(cached->ttl, timenow) )
return 1;
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal ) {
@@ -300,7 +300,7 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
/* check TTL */
struct packed_rrset_data* data =
(struct packed_rrset_data*)e->data;
if(timenow > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
lock_rw_unlock(&e->lock);
return NULL;
}
@@ -310,17 +310,18 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
return NULL;
}
int
int
rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow)
{
size_t i;
struct packed_rrset_data* d;
for(i=0; i<count; i++) {
if(i>0 && ref[i].key == ref[i-1].key)
continue; /* only lock items once */
lock_rw_rdlock(&ref[i].key->entry.lock);
if(ref[i].id != ref[i].key->id || timenow >
((struct packed_rrset_data*)(ref[i].key->entry.data))
->ttl) {
d = ref[i].key->entry.data;
if(ref[i].id != ref[i].key->id ||
TTL_IS_EXPIRED(d->ttl, timenow)) {
/* failure! rollback our readlocks */
rrset_array_unlock(ref, i+1);
return 0;
@@ -511,7 +512,7 @@ rrset_cache_expired_above(struct rrset_cache* r, uint8_t** qname, size_t*
*qnamelen, searchtype, qclass, 0, 0, 0))) {
struct packed_rrset_data* data =
(struct packed_rrset_data*)rrset->entry.data;
if(now > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, now)) {
/* it is expired, this is not wanted */
lock_rw_unlock(&rrset->entry.lock);
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
+15 -7
View File
@@ -450,7 +450,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
* /proc/sys/net/core/wmem_max or sysctl net.core.wmem_max */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
if(errno != EPERM) {
if(errno != EPERM && errno != ENOBUFS) {
log_err("setsockopt(..., SO_SNDBUFFORCE, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
@@ -458,15 +458,23 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*inuse = 0;
return -1;
}
if(errno != EPERM) {
verbose(VERB_ALGO, "setsockopt(..., SO_SNDBUFFORCE, "
"...) was not granted: %s", sock_strerror(errno));
}
# endif /* SO_SNDBUFFORCE */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
log_err("setsockopt(..., SO_SNDBUF, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
if(errno != ENOSYS && errno != ENOBUFS) {
log_err("setsockopt(..., SO_SNDBUF, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
}
log_warn("setsockopt(..., SO_SNDBUF, "
"...) was not granted: %s", sock_strerror(errno));
}
/* check if we got the right thing or if system
* reduced to some system max. Warn if so */
+19 -18
View File
@@ -348,7 +348,7 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
key = (struct msgreply_entry*)e->key;
data = (struct reply_info*)e->data;
if(data->ttl < timenow) *is_expired = 1;
if(TTL_IS_EXPIRED(data->ttl, timenow)) *is_expired = 1;
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
qstate->env->cfg->serve_expired, qstate->env->scratch);
if(!msg)
@@ -1152,8 +1152,7 @@ mesh_detect_cycle_found(struct module_qstate* qstate, struct mesh_state* dep_m)
{
struct mesh_state* cyc_m = qstate->mesh_info;
size_t counter = 0;
if(!dep_m)
return 0;
log_assert(dep_m);
if(dep_m == cyc_m || find_in_subsub(dep_m, cyc_m, &counter)) {
if(counter > MESH_MAX_SUBSUB)
return 2;
@@ -1190,24 +1189,19 @@ void mesh_detach_subs(struct module_qstate* qstate)
}
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub)
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub)
{
/* find it, if not, create it */
struct mesh_area* mesh = qstate->env->mesh;
*sub = mesh_area_find(mesh, NULL, qinfo, qflags,
prime, valrec);
if(mesh_detect_cycle_found(qstate, *sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
return 0;
}
*sub = mesh_area_find(mesh, cinfo, qinfo, qflags, prime, valrec);
if(!*sub) {
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
#endif
/* create a new one */
*sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime,
valrec);
*sub = mesh_state_create(qstate->env, qinfo, cinfo, qflags,
prime, valrec);
if(!*sub) {
log_err("mesh_attach_sub: out of memory");
return 0;
@@ -1230,18 +1224,25 @@ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
rbtree_insert(&mesh->run, &(*sub)->run_node);
log_assert(n != NULL);
*newq = &(*sub)->s;
} else
} else {
*newq = NULL;
if(mesh_detect_cycle_found(qstate, *sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
return 0;
}
}
return 1;
}
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq)
{
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* sub = NULL;
int was_detached;
if(!mesh_add_sub(qstate, qinfo, qflags, prime, valrec, newq, &sub))
if(!mesh_add_sub(qstate, qinfo, cinfo, qflags, prime, valrec, newq,
&sub))
return 0;
was_detached = (sub->super_set.count == 0);
if(!mesh_state_attachment(qstate->mesh_info, sub))
@@ -1684,7 +1685,7 @@ static void dns_error_reporting(struct module_qstate* qstate,
log_query_info(VERB_ALGO, "DNS Error Reporting: generating report "
"query for", &qinfo);
if(mesh_add_sub(qstate, &qinfo, BIT_RD, 0, 0, &newq, &sub)) {
if(mesh_add_sub(qstate, &qinfo, NULL, BIT_RD, 0, 0, &newq, &sub)) {
qstate->env->mesh->num_dns_error_reports++;
}
return;
@@ -2297,7 +2298,7 @@ mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* dep_m = NULL;
dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
return mesh_detect_cycle_found(qstate, dep_m);
return dep_m?mesh_detect_cycle_found(qstate, dep_m):0;
}
void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp,
+8 -3
View File
@@ -399,6 +399,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -407,7 +409,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @return: false on error, true if success (and init may be needed).
*/
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
/**
* Add detached query.
@@ -426,6 +429,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -435,8 +440,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @return: false on error, true if success (and init may be needed).
*/
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub);
/**
* Query state is done, send messages to reply entries.
+5 -2
View File
@@ -262,6 +262,7 @@ int
modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
const char* orig_module_conf = module_conf;
int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
@@ -276,11 +277,13 @@ modstack_call_init(struct module_stack* stack, const char* module_conf,
changed = 1;
}
}
module_conf += strlen(stack->mod[i]->name);
/* Skip this module name in module_conf. */
while(*module_conf && !isspace((unsigned char)*module_conf))
module_conf++;
}
if(changed) {
modstack_free(stack);
if(!modstack_config(stack, module_conf)) {
if(!modstack_config(stack, orig_module_conf)) {
return 0;
}
}
+1 -1
View File
@@ -784,7 +784,6 @@ morechecks(struct config_file* cfg)
/* check that the modules listed in module_conf exist */
check_modules_exist(cfg->module_conf);
/* Respip is known to *not* work with dns64. */
if(strcmp(cfg->module_conf, "iterator") != 0
&& strcmp(cfg->module_conf, "validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
@@ -870,6 +869,7 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip dns64 validator cachedb iterator") != 0
#endif
#if defined(WITH_PYTHONMODULE) && defined(USE_CACHEDB)
&& strcmp(cfg->module_conf, "python dns64 cachedb iterator") != 0
@@ -0,0 +1,5 @@
$ORIGIN .
$TTL 7200
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
example.com. IN NS ns.example.net.
www.example.com. IN A 1.2.3.4
+17
View File
@@ -0,0 +1,17 @@
server:
verbosity: 7
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
auth-zone:
name: "example.com"
for-upstream: yes
for-downstream: yes
url: "https://127.0.0.1:@TOPORT@/example.com.zone"
+16
View File
@@ -0,0 +1,16 @@
BaseName: auth_https_origin
Version: 1.0
Description: Perform https for authority zone with $ORIGIN
CreationDate: Mon 29 September 14:35:40 CEST 2025
Maintainer: dr. W.C.A. Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: auth_https_origin.pre
Post: auth_https_origin.post
Test: auth_https_origin.test
AuxFiles:
Passed:
Failure:
+11
View File
@@ -0,0 +1,11 @@
# #-- auth_https_origin.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 $UNBOUND_PID
kill_pid $PETAL_PID
+34
View File
@@ -0,0 +1,34 @@
# #-- auth_https_origin.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
get_random_port 2
UNBOUND_PORT=$RND_PORT
PETAL_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "PETAL_PORT=$PETAL_PORT" >> .tpkg.var.test
get_make
(cd $PRE; $MAKE petal)
# start https daemon
$PRE/petal -v -a "127.0.0.1" -p $PETAL_PORT >petal.log 2>&1 &
PETAL_PID=$!
echo "PETAL_PID=$PETAL_PID" >> .tpkg.var.test
cat .tpkg.var.test
wait_petal_up petal.log
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$PETAL_PORT'/' < auth_https_origin.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
+63
View File
@@ -0,0 +1,63 @@
# #-- auth_https_origin.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
# do the test
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
if grep SERVFAIL outfile; then
echo "> try again"
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 1
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
if grep SERVFAIL outfile; then
echo "> try again"
sleep 10
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
fi
echo "> cat logfiles"
cat petal.log
cat unbound.log
echo "> check answer"
if grep "1.2.3.4" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
# Test that notify is allowed from the webserver address
get_ldns_notify
echo "> ldns-notify -z example.com"
$LDNS_NOTIFY -p $UNBOUND_PORT -z example.com 127.0.0.1 | tee outfile
if grep "rcode: REFUSED" outfile; then
echo "Not OK"
exit 1
else
echo "OK"
fi
exit 0
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN RSA PRIVATE KEY-----
MIIDfQIBAAKBwQC1xQ/Kca6zszZbcCtdOTIH2Uy2gOy/DfabMUU7TmNPm0dVE0NJ
RuN+Rm304SonpwghfP2/ULZNnuDgpG03/32yI7k/VzG6iA4hiF7tT/KAAWC/+2l1
QCsawCV2bSrFK0VhcZr7ALqXd8vkDaQ867K029ypjOQtAJ85qdO3mERy7TGtdUcu
O6hLeVet419YeQ2F8cfNxn63d7bOzNGLPW5xwaCd3UcgD+Ib0k4xfFvbinvPQUeU
J/i4YDWexFYSL+ECAwEAAQKBwCLXXQl+9O+5AEhSnd1Go1Jh0pSA7eBJOuXQcebG
Rb7ykp+6C4G2NtDziwwPRNdI6wQQQ0sym18RfyVQHydGr78/nbiIbB3HCn5e92Mh
mefzW6ow9Kvm2txLzGKA1lvoyRbNm81jnG/eygi3u7Nqd5PNv+4dHj2RkTlmxOeh
qnDMVP5md8uZPv6lYNnrnIzvLCR5vnPNdVwn89AqzI85IcDZdy0R9ZX4NBbsDgAU
6ig6uXuRXvSGiyJ/OUXSrnogaQJhAOjvkHUhVZQkPOxO90TNH4j0GdKKtbSWxIdz
lKfuJeBAEqs0TL+C6vbS81Xw3W1alyDdUBk3rJMOBqW6Ryq5HNL+j5H+Jfsh7fvc
Yle+5wHGci0P9zCFZCrY8It7n9XFIwJhAMfEi6oJa2G8waPJ1bQhxka82Tf9pnKM
XCn/1BBOFjVIx5F842cpA+zp5a62GENTGYPQTTRBB/2/ZwnW5aIkrlg54AtmbqBZ
Oh+2kJdJQD/tfoVmc5soUE2ScTHadK5RKwJhAN4w9kjkXS+MSZjX0kIMsBIBVkhh
C+aREjJqa9ir7/Ey7RvmLXdYuCxtGLRXp7/R8+rjcK49Tx6O+IRJZe042mfhbq3C
EhS1Tr86f4xXix9EXlDhs9bSxrOgcAN9Dv/opQJhAK7eBcPaav0rVfYh/8emqQHS
3fJ9Pu6WnzbEksWTFS2ff9KDGCx9YspIFJ5TF/oXDAaumGZdZrlgirm6O1kr8tGY
F97i04PZl1+bWAaWQH+1TUNI43m2WFUPE7coG2tb8QJgcddDg9VlXliZqgcETZfJ
kJmYETxrcSn3ao6v116N8yxhEgUgjkmsCTiFgx36iDVnXwK6PIt+sIu8MC7eYNa3
berrv/M21K0LRn20IWRxvUobG070weHCAgkko7fTWgr2
-----END RSA PRIVATE KEY-----
+14
View File
@@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICFzCCAUACCQDO660L5y5LGDANBgkqhkiG9w0BAQUFADAQMQ4wDAYDVQQDEwVw
ZXRhbDAeFw0xMDA5MzAxMzQzMDFaFw0zMDA2MTcxMzQzMDFaMBAxDjAMBgNVBAMT
BXBldGFsMIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQC1xQ/Kca6zszZbcCtd
OTIH2Uy2gOy/DfabMUU7TmNPm0dVE0NJRuN+Rm304SonpwghfP2/ULZNnuDgpG03
/32yI7k/VzG6iA4hiF7tT/KAAWC/+2l1QCsawCV2bSrFK0VhcZr7ALqXd8vkDaQ8
67K029ypjOQtAJ85qdO3mERy7TGtdUcuO6hLeVet419YeQ2F8cfNxn63d7bOzNGL
PW5xwaCd3UcgD+Ib0k4xfFvbinvPQUeUJ/i4YDWexFYSL+ECAwEAATANBgkqhkiG
9w0BAQUFAAOBwQBBkX9KDP2RXbg+xPmdJ4P6CwvA5x1LZwC++ydVx4NlvT0pWicD
ZUnXjcWAJlkeOuUBAqFG7WHTrXpUUAjmdqFVq2yFjteUYBdrFz0RDB2jM9feeKYO
mTgxdZyT9a6humxCxt5VfgT02axLjm/2AqCyFPMbf4PASoJDln01AEuZLZ8Xl2gV
bYHMnHTGoD1Hu6FNEzRgkMC6XT8X3YjHvzQhpc/qL5wEfEsinQGdX4twsuWbf8xd
q7miNnkO8vd0maw=
-----END CERTIFICATE-----
+32 -28
View File
@@ -5,7 +5,10 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
module-config: "cachedb iterator"
ede: yes
ede-serve-expired: yes
cachedb:
backend: "testframe"
@@ -82,7 +85,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -91,7 +94,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
RANGE_END
@@ -111,7 +115,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Get another query in cache to make it expired.
@@ -130,46 +134,46 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; it is now expired
STEP 40 TIME_PASSES ELAPSE 20
STEP 40 TIME_PASSES ELAPSE 200
; cache is expired, and cachedb is expired.
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 30 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; cache is expired, cachedb has no answer
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 90 TRAFFIC
@@ -189,7 +193,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; flush the entry from cache
@@ -210,30 +214,30 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 150 TIME_PASSES ELAPSE 20
STEP 150 TIME_PASSES ELAPSE 200
; flush the entry from cache
STEP 160 FLUSH_MESSAGE www.example.com. IN A
; cache has no answer, cachedb is expired
STEP 170 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 180 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 190 TRAFFIC
@@ -254,7 +258,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; expire the entry in cache
@@ -275,30 +279,30 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 250 TIME_PASSES ELAPSE 20
STEP 250 TIME_PASSES ELAPSE 200
; expire the entry in cache
STEP 260 EXPIRE_MESSAGE www.example.com. IN A
; cache is expired, cachedb is expired
STEP 270 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 280 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 290 TRAFFIC
@@ -319,7 +323,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+31 -26
View File
@@ -4,12 +4,14 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 30
serve-expired-reply-ttl: 123
; at least one second, so we can time skip past the timer in the
; testbound script steps, but also reply within the time.
serve-expired-client-timeout: 1200
module-config: "cachedb iterator"
discard-timeout: 3000
ede: yes
ede-serve-expired: yes
cachedb:
backend: "testframe"
@@ -86,7 +88,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -95,7 +97,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
RANGE_END
@@ -108,7 +111,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.6
www.example.com. 200 IN A 1.2.3.6
ENTRY_END
ENTRY_BEGIN
@@ -117,7 +120,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.7
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.7
ENTRY_END
RANGE_END
@@ -132,7 +136,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.8
www.example.com. 200 IN A 1.2.3.8
ENTRY_END
ENTRY_BEGIN
@@ -141,7 +145,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.9
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.9
ENTRY_END
RANGE_END
@@ -156,7 +161,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.10
www.example.com. 200 IN A 1.2.3.10
ENTRY_END
ENTRY_BEGIN
@@ -165,7 +170,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.11
www2.example.com. 100 IN A 1.2.3.11
ENTRY_END
RANGE_END
@@ -188,7 +193,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Get another query in cache.
@@ -207,7 +212,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; www.example.com and www2.example.com are in cache, www2 in cachedb.
@@ -217,7 +222,7 @@ STEP 40 FLUSH_MESSAGE www2.example.com. IN A
; response from cachedb for www2.
; make 2 seconds pass to decrement the TTL on the response,
; the upstream TTL would be 10, cachedb 8.
; the upstream TTL would be 200, cachedb 198.
STEP 48 TIME_PASSES ELAPSE 2
STEP 50 QUERY
@@ -234,11 +239,11 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 8 IN A 1.2.3.5
www2.example.com. 98 IN A 1.2.3.5
ENTRY_END
; make both cache and cachedb expired
STEP 70 TIME_PASSES ELAPSE 20
STEP 70 TIME_PASSES ELAPSE 200
; www and www2 expired in cache, www2 expired in cachedb.
; the query should now try to resolve and complete within the
@@ -258,11 +263,11 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.7
www2.example.com. 100 IN A 1.2.3.7
ENTRY_END
; expire the data again
STEP 100 TIME_PASSES ELAPSE 20
STEP 100 TIME_PASSES ELAPSE 200
; the query should now try to resolve, but the upstream is not
; responsive for several testbound steps. When the timer expires,
@@ -271,7 +276,7 @@ STEP 100 TIME_PASSES ELAPSE 20
; www2 expired in cache and www2 expired in cachedb.
STEP 110 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
@@ -281,26 +286,26 @@ STEP 112 TIME_PASSES ELAPSE 2
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 30 IN A 1.2.3.7
www2.example.com. 100 IN A 1.2.3.7
ENTRY_END
; make traffic flow to resolve the query, server responds.
STEP 130 TRAFFIC
; expire the data again
STEP 140 TIME_PASSES ELAPSE 20
STEP 140 TIME_PASSES ELAPSE 200
; The client query tries to resolve, but gets no immediate answer,
; so the expired data is used. But the expired data is in cache and
; the query is not in cachedb.
STEP 150 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -310,12 +315,12 @@ STEP 152 TIME_PASSES ELAPSE 2
STEP 160 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
; make traffic flow to resolve the query, server responds.
@@ -337,7 +342,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.11
www2.example.com. 100 IN A 1.2.3.11
ENTRY_END
SCENARIO_END
+25 -22
View File
@@ -5,8 +5,10 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 30
serve-expired-reply-ttl: 123
module-config: "cachedb iterator"
ede: yes
ede-serve-expired: yes
cachedb:
backend: "testframe"
@@ -83,7 +85,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -92,7 +94,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
RANGE_END
@@ -115,7 +118,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Get another query in cache to make it expired.
@@ -134,28 +137,28 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; it is now expired
STEP 40 TIME_PASSES ELAPSE 20
STEP 40 TIME_PASSES ELAPSE 200
; cache is expired, and cachedb is expired.
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 30 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; got an answer from upstream
@@ -173,25 +176,25 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; cache is expired, cachedb has no answer
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 90 TRAFFIC
@@ -211,29 +214,29 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; make both cache and cachedb expired.
STEP 120 TIME_PASSES ELAPSE 20
STEP 120 TIME_PASSES ELAPSE 200
STEP 130 FLUSH_MESSAGE www.example.com. IN A
; cache has no entry and cachedb is expired.
STEP 140 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 150 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
; the name is resolved
@@ -254,7 +257,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+24 -22
View File
@@ -4,7 +4,7 @@ server:
qname-minimisation: no
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 30
serve-expired-reply-ttl: 123
; disable the serve expired client timeout.
serve-expired-client-timeout: 0
@@ -14,6 +14,8 @@ server:
; store for edns subnet content for modules to the right of it.
; this keeps subnet content out of cachedb as global content.
module-config: "subnetcache cachedb iterator"
ede: yes
ede-serve-expired: yes
cachedb:
backend: "testframe"
@@ -105,7 +107,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN CNAME www.initial.com.
www.example.com. 200 IN CNAME www.initial.com.
ENTRY_END
RANGE_END
@@ -118,7 +120,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN CNAME example.foo.com.
www.example.com. 200 IN CNAME example.foo.com.
ENTRY_END
RANGE_END
@@ -131,7 +133,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.initial.com. IN A
SECTION ANSWER
www.initial.com. 10 IN A 1.2.3.4
www.initial.com. 200 IN A 1.2.3.4
ENTRY_END
RANGE_END
@@ -144,7 +146,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
example.foo.com. IN A
SECTION ANSWER
example.foo.com. 10 IN A 1.2.3.5
example.foo.com. 200 IN A 1.2.3.5
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
@@ -166,7 +168,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN CNAME example.foo.com.
www.example.com. 200 IN CNAME example.foo.com.
ENTRY_END
RANGE_END
@@ -179,7 +181,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
example.foo.com. IN A
SECTION ANSWER
example.foo.com. 10 IN A 1.2.3.6
example.foo.com. 200 IN A 1.2.3.6
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
@@ -211,19 +213,19 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN CNAME www.initial.com.
www.initial.com. 10 IN A 1.2.3.4
www.example.com. 200 IN CNAME www.initial.com.
www.initial.com. 200 IN A 1.2.3.4
ENTRY_END
; now valid in cache and valid in cachedb, without subnet.
STEP 30 TIME_PASSES ELAPSE 20
STEP 30 TIME_PASSES ELAPSE 200
; now the cache and cachedb have an expired entry.
; the upstream is updated to CNAME to a subnet zone A record.
STEP 40 QUERY ADDRESS 127.0.0.1
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -231,13 +233,13 @@ ENTRY_END
; the expired answer, while the ECS answer is looked up.
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN CNAME www.initial.com.
www.initial.com. 30 IN A 1.2.3.4
www.example.com. 123 IN CNAME www.initial.com.
www.initial.com. 123 IN A 1.2.3.4
ENTRY_END
; check that subnet has the query in cache.
@@ -256,12 +258,12 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 8 IN CNAME example.foo.com.
example.foo.com. 8 IN A 1.2.3.5
www.example.com. 198 IN CNAME example.foo.com.
example.foo.com. 198 IN A 1.2.3.5
ENTRY_END
; everything is expired, cache, subnetcache and cachedb.
STEP 80 TIME_PASSES ELAPSE 20
STEP 80 TIME_PASSES ELAPSE 200
STEP 90 QUERY ADDRESS 127.0.0.1
ENTRY_BEGIN
@@ -277,8 +279,8 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN CNAME example.foo.com.
example.foo.com. 10 IN A 1.2.3.6
www.example.com. 200 IN CNAME example.foo.com.
example.foo.com. 200 IN A 1.2.3.6
ENTRY_END
; see the entry now in cache, from the subnetcache.
@@ -297,8 +299,8 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 8 IN CNAME example.foo.com.
example.foo.com. 8 IN A 1.2.3.6
www.example.com. 198 IN CNAME example.foo.com.
example.foo.com. 198 IN A 1.2.3.6
ENTRY_END
SCENARIO_END
+32 -28
View File
@@ -5,8 +5,11 @@ server:
minimal-responses: yes
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
;module-config: "subnetcache validator cachedb iterator"
module-config: "validator cachedb iterator"
ede: yes
ede-serve-expired: yes
cachedb:
backend: "testframe"
@@ -83,7 +86,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -92,7 +95,8 @@ REPLY QR AA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
; TTL lower than serve-expired-reply-ttl on purpose
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
RANGE_END
@@ -112,7 +116,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Get another query in cache to make it expired.
@@ -131,48 +135,48 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 10 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; it is now expired
STEP 40 TIME_PASSES ELAPSE 20
STEP 40 TIME_PASSES ELAPSE 200
; cache is expired, and cachedb is expired.
; The expired reply, from cachedb, needs a validation status,
; because the validator module set that validation is needed.
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. 30 IN A 1.2.3.5
www2.example.com. 100 IN A 1.2.3.5
ENTRY_END
; cache is expired, cachedb has no answer
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 90 TRAFFIC
@@ -192,7 +196,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; flush the entry from cache
@@ -213,30 +217,30 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 150 TIME_PASSES ELAPSE 20
STEP 150 TIME_PASSES ELAPSE 200
; flush the entry from cache
STEP 160 FLUSH_MESSAGE www.example.com. IN A
; cache has no answer, cachedb is expired
STEP 170 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 180 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 190 TRAFFIC
@@ -257,7 +261,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; expire the entry in cache
@@ -278,30 +282,30 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
; it is now expired
STEP 250 TIME_PASSES ELAPSE 20
STEP 250 TIME_PASSES ELAPSE 200
; expire the entry in cache
STEP 260 EXPIRE_MESSAGE www.example.com. IN A
; cache is expired, cachedb is expired
STEP 270 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 280 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 1.2.3.4
www.example.com. 123 IN A 1.2.3.4
ENTRY_END
STEP 290 TRAFFIC
@@ -322,7 +326,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+3 -18
View File
@@ -46,25 +46,10 @@ www.example.com. IN A
SECTION ANSWER
ENTRY_END
; enough to pass by the TTL of the servfail answer in cache
; enough to expire the servfail answer in cache
STEP 50 TIME_PASSES ELAPSE 5
; this query triggers a prefetch
STEP 210 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 220 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
ENTRY_END
; Expired SERVFAILS are no longer served from Unbound
; this query gets the 0ttl answer
STEP 230 QUERY
@@ -76,7 +61,7 @@ ENTRY_END
STEP 240 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
+522
View File
@@ -0,0 +1,522 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: yes
; respip is before dns64 in the module list.
module-config: "respip dns64 validator iterator"
dns64-prefix: 64:ff9b::0/96
response-ip: 10.20.30.42/32 always_refuse
response-ip: 10.20.30.43/32 redirect
response-ip-data: 10.20.30.43/32 "A 4.5.6.3"
response-ip: 5.6.7.9/32 redirect
response-ip-data: 5.6.7.9/32 "A 4.5.6.7"
response-ip: 5.6.7.10/32 always_nxdomain
response-ip: 64:ff9b::506:70B/128 redirect
response-ip-data: 64:ff9b::506:70B/128 "AAAA 2001:db8::4"
rpz:
name: "rpz.example.com."
rpz-log: yes
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
32.44.30.20.10.rpz-ip CNAME .
32.12.7.6.5.rpz-ip CNAME .
32.13.7.6.5.rpz-ip A 4.5.6.13
32.14.7.6.5.rpz-ip CNAME alias.example.com.
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test respip and dns64 lookup.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 1000
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. 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. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 1000
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. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. 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
; ns.example.com.
RANGE_BEGIN 0 1000
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
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
www2.example.com. IN A 10.20.30.42
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www3.example.com. IN A
SECTION ANSWER
www3.example.com. IN A 10.20.30.43
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www4.example.com. IN A
SECTION ANSWER
www4.example.com. IN A 10.20.30.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4.example.com. IN A
SECTION ANSWER
ip4.example.com. IN A 5.6.7.8
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-2.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-2.example.com. IN A
SECTION ANSWER
ip4-2.example.com. IN A 5.6.7.9
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-3.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-3.example.com. IN A
SECTION ANSWER
ip4-3.example.com. IN A 5.6.7.10
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-4.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-4.example.com. IN A
SECTION ANSWER
ip4-4.example.com. IN A 5.6.7.11
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-5.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-5.example.com. IN A
SECTION ANSWER
ip4-5.example.com. IN A 5.6.7.12
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-6.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-6.example.com. IN A
SECTION ANSWER
ip4-6.example.com. IN A 5.6.7.13
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-7.example.com. IN AAAA
SECTION ANSWER
; NO AAAA present
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ip4-7.example.com. IN A
SECTION ANSWER
ip4-7.example.com. IN A 5.6.7.14
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
alias.example.com. IN A
SECTION ANSWER
alias.example.com. IN A 4.5.6.14
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; The query is unaltered.
STEP 10 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
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www2.example.com. IN A
ENTRY_END
; The query is altered by respip, A query refused.
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA REFUSED
SECTION QUESTION
www2.example.com. IN A
SECTION ANSWER
ENTRY_END
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www3.example.com. IN A
ENTRY_END
; The query is altered by respip, with redirect.
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www3.example.com. IN A
SECTION ANSWER
www3.example.com. IN A 4.5.6.3
ENTRY_END
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4.example.com. IN AAAA
ENTRY_END
; synthesize from A record 5.6.7.8 with DNS64.
STEP 70 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4.example.com. IN AAAA
SECTION ANSWER
ip4.example.com. IN AAAA 64:ff9b::506:708
ENTRY_END
STEP 80 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-2.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is altered by respip, with redirect.
; and the respip result is dns64 synthesized.
STEP 90 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-2.example.com. IN AAAA
SECTION ANSWER
ip4-2.example.com. IN AAAA 64:ff9b::405:607
ENTRY_END
STEP 100 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-3.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is altered by respip, with nxdomain.
; and the respip result is dns64 synthesized.
STEP 110 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-3.example.com. IN AAAA
SECTION ANSWER
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
STEP 120 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-4.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is synthesized, respip operates on the
; synthesized AAAA result, and makes a redirect.
STEP 130 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-4.example.com. IN AAAA
SECTION ANSWER
ip4-4.example.com. IN AAAA 2001:db8::4
ENTRY_END
STEP 140 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www4.example.com. IN A
ENTRY_END
; The query is blocked by rpz.
STEP 150 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
www4.example.com. IN A
SECTION ANSWER
ENTRY_END
STEP 160 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-5.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is blocked by RPZ.
STEP 170 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-5.example.com. IN AAAA
SECTION ANSWER
SECTION AUTHORITY
example.com. IN SOA a. b. 1 2 3 4 5
ENTRY_END
STEP 180 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-6.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is redirected by RPZ.
STEP 190 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-6.example.com. IN AAAA
SECTION ANSWER
ip4-6.example.com. AAAA 64:ff9b::405:60d
ENTRY_END
STEP 200 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
ip4-7.example.com. IN AAAA
ENTRY_END
; The dns64 subquery is a CNAME by RPZ.
; that CNAME resolves to an A record, dns64 synthesizes that A record.
STEP 210 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
ip4-7.example.com. IN AAAA
SECTION ANSWER
ip4-7.example.com. CNAME alias.example.com.
alias.example.com. AAAA 64:ff9b::405:60e
ENTRY_END
SCENARIO_END
+25 -22
View File
@@ -5,8 +5,11 @@ server:
# We do not want only serve-expired because fetches from that
# apply a generous PREFETCH_LEEWAY.
serve-expired-client-timeout: 1000
serve-expired-reply-ttl: 123
# So that we can only have to give one SERVFAIL answer.
outbound-msg-retry: 0
ede: yes
ede-serve-expired: yes
forward-zone: name: "." forward-addr: 216.0.0.1
CONFIG_END
@@ -35,11 +38,11 @@ ENTRY_BEGIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 5 IN A 10.20.30.40
www.example.com. 205 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 210 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 10.20.30.50
ns.example.com. 210 IN A 10.20.30.50
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
@@ -48,15 +51,15 @@ ENTRY_BEGIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 5 IN A 10.20.30.40
www.example.com. 205 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 210 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 10.20.30.50
ns.example.com. 210 IN A 10.20.30.50
ENTRY_END
; Wait for the A RRSET to expire.
STEP 5 TIME_PASSES ELAPSE 6
STEP 5 TIME_PASSES ELAPSE 205
STEP 6 QUERY
ENTRY_BEGIN
@@ -80,14 +83,14 @@ ENTRY_BEGIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 5 IN A 10.20.30.40
www.example.com. 205 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 210 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 10.20.30.50
ns.example.com. 210 IN A 10.20.30.50
ENTRY_END
; The cached NS related RRSETs will not be overwritten by the fresh answer.
; The message should have a TTL of 4 instead of 5 from above.
; The message should have a TTL of 5 instead of 205 from above.
STEP 9 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
@@ -95,11 +98,11 @@ ENTRY_BEGIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 5 IN A 10.20.30.40
www.example.com. 205 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 4 IN NS ns.example.com.
example.com. 5 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 4 IN A 10.20.30.50
ns.example.com. 5 IN A 10.20.30.50
ENTRY_END
; Wait for the NS RRSETs to expire.
@@ -107,7 +110,7 @@ STEP 10 TIME_PASSES ELAPSE 5
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -129,23 +132,23 @@ ENTRY_BEGIN
ENTRY_END
; The SERVFAIL will trigger the serve-expired-client-timeout logic to try and
; replace the SERVFAIL with a possible cached (expired) answer.
; The A RRSET would be at 0TTL left (not expired) but the message should have
; been updated to use a TTL of 4 so expired by now.
; The A RRSET would be at 200 left but the message should have
; been updated to use a TTL of 5 so expired by now.
; If the message TTL was not updated (bug), this message would be treated as
; non-expired and the now expired NS related RRSETs would fail sanity checks
; for non-expired messages. The result would be SERVFAIL here.
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA
MATCH all ttl ede=3
REPLY QR RD RA DO
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 0 IN A 10.20.30.40
www.example.com. 200 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 30 IN NS ns.example.com.
example.com. 123 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 30 IN A 10.20.30.50
ns.example.com. 123 IN A 10.20.30.50
ENTRY_END
SCENARIO_END
+9 -8
View File
@@ -5,6 +5,7 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
access-control: 127.0.0.1/32 allow_snoop
ede: yes
ede-serve-expired: yes
@@ -44,7 +45,7 @@ RANGE_BEGIN 0 100
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -68,15 +69,15 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 11 TIME_PASSES ELAPSE 3601
; Wait for the TTL to expire (for all RRSets; default 3600)
STEP 11 TIME_PASSES ELAPSE 3600
; Query again without RD bit
STEP 30 QUERY
@@ -94,11 +95,11 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 30 IN A 5.6.7.8
example.com. 123 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 30 IN NS ns.example.com.
example.com. 123 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 30 IN A 1.2.3.4
ns.example.com. 123 IN A 1.2.3.4
ENTRY_END
; Query with RD bit (the record should have been prefetched)
@@ -116,7 +117,7 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
+12 -11
View File
@@ -5,6 +5,7 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
@@ -48,9 +49,9 @@ RANGE_BEGIN 30 100
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -62,9 +63,9 @@ RANGE_BEGIN 30 100
SECTION ANSWER
0ttl.example.com. 0 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
RANGE_END
@@ -106,13 +107,13 @@ ENTRY_BEGIN
example.com IN SOA ns.example.com dns.example.com 1 7200 3600 2419200 10
ENTRY_END
; Wait for the NXDOMAIN to expire
STEP 31 TIME_PASSES ELAPSE 32
; Wait for the NODATA to expire
STEP 31 TIME_PASSES ELAPSE 10
; Query again
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
0ttl.example.com. IN A
ENTRY_END
@@ -120,8 +121,8 @@ ENTRY_END
; Check that we get the cached NODATA
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
MATCH all ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
0ttl.example.com. IN A
SECTION AUTHORITY
@@ -146,9 +147,9 @@ ENTRY_BEGIN
SECTION ANSWER
0ttl.example.com. 0 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+2 -2
View File
@@ -107,7 +107,7 @@ ENTRY_BEGIN
ENTRY_END
; Wait for the NXDOMAIN to expire
STEP 31 TIME_PASSES ELAPSE 32
STEP 31 TIME_PASSES ELAPSE 10
; Query again
STEP 40 QUERY
@@ -117,7 +117,7 @@ ENTRY_BEGIN
0ttl.example.com. IN A
ENTRY_END
; Check that we get the cached NXDOMAIN
; Check that we get the newly cached NXDOMAIN
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
+1 -1
View File
@@ -101,7 +101,7 @@ ENTRY_BEGIN
ENTRY_END
; Wait for the SERVFAIL to expire
STEP 31 TIME_PASSES ELAPSE 32
STEP 31 TIME_PASSES ELAPSE 10
; Query again
STEP 40 QUERY
+2 -2
View File
@@ -48,7 +48,7 @@ RANGE_BEGIN 0 20
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -72,7 +72,7 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
-110
View File
@@ -1,110 +0,0 @@
; config options
server:
module-config: "validator iterator"
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 1
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test that no prefetch is triggered for 0TTL records with serve-expired and client-timeout enabled
; Scenario overview:
; - query for example.com. IN A
; - check that we get an answer for example.com. IN A with the correct TTL
; - query again right at the 0TTL cached entry
; - check that we get the cached answer with no prefetching triggered
; 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
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 10
ADDRESS 1.2.3.4
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; Query with RD flag
STEP 0 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we got the correct answer (should be cached)
STEP 1 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire and produce a 0 TTL cached record.
STEP 10 TIME_PASSES ELAPSE 10
; Query again
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
; This should come from the cache with no prefetch triggered (earlier bug).
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 0 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 3590 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3590 IN A 1.2.3.4
ENTRY_END
; If a prefetch triggers the test will fail with 'messages pending'.
SCENARIO_END
+15 -15
View File
@@ -40,9 +40,9 @@ RANGE_BEGIN 0 20
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -52,11 +52,11 @@ RANGE_BEGIN 0 20
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
RANGE_END
@@ -84,11 +84,11 @@ RANGE_BEGIN 50 100
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
RANGE_END
@@ -108,15 +108,15 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 11 TIME_PASSES ELAPSE 11
STEP 11 TIME_PASSES ELAPSE 200
; Query again
STEP 30 QUERY
@@ -209,11 +209,11 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+69 -6
View File
@@ -18,8 +18,11 @@ SCENARIO_BEGIN Test serve-expired with reply-ttl
; Scenario overview:
; - query for example.com. IN A
; - check that we get an answer for example.com. IN A with the correct TTL
; - query for shorterttl.example.com. IN A
; - check that we get an answer for shorterttl.example.com. IN A with the correct TTL
; - query again right after the TTL expired
; - check that we get the expired cached answer with the configured TTL
; - check that we get the expired cached answer for example.com. with the configured TTL
; - check that we get the expired cached answer for shorterttl.example.com. with its own original TTL since it is shorter than the configured one
; ns.example.com.
RANGE_BEGIN 0 100
@@ -43,7 +46,21 @@ RANGE_BEGIN 0 100
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
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
shorterttl.example.com. IN A
SECTION ANSWER
shorterttl.example.com. 121 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -67,15 +84,37 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 11 TIME_PASSES ELAPSE 3601
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
shorterttl.example.com. IN A
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
shorterttl.example.com. IN A
SECTION ANSWER
shorterttl.example.com. 121 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire (for all rrsets; default 3600)
STEP 20 TIME_PASSES ELAPSE 3600
; Query again
STEP 30 QUERY
@@ -100,7 +139,31 @@ ENTRY_BEGIN
ns.example.com. 123 A 1.2.3.4
ENTRY_END
; Query again for shorter ttl
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
shorterttl.example.com. IN A
ENTRY_END
; Check that we got a stale answer
; Note: auth, additional rrsets are already updated from previous recursion.
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
shorterttl.example.com. IN A
SECTION ANSWER
shorterttl.example.com. 121 A 5.6.7.8
SECTION AUTHORITY
example.com. 3600 NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3600 A 1.2.3.4
ENTRY_END
; Give time for the pending query to get answered
STEP 41 TRAFFIC
STEP 61 TRAFFIC
SCENARIO_END
+1 -1
View File
@@ -78,7 +78,7 @@ ENTRY_BEGIN
ENTRY_END
; Wait for the TTL to expire + serve-expired-ttl
STEP 11 TIME_PASSES ELAPSE 3611
STEP 11 TIME_PASSES ELAPSE 3610
; Query again
STEP 30 QUERY
+3 -3
View File
@@ -36,7 +36,7 @@ REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 0.0.0.0
www.example.com. 200 IN A 0.0.0.0
ENTRY_END
STEP 3 CHECK_ANSWER
@@ -46,11 +46,11 @@ REPLY QR RA RD NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 0.0.0.0
www.example.com. 200 IN A 0.0.0.0
ENTRY_END
; Expire the record (+ serve-expired-ttl)
STEP 4 TIME_PASSES ELAPSE 12
STEP 4 TIME_PASSES ELAPSE 201
STEP 5 QUERY
ENTRY_BEGIN
+7 -7
View File
@@ -65,11 +65,11 @@ RANGE_BEGIN 11 100
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
RANGE_END
@@ -118,15 +118,15 @@ ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
example.com. 200 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ns.example.com. 200 IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 30 TIME_PASSES ELAPSE 11
STEP 30 TIME_PASSES ELAPSE 200
; Query with RD flag
STEP 40 QUERY
+11 -8
View File
@@ -7,12 +7,15 @@ server:
target-fetch-policy: "0 0 0 0 0"
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
client-subnet-always-forward: yes
module-config: "subnetcache iterator"
verbosity: 3
access-control: 127.0.0.1 allow_snoop
qname-minimisation: no
minimal-responses: no
ede: yes
ede-serve-expired: yes
stub-zone:
name: "."
@@ -100,7 +103,7 @@ RANGE_BEGIN 0 100
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
www.example.com. 200 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -131,11 +134,11 @@ ns.example.com. IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 3 TIME_PASSES ELAPSE 20
STEP 3 TIME_PASSES ELAPSE 200
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -143,16 +146,16 @@ ENTRY_END
; This record came from the global cache and a prefetch was triggered
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 10.20.30.40
www.example.com. 123 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 3580 IN NS ns.example.com.
example.com. 3400 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3580 IN A 1.2.3.4
ns.example.com. 3400 IN A 1.2.3.4
ENTRY_END
STEP 13 CHECK_OUT_QUERY
+16 -13
View File
@@ -16,7 +16,11 @@ server:
serve-expired: yes
serve-expired-client-timeout: 0
serve-expired-ttl: 1
prefetch: yes
serve-expired-client-timeout: 0
serve-expired-reply-ttl: 123
#prefetch: yes #not needed, expired answers also trigger refetch
ede: yes
ede-serve-expired: yes
stub-zone:
name: "."
@@ -113,7 +117,7 @@ RANGE_BEGIN 0 10
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
www.example.com. 200 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -147,7 +151,7 @@ RANGE_BEGIN 11 100
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
www.example.com. 200 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -178,7 +182,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 200 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
@@ -186,11 +190,11 @@ ns.example.com. IN A 1.2.3.4
ENTRY_END
; Try to trigger a prefetch with expired data
STEP 3 TIME_PASSES ELAPSE 11
STEP 3 TIME_PASSES ELAPSE 200
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -198,19 +202,18 @@ ENTRY_END
; This expired record came from the global cache and a prefetch is triggered.
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 30 IN A 10.20.30.40
www.example.com. 123 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 3589 IN NS ns.example.com.
example.com. 3400 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 3589 IN A 1.2.3.4
ns.example.com. 3400 IN A 1.2.3.4
ENTRY_END
;STEP 13 TRAFFIC
; Allow enough time to pass so that the expired record from the global cache
; cannot be used anymore.
STEP 14 TIME_PASSES ELAPSE 1
@@ -232,7 +235,7 @@ REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 9 IN A 10.20.30.40
www.example.com. 199 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 3599 IN NS ns.example.com.
SECTION ADDITIONAL
+269
View File
@@ -0,0 +1,269 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
prefetch: no
serve-expired: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test TTL for the last zero second of cached messages.
; 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
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. 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 A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN A
SECTION ANSWER
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN A
SECTION ANSWER
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 300
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. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. 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 A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
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 AA 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 AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com
RANGE_BEGIN 100 300
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA REFUSED
SECTION QUESTION
example.com. IN NS
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA REFUSED
SECTION QUESTION
ns.example.com. IN A
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA REFUSED
SECTION QUESTION
ns.example.com. IN AAAA
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR REFUSED
SECTION QUESTION
www.example.com. IN A
ENTRY_END
RANGE_END
STEP 1 TIME_PASSES ELAPSE 10
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 1.2.3.4
ENTRY_END
STEP 30 TIME_PASSES ELAPSE 5
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 5 IN A 1.2.3.4
ENTRY_END
STEP 60 TIME_PASSES ELAPSE 3
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 2 IN A 1.2.3.4
ENTRY_END
STEP 90 TIME_PASSES ELAPSE 1
STEP 100 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 110 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 1 IN A 1.2.3.4
ENTRY_END
STEP 120 TIME_PASSES ELAPSE 1
STEP 130 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 140 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
ENTRY_END
SCENARIO_END
+3
View File
@@ -129,6 +129,7 @@ config_create(void)
cfg->tls_cert_bundle = NULL;
cfg->tls_win_cert = 0;
cfg->tls_use_sni = 1;
cfg->tls_use_system_policy_versions = 0;
cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit;
cfg->http_max_streams = 100;
@@ -629,6 +630,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STR("tls-ciphers:", tls_ciphers)
else S_STR("tls-ciphersuites:", tls_ciphersuites)
else S_YNO("tls-use-sni:", tls_use_sni)
else S_YNO("tls-use-system-policy-versions:", tls_use_system_policy_versions)
else S_NUMBER_NONZERO("https-port:", https_port)
else S_STR("http-endpoint:", http_endpoint)
else S_NUMBER_NONZERO("http-max-streams:", http_max_streams)
@@ -1180,6 +1182,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_STR(opt, "tls-ciphers", tls_ciphers)
else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
else O_YNO(opt, "tls-use-sni", tls_use_sni)
else O_YNO(opt, "tls-use-system-policy-versions", tls_use_system_policy_versions)
else O_DEC(opt, "https-port", https_port)
else O_STR(opt, "http-endpoint", http_endpoint)
else O_UNS(opt, "http-max-streams", http_max_streams)
+2
View File
@@ -149,6 +149,8 @@ struct config_file {
char* tls_ciphersuites;
/** if SNI is to be used */
int tls_use_sni;
/** if all TLS versions can be used; based on system policy (if any) */
int tls_use_system_policy_versions;
/** port on which to provide DNS over HTTPS service */
int https_port;
+1
View File
@@ -262,6 +262,7 @@ tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) }
tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) }
tls-use-sni{COLON} { YDVAR(1, VAR_TLS_USE_SNI) }
tls-use-system-policy-versions{COLON} { YDVAR(1, VAR_TLS_USE_SYSTEM_POLICY_VERSIONS) }
https-port{COLON} { YDVAR(1, VAR_HTTPS_PORT) }
http-endpoint{COLON} { YDVAR(1, VAR_HTTP_ENDPOINT) }
http-max-streams{COLON} { YDVAR(1, VAR_HTTP_MAX_STREAMS) }
+11
View File
@@ -202,6 +202,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE
%token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
%token VAR_TLS_USE_SYSTEM_POLICY_VERSIONS
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
@@ -350,6 +351,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_tls_ciphersuites | server_tls_session_ticket_keys |
server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie |
server_tls_use_sni | server_edns_client_string |
server_tls_use_system_policy_versions |
server_edns_client_string_opcode | server_nsid |
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
@@ -1160,6 +1162,15 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG
free($2);
}
;
server_tls_use_system_policy_versions: VAR_TLS_USE_SYSTEM_POLICY_VERSIONS STRING_ARG
{
OUTYY(("P(server_tls_use_system_policy_versions:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->tls_use_system_policy_versions = (strcmp($2, "yes")==0);
free($2);
}
;
server_https_port: VAR_HTTPS_PORT STRING_ARG
{
OUTYY(("P(server_https_port:%s)\n", $2));
+25 -9
View File
@@ -496,10 +496,18 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
return r;
sldns_buffer_write(pkt, &key->rk.type, 2);
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
if(data->rr_ttl[j] < adjust)
if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) {
sldns_buffer_write_u32(pkt, 0);
} else if(adjust == 0) {
sldns_buffer_write_u32(pkt, data->rr_ttl[j]);
} else if(TTL_IS_EXPIRED(data->rr_ttl[j], adjust)) {
sldns_buffer_write_u32(pkt,
SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust);
EXPIRED_REPLY_TTL_CALC(
data->rr_ttl[j], data->ttl_add));
} else {
sldns_buffer_write_u32(pkt,
data->rr_ttl[j] - adjust);
}
if(c) {
if((r=compress_rdata(pkt, data->rr_data[j],
data->rr_len[j], region, tree, c,
@@ -533,10 +541,18 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
}
sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG);
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
if(data->rr_ttl[i] < adjust)
if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) {
sldns_buffer_write_u32(pkt, 0);
} else if(adjust == 0) {
sldns_buffer_write_u32(pkt, data->rr_ttl[i]);
} else if(TTL_IS_EXPIRED(data->rr_ttl[i], adjust)) {
sldns_buffer_write_u32(pkt,
SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0);
else sldns_buffer_write_u32(pkt, data->rr_ttl[i]-adjust);
EXPIRED_REPLY_TTL_CALC(
data->rr_ttl[i], data->ttl_add));
} else {
sldns_buffer_write_u32(pkt,
data->rr_ttl[i] - adjust);
}
/* rrsig rdata cannot be compressed, perform 100+ byte
* memcopy. */
sldns_buffer_write(pkt, data->rr_data[i],
@@ -993,10 +1009,10 @@ attach_edns_record(sldns_buffer* pkt, struct edns_data* edns)
attach_edns_record_max_msg_sz(pkt, edns, edns->udp_size);
}
int
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
int
reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow,
int cached, struct regional* region, uint16_t udpsize,
int cached, struct regional* region, uint16_t udpsize,
struct edns_data* edns, int dnssec, int secure)
{
uint16_t flags;
+2 -2
View File
@@ -66,9 +66,9 @@ struct edns_data;
* @param secure: if 1, the AD bit is set in the reply.
* @return: 0 on error (server failure).
*/
int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
uint16_t id, uint16_t qflags, struct sldns_buffer* dest, time_t timenow,
int cached, struct regional* region, uint16_t udpsize,
int cached, struct regional* region, uint16_t udpsize,
struct edns_data* edns, int dnssec, int secure);
/**
+10
View File
@@ -1383,3 +1383,13 @@ msgparse_rrset_remove_rr(const char* str, sldns_buffer* pkt, struct rrset_parse*
* the rr->next works fine to continue. */
return rrset->rr_count == 0;
}
#ifdef UNBOUND_DEBUG
time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add) {
/* Check that we are serving expired when this is called */
/* ttl (absolute) should be later than ttl_add */
log_assert(SERVE_EXPIRED && ttl_add <= ttl);
return (SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ?
SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add));
}
#endif
+25
View File
@@ -98,6 +98,31 @@ extern time_t SERVE_EXPIRED_REPLY_TTL;
/** If we serve the original TTL or decrementing TTLs */
extern int SERVE_ORIGINAL_TTL;
/** calculate the prefetch TTL as 90% of original. Calculation
* without numerical overflow (uin32_t) */
#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10)
/* caclulate the TTL used for expired answers to somewhat make sense wrt the
* original TTL; don't reply with higher TTL than the original */
#ifdef UNBOUND_DEBUG
time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add);
#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \
debug_expired_reply_ttl_calc(ttl, ttl_add)
#else
#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \
(SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ? \
SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add))
#endif
/** Update the reply_info TTL from an RRSet's TTL, essentially keeping the TTL
* sane with all the (progressively added) rrsets to the message */
#define UPDATE_TTL_FROM_RRSET(ttl, rrsetttl) \
((ttl) = ((ttl) < (rrsetttl)) ? (ttl) : (rrsetttl))
/** Check if TTL is expired. 0 TTL is considered expired.
* Used mainly to identify parts of the code that do this comparison. */
#define TTL_IS_EXPIRED(ttl, now) ((ttl) <= (now))
/**
* Data stored in scratch pad memory during parsing.
* Stores the data that will enter into the msgreply and packet result.
+51 -23
View File
@@ -178,9 +178,9 @@ reply_info_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
int
reply_info_can_answer_expired(struct reply_info* rep, time_t timenow)
{
log_assert(rep->ttl < timenow);
log_assert(TTL_IS_EXPIRED(rep->ttl, timenow));
/* Really expired */
if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow) return 0;
if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)) return 0;
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN &&
@@ -188,12 +188,13 @@ reply_info_can_answer_expired(struct reply_info* rep, time_t timenow)
return 1;
}
int reply_info_could_use_expired(struct reply_info* rep, time_t timenow)
int
reply_info_could_use_expired(struct reply_info* rep, time_t timenow)
{
log_assert(rep->ttl < timenow);
log_assert(TTL_IS_EXPIRED(rep->ttl, timenow));
/* Really expired */
if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow &&
!SERVE_EXPIRED_TTL_RESET) return 0;
if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)
&& !SERVE_EXPIRED_TTL_RESET) return 0;
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN &&
@@ -229,7 +230,7 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
}
/** find the minimumttl in the rdata of SOA record */
static time_t
static uint32_t
soa_find_minttl(struct rr_parse* rr)
{
uint16_t rlen = sldns_read_uint16(rr->ttl_data+4);
@@ -237,7 +238,7 @@ soa_find_minttl(struct rr_parse* rr)
return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */
/* minimum TTL is the last 32bit value in the rdata of the record */
/* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/
return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4);
return sldns_read_uint32(rr->ttl_data+6+rlen-4);
}
/** do the rdata copy */
@@ -247,37 +248,40 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
sldns_pkt_section section)
{
uint16_t pkt_len;
uint32_t ttl;
const sldns_rr_descriptor* desc;
*rr_ttl = sldns_read_uint32(rr->ttl_data);
ttl = sldns_read_uint32(rr->ttl_data);
/* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */
if((*rr_ttl & 0x80000000U))
*rr_ttl = 0;
/* RFC 8767 Section 4. values with high-order bit as positive, not 0.
+ * As such, it will be capped by MAX_TTL below. */
if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) {
/* negative response. see if TTL of SOA record larger than the
* minimum-ttl in the rdata of the SOA record */
if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr);
if(ttl > soa_find_minttl(rr)) ttl = soa_find_minttl(rr);
if(!SERVE_ORIGINAL_TTL) {
/* If MIN_NEG_TTL is configured skip setting MIN_TTL */
if(MIN_NEG_TTL <= 0 && *rr_ttl < MIN_TTL) {
*rr_ttl = MIN_TTL;
if(MIN_NEG_TTL <= 0 && ttl < MIN_TTL) {
ttl = MIN_TTL;
}
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
if(ttl > MAX_TTL) ttl = MAX_TTL;
}
/* MAX_NEG_TTL overrides the min and max ttl of everything
* else; it is for a more specific record */
if(*rr_ttl > MAX_NEG_TTL) *rr_ttl = MAX_NEG_TTL;
if(ttl > MAX_NEG_TTL) ttl = MAX_NEG_TTL;
/* MIN_NEG_TTL overrides the min and max ttl of everything
* else if configured; it is for a more specific record */
if(MIN_NEG_TTL > 0 && *rr_ttl < MIN_NEG_TTL) {
*rr_ttl = MIN_NEG_TTL;
if(MIN_NEG_TTL > 0 && ttl < MIN_NEG_TTL) {
ttl = MIN_NEG_TTL;
}
} else if(!SERVE_ORIGINAL_TTL) {
if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL;
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
if(ttl < MIN_TTL) ttl = MIN_TTL;
if(ttl > MAX_TTL) ttl = MAX_TTL;
}
if(*rr_ttl < data->ttl)
data->ttl = *rr_ttl;
if(ttl < data->ttl)
data->ttl = ttl;
/* We have concluded the TTL checks */
*rr_ttl = (time_t)ttl;
if(rr->outside_packet) {
/* uncompressed already, only needs copy */
@@ -481,6 +485,7 @@ parse_copy_decompress_rrset(sldns_buffer* pkt, struct msg_parse* msg,
pk->entry.key = (void*)pk;
pk->entry.hash = pset->hash;
data->trust = get_rrset_trust(msg, pset);
pk->rk.flags |= (data->ttl == 0) ? PACKED_RRSET_UPSTREAM_0TTL : 0;
return 1;
}
@@ -617,6 +622,29 @@ reply_info_set_ttls(struct reply_info* rep, time_t timenow)
}
}
void
reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add)
{
size_t i, j;
rep->ttl = ttl;
rep->prefetch_ttl = PREFETCH_TTL_CALC(ttl);
rep->serve_expired_ttl = ttl + SERVE_EXPIRED_TTL;
/* Don't set rep->serve_expired_norec_ttl; this should only be set
* on cached records when encountering an error */
log_assert(rep->serve_expired_norec_ttl == 0);
for(i=0; i<rep->rrset_count; i++) {
struct packed_rrset_data* data = (struct packed_rrset_data*)
rep->ref[i].key->entry.data;
if(i>0 && rep->ref[i].key == rep->ref[i-1].key)
continue;
data->ttl = ttl;
for(j=0; j<data->count + data->rrsig_count; j++) {
data->rr_ttl[j] = ttl;
}
data->ttl_add = ttl_add;
}
}
void
reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc)
{
@@ -1129,7 +1157,7 @@ int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
prevp = list;
while(*prevp != NULL)
prevp = &((*prevp)->next);
verbose(VERB_ALGO, "attached EDE code: %d with message: %s", code, (txt?txt:"\"\""));
verbose(VERB_ALGO, "attached EDE code: %d with message: '%s'", code, (txt?txt:""));
*prevp = opt;
return 1;
}
+17 -9
View File
@@ -60,10 +60,6 @@ struct local_rrset;
struct dns_msg;
enum comm_point_type;
/** calculate the prefetch TTL as 90% of original. Calculation
* without numerical overflow (uin32_t) */
#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10)
/**
* Structure to store query information that makes answers to queries
* different.
@@ -340,6 +336,15 @@ void reply_info_sortref(struct reply_info* rep);
*/
void reply_info_set_ttls(struct reply_info* rep, time_t timenow);
/**
* Set TTLs inside the replyinfo to the given absolute values.
* @param rep: reply info. rrsets must be filled in.
* Also refs must be filled in.
* @param ttl: absolute ttl value to be set.
* @param ttl_add: the current time to be used verbatim for ttl_add in the rrsets.
*/
void reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add);
/**
* Delete reply_info and packed_rrsets (while they are not yet added to the
* hashtables.). Returns rrsets to the alloc cache.
@@ -572,7 +577,7 @@ void log_query_info(enum verbosity_value v, const char* str,
struct query_info* qinf);
/**
* Append edns option to edns option list
* Append edns option to edns option list.
* @param list: the edns option list to append the edns option to.
* @param code: the edns option's code.
* @param len: the edns option's length.
@@ -584,20 +589,23 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
uint8_t* data, struct regional* region);
/**
* Append edns EDE option to edns options list
* Append edns EDE option to edns options list.
* We need ATTR_NONSTRING because we are trimming the trailing \0 of static
* string (TXT) when assigning to ede.text; it silences compiler nonstring
* warnings.
* @param LIST: the edns option list to append the edns option to.
* @param REGION: region to allocate the new edns option.
* @param CODE: the EDE code.
* @param TXT: Additional text for the option
* @param TXT: Additional text for the option.
*/
#define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT) \
do { \
struct { \
uint16_t code; \
char text[sizeof(TXT) - 1]; \
char ATTR_NONSTRING(text[sizeof(TXT) - 1]) ; \
} ede = { htons(CODE), TXT }; \
verbose(VERB_ALGO, "attached EDE code: %d with" \
" message: %s", CODE, TXT); \
" message: '%s'", CODE, TXT); \
edns_opt_list_append((LIST), LDNS_EDNS_EDE, \
sizeof(uint16_t) + sizeof(TXT) - 1, \
(void *)&ede, (REGION)); \
+22 -14
View File
@@ -336,10 +336,9 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key,
struct ub_packed_rrset_key* ck = regional_alloc(region,
sizeof(struct ub_packed_rrset_key));
struct packed_rrset_data* d;
struct packed_rrset_data* data = (struct packed_rrset_data*)
key->entry.data;
struct packed_rrset_data* data = key->entry.data;
size_t dsize, i;
time_t adjust = 0;
time_t now_control;
if(!ck)
return NULL;
ck->id = key->id;
@@ -352,22 +351,31 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key,
if(!ck->rk.dname)
return NULL;
dsize = packed_rrset_sizeof(data);
d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize);
d = regional_alloc_init(region, data, dsize);
if(!d)
return NULL;
ck->entry.data = d;
packed_rrset_ptr_fixup(d);
/* make TTLs relative - once per rrset */
adjust = SERVE_ORIGINAL_TTL ? data->ttl_add : now;
for(i=0; i<d->count + d->rrsig_count; i++) {
if(d->rr_ttl[i] < adjust)
d->rr_ttl[i] = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
else d->rr_ttl[i] -= adjust;
/* make TTLs relative - once per rr */
if(now > 0) {
/* NS RRSets may be here with ttl_add higher than now because
* of the novel ghost attack mitigation i.e., using the
* qstarttime for NS RRSets. In that case make sure that the
* returned TTL is not higher than the original one. */
log_assert(d->ttl_add <= now ||
(ntohs(key->rk.type) == LDNS_RR_TYPE_NS));
now_control = SERVE_ORIGINAL_TTL ? data->ttl_add
: (d->ttl_add > now ? d->ttl_add : now );
for(i=0; i<d->count + d->rrsig_count; i++) {
if(TTL_IS_EXPIRED(d->rr_ttl[i], now_control)) {
d->rr_ttl[i] = EXPIRED_REPLY_TTL_CALC(d->rr_ttl[i], data->ttl_add);
} else d->rr_ttl[i] -= now_control;
}
if(TTL_IS_EXPIRED(d->ttl, now_control)) {
d->ttl = EXPIRED_REPLY_TTL_CALC(d->ttl, data->ttl_add);
} else d->ttl -= now_control;
d->ttl_add = 0; /* TTLs have been made relative */
}
if(d->ttl < adjust)
d->ttl = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0;
else d->ttl -= adjust;
d->ttl_add = 0; /* TTLs have been made relative */
return ck;
}
+3
View File
@@ -70,6 +70,8 @@ typedef uint64_t rrset_id_type;
#define PACKED_RRSET_RPZ 0x8
/** this rrset is A/AAAA and is an unverified glue record */
#define PACKED_RRSET_UNVERIFIED_GLUE 0x10
/** this rrset has a 0TTL from upstream */
#define PACKED_RRSET_UPSTREAM_0TTL 0x20
/** number of rrs and rrsets for integer overflow protection. More than
* this is not really possible (64K packet has much less RRs and RRsets) in
@@ -99,6 +101,7 @@ struct packed_rrset_key {
* o PACKED_RRSET_FIXEDTTL (not supposed to be cached)
* o PACKED_RRSET_RPZ
* o PACKED_RRSET_UNVERIFIED_GLUE
* o PACKED_RRSET_UPSTREAM_0TTL (not supposed to be cached)
*/
uint32_t flags;
/** the rrset type in network format */
+4 -3
View File
@@ -382,7 +382,8 @@ fptr_whitelist_modenv_detach_subs(void (*fptr)(
int
fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq))
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq))
{
if(fptr == &mesh_attach_sub) return 1;
return 0;
@@ -391,8 +392,8 @@ fptr_whitelist_modenv_attach_sub(int (*fptr)(
int
fptr_whitelist_modenv_add_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub))
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub))
{
if(fptr == &mesh_add_sub) return 1;
return 0;
+5 -3
View File
@@ -233,7 +233,8 @@ int fptr_whitelist_modenv_detach_subs(void (*fptr)(
*/
int fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq));
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq));
/**
* Check function pointer whitelist for module_env add_sub callback values.
@@ -242,8 +243,9 @@ int fptr_whitelist_modenv_attach_sub(int (*fptr)(
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_add_sub(int (*fptr)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime, int valrec,
struct module_qstate** newq, struct mesh_state** sub));
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub));
/**
* Check function pointer whitelist for module_env kill_sub callback values.
*
+10 -5
View File
@@ -412,6 +412,8 @@ struct module_env {
* @param qstate: the state to find mesh state, and that wants to
* receive the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect
* IP-based actions that apply to the query result.
* @param qflags: what flags to use (RD, CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: validation lookup recursion, does not need validation
@@ -420,8 +422,9 @@ struct module_env {
* @return: false on error, true if success (and init may be needed).
*/
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec,
struct module_qstate** newq);
/**
* Add detached query.
@@ -441,6 +444,8 @@ struct module_env {
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect
* IP-based actions that apply to the query result.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -450,9 +455,9 @@ struct module_env {
* @return: false on error, true if success (and init may be needed).
*/
int (*add_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq,
struct mesh_state** sub);
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec,
struct module_qstate** newq, struct mesh_state** sub);
/**
* Kill newly attached sub. If attach_sub returns newq for
+28 -26
View File
@@ -1226,7 +1226,7 @@ setup_ticket_keys_cb(void* sslctx)
#endif /* HAVE_SSL */
int
listen_sslctx_setup(void* ctxt)
listen_sslctx_setup(void* ctxt, int use_system_versions)
{
#ifdef HAVE_SSL
SSL_CTX* ctx = (SSL_CTX*)ctxt;
@@ -1238,35 +1238,37 @@ listen_sslctx_setup(void* ctxt)
return 0;
}
#endif
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
!= SSL_OP_NO_SSLv3){
log_crypto_err("could not set SSL_OP_NO_SSLv3");
return 0;
}
if(!use_system_versions) {
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
!= SSL_OP_NO_SSLv3){
log_crypto_err("could not set SSL_OP_NO_SSLv3");
return 0;
}
#if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1)
/* if we have tls 1.1 disable 1.0 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
!= SSL_OP_NO_TLSv1){
log_crypto_err("could not set SSL_OP_NO_TLSv1");
return 0;
}
/* if we have tls 1.1 disable 1.0 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1)
!= SSL_OP_NO_TLSv1){
log_crypto_err("could not set SSL_OP_NO_TLSv1");
return 0;
}
#endif
#if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2)
/* if we have tls 1.2 disable 1.1 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
!= SSL_OP_NO_TLSv1_1){
log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
return 0;
}
/* if we have tls 1.2 disable 1.1 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1)
!= SSL_OP_NO_TLSv1_1){
log_crypto_err("could not set SSL_OP_NO_TLSv1_1");
return 0;
}
#endif
#if defined(SSL_OP_NO_TLSv1_2) && defined(SSL_OP_NO_TLSv1_3)
/* if we have tls 1.3 disable 1.2 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2)
!= SSL_OP_NO_TLSv1_2){
log_crypto_err("could not set SSL_OP_NO_TLSv1_2");
return 0;
}
/* if we have tls 1.3 disable 1.2 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2)
!= SSL_OP_NO_TLSv1_2){
log_crypto_err("could not set SSL_OP_NO_TLSv1_2");
return 0;
}
#endif
}
#if defined(SSL_OP_NO_RENEGOTIATION)
/* disable client renegotiation */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
@@ -1341,7 +1343,7 @@ listen_sslctx_setup_2(void* ctxt)
void* listen_sslctx_create(const char* key, const char* pem,
const char* verifypem, const char* tls_ciphers,
const char* tls_ciphersuites, int set_ticket_keys_cb,
int is_dot, int is_doh)
int is_dot, int is_doh, int use_system_versions)
{
#ifdef HAVE_SSL
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
@@ -1359,7 +1361,7 @@ void* listen_sslctx_create(const char* key, const char* pem,
SSL_CTX_free(ctx);
return NULL;
}
if(!listen_sslctx_setup(ctx)) {
if(!listen_sslctx_setup(ctx, use_system_versions)) {
SSL_CTX_free(ctx);
return NULL;
}
+6 -2
View File
@@ -478,9 +478,11 @@ void log_cert(unsigned level, const char* str, void* cert);
/**
* Set SSL_OP_NOxxx options on SSL context to disable bad crypto
* @param ctxt: SSL_CTX*
* @param use_system_versions: rely on the system policy (if any) for allowed
* TLS versions
* @return false on failure.
*/
int listen_sslctx_setup(void* ctxt);
int listen_sslctx_setup(void* ctxt, int use_system_versions);
/**
* Further setup of listening SSL context, after keys loaded.
@@ -499,12 +501,14 @@ void listen_sslctx_setup_2(void* ctxt);
* to be set.
* @param is_dot: if the TLS connection is for DoT to set the appropriate ALPN.
* @param is_doh: if the TLS connection is for DoH to set the appropriate ALPN.
* @param use_system_versions: rely on the system policy (if any) for allowed
* TLS versions
* return SSL_CTX* or NULL on failure (logged).
*/
void* listen_sslctx_create(const char* key, const char* pem,
const char* verifypem, const char* tls_ciphers,
const char* tls_ciphersuites, int set_ticket_keys_cb,
int is_dot, int is_doh);
int is_dot, int is_doh, int use_system_versions);
/**
* create SSL connect context
+1 -5
View File
@@ -1066,11 +1066,7 @@ grab_nsec(struct rrset_cache* rrset_cache, uint8_t* qname, size_t qname_len,
qname, qname_len, qtype, qclass, flags, now, 0);
struct packed_rrset_data* d;
if(!k) return NULL;
d = (struct packed_rrset_data*)k->entry.data;
if(d->ttl < now) {
lock_rw_unlock(&k->entry.lock);
return NULL;
}
d = k->entry.data;
/* only secure or unchecked records that have signatures. */
if( ! ( d->security == sec_status_secure ||
(d->security == sec_status_unchecked &&
+2
View File
@@ -1310,6 +1310,7 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
/* DS rrset exists. Return it to the validator immediately*/
struct ub_packed_rrset_key* copy = packed_rrset_copy_region(
rrset, region, *env->now);
struct packed_rrset_data* d = copy->entry.data;
lock_rw_unlock(&rrset->entry.lock);
if(!copy)
return NULL;
@@ -1319,6 +1320,7 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
msg->rep->rrsets[0] = copy;
msg->rep->rrset_count++;
msg->rep->an_numrrsets++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
return msg;
}
/* lookup in rrset and negative cache for NSEC/NSEC3 */
+2 -2
View File
@@ -496,7 +496,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
struct mesh_state* sub = NULL;
fptr_ok(fptr_whitelist_modenv_add_sub(
qstate->env->add_sub));
if(!(*qstate->env->add_sub)(qstate, &ask,
if(!(*qstate->env->add_sub)(qstate, &ask, NULL,
(uint16_t)(BIT_RD|flags), 0, valrec, newq, &sub)){
log_err("Could not generate request: out of memory");
return 0;
@@ -505,7 +505,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
else {
fptr_ok(fptr_whitelist_modenv_attach_sub(
qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
if(!(*qstate->env->attach_sub)(qstate, &ask, NULL,
(uint16_t)(BIT_RD|flags), 0, valrec, newq)){
log_err("Could not generate request: out of memory");
return 0;
+2 -2
View File
@@ -369,7 +369,7 @@ service_init(int r, struct daemon** d, struct config_file** c)
cfg->tls_ciphers, cfg->tls_ciphersuites,
(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0),
1, 0))) {
1, 0, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen SSL_CTX");
}
#ifdef HAVE_NGHTTP2_NGHTTP2_H
@@ -379,7 +379,7 @@ service_init(int r, struct daemon** d, struct config_file** c)
cfg->tls_ciphers, cfg->tls_ciphersuites,
(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0),
0, 1))) {
0, 1, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen doh SSL_CTX");
}
}