diff --git a/config.h.in b/config.h.in index 3fe6c73a2..1646c3863 100644 --- a/config.h.in +++ b/config.h.in @@ -173,6 +173,10 @@ 0 if you don't. */ #undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO +/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0 + if you don't. */ +#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH + /* Define to 1 if you have the declaration of `strlcat', and to 0 if you don't. */ #undef HAVE_DECL_STRLCAT diff --git a/configure b/configure index f32fa2959..ca4fe1b31 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for unbound 1.23.1. +# Generated by GNU Autoconf 2.71 for unbound 1.23.2. # # Report bugs to . # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.23.1' -PACKAGE_STRING='unbound 1.23.1' +PACKAGE_VERSION='1.23.2' +PACKAGE_STRING='unbound 1.23.2' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl 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.23.1 to adapt to many kinds of systems. +\`configure' configures unbound 1.23.2 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.23.1:";; + short | recursive ) echo "Configuration of unbound 1.23.2:";; 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.23.1 +unbound configure 1.23.2 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.23.1, which was +It was created by unbound $as_me 1.23.2, 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=23 -UNBOUND_VERSION_MICRO=1 +UNBOUND_VERSION_MICRO=2 LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=32 +LIBUNBOUND_REVISION=33 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -3357,6 +3357,7 @@ LIBUNBOUND_AGE=1 # 1.22.0 had 9:30:1 # 1.23.0 had 9:31:1 # 1.23.1 had 9:32:1 +# 1.23.2 had 9:33:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -20995,6 +20996,34 @@ else $as_nop ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" " +$ac_includes_default +#ifdef HAVE_OPENSSL_ERR_H +#include +#endif + +#ifdef HAVE_OPENSSL_RAND_H +#include +#endif + +#ifdef HAVE_OPENSSL_CONF_H +#include +#endif + +#ifdef HAVE_OPENSSL_ENGINE_H +#include +#endif +#include +#include + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_SSL_CTX_SET_TMP_ECDH $ac_have_decl" >>confdefs.h if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then @@ -22550,6 +22579,10 @@ then : fi + # these check_funcs need -lssl + BAKLIBS="$LIBS" + LIBS="-lssl $LIBS" + for ac_func in SSL_is_quic do : ac_fn_c_check_func "$LINENO" "SSL_is_quic" "ac_cv_func_SSL_is_quic" @@ -22562,6 +22595,8 @@ else $as_nop fi done + LIBS="$BAKLIBS" + ac_fn_c_check_type "$LINENO" "struct ngtcp2_version_cid" "ac_cv_type_struct_ngtcp2_version_cid" "$ac_includes_default #include @@ -25274,7 +25309,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h -version=1.23.1 +version=1.23.2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 printf %s "checking for build time... " >&6; } @@ -25804,7 +25839,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.23.1, which was +This file was extended by unbound $as_me 1.23.2, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25872,7 +25907,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.23.1 +unbound config.status 1.23.2 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index d2e9b47f4..9685dac0c 100644 --- a/configure.ac +++ b/configure.ac @@ -12,14 +12,14 @@ sinclude(dnscrypt/dnscrypt.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MINOR],[23]) -m4_define([VERSION_MICRO],[1]) +m4_define([VERSION_MICRO],[2]) AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=32 +LIBUNBOUND_REVISION=33 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -119,6 +119,7 @@ LIBUNBOUND_AGE=1 # 1.22.0 had 9:30:1 # 1.23.0 had 9:31:1 # 1.23.1 had 9:32:1 +# 1.23.2 had 9:33:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -1004,7 +1005,7 @@ LIBS="-lssl $LIBS" AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate]) LIBS="$BAKLIBS" -AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ +AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [ AC_INCLUDES_DEFAULT #ifdef HAVE_OPENSSL_ERR_H #include @@ -1626,7 +1627,13 @@ if test x_$withval = x_yes -o x_$withval != x_no; then ]) ]) AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_crypto_quictls_init ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params]) + + # these check_funcs need -lssl + BAKLIBS="$LIBS" + LIBS="-lssl $LIBS" AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])]) + LIBS="$BAKLIBS" + AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT #include ]) diff --git a/daemon/remote.c b/daemon/remote.c index 3b9f803a2..c17254bb5 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1148,6 +1148,8 @@ print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero) (unsigned long)s->svr.ans_bogus)) return 0; if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%lu\n", (unsigned long)s->svr.rrset_bogus)) return 0; + if(!ssl_printf(ssl, "num.valops"SQ"%lu\n", + (unsigned long)s->svr.val_ops)) return 0; if(!ssl_printf(ssl, "num.query.aggressive.NOERROR"SQ"%lu\n", (unsigned long)s->svr.num_neg_cache_noerror)) return 0; if(!ssl_printf(ssl, "num.query.aggressive.NXDOMAIN"SQ"%lu\n", diff --git a/daemon/stats.c b/daemon/stats.c index 7efb83a0b..41c4656aa 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -273,6 +273,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) /* add in the values from the mesh */ s->svr.ans_secure += (long long)worker->env.mesh->ans_secure; s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus; + s->svr.val_ops += (long long)worker->env.mesh->val_ops; s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata; s->svr.ans_expired += (long long)worker->env.mesh->ans_expired; for(i=0; isvr.ans_rcode_nodata += a->svr.ans_rcode_nodata; total->svr.ans_secure += a->svr.ans_secure; total->svr.ans_bogus += a->svr.ans_bogus; + total->svr.val_ops += a->svr.val_ops; total->svr.unwanted_replies += a->svr.unwanted_replies; total->svr.unwanted_queries += a->svr.unwanted_queries; total->svr.tcp_accept_usage += a->svr.tcp_accept_usage; diff --git a/daemon/unbound.c b/daemon/unbound.c index 143f2d160..aa7cfc8e8 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -174,7 +174,7 @@ static void checkrlimits(struct config_file* cfg) { #ifndef S_SPLINT_S -#ifdef HAVE_GETRLIMIT +#if defined(HAVE_GETRLIMIT) && !defined(unbound_testbound) /* list has number of ports to listen to, ifs number addresses */ int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 + (int)cfg->incoming_num_tcp:0)); diff --git a/doc/Changelog b/doc/Changelog index 5729d4606..75e8fab91 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,26 @@ +17 July 2025: Wouter + - Fix to not set rlimits in the unit tests. + - Fix #1303: [FR] Disable TLSv1.2. + - iana portlist updated. + +16 July 2025: Wouter + - Fix for RebirthDay Attack CVE-2025-5994, reported by Xiang Li + from AOSP Lab Nankai University. + - Tag for 1.23.1 with the release of 1.23.0 and the CVE fix, the + repository continues with the previous fixes, with 1.23.2. + - Add unit tests for non-ecs aggregation. + +12 July 2025: Yorgos + - Merge #1289 from Roland van Rijswijk-Deij: Add extra statistic to + track the number of signature validation operations. + Adds 'num.valops' to extended statistics. + - For #1289: test num.valops in existing stat_values.tdir. + - For #1289: add num.valops in the unbound-control man page. + +11 July 2025: Wouter + - Fix detection of SSL_CTX_set_tmp_ecdh function. + - For #1301: configure cant find SSL_is_quic in OpenSSL 3.5.1. + 8 July 2025: Wouter - Fix to improve dnstap discovery on Fedora. diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index 4a3bf6374..687c680e2 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -1367,6 +1367,15 @@ Increased for every RRset inspection that fails. .UNINDENT .INDENT 0.0 .TP +.B num.valops +The number of validation operations performed by the validator. +Increased for every RRSIG verification operation regardless of the +validation result. +The RRSIG and key combination needs to first pass some sanity checks before +Unbound even performs the verification, e.g., length/protocol checks. +.UNINDENT +.INDENT 0.0 +.TP .B unwanted.queries Number of queries that were refused or dropped because they failed the access control settings. diff --git a/doc/unbound-control.rst b/doc/unbound-control.rst index 0a4df65b2..1f3cc4a8e 100644 --- a/doc/unbound-control.rst +++ b/doc/unbound-control.rst @@ -1219,6 +1219,14 @@ Extended Statistics Increased for every RRset inspection that fails. +@@UAHL@unbound-control.stats@num.valops@@ + The number of validation operations performed by the validator. + Increased for every RRSIG verification operation regardless of the + validation result. + The RRSIG and key combination needs to first pass some sanity checks before + Unbound even performs the verification, e.g., length/protocol checks. + + @@UAHL@unbound-control.stats@unwanted.queries@@ Number of queries that were refused or dropped because they failed the access control settings. diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index f6b748d5c..5cb497c97 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -996,6 +996,7 @@ that likely the client does not need a reply for any more. This could happen if the host has not been able to service the queries for a while, i.e. Unbound is not running, and then is enabled again. It uses timestamp socket options. +The socket option is available on the Linux and FreeBSD platforms. .sp Default: 0 (disabled) .UNINDENT @@ -2283,8 +2284,8 @@ Default: yes .INDENT 0.0 .TP .B disable\-dnssec\-lame\-check: \fI\fP -If true, disables the DNSSEC lameness check in the iterator. -This check sees if RRSIGs are present in the answer, when dnssec is +If yes, disables the DNSSEC lameness check in the iterator. +This check sees if RRSIGs are present in the answer, when DNSSEC is expected, and retries another authority if RRSIGs are unexpectedly missing. The validator will insist in RRSIGs for DNSSEC signed domains regardless of this setting, if a trust anchor is loaded. @@ -3750,7 +3751,7 @@ Default: 65001 .B ede: \fI\fP If enabled, Unbound will respond with Extended DNS Error codes (\fI\%RFC 8914\fP). -These EDEs privide additional information with a response mainly for, but +These EDEs provide additional information with a response mainly for, but not limited to, DNS and DNSSEC errors. .sp When the \fI\%val\-log\-level\fP option is also diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index ef70098be..c763c5f1a 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -51,6 +51,7 @@ #include "services/cache/dns.h" #include "util/module.h" #include "util/regional.h" +#include "util/fptr_wlist.h" #include "util/storage/slabhash.h" #include "util/config_file.h" #include "util/data/msgreply.h" @@ -155,7 +156,8 @@ int ecs_whitelist_check(struct query_info* qinfo, /* Cache by default, might be disabled after parsing EDNS option * received from nameserver. */ - if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) { + if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0) + && sq->ecs_client_in.subnet_validdata) { qstate->no_cache_store = 0; } @@ -522,6 +524,69 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net) return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]); } +/** + * Create sub request that looks up the query. + * @param qstate: query state + * @param sq: subnet qstate + * @return false on failure. + */ +static int +generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq) +{ + struct module_qstate* subq = NULL; + uint16_t qflags = 0; /* OPCODE QUERY, no flags */ + int prime = 0; + int valrec = 0; + struct query_info qinf; + qinf.qname = qstate->qinfo.qname; + qinf.qname_len = qstate->qinfo.qname_len; + qinf.qtype = qstate->qinfo.qtype; + qinf.qclass = qstate->qinfo.qclass; + qinf.local_alias = NULL; + + qflags |= BIT_RD; + if((qstate->query_flags & BIT_CD)!=0) { + qflags |= BIT_CD; + valrec = 1; + } + + fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); + if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, + &subq)) { + return 0; + } + if(subq) { + /* It is possible to access the subquery module state. */ + if(sq->ecs_client_in.subnet_source_mask == 0 && + edns_opt_list_find(qstate->edns_opts_front_in, + qstate->env->cfg->client_subnet_opcode)) { + subq->no_cache_store = 1; + } + } + return 1; +} + +/** + * Perform the query without subnet + * @param qstate: query state + * @param sq: subnet qstate + * @return module state + */ +static enum module_ext_state +generate_lookup_without_subnet(struct module_qstate *qstate, + struct subnet_qstate* sq) +{ + verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet"); + if(!generate_sub_request(qstate, sq)) { + verbose(VERB_ALGO, "Could not generate sub query"); + qstate->return_rcode = LDNS_RCODE_FORMERR; + qstate->return_msg = NULL; + return module_finished; + } + sq->wait_subquery = 1; + return module_wait_subquery; +} + static enum module_ext_state eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) { @@ -557,14 +622,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) * is still useful to put it in the edns subnet cache for * when a client explicitly asks for subnet specific answer. */ verbose(VERB_QUERY, "subnetcache: Authority indicates no support"); - if(!sq->started_no_cache_store) { - lock_rw_wrlock(&sne->biglock); - update_cache(qstate, id); - lock_rw_unlock(&sne->biglock); - } - if (sq->subnet_downstream) - cp_edns_bad_response(c_out, c_in); - return module_finished; + return generate_lookup_without_subnet(qstate, sq); } /* Purposefully there was no sent subnet, and there is consequently @@ -589,14 +647,14 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) !common_prefix(s_out->subnet_addr, s_in->subnet_addr, s_out->subnet_source_mask)) { - /* we can not accept, restart query without option */ + /* we can not accept, perform query without option */ verbose(VERB_QUERY, "subnetcache: forged data"); s_out->subnet_validdata = 0; (void)edns_opt_list_remove(&qstate->edns_opts_back_out, qstate->env->cfg->client_subnet_opcode); sq->subnet_sent = 0; sq->subnet_sent_no_subnet = 0; - return module_restart_next; + return generate_lookup_without_subnet(qstate, sq); } lock_rw_wrlock(&sne->biglock); @@ -795,6 +853,9 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id, } else if(sq->subnet_sent_no_subnet) { /* The answer can be stored as scope 0, not in global cache. */ qstate->no_cache_store = 1; + } else if(sq->subnet_sent) { + /* Need another query to be able to store in global cache. */ + qstate->no_cache_store = 1; } return 1; @@ -812,6 +873,32 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, strmodulevent(event)); log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo); + if(sq && sq->wait_subquery_done) { + /* The subquery lookup returned. */ + if(sq->ecs_client_in.subnet_source_mask == 0 && + edns_opt_list_find(qstate->edns_opts_front_in, + qstate->env->cfg->client_subnet_opcode)) { + if(!sq->started_no_cache_store && + qstate->return_msg) { + lock_rw_wrlock(&sne->biglock); + update_cache(qstate, id); + lock_rw_unlock(&sne->biglock); + } + if (sq->subnet_downstream) + cp_edns_bad_response(&sq->ecs_client_out, + &sq->ecs_client_in); + /* It is a scope zero lookup, append edns subnet + * option to the querier. */ + subnet_ecs_opt_list_append(&sq->ecs_client_out, + &qstate->edns_opts_front_out, qstate, + qstate->region); + } + sq->wait_subquery_done = 0; + qstate->ext_state[id] = module_finished; + qstate->no_cache_store = sq->started_no_cache_store; + qstate->no_cache_lookup = sq->started_no_cache_lookup; + return; + } if((event == module_event_new || event == module_event_pass) && sq == NULL) { struct edns_option* ecs_opt; @@ -822,6 +909,8 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, } sq = (struct subnet_qstate*)qstate->minfo[id]; + if(sq->wait_subquery) + return; /* Wait for that subquery to return */ if((ecs_opt = edns_opt_list_find( qstate->edns_opts_front_in, @@ -851,6 +940,14 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, /* No clients are interested in result or we could not * parse it, we don't do client subnet */ sq->ecs_server_out.subnet_validdata = 0; + if(edns_opt_list_find(qstate->edns_opts_front_in, + qstate->env->cfg->client_subnet_opcode)) { + /* aggregated this deaggregated state */ + qstate->ext_state[id] = + generate_lookup_without_subnet( + qstate, sq); + return; + } verbose(VERB_ALGO, "subnetcache: pass to next module"); qstate->ext_state[id] = module_wait_module; return; @@ -891,6 +988,14 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, } lock_rw_unlock(&sne->biglock); } + if(sq->ecs_client_in.subnet_source_mask == 0 && + edns_opt_list_find(qstate->edns_opts_front_in, + qstate->env->cfg->client_subnet_opcode)) { + /* client asked for resolution without edns subnet */ + qstate->ext_state[id] = generate_lookup_without_subnet( + qstate, sq); + return; + } sq->ecs_server_out.subnet_addr_fam = sq->ecs_client_in.subnet_addr_fam; @@ -927,6 +1032,8 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, qstate->ext_state[id] = module_wait_module; return; } + if(sq && sq->wait_subquery) + return; /* Wait for that subquery to return */ /* Query handed back by next module, we have a 'final' answer */ if(sq && event == module_event_moddone) { qstate->ext_state[id] = eval_response(qstate, id, sq); @@ -975,10 +1082,27 @@ subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate), } void -subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate), - int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) +subnetmod_inform_super(struct module_qstate *qstate, int id, + struct module_qstate *super) { - /* Not used */ + struct subnet_qstate* super_sq = + (struct subnet_qstate*)super->minfo[id]; + log_query_info(VERB_ALGO, "subnetcache inform_super: query", + &super->qinfo); + super_sq->wait_subquery = 0; + super_sq->wait_subquery_done = 1; + if(qstate->return_rcode != LDNS_RCODE_NOERROR || + !qstate->return_msg) { + super->return_msg = NULL; + super->return_rcode = LDNS_RCODE_SERVFAIL; + return; + } + super->return_rcode = LDNS_RCODE_NOERROR; + super->return_msg = dns_copy_msg(qstate->return_msg, super->region); + if(!super->return_msg) { + log_err("subnetcache: copy response, out of memory"); + super->return_rcode = LDNS_RCODE_SERVFAIL; + } } size_t diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h index 1ff8a23ec..3893820fa 100644 --- a/edns-subnet/subnetmod.h +++ b/edns-subnet/subnetmod.h @@ -102,6 +102,10 @@ struct subnet_qstate { int started_no_cache_store; /** has the subnet module been started with no_cache_lookup? */ int started_no_cache_lookup; + /** Wait for subquery that has been started for nonsubnet lookup. */ + int wait_subquery; + /** The subquery waited for is done. */ + int wait_subquery_done; }; void subnet_data_delete(void* d, void* ATTR_UNUSED(arg)); diff --git a/libunbound/unbound.h b/libunbound/unbound.h index bdcf4edec..c274f80ab 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -772,6 +772,8 @@ struct ub_server_stats { long long ans_bogus; /** rrsets marked bogus by validator */ long long rrset_bogus; + /** number of signature validation operations performed by validator */ + long long val_ops; /** number of queries that have been ratelimited by domain recursion. */ long long queries_ratelimited; /** unwanted traffic received on server-facing ports */ diff --git a/services/mesh.c b/services/mesh.c index 8a52fe4a6..3212a6abf 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -2265,6 +2265,7 @@ mesh_stats_clear(struct mesh_area* mesh) timehist_clear(mesh->histogram); mesh->ans_secure = 0; mesh->ans_bogus = 0; + mesh->val_ops = 0; mesh->ans_expired = 0; mesh->ans_cachedb = 0; memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM); diff --git a/services/mesh.h b/services/mesh.h index fd17c05da..f19f423a8 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -131,6 +131,8 @@ struct mesh_area { size_t ans_secure; /** (extended stats) bogus replies */ size_t ans_bogus; + /** (extended stats) number of validation operations */ + size_t val_ops; /** (extended stats) rcodes in replies */ size_t ans_rcode[UB_STATS_RCODE_NUM]; /** (extended stats) rcode nodata in replies */ diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 0136b5e4e..994a42870 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -409,6 +409,7 @@ static void print_extended(struct ub_stats_info* s, int inhibit_zero) PR_UL("num.answer.secure", s->svr.ans_secure); PR_UL("num.answer.bogus", s->svr.ans_bogus); PR_UL("num.rrset.bogus", s->svr.rrset_bogus); + PR_UL("num.valops", s->svr.val_ops); PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror); PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain); /* threat detection */ diff --git a/testcode/petal.c b/testcode/petal.c index 6d825f1e0..627c77d57 100644 --- a/testcode/petal.c +++ b/testcode/petal.c @@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert) #if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO if (!SSL_CTX_set_ecdh_auto(ctx,1)) if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n"); -#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH) +#elif defined(USE_ECDSA) && HAVE_DECL_SSL_CTX_SET_TMP_ECDH if(1) { EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); if (!ecdh) { diff --git a/testdata/stat_values.tdir/stat_values.conf b/testdata/stat_values.tdir/stat_values.conf index 312a7e174..a22746297 100644 --- a/testdata/stat_values.tdir/stat_values.conf +++ b/testdata/stat_values.tdir/stat_values.conf @@ -17,7 +17,7 @@ server: serve-expired-client-timeout: 0 dns-error-reporting: yes - trust-anchor: "bogusdnssec. DS 1444 8 2 5224fb17d630a2e3efdc863a05a4032c5db415b5de3f32472ee9abed42e10146" + trust-anchor: "bogusdnssec. DNSKEY 257 3 8 AwEAAbwL6LuXTLXtb23CsXhpkxxyGbEFUROh/L8BWA1EEF8LdQ4Rmsj4 D5D8uAnRFDkNhM6XiII9xcsavwBGNwHxzUaij4MZQu1vrzcfGIJLcC1Q paZmSH9WqIYFQci+T4s4UfDrrS96wO/H0nJvFmavWVX/7p1Q6dv0Arwz XMXaHGrRVdEgK2MDS3dFRngx5JC5fwD7YnwH08EAoFRjdAoXe+etOAeG aOT9IGjVM5LKkN2k6fIRvZ2l9eu5/o+h5L+kpDRcapW2QiL21hCcmwpW 50Llfx9Ovk+M7TBjp4iT7Tc8gLzRZr24LmXEyABb54WW3aoF5k8DZPot 9ogUjxVN/dM=" local-zone: local.zone static local-data: "www.local.zone A 192.0.2.1" diff --git a/testdata/stat_values.tdir/stat_values.test b/testdata/stat_values.tdir/stat_values.test index d538e4d60..7dd71edd6 100644 --- a/testdata/stat_values.tdir/stat_values.test +++ b/testdata/stat_values.tdir/stat_values.test @@ -448,7 +448,8 @@ num.query.flags.RD=1 num.query.opcode.QUERY=1 num.query.type.A=1 num.query.udpout=9 -rrset.cache.count=4 +num.valops=6 +rrset.cache.count=5 total.num.cachemiss=1 total.num.dns_error_reports=1 total.num.queries=1 diff --git a/testdata/stat_values.tdir/stat_values.testns b/testdata/stat_values.tdir/stat_values.testns index a5c0ae92b..8dd8e26ee 100644 --- a/testdata/stat_values.tdir/stat_values.testns +++ b/testdata/stat_values.tdir/stat_values.testns @@ -43,6 +43,11 @@ ADJUST copy_id SECTION QUESTION @ IN DNSKEY SECTION ANSWER +;; random keys with bogus rrsig (originally from nlnetlabs.nl) +;; These will result in 6 validation attempts (1 + 5 retries) when trying to prime the configured trust anchor +@ IN DNSKEY 256 3 8 AwEAAdR7XR95OaAN9Rz7TbtPalQ9guQk7zfxTHYNKhsiwTZA9z+F16nD 0VeBlk7dNik3ETpT2GLAwr9sntG898JwurCDe353wHPvjZtMCdiTVp3c RCrjuCEvoFpmZNN82H0gaH/4v8mkv/QBDAkDSncYjz/FqHKAeYy3cMcj Y6RyVweh +@ IN DNSKEY 257 3 8 AwEAAbwL6LuXTLXtb23CsXhpkxxyGbEFUROh/L8BWA1EEF8LdQ4Rmsj4 D5D8uAnRFDkNhM6XiII9xcsavwBGNwHxzUaij4MZQu1vrzcfGIJLcC1Q paZmSH9WqIYFQci+T4s4UfDrrS96wO/H0nJvFmavWVX/7p1Q6dv0Arwz XMXaHGrRVdEgK2MDS3dFRngx5JC5fwD7YnwH08EAoFRjdAoXe+etOAeG aOT9IGjVM5LKkN2k6fIRvZ2l9eu5/o+h5L+kpDRcapW2QiL21hCcmwpW 50Llfx9Ovk+M7TBjp4iT7Tc8gLzRZr24LmXEyABb54WW3aoF5k8DZPot 9ogUjxVN/dM= +@ IN RRSIG DNSKEY 8 1 3600 20250806005014 20250709005014 50602 bogusdnssec. WIv6Qe9RAALyMK04dnDfOHtudHzIyk2DcwBLupbPdmSu+0NcAjcQBo2x rWNrdvNHVCAi5OvRwIz/ac81TptsnsSd6zcOtbeSijWpQj21vnSHhlWv zvJW+/WAm3h/XbOPFSE08FNaig9CeRE2GmKemKAdUeDbWoNrku8klCG+ GHJCCyqdmgS6249oUvIgV/m6OwRSCEeUxHlDqbM+OF+Up3dj0iQ61n9l 2nrQR9WNFn9YGTNHiA9bhdFfiCmrAb6X01IrlmSe+ENiQPeRnOWv24ls V5Re9zAOz+X26vjev/wMTEhlrAvl6FIRg7hIgnd3UxQ/UCQ5gxSriaWi YoiH6g== ENTRY_END ENTRY_BEGIN diff --git a/testdata/subnet_noecs_mult.crpl b/testdata/subnet_noecs_mult.crpl new file mode 100644 index 000000000..3e2acefb0 --- /dev/null +++ b/testdata/subnet_noecs_mult.crpl @@ -0,0 +1,334 @@ +# config +server: + send-client-subnet: 1.2.3.4 + max-client-subnet-ipv4: 17 + module-config: "subnetcache iterator" + qname-minimisation: no + minimal-responses: yes + target-fetch-policy: "0 0 0 0 0" + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test subnet with no edns subnet from server multiple times +; Multiple queries are sent to a server that does not reply with the +; edns-subnet option. + +; 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 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 100 + ADDRESS 192.5.6.30 + +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 50 52 + 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. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN A +SECTION ANSWER +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 +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname ednsdata +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +SECTION ADDITIONAL + ; Match this subnet option + HEX_EDNSDATA_BEGIN + ; client is 127.0.0.1 + 00 08 ; OPC + 00 07 ; option length + 00 01 ; Family + 11 00 ; source mask, scopemask + 7f 00 00 ; address + HEX_EDNSDATA_END + ; This is the response, without the subnet option + HEX_ANSWER_BEGIN; + 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR + 00 00 00 01 03 77 77 77 ; www.example.com A (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 + C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600 + 00 04 0A 14 1E 2C ; rdata 10.20.30.44 + 00 00 29 10 00 00 00 + 80 00 00 00 + HEX_ANSWER_END +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname ednsdata +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +SECTION ADDITIONAL + ; Match this subnet option + HEX_EDNSDATA_BEGIN + ; client is 127.2.0.1 + 00 08 ; OPC + 00 07 ; option length + 00 01 ; Family + 11 00 ; source mask, scopemask + 7f 02 00 ; address + HEX_EDNSDATA_END + ; This is the response, without the subnet option + HEX_ANSWER_BEGIN; + 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR + 00 00 00 01 03 77 77 77 ; www.example.com A (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 + C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600 + 00 04 0A 14 1E 2C ; rdata 10.20.30.44 + 00 00 29 10 00 00 00 + 80 00 00 00 + HEX_ANSWER_END +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname ednsdata +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +SECTION ADDITIONAL + ; Match this subnet option + HEX_EDNSDATA_BEGIN + ; client is 127.3.0.1 + 00 08 ; OPC + 00 07 ; option length + 00 01 ; Family + 11 00 ; source mask, scopemask + 7f 03 00 ; address + HEX_EDNSDATA_END + ; This is the response, without the subnet option + HEX_ANSWER_BEGIN; + 00 00 84 00 00 01 00 01 ; ID 0 QR AA NOERROR + 00 00 00 01 03 77 77 77 ; www.example.com A (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 + C0 0C 00 01 00 01 00 00 0E 10 ; www.example.com. A IN 3600 + 00 04 0A 14 1E 2C ; rdata 10.20.30.44 + 00 00 29 10 00 00 00 + 80 00 00 00 + HEX_ANSWER_END +ENTRY_END + +; The answer for a query without subnet +;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. IN A 10.20.30.40 +;ENTRY_END +RANGE_END + +; ns.example.com. +RANGE_BEGIN 53 57 + ADDRESS 1.2.3.4 +; The answer for a query without subnet +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. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +STEP 10 QUERY +ENTRY_BEGIN + HEX_ANSWER_BEGIN; + 00 00 01 00 00 01 00 00 ; ID 0 + 00 00 00 01 03 77 77 77 ; www.example.com A? (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 00 00 29 10 00 00 00 + 80 00 00 0b + + 00 08 00 07 ; OPC, optlen + 00 01 11 00 ; ip4, scope 17, source 0 + 7f 00 00 ; 127.0.0.0/17 + HEX_ANSWER_END +ENTRY_END + +STEP 20 QUERY +ENTRY_BEGIN + HEX_ANSWER_BEGIN; + 00 00 01 00 00 01 00 00 ; ID 0 + 00 00 00 01 03 77 77 77 ; www.example.com A? (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 00 00 29 10 00 00 00 + 80 00 00 0b + + 00 08 00 07 ; OPC, optlen + 00 01 11 00 ; ip4, scope 17, source 0 + 7f 02 00 ; 127.2.0.0/17 + HEX_ANSWER_END +ENTRY_END + +STEP 30 QUERY +ENTRY_BEGIN + HEX_ANSWER_BEGIN; + 00 00 01 00 00 01 00 00 ; ID 0 + 00 00 00 01 03 77 77 77 ; www.example.com A? (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 00 00 29 10 00 00 00 + 80 00 00 0b + + 00 08 00 07 ; OPC, optlen + 00 01 11 00 ; ip4, scope 17, source 0 + 7f 03 00 ; 127.3.0.0/17 + HEX_ANSWER_END +ENTRY_END + +; recursion happens here. +; The upstream server RANGE starts responding at STEP 50. +STEP 50 TRAFFIC + +; The upstream server now responds for the nonsubnet response. +STEP 55 TRAFFIC + +STEP 60 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +;www.example.com. IN A 10.20.30.44 +SECTION ADDITIONAL +; HEX_EDNSDATA_BEGIN +; ; client is 127.3.0.1 +; 00 08 ; OPC +; 00 07 ; option length +; 00 01 ; Family +; 11 00 ; source mask, scopemask +; 7f 03 00 ; address +; HEX_EDNSDATA_END +ENTRY_END + +STEP 70 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +;www.example.com. IN A 10.20.30.44 +SECTION ADDITIONAL +; HEX_EDNSDATA_BEGIN +; ; client is 127.2.0.1 +; 00 08 ; OPC +; 00 07 ; option length +; 00 01 ; Family +; 11 00 ; source mask, scopemask +; 7f 02 00 ; address +; HEX_EDNSDATA_END +ENTRY_END + +STEP 80 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +;www.example.com. IN A 10.20.30.44 +SECTION ADDITIONAL +; HEX_EDNSDATA_BEGIN +; ; client is 127.0.0.1 +; 00 08 ; OPC +; 00 07 ; option length +; 00 01 ; Family +; 11 00 ; source mask, scopemask +; 7f 00 00 ; address +; HEX_EDNSDATA_END +ENTRY_END + +SCENARIO_END diff --git a/testdata/subnet_noecs_refused.crpl b/testdata/subnet_noecs_refused.crpl new file mode 100644 index 000000000..39fbe85b4 --- /dev/null +++ b/testdata/subnet_noecs_refused.crpl @@ -0,0 +1,159 @@ +# config +server: + send-client-subnet: 1.2.3.4 + max-client-subnet-ipv4: 17 + module-config: "subnetcache iterator" + qname-minimisation: no + minimal-responses: yes + target-fetch-policy: "0 0 0 0 0" + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test subnet with no edns subnet support but it is refused +; The query is sent to a server that does not reply with the edns-subnet +; option. The upstream server sends rcode refused. That results in a +; NULL return_msg. + +; 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 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 100 + ADDRESS 192.5.6.30 + +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 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. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN A +SECTION ANSWER +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 +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600 +ENTRY_END + +; This matches the no EDNS subnet info queries that are made for the +; fallback without subnet. The answer is refused. +ENTRY_BEGIN +MATCH opcode qtype qname ednsdata +ADJUST copy_id +REPLY QR AA REFUSED +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +;www.example.com. IN A 10.20.30.40 +ENTRY_END + +; This matches the initial query with edns subnet in the query, +; the answer has no edns subnet in the reply. +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. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +STEP 1 QUERY +;ENTRY_BEGIN +;REPLY RD DO +;SECTION QUESTION +;www.example.com. IN A +; but send this query with subnet scope zero in the query, because that +; makes the reply possibly get stored in the cache. +; +; query with subnet 0.0.0.0/0. +ENTRY_BEGIN +HEX_ANSWER_BEGIN + 00 00 01 00 00 01 00 00 ;ID 0 + 00 00 00 01 03 77 77 77 ; www.example.com A? (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 00 00 29 10 00 00 00 + 80 00 00 08 + + 00 08 00 04 ; OPC, optlen + 00 01 00 00 ; ip4, scope 0, source 0 + ;0.0.0.0/0 +HEX_ANSWER_END +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA DO SERVFAIL +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +;www.example.com. IN A 10.20.30.40 +ENTRY_END +SCENARIO_END diff --git a/testdata/subnet_noecs_support.crpl b/testdata/subnet_noecs_support.crpl new file mode 100644 index 000000000..0c9826c83 --- /dev/null +++ b/testdata/subnet_noecs_support.crpl @@ -0,0 +1,127 @@ +# config +server: + send-client-subnet: 1.2.3.4 + max-client-subnet-ipv4: 17 + module-config: "subnetcache iterator" + qname-minimisation: no + minimal-responses: yes + target-fetch-policy: "0 0 0 0 0" + +stub-zone: + name: "." + stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. +CONFIG_END + +SCENARIO_BEGIN Test subnet with no edns subnet support from the server +; The query is sent to a server that does not reply with the edns-subnet +; option. + +; 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 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 100 + ADDRESS 192.5.6.30 + +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 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. +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +ns.example.com. IN A +SECTION ANSWER +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 +ns.example.com. IN AAAA +SECTION ANSWER +SECTION AUTHORITY +example.com. IN SOA ns.example.com. host.example.com. 4 86400 3600 86400 3600 +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. IN A 10.20.30.40 +ENTRY_END +RANGE_END + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +ENTRY_END +SCENARIO_END diff --git a/util/iana_ports.inc b/util/iana_ports.inc index 727854292..6d8cfd27b 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -3980,6 +3980,7 @@ 4790, 4791, 4792, +4793, 4800, 4801, 4802, diff --git a/util/net_help.c b/util/net_help.c index 19e42642e..6ce0d9131 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -1259,6 +1259,14 @@ listen_sslctx_setup(void* ctxt) 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; + } +#endif #if defined(SSL_OP_NO_RENEGOTIATION) /* disable client renegotiation */ if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & @@ -1312,7 +1320,7 @@ listen_sslctx_setup_2(void* ctxt) if(!SSL_CTX_set_ecdh_auto(ctx,1)) { log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); } -#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH) +#elif defined(USE_ECDSA) && HAVE_DECL_SSL_CTX_SET_TMP_ECDH if(1) { EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); if (!ecdh) { diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 9251d2b1f..86de6fb8e 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -57,6 +57,7 @@ #include "sldns/sbuffer.h" #include "sldns/parseutil.h" #include "sldns/wire2str.h" +#include "services/mesh.h" #include #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE) @@ -1677,6 +1678,10 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf, /* verify */ sec = verify_canonrrset(buf, (int)sig[2+2], sigblock, sigblock_len, key, keylen, reason); + + /* count validation operation */ + if(qstate && qstate->env && qstate->env->mesh) + qstate->env->mesh->val_ops++; if(sec == sec_status_secure) { /* check if TTL is too high - reduce if so */