Compare commits

...
Author SHA1 Message Date
W.C.A. Wijngaards 07c96792f2 - Fix doxygen comment syntax. 2026-04-21 13:44:55 +02:00
W.C.A. Wijngaards 84ab430e11 - Set version number to 1.25.0 of code repository. 2026-04-21 13:27:55 +02:00
W.C.A. Wijngaards 53499e4a88 - Fix handling of wildcard CNAMEs in the chain of trust.
An improper wildcard in the chain of trust would send
  the retries to the wrong upstream. Also it could label
  the step in the chain of trust as secure, when it was not.
  Thanks to Qifan Zhang, Palo Alto Networks for the report.
2026-04-21 13:24:40 +02:00
W.C.A. Wijngaards 8a25a97687 - Fix that a DNAME with an unsigned CNAME is checked for
the correct match. This stops that for certain zone
  configurations an unchecked unsigned CNAME could get
  secure status. Thanks to Qifan Zhang, Palo Alto Networks
  for the report.
2026-04-21 13:19:13 +02:00
W.C.A. Wijngaards c112bcf2fd - Fix that signatures are not allowed with revoked dnskeys.
Thanks to Qifan Zhang, Palo Alto Networks for the report.
2026-04-21 13:07:34 +02:00
W.C.A. Wijngaards 9de549c498 - Fix that upstream TLS connections are not reused as TLS
connections for a different name, at the same IP. This
  checks that the tls name is correct when reusing the
  upstream connections. Thanks to TaoFei Guo from Peking
  University and JianJun Chen from Tsinghua University for
  the report.
2026-04-21 11:59:05 +02:00
W.C.A. Wijngaards 84c645e7b3 - Fix for missing bounds check for decompressing dnames
for downloaded authority zones. This fixes that the server
  could end up with malformed zone content after receiving
  truncated packet contents from an AXFR. In addition, the
  domain names in the SOA rdata are checked before the
  authority code picks up the zone serial.
  Thanks to Halil Oktay for the report.
2026-04-21 10:32:37 +02:00
W.C.A. Wijngaards 197a425c7d - Fix for iterator RCODE handling of YXDOMAIN. This fixes
that the server only accepts YXDOMAIN answers that contain
  a DNAME record. This stops bad answers, and checks that
  the authoritative server gives correct replies.
  Thanks to Qifan Zhang, Palo Alto Networks for the report.
2026-04-21 10:09:02 +02:00
W.C.A. Wijngaards 311054728d - Fix EDNS extended RCODE reflection. This fixes that
the server does not echo extended rcode values after class
  chaos queries. Thanks to Qifan Zhang, Palo Alto Networks
  for the report.
2026-04-21 09:58:19 +02:00
W.C.A. Wijngaards 6d74856212 - Fix for the Jiggle Attack. The server is fixed to answer
with errors for error cases, and does not stay silent.
  In addition, the error replies do not contain parts of the
  incoming query. This is more conformant, stops reflection
  and stops it as a covert channel. Thanks to Yuqi Qiu and
  Xiang Li, Nankai University (AOSP Lab) for the report.
  In addition, thanks to Qifan Zhang, Palo Alto Networks, for
  noting the fingerprinting possibility, that is also fixed
  with this.
2026-04-21 09:54:17 +02:00
W.C.A. Wijngaards d489e6027e - Add test case for malformed SVCB records. Thanks to
Qifan Zhang, Palo Alto Networks for the additional test.
2026-04-21 09:41:53 +02:00
W.C.A. Wijngaards e1d146d6b0 - Fix test with https zone for libressl. 2026-04-20 16:10:33 +02:00
W.C.A. Wijngaards eb2fe8df8d - Fix unused variable warning when compiled without ssl. 2026-04-20 12:24:55 +02:00
W.C.A. Wijngaards 86a8be75f0 - Fix compile warnings for thread setname routine, and test compile. 2026-04-20 12:24:28 +02:00
W.C.A. Wijngaards 52fc5ee374 - Fix pthread_setname detection to fail on warnings. 2026-04-17 17:13:14 +02:00
W.C.A. Wijngaards 82359c8fb1 - Update generated configure, with autoconf. 2026-04-17 17:00:09 +02:00
W.C.A. Wijngaards c996671a1f - Update generated man pages. 2026-04-17 16:32:02 +02:00
Yorgos Thessalonikefs e233a1ef65 Changelog entry for #1400:
- Merge #1400: Support pthread_setname_np.
2026-04-17 16:23:53 +02:00
Yorgos Thessalonikefs 06ff9f20d0 Merge branch 'features/pthread-setname' 2026-04-17 16:22:04 +02:00
W.C.A. Wijngaards af209a12ea - Fix subnet store of servfail to not leak memory. 2026-04-17 13:48:38 +02:00
W.C.A. Wijngaards 84ac7e1b58 - Fix ttl comparisons in rdata_copy for 32bit signed or unsigned. 2026-04-17 13:27:41 +02:00
W.C.A. Wijngaards 24d502763c - Fix to increase size of the buffer for the win_svc reportev log
function.
2026-04-17 11:05:31 +02:00
W.C.A. Wijngaards 99c61c19ac - Fix compat/gmtime_r old style definition syntax. 2026-04-17 11:05:15 +02:00
W.C.A. Wijngaards cb05e9d525 - Fix compat/chacha_private sigma and tau definitions to use
nonstring attribute.
2026-04-17 11:04:51 +02:00
W.C.A. Wijngaards abddd4e270 - Update github ci cross platform to use
cross-platform-actions/action@v1.0.0.
- Fix github ci to speed up with parralel build, for windows ci.
2026-04-17 10:41:24 +02:00
W.C.A. Wijngaards 656b412492 - Update github ci to use actions/checkout@v6. 2026-04-17 10:13:06 +02:00
W.C.A. Wijngaards f15a46fcd4 - Fix to compile the shm code when there is no shmget. 2026-04-17 09:42:35 +02:00
W.C.A. Wijngaards 8d434bf744 - Fix setup of ssl context copy, to check for the tls service
pem option for stat calls.
2026-04-17 09:34:06 +02:00
W.C.A. Wijngaards 13b269d398 - Fix setup of ssl context copy of the tls service pem option,
from a clang analyzer warning.
2026-04-17 09:29:10 +02:00
Yorgos Thessalonikefs 7aff88881a - Fix cleaning up DoH session. The same query can be on multiple
streams in a session.
2026-04-16 11:01:07 +02:00
W.C.A. Wijngaards b97bd3a1fc - Fix configure, autoconf for #1406. 2026-04-16 10:55:57 +02:00
Yorgos Thessalonikefs 6aa5ad85f4 Changelog entry for #1406:
- Merge #1406: Introduce new 'tls-protocols' configuration option.
2026-04-16 10:53:01 +02:00
42b19c20c1 Introduce new 'tls-protocols' configuration option (#1406)
- Introduce new 'tls-protocols' configuration option that specifies
  which of the supported TLS protocols will be used.
  This change invalidates some previous changes:
- TLSv1.2 is again enabled by default, but can be selectively turned off if
  desired (related to #1303).
- The biefly introduced (not yet released) 'tls-use-system-versions'
  configuration option, that addressed #1346, is reverted in favor of
  'tls-protocols'.
- The briefly introduced (not yet released) '--enable-system-tls'
  configure option, related to #1401, is no longer needed with the new
  option and the current default.

- Review comment for checking out of memory condition

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2026-04-16 10:38:24 +02:00
W.C.A. Wijngaards db1fe8b475 - Fix to shorten RRSIG count in scrubber, this protects against
an overly large number of RRSIGs. It can be configured with
  `iter-scrub-rrsig: 8`, it has default 8. Thanks to Yuxiao Wu,
  Tsinghua University for the report.
2026-04-15 11:41:28 +02:00
W.C.A. Wijngaards f4f964f4fb - Fix RFC7766 compliance when client sends EOF over TCP. It stops
pending replies and closes. Thanks to Yuxiao Wu, Tsinghua
  University for the report.
2026-04-15 11:29:07 +02:00
W.C.A. Wijngaards a2272860de - iana portlist updated. 2026-04-14 15:36:33 +02:00
W.C.A. Wijngaards 95083d4377 - Fix clang analyzer warning for subnetmod, when return_msg is
NULL for update cache, like when it stores servfail status.
2026-04-14 15:36:00 +02:00
W.C.A. Wijngaards 5ce0bf5281 - Fix #1017: memory corruption related core dumps.
When alloc_reg_obtain has an empty list, return a new allocation.
2026-04-14 15:34:59 +02:00
Yorgos Thessalonikefs 6a0d5e2cb1 - Update the documentation of 'max-query-restarts' in the man page. 2026-04-13 18:07:01 +02:00
W.C.A. Wijngaards 330d5211c9 - Fix for EDNS client subnet so that it does not store SERVFAIL in
the global cache after a failed lookup, such as timeouts. A failure
  entry is stored in the subnet cache, for the query name, for a
  couple of seconds. Queries can continue to use the subnet cache
  during that time.
2026-04-10 15:45:28 +02:00
Yorgos Thessalonikefs 2dc28a249a - Fix unused variable warning. 2026-04-07 18:03:20 +02:00
W.C.A. Wijngaards c5f14dc880 Changelog comment for #1408
- Merge #1408: Fix shared memory stats with threads.
2026-03-30 16:15:32 +02:00
a2ace114de Fix shared memory stats with threads (#1408)
* - stats-shm-volley, with mesh_time_median the additions add up to the correct
  average that is used.

* - stats-shm-volley, the stat interval is selected with offset.

* - stats-shm-volley, stat totals in separate struct. The first thread zeroes
  it, and the last thread copies it.

* - stats-shm-volley, the array is inited for a new round if one or more

* - stats-shm-volley, the array is inited for a new round if one or more
  threads are not responsive for stat collection.

* - stats-shm-volley review, typos and slightly more detailed text for comments.

---------

Co-authored-by: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
2026-03-30 16:13:11 +02:00
W.C.A. Wijngaards 2e9b880718 - Fix defense in depth for service callback with empty packet. 2026-03-27 15:42:45 +01:00
W.C.A. Wijngaards a0ec6cd946 - Fix test code to allow empty hex answer packets from testbound. 2026-03-27 15:39:27 +01:00
W.C.A. Wijngaards ea36979c40 - Fix to allow the control-interface config to use ip@port notation. 2026-03-27 14:29:15 +01:00
W.C.A. Wijngaards 315077b9e6 - Fix to check for invalid http content length and chunk size,
and to check the RR rdata field lengths when decompressing and
  inserting RRs from an authority zone transfer. This stops
  large memory use and heap buffer-overflow read errors. Thanks
  to Haruto Kimura (Stella) for the report.
2026-03-24 08:45:52 +01:00
W.C.A. Wijngaards 535d899bef - Fix for testcode pktview to check buffer size and log errors. 2026-03-20 15:57:46 +01:00
W.C.A. Wijngaards 8656cfd4c8 - Fix to add tls-service-key to memory printout for fast_reload. 2026-03-13 16:49:34 +01:00
W.C.A. Wijngaards 8f44ddb7de - Fix detection of http listening port in fast_reload. 2026-03-13 16:37:41 +01:00
W.C.A. Wijngaards 4484dc3954 - For #278: fast_reload can reload tls-service-key, tls-service-pem
and tls-cert-bundle changes. It checks the modification time of
  the tls-service-key and tls-service-pem files for update.
2026-03-13 16:25:42 +01:00
W.C.A. Wijngaards eb3bba0724 - iana portlist updated. 2026-03-13 12:05:33 +01:00
W.C.A. Wijngaards 2eff1d8ab5 - Fix #278: DoT: complete unbound restart required on certificate
renew. Fix so that a reload checks if the files have changed, and
  if so, reload the contexts. Also for DoH, DoQ and outgoing DoT.
2026-03-13 11:42:34 +01:00
Yorgos Thessalonikefs 4672fa5b53 - Fix to ignore out-of-zone DNAME records for CNAME synthesis. Thanks
to Yuxiao Wu, Yiyi Wang, Zhang Chao, Baojun Liu, and Haixin Duan from
  Tsinghua University.
2026-03-13 11:28:32 +01:00
W.C.A. Wijngaards 18029fc44f Changelog comment for #1418
- Merge #1418: Apply cache TTL policy to DNAME and synthesized
  CNAME on wire path.
2026-03-09 13:54:37 +01:00
Arunabha DasandGitHub 5c6f56f8f1 Apply cache TTL policy to DNAME and synthesized CNAME on wire path (#1418)
When the scrubber synthesizes a CNAME from a DNAME (authority omits CNAME),
apply cache-min-ttl/cache-max-ttl to both DNAME and synthesized CNAME in
msg_parse so they stay equal and respect config (RFC 6672).

- iterator/iter_scrub.c: In synth_cname_rrset(), clamp TTL to [MIN_TTL,
  MAX_TTL] when !SERVE_ORIGINAL_TTL and write back to both synth CNAME
  and DNAME rrset. Removes FIXME.
2026-03-09 13:53:52 +01:00
W.C.A. Wijngaards 9af29c3ed1 - Fix compile failure in unbound-checkconf for older gcc compiler. 2026-03-09 09:18:43 +01:00
Yorgos Thessalonikefs 76ef8c5803 - Constrain the explicit macros for remote.c:fr_atomic_copy_cfg(). 2026-03-06 17:27:21 +01:00
Yorgos Thessalonikefs 94ef1a8fee - Warn for unused 'nodefault' local-zone configuration in
unbound-checkconf (related to #1416).
2026-03-06 17:05:57 +01:00
Yorgos Thessalonikefs 683241a2f5 - Document the suggestion for a higher value for 'outgoing-range';
helps when the request list is full.
2026-03-06 17:01:41 +01:00
W.C.A. Wijngaards 92ab54641e Changelog entry for #1415
- Merge #1415: Add lock unlock for view in memory error handling.
2026-03-06 08:58:33 +01:00
Andy WarnerandGitHub da3812953a Add lock unlock for view in memory error handling (#1415)
view->lock would be skipped during an out of memory error bailout.
2026-03-06 08:57:54 +01:00
W.C.A. Wijngaards 1bd7c8dfee - Update generated man pages. 2026-03-05 12:15:54 +01:00
W.C.A. Wijngaards 8f96ae7acf - Fix for DNS Rebinding Bypass via SVCB/HTTPS Records in Unbound.
Thanks to Kunta Chu, School of Software, Tsinghua University,
  Taofei Guo, Peking University, and Jianjun Chen, Institute for
  Network Sciences and Cyberspace, Tsinghua University for the
  report. The private-address option is fixed to also elide
  SVCB and HTTPS records that match the filter.
2026-03-05 09:47:13 +01:00
Yorgos Thessalonikefs c4f8e60c85 - For #1411: Introduce a failing case in the rpl test so that it only
passes with the fix in place.
2026-03-04 13:22:42 +01:00
W.C.A. Wijngaards a296b248b0 - For #1411: Fix that the lookup for DNAME uses flag. Fix assertion
in expired calc debug routine.
2026-03-03 17:44:31 +01:00
W.C.A. Wijngaards 1ef131299a For #1411, fix up doc/Changelog. 2026-03-03 08:55:56 +01:00
Arunabha DasandGitHub 5b58a872ef Allow synthesized DNAME TTL=0 to be served from cache within grace period (#1411)
* Allow synthesized DNAME TTL=0 to be served from cache within grace period

Addresses doc/TODO: cache TTL=0 packets properly for synthesis.
- rrset_cache_lookup: allow TTL=0 DNAME within 1s grace for synthesis
- synth_dname_msg: support PACKED_RRSET_UPSTREAM_0TTL, return TTL=0 to client

Reduces recursion when authoritative servers return DNAME with TTL=0 (RFC 2308).
Client response still correctly returns TTL=0.

Note: Test with proper TTL=0 DNSSEC RRSIGs omitted - requires ldns-signzone
to generate valid signatures for TTL=0 RRsets.

* Add iter_dname_ttl0.rpl replay test for DNAME TTL=0
Tests signed DNAME with TTL=0 and RRSIG Original TTL=0 (RFC 4034).
Verifies end-to-end handling of TTL=0 DNAME responses.
2026-03-03 08:51:31 +01:00
W.C.A. Wijngaards 94b04d6d46 - Update generated man pages. 2026-02-27 14:33:55 +01:00
W.C.A. Wijngaards f1a65eb4e8 For #1409: Changelog entry and more text. 2026-02-27 13:55:25 +01:00
Daisuke HIGASHIandGitHub 38e1e3eec3 Documentation CNAME in redirect-type local-zone (#1409) 2026-02-27 13:37:56 +01:00
W.C.A. Wijngaards bff3d762ff - Fix validator to set unchecked when validation recursion
requests are passed. The edns subnet module checks if validation
  is needed for a cache response, and set the validator to protect
  the cache with validation for non-subnet lookups.
2026-02-25 10:59:33 +01:00
Yorgos Thessalonikefs fb322f3e87 - Fixed some typos reported in #1395 by rezky_nightky. 2026-02-23 16:17:40 +01:00
Yorgos Thessalonikefs 2feee13735 - Fix to disallow cache lookup/store in external cachedb when a
forwarder/stub forbids it with the no-cache option.
2026-02-23 14:35:50 +01:00
W.C.A. Wijngaards 1d36696462 - Fix to make the cachedb_val_expired.crpl succeed. 2026-02-23 12:52:10 +01:00
W.C.A. Wijngaards aa4e2a9e69 - Fix to have cachedb not return expired bogus data as non-bogus. 2026-02-23 12:45:14 +01:00
W.C.A. Wijngaards 8e04d04949 - For #1405: local-zone always_refuse also blocks queries of type DS. 2026-02-17 15:36:08 +01:00
W.C.A. Wijngaards c5627dbd52 - Fix to remove unused conditional from cookie timestamp at
worker env.
2026-02-17 11:15:15 +01:00
W.C.A. Wijngaards 014ed9c5ff - Fix that cachedb aggressive negative responses have the RA flag set. 2026-02-16 16:35:37 +01:00
Yorgos Thessalonikefs 16e1e6d375 - Fix #1404: Priming the root key fails after loading ipfire.org RPZ
zones. Fixed by including the ZONEMD RRtype in the list of types to
  ignore for RPZ zones. Analysis and patch provided by ummeegge.
2026-02-16 13:37:19 +01:00
W.C.A. Wijngaards 1a9a4e4ca1 - Fix #1403: Inconsistency between do-nat64 and do-not-query-address
during retries.
2026-02-11 16:01:30 +01:00
W.C.A. Wijngaards f7f638e18f - Update generated man pages. 2026-02-09 16:11:17 +01:00
W.C.A. Wijngaards c956aea93d Changelog note and documentation for #1401.
- Merge #1401: Add a new build-time option for system TLS.
  The --enable-system-tls flag enables the
  tls-use-system-policy-versions setting by default.
2026-02-09 16:05:28 +01:00
Petr MenšíkandGitHub 4556a4f490 Add a new build-time option for system TLS (#1401)
We want to use crypto-policy provided configuration always in our
builds. Allow changing the default of tls-use-system-policy-versions at
build time by a simple configure parameter.
2026-02-09 15:57:16 +01:00
Yorgos Thessalonikefs 1cdddf0fe9 - Fix #1389: [FR] replacement with ECC-GOST12 according to RFC9558.
Patch contributed by Igor V. Ruzanov, available in
  contrib/gost12.patch.
2026-02-06 14:39:23 +01:00
Yorgos Thessalonikefs 18fec256b7 - Support pthread_setname_np, and variants, to set the name on spawned
threads for easier debugging/monitoring.
2026-02-06 14:17:04 +01:00
W.C.A. Wijngaards 567c70dada Fix attribution of fix. 2026-02-04 14:17:56 +01:00
W.C.A. Wijngaards 8b4b2a88f7 - Fix local privilege escalation on Windows. Thanks to Hao Huang
for the report. The OpenSSL init calls are set to not load
  the openssl.cnf file when compiled for Windows.
2026-02-04 11:54:11 +01:00
Yorgos Thessalonikefs faf40c97fc - Eagerly remove .skip mark files in between mini_tdir.sh runs in case
there has been a change on the environment.
2026-02-03 15:08:59 +01:00
101 changed files with 6001 additions and 538 deletions
+8 -6
View File
@@ -173,7 +173,7 @@ jobs:
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: false
persist-credentials: false
@@ -189,6 +189,8 @@ jobs:
cd ..
export prepath=`pwd`
echo prepath=${prepath}
# parralel build option
export MINJ="-j4"
echo "choco install winflexbison3"
choco install winflexbison3
echo 'LEX="win_flex"'
@@ -211,8 +213,8 @@ jobs:
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
# make the libs only, build faster
echo "make build_libs"
#make
make build_libs
#make $MINJ
make $MINJ build_libs
mv Makefile Makefile.orig
# fixup \\ in the installtop to /.
echo "fixup INSTALLTOP"
@@ -244,7 +246,7 @@ jobs:
mv xmlwf/Makefile xmlwf/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < xmlwf/Makefile.orig > xmlwf/Makefile
echo "make"
make
make $MINJ
echo "make install"
make install
cd ..
@@ -252,7 +254,7 @@ jobs:
cd unbound
echo "./configure --enable-debug --enable-static-exe --disable-flto \"--with-ssl=$prepath/openssl\" --with-libexpat=\"$prepath/expat\" --disable-shared"
./configure --enable-debug --enable-static-exe --disable-flto "--with-ssl=$prepath/openssl" --with-libexpat="$prepath/expat" --disable-shared
make
make $MINJ
# specific test output
#make testbound.exe; ./testbound.exe -s
#make testbound; ./testbound.exe -p testdata/acl.rpl -o -vvvv
@@ -347,7 +349,7 @@ jobs:
echo "::endgroup::"
- name: cross-platform-action on ${{ matrix.cross_platform_os }} ${{ matrix.cross_platform_version }}
if: ${{ matrix.with_cross_platform_action == 'yes' }}
uses: cross-platform-actions/action@v0.25.0
uses: cross-platform-actions/action@v1.0.0
env:
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
with:
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: configure
+11 -4
View File
@@ -754,8 +754,10 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
"(original ttl: %d)", (int)original_ttl);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
/* By setting this to unchecked, bogus data is not returned
* as non-bogus. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
qstate->return_msg->rep->security = sec_status_insecure;
qstate->return_msg->rep->security = sec_status_unchecked;
}
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
@@ -803,8 +805,11 @@ cachedb_handle_query(struct module_qstate* qstate,
return;
}
if(qstate->blacklist || qstate->no_cache_lookup) {
/* cache is blacklisted or we are instructed from edns to not look */
if(qstate->blacklist || qstate->no_cache_lookup
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
NULL, 0)) {
/* cache is blacklisted or we are instructed from edns to not
* look or a forwarder/stub forbids it */
/* pass request to next module */
qstate->ext_state[id] = module_wait_module;
return;
@@ -892,7 +897,9 @@ cachedb_handle_response(struct module_qstate* qstate,
{
qstate->is_cachedb_answer = 0;
/* check if we are not enabled or instructed to not cache, and skip */
if(!ie->enabled || qstate->no_cache_store) {
if(!ie->enabled || qstate->no_cache_store
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
NULL, 0)) {
/* we are done with the query */
qstate->ext_state[id] = module_finished;
return;
+2 -2
View File
@@ -48,8 +48,8 @@ typedef struct
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k";
static const char ATTR_NONSTRING(sigma[16]) = "expand 32-byte k";
static const char ATTR_NONSTRING(tau[16]) = "expand 16-byte k";
static void
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
+1 -4
View File
@@ -42,10 +42,7 @@ static const int year_lengths[2] = {
};
static void
timesub(timep, offset, tmp)
const time_t * const timep;
const long offset;
struct tm * const tmp;
timesub(const time_t * const timep, const long offset, struct tm * const tmp)
{
long days;
long rem;
+21
View File
@@ -564,12 +564,27 @@
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the <pthread_np.h> header file. */
#undef HAVE_PTHREAD_NP_H
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if the system has the type `pthread_rwlock_t'. */
#undef HAVE_PTHREAD_RWLOCK_T
/* Define if pthread_setname_np has the common 2 arguments. */
#undef HAVE_PTHREAD_SETNAME_NP
/* Define if pthread_setname_np has only 1 argument. */
#undef HAVE_PTHREAD_SETNAME_NP1
/* Define if pthread_setname_np has 3 arguments. */
#undef HAVE_PTHREAD_SETNAME_NP3
/* Define if pthread_setname_np exists as pthread_set_name_np instead. */
#undef HAVE_PTHREAD_SET_NAME_NP
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
#undef HAVE_PTHREAD_SPINLOCK_T
@@ -735,6 +750,12 @@
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
/* Define if you have Swig libraries and header files. */
#undef HAVE_SWIG
Vendored
+195 -13
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.3.
# Generated by GNU Autoconf 2.71 for unbound 1.25.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl 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.3'
PACKAGE_STRING='unbound 1.24.3'
PACKAGE_VERSION='1.25.0'
PACKAGE_STRING='unbound 1.25.0'
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.24.3 to adapt to many kinds of systems.
\`configure' configures unbound 1.25.0 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.3:";;
short | recursive ) echo "Configuration of unbound 1.25.0:";;
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.3
unbound configure 1.25.0
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.3, which was
It was created by unbound $as_me 1.25.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3251,9 +3251,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=24
UNBOUND_VERSION_MINOR=25
UNBOUND_VERSION_MICRO=3
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
@@ -3360,7 +3360,7 @@ LIBUNBOUND_AGE=1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# 1.24.2 had 9:35:1
# 1.24.3 had 9:36:1
# 1.25.0 had 9:36:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -19080,6 +19080,171 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
if test x_$ub_have_pthreads != x_no; then
# Long checks to support pthread_setname_np().
# Some OSes have the extra non-portable functions in a specific
# header file.
ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default
"
if test "x$ac_cv_header_pthread_np_h" = xyes
then :
printf "%s\n" "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h
fi
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
# MacOS only has 1 argument, the name.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has only 1 argument" >&5
printf %s "checking whether pthread_setname_np has only 1 argument... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
int
main (void)
{
(void)pthread_setname_np("");
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP1 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
# NetBSD has 3 arguments to allow for formatting of the name.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has 3 arguments" >&5
printf %s "checking whether pthread_setname_np has 3 arguments... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
int
main (void)
{
(void)pthread_setname_np(0, "", NULL);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP3 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
# Most OSes have the common 2 arguments, thread and name.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has the common 2 arguments" >&5
printf %s "checking whether pthread_setname_np has the common 2 arguments... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
int
main (void)
{
(void)pthread_setname_np(0, "");
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
# FreeBSD/OpenBSD use a slightly different function name.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np exists as pthread_set_name_np instead" >&5
printf %s "checking whether pthread_setname_np exists as pthread_set_name_np instead... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
int
main (void)
{
(void)pthread_set_name_np(0, "");
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_PTHREAD_SET_NAME_NP 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$BAKCFLAGS"
fi
# check solaris thread library
# Check whether --with-solaris-threads was given.
@@ -23264,6 +23429,23 @@ printf "%s\n" "no" >&6; }
fi
fi
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec" "ac_cv_member_struct_stat_st_mtimensec" "$ac_includes_default"
if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_struct_stat_st_mtim_tv_nsec" "$ac_includes_default"
if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" "
@@ -25369,7 +25551,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.24.3
version=1.25.0
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
printf %s "checking for build time... " >&6; }
@@ -25899,7 +26081,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.3, which was
This file was extended by unbound $as_me 1.25.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25967,7 +26149,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.3
unbound config.status 1.25.0
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+74 -3
View File
@@ -11,8 +11,8 @@ 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],[3])
m4_define([VERSION_MINOR],[25])
m4_define([VERSION_MICRO],[0])
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])
@@ -122,7 +122,7 @@ LIBUNBOUND_AGE=1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# 1.24.2 had 9:35:1
# 1.24.3 had 9:36:1
# 1.25.0 had 9:36:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -731,6 +731,76 @@ int main(void) {return 0;}
])
fi
if test x_$ub_have_pthreads != x_no; then
# Long checks to support pthread_setname_np().
# Some OSes have the extra non-portable functions in a specific
# header file.
AC_CHECK_HEADERS([pthread_np.h],,, [AC_INCLUDES_DEFAULT])
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
# MacOS only has 1 argument, the name.
AC_MSG_CHECKING([whether pthread_setname_np has only 1 argument])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
],[
(void)pthread_setname_np("");
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP1, 1, [Define if pthread_setname_np has only 1 argument.])
],[
AC_MSG_RESULT(no)
])
# NetBSD has 3 arguments to allow for formatting of the name.
AC_MSG_CHECKING([whether pthread_setname_np has 3 arguments])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
],[
(void)pthread_setname_np(0, "", NULL);
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP3, 1, [Define if pthread_setname_np has 3 arguments.])
],[
AC_MSG_RESULT(no)
])
# Most OSes have the common 2 arguments, thread and name.
AC_MSG_CHECKING([whether pthread_setname_np has the common 2 arguments])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
],[
(void)pthread_setname_np(0, "");
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Define if pthread_setname_np has the common 2 arguments.])
],[
AC_MSG_RESULT(no)
])
# FreeBSD/OpenBSD use a slightly different function name.
AC_MSG_CHECKING([whether pthread_setname_np exists as pthread_set_name_np instead])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
],[
(void)pthread_set_name_np(0, "");
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [Define if pthread_setname_np exists as pthread_set_name_np instead.])
],[
AC_MSG_RESULT(no)
])
CFLAGS="$BAKCFLAGS"
fi
# check solaris thread library
AC_ARG_WITH(solaris-threads, AS_HELP_STRING([--with-solaris-threads],[use solaris native thread library.]), [ ],[ withval="no" ])
ub_have_sol_threads=no
@@ -1769,6 +1839,7 @@ if test $ac_cv_func_daemon = yes; then
])
fi
AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec])
AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[
AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_UN_H
+2
View File
@@ -58,3 +58,5 @@ distribution but may be helpful.
* unbound.init_yocto: An init script to start and stop the server. Put it
in /etc/init.d/unbound to use it. It is for the Yocto Project, in
embedded systems, contributed by beni-sandu.
* gost12.patch: adds ECC-GOST12 support for the informational RFC9558.
Contributed by Igor V. Ruzanov.
+325
View File
@@ -0,0 +1,325 @@
diff --git a/sldns/keyraw.c b/sldns/keyraw.c
index 42a9262a3..cc6406a56 100644
--- a/sldns/keyraw.c
+++ b/sldns/keyraw.c
@@ -85,7 +85,7 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
}
break;
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
return 512;
#endif
#ifdef USE_ECDSA
@@ -146,7 +146,7 @@ sldns_key_EVP_load_gost_id(void)
if(gost_id) return gost_id;
/* see if configuration loaded gost implementation from other engine*/
- meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
+ meth = EVP_PKEY_asn1_find_str(NULL, "gost2012_256", -1);
if(meth) {
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
@@ -170,7 +170,7 @@ sldns_key_EVP_load_gost_id(void)
return 0;
}
- meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
+ meth = EVP_PKEY_asn1_find_str(&e, "gost2012_256", -1);
if(!meth) {
/* algo not found */
ENGINE_finish(e);
@@ -536,12 +536,17 @@ EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
EVP_PKEY*
sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
{
- /* prefix header for X509 encoding */
- uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
- 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
- unsigned char encoded[37+64];
+ /* prefix header for X509 encoding
+ *
+ * note: based on draft-makarenko-gost2012-dnssec-01 (pre-RFC9558 and it DOES work!)
+ * ASN1 header described in RFC9558 is not suitable due to d2i_PUBKEY() works with
+ * non-compressed public keys (two additional bytes 0x04, 0x40 at the end of header)
+ */
+ uint8_t asn[32] = { 0x30, 0x5e, 0x30, 0x17, 0x06, 0x08, 0x2a, 0x85,
+ 0x03, 0x07, 0x01, 0x01, 0x01, 0x01, 0x30, 0x0b,
+ 0x06, 0x09, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x02,
+ 0x01, 0x01, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40 };
+ unsigned char encoded[32+64];
const unsigned char* pp;
if(keylen != 64) {
/* key wrong size */
@@ -549,8 +554,8 @@ sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
}
/* create evp_key */
- memmove(encoded, asn, 37);
- memmove(encoded+37, key, 64);
+ memmove(encoded, asn, 32);
+ memmove(encoded+32, key, 64);
pp = (unsigned char*)&encoded[0];
return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
diff --git a/sldns/rrdef.h b/sldns/rrdef.h
index bbc3d5b86..7d5f3c057 100644
--- a/sldns/rrdef.h
+++ b/sldns/rrdef.h
@@ -384,11 +384,12 @@ enum sldns_enum_algorithm
LDNS_RSASHA1_NSEC3 = 7,
LDNS_RSASHA256 = 8, /* RFC 5702 */
LDNS_RSASHA512 = 10, /* RFC 5702 */
- LDNS_ECC_GOST = 12, /* RFC 5933 */
+ LDNS_ECC_GOST = 12, /* RFC 5933, deprecated */
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
LDNS_ED25519 = 15, /* RFC 8080 */
LDNS_ED448 = 16, /* RFC 8080 */
+ LDNS_ECC_GOST12 = 23, /* RFC 9558 */
LDNS_INDIRECT = 252,
LDNS_PRIVATEDNS = 253,
LDNS_PRIVATEOID = 254
@@ -402,8 +403,9 @@ enum sldns_enum_hash
{
LDNS_SHA1 = 1, /* RFC 4034 */
LDNS_SHA256 = 2, /* RFC 4509 */
- LDNS_HASH_GOST = 3, /* RFC 5933 */
- LDNS_SHA384 = 4 /* RFC 6605 */
+ LDNS_HASH_GOST = 3, /* RFC 5933, deprecated */
+ LDNS_SHA384 = 4, /* RFC 6605 */
+ LDNS_HASH_GOST12 = 5 /* RFC 9558 */
};
typedef enum sldns_enum_hash sldns_hash;
diff --git a/sldns/wire2str.c b/sldns/wire2str.c
index 75b8f37b0..b4c4755e6 100644
--- a/sldns/wire2str.c
+++ b/sldns/wire2str.c
@@ -45,11 +45,12 @@ static sldns_lookup_table sldns_algorithms_data[] = {
{ LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
{ LDNS_RSASHA256, "RSASHA256"},
{ LDNS_RSASHA512, "RSASHA512"},
- { LDNS_ECC_GOST, "ECC-GOST"},
+ { LDNS_ECC_GOST, "ECC-GOST"}, /* deprecated */
{ LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
{ LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
{ LDNS_ED25519, "ED25519"},
{ LDNS_ED448, "ED448"},
+ { LDNS_ECC_GOST12, "ECC-GOST12"},
{ LDNS_INDIRECT, "INDIRECT" },
{ LDNS_PRIVATEDNS, "PRIVATEDNS" },
{ LDNS_PRIVATEOID, "PRIVATEOID" },
@@ -61,8 +62,9 @@ sldns_lookup_table* sldns_algorithms = sldns_algorithms_data;
static sldns_lookup_table sldns_hashes_data[] = {
{ LDNS_SHA1, "SHA1" },
{ LDNS_SHA256, "SHA256" },
- { LDNS_HASH_GOST, "HASH-GOST" },
+ { LDNS_HASH_GOST, "HASH-GOST" }, /* deprecated */
{ LDNS_SHA384, "SHA384" },
+ { LDNS_HASH_GOST12, "HASH-GOST12" },
{ 0, NULL }
};
sldns_lookup_table* sldns_hashes = sldns_hashes_data;
diff --git a/testcode/unitverify.c b/testcode/unitverify.c
index fcf2e2ffe..4a33e9f6a 100644
--- a/testcode/unitverify.c
+++ b/testcode/unitverify.c
@@ -696,7 +696,7 @@ verify_test(void)
#endif
#ifdef USE_GOST
if(sldns_key_EVP_load_gost_id())
- verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504");
+ verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost12", "20251226060504");
else printf("Warning: skipped GOST, openssl does not provide gost.\n");
#endif
#ifdef USE_ECDSA
diff --git a/testdata/test_sigs.gost12 b/testdata/test_sigs.gost12
new file mode 100644
index 000000000..72a250cff
--- /dev/null
+++ b/testdata/test_sigs.gost12
@@ -0,0 +1,39 @@
+; Signature test file
+
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification.
+; later entries are verified with it.
+
+; Test GOST signatures using algo number 23.
+
+ENTRY_BEGIN
+SECTION QUESTION
+nlnetlabs.nl. IN DNSKEY
+SECTION ANSWER
+nlnetlabs.nl. 3600 IN DNSKEY 256 3 23 cdOtkEcb6NhcdOpIbPYtWyWxdlUiKgtKQbYg3lIjtG7i3fYjUID9zyOgoQEiV9wuGCfrw5cNsnvNw+8HiVFK4g== ;{id = 12301 (zsk), size = 512b}
+ENTRY_END
+
+; entry to test
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN A
+SECTION ANSWER
+open.nlnetlabs.nl. 600 IN A 213.154.224.1
+open.nlnetlabs.nl. 600 IN RRSIG A 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. I12wYNs96DxMy26CWx296/sWMJAFg4nNXBo0sw7PnuMbJW5NFAmZYtFWhUdOWn4umaiodYOAmKG8Zg/OKvEtAQ==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN AAAA
+SECTION ANSWER
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::1
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::53
+open.nlnetlabs.nl. 600 IN RRSIG AAAA 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. J0jHa+CP8HM6UDa2+uYgaze2mfpJTh2hkZ2KwMTYb5sfL6iBmxxql0c/403Itk4fMfYBMGn7zfzDQ+CxnCgSWw==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN NSEC
+SECTION ANSWER
+open.nlnetlabs.nl. 86400 IN NSEC nlnetlabs.nl. A AAAA RRSIG NSEC
+open.nlnetlabs.nl. 86400 IN RRSIG NSEC 23 3 86400 20260122084903 20251225084903 12301 nlnetlabs.nl. INCLYe9vAaNYaYx5Ay3Q6QdX+wPW9sMRvVlGt/jUEGgCi+88QlV80CT1oHrhRI66I14Wk6NRAGZRNx1tUPSHSg==
+ENTRY_END
diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c
index be8347b1b..4f621a309 100644
--- a/validator/val_secalgo.c
+++ b/validator/val_secalgo.c
@@ -246,10 +246,10 @@ ds_digest_size_supported(int algo)
return SHA256_DIGEST_LENGTH;
#endif
#ifdef USE_GOST
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
/* we support GOST if it can be loaded */
(void)sldns_key_EVP_load_gost_id();
- if(EVP_get_digestbyname("md_gost94"))
+ if(EVP_get_digestbyname("md_gost12_256"))
return 32;
else return 0;
#endif
@@ -265,9 +265,9 @@ ds_digest_size_supported(int algo)
#ifdef USE_GOST
/** Perform GOST hash */
static int
-do_gost94(unsigned char* data, size_t len, unsigned char* dest)
+do_gost12(unsigned char* data, size_t len, unsigned char* dest)
{
- const EVP_MD* md = EVP_get_digestbyname("md_gost94");
+ const EVP_MD* md = EVP_get_digestbyname("md_gost12_256");
if(!md)
return 0;
return sldns_digest_evp(data, (unsigned int)len, dest, md);
@@ -302,8 +302,8 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return 1;
#endif
#ifdef USE_GOST
- case LDNS_HASH_GOST:
- if(do_gost94(buf, len, res))
+ case LDNS_HASH_GOST12:
+ if(do_gost12(buf, len, res))
return 1;
break;
#endif
@@ -384,7 +384,7 @@ dnskey_algo_id_is_supported(int id)
#endif
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
/* we support GOST if it can be loaded */
return sldns_key_EVP_load_gost_id();
#endif
@@ -612,17 +612,17 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
break;
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
*evp_key = sldns_gost2pkey_raw(key, keylen);
if(!*evp_key) {
verbose(VERB_QUERY, "verify: "
"sldns_gost2pkey_raw failed");
return 0;
}
- *digest_type = EVP_get_digestbyname("md_gost94");
+ *digest_type = EVP_get_digestbyname("md_gost12_256");
if(!*digest_type) {
verbose(VERB_QUERY, "verify: "
- "EVP_getdigest md_gost94 failed");
+ "EVP_getdigest md_gost12_256 failed");
return 0;
}
break;
@@ -964,7 +964,7 @@ ds_digest_size_supported(int algo)
return SHA384_LENGTH;
#endif
/* GOST not supported in NSS */
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
default: break;
}
return 0;
@@ -991,7 +991,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
== SECSuccess;
#endif
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
default:
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
algo);
@@ -1031,7 +1031,7 @@ dnskey_algo_id_is_supported(int id)
case LDNS_ECDSAP384SHA384:
return PK11_TokenExists(CKM_ECDSA);
#endif
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
return 0;
}
@@ -1352,7 +1352,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
/* no prefix for DSA verification */
break;
#endif /* USE_ECDSA */
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
verbose(VERB_QUERY, "verify: unknown algorithm %d",
algo);
@@ -1675,7 +1675,7 @@ ds_digest_size_supported(int algo)
return SHA384_DIGEST_SIZE;
#endif
/* GOST not supported */
- case LDNS_HASH_GOST:
+ case LDNS_ECC_GOST12:
default:
break;
}
@@ -1700,7 +1700,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res);
#endif
- case LDNS_HASH_GOST:
+ case LDNS_ECC_GOST12:
default:
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
algo);
@@ -1744,7 +1744,7 @@ dnskey_algo_id_is_supported(int id)
return 1;
#endif
case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
return 0;
}
@@ -2103,7 +2103,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_secure;
#endif
case LDNS_RSAMD5:
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
*reason = "unable to verify signature, unknown algorithm";
return sec_status_bogus;
+274 -11
View File
@@ -199,6 +199,255 @@ signal_handling_playback(struct worker* wrk)
sig_record_reload = 0;
}
#ifdef HAVE_SSL
/* setup a listening ssl context, fatal_exit() on any failure */
static void
setup_listen_sslctx(void** ctx, int is_dot, int is_doh,
struct config_file* cfg, char* chroot)
{
char* key = cfg->ssl_service_key;
char* pem = cfg->ssl_service_pem;
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
key += strlen(chroot);
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
pem += strlen(chroot);
if(!(*ctx = listen_sslctx_create(key, pem, NULL,
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, cfg->tls_protocols))) {
fatal_exit("could not set up listen SSL_CTX");
}
}
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
void* daemon_setup_listen_dot_sslctx(struct daemon* daemon,
struct config_file* cfg)
{
void* ctx;
(void)setup_listen_sslctx(&ctx, 1, 0, cfg, daemon->chroot);
return ctx;
}
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
#ifdef HAVE_NGHTTP2_NGHTTP2_H
void* daemon_setup_listen_doh_sslctx(struct daemon* daemon,
struct config_file* cfg)
{
void* ctx;
(void)setup_listen_sslctx(&ctx, 0, 1, cfg, daemon->chroot);
return ctx;
}
#endif /* HAVE_NGHTTP2_NGHTTP2_H */
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
#ifdef HAVE_NGTCP2
void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
struct config_file* cfg)
{
void* ctx;
char* chroot = daemon->chroot;
char* key = cfg->ssl_service_key;
char* pem = cfg->ssl_service_pem;
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
key += strlen(chroot);
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
pem += strlen(chroot);
if(!(ctx = quic_sslctx_create(key, pem, NULL))) {
fatal_exit("could not set up quic SSL_CTX");
}
return ctx;
}
#endif /* HAVE_NGTCP2 */
#endif /* HAVE_SSL */
#ifdef HAVE_SSL
void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
struct config_file* cfg)
{
void* ctx;
char* bundle, *chroot = daemon->chroot;
bundle = cfg->tls_cert_bundle;
if(chroot && bundle && strncmp(bundle, chroot, strlen(chroot)) == 0)
bundle += strlen(chroot);
if(!(ctx = connect_sslctx_create(NULL, NULL, bundle,
cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
return ctx;
}
#endif /* HAVE_SSL */
/* setups the needed ssl contexts, fatal_exit() on any failure */
void
daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
{
#ifdef HAVE_SSL
char* chroot = daemon->chroot;
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
char* key = cfg->ssl_service_key;
char* pem = cfg->ssl_service_pem;
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
key += strlen(chroot);
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
pem += strlen(chroot);
/* setup the session keys; the callback to use them will be
* attached to each sslctx separately */
if(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0) {
if(!listen_sslctx_setup_ticket_keys(
cfg->tls_session_ticket_keys.first, chroot)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
daemon->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(
daemon, cfg);
#ifdef HAVE_NGHTTP2_NGHTTP2_H
if(cfg_has_https(cfg)) {
daemon->listen_doh_sslctx =
daemon_setup_listen_doh_sslctx(daemon, cfg);
}
#endif
#ifdef HAVE_NGTCP2
if(cfg_has_quic(cfg)) {
daemon->listen_quic_sslctx =
daemon_setup_listen_quic_sslctx(daemon, cfg);
}
#endif /* HAVE_NGTCP2 */
/* Store the file name and mtime to detect changes later. */
daemon->ssl_service_key = strdup(cfg->ssl_service_key);
if(!daemon->ssl_service_key)
fatal_exit("could not setup ssl ctx: out of memory");
if(cfg->ssl_service_pem) {
daemon->ssl_service_pem = strdup(cfg->ssl_service_pem);
if(!daemon->ssl_service_pem)
fatal_exit("could not setup ssl ctx: out of memory");
} else {
daemon->ssl_service_pem = NULL;
}
if(!file_get_mtime(key,
&daemon->mtime_ssl_service_key,
&daemon->mtime_ns_ssl_service_key, NULL))
log_err("Could not stat(%s): %s",
key, strerror(errno));
if(pem) {
if(!file_get_mtime(pem,
&daemon->mtime_ssl_service_pem,
&daemon->mtime_ns_ssl_service_pem, NULL))
log_err("Could not stat(%s): %s",
pem, strerror(errno));
} else {
daemon->mtime_ssl_service_pem = 0;
daemon->mtime_ns_ssl_service_pem = 0;
}
}
daemon->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
daemon, cfg);
#else /* HAVE_SSL */
(void)daemon;(void)cfg;
#endif /* HAVE_SSL */
}
/** Delete the ssl ctxs */
static void
daemon_delete_sslctxs(struct daemon* daemon)
{
#ifdef HAVE_SSL
listen_sslctx_delete_ticket_keys();
SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx);
daemon->listen_dot_sslctx = NULL;
SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx);
daemon->listen_doh_sslctx = NULL;
SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx);
daemon->connect_dot_sslctx = NULL;
free(daemon->ssl_service_key);
daemon->ssl_service_key = NULL;
free(daemon->ssl_service_pem);
daemon->ssl_service_pem = NULL;
#else
(void)daemon;
#endif
#ifdef HAVE_NGTCP2
SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx);
daemon->listen_quic_sslctx = NULL;
#endif
}
int
ssl_cert_changed(struct daemon* daemon, struct config_file* cfg)
{
time_t mtime = 0;
long ns = 0;
char* chroot = daemon->chroot;
char* key = cfg->ssl_service_key;
char* pem = cfg->ssl_service_pem;
log_assert(daemon->ssl_service_key && cfg->ssl_service_key);
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
key += strlen(chroot);
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
pem += strlen(chroot);
if(strcmp(daemon->ssl_service_key, cfg->ssl_service_key) != 0)
return 1;
if(daemon->ssl_service_pem && cfg->ssl_service_pem &&
strcmp(daemon->ssl_service_pem, cfg->ssl_service_pem) != 0)
return 1;
if(!file_get_mtime(key, &mtime, &ns, NULL)) {
log_err("Could not stat(%s): %s",
key, strerror(errno));
/* It has probably changed, but file read is likely going to
* fail. */
return 0;
}
if(mtime != daemon->mtime_ssl_service_key ||
ns != daemon->mtime_ns_ssl_service_key)
return 1;
if(pem) {
if(!file_get_mtime(pem, &mtime, &ns, NULL)) {
log_err("Could not stat(%s): %s",
pem, strerror(errno));
/* It has probably changed, but file read is likely going to
* fail. */
return 0;
}
if(mtime != daemon->mtime_ssl_service_pem ||
ns != daemon->mtime_ns_ssl_service_pem)
return 1;
}
return 0;
}
/** Reload the sslctxs if they have changed */
static void
daemon_reload_sslctxs(struct daemon* daemon)
{
#ifdef HAVE_SSL
if(daemon->cfg->ssl_service_key && daemon->cfg->ssl_service_key[0]) {
/* See if changed */
if(!daemon->ssl_service_key ||
ssl_cert_changed(daemon,daemon->cfg)) {
verbose(VERB_ALGO, "Reloading certificates");
daemon_delete_sslctxs(daemon);
daemon_setup_sslctxs(daemon, daemon->cfg);
}
} else {
/* See if sslctxs are removed from config. */
if(daemon->ssl_service_key) {
verbose(VERB_ALGO, "Removing certificates");
daemon_delete_sslctxs(daemon);
}
}
#else
(void)daemon;
#endif
}
struct daemon*
daemon_init(void)
{
@@ -235,7 +484,11 @@ daemon_init(void)
# else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
# endif
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
/* grab the COMP method ptr because openssl leaks it */
@@ -244,7 +497,11 @@ daemon_init(void)
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
# else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
# endif
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
if(!ub_openssl_lock_init())
@@ -662,7 +919,14 @@ thread_start(void* arg)
{
struct worker* worker = (struct worker*)arg;
int port_num = 0;
log_assert(worker->thr_id);
set_log_thread_id(worker, worker->daemon->cfg);
{
char name[16]; /* seems to be the safest size between
different OSes */
snprintf(name, sizeof(name), "unbound/%u", worker->thread_num);
ub_thread_setname(worker->thr_id, name);
}
ub_thread_blocksigs();
#ifdef THREADS_DISABLED
/* close pipe ends used by main */
@@ -737,6 +1001,7 @@ daemon_fork(struct daemon* daemon)
#endif
log_assert(daemon);
daemon_reload_sslctxs(daemon);
if(!(daemon->env->views = views_create()))
fatal_exit("Could not create views: out of memory");
/* create individual views and their localzone/data trees */
@@ -829,6 +1094,12 @@ daemon_fork(struct daemon* daemon)
* the thread_start() procedure.
*/
set_log_thread_id(daemon->workers[0], daemon->cfg);
/* If shm stats need an offset, calculate it */
if(daemon->cfg->shm_enable && daemon->cfg->stat_interval > 0) {
daemon->stat_time_specific = 1;
daemon->stat_time_offset =
((int)time(NULL))%daemon->cfg->stat_interval;
}
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
/* in libev the first inited base gets signals */
@@ -983,15 +1254,7 @@ daemon_delete(struct daemon* daemon)
free(daemon->pidfile);
free(daemon->cfgfile);
free(daemon->env);
#ifdef HAVE_SSL
listen_sslctx_delete_ticket_keys();
SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx);
#endif
#ifdef HAVE_NGTCP2
SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx);
#endif
daemon_delete_sslctxs(daemon);
free(daemon);
/* lex cleanup */
ub_c_lex_destroy();
+41
View File
@@ -107,6 +107,18 @@ struct daemon {
void* listen_doh_sslctx;
/** ssl context for listening to quic */
void* listen_quic_sslctx;
/** the file name that the ssl context is made with, private key. */
char* ssl_service_key;
/** the file name that the ssl context is made with, certificate. */
char* ssl_service_pem;
/** modification time for ssl_service_key, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_key;
long mtime_ns_ssl_service_key;
/** modification time for ssl_service_pem, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_pem;
long mtime_ns_ssl_service_pem;
/** num threads allocated */
int num;
/** num threads allocated in the previous config or 0 at first */
@@ -143,7 +155,14 @@ struct daemon {
/** the dnstap environment master value, copied and changed by threads*/
struct dt_env* dtenv;
#endif
/** The SHM info for shared memory stats. */
struct shm_main_info* shm_info;
/** if the timeout for statistics is attempted at specific offset.
* If it is true, the stat timeout is the interval+offset, and that
* picks (roughly) the same time offset every time period. */
int stat_time_specific;
/** if the timeout is specific, what offset in the period. */
int stat_time_offset;
/** some response-ip tags or actions are configured if true */
int use_response_ip;
/** some RPZ policies are configured */
@@ -229,4 +248,26 @@ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
*/
int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list);
/* setups the needed ssl contexts, fatal_exit() on any failure */
void daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg);
/** See if the SSL cert files have changed */
int ssl_cert_changed(struct daemon* daemon, struct config_file* cfg);
/** Setup the listening DoT SSL_CTX, returns the ssl ctx. */
void* daemon_setup_listen_dot_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the listening DoH SSL_CTX, returns the ssl ctx. */
void* daemon_setup_listen_doh_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the listening Quic SSL_CTX, returns the ssl ctx */
void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the connect DoT SSL_CTX, returns the ssl ctx */
void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
struct config_file* cfg);
#endif /* DAEMON_H */
+253 -5
View File
@@ -153,7 +153,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, cfg->tls_use_system_policy_versions)) {
if(!listen_sslctx_setup(rc->ctx, cfg->tls_protocols)) {
return 0;
}
@@ -307,6 +307,26 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
#endif
}
} else {
char* s = strchr(ip, '@');
char newif[128];
if(s) {
/* override port with ifspec@port */
int portnr;
if((size_t)(s-ip) >= sizeof(newif)) {
log_err("ifname too long: %s", ip);
return -1;
}
portnr = atoi(s+1);
if(portnr < 0 || 0 == portnr || portnr > 65535) {
log_err("invalid portnumber in control-interface: %s", ip);
return -1;
}
(void)strlcpy(newif, ip, sizeof(newif));
newif[s-ip] = 0;
ip = newif;
snprintf(port, sizeof(port), "%d", portnr);
port[sizeof(port)-1]=0;
}
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
@@ -4633,6 +4653,26 @@ fr_init_time(struct timeval* time_start, struct timeval* time_read,
* are kept in here. They can then be deleted.
*/
struct fast_reload_construct {
/** ssl context for listening to dnstcp over ssl */
void* listen_dot_sslctx;
/** ssl context for connecting to dnstcp over ssl */
void* connect_dot_sslctx;
/** ssl context for listening to DoH */
void* listen_doh_sslctx;
/** ssl context for listening to quic */
void* listen_quic_sslctx;
/** the file name that the ssl context is made with, private key. */
char* ssl_service_key;
/** the file name that the ssl context is made with, certificate. */
char* ssl_service_pem;
/** modification time for ssl_service_key, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_key;
long mtime_ns_ssl_service_key;
/** modification time for ssl_service_pem, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_pem;
long mtime_ns_ssl_service_pem;
/** construct for views */
struct views* views;
/** construct for auth zones */
@@ -4936,9 +4976,7 @@ fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
FR_CHECK_CHANGED_CFG("http_notls_downstream", http_notls_downstream, changed_str);
FR_CHECK_CHANGED_CFG("https-port", https_port, changed_str);
FR_CHECK_CHANGED_CFG("tls-port", ssl_port, changed_str);
FR_CHECK_CHANGED_CFG_STR("tls-service-key", ssl_service_key, changed_str);
FR_CHECK_CHANGED_CFG_STR("tls-service-pem", ssl_service_pem, changed_str);
FR_CHECK_CHANGED_CFG_STR("tls-cert-bundle", tls_cert_bundle, changed_str);
FR_CHECK_CHANGED_CFG_STR("tls-protocols", tls_protocols, changed_str);
FR_CHECK_CHANGED_CFG_STRLIST("proxy-protocol-port", proxy_protocol_port, changed_str);
FR_CHECK_CHANGED_CFG_STRLIST("tls-additional-port", tls_additional_port, changed_str);
FR_CHECK_CHANGED_CFG_STR("interface-automatic-ports", if_automatic_ports, changed_str);
@@ -5047,6 +5085,19 @@ fr_construct_clear(struct fast_reload_construct* ct)
wait_limits_free(&ct->wait_limits_netblock);
wait_limits_free(&ct->wait_limits_cookie_netblock);
domain_limits_free(&ct->domain_limits);
#ifdef HAVE_SSL
/* The SSL contexts can be SSL_CTX_free here. It is reference
* counted. So ongoing transfers with can continue.
* Once they are done, the context is freed. */
SSL_CTX_free((SSL_CTX*)ct->listen_dot_sslctx);
SSL_CTX_free((SSL_CTX*)ct->connect_dot_sslctx);
SSL_CTX_free((SSL_CTX*)ct->listen_doh_sslctx);
#endif /* HAVE_SSL */
#ifdef HAVE_NGTCP2
SSL_CTX_free((SSL_CTX*)ct->listen_quic_sslctx);
#endif
free(ct->ssl_service_key);
free(ct->ssl_service_pem);
/* Delete the log identity here so that the global value is not
* reset by config_delete. */
if(ct->oldcfg && ct->oldcfg->log_identity) {
@@ -5179,6 +5230,7 @@ config_file_getmem(struct config_file* cfg)
m += getmem_config_strlist(cfg->tls_session_ticket_keys.first);
m += getmem_str(cfg->tls_ciphers);
m += getmem_str(cfg->tls_ciphersuites);
m += getmem_str(cfg->tls_protocols);
m += getmem_str(cfg->http_endpoint);
m += (cfg->outgoing_avail_ports?65536*sizeof(int):0);
m += getmem_str(cfg->target_fetch_policy);
@@ -5295,6 +5347,8 @@ fr_printmem(struct fast_reload_thread* fr,
size_t mem = 0;
if(fr_poll_for_quit(fr))
return 1;
mem += getmem_str(ct->ssl_service_key);
mem += getmem_str(ct->ssl_service_pem);
mem += views_get_mem(ct->views);
mem += respip_set_get_mem(ct->respip_set);
mem += auth_zones_get_mem(ct->auth_zones);
@@ -5528,6 +5582,96 @@ auth_zones_check_changes(struct fast_reload_thread* fr,
return 1;
}
/** Check if the sslctxs have changed. */
static int
fr_check_sslctx_change(struct fast_reload_thread* fr,
struct config_file* newcfg)
{
#ifdef HAVE_SSL
struct daemon* daemon = fr->worker->daemon;
if(newcfg->ssl_service_key && newcfg->ssl_service_key[0]) {
if(!daemon->ssl_service_key ||
ssl_cert_changed(daemon, newcfg))
return 1;
} else {
if(daemon->ssl_service_key)
return 1; /* it is removed */
}
if((daemon->cfg->tls_cert_bundle && !newcfg->tls_cert_bundle) ||
(!daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle) ||
(daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle &&
strcmp(daemon->cfg->tls_cert_bundle, newcfg->tls_cert_bundle)!=0))
return 1; /* The tls-cert-bundle has changed and return
true here makes it reload the connect_dot_sslctx. */
#else
(void)fr; (void)newcfg;
#endif /* HAVE_SSL */
return 0;
}
/** Create the SSL CTXs when they have changed. */
static int
ct_create_sslctxs(struct fast_reload_construct* ct,
struct config_file* newcfg, struct daemon* daemon)
{
#ifdef HAVE_SSL
char* chroot = daemon->chroot;
char* key = newcfg->ssl_service_key;
char* pem = newcfg->ssl_service_pem;
if(!(newcfg->ssl_service_key && newcfg->ssl_service_key[0])) {
/* Leave listen ctxs and file str at NULL */
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
daemon, newcfg);
return 1;
}
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
key += strlen(chroot);
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
pem += strlen(chroot);
ct->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(daemon, newcfg);
#ifdef HAVE_NGHTTP2_NGHTTP2_H
if(cfg_has_https(newcfg)) {
ct->listen_doh_sslctx = daemon_setup_listen_doh_sslctx(
daemon, newcfg);
}
#endif
#ifdef HAVE_NGTCP2
if(cfg_has_quic(newcfg)) {
ct->listen_quic_sslctx = daemon_setup_listen_quic_sslctx(
daemon, newcfg);
}
#endif /* HAVE_NGTCP2 */
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(daemon,
newcfg);
/* Store mtime and names */
ct->ssl_service_key = strdup(newcfg->ssl_service_key);
if(!ct->ssl_service_key) {
log_err("ct_create_sslctxs: out of memory");
return 0;
}
ct->ssl_service_pem = strdup(newcfg->ssl_service_pem);
if(!ct->ssl_service_pem) {
log_err("ct_create_sslctxs: out of memory");
return 0;
}
if(!file_get_mtime(key, &ct->mtime_ssl_service_key,
&ct->mtime_ns_ssl_service_key, NULL))
log_err("Could not stat(%s): %s",
key, strerror(errno));
if(!file_get_mtime(pem, &ct->mtime_ssl_service_pem,
&ct->mtime_ns_ssl_service_pem, NULL))
log_err("Could not stat(%s): %s",
pem, strerror(errno));
#else
(void)ct; (void)newcfg; (void)daemon;
#endif /* HAVE_SSL */
return 1;
}
/** fast reload thread, construct from config the new items */
static int
fr_construct_from_config(struct fast_reload_thread* fr,
@@ -5535,6 +5679,13 @@ fr_construct_from_config(struct fast_reload_thread* fr,
{
int have_view_respip_cfg = 0;
fr->sslctxs_changed = fr_check_sslctx_change(fr, newcfg);
if(fr->sslctxs_changed) {
if(!ct_create_sslctxs(ct, newcfg, fr->worker->daemon)) {
fr_construct_clear(ct);
return 0;
}
}
if(!(ct->views = views_create())) {
fr_construct_clear(ct);
return 0;
@@ -5812,6 +5963,44 @@ auth_zones_swap(struct auth_zones* az, struct auth_zones* data)
* the xfer elements can continue to be their callbacks. */
}
/** Swap two void* */
static void
void_ptr_swap(void** a, void **b)
{
void* tmp = *a;
*a = *b;
*b = tmp;
}
/** Swap two char* */
static void
char_ptr_swap(char** a, char **b)
{
char* tmp = *a;
*a = *b;
*b = tmp;
}
/** Swap and set ssl ctx information */
static void
sslctxs_swap(struct daemon* daemon, struct fast_reload_construct* ct)
{
void_ptr_swap(&daemon->listen_dot_sslctx, &ct->listen_dot_sslctx);
void_ptr_swap(&daemon->connect_dot_sslctx, &ct->connect_dot_sslctx);
#ifdef HAVE_NGHTTP2_NGHTTP2_H
void_ptr_swap(&daemon->listen_doh_sslctx, &ct->listen_doh_sslctx);
#endif
#ifdef HAVE_NGTCP2
void_ptr_swap(&daemon->listen_quic_sslctx, &ct->listen_quic_sslctx);
#endif /* HAVE_NGTCP2 */
char_ptr_swap(&daemon->ssl_service_key, &ct->ssl_service_key);
char_ptr_swap(&daemon->ssl_service_pem, &ct->ssl_service_pem);
daemon->mtime_ssl_service_key = ct->mtime_ssl_service_key;
daemon->mtime_ns_ssl_service_key = ct->mtime_ns_ssl_service_key;
daemon->mtime_ssl_service_pem = ct->mtime_ssl_service_pem;
daemon->mtime_ns_ssl_service_pem = ct->mtime_ns_ssl_service_pem;
}
#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
/** Fast reload thread, if atomics are available, copy the config items
* one by one with atomic store operations. */
@@ -5873,8 +6062,8 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(tls_session_ticket_keys.last);
COPY_VAR_ptr(tls_ciphers);
COPY_VAR_ptr(tls_ciphersuites);
COPY_VAR_ptr(tls_protocols);
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);
@@ -6184,8 +6373,18 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_int(ede);
COPY_VAR_int(iter_scrub_ns);
COPY_VAR_int(iter_scrub_cname);
COPY_VAR_int(iter_scrub_rrsig);
COPY_VAR_int(max_global_quota);
COPY_VAR_int(iter_scrub_promiscuous);
#undef COPY_VAR_int
#undef COPY_VAR_ptr
#undef COPY_VAR_unsigned_int
#undef COPY_VAR_size_t
#undef COPY_VAR_uint8_t
#undef COPY_VAR_uint16_t
#undef COPY_VAR_uint32_t
#undef COPY_VAR_int32_t
}
#endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */
@@ -6411,6 +6610,9 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
daemon->env);
#endif
if(fr->sslctxs_changed) {
sslctxs_swap(daemon, ct);
}
#ifdef USE_DNSTAP
if(env->cfg->dnstap) {
if(!fr->fr_nopause)
@@ -6635,6 +6837,8 @@ static void* fast_reload_thread_main(void* arg)
struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg;
struct timeval time_start, time_read, time_construct, time_reload,
time_end;
const char name[16] = "unbound/freload"; /* seems to be the safest size
between different OSes */
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
fast_reload_thread->thread_tid = gettid();
@@ -6644,6 +6848,9 @@ static void* fast_reload_thread_main(void* arg)
#endif
log_thread_set(&fast_reload_thread->threadnum);
ub_thread_setname(fast_reload_thread->tid, name);
(void)name; /* When setname is not defined, ignore the name variable. */
verbose(VERB_ALGO, "start fast reload thread");
if(fast_reload_thread->fr_verb >= 1) {
fr_init_time(&time_start, &time_read, &time_construct,
@@ -7607,6 +7814,44 @@ fr_worker_pickup_auth_changes(struct worker* worker,
}
}
/** Fast reload, the worker picks up changes in listen_dnsport. */
static void
fr_worker_pickup_listen_dnsport(struct worker* worker)
{
struct listen_dnsport* front = worker->front;
struct daemon* daemon = worker->daemon;
if(worker->daemon->fast_reload_thread->sslctxs_changed) {
struct listen_list* ll;
void* dot_sslctx = daemon->listen_dot_sslctx;
void* doh_sslctx = daemon->listen_doh_sslctx;
#ifdef HAVE_NGTCP2
void* quic_sslctx = daemon->listen_quic_sslctx;
#endif /* HAVE_NGTCP2 */
for(ll = front->cps; ll; ll = ll->next) {
struct comm_point* cp = ll->com;
if(cp->type == comm_tcp_accept &&
cp->tcp_handlers &&
cp->max_tcp_count > 0 &&
cp->tcp_handlers[0]->type == comm_http) {
if(cp->ssl)
cp->ssl = doh_sslctx;
} else if(cp->type == comm_tcp_accept) {
if(cp->ssl)
cp->ssl = dot_sslctx;
#ifdef HAVE_NGTCP2
} else if(cp->type == comm_doq) {
if(cp->ssl) {
cp->ssl = quic_sslctx;
if(cp->doq_socket)
cp->doq_socket->ctx =
(SSL_CTX*)quic_sslctx;
}
#endif /* HAVE_NGTCP2 */
}
}
}
}
/** Fast reload, the worker picks up changes in outside_network. */
static void
fr_worker_pickup_outside_network(struct worker* worker)
@@ -7622,6 +7867,8 @@ fr_worker_pickup_outside_network(struct worker* worker)
outnet->tcp_reuse_timeout = cfg->tcp_reuse_timeout;
outnet->tcp_auth_query_timeout = cfg->tcp_auth_query_timeout;
outnet->delayclose = cfg->delay_close;
if(worker->daemon->fast_reload_thread->sslctxs_changed)
outnet->sslctx = worker->daemon->connect_dot_sslctx;
if(outnet->delayclose) {
#ifndef S_SPLINT_S
outnet->delay_tv.tv_sec = cfg->delay_close/1000;
@@ -7692,6 +7939,7 @@ fast_reload_worker_pickup_changes(struct worker* worker)
#ifdef USE_CACHEDB
worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled;
#endif
fr_worker_pickup_listen_dnsport(worker);
fr_worker_pickup_outside_network(worker);
#ifdef USE_DNSTAP
fr_worker_pickup_dnstap_changes(worker);
+2
View File
@@ -255,6 +255,8 @@ struct fast_reload_thread {
struct fast_reload_auth_change* auth_zone_change_list;
/** the old tree of auth zones, to lookup. */
struct auth_zones* old_auth_zones;
/** If the ssl ctxs have changed. */
int sslctxs_changed;
};
/**
+4 -47
View File
@@ -463,57 +463,13 @@ detach(void)
#endif /* HAVE_DAEMON */
}
#ifdef HAVE_SSL
/* setup a listening ssl context, fatal_exit() on any failure */
/** setup the remote and ticket keys */
static void
setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
{
if(!(*ctx = listen_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL,
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, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen SSL_CTX");
}
}
#endif /* HAVE_SSL */
/* setups the needed ssl contexts, fatal_exit() on any failure */
static void
setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
setup_sslctx_remote(struct daemon* daemon, struct config_file* cfg)
{
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
fatal_exit("could not set up remote-control");
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
/* setup the session keys; the callback to use them will be
* attached to each sslctx separately */
if(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0) {
if(!listen_sslctx_setup_ticket_keys(
cfg->tls_session_ticket_keys.first)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
(void)setup_listen_sslctx(&daemon->listen_dot_sslctx, 1, 0, cfg);
#ifdef HAVE_NGHTTP2_NGHTTP2_H
if(cfg_has_https(cfg)) {
(void)setup_listen_sslctx(&daemon->listen_doh_sslctx, 0, 1, cfg);
}
#endif
#ifdef HAVE_NGTCP2
if(cfg_has_quic(cfg)) {
if(!(daemon->listen_quic_sslctx = quic_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) {
fatal_exit("could not set up quic SSL_CTX");
}
}
#endif /* HAVE_NGTCP2 */
}
if(!(daemon->connect_dot_sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
#else /* HAVE_SSL */
(void)daemon;(void)cfg;
#endif /* HAVE_SSL */
@@ -545,7 +501,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#endif
/* read ssl keys while superuser and outside chroot */
(void)setup_sslctxs(daemon, cfg);
setup_sslctx_remote(daemon, cfg);
daemon_setup_sslctxs(daemon, cfg);
/* init syslog (as root) if needed, before daemonize, otherwise
* a fork error could not be printed since daemonize closed stderr.*/
+145 -82
View File
@@ -255,7 +255,8 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
return 0;
}
/* sanity check. */
if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
if(sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE
|| !LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
|| LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
LDNS_PACKET_QUERY
|| LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
@@ -292,6 +293,44 @@ worker_err_ratelimit(struct worker* worker, int err)
return err;
}
/**
* Reply with an error.
* This reply includes the qname if it has been parsed.
* For error ratelimiting, the err ratelimit routine should be checked
* beforehand. The reply is without EDNS, and copies RD and sets QR flag.
* @param pkt: the packet buffer from the comm point.
* @param err: the error code that would be wanted.
* @param qname_len: 0 if not parsed, and the qname length in packet.
*/
static void
query_error(sldns_buffer* pkt, int err, size_t qname_len)
{
/* Preserve the RD flag.
* The CD flag must be cleared in authoritative answers,
* also the AD flag need not be copied into answers.
* The other flags need not be copied into the answer. */
sldns_buffer_write_u16_at(pkt, 2,
sldns_buffer_read_u16_at(pkt, 2)&0x0100U);
LDNS_QR_SET(sldns_buffer_begin(pkt)); /* Set QR flag. */
LDNS_RCODE_SET(sldns_buffer_begin(pkt), err); /* Set rcode */
if(qname_len && LDNS_QDCOUNT(sldns_buffer_begin(pkt))>=1 &&
qname_len <= LDNS_MAX_DOMAINLEN) {
/* Copy query into the answer. */
LDNS_QDCOUNT_SET(sldns_buffer_begin(pkt), 1);
sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE +
qname_len + 2 /* type */ + 2 /* class */ );
} else {
/* No query section in answer. */
LDNS_QDCOUNT_SET(sldns_buffer_begin(pkt), 0);
sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE);
}
LDNS_ANCOUNT_SET(sldns_buffer_begin(pkt), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(pkt), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(pkt), 0);
sldns_buffer_flip(pkt);
}
/**
* Structure holding the result of the worker_check_request function.
* Based on configuration it could be called up to four times; ideally should
@@ -329,7 +368,6 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
return;
}
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
LDNS_TC_CLR(sldns_buffer_begin(pkt));
verbose(VERB_QUERY, "request bad, has TC bit on");
out->value = worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
return;
@@ -971,6 +1009,7 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
size_t udpsize = edns->udp_size;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad,
@@ -1229,9 +1268,7 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
query_error(c->buffer, check_result->value, 0);
return 1;
}
comm_point_drop_reply(repinfo);
@@ -1248,41 +1285,17 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_REFUSED, 0);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
@@ -1304,35 +1317,27 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_FORMERR,
opt_rr_mark - LDNS_HEADER_SIZE
- 2 /* qtype */ - 2 /* qclass */);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_REFUSED,
opt_rr_mark - LDNS_HEADER_SIZE
- 2 /* qtype */ - 2 /* qclass */);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
query_error(c->buffer, LDNS_RCODE_REFUSED,
opt_rr_mark - LDNS_HEADER_SIZE
- 2 /* qtype */ - 2 /* qclass */);
return 1;
}
/* Write OPT RR directly after the query,
@@ -1528,6 +1533,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
"dnscrypt: worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
repinfo->client_addrlen);
if(check_result.value != -1) {
query_error(c->buffer, check_result.value, 0);
return 1;
}
comm_point_drop_reply(repinfo);
return 0;
}
@@ -1536,8 +1545,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
"dnscrypt: worker parse request: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
comm_point_drop_reply(repinfo);
return 0;
}
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
return 1;
}
dname_str(qinfo.qname, buf);
if(!(qinfo.qtype == LDNS_RR_TYPE_TXT &&
@@ -1548,9 +1561,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
worker->daemon->dnscenv->provider_name,
sldns_rr_descript(qinfo.qtype)->_name,
buf);
comm_point_drop_reply(repinfo);
if(worker_err_ratelimit(worker, LDNS_RCODE_SERVFAIL) == -1) {
comm_point_drop_reply(repinfo);
return 0;
}
query_error(c->buffer, LDNS_RCODE_SERVFAIL,
qinfo.qname_len);
worker->stats.num_query_dnscrypt_cleartext++;
return 0;
return 1;
}
worker->stats.num_query_dnscrypt_cert++;
sldns_buffer_rewind(c->buffer);
@@ -1590,9 +1608,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
if(check_result.value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result.value);
query_error(c->buffer, check_result.value, 0);
return 1;
}
comm_point_drop_reply(repinfo);
@@ -1626,10 +1642,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
goto send_reply;
}
if(worker->env.cfg->log_queries) {
@@ -1642,10 +1655,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "worker request: refused zone transfer.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
comm_point_drop_reply(repinfo);
return 0;
}
query_error(c->buffer, LDNS_RCODE_REFUSED, qinfo.qname_len);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
}
@@ -1664,10 +1678,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
query_error(c->buffer, LDNS_RCODE_FORMERR, qinfo.qname_len);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
}
@@ -1675,13 +1686,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
if((ret=parse_edns_from_query_pkt(
c->buffer, &edns, worker->env.cfg, c, repinfo,
(worker->env.now ? *worker->env.now : time(NULL)),
worker->scratchpad,
*worker->env.now, worker->scratchpad,
worker->daemon->cookie_secrets)) != 0) {
struct edns_data reply_edns;
verbose(VERB_ALGO, "worker parse edns: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
if(worker_err_ratelimit(worker, ret) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
memset(&reply_edns, 0, sizeof(reply_edns));
reply_edns.edns_present = 1;
error_encode(c->buffer, ret, &qinfo,
@@ -1698,6 +1713,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
if(worker_err_ratelimit(worker, EDNS_RCODE_BADVERS) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
extended_error_encode(c->buffer, EDNS_RCODE_BADVERS, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), 0, &edns);
@@ -1743,6 +1763,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
else if(edns.cookie_present) {
/* Cookie present, but not valid: Cookie was bad! */
if(worker_err_ratelimit(worker, LDNS_EXT_RCODE_BADCOOKIE) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
extended_error_encode(c->buffer,
LDNS_EXT_RCODE_BADCOOKIE, &qinfo,
*(uint16_t*)(void *)
@@ -1757,6 +1782,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
"need cookie or stateful transport");
log_addr(VERB_ALGO, "from",&repinfo->remote_addr
, repinfo->remote_addrlen);
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
worker->scratchpad, LDNS_EDE_OTHER,
"DNS Cookie needed for UDP replies");
@@ -1783,14 +1813,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "worker request: edns is too small.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
if(worker_err_ratelimit(worker, LDNS_RCODE_SERVFAIL) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
/* A small error without qname, and TC flag on. */
query_error(c->buffer, LDNS_RCODE_SERVFAIL, 0);
LDNS_TC_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_SERVFAIL);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_write_at(c->buffer, 4,
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
sldns_buffer_flip(c->buffer);
regional_free_all(worker->scratchpad);
goto send_reply;
}
@@ -1875,6 +1905,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
* ACLs allow the snooping. */
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
acl != acl_allow_snoop ) {
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->client_addr, repinfo->client_addrlen);
/* This ratelimited error query is accounted in the stats,
* as an incoming query. */
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
comm_point_drop_reply(repinfo);
regional_free_all(worker->scratchpad);
return 0;
}
if(worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
@@ -1883,9 +1922,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
regional_free_all(worker->scratchpad);
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->client_addr, repinfo->client_addrlen);
goto send_reply;
}
@@ -2124,10 +2160,37 @@ worker_restart_timer(struct worker* worker)
{
if(worker->env.cfg->stat_interval > 0) {
struct timeval tv;
if(worker->daemon->stat_time_specific) {
struct timeval dest, now;
int interval = worker->env.cfg->stat_interval;
int offset = worker->daemon->stat_time_offset;
int nows, spec;
if(gettimeofday(&now, NULL) < 0)
log_err("gettimeofday: %s", strerror(errno));
#ifndef S_SPLINT_S
tv.tv_sec = worker->env.cfg->stat_interval;
tv.tv_usec = 0;
nows = (int)now.tv_sec;
/* The next time is on the timer interval, at the
* specific offset, time value % interval = offset. */
/* It relies on the integer division below to drop the
* remainder in order to calculate the expected
* result. */
spec = ((nows-offset)/interval+1)*interval+offset;
/* This is instead of an assertion, and should not
* be needed. So assert(spec > nows), tv is going to
* be positive. */
if(spec<=nows) spec += interval;
dest.tv_sec = spec;
dest.tv_usec = 0;
#endif
/* Subtract in timeval, so the fractions of a second
* are rounded to the whole specific time. */
timeval_subtract(&tv, &dest, &now);
} else {
#ifndef S_SPLINT_S
tv.tv_sec = worker->env.cfg->stat_interval;
tv.tv_usec = 0;
#endif
}
comm_timer_set(worker->stat_timer, &tv);
}
}
+4
View File
@@ -2133,6 +2133,8 @@ static void* dnstap_io(void* arg)
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
time_t secs = 0;
struct timeval now;
const char name[16] = "unbound/dnstap"; /* seems to be the safest size
between different OSes */
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
dtio->thread_tid = gettid();
@@ -2142,6 +2144,8 @@ static void* dnstap_io(void* arg)
#endif
log_thread_set(&dtio->threadnum);
ub_thread_setname(dtio->tid, name);
/* setup */
verbose(VERB_ALGO, "start dnstap io thread");
dtio_setup_base(dtio, &secs, &now);
+19 -9
View File
@@ -330,7 +330,7 @@ static struct tap_socket* tap_socket_new_tcpaccept(char* ip,
/** create new socket (unconnected, not base-added), or NULL malloc fail */
static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
void (*ev_cb)(int, short, void*), void* data, char* server_key,
char* server_cert, char* verifypem)
char* server_cert, char* verifypem, char* tls_protocols)
{
struct tap_socket* s = calloc(1, sizeof(*s));
if(!s) {
@@ -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, 0);
NULL, NULL, 0, 0, 0, tls_protocols);
if(!s->sslctx) {
log_err("could not create ssl context");
free(s->ip);
@@ -1261,13 +1261,13 @@ static void setup_tcp_list(struct main_tap_data* maindata,
/** setup tls accept sockets */
static void setup_tls_list(struct main_tap_data* maindata,
struct config_strlist_head* tls_list, char* server_key,
char* server_cert, char* verifypem)
char* server_cert, char* verifypem, char* tls_protocols)
{
struct config_strlist* item;
for(item = tls_list->first; item; item = item->next) {
struct tap_socket* s;
s = tap_socket_new_tlsaccept(item->str, &dtio_mainfdcallback,
maindata, server_key, server_cert, verifypem);
maindata, server_key, server_cert, verifypem, tls_protocols);
if(!s) fatal_exit("out of memory");
if(!tap_socket_list_insert(&maindata->acceptlist, s))
fatal_exit("out of memory");
@@ -1300,7 +1300,7 @@ static void
setup_and_run(struct config_strlist_head* local_list,
struct config_strlist_head* tcp_list,
struct config_strlist_head* tls_list, char* server_key,
char* server_cert, char* verifypem)
char* server_cert, char* verifypem, char* tls_protocols)
{
time_t secs = 0;
struct timeval now;
@@ -1326,7 +1326,7 @@ setup_and_run(struct config_strlist_head* local_list,
setup_local_list(maindata, local_list);
setup_tcp_list(maindata, tcp_list);
setup_tls_list(maindata, tls_list, server_key, server_cert,
verifypem);
verifypem, tls_protocols);
if(!tap_socket_list_addevs(maindata->acceptlist, base))
fatal_exit("could not setup accept events");
if(verbosity) log_info("start of service");
@@ -1462,6 +1462,8 @@ int main(int argc, char** argv)
struct config_strlist_head tcp_list;
struct config_strlist_head tls_list;
char* server_key = NULL, *server_cert = NULL, *verifypem = NULL;
char* tls_protocols = "TLSv1.2 TLSv1.3";
#ifdef USE_WINSOCK
WSADATA wsa_data;
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
@@ -1561,17 +1563,25 @@ int main(int argc, char** argv)
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#endif /* HAVE_SSL */
}
setup_and_run(&local_list, &tcp_list, &tls_list, server_key,
server_cert, verifypem);
server_cert, verifypem, tls_protocols);
config_delstrlist(local_list.first);
config_delstrlist(tcp_list.first);
config_delstrlist(tls_list.first);
+255
View File
@@ -1,3 +1,258 @@
21 April 2026: Wouter
- Add test case for malformed SVCB records. Thanks to
Qifan Zhang, Palo Alto Networks for the additional test.
- Fix for the Jiggle Attack. The server is fixed to answer
with errors for error cases, and does not stay silent.
In addition, the error replies do not contain parts of the
incoming query. This is more conformant, stops reflection
and stops it as a covert channel. Thanks to Yuqi Qiu and
Xiang Li, Nankai University (AOSP Lab) for the report.
In addition, thanks to Qifan Zhang, Palo Alto Networks, for
noting the fingerprinting possibility, that is also fixed
with this.
- Fix EDNS extended RCODE reflection. This fixes that
the server does not echo extended rcode values after class
chaos queries. Thanks to Qifan Zhang, Palo Alto Networks
for the report.
- Fix for iterator RCODE handling of YXDOMAIN. This fixes
that the server only accepts YXDOMAIN answers that contain
a DNAME record. This stops bad answers, and checks that
the authoritative server gives correct replies.
Thanks to Qifan Zhang, Palo Alto Networks for the report.
- Fix for missing bounds check for decompressing dnames
for downloaded authority zones. This fixes that the server
could end up with malformed zone content after receiving
truncated packet contents from an AXFR. In addition, the
domain names in the SOA rdata are checked before the
authority code picks up the zone serial.
Thanks to Halil Oktay for the report.
- Fix that upstream TLS connections are not reused as TLS
connections for a different name, at the same IP. This
checks that the tls name is correct when reusing the
upstream connections. Thanks to TaoFei Guo from Peking
University and JianJun Chen from Tsinghua University for
the report.
- Fix that signatures are not allowed with revoked dnskeys.
Thanks to Qifan Zhang, Palo Alto Networks for the report.
- Fix that a DNAME with an unsigned CNAME is checked for
the correct match. This stops that for certain zone
configurations an unchecked unsigned CNAME could get
secure status. Thanks to Qifan Zhang, Palo Alto Networks
for the report.
- Fix handling of wildcard CNAMEs in the chain of trust.
An improper wildcard in the chain of trust would send
the retries to the wrong upstream. Also it could label
the step in the chain of trust as secure, when it was not.
Thanks to Qifan Zhang, Palo Alto Networks for the report.
- Set version number to 1.25.0 of code repository.
- Fix doxygen comment syntax.
20 April 2026: Wouter
- Fix compile warnings for thread setname routine, and test compile.
- Fix unused variable warning when compiled without ssl.
- Fix test with https zone for libressl.
17 April 2026: Wouter
- Fix setup of ssl context copy of the tls service pem option,
from a clang analyzer warning.
- Fix setup of ssl context copy, to check for the tls service
pem option for stat calls.
- Fix to compile the shm code when there is no shmget.
- Update github ci to use actions/checkout@v6.
- Update github ci cross platform to use
cross-platform-actions/action@v1.0.0.
- Fix github ci to speed up with parralel build, for windows ci.
- Fix compat/chacha_private sigma and tau definitions to use
nonstring attribute.
- Fix compat/gmtime_r old style definition syntax.
- Fix to increase size of the buffer for the win_svc reportev log
function.
- Fix ttl comparisons in rdata_copy for 32bit signed or unsigned.
- Fix subnet store of servfail to not leak memory.
- Update generated man pages.
- Update generated configure, with autoconf.
- Fix pthread_setname detection to fail on warnings.
17 April 2026: Yorgos
- Merge #1400: Support pthread_setname_np. Adds support for
pthread_setname_np and variants to set the name on spawned threads
for easier debugging/monitoring.
16 April 2026: Yorgos
- Merge #1406: Introduce new 'tls-protocols' configuration option.
- Introduce new 'tls-protocols' configuration option that specifies
which of the supported TLS protocols will be used.
This change invalidates some previous changes:
- TLSv1.2 is again enabled by default, but can be selectively turned
off if desired (related to #1303).
- The biefly introduced (not yet released) 'tls-use-system-versions'
configuration option, that addressed #1346, is reverted in favor of
'tls-protocols'.
- The briefly introduced (not yet released) '--enable-system-tls'
configure option, related to #1401, is no longer needed with the new
option and the current default.
- Fix cleaning up DoH session. The same query can be on multiple
streams in a session.
16 April 2026: Wouter
- Fix configure, autoconf for #1406.
15 April 2026: Wouter
- Fix RFC7766 compliance when client sends EOF over TCP. It stops
pending replies and closes. Thanks to Yuxiao Wu, Tsinghua
University for the report.
- Fix to shorten RRSIG count in scrubber, this protects against
an overly large number of RRSIGs. It can be configured with
`iter-scrub-rrsig: 8`, it has default 8. Thanks to Yuxiao Wu,
Tsinghua University for the report.
14 April 2026: Wouter
- Fix #1017: memory corruption related core dumps.
When alloc_reg_obtain has an empty list, return a new allocation.
- Fix clang analyzer warning for subnetmod, when return_msg is
NULL for update cache, like when it stores servfail status.
- iana portlist updated.
13 April 2026: Yorgos
- Update the documentation of 'max-query-restarts' in the man page.
10 April 2026: Wouter
- Fix for EDNS client subnet so that it does not store SERVFAIL in
the global cache after a failed lookup, such as timeouts. A failure
entry is stored in the subnet cache, for the query name, for a
couple of seconds. Queries can continue to use the subnet cache
during that time.
7 April 2026: Yorgos
- Fix unused variable warning.
30 March 2026: Wouter
- Merge #1408: Fix shared memory stats with threads.
27 March 2026: Wouter
- Fix to allow the control-interface config to use ip@port notation.
- Fix test code to allow empty hex answer packets from testbound.
- Fix defense in depth for service callback with empty packet.
24 March 2026: Wouter
- Fix to check for invalid http content length and chunk size,
and to check the RR rdata field lengths when decompressing and
inserting RRs from an authority zone transfer. This stops
large memory use and heap buffer-overflow read errors. Thanks
to Haruto Kimura (Stella) for the report.
20 March 2026: Wouter
- Fix for testcode pktview to check buffer size and log errors.
13 March 2026: Yorgos
- Fix to ignore out-of-zone DNAME records for CNAME synthesis. Thanks
to Yuxiao Wu, Yiyi Wang, Zhang Chao, Baojun Liu, and Haixin Duan from
Tsinghua University.
13 March 2026: Wouter
- Fix #278: DoT: complete unbound restart required on certificate
renew. Fix so that a reload checks if the files have changed, and
if so, reload the contexts. Also for DoH, DoQ and outgoing DoT.
- iana portlist updated.
- For #278: fast_reload can reload tls-service-key, tls-service-pem
and tls-cert-bundle changes. It checks the modification time of
the tls-service-key and tls-service-pem files for update.
- Fix detection of http listening port in fast_reload.
- Fix to add tls-service-key to memory printout for fast_reload.
9 March 2026: Wouter
- Fix compile failure in unbound-checkconf for older gcc compiler.
- Merge #1418: Apply cache TTL policy to DNAME and synthesized
CNAME on wire path.
6 March 2026: Wouter
- Merge #1415: Add lock unlock for view in memory error handling.
6 March 2026: Yorgos
- Document the suggestion for a higher value for 'outgoing-range';
helps when the request list is full.
- Warn for unused 'nodefault' local-zone configuration in
unbound-checkconf (related to #1416).
5 March 2026: Wouter
- Fix for DNS Rebinding Bypass via SVCB/HTTPS Records in Unbound.
Thanks to Kunta Chu, School of Software, Tsinghua University,
Taofei Guo, Peking University, and Jianjun Chen, Institute for
Network Sciences and Cyberspace, Tsinghua University for the
report. The private-address option is fixed to also elide
SVCB and HTTPS records that match the filter.
- Update generated man pages.
4 March 2026: Yorgos
- For #1411: Introduce a failing case in the rpl test so that it only
passes with the fix in place.
3 March 2026: Wouter
- Merge #1411: Allow synthesized DNAME TTL=0 to be served from cache
within grace period. The responses are served from cache within
a 1-second grace period. Reduces recursion when authoritative
servers return DNAME with TTL=0 (RFC 2308). Response
still returns TTL=0 to clients. Adds a test for it.
- For #1411: Fix that the lookup for DNAME uses flag. Fix assertion
in expired calc debug routine.
27 February 2026: Wouter
- Merge #1409: Documentation CNAME in redirect-type local-zone.
- Update generated man pages.
25 February 2026: Wouter
- Fix validator to set unchecked when validation recursion
requests are passed. The edns subnet module checks if validation
is needed for a cache response, and set the validator to protect
the cache with validation for non-subnet lookups.
23 February 2026: Wouter
- Fix to have cachedb not return expired bogus data as non-bogus.
- Fix to make the cachedb_val_expired.crpl succeed.
23 February 2026: Yorgos
- Fix to disallow cache lookup/store in external cachedb when a
forwarder/stub forbids it with the no-cache option.
- Fixed some typos reported in #1395 by rezky_nightky.
17 February 2026: Wouter
- Fix to remove unused conditional from cookie timestamp at
worker env.
- For #1405: local-zone always_refuse also blocks queries of type DS.
16 February 2026: Yorgos
- Fix #1404: Priming the root key fails after loading ipfire.org RPZ
zones. Fixed by including the ZONEMD RRtype in the list of types to
ignore for RPZ zones. Analysis and patch provided by ummeegge.
16 February 2026: Wouter
- Fix that cachedb aggressive negative responses have the RA flag set.
11 February 2026: Wouter
- Fix #1403: Inconsistency between do-nat64 and do-not-query-address
during retries.
9 February 2026: Wouter
- Merge #1401: Add a new build-time option for system TLS.
The --enable-system-tls flag enables the
tls-use-system-policy-versions setting by default.
- Update generated man pages.
6 February 2026: Yorgos
- Fix #1389: [FR] replacement with ECC-GOST12 according to RFC9558.
Patch contributed by Igor V. Ruzanov, available in
contrib/gost12.patch.
4 February 2026: Wouter
- Fix local privilege escalation on Windows. Thanks to Hao Huang and
CrisprXiang with Fudan University for the report. The OpenSSL
init calls are set to not load the openssl.cnf file when compiled
for Windows.
3 February 2026: Yorgos
- Eagerly remove .skip mark files in between mini_tdir.sh runs in case
there has been a change on the environment.
27 January 2026: Wouter
- Add test for allow-notify with a host name.
+9 -10
View File
@@ -193,6 +193,9 @@ server:
# Limit on number of CNAME, DNAME records for incoming packets.
# iter-scrub-cname: 11
# Limit on number of RRSIGs for an RRset for incoming packets.
# iter-scrub-rrsig: 8
# Limit on upstream queries for an incoming query and its recursion.
# max-global-quota: 200
@@ -662,7 +665,7 @@ server:
# or, just before the iterator).
# module-config: "validator iterator"
# File with trusted keys, kept uptodate using RFC5011 probes,
# File with trusted keys, kept up-to-date using RFC5011 probes,
# initial file like trust-anchor-file, then it stores metadata.
# Use several entries, one per domain name, to track multiple zones.
#
@@ -722,7 +725,7 @@ server:
# val-max-restart: 5
# Should additional section of secure message also be kept clean of
# unsecure data. Useful to shield the users of this validator from
# non-secure data. Useful to shield the users of this validator from
# potential bogus data in the additional section. All unsigned data
# in the additional section is removed from secure messages.
# val-clean-additional: yes
@@ -965,16 +968,12 @@ server:
# 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"
# Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload.
# Changing the value requires a restart.
# 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
# TLS protocols.
# Changing the value requires a restart.
# tls-protocols: "TLSv1.2 TLSv1.3"
# Add the secret file for TLS Session Ticket.
# Secret file must be 80 bytes of random data.
+2
View File
@@ -168,6 +168,8 @@ ipset,
\fI\%tcp\-auth\-query\-timeout\fP,
\fI\%delay\-close\fP\&.
\fI\%iter\-scrub\-promiscuous\fP\&.
\fI\%tls\-service\-key\fP\&.
\fI\%tls\-service\-pem\fP\&.
.sp
It does not work with
\fI\%interface\fP and
+2
View File
@@ -170,6 +170,8 @@ There are several commands that the server understands.
:ref:`tcp-auth-query-timeout<unbound.conf.tcp-auth-query-timeout>`,
:ref:`delay-close<unbound.conf.delay-close>`.
:ref:`iter-scrub-promiscuous<unbound.conf.iter-scrub-promiscuous>`.
:ref:`tls-service-key<unbound.conf.tls-service-key>`.
:ref:`tls-service-pem<unbound.conf.tls-service-pem>`.
It does not work with
:ref:`interface<unbound.conf.interface>` and
+85 -22
View File
@@ -382,6 +382,10 @@ Default depends on compile options.
Larger numbers need extra resources from the operating system.
For performance a very large value is best, use libevent to make this
possible.
Should be higher (preferably double) than the value of
\fI\%num\-queries\-per\-thread\fP to
account for cases where the request list is full and avoid file descriptor
starvation.
.sp
Default: 4096 (libevent) / 960 (minievent) / 48 (windows)
.UNINDENT
@@ -1135,9 +1139,13 @@ The file must contain the private key for the TLS session, the public
certificate is in the \fI\%tls\-service\-pem\fP
file and it must also be specified if
\fI\%tls\-service\-key\fP is specified.
Enabling or disabling this service requires a restart (a reload is not
enough), because the key is read while root permissions are held and before
chroot (if any).
If the key is stored with root permissions or outside of chroot, then
a change or enabling or disabling requires a restart (a reload is not
enough).
But if the key file (and tls\-service\-pem file) are accessible, then they
are read in on reload, and fast_reload.
The server checks the modification time of the file (and the filename)
to see if the file has changed for reload.
The ports enabled implicitly or explicitly via
\fI\%tls\-port\fP and
\fI\%https\-port\fP do not provide normal DNS TCP
@@ -1290,7 +1298,7 @@ Enable or disable sending the SNI extension on TLS connections.
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
Changing the value requires a restart.
.UNINDENT
.UNINDENT
.sp
@@ -1298,30 +1306,19 @@ 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
.B tls\-protocols: \fI\(dq<list of protocols>\(dq\fP
Specify the allowed TLS protocol versions to use, in no particular order.
Possible values are \fBTLSv1.2\fP and \fBTLSv1.3\fP\&.
Enclose list of protocols in quotes (\fB\(dq\(dq\fP) and put spaces between them.
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
Changing the value requires a restart.
.UNINDENT
.UNINDENT
.sp
Default: no
Default: \(dqTLSv1.2 TLSv1.3\(dq
.UNINDENT
.INDENT 0.0
.TP
@@ -2272,6 +2269,11 @@ This protects against so\-called DNS Rebinding, where a user browser is
turned into a network proxy, allowing remote access through the browser to
other parts of your private network.
.sp
The option removes resource records of types A, AAAA, SVCB and HTTPS
that match the filter.
Inside the SVCB and HTTPS records, the svcparams of type ipv4hint
and ipv6hint are checked for matches.
.sp
Some names can be allowed to contain your private addresses, by default all
the \fI\%local\-data\fP that you configured is
allowed to, and you can specify additional names using
@@ -3010,6 +3012,39 @@ local\-data: \(dqexample.com. A 127.0.0.1\(dq
queries for \fBwww.example.com\fP and \fBwww.foo.example.com\fP are
redirected, so that users with web browsers cannot access sites with
suffix example.com.
.sp
A \fBCNAME\fP record can also be provided via local\-data:
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
local\-zone: \(dqexample.com.\(dq redirect
local\-data: \(dqexample.com. CNAME www.example.org.\(dq
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
In that case, the \fBCNAME\fP is resolved and the answer
includes resolved target records as well.
The \fBCNAME\fP record has to be with the zone name of the local\-zone,
and there can be one CNAME, not more.
The \fBCNAME\fP record has to be at the zone apex of the
\fBredirect\fP zone, then it is used for redirection.
The resolution proceeds with upstream DNS resolution, and
that does not include the lookup in local zones.
So the record is not able to point in local zones, but it
can point to upstream DNS answers.
.sp
\fBCNAME\fP resolution is supported only in type \fBredirect\fP
local\-zone, and in type \fBinform_redirect\fP local\-zone.
.sp
As different from \fBCNAME\fP records that are used elsewhere, in
the \fBredirect\fP type local\-zone, it is supported that in the target
of the record a wildcard label gets expanded to the query name, with
for example: \fBexample.com. CNAME *.foo.net.\fP gets expanded
to \fBwww.example.com. CNAME www.example.com.foo.net.\fP\&.
.UNINDENT
.INDENT 7.0
.TP
@@ -3068,6 +3103,9 @@ use IPv6 protocol and avoid any queries to IPv4.
.B always_refuse
Like \fI\%refuse\fP, but ignores
local data and refuses the query.
This type also blocks queries of type DS for the zone name.
That can break the DNSSEC chain of trust, but it is refused anyway.
The block for type DS assists in more completely blocking the zone.
.UNINDENT
.INDENT 7.0
.TP
@@ -3731,6 +3769,10 @@ Default: 32
Hard limit on the number of times Unbound is allowed to restart a query
upon encountering a CNAME record.
Results in SERVFAIL when reached.
This applies to chained CNAME records but not sporadic CNAME records that
could be encountered in the lifetime of the query\(aqs resolution effort.
When a CNAME chain concludes, the counter keeping track of this limit is
reset.
Changing this value needs caution as it can allow long CNAME chains to be
accepted, where Unbound needs to verify (resolve) each link individually.
.sp
@@ -3758,6 +3800,16 @@ Default: 11
.UNINDENT
.INDENT 0.0
.TP
.B iter\-scrub\-rrsig: \fI<number>\fP
Limit on the number of RRSIGs allowed for an RRset, from the iterator
scrubber.
This protects against an overly large number of RRSIGs.
Clips off the remainder of the RRSIG list at that point.
.sp
Default: 8
.UNINDENT
.INDENT 0.0
.TP
.B max\-global\-quota: \fI<number>\fP
Limit on the number of upstream queries sent out for an incoming query and
its subqueries from recursion.
@@ -3939,7 +3991,7 @@ Default: no
.UNINDENT
.INDENT 0.0
.TP
.B control\-interface: \fI<IP address or interface name or path>\fP
.B control\-interface: \fI<IP address or interface name[@port] or path>\fP
Give IPv4 or IPv6 addresses or local socket path to listen on for control
commands.
If an interface name is used instead of an IP address, the list of IP
@@ -4756,6 +4808,17 @@ Default: no
Use a specific NAT64 prefix to reach IPv4\-only servers.
The prefix length must be one of /32, /40, /48, /56, /64 or /96.
.sp
The NAT64 prefix is allowed by the
\fI\%do\-not\-query\-address\fP option,
so that there is a clear outcome of addresses in both; the NAT64 prefix
is allowed.
The IPv4 address could be filtered by the
\fI\%do\-not\-query\-address\fP option,
if needed.
Allowing the NAT64 prefix is useful when using do\-not\-query\-address
for a cluster of machines that is IPv6\-only and uses NAT64, but does
not have internet access.
.sp
Default: 64:ff9b::/96 (same as \fI\%dns64\-prefix\fP)
.UNINDENT
.SH DNSCRYPT OPTIONS
+78 -17
View File
@@ -366,6 +366,10 @@ These options are part of the ``server:`` section.
Larger numbers need extra resources from the operating system.
For performance a very large value is best, use libevent to make this
possible.
Should be higher (preferably double) than the value of
:ref:`num-queries-per-thread<unbound.conf.num-queries-per-thread>` to
account for cases where the request list is full and avoid file descriptor
starvation.
Default: 4096 (libevent) / 960 (minievent) / 48 (windows)
@@ -1044,9 +1048,13 @@ These options are part of the ``server:`` section.
certificate is in the :ref:`tls-service-pem<unbound.conf.tls-service-pem>`
file and it must also be specified if
:ref:`tls-service-key<unbound.conf.tls-service-key>` is specified.
Enabling or disabling this service requires a restart (a reload is not
enough), because the key is read while root permissions are held and before
chroot (if any).
If the key is stored with root permissions or outside of chroot, then
a change or enabling or disabling requires a restart (a reload is not
enough).
But if the key file (and tls-service-pem file) are accessible, then they
are read in on reload, and fast_reload.
The server checks the modification time of the file (and the filename)
to see if the file has changed for reload.
The ports enabled implicitly or explicitly via
:ref:`tls-port<unbound.conf.tls-port>` and
:ref:`https-port<unbound.conf.https-port>` do not provide normal DNS TCP
@@ -1172,25 +1180,19 @@ These options are part of the ``server:`` section.
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
Enable or disable sending the SNI extension on TLS connections.
.. note:: Changing the value requires a reload.
.. note:: Changing the value requires a restart.
Default: yes
@@UAHL@unbound.conf@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.
@@UAHL@unbound.conf@tls-protocols@@: *"<list of protocols>"*
Specify the allowed TLS protocol versions to use, in no particular order.
Possible values are ``TLSv1.2`` and ``TLSv1.3``.
Enclose list of protocols in quotes (``""``) and put spaces between them.
By default Unbound only uses the latest available TLS version.
.. note:: Changing the value requires a restart.
.. caution:: Use only if you want to support legacy TLS client connections.
.. note:: Changing the value requires a reload.
Default: no
Default: "TLSv1.2 TLSv1.3"
@@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
@@ -2012,6 +2014,11 @@ These options are part of the ``server:`` section.
turned into a network proxy, allowing remote access through the browser to
other parts of your private network.
The option removes resource records of types A, AAAA, SVCB and HTTPS
that match the filter.
Inside the SVCB and HTTPS records, the svcparams of type ipv4hint
and ipv6hint are checked for matches.
Some names can be allowed to contain your private addresses, by default all
the :ref:`local-data<unbound.conf.local-data>` that you configured is
allowed to, and you can specify additional names using
@@ -2662,6 +2669,33 @@ These options are part of the ``server:`` section.
redirected, so that users with web browsers cannot access sites with
suffix example.com.
A ``CNAME`` record can also be provided via local-data:
.. code-block:: text
local-zone: "example.com." redirect
local-data: "example.com. CNAME www.example.org."
In that case, the ``CNAME`` is resolved and the answer
includes resolved target records as well.
The ``CNAME`` record has to be with the zone name of the local-zone,
and there can be one CNAME, not more.
The ``CNAME`` record has to be at the zone apex of the
``redirect`` zone, then it is used for redirection.
The resolution proceeds with upstream DNS resolution, and
that does not include the lookup in local zones.
So the record is not able to point in local zones, but it
can point to upstream DNS answers.
``CNAME`` resolution is supported only in type ``redirect``
local-zone, and in type ``inform_redirect`` local-zone.
As different from ``CNAME`` records that are used elsewhere, in
the ``redirect`` type local-zone, it is supported that in the target
of the record a wildcard label gets expanded to the query name, with
for example: ``example.com. CNAME *.foo.net.`` gets expanded
to ``www.example.com. CNAME www.example.com.foo.net.``.
@@UAHL@unbound.conf.local-zone.type@inform@@
The query is answered normally, same as
:ref:`transparent<unbound.conf.local-zone.type.transparent>`.
@@ -2701,6 +2735,9 @@ These options are part of the ``server:`` section.
@@UAHL@unbound.conf.local-zone.type@always_refuse@@
Like :ref:`refuse<unbound.conf.local-zone.type.refuse>`, but ignores
local data and refuses the query.
This type also blocks queries of type DS for the zone name.
That can break the DNSSEC chain of trust, but it is refused anyway.
The block for type DS assists in more completely blocking the zone.
@@UAHL@unbound.conf.local-zone.type@always_nxdomain@@
Like :ref:`static<unbound.conf.local-zone.type.static>`, but ignores
@@ -3223,6 +3260,10 @@ These options are part of the ``server:`` section.
Hard limit on the number of times Unbound is allowed to restart a query
upon encountering a CNAME record.
Results in SERVFAIL when reached.
This applies to chained CNAME records but not sporadic CNAME records that
could be encountered in the lifetime of the query's resolution effort.
When a CNAME chain concludes, the counter keeping track of this limit is
reset.
Changing this value needs caution as it can allow long CNAME chains to be
accepted, where Unbound needs to verify (resolve) each link individually.
@@ -3247,6 +3288,15 @@ These options are part of the ``server:`` section.
Default: 11
@@UAHL@unbound.conf@iter-scrub-rrsig@@: *<number>*
Limit on the number of RRSIGs allowed for an RRset, from the iterator
scrubber.
This protects against an overly large number of RRSIGs.
Clips off the remainder of the RRSIG list at that point.
Default: 8
@@UAHL@unbound.conf@max-global-quota@@: *<number>*
Limit on the number of upstream queries sent out for an incoming query and
its subqueries from recursion.
@@ -3411,7 +3461,7 @@ To setup the correct self-signed certificates use the
Default: no
@@UAHL@unbound.conf.remote@control-interface@@: *<IP address or interface name or path>*
@@UAHL@unbound.conf.remote@control-interface@@: *<IP address or interface name[@port] or path>*
Give IPv4 or IPv6 addresses or local socket path to listen on for control
commands.
If an interface name is used instead of an IP address, the list of IP
@@ -4161,6 +4211,17 @@ servers.
Use a specific NAT64 prefix to reach IPv4-only servers.
The prefix length must be one of /32, /40, /48, /56, /64 or /96.
The NAT64 prefix is allowed by the
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
so that there is a clear outcome of addresses in both; the NAT64 prefix
is allowed.
The IPv4 address could be filtered by the
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
if needed.
Allowing the NAT64 prefix is useful when using do-not-query-address
for a cluster of machines that is IPv6-only and uses NAT64, but does
not have internet access.
Default: 64:ff9b::/96 (same as :ref:`dns64-prefix<unbound.conf.dns64.dns64-prefix>`)
.. _unbound.conf.dnscrypt:
+89 -3
View File
@@ -70,6 +70,7 @@ subnet_data_delete(void *d, void *ATTR_UNUSED(arg))
r = (struct subnet_msg_cache_data*)d;
addrtree_delete(r->tree4);
addrtree_delete(r->tree6);
free(r->reason_fail);
free(r);
}
@@ -84,6 +85,8 @@ msg_cache_sizefunc(void *k, void *d)
+ q->key.qname_len + lock_get_mem(&q->entry.lock);
s += addrtree_size(r->tree4);
s += addrtree_size(r->tree6);
if(r->reason_fail)
s += strlen(r->reason_fail)+1;
return s;
}
@@ -200,12 +203,18 @@ int ecs_whitelist_check(struct query_info* qinfo,
if(sq->ecs_server_out.subnet_source_mask == 0) {
sq->subnet_sent_no_subnet = 1;
sq->subnet_sent = 0;
/* The result should end up in subnet cache,
* not in global cache. */
qstate->no_cache_store = 1;
return 1;
}
subnet_ecs_opt_list_append(&sq->ecs_server_out,
&qstate->edns_opts_back_out, qstate, region);
}
sq->subnet_sent = 1;
/* Do not store servfails in global cache, since the subnet
* option is sent out. */
qstate->no_cache_store = 1;
}
else {
/* Outgoing ECS option is set, but we don't want to sent it to
@@ -427,6 +436,35 @@ update_cache(struct module_qstate *qstate, int id)
}
/* lru_entry->lock is locked regardless of how we got here,
* either from the slabhash_lookup, or above in the new allocated */
if(!qstate->return_msg && qstate->error_response_cache) {
struct subnet_msg_cache_data *data =
(struct subnet_msg_cache_data*)lru_entry->data;
data->ttl_servfail = *qstate->env->now + NORR_TTL;
data->ede_fail = errinf_to_reason_bogus(qstate);
diff_size = (data->reason_fail?strlen(data->reason_fail)+1:0);
if(qstate->errinf) {
char* str = errinf_to_str_misc(qstate);
free(data->reason_fail);
data->reason_fail = NULL;
if(str)
data->reason_fail = strdup(str);
}
diff_size = (data->reason_fail?strlen(data->reason_fail)+1:0)
- diff_size;
lock_rw_unlock(&lru_entry->lock);
if (need_to_insert) {
slabhash_insert(subnet_msg_cache, h, lru_entry,
lru_entry->data, NULL);
} else {
slabhash_update_space_used(subnet_msg_cache, h, NULL,
diff_size);
}
return;
}
if(!qstate->return_msg) {
lock_rw_unlock(&lru_entry->lock);
return;
}
/* Step 2, find the correct tree */
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
lock_rw_unlock(&lru_entry->lock);
@@ -470,6 +508,21 @@ update_cache(struct module_qstate *qstate, int id)
}
}
/** See if there is a stored servfail, returns true if so, and sets reply. */
static int
lookup_check_servfail(struct module_qstate *qstate,
struct subnet_msg_cache_data *data)
{
struct module_env *env = qstate->env;
if(!data)
return 0;
if(!data->ttl_servfail || TTL_IS_EXPIRED(data->ttl_servfail, *env->now))
return 0;
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
errinf_ede(qstate, data->reason_fail, data->ede_fail);
return 1;
}
/** Lookup in cache and reply true iff reply is sent. */
static int
lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq, int prefetch)
@@ -483,6 +536,8 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
struct addrtree *tree;
struct addrnode *node;
uint8_t scope;
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out));
@@ -496,12 +551,20 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
tree = (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4)?
data->tree4 : data->tree6;
if (!tree) { /* qinfo in cache but not for this family */
if(lookup_check_servfail(qstate, data)) {
lock_rw_unlock(&e->lock);
return 1;
}
lock_rw_unlock(&e->lock);
return 0;
}
node = addrtree_find(tree, (addrkey_t*)ecs->subnet_addr,
ecs->subnet_source_mask, *env->now);
if (!node) { /* plain old cache miss */
if(lookup_check_servfail(qstate, data)) {
lock_rw_unlock(&e->lock);
return 1;
}
lock_rw_unlock(&e->lock);
return 0;
}
@@ -510,12 +573,24 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
(struct reply_info *)node->elem, qstate->region, *env->now, 0,
env->scratch);
scope = (uint8_t)node->scope;
lock_rw_unlock(&e->lock);
if (!qstate->return_msg) { /* Failed allocation or expired TTL */
if(lookup_check_servfail(qstate, data)) {
lock_rw_unlock(&e->lock);
return 1;
}
lock_rw_unlock(&e->lock);
return 0;
}
lock_rw_unlock(&e->lock);
if(qstate->return_msg->rep->security == sec_status_unchecked
&& must_validate) {
/* The message has to be validated first. */
verbose(VERB_ALGO, "subnet: unchecked cache entry needs "
"validation");
return 0;
}
if (sq->subnet_downstream) { /* relay to interested client */
sq->ecs_client_out.subnet_scope_mask = scope;
sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam;
@@ -570,7 +645,10 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
qflags |= BIT_RD;
if((qstate->query_flags & BIT_CD)!=0) {
qflags |= BIT_CD;
valrec = 1;
/* The valrec is left off. Leave out: valrec = 1;
* So that the cache is protected with DNSSEC validation.
* Just like the global cache. DNSSEC validation is performed
* regardless of the setting of the querier's CD flag. */
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
@@ -640,6 +718,12 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
/* already an answer and its not a message, but retain
* the actual rcode, instead of module_error, so send
* module_finished */
if(qstate->error_response_cache) {
verbose(VERB_ALGO, "subnet: store error response");
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
}
return module_finished;
}
@@ -889,9 +973,11 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
} else if(sq->subnet_sent_no_subnet) {
/* The answer can be stored as scope 0, not in global cache. */
/* This was already set in ecs_whitelist_check */
qstate->no_cache_store = 1;
} else if(sq->subnet_sent) {
/* Need another query to be able to store in global cache. */
/* This was already set in ecs_whitelist_check */
qstate->no_cache_store = 1;
}
+10
View File
@@ -69,8 +69,18 @@ struct subnet_env {
};
struct subnet_msg_cache_data {
/** Tree for nodes with IPv4 subnets. */
struct addrtree* tree4;
/** Tree for nodes with IPv6 subnets. */
struct addrtree* tree6;
/** If servfail is stored, for how long. Abs time in seconds.
* This protects against too much recusion on the item when
* resolution fails, for a couple of seconds. */
time_t ttl_servfail;
/** servfail ede */
sldns_ede_code ede_fail;
/** servfail reason */
char* reason_fail;
};
struct subnet_qstate {
+167 -1
View File
@@ -207,6 +207,168 @@ size_t priv_get_mem(struct iter_priv* priv)
return sizeof(*priv) + regional_get_mem(priv->region);
}
/**
* Check if svcparam ipv4hint contains a private address.
* @param priv: private address lookup struct.
* @param d: the data bytes.
* @param data_len: number of data bytes in the svcparam.
* @param addr: address to return the private address to log in to.
* It has space for IPv4 and IPv6 addresses.
* @param addrlen: length of the addr. Returns the correct size for the addr.
* @return true if the rdata contains a private address.
*/
static int svcb_ipv4hint_contains_priv_addr(struct iter_priv* priv,
uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr,
socklen_t* addrlen)
{
struct sockaddr_in sa;
*addrlen = (socklen_t)sizeof(struct sockaddr_in);
memset(&sa, 0, sizeof(struct sockaddr_in));
sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
while(data_len >= LDNS_IP4ADDRLEN) {
memmove(&sa.sin_addr, d, LDNS_IP4ADDRLEN);
memmove(addr, &sa, *addrlen);
if(priv_lookup_addr(priv, addr, *addrlen))
return 1;
d += LDNS_IP4ADDRLEN;
data_len -= LDNS_IP4ADDRLEN;
}
/* if data_len != 0 here, then the svcparam is malformed. */
return 0;
}
/**
* Check if svcparam ipv6hint contains a private address.
* @param priv: private address lookup struct.
* @param d: the data bytes.
* @param data_len: number of data bytes in the svcparam.
* @param addr: address to return the private address to log in to.
* It has space for IPv4 and IPv6 addresses.
* @param addrlen: length of the addr. Returns the correct size for the addr.
* @return true if the rdata contains a private address.
*/
static int svcb_ipv6hint_contains_priv_addr(struct iter_priv* priv,
uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr,
socklen_t* addrlen)
{
struct sockaddr_in6 sa;
*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
memset(&sa, 0, sizeof(struct sockaddr_in6));
sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
while(data_len >= LDNS_IP6ADDRLEN) {
memmove(&sa.sin6_addr, d, LDNS_IP6ADDRLEN);
memmove(addr, &sa, *addrlen);
if(priv_lookup_addr(priv, addr, *addrlen))
return 1;
d += LDNS_IP6ADDRLEN;
data_len -= LDNS_IP6ADDRLEN;
}
/* if data_len != 0 here, then the svcparam is malformed. */
return 0;
}
/**
* Check if type SVCB and HTTPS rdata contains a private address.
* @param priv: private address lookup struct.
* @param pkt: the packet.
* @param rr: the rr with rdata to check.
* @param addr: address to return the private address to log in to.
* @param addrlen: length of the addr. Initially the total size, on
* return the correct size for the addr.
* @return true if the rdata contains a private address.
*/
static int svcb_rr_contains_priv_addr(struct iter_priv* priv,
sldns_buffer* pkt, struct rr_parse* rr, struct sockaddr_storage* addr,
socklen_t* addrlen)
{
uint8_t* d = rr->ttl_data;
uint16_t svcparamkey, data_len, rdatalen;
size_t oldpos, dname_len, dname_start, dname_compr_len;
d += 4; /* skip TTL */
rdatalen = sldns_read_uint16(d); /* read rdata length */
d += 2;
if(rdatalen < 2 /* priority */ + 1 /* 1 length target */)
return 0; /* malformed, too short */
d += 2; /* skip priority */
rdatalen -= 2;
oldpos = sldns_buffer_position(pkt);
sldns_buffer_set_position(pkt, (size_t)(d - sldns_buffer_begin(pkt)));
dname_start = sldns_buffer_position(pkt);
dname_len = pkt_dname_len(pkt);
dname_compr_len = sldns_buffer_position(pkt) - dname_start;
sldns_buffer_set_position(pkt, oldpos);
if(dname_len == 0)
return 0; /* dname malformed */
if(dname_compr_len > rdatalen)
return 0; /* malformed */
d += dname_compr_len; /* skip target */
rdatalen -= dname_compr_len;
while(rdatalen >= 4) {
svcparamkey = sldns_read_uint16(d);
data_len = sldns_read_uint16(d+2);
d += 4;
rdatalen -= 4;
/* verify that we have data_len data */
if(data_len > rdatalen) {
/* It is malformed, but if there are addresses
* in there it can be rejected. */
data_len = rdatalen;
}
if(!data_len)
continue; /* no data for the svcparamkey */
if(svcparamkey == SVCB_KEY_IPV4HINT) {
if(svcb_ipv4hint_contains_priv_addr(priv, d, data_len,
addr, addrlen))
return 1;
} else if(svcparamkey == SVCB_KEY_IPV6HINT) {
if(svcb_ipv6hint_contains_priv_addr(priv, d, data_len,
addr, addrlen))
return 1;
}
d += data_len;
rdatalen -= data_len;
}
/* If rdatalen != 0 here, then the svcb rdata is malformed. */
return 0;
}
/**
* Check if the SVCB and HTTPS rrset is bad.
* @param priv: private address lookup struct.
* @param pkt: the packet.
* @param rrset: the rrset to check.
* @return 1 if the entire rrset has to be removed. 0 if not.
* It removes RRs if they have private addresses, and log that.
*/
static int priv_svcb_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
struct rrset_parse* rrset)
{
struct rr_parse* rr, *prev = NULL;
struct sockaddr_storage addr;
socklen_t addrlen = (socklen_t)sizeof(addr);
for(rr = rrset->rr_first; rr; rr = rr->next) {
if(svcb_rr_contains_priv_addr(priv, pkt, rr, &addr,
&addrlen)) {
if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, addrlen))
return 1;
continue;
}
prev = rr;
}
return 0;
}
int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
struct rrset_parse* rrset)
{
@@ -268,7 +430,11 @@ int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
}
prev = rr;
}
}
} else if(rrset->type == LDNS_RR_TYPE_SVCB ||
rrset->type == LDNS_RR_TYPE_HTTPS) {
if(priv_svcb_rrset_bad(priv, pkt, rrset))
return 1;
}
}
return 0;
}
+63 -7
View File
@@ -285,6 +285,17 @@ synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
return NULL;
memmove(cn->rr_first->ttl_data, rrset->rr_first->ttl_data,
sizeof(uint32_t)); /* RFC6672: synth CNAME TTL == DNAME TTL */
/* Apply cache TTL policy so DNAME and synthesized CNAME stay equal
* and respect cache-min-ttl/cache-max-ttl (same as rdata_copy path). */
if(!SERVE_ORIGINAL_TTL) {
uint32_t ttl = sldns_read_uint32(cn->rr_first->ttl_data);
time_t ttl_t = (time_t)ttl;
if(ttl_t < MIN_TTL) ttl_t = MIN_TTL;
if(ttl_t > MAX_TTL) ttl_t = MAX_TTL;
ttl = (uint32_t)ttl_t;
sldns_write_uint32(cn->rr_first->ttl_data, ttl);
sldns_write_uint32(rrset->rr_first->ttl_data, ttl);
}
sldns_write_uint16(cn->rr_first->ttl_data+4, aliaslen);
memmove(cn->rr_first->ttl_data+6, alias, aliaslen);
cn->rr_first->size = sizeof(uint16_t)+aliaslen;
@@ -408,6 +419,43 @@ shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
else rrset->rr_first = NULL;
}
/** Shorten RRSIGs list */
static void
shorten_rrsig(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
{
/* The too large list of RRSIGs on the RRset is shortened.
* This is so that too large content does not overwhelm the cache.
* The validator does not validate more than a max number of
* RRSIGs as well. */
int i;
struct rr_parse* rr = rrset->rrsig_first, *prev = NULL;
if(!rr)
return;
for(i=0; i<count; i++) {
prev = rr;
rr = rr->next;
if(!rr)
return; /* The RRSIG list is already short. */
}
if(verbosity >= VERB_QUERY
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
dname_pkt_copy(pkt, buf, rrset->dname);
log_nametypeclass(VERB_QUERY, "normalize: shorten RRSIGs:",
buf, rrset->type, ntohs(rrset->rrset_class));
}
/* remove further rrsigs */
rrset->rrsig_last = prev;
rrset->rrsig_count = count;
while(rr) {
rrset->size -= rr->size;
rr = rr->next;
}
if(rrset->rrsig_last)
rrset->rrsig_last->next = NULL;
else rrset->rrsig_first = NULL;
}
/**
* This routine normalizes a response. This includes removing "irrelevant"
* records from the answer and additional sections and (re)synthesizing
@@ -445,6 +493,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
prev = NULL;
rrset = msg->rrset_first;
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
if(cname_length > env->cfg->iter_scrub_cname) {
/* Too many CNAMEs, or DNAMEs, from the authority
* server, scrub down the length to something
@@ -455,8 +505,9 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
pkt, msg, prev, &rrset);
continue;
}
if(rrset->type == LDNS_RR_TYPE_DNAME &&
pkt_strict_sub(pkt, sname, rrset->dname)) {
if(rrset->type == LDNS_RR_TYPE_DNAME &&
pkt_strict_sub(pkt, sname, rrset->dname) &&
pkt_sub(pkt, rrset->dname, zonename)) {
/* check if next rrset is correct CNAME. else,
* synthesize a CNAME */
struct rrset_parse* nx = rrset->rrset_all_next;
@@ -502,8 +553,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
log_err("out of memory synthesizing CNAME");
return 0;
}
/* FIXME: resolve the conflict between synthesized
* CNAME ttls and the cache. */
rrset = nx;
continue;
@@ -525,7 +574,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
if(nx && nx->section == LDNS_SECTION_ANSWER &&
nx->type == LDNS_RR_TYPE_DNAME &&
nx->rr_count == 1 &&
pkt_strict_sub(pkt, sname, nx->dname)) {
pkt_strict_sub(pkt, sname, nx->dname) &&
pkt_sub(pkt, nx->dname, zonename)) {
/* there is a DNAME after this CNAME, it
* is in the ANSWER section, and the DNAME
* applies to the name we cover */
@@ -620,6 +670,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
/* only one NS set allowed in authority section */
if(rrset->type==LDNS_RR_TYPE_NS) {
/* NS set must be pertinent to the query */
@@ -762,6 +814,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
prev = rrset;
rrset = rrset->rrset_all_next;
}
@@ -972,8 +1026,10 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
}
/* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA)) {
if(rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA ||
rrset->type == LDNS_RR_TYPE_SVCB ||
rrset->type == LDNS_RR_TYPE_HTTPS) {
/* do not set servfail since this leads to too
* many drops of other people using rfc1918 space */
+29 -3
View File
@@ -308,9 +308,30 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
if(a->bogus)
return -1; /* address of server is bogus */
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
log_addr(VERB_ALGO, "skip addr on the donotquery list",
&a->addr, a->addrlen);
return -1; /* server is on the donotquery list */
if(iter_env->nat64.use_nat64 &&
addr_is_ip6(&a->addr, a->addrlen) &&
a->addrlen == iter_env->nat64.nat64_prefix_addrlen &&
addr_in_common(&a->addr, 128,
&iter_env->nat64.nat64_prefix_addr,
iter_env->nat64.nat64_prefix_net,
iter_env->nat64.nat64_prefix_addrlen) ==
iter_env->nat64.nat64_prefix_net) {
/* The NAT64 is enabled, and address is IPv6, it is
* in the NAT64 prefix. It is allowed.
* So that in an IPv6-only cluster without internet
* access, that makes the NAT64 translation continue
* to work. The NAT64 prefix is allowed. */
/* Otherwise, after a timeout, the already NAT64
* translated address would be treated differently,
* and that causes confusion. */
log_addr(VERB_ALGO, "the addr is on the donotquery "
"list, but allowed because it is NAT64",
&a->addr, a->addrlen);
} else {
log_addr(VERB_ALGO, "skip addr on the donotquery list",
&a->addr, a->addrlen);
return -1; /* server is on the donotquery list */
}
}
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip6 available */
@@ -1527,6 +1548,11 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
struct delegpt *dp;
int nolock = 1;
log_assert((retdpname && retdpnamelen
&& dpname_storage && dpname_storage_len > 0) ||
(retdpname == NULL && retdpnamelen == NULL
&& dpname_storage == NULL && dpname_storage_len == 0));
/* Check for stub. */
/* Lock both forwards and hints for atomic read. */
lock_rw_rdlock(&qstate->env->fwds->lock);
+14 -2
View File
@@ -297,6 +297,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
struct reply_info err;
struct msgreply_entry* msg;
if(qstate->no_cache_store) {
qstate->error_response_cache = 1;
return error_response(qstate, id, rcode);
}
if(qstate->prefetch_leeway > NORR_TTL) {
@@ -3223,8 +3224,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
} else iter_scrub_ds(iq->response, NULL, NULL);
if(type == RESPONSE_TYPE_THROWAWAY &&
FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_YXDOMAIN) {
/* YXDOMAIN is a permanent error, no need to retry */
type = RESPONSE_TYPE_ANSWER;
/* YXDOMAIN is a permanent error for DNAME expansion overflow
* (RFC 6672 Section 2.2). Only accept if the response
* contains a DNAME record in the answer section; otherwise
* treat as invalid, to make sure the authoritative answer
* make sense. */
size_t i;
for(i=0; i<iq->response->rep->an_numrrsets; i++) {
if(ntohs(iq->response->rep->rrsets[i]->rk.type)
== LDNS_RR_TYPE_DNAME) {
type = RESPONSE_TYPE_ANSWER;
break;
}
}
}
if(type == RESPONSE_TYPE_CNAME)
origtypecname = 1;
+3
View File
@@ -973,6 +973,9 @@ respip_rewrite_reply(const struct query_info* qinfo,
lock_rw_unlock(&raddr->lock);
lock_rw_unlock(&a->lock);
lock_rw_unlock(&az->rpz_lock);
if(view) {
lock_rw_unlock(&view->lock);
}
return 0;
}
if(rpz_used) {
+27 -2
View File
@@ -1369,6 +1369,10 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
uncompressed_len = pkt_dname_len(&pktbuf);
if(!uncompressed_len)
return 0; /* parse error in dname */
compressed_len = sldns_buffer_position(
&pktbuf) - oldpos;
if(compressed_len > rdlen)
return 0; /* dname exceeds rdata */
if(!sldns_buffer_available(buf,
uncompressed_len))
/* dname too long for buffer */
@@ -1376,14 +1380,15 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
dname_pkt_copy(&pktbuf,
sldns_buffer_current(buf), rd);
sldns_buffer_skip(buf, (ssize_t)uncompressed_len);
compressed_len = sldns_buffer_position(
&pktbuf) - oldpos;
rd += compressed_len;
rdlen -= compressed_len;
count--;
len = 0;
break;
case LDNS_RDF_TYPE_STR:
/* Check rdlen for resilience, because it is
* checked above, that rdlen > 0 */
if(rdlen < 1) return 0; /* malformed */
len = rd[0] + 1;
break;
default:
@@ -1391,6 +1396,8 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
break;
}
if(len) {
if(len > rdlen)
return 0; /* malformed */
if(!sldns_buffer_available(buf, len))
return 0; /* too long for buffer */
sldns_buffer_write(buf, rd, len);
@@ -1998,12 +2005,21 @@ auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
struct auth_data* apex;
struct auth_rrset* soa;
struct packed_rrset_data* d;
size_t primlen, mboxlen;
apex = az_find_name(z, z->name, z->namelen);
if(!apex) return 0;
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
if(!soa || soa->data->count==0)
return 0; /* no RRset or no RRs in rrset */
if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
if((primlen = dname_valid(soa->data->rr_data[0]+2,
soa->data->rr_len[0]-2)) == 0)
return 0; /* primary dname malformed */
if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen,
soa->data->rr_len[0]-2-primlen)) == 0)
return 0; /* mailbox dname malformed */
if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0])
return 0; /* rdata malformed */
d = soa->data;
*serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20));
return 1;
@@ -2016,12 +2032,21 @@ xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
struct auth_data* apex;
struct auth_rrset* soa;
struct packed_rrset_data* d;
size_t primlen, mboxlen;
apex = az_find_name(z, z->name, z->namelen);
if(!apex) return 0;
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
if(!soa || soa->data->count==0)
return 0; /* no RRset or no RRs in rrset */
if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
if((primlen = dname_valid(soa->data->rr_data[0]+2,
soa->data->rr_len[0]-2)) == 0)
return 0; /* primary dname malformed */
if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen,
soa->data->rr_len[0]-2-primlen)) == 0)
return 0; /* mailbox dname malformed */
if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0])
return 0; /* rdata malformed */
/* SOA record ends with serial, refresh, retry, expiry, minimum,
* as 4 byte fields */
d = soa->data;
+20 -6
View File
@@ -232,8 +232,15 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
/* snip off front part of qname until the type is found */
while(qnamelen > 0) {
if((rrset = rrset_cache_lookup(env->rrset_cache, qname,
qnamelen, searchtype, qclass, 0, now, 0))) {
rrset = rrset_cache_lookup(env->rrset_cache, qname,
qnamelen, searchtype, qclass, 0, now, 0);
if(!rrset && searchtype == LDNS_RR_TYPE_DNAME)
/* If not found, for type DNAME, try 0TTL stored,
* for its grace period. */
rrset = rrset_cache_lookup(env->rrset_cache, qname,
qnamelen, searchtype, qclass,
PACKED_RRSET_UPSTREAM_0TTL, now, 0);
if(rrset) {
uint8_t* origqname = qname;
size_t origqnamelen = qnamelen;
if(!noexpiredabove)
@@ -766,8 +773,15 @@ 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(TTL_IS_EXPIRED(d->ttl, now))
return NULL;
time_t rr_ttl;
if(TTL_IS_EXPIRED(d->ttl, now)) {
/* Allow TTL=0 DNAME from upstream within grace period */
if(!(rrset->rk.flags & PACKED_RRSET_UPSTREAM_0TTL))
return NULL;
rr_ttl = 0;
} else {
rr_ttl = d->ttl - now;
}
/* only allow validated (with DNSSEC) DNAMEs used from cache
* for insecure DNAMEs, query again. */
*sec_status = d->security;
@@ -779,7 +793,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->flags = BIT_QR; /* reply, no AA, no error */
msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */
msg->rep->qdcount = 1;
msg->rep->ttl = d->ttl - now;
msg->rep->ttl = rr_ttl;
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;
@@ -831,7 +845,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
if(!newd)
return NULL;
ck->entry.data = newd;
newd->ttl = d->ttl - now; /* RFC6672: synth CNAME TTL == DNAME TTL */
newd->ttl = rr_ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */
newd->count = 1;
newd->rrsig_count = 0;
newd->trust = rrset_trust_ans_noAA;
+15 -3
View File
@@ -278,6 +278,10 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
(void)rrset_cache_update(rrset_cache, &ref, alloc, timenow);
}
/** Grace period in seconds for TTL=0 DNAME rrsets (RFC 2308: do not cache).
* Allows synthesis from cache within this window to reduce recursion load. */
#define DNAME_TTL0_GRACE_SECONDS 1
struct ub_packed_rrset_key*
rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint32_t flags, time_t timenow,
@@ -300,12 +304,20 @@ 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;
struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
lock_rw_unlock(&e->lock);
return NULL;
/* Allow TTL=0 DNAME within grace period for synthesis */
if(qtype == LDNS_RR_TYPE_DNAME &&
(k->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) &&
(timenow - data->ttl_add) <= DNAME_TTL0_GRACE_SECONDS) {
/* within grace: allow for synthesis */
} else {
lock_rw_unlock(&e->lock);
return NULL;
}
}
/* we're done */
return (struct ub_packed_rrset_key*)e->key;
return k;
}
return NULL;
}
+2 -15
View File
@@ -2300,21 +2300,8 @@ int
tcp_req_info_handle_read_close(struct tcp_req_info* req)
{
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
/* reset byte count for (potential) partial read */
req->cp->tcp_byte_count = 0;
/* if we still have results to write, pick up next and write it */
if(req->num_done_req != 0) {
tcp_req_pickup_next_result(req);
tcp_req_info_setup_listen(req);
return 1;
}
/* if nothing to do, this closes the connection */
if(req->num_open_req == 0 && req->num_done_req == 0)
return 0;
/* otherwise, we must be waiting for dns resolve, wait with timeout */
req->read_is_closed = 1;
tcp_req_info_setup_listen(req);
return 1;
/* RFC 7766 6.2.4 says to drop pending replies when client closes. */
return 0; /* drop connection */
}
void
+106 -75
View File
@@ -56,6 +56,24 @@
* with 16 bytes for an A record, a 64K packet has about 4000 max */
#define LOCALZONE_RRSET_COUNT_MAX 4096
static const char* default_zones_reverse_array[] = {
"127.in-addr.arpa.", /* reverse ip4 zone */
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", /* reverse ip6 zone */
0
};
const char** local_zones_default_reverse = default_zones_reverse_array;
static const char* default_zones_special_array[] = {
"test.", /* RFC 6761 */
"invalid.", /* RFC 6761 */
"onion.", /* RFC 7686 */
"home.arpa.", /* RFC 8375 */
"resolver.arpa.", /* RFC 9462 */
"service.arpa.", /* RFC 9665 */
0
};
const char** local_zones_default_special = default_zones_special_array;
/** print all RRsets in local zone */
static void
local_zone_out(struct local_zone* z)
@@ -650,7 +668,7 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr)
}
labs = dname_count_size_labels(rr_name, &len);
lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type, 1);
if(!z) {
lock_rw_unlock(&zones->lock);
fatal_exit("internal error: no zone for rr %s", rr);
@@ -834,7 +852,7 @@ lz_nodefault(struct config_file* cfg, const char* name)
for(p = cfg->local_zones_nodefault; p; p = p->next) {
/* compare zone name, lowercase, compare without ending . */
if(strncasecmp(p->str, name, len) == 0 &&
if(strncasecmp(p->str, name, len) == 0 &&
(strlen(p->str) == len || (strlen(p->str)==len+1 &&
p->str[len] == '.')))
return 1;
@@ -842,6 +860,45 @@ lz_nodefault(struct config_file* cfg, const char* name)
return 0;
}
/** enter reverse default zone */
static int
add_reverse_default(struct local_zones* zones, struct config_file* cfg,
const char* name)
{
struct local_zone* z;
char str[1024]; /* known long enough */
if(lz_exists(zones, name) || lz_nodefault(cfg, name))
return 1; /* do not enter default content */
if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN)))
return 0;
snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800", name);
if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
if(strncasecmp("127.in-addr.arpa.", name, 17) == 0) {
if(!lz_enter_rr_into_zone(z,
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
lock_rw_unlock(&z->lock);
return 0;
}
} else if(strncasecmp("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", name, 73) == 0) {
snprintf(str, sizeof(str), "%s 10800 IN PTR localhost.", name);
if(!lz_enter_rr_into_zone(z, str)) {
lock_rw_unlock(&z->lock);
return 0;
}
}
lock_rw_unlock(&z->lock);
return 1;
}
/** enter (AS112) empty default zone */
static int
add_empty_default(struct local_zones* zones, struct config_file* cfg,
@@ -902,72 +959,23 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
}
lock_rw_unlock(&z->lock);
}
/* reverse ip4 zone */
if(!lz_exists(zones, "127.in-addr.arpa.") &&
!lz_nodefault(cfg, "127.in-addr.arpa.")) {
if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN NS localhost.") ||
!lz_enter_rr_into_zone(z,
"127.in-addr.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
!lz_enter_rr_into_zone(z,
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
/* ip4 and ip6 reverse */
for(zstr = local_zones_default_reverse; *zstr; zstr++) {
if(!add_reverse_default(zones, cfg, *zstr)) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
return 0;
}
lock_rw_unlock(&z->lock);
}
/* reverse ip6 zone */
if(!lz_exists(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") &&
!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
LDNS_RR_CLASS_IN)) ||
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
"nobody.invalid. 1 3600 1200 604800 10800") ||
!lz_enter_rr_into_zone(z,
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
/* special-use zones */
for(zstr = local_zones_default_special; *zstr; zstr++) {
if(!add_empty_default(zones, cfg, *zstr)) {
log_err("out of memory adding default zone");
if(z) { lock_rw_unlock(&z->lock); }
return 0;
}
lock_rw_unlock(&z->lock);
}
/* home.arpa. zone (RFC 8375) */
if(!add_empty_default(zones, cfg, "home.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
/* resolver.arpa. zone (RFC 9462) */
if(!add_empty_default(zones, cfg, "resolver.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
/* service.arpa. zone (draft-ietf-dnssd-srp-25) */
if(!add_empty_default(zones, cfg, "service.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
/* onion. zone (RFC 7686) */
if(!add_empty_default(zones, cfg, "onion.")) {
log_err("out of memory adding default zone");
return 0;
}
/* test. zone (RFC 6761) */
if(!add_empty_default(zones, cfg, "test.")) {
log_err("out of memory adding default zone");
return 0;
}
/* invalid. zone (RFC 6761) */
if(!add_empty_default(zones, cfg, "invalid.")) {
log_err("out of memory adding default zone");
return 0;
}
/* block AS112 zones, unless asked not to */
if(!cfg->unblock_lan_zones) {
for(zstr = as112_zones; *zstr; zstr++) {
@@ -1062,14 +1070,15 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
labs = dname_count_size_labels(rr_name, &len);
lock_rw_rdlock(&zones->lock);
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
rr_type)) {
rr_type, 1)) {
/* Check if there is a zone that this could go
* under but for different class; created zones are
* always for LDNS_RR_CLASS_IN. Create the zone with
* a different class but the same configured
* local_zone_type. */
struct local_zone* z = local_zones_lookup(zones,
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type,
1);
if(z) {
uint8_t* name = memdup(z->name, z->namelen);
size_t znamelen = z->namelen;
@@ -1231,28 +1240,48 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
struct local_zone*
local_zones_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype)
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
int foradd)
{
return local_zones_tags_lookup(zones, name, len, labs,
dclass, dtype, NULL, 0, 1);
dclass, dtype, NULL, 0, 1, foradd);
}
struct local_zone*
local_zones_tags_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
uint8_t* taglist, size_t taglen, int ignoretags)
uint8_t* taglist, size_t taglen, int ignoretags, int foradd)
{
rbnode_type* res = NULL;
struct local_zone *result;
struct local_zone key;
int m;
/* for type DS use a zone higher when on a zonecut */
if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
dname_remove_label(&name, &len);
labs--;
}
key.node.key = &key;
key.dclass = dclass;
/* for type DS use a zone higher when on a zonecut */
if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
/* If this is at a zone cut, of a local-zone, and it is
* of type always_refuse. Then also refuse the type DS
* for it. That could make it DNSSEC bogus, but it is
* REFUSED anyway. It stops CNAME type answers in the
* type DS lookup. */
key.name = name;
key.namelen = len;
key.namelabs = labs;
/* For additions and removals, use the ordinary rule,
* to remove a label for type DS to locate the parent zone.
* That is where the DS RR needs to be put. */
if(!foradd &&
(result=(struct local_zone*)rbtree_search(
&zones->ztree, &key)) != NULL &&
result->type == local_zone_always_refuse) {
/* The type DS does not go up one label. */
return result;
} else {
dname_remove_label(&name, &len);
labs--;
}
}
key.name = name;
key.namelen = len;
key.namelabs = labs;
@@ -1863,7 +1892,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
if(view->local_zones &&
(z = local_zones_lookup(view->local_zones,
qinfo->qname, qinfo->qname_len, labs,
qinfo->qclass, qinfo->qtype))) {
qinfo->qclass, qinfo->qtype, 0))) {
lock_rw_rdlock(&z->lock);
lzt = z->type;
}
@@ -1897,7 +1926,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
lock_rw_rdlock(&zones->lock);
if(!(z = local_zones_tags_lookup(zones, qinfo->qname,
qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype,
taglist, taglen, 0))) {
taglist, taglen, 0, 0))) {
lock_rw_unlock(&zones->lock);
return 0;
}
@@ -2102,7 +2131,8 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
/* could first try readlock then get writelock if zone does not exist,
* but we do not add enough RRs (from multiple threads) to optimize */
lock_rw_wrlock(&zones->lock);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type,
1);
if(!z) {
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
local_zone_transparent);
@@ -2180,7 +2210,8 @@ void local_zones_del_data(struct local_zones* zones,
/* remove DS */
lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS,
1);
if(z) {
lock_rw_wrlock(&z->lock);
d = local_zone_find_data(z, name, len, labs);
@@ -2194,7 +2225,7 @@ void local_zones_del_data(struct local_zones* zones,
/* remove other types */
lock_rw_rdlock(&zones->lock);
z = local_zones_lookup(zones, name, len, labs, dclass, 0);
z = local_zones_lookup(zones, name, len, labs, dclass, 0, 1);
if(!z) {
/* no such zone, we're done */
lock_rw_unlock(&zones->lock);
+10 -2
View File
@@ -57,6 +57,9 @@ struct sldns_buffer;
struct comm_reply;
struct config_strlist;
extern const char** local_zones_default_special;
extern const char** local_zones_default_reverse;
/**
* Local zone type
* This type determines processing for queries that did not match
@@ -262,11 +265,13 @@ void local_zone_delete(struct local_zone* z);
* @param taglen: length of taglist.
* @param ignoretags: lookup zone by name and class, regardless the
* local-zone's tags.
* @param foradd: if the lookup is for addition or removal of the type.
* Used for type DS. The lookup for answers turns this off.
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
uint8_t* taglist, size_t taglen, int ignoretags);
uint8_t* taglist, size_t taglen, int ignoretags, int foradd);
/**
* Lookup zone that contains the given name, class.
@@ -278,10 +283,13 @@ struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
* @param dclass: class to lookup.
* @param dtype: type of the record, if type DS then a zone higher up is found
* pass 0 to just plain find a zone for a name.
* @param foradd: if the lookup is for addition or removal of the type.
* Used for type DS. The lookup for answers turns this off.
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype);
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
int foradd);
/**
* Debug helper. Print all zones
+13 -2
View File
@@ -1036,6 +1036,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
mstate->s.no_cache_store = 0;
mstate->s.need_refetch = 0;
mstate->s.was_ratelimited = 0;
mstate->s.error_response_cache = 0;
mstate->s.qstarttime = *env->now;
/* init modules */
@@ -1075,6 +1076,14 @@ mesh_state_cleanup(struct mesh_state* mstate)
if(!mstate->replies_sent) {
struct mesh_reply* rep = mstate->reply_list;
struct mesh_cb* cb;
/* One http2 stream could bring down its comm_point along with
* the other streams which could share the same query. Do all
* the http2 stream bookkeeping upfront. */
for(; rep; rep=rep->next) {
if(rep->query_reply.c->use_h2)
http2_stream_remove_mesh_state(rep->h2_stream);
}
rep = mstate->reply_list;
/* in tcp_req_info, the mstates linked are removed, but
* the reply_list is now NULL, so the remove-from-empty-list
* takes no time and also it does not do the mesh accounting */
@@ -1082,8 +1091,6 @@ mesh_state_cleanup(struct mesh_state* mstate)
for(; rep; rep=rep->next) {
infra_wait_limit_dec(mesh->env->infra_cache,
&rep->query_reply, mesh->env->cfg);
if(rep->query_reply.c->use_h2)
http2_stream_remove_mesh_state(rep->h2_stream);
comm_point_drop_reply(&rep->query_reply);
log_assert(mesh->num_reply_addrs > 0);
mesh->num_reply_addrs--;
@@ -2370,6 +2377,10 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
mesh->num_reply_addrs--;
infra_wait_limit_dec(mesh->env->infra_cache,
&n->query_reply, mesh->env->cfg);
/* We may be removing more than one http2 stream (they
* share the same comm_point); make sure the streams
* don't point back. */
if(n->h2_stream) n->h2_stream->mesh_state = NULL;
/* prev = prev; */
n = n->next;
+58 -7
View File
@@ -160,6 +160,19 @@ reuse_cmp_addrportssl(const void* key1, const void* key2)
return 1;
if(!r1->is_ssl && r2->is_ssl)
return -1;
/* compare tls_auth_name if SSL-enabled */
if(r1->is_ssl) {
if(r1->tls_auth_name && !r2->tls_auth_name)
return 1;
if(!r1->tls_auth_name && r2->tls_auth_name)
return -1;
if(r1->tls_auth_name && r2->tls_auth_name) {
r = strcmp(r1->tls_auth_name, r2->tls_auth_name);
if(r != 0)
return r;
}
}
return 0;
}
@@ -531,7 +544,7 @@ reuse_tcp_insert(struct outside_network* outnet, struct pending_tcp* pend_tcp)
/** find reuse tcp stream to destination for query, or NULL if none */
static struct reuse_tcp*
reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
socklen_t addrlen, int use_ssl)
socklen_t addrlen, int use_ssl, char* tls_auth_name)
{
struct waiting_tcp key_w;
struct pending_tcp key_p;
@@ -545,8 +558,10 @@ reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
key_p.c = &c;
key_p.reuse.pending = &key_p;
key_p.reuse.node.key = &key_p.reuse;
if(use_ssl)
if(use_ssl) {
key_p.reuse.is_ssl = 1;
key_p.reuse.tls_auth_name = tls_auth_name;
}
if(addrlen > (socklen_t)sizeof(key_p.reuse.addr))
return NULL;
memmove(&key_p.reuse.addr, addr, addrlen);
@@ -646,6 +661,7 @@ static int
outnet_tcp_take_into_use(struct waiting_tcp* w)
{
struct pending_tcp* pend = w->outnet->tcp_free;
char* tls_auth_name = NULL;
int s;
log_assert(pend);
log_assert(w->pkt);
@@ -746,7 +762,22 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
#endif
pend->c->ssl_shake_state = comm_ssl_shake_write;
if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name,
if(w->tls_auth_name) {
/* strdup the auth name, while not linked the list yet,
* in case of failure, easy cleanup. */
tls_auth_name = strdup(w->tls_auth_name);
if(!tls_auth_name) {
log_err("out of memory: alloc tls auth name");
pend->c->fd = s;
#ifdef HAVE_SSL
SSL_free(pend->c->ssl);
#endif
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
}
if(!set_auth_name_on_ssl(pend->c->ssl, tls_auth_name,
w->outnet->tls_use_sni)) {
pend->c->fd = s;
#ifdef HAVE_SSL
@@ -754,6 +785,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
#endif
pend->c->ssl = NULL;
comm_point_close(pend->c);
free(tls_auth_name);
return 0;
}
}
@@ -778,9 +810,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
if(pend->reuse.node.key)
reuse_tcp_remove_tree_list(w->outnet, &pend->reuse);
if(pend->c->ssl)
if(pend->c->ssl) {
pend->reuse.is_ssl = 1;
else pend->reuse.is_ssl = 0;
if(pend->reuse.tls_auth_name)
free(pend->reuse.tls_auth_name);
pend->reuse.tls_auth_name = tls_auth_name;
tls_auth_name = NULL;
} else {
pend->reuse.is_ssl = 0;
if(pend->reuse.tls_auth_name)
free(pend->reuse.tls_auth_name);
pend->reuse.tls_auth_name = NULL;
}
/* free tls auth name if nonNULL */
free(tls_auth_name);
/* insert in reuse by address tree if not already inserted there */
(void)reuse_tcp_insert(w->outnet, pend);
reuse_tree_by_id_insert(&pend->reuse, w);
@@ -969,7 +1012,7 @@ use_free_buffer(struct outside_network* outnet)
(!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen,
w->ssl_upstream);
w->ssl_upstream, w->tls_auth_name);
/* re-select an ID when moving to a new TCP buffer */
w->id = tcp_select_id(outnet, reuse);
LDNS_ID_SET(w->pkt, w->id);
@@ -1198,6 +1241,10 @@ decommission_pending_tcp(struct outside_network* outnet,
/* needs unlink from the reuse tree to get deleted */
reuse_tcp_remove_tree_list(outnet, &pend->reuse);
}
if(pend->reuse.tls_auth_name) {
free(pend->reuse.tls_auth_name);
pend->reuse.tls_auth_name = NULL;
}
/* free SSL structure after remove from outnet tcp reuse tree,
* because the c->ssl null or not is used for sorting in the tree */
if(pend->c->ssl) {
@@ -1922,6 +1969,10 @@ outside_network_delete(struct outside_network* outnet)
* the tcp conn is working on */
decommission_pending_tcp(outnet, pend);
}
if(pend->reuse.tls_auth_name) {
free(pend->reuse.tls_auth_name);
pend->reuse.tls_auth_name = NULL;
}
comm_point_delete(outnet->tcp_conns[i]->c);
free(outnet->tcp_conns[i]);
outnet->tcp_conns[i] = NULL;
@@ -2447,7 +2498,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
/* find out if a reused stream to the target exists */
/* if so, take it into use */
reuse = reuse_tcp_find(sq->outnet, &sq->addr, sq->addrlen,
sq->ssl_upstream);
sq->ssl_upstream, sq->tls_auth_name);
if(reuse) {
log_reuse_tcp(VERB_CLIENT, "pending_tcp_query: found reuse", reuse);
log_assert(reuse->pending);
+3
View File
@@ -264,6 +264,9 @@ struct reuse_tcp {
socklen_t addrlen;
/** also key for tcp_reuse tree, if ssl is used */
int is_ssl;
/** If is_ssl is enabled, tls_auth_name is part of the key for
* tcp_reuse tree. If the string is NULL, it without a tls_auth_name */
char* tls_auth_name;
/** lru chain, so that the oldest can be removed to get a new
* connection when all are in (re)use. oldest is last in list.
* The lru only contains empty connections waiting for reuse,
+1
View File
@@ -153,6 +153,7 @@ rpz_type_ignored(uint16_t rr_type)
case LDNS_RR_TYPE_SOA:
case LDNS_RR_TYPE_NS:
case LDNS_RR_TYPE_DNAME:
case LDNS_RR_TYPE_ZONEMD:
/* all DNSSEC-related RRs must be ignored */
case LDNS_RR_TYPE_DNSKEY:
case LDNS_RR_TYPE_DS:
+10 -2
View File
@@ -2430,12 +2430,20 @@ int main(int argc, char* argv[])
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
if(dolist) do_list_builtin();
+46
View File
@@ -44,6 +44,7 @@
#include "config.h"
#include <ctype.h>
#include "util/as112.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/module.h"
@@ -188,11 +189,56 @@ donotquerylocalhostcheck(struct config_file* cfg)
}
}
static void
nodefaultzonescheck(struct config_file* cfg)
{
struct config_strlist* d;
const char** zstr;
size_t len;
#define COMPARE_ZONE_NAME(confname, builtname, len) \
(strncasecmp(confname, builtname, (len)) == 0 && \
(strlen(confname) == (len) || \
(strlen(confname) == (len) + 1 \
&& confname[(len)] == '.')))
for(d = cfg->local_zones_nodefault; d; d = d->next) {
if(!cfg->unblock_lan_zones) {
for(zstr = as112_zones; *zstr; zstr++) {
len = strlen(*zstr) - 1; /* trailing '.' */
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
goto default_continue;
}
}
for(zstr = local_zones_default_special; *zstr; zstr++) {
len = strlen(*zstr) - 1; /* trailing '.' */
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
goto default_continue;
}
for(zstr = local_zones_default_reverse; *zstr; zstr++) {
len = strlen(*zstr) - 1; /* trailing '.' */
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
goto default_continue;
}
if(COMPARE_ZONE_NAME(d->str, "localhost.", 10 - 1))
goto default_continue;
fprintf(stderr, "unbound-checkconf: warning: local-zone: '%s' "
"is configured as 'nodefault' but there is no such "
"default local-zone. Check the unbound.conf "
"documentation for default configured local-zones.\n",
d->str);
default_continue:
; /* statement to jump to, for older gcc. */
}
#undef COMPARE_ZONE_NAME
}
/** check localzones */
static void
localzonechecks(struct config_file* cfg)
{
struct local_zones* zs;
nodefaultzonescheck(cfg);
if(!(zs = local_zones_create()))
fatal_exit("out of memory");
if(!local_zones_apply_cfg(zs, cfg))
+10 -2
View File
@@ -1052,12 +1052,20 @@ int main(int argc, char* argv[])
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
if(!RAND_status()) {
+10 -2
View File
@@ -521,12 +521,20 @@ int main(int argc, char* argv[])
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#endif /* HAVE_SSL */
#ifdef HAVE_NSS
+10 -2
View File
@@ -488,12 +488,20 @@ int main(int argc, char** argv)
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#endif /* HAVE_SSL */
+1
View File
@@ -360,6 +360,7 @@ typedef pthread_key_t ub_thread_key_type;
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
#define ub_thread_key_get(key) pthread_getspecific(key)
#define ub_thread_setname(thread, name) /* nop */
#endif /* USE_THREAD_DEBUG */
#endif /* TESTCODE_CHECK_LOCKS_H */
+10 -2
View File
@@ -642,12 +642,20 @@ int main(int argc, char** argv)
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
}
run(h2_session, port, no_tls, argc, argv);
+7
View File
@@ -141,6 +141,13 @@ if test -f $done; then
exit 0
fi
# always clear the skip mark file in case something changed in the environment
# in between runs
if test -f $skip; then
echo "minitdir $skip exists; removing."
rm $skip
fi
# Copy
if test $quiet = 0; then
echo "minitdir copy $1 to $dir"
+27 -4
View File
@@ -160,11 +160,26 @@ read_ssl_line(SSL* ssl, char* buf, size_t len)
return 0;
}
if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
int e = SSL_get_error(ssl, r);
if(e == SSL_ERROR_ZERO_RETURN) {
/* EOF */
break;
} else if(e == SSL_ERROR_WANT_READ) {
continue;
} else if(e == SSL_ERROR_WANT_WRITE) {
continue;
} else if(e == SSL_ERROR_SYSCALL) {
if(verb) printf("could not SSL_read %s\n",
strerror(errno));
} else if(e == SSL_ERROR_SSL) {
int er = ERR_peek_error();
if(er)
printf("could not SSL_read: %s\n",
ERR_reason_error_string(er));
} else {
if(verb) printf("could not SSL_read "
"(SSL_get_error %d)\n", e);
}
if(verb) printf("could not SSL_read\n");
return 0;
}
if(endnl && buf[n] == '\n') {
@@ -675,12 +690,20 @@ int main(int argc, char* argv[])
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
do_service(addr, port, key, cert);
+12 -2
View File
@@ -59,12 +59,16 @@ static void usage(char* argv[])
/** read hex input */
static void read_input(sldns_buffer* pkt, FILE* in)
{
char buf[102400];
/* Buffer for 64Kib packet, in hex, with spaces and comments. */
char buf[1024000];
char* np = buf;
while(fgets(np, (int)sizeof(buf) - (np-buf), in)) {
if(buf[0] == ';') /* comment */
continue;
np = &np[strlen(np)];
if((size_t)(np-buf) >= sizeof(buf)-1)
fatal_exit("input too large (%lu bytes)",
(unsigned long)sizeof(buf));
}
hex_to_buf(pkt, buf);
}
@@ -188,10 +192,16 @@ static void analyze(sldns_buffer* pkt)
/** main program for pktview */
int main(int argc, char* argv[])
{
sldns_buffer* pkt = sldns_buffer_new(65553);
sldns_buffer* pkt;
log_init(NULL, 0, NULL);
log_ident_set("pktview");
if(argc != 1) {
usage(argv);
}
pkt = sldns_buffer_new(65553);
if(!pkt) fatal_exit("out of memory");
read_input(pkt, stdin);
+10 -2
View File
@@ -652,12 +652,20 @@ int main(int argc, char** argv)
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
(void)SSL_library_init();
#else
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
| OPENSSL_INIT_NO_LOAD_CONFIG
# endif
, NULL);
#endif
}
send_em(svr, pp2_client, udp, usessl, noanswer, onarrival, delay, argc, argv);
+4 -1
View File
@@ -1774,11 +1774,14 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
memmove(res+LDNS_HEADER_SIZE+dlen+4,
orig+LDNS_HEADER_SIZE+olen+4,
reslen-(LDNS_HEADER_SIZE+dlen+4));
} else if(origlen == 0) {
res = NULL;
reslen = 0;
} else {
res = memdup(orig, origlen);
reslen = origlen;
}
if(!res) {
if(!res && reslen > 0) {
verbose(1, "out of memory; send without adjust\n");
return;
}
+10 -4
View File
@@ -226,6 +226,7 @@ STEP 150 TIME_PASSES ELAPSE 200
STEP 160 FLUSH_MESSAGE www.example.com. IN A
; cache has no answer, cachedb is expired
; but it needs to be validated.
STEP 170 QUERY
ENTRY_BEGIN
REPLY RD DO
@@ -235,12 +236,14 @@ ENTRY_END
STEP 180 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
MATCH all ttl
;ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 123 IN A 1.2.3.4
;www.example.com. 123 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
STEP 190 TRAFFIC
@@ -298,14 +301,17 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
; but it needs to be validated
STEP 280 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl ede=3
MATCH all ttl
;ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 123 IN A 1.2.3.4
;www.example.com. 123 IN A 1.2.3.4
www.example.com. 200 IN A 1.2.3.4
ENTRY_END
STEP 290 TRAFFIC
+297
View File
@@ -0,0 +1,297 @@
; config options
; The island of trust is at test.
server:
trust-anchor: "test. DS 1444 8 2 8a87d067fd09a5965244fe2e317dd26d182c468e0a7f26ecc4c7b479bf89db9b"
val-override-date: "20201020135527"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
fake-sha1: yes
trust-anchor-signaling: no
minimal-responses: no
iter-scrub-promiscuous: no
aggressive-nsec: yes
local-zone: test. nodefault
log-servfail: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test DNAME with an unsigned CNAME that mismatches the DNAME.
; The CNAME occurs later in a list of redirections.
; 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
test. IN NS
SECTION AUTHORITY
test. IN NS ns.test.
SECTION ADDITIONAL
ns.test. IN A 1.2.3.5
ENTRY_END
RANGE_END
; ns.test
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
test. IN NS
SECTION ANSWER
test. IN NS ns.test
test. 3600 IN RRSIG NS 8 1 3600 20201116135527 20201019135527 1444 test. RGCxIO32TbbLTk6xZmTr+fjYPH50hntBxeOQ2DIj2pDsmjALcHYtVkOfpfk2EhOhHZd+9PLuoJPbJh6a9NqLSFeBvr0XZoCZoQ2g0tCHUNHcH5EVjA2TuYBQem6DVYnPLJ3914aRx0uA1j42b8dC2xsam/XkOo7U+dLbUW2Os1s=
SECTION ADDITIONAL
ns.test. IN A 1.2.3.5
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.test. IN A
SECTION ANSWER
ns.test. IN A 1.2.3.5
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.test. IN AAAA
SECTION AUTHORITY
test. 3600 IN SOA ns.test. host.test. 20201 3600 1800 604800 3600
test. 3600 IN RRSIG SOA 8 1 3600 20201116135527 20201019135527 1444 test. IZJIDmEgf0W7A5G7hvvZ2hUqJ9Trbv1/i7ySapDmPbYV9lVCmHHobySxO01yDhI2/Pvpsvxqrm1Tiv3BxH8uzZ4keKgiQjBsSy4htAsFct9I4E7ly2glPj/Fm3oun3PsjJDv5QYhx0KS7w4IQKU7Nc9pfJc92uoUI5bdoC1pRGw=
ns.test. 3600 IN NSEC nz.test. A RRSIG
ns.test. 3600 IN RRSIG NSEC 8 2 3600 20201116135527 20201019135527 1444 test. PElArVB3KPg8KHAP7lzcNbhFuXNxTsHNTn1dZVncB5qmWRdIaeKpaXDjpH0JSXMaelGFS+/QhuQ6Hmw9+4VyZFRqMzGhw4agUR/2bxABHcDIG4ZpUwyeSP61ATTfHUkQVxaH2wjCWI/tfmesdP2xVE4GXyUvCIBxU914MkZbULU=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
test. IN DNSKEY
SECTION ANSWER
test. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
test. 3600 IN RRSIG DNSKEY 8 1 3600 20201116135527 20201019135527 1444 test. UmRMS4iG9NBBHZYOtpwFFcJgbEb5SfHSgHd9XRe/8pTWM31WSDayn5ViPOBMqI1T5TXg2amc13dDI574xIM2oKMus3b5cBW72jJLW13jprBtslO6P8BMWb4HNnvLrJtQjwf3ErRirtTxinLmywQtmyr1cdthyG3Gp4N7i90fHSc=
SECTION ADDITIONAL
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.test. IN DS
SECTION ANSWER
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.test. IN NS
SECTION AUTHORITY
example.test. IN NS ns.example.test.
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
SECTION ADDITIONAL
ns.example.test. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
fox.test. IN NS
SECTION AUTHORITY
fox.test. IN NS ns.fox.test.
fox.test. 3600 IN DS 29332 8 2 5b06f16c7b8cc07ba7b8e1ab0a40a40ecf89e1e94da2f0b1d2159b64dba80d96
fox.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. B9bKqUJgJcGlKSWyGkdGGS6unKUwNJteTq08caL40QEZcAy836vwypGzOIQJNUw+mYIEecvtrF9H4mG+EjzDKv+n+36DCNvJMn6b8+FC9COw4mqITAjYPZjDwtOXAKVbuBuZJsbP2ztacJ98tXcORozaaKDGH/3fmsUlaKcuPmo=
SECTION ADDITIONAL
ns.fox.test. IN A 1.2.3.6
ENTRY_END
RANGE_END
; ns.example.test.
RANGE_BEGIN 0 15
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.test. IN NS
SECTION ANSWER
example.test. IN NS ns.example.test.
example.test. 3600 IN RRSIG NS 8 2 3600 20201116135527 20201019135527 55567 example.test. l1JT0wMlK0YI7/CWHzexf/k0iafUhCgN+BdgjBXIRXmSQNf4HDTiAkbcWL2/15qtnp12nQy9JeiTdSQ3vtPoHAJX4C5uTWaze4ms+Wrrf+n92sLCjacP9x50uuicH3URT6cKb1QCAPwlvlWxIlZjAMYFScSns7+C441NMJT8aE4=
SECTION ADDITIONAL
ns.example.test. IN A 1.2.3.4
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.test. IN A
SECTION ANSWER
ns.example.test. IN A 1.2.3.4
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.test. IN AAAA
SECTION AUTHORITY
example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
ns.example.test. 3600 IN NSEC nz.example.test. A RRSIG
ns.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. v/5aO/n8Ow21y7LE7JKZsFkUJU5MjIfadVRm2Tdb8f3RLwYDdBTs3aWeeEQdCRSUF61TmfJM1jIxlWQPuHbqzGnjSk7adw9gFpP7wFwoqG3/xdCFHoxo/3/1F/4Ankey3sDgKgOFsgnu40TlL36mGPYszeK+/2o3SAx2GM+3BdU=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.test. IN DNSKEY
SECTION ANSWER
example.test. 3600 IN DNSKEY 257 3 8 AwEAAdug/L739i0mgN2nuK/bhxu3wFn5Ud9nK2+XUmZQlPUEZUC5YZvm1rfMmEWTGBn87fFxEu/kjFZHJ55JLzqsbbpVHLbmKCTT2gYR2FV2WDKROGKuYbVkJIXdKAjJ0ONuK507NinYvlWXIoxHn22KAWOd9wKgSTNHBlmGkX+ts3hh ;{id = 55567 (ksk), size = 1024b}
example.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 55567 example.test. IbWMC6quOuZFNPAVxQLqCJ9nLhindBo826rnLcg5yMgs9dGUSPOCXAfHTmbgJAUNs9HTFfrJWNvasnETs0UOpmEuifGwWdH1OlME7Gny4RL2QmITUFeMW81Jz1tiVQxFXl6yxT0jxOxvz+bqMHlrz+8IeWQXcO+GZTPu8ueq30g=
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.d.example.test. IN A
SECTION ANSWER
d.example.test. 3600 IN DNAME tgt.example.test.
d.example.test. 3600 IN RRSIG DNAME 8 3 3600 20201116135527 20201019135527 55567 example.test. EGpXUnJuzkETAO2OWyZDrTeInnyxF7CXPXGDfFt2x3CBUeckUUZcgQQ3yMh+BATKph2nOhBfk8klvZ35C9sQO7Z32REAnqGjpHiR86xRPYxG62Nk9kXv1Odeh/adz2QhB93N8U7W57FM0P/VQDkP0GQXTSRGTuj+7ihfYVd4HWI=
; with CNAME signature
a.d.example.test. 3600 IN CNAME a.tgt.example.test.
a.d.example.test. 3600 IN RRSIG CNAME 8 4 3600 20201116135527 20201019135527 55567 example.test. efnytLE7P95kLr/tA9H0Z77VTOUQk24ci2bDgdVe8EuodTXtgg5PVHVLljD3QQ1Cpyme50odH/fhn2j1ORQpJTMk24Un/VRhVNquf+kj1nawJ59J0hjag4i0FIwZEG3/P7ogTB3Yd2y0Osb42Aawp48KvtVkUeBukk/GSutaTVQ=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.tgt.example.test. IN A
SECTION ANSWER
a.tgt.example.test. 3600 IN CNAME b.d.example.test.
a.tgt.example.test. 3600 IN RRSIG CNAME 8 4 3600 20201116135527 20201019135527 55567 example.test. XHYWSHIm9J8j8T1qMh1tHZS71UguXYUVescKPFtoGHRuyRhHNob+NAqdn3I4/+8HSSGrJDqhTX/Vo3rcc3/g5HOHScwzZByB/diyJWpG9IA7pm7c7FnHnHpGBVdHq9wXlkgCPiaJShpE1zg1nNy3p99ca9/wh4y9XWSfcl0L8aw=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
b.d.example.test. IN A
SECTION ANSWER
; This answer is injected
; Without an RRSIG.
b.d.example.test. 3600 IN CNAME www.fox.test.
ENTRY_END
RANGE_END
; ns.fox.test.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.6
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.fox.test. IN AAAA
SECTION AUTHORITY
fox.test. 3600 IN SOA ns.fox.test. host.fox.test. 20601 3600 1800 604800 3600
fox.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 29332 fox.test. QScf+vyis5/Km03ALuLQDfUDagA9/UG/oIQw6LnvmsVoqJSNXa3LIObWT9zfWgdJT0qFayWR4K9hnd9rT1enuVmXX8k47s7AjPZmE0qQxms5xz7jOhj/XLFplXOE9/GkgvAZKPb42qkU3Xf6Bevxzfy4/qW7+yXflWsjLV1vAhz38M4ESeWp0MDme8+DND0f7aoprGcC5saAPfa35nQhHS40q4IwiUDBBk1uwhCBF9ZGsjRfXmECOxIc1/0hBOv+Hhwog4K5b8rdl7LA2VggNiVOUuLFpXEH0XxknEspbQwWppP4TWC1H2QYGaKCc2Hu7NBhM/Ly7caGK+2u1MZvsg==
ns.fox.test. 3600 IN NSEC nz.fox.test. A RRSIG
ns.fox.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 29332 fox.test. RQjV2PHbBVdGhvSRl0lutzoIZ9KezBAAwvI5sQoIGLdlMeQxj/BOy16auYRLTxvB9xehkrTTeL5xYUwcbi4uFS/kr3IUmlVXeldHOk4T42huV9MGfWzguUsB2jjsrcdt11qEnLo27SVVcvQReswwfpOPRPHg52fS6vt50AIWwttLOLvZEGiGIjRGb4lBaCnoO6YYzOnwcRCV0UScTjlPxS1SBEKsdbPvzfUUyp+wOVnIVAXrd0xEChB7QrTIrcBt4mutXVUNBDcfkZCXgEwu3scWQQS8rNO6O3PvpLgs6PIHX191WjovkJ9/PL+8MO/7UUatSWhZUwuQBUq6VofCYw==
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
fox.test. IN DNSKEY
SECTION ANSWER
fox.test. IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
fox.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 29332 fox.test. bTslCQKai9U9EWkBPnMiO+Rb34qMAZSzfgEb68x+ZKi2DDyzK7v8TCX8unTlqeQCnTqqgJ7cCUcqrbSV3ip9WGNe5fUy5j9hxH04ddLcDhygnjLi4C7iQX67ratRGu1JM3Evk/gVF76a5J2RSQk340jOFHC0nnjWOMHlDDxBeK4Zr6lYvAMJB2uy08xbi1FuGUSPcrbRFnVb74QMAPLS9Uj5JM8lMsOMtrhHX9zBN8Euo4M1X0sinBdJse3P/fIZ+ZvSnOEpVvur3bcUl+bqFJ18nM/Mj/e3XW3WBWE1dI6p6HdAXLrJyjJINzm+YnNzj11tzu/e4BQCjOutY9XkKA==
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.fox.test. IN A
SECTION ANSWER
www.fox.test. 3600 IN A 10.20.30.43
www.fox.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 29332 fox.test. ehPLws7Jnlx5Trm7Z8Hxr0WkLdkxyif+E1aGzFMib4eP0nvLV89WOQ2Fpm1xT/VaNJBXjXhWPB0Oo/gAKVs1znqmyjutFdXi2+9rXnK73jD2+rWBGW/sgBl/9cr458j7441nEK18Mq4SserQcLBqM38IivTlK1J5uXUpEPKMCSA82waf0Z+LUk8czFqeYy+KlJSsiu33mrVWrjyNLIXCbZ2dxfdaVSKyAoQafiokp1NGnw3onQkXXOPqJ7GRsN8Ml4c2nOrEYIG6otoZXXjtkoNCOHzBBkPVEP82JjzQchq0fDWQ2UHOXXZYBG/B6m5PuOXmgKJVDKZ/iVNQofPp8w==
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
a.d.example.test. IN A
ENTRY_END
STEP 10 TRAFFIC
; The unsigned CNAME should make SERVFAIL.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
a.d.example.test. IN A
SECTION ANSWER
ENTRY_END
SCENARIO_END
+374
View File
@@ -0,0 +1,374 @@
; config options
; The island of trust is at test.
server:
trust-anchor: "test. DS 1444 8 2 8a87d067fd09a5965244fe2e317dd26d182c468e0a7f26ecc4c7b479bf89db9b"
val-override-date: "20201020135527"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
fake-sha1: yes
trust-anchor-signaling: no
minimal-responses: no
iter-scrub-promiscuous: no
aggressive-nsec: yes
local-zone: test. nodefault
log-servfail: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test DS response with wildcard CNAME
; 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
test. IN NS
SECTION AUTHORITY
test. IN NS ns.test.
SECTION ADDITIONAL
ns.test. IN A 1.2.3.5
ENTRY_END
RANGE_END
; ns.test
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
test. IN NS
SECTION ANSWER
test. IN NS ns.test
test. 3600 IN RRSIG NS 8 1 3600 20201116135527 20201019135527 1444 test. RGCxIO32TbbLTk6xZmTr+fjYPH50hntBxeOQ2DIj2pDsmjALcHYtVkOfpfk2EhOhHZd+9PLuoJPbJh6a9NqLSFeBvr0XZoCZoQ2g0tCHUNHcH5EVjA2TuYBQem6DVYnPLJ3914aRx0uA1j42b8dC2xsam/XkOo7U+dLbUW2Os1s=
SECTION ADDITIONAL
ns.test. IN A 1.2.3.5
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.test. IN A
SECTION ANSWER
ns.test. IN A 1.2.3.5
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.test. IN AAAA
SECTION AUTHORITY
test. 3600 IN SOA ns.test. host.test. 20201 3600 1800 604800 3600
test. 3600 IN RRSIG SOA 8 1 3600 20201116135527 20201019135527 1444 test. IZJIDmEgf0W7A5G7hvvZ2hUqJ9Trbv1/i7ySapDmPbYV9lVCmHHobySxO01yDhI2/Pvpsvxqrm1Tiv3BxH8uzZ4keKgiQjBsSy4htAsFct9I4E7ly2glPj/Fm3oun3PsjJDv5QYhx0KS7w4IQKU7Nc9pfJc92uoUI5bdoC1pRGw=
ns.test. 3600 IN NSEC nz.test. A RRSIG
ns.test. 3600 IN RRSIG NSEC 8 2 3600 20201116135527 20201019135527 1444 test. PElArVB3KPg8KHAP7lzcNbhFuXNxTsHNTn1dZVncB5qmWRdIaeKpaXDjpH0JSXMaelGFS+/QhuQ6Hmw9+4VyZFRqMzGhw4agUR/2bxABHcDIG4ZpUwyeSP61ATTfHUkQVxaH2wjCWI/tfmesdP2xVE4GXyUvCIBxU914MkZbULU=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
test. IN DNSKEY
SECTION ANSWER
test. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
test. 3600 IN RRSIG DNSKEY 8 1 3600 20201116135527 20201019135527 1444 test. UmRMS4iG9NBBHZYOtpwFFcJgbEb5SfHSgHd9XRe/8pTWM31WSDayn5ViPOBMqI1T5TXg2amc13dDI574xIM2oKMus3b5cBW72jJLW13jprBtslO6P8BMWb4HNnvLrJtQjwf3ErRirtTxinLmywQtmyr1cdthyG3Gp4N7i90fHSc=
SECTION ADDITIONAL
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.test. IN DS
SECTION ANSWER
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.test. IN NS
SECTION AUTHORITY
example.test. IN NS ns.example.test.
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
SECTION ADDITIONAL
ns.example.test. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.test.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.test. IN NS
SECTION ANSWER
example.test. IN NS ns.example.test.
example.test. 3600 IN RRSIG NS 8 2 3600 20201116135527 20201019135527 55567 example.test. l1JT0wMlK0YI7/CWHzexf/k0iafUhCgN+BdgjBXIRXmSQNf4HDTiAkbcWL2/15qtnp12nQy9JeiTdSQ3vtPoHAJX4C5uTWaze4ms+Wrrf+n92sLCjacP9x50uuicH3URT6cKb1QCAPwlvlWxIlZjAMYFScSns7+C441NMJT8aE4=
SECTION ADDITIONAL
ns.example.test. IN A 1.2.3.4
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.test. IN A
SECTION ANSWER
ns.example.test. IN A 1.2.3.4
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.test. IN AAAA
SECTION ANSWER
ns.example.test. 3600 IN AAAA 2001::1:2:3:4
ns.example.test. 3600 IN RRSIG AAAA 8 3 3600 20201116135527 20201019135527 55567 example.test. IuFmNUqxRjWSw/Ua2A0XmeKbsVkw6Yzd/D4TGBZ5pyKtbYIFvmF/QfcqzONiwqG3KEW2tAeyEjZOYjrM37NqgIwwk56LJ16fFA7e2tShjSjPhgNzjHZW9zvFTjPyTTVpMVb3SGV59RQTm3jJwlQCq7qVHyKQ+HT3pa+XZQJEzdw=
SECTION AUTHORITY
;example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
;example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
;ns.example.test. 3600 IN NSEC nz.example.test. A RRSIG
;ns.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. v/5aO/n8Ow21y7LE7JKZsFkUJU5MjIfadVRm2Tdb8f3RLwYDdBTs3aWeeEQdCRSUF61TmfJM1jIxlWQPuHbqzGnjSk7adw9gFpP7wFwoqG3/xdCFHoxo/3/1F/4Ankey3sDgKgOFsgnu40TlL36mGPYszeK+/2o3SAx2GM+3BdU=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.test. IN DNSKEY
SECTION ANSWER
example.test. 3600 IN DNSKEY 257 3 8 AwEAAdug/L739i0mgN2nuK/bhxu3wFn5Ud9nK2+XUmZQlPUEZUC5YZvm1rfMmEWTGBn87fFxEu/kjFZHJ55JLzqsbbpVHLbmKCTT2gYR2FV2WDKROGKuYbVkJIXdKAjJ0ONuK507NinYvlWXIoxHn22KAWOd9wKgSTNHBlmGkX+ts3hh ;{id = 55567 (ksk), size = 1024b}
example.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 55567 example.test. IbWMC6quOuZFNPAVxQLqCJ9nLhindBo826rnLcg5yMgs9dGUSPOCXAfHTmbgJAUNs9HTFfrJWNvasnETs0UOpmEuifGwWdH1OlME7Gny4RL2QmITUFeMW81Jz1tiVQxFXl6yxT0jxOxvz+bqMHlrz+8IeWQXcO+GZTPu8ueq30g=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
tgt.example.test. DS
SECTION ANSWER
SECTION AUTHORITY
; denial of the DS record for tgt.example.test.
example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
tgt.example.test. 3600 IN NSEC tgz.example.test. A RRSIG
tgt.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. R9v8k/M56dLOUbrTP/m2XnKsOjIj1kAfwCQvHW4KPdDn3XJIvCLs4mTjxvyQ70uP+zA8WxrPgbqPZv//Ms3Sher2j41VKIBRFkJpyJn6/D9/QmOOhWzoPYXuujHJAkB9IDit3YOgJutirFnB7reTTav42P5x7PzQDSt+crUnXkw=
ENTRY_END
; when there is a re-query for the DS record, this answer is used.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.test. IN DS
SECTION ANSWER
; This reply is an injected reply.
sub.example.test. 300 IN CNAME tgt.example.test.
; signature for wildcard, *.example.test. 300 IN CNAME tgt.example.test.
sub.example.test. 300 IN RRSIG CNAME 8 2 300 20201116135527 20201019135527 55567 example.test. fz+xLPcRAbGUcnF7hITQHRT6AeA/I/dSjyLWb3it+cHSMY7dN4Jpw7Dk0GJh0y71HXFwaWgk1If0O4IOVo4mfkm1RrRhBnxJT8R88AQlN69SXLZrlHIhoupBpZADz/J15hOcHG+/1svsEpAA5qkOrgZwf581X9ygwPGFkIHgS+o=
ENTRY_END
; The referral to sub.example.test, for other queries than type DS.
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.test. IN NS
SECTION ANSWER
SECTION AUTHORITY
sub.example.test. 3600 NS ns.sub.example.test.
; Smaller TTL 300 for the DS.
sub.example.test. 300 IN DS 29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
sub.example.test. 300 IN RRSIG DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
SECTION ADDITIONAL
ns.sub.example.test. IN A 1.2.3.7
ENTRY_END
RANGE_END
; ns.sub.example.test.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.7
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.sub.example.test. IN AAAA
SECTION ANSWER
SECTION AUTHORITY
sub.example.test. 3600 IN SOA ns.sub.example.test. host.sub.example.test. 20701 3600 1800 604800 3600
sub.example.test. 3600 IN RRSIG SOA 8 3 3600 20201116135527 20201019135527 29332 sub.example.test. EEeC/XlG/XuItqRphAOREwHPzqSsJSs9TEhPnqOzXU4/+j0Eq05WN8ZE+GxHnmrxzaLiqAT6pLYLaQxCFcpkMVKUFYfMFyK6jOkTHZ1ODXNIdAA/ZGMCOQQUco3rcrY6F2U8ETHSxiFQkEl8iQntWM6wUoUF37Yd4hab+o1eD/HZXKLwgNXbXC1iY40ZzqwAlxLcCt0SexiTI9BNfyDy3iROeT3XuloC2x9o2zclAqz3m42n8UKAs8Gh7sAkoTua2fqtNfWZtQctlp1tZgdJFXbI4vuxMEldD+Rh5kUJ72aXvD2W7vd042G7z3n+d+I4vtnH2qKNbVA4YHMXzA/3ug==
ns.sub.example.test. 3600 IN NSEC nz.sub.example.test. A RRSIG
ns.sub.example.test. 3600 IN RRSIG NSEC 8 4 3600 20201116135527 20201019135527 29332 sub.example.test. CqaJIHttjfPIdBM1Ty8RDGRnrkaoC7Y7pzS/Kbzjn3lsEJg2XPWZGRln75imsoVOdi46YG95HZdgvnndTAAH3dE0eZHycvo2O7zR0f+Ty3v/HWpvOsRp/XE/8/7g45DHLuyTXxiO6cDSu0bW/qTC4xyix7vMFNEyOmGMGIZEnvkoRWJvUToj8VW6r+a8dU1KIGQXKSXg3lRcXc0Zfk2lk5P0XGrGzdLcITbZbVP3aFgusoi6uCTqhPmwZRVJjuh1E0qXTTE2A67vloVBvwVxfhNajHNkVhEYtxqZyiRLPs1tRyWit4J2Kkk5qoWuPwNRoTHsgzmPJoDGxheUxGEvbA==
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.test. IN DNSKEY
SECTION ANSWER
sub.example.test. 300 IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
sub.example.test. 300 IN RRSIG DNSKEY 8 3 300 20201116135527 20201019135527 29332 sub.example.test. j8lyYKogmlBon1WsYJp2H4DSdXZIGkzKHplH2hs9b5D2I+4kZ7jiwHz5/OZca5aOOE1QbhcPNRyhenSmtwePjhvBLSDDYC4OhowVpWW5o5aRQMnsTYZgmgqX0zPtUWBoK8P+GZRd1VO/Jam0qWoHjHY9lQlDnblN6f2yDRHQI2CVrSal8x12zl1s/QHVNpodb4MwowvL4WeGxDVxBOiS3v+9SobnfPa9oecu9onrcPryr4KDQHi6i5BNvHVPqE9eBkHnRe3DcvfEbOke6vZY7CCNgfGttaJL64ubCVUv2xu3okTQS5gSX9pRbjaxKlw1ZWmJR0HSq/dn2HDuWjzxkQ==
SECTION ADDITIONAL
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.sub.example.test. IN A
SECTION ANSWER
a.sub.example.test. 300 IN A 10.20.30.40
a.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
b.sub.example.test. IN A
SECTION ANSWER
b.sub.example.test. 300 IN A 10.20.30.41
b.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.test. IN A
SECTION ANSWER
www.sub.example.test. 300 IN A 10.20.30.42
www.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
ENTRY_END
RANGE_END
; ns.example.test.
RANGE_BEGIN 0 100
ADDRESS 2001::1:2:3:4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.test. IN DS
SECTION ANSWER
; This is the correct reply.
sub.example.test. 300 IN DS 29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
sub.example.test. 300 IN RRSIG DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
a.sub.example.test. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
a.sub.example.test. IN A
SECTION ANSWER
a.sub.example.test. 300 IN A 10.20.30.40
a.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
ENTRY_END
STEP 20 TIME_PASSES ELAPSE 320
; The DS record has expired, but the NS record for sub.example.test. is in
; cache.
; The DS lookup fails with wildcard CNAME.
; Then it should blacklist the parent (1.2.3.4) not the sub zone (1.2.3.7)
; the AAAA for the parent can then be retrieved, and it is used.
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.sub.example.test. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.test. IN A
SECTION ANSWER
www.sub.example.test. 300 IN A 10.20.30.42
www.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
ENTRY_END
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
b.sub.example.test. IN A
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
b.sub.example.test. IN A
SECTION ANSWER
b.sub.example.test. 300 IN A 10.20.30.41
b.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
ENTRY_END
SCENARIO_END
+1 -1
View File
@@ -8,7 +8,7 @@
if nc -h 2>&1 | grep "q secs"; then
ncopt="-q 3 -i 2"
else
ncopt="-i 2"
ncopt="-i 2 --no-shutdown"
fi
PRE="../.."
+93
View File
@@ -0,0 +1,93 @@
; This is a comment
server:
forward-zone: name: "." forward-addr: 216.0.0.1
CONFIG_END
SCENARIO_BEGIN Test scrub of RRSIG amount
RANGE_BEGIN 0 100
ADDRESS 216.0.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
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. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MQ== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mg== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mw== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NA== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NQ== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Ng== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Nw== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OA== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OQ== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTA= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTE= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTI= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTM= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTQ= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTU= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTY= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTc= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTg= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTk= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjA= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjE= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjI= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjM= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjQ= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjU= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjY= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjc= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjg= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjk= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzA= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzE= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzI= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzM= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzQ= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzU= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzY= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzc= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzg= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzk= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDA= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDE= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDI= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDM= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDQ= ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDU= ;{id = 12345}
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
MATCH TCP
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qname qtype all
REPLY QR RD DO RA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MQ== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mg== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mw== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NA== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NQ== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Ng== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Nw== ;{id = 12345}
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OA== ;{id = 12345}
ENTRY_END
SCENARIO_END
+272
View File
@@ -0,0 +1,272 @@
; config options
; Test DNAME TTL=0 grace period: synthesis from cache within 1 second
; Island of trust at example.com, DNSSEC signed DNAME with TTL=0 (RFC 2308)
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
trust-anchor: "example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}"
val-override-date: "20070916134226"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
fake-sha1: yes
trust-anchor-signaling: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test DNAME TTL=0: signed DNAME with TTL=0 and RRSIG Original TTL=0.
; 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
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
net. IN A
SECTION AUTHORITY
net. 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 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 qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
net. IN NS
SECTION ANSWER
net. 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
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.5
ENTRY_END
RANGE_END
; ns.example.com. - DNAME with TTL=0 (RRSIG Original TTL=0)
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.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; DNAME with TTL=0, RRSIG Original TTL=0 (signed with ldns-signzone)
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
foo.test-dname.example.com. IN A
SECTION ANSWER
test-dname.example.com. 0 IN DNAME example.net.
test-dname.example.com. 0 IN RRSIG DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
foo.test-dname.example.com. 0 IN CNAME foo.example.net.
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.net. IN NS
SECTION ANSWER
example.net. IN NS ns.example.net.
example.net. 3600 IN RRSIG NS RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. E8JX0l4B+cSR5bkHQwOJy1pBmlLMTYCJ8EwfNMU/eCv0YhKwo26rHhn52FGisgv+Nwp7/NbhHqQ+kJgoZC94XA== ;{id = 30899}
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.5
ns.example.net. 3600 IN RRSIG A RSASHA1 3 3600 20070926134150 20070829134150 30899 example.net. x+tQMC9FhzT7Fcy1pM5NrOC7E8nLd7THPI3C6ie4EwL8PrxllqlR3q/DKB0d/m0qCOPcgN6HFOYURV1s4uAcsw== ;{id = 30899}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.net. IN DNSKEY
SECTION ANSWER
example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
example.net. 3600 IN RRSIG DNSKEY RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. hiFzlQ8VoYgCuvIsfVuxC3mfJDqsTh0yc6abs5xMx5uEcIjb0dndFQx7INOM+imlzveEN73Hqp4OLFpFhsWLlw== ;{id = 30899}
SECTION AUTHORITY
example.net. IN NS ns.example.net.
example.net. 3600 IN RRSIG NS RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. E8JX0l4B+cSR5bkHQwOJy1pBmlLMTYCJ8EwfNMU/eCv0YhKwo26rHhn52FGisgv+Nwp7/NbhHqQ+kJgoZC94XA== ;{id = 30899}
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.5
ns.example.net. 3600 IN RRSIG A RSASHA1 3 3600 20070926134150 20070829134150 30899 example.net. x+tQMC9FhzT7Fcy1pM5NrOC7E8nLd7THPI3C6ie4EwL8PrxllqlR3q/DKB0d/m0qCOPcgN6HFOYURV1s4uAcsw== ;{id = 30899}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
foo.example.net. IN A
SECTION ANSWER
foo.example.net. IN A 11.12.13.15
foo.example.net. 3600 IN RRSIG A 5 3 3600 20070926134150 20070829134150 30899 example.net. X6T6SE9UzxAD/4zKpwGOxEDyE4g7lfYYw3lvw533uwRN8mWTcBvSva0/jjyhrogJcuLO32jPHK6zGb93w2xnuA==
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
foo2.example.net. IN A
SECTION ANSWER
foo2.example.net. IN A 11.12.13.16
foo2.example.net. 3600 IN RRSIG A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
RANGE_END
STEP 1 TIME_PASSES ELAPSE 10
; First query: get DNAME TTL=0 into cache
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
foo.test-dname.example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
foo.test-dname.example.com. IN A
SECTION ANSWER
test-dname.example.com. 0 IN DNAME example.net.
test-dname.example.com. 0 IN RRSIG DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
foo.test-dname.example.com. 0 IN CNAME foo.example.net.
foo.example.net. IN A 11.12.13.15
foo.example.net. 3600 IN RRSIG A 5 3 3600 20070926134150 20070829134150 30899 example.net. X6T6SE9UzxAD/4zKpwGOxEDyE4g7lfYYw3lvw533uwRN8mWTcBvSva0/jjyhrogJcuLO32jPHK6zGb93w2xnuA==
ENTRY_END
STEP 29 TIME_PASSES ELAPSE 1
; Second query: within grace period (TIME_PASSES 1 above)
; With cache grace: synthesis from cached TTL=0 DNAME
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
foo2.test-dname.example.com. IN A
ENTRY_END
; foo2.test-dname.example.com is not answered upstream
; so this reply is synthesized by the cached (1 second grace period) DNAME
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
foo2.test-dname.example.com. IN A
SECTION ANSWER
test-dname.example.com. 0 IN DNAME example.net.
test-dname.example.com. 0 IN RRSIG DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
foo2.test-dname.example.com. 0 IN CNAME foo2.example.net.
foo2.example.net. 3600 IN A 11.12.13.16
foo2.example.net. 3600 IN RRSIG A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
ENTRY_END
SCENARIO_END
+192
View File
@@ -0,0 +1,192 @@
; config options
server:
do-nat64: yes
nat64-prefix: 2001:db8:1234::/96
target-fetch-policy: "0 0 0 0 0"
; This is like a machine that is part of a cluster of hosts that
; is IPv6-only, and uses NAT64. The cluster has no internet access.
do-not-query-address: ::0/0
qname-minimisation: no
stub-zone:
name: "."
; Pick an address in the NAT64 prefix, so it is allowed.
; other addresses would not be allowed. Or without the bugfix,
; allowed depending on state machine activation sequence.
stub-addr: 2001:db8:1234::1
CONFIG_END
SCENARIO_BEGIN Test NAT64 transport for v4-only with do-not-query-addresses.
RANGE_BEGIN 0 100
ADDRESS 2001:db8:1234::1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS FAKE.ROOT.
SECTION ADDITIONAL
FAKE.ROOT. IN AAAA 2001:db8:1234::1
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
v4only. IN NS
SECTION AUTHORITY
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
RANGE_END
; replies from NS over "NAT64"
RANGE_BEGIN 0 20
ADDRESS 2001:db8:1234::c000:0201
; A over NAT64
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN A
SECTION ANSWER
ns.v4only. IN A 192.0.2.1
SECTION AUTHORITY
v4only. IN NS ns.v4only.
ENTRY_END
; no AAAA
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN AAAA
SECTION AUTHORITY
v4only. IN SOA ns.v4only. host. 1 3600 300 48000 3600
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
v4only. IN NS
SECTION ANSWER
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
test.v4only. IN A
SECTION ANSWER
test.v4only. IN A 192.0.2.2
SECTION AUTHORITY
v4only. IN NS ns.v4only.
SECTION ADDITIONAL
ns.v4only. IN A 192.0.2.1
ENTRY_END
RANGE_END
RANGE_BEGIN 50 100
ADDRESS 2001:db8:1234::c000:0201
; no AAAA
; The last resort lookup of the AAAA is blocked here,
; the last resort processing is not desired, it should resolve test2
; straight away.
;ENTRY_BEGIN
;MATCH opcode qtype qname
;ADJUST copy_id
;REPLY AA QR NOERROR
;SECTION QUESTION
;ns.v4only. IN AAAA
;SECTION AUTHORITY
;v4only. IN SOA ns.v4only. host. 1 3600 300 48000 3600
;v4only. IN NS ns.v4only.
;SECTION ADDITIONAL
;ns.v4only. IN A 192.0.2.1
;ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.v4only. IN A
SECTION ANSWER
ns.v4only. IN A 192.0.2.1
SECTION AUTHORITY
v4only. IN NS ns.v4only.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
test2.v4only. IN A
SECTION ANSWER
test2.v4only. IN A 192.0.2.3
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
test.v4only. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
test.v4only. IN A
SECTION ANSWER
test.v4only. IN A 192.0.2.2
ENTRY_END
; for a query where the upstream nameserver has a timeout.
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
test2.v4only. IN A
ENTRY_END
; Only the test2 query is there, and it has a timeout.
; The address is already NAT64 translated, so now that it is
; attempted again, it is looked up in dotnotq as the ipv6 address.
STEP 40 TIMEOUT
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
test2.v4only. IN A
SECTION ANSWER
test2.v4only. IN A 192.0.2.3
ENTRY_END
SCENARIO_END
+283
View File
@@ -0,0 +1,283 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: yes
iter-scrub-promiscuous: yes
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
private-domain: "example.net"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test iterator scrubber with private addresses in SVCB.
; 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
; root server authoritative for example.net too.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
mail.example.net. IN SVCB
SECTION ANSWER
mail.example.net. IN SVCB 1 foo.example.net. ipv4hint=10.20.30.40
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. 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 NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION ANSWER
SECTION AUTHORITY
example.com. IN SOA ns.example.com. root.example.com. 4 14400 3600 604800 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN SVCB
SECTION ANSWER
www.example.com. IN SVCB 1 foo.example.com. ipv4hint=192.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
mail.example.com. IN SVCB
SECTION ANSWER
mail.example.com. IN SVCB 1 foo.example.com. ipv6hint=fe80::15
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 AA NOERROR
SECTION QUESTION
foo.example.com. IN SVCB
SECTION ANSWER
foo.example.com. IN SVCB 1 foo.example.com. ipv4hint=10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
toss.example.com. IN SVCB
SECTION ANSWER
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=10.20.30.40
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=10.20.30.40
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=1.2.3.4
toss.example.com. IN SVCB 1 foo.example.com. ipv6hint=fe80::15
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=10.20.30.41
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=192.0.2.1,10.20.30.42,192.0.2.2
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; public address is not scrubbed
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN SVCB
ENTRY_END
; recursion happens here.
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN SVCB
SECTION ANSWER
www.example.com. IN SVCB 1 foo.example.com. ipv4hint=192.20.30.40
ENTRY_END
; IPv4 address is scrubbed
STEP 3 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
foo.example.com. IN SVCB
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
foo.example.com. IN SVCB
SECTION ANSWER
; scrubbed away
ENTRY_END
; IPv6 address is scrubbed
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
mail.example.com. IN SVCB
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
mail.example.com. IN SVCB
SECTION ANSWER
ENTRY_END
; allowed domain is not scrubbed.
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
mail.example.net. IN SVCB
ENTRY_END
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
mail.example.net. IN SVCB
SECTION ANSWER
mail.example.net. IN SVCB 1 foo.example.net. ipv4hint=10.20.30.40
ENTRY_END
; rest of RRset intact, only 10/8 tossed away.
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
toss.example.com. IN SVCB
ENTRY_END
STEP 70 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
toss.example.com. IN SVCB
SECTION ANSWER
toss.example.com. IN SVCB 1 foo.example.com. ipv4hint=1.2.3.4
ENTRY_END
SCENARIO_END
+122
View File
@@ -0,0 +1,122 @@
; config options
server:
harden-referral-path: no
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
minimal-responses: no
iter-scrub-promiscuous: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test scrub of out-of-zone DNAME in answer section
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
x.y.example.com. IN A
ENTRY_END
; root prime is sent
STEP 20 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
. IN NS
ENTRY_END
STEP 30 REPLY
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA 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
; query sent to root server
STEP 40 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
x.y.example.com. IN A
ENTRY_END
STEP 50 REPLY
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
x.y.example.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
; query sent to .com server
STEP 60 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
x.y.example.com. IN A
ENTRY_END
STEP 70 REPLY
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
x.y.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns1.example.com.
SECTION ADDITIONAL
ns1.example.com. IN A 168.192.2.2
ENTRY_END
STEP 80 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
x.y.example.com. IN A
ENTRY_END
STEP 90 REPLY
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
x.y.example.com. IN A
SECTION ANSWER
com. DNAME z.example.com.
SECTION AUTHORITY
example.com. IN NS ns1.example.com.
SECTION ADDITIONAL
ns1.example.com. IN A 168.192.2.2
ENTRY_END
; answer to first query
; nodata answer since the DNAME is ignored for synthesis and scrubbed
; all together.
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA
SECTION QUESTION
x.y.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. IN NS ns1.example.com.
SECTION ADDITIONAL
ns1.example.com. IN A 168.192.2.2
ENTRY_END
SCENARIO_END
+29 -6
View File
@@ -204,6 +204,25 @@ RANGE_END
; ns.pollute4.mesa
RANGE_BEGIN 0 400
ADDRESS 1.2.4.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.pollute4.mesa. IN A
SECTION ANSWER
ns.pollute4.mesa. IN A 1.2.4.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.pollute4.mesa. IN AAAA
SECTION AUTHORITY
pollute4.mesa. IN SOA ns.pollute4.mesa. host.pollute4.mesa 20701 3600 3600 604800 3600
ENTRY_END
; This is the spoofed answer that is returned.
ENTRY_BEGIN
@@ -423,14 +442,18 @@ ENTRY_END
STEP 130 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA YXDOMAIN
REPLY QR RD RA SERVFAIL
SECTION QUESTION
test4.atkr.pollute4.mesa. IN A
SECTION ANSWER
test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4
SECTION AUTHORITY
; removed record
;pollute4.mesa. 0 IN NS ns.attacker.mesa.
; Since the reply does not contain a DNAME, it is rejected as YXDOMAIN answer.
;REPLY QR RD RA YXDOMAIN
;SECTION QUESTION
;test4.atkr.pollute4.mesa. IN A
;SECTION ANSWER
;test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4
;SECTION AUTHORITY
;; removed record
;;pollute4.mesa. 0 IN NS ns.attacker.mesa.
ENTRY_END
; Check the cache contents, for query 4.
+200
View File
@@ -0,0 +1,200 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
minimal-responses: no
iter-scrub-promiscuous: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test lookup of malformed SVCB
; 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 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 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN HTTPS
SECTION ANSWER
www.example.com. IN HTTPS \# 17 00 01 00 00 01 00 03 02 68 32 00 01 00 03 02 68 33
; Duplicate `alpn` key (17 bytes)
; Decoded:
; SvcPriority = 1 (service mode)
; TargetName = . (root label, 0x00)
; SvcParam[0]: key=1 (alpn), value_len=3, value=\x02h2 ← "h2"
; SvcParam[1]: key=1 (alpn), value_len=3, value=\x02h3 ← DUPLICATE KEY
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
testb.example.com. IN HTTPS
SECTION ANSWER
; The parser for testbound does allow this.
;testb.example.com. IN HTTPS \# 9 00 01 00 00 01 00 04 02 68
; Truncated `alpn` value (9 bytes)
; Decoded:
; SvcPriority = 1
; TargetName = .
; SvcParam[0]: key=1 (alpn), value_len=4 (claims 4 bytes), value=\x02h (only 2 bytes present)
; placeholder for hex: testb.example.com. IN HTTPS \# 9 00 01 00 00 01 00 02 01 68
HEX_ANSWER_BEGIN
000084000001000100000000057465737462076578616D706C6503636F6D0000410001057465737462076578616D706C6503636F6D000041000100000E10
0009
0001
00
000100040268
HEX_ANSWER_END
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
testc.example.com. IN HTTPS
SECTION ANSWER
testc.example.com. IN HTTPS \# 21 00 01 00 00 01 00 06 02 68 32 02 68 33 00 04 00 04 01 02 03 04
; valid HTTPS RDATA
; SvcPriority=1, TargetName=., alpn=h2+h3, ipv4hint=1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN HTTPS
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN HTTPS
SECTION ANSWER
www.example.com. 0 IN HTTPS 1 . alpn="h2" alpn="h3"
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
testb.example.com. IN HTTPS
ENTRY_END
; recursion happens here.
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH rcode
REPLY QR RD RA NOERROR
SECTION QUESTION
testb.example.com. IN HTTPS
SECTION ANSWER
; testb.example.com. 0 IN HTTPS \# 9 000100000100040268
HEX_ANSWER_BEGIN
000084000001000100000000057465737462076578616D706C6503636F6D0000410001057465737462076578616D706C6503636F6D000041000100000E10
0009
0001
00
000100040268
HEX_ANSWER_END
ENTRY_END
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
testc.example.com. IN HTTPS
ENTRY_END
; recursion happens here.
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
testc.example.com. IN HTTPS
SECTION ANSWER
testc.example.com. 0 IN HTTPS 1 . alpn="h2,h3" ipv4hint=1.2.3.4
ENTRY_END
SCENARIO_END
+73
View File
@@ -0,0 +1,73 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
minimal-responses: no
iter-scrub-promiscuous: no
stub-zone:
name: "."
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test long query name.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.root.
SECTION ADDITIONAL
ns.root. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
; matched anything
MATCH opcode
ADJUST copy_id copy_query
REPLY QR AA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
. SOA ns.root. host.invalid. 1 2 3 4 5
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
HEX_ANSWER_BEGIN
00 00 01 00 ; RD
00 01 00 00 00 00 00 00 ; QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=0.
; www.example.com.
;03 77 77 77
;07 65 78 61 6d 70 6c 65
;03 63 6f 6d
;00
;
; a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.example.com.
01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62
07 65 78 61 6d 70 6c 65
03 63 6f 6d
00
00 01 00 01
HEX_ANSWER_END
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD FORMERR
SECTION QUESTION
SECTION ANSWER
ENTRY_END
SCENARIO_END
+5 -4
View File
@@ -28,10 +28,11 @@ STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR FORMERR
SECTION QUESTION
nlnetlabs.nl. IN IXFR
SECTION AUTHORITY
nlnetlabs.nl. IN SOA mr. op. 12 0 0 0 0
; The SOA RR should not be echoed back.
; The question section is absent, because it gives a formerr because of the
; authority section contents.
;SECTION QUESTION
;nlnetlabs.nl. IN IXFR
ENTRY_END
SCENARIO_END
+239
View File
@@ -0,0 +1,239 @@
; Check if an SERVFAIL answer is not stored in the global cache, and
; does not block ECS queries to reach the ECS cache.
server:
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
;send-client-subnet: 1.2.3.4
client-subnet-zone: "example.com"
max-client-subnet-ipv4: 21
module-config: "subnetcache iterator"
verbosity: 3
access-control: 127.0.0.1 allow_snoop
qname-minimisation: no
minimal-responses: yes
prefetch: yes
outbound-msg-retry: 3
ede: yes
log-servfail: yes
stub-zone:
name: "example.com."
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test that SERVFAIL after timeout does not block clients to reach the ECS cache
; And that withing the servfail time a couple of seconds have cached servfail
; for the subnet queries for that name.
; ns.example.com.
RANGE_BEGIN 1 20
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
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id copy_ednsdata_assume_clientsubnet
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
SECTION AUTHORITY
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
00 08 ; OPC
00 05 ; option length
00 01 ; Family
08 00 ; source mask, scopemask
7f ; address
HEX_EDNSDATA_END
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 100 120
ADDRESS 1.2.3.4
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id copy_ednsdata_assume_clientsubnet
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.41
SECTION AUTHORITY
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 1.0.0.0
00 08 ; OPC
00 05 ; option length
00 01 ; Family
08 00 ; source mask, scopemask
01 ; address
HEX_EDNSDATA_END
ENTRY_END
RANGE_END
; Put an item in subnet cache
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 08 ; ip4, source 8, scope 8
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
SECTION AUTHORITY
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 08 ; ip4, source 8, scope 8
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
; There is a valid subnet query in cache.
; this query timeouts.
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
01 ; 1.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
; This query faces timeouts during the resolution.
; The timeouted query is the 1.0.0.0/8 subnet lookup of www.example.com. A.
STEP 31 TIMEOUT
STEP 32 TIMEOUT
STEP 33 TIMEOUT
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD DO RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; Check if subnet cache item can be accessed.
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
SECTION AUTHORITY
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 08 ; ip4, source 8, scope 8
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
; the existing subnet cache item can be accessed.
; but another resolution, is now not cached at all?
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
01 ; 1.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
STEP 80 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD DO RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; after a couple of seconds, the servfail entry should have cleared.
STEP 90 TIME_PASSES ELAPSE 10
STEP 100 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
01 ; 1.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
STEP 110 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.41
SECTION AUTHORITY
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 08 ; ip4, source 8, scope 8
01 ; 1.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END
+274
View File
@@ -0,0 +1,274 @@
; Test subnet option
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
send-client-subnet: 1.2.3.4
max-client-subnet-ipv4: 17
module-config: "subnetcache validator iterator"
verbosity: 3
fake-sha1: yes
fake-dsa: yes
qname-minimisation: no
minimal-responses: yes
iter-scrub-promiscuous: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test subnet with scopezero bogus response
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
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 qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
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 ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; no data for ns.example.com. AAAA
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN SOA a. b. 3 28800 7200 604800 3600
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. ACYHmWSLfBwPXwjI23+PW0db/DuqFwgpJYCbHOPeftbLR9nGy3nyEAE=
ns.example.com. 3600 IN NSEC op.example.com. A RRSIG NSEC
ns.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHMBw+lDAm9o2xG7v/8oWkYUc3WefUOuHFMHN9qZEp5/kooJqmlj974=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
; to make it bogus, the address is changed.
; and also the RRSIG is expired (dated in 2005).
;www.example.com. IN A 10.20.30.40
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
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
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
; response to query of interest without subnet
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
; to make it bogus, the address is changed.
; and also the RRSIG is expired (dated in 2005).
;www.example.com. IN A 10.20.30.40
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
;; we expect to receive empty
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
RANGE_END
; query for www.example.com 0.0.0.0/0 with CD flag
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD CD DO NOERROR
SECTION QUESTION
www.example.com. IN A
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ednsdata
REPLY QR RD CD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.41
www.example.com. 3600 IN RRSIG A 3 3 3600 20050926134150 20050829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
; query for www.example.com 0.0.0.0/0 without CD flag
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD DO NOERROR
SECTION QUESTION
www.example.com. IN A
HEX_EDNSDATA_BEGIN
; 0.0.0.0/0 scope /0
00 08 ; OPC
00 04 ; option length
00 01 ; Family
00 00 ; source mask, scopemask
; address
HEX_EDNSDATA_END
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ednsdata
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; ; 0.0.0.0/0 scope /0
; 00 08 ; OPC
; 00 04 ; option length
; 00 01 ; Family
; 00 00 ; source mask, scopemask
; ; address
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END
+20 -1
View File
@@ -15,10 +15,29 @@ ENTRY_END
; entry to test
ENTRY_BEGIN
SECTION QUESTION
secure.example.com. IN SOA
bogus.example.com. IN SOA
SECTION ANSWER
; The REVOKE key is not allowed to sign other data
example.com. 43200 IN SOA home.kuroiwa.eng.br. hostmaster.cesar.sec3.br. 2008040903 86400 86400 8640000 600
example.com. 43200 IN RRSIG SOA 5 2 43200 20081010000000 20080410122550 31027 example.com. af7nqRak6cEeQLytqLHMIUKPsOECA4Cu/Zpm7vdnKSh2q2+/8ZwIxwHLyCEGdiu/mTYffZEHTZytJyzxnB0oxA== ;{id = 31027}
ENTRY_END
; entry to test
ENTRY_BEGIN
SECTION QUESTION
bogus.a.example.com. IN DNSKEY
SECTION ANSWER
a.example.com. 3600 IN DNSKEY 384 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3
a.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20081010000000 20080410122550 31027 example.com. MdkvlzXlNEUrnk7jTXZ0whEjYLp1bGjOevL4yyzWAl+/LgaQqbFVApXbAQhHvouFQeoMp2+NvEGTLW8unBzJEw==
ENTRY_END
; entry to test
ENTRY_BEGIN
SECTION QUESTION
secure.example.com. IN DNSKEY
SECTION ANSWER
; the REVOKE key can sign itself
example.com. 3600 IN DNSKEY 384 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 31027 (zsk), size = 512b}
example.com. 3600 IN RRSIG DNSKEY 5 2 3600 20081010000000 20080410122550 31027 example.com. NEEY7W2F0XGUo9pVhiLALoz1ToM1gIS4TwUvVBPlIQMF+ZRGtB7PMthV0BN+aR+AEurxYsMfVmXEH2vKUVepgw==
ENTRY_END
+22
View File
@@ -0,0 +1,22 @@
server:
verbosity: 5
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: .
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
tls-cert-bundle: "unbound_server.pem"
tls-upstream: yes
forward-zone:
name: "."
forward-addr: "127.0.0.1@@TOPORT@#unbound"
forward-zone:
name: "example.org."
forward-addr: "127.0.0.1@@TOPORT@#badname"
+40
View File
@@ -0,0 +1,40 @@
# this is the upstream server that has pipelining and responds to queries.
server:
verbosity: 1
# num-threads: 1
interface: 127.0.0.1@@PORT@
port: @PORT@
use-syslog: no
directory: .
pidfile: "unbound2.pid"
chroot: ""
username: ""
do-not-query-localhost: no
tls-port: @PORT@
tls-service-key: "unbound_server.key"
tls-service-pem: "unbound_server.pem"
tcp-idle-timeout: 10000
log-queries: yes
log-replies: yes
log-identity: "upstream"
local-zone: "." refuse
local-zone: "example.com" static
local-data: "www.example.com A 10.20.30.40"
local-data: "www1.example.com A 10.20.30.41"
local-data: "www2.example.com A 10.20.30.42"
local-data: "www3.example.com A 10.20.30.43"
local-data: "www4.example.com A 10.20.30.44"
local-data: "www5.example.com A 10.20.30.45"
local-data: "www6.example.com A 10.20.30.46"
local-data: "www7.example.com A 10.20.30.47"
local-data: "www.example.org A 10.20.31.40"
local-data: "badname.example.org A 10.20.31.41"
# if queries escape, send them to localhost
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: "127.0.0.1@@TOPORT@"
+16
View File
@@ -0,0 +1,16 @@
BaseName: tls_reuse_auth
Version: 1.0
Description: Test tls stream reuse with tls auth name.
CreationDate: Thu Apr 02 11:11:00 CEST 2026
Maintainer: Wouter Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: tls_reuse_auth.pre
Post: tls_reuse_auth.post
Test: tls_reuse_auth.test
AuxFiles:
Passed:
Failure:
+19
View File
@@ -0,0 +1,19 @@
# #-- tls_reuse_auth.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_from_pidfile "unbound2.pid"
if test -f unbound2.log; then
echo ">>> upstream log"
cat unbound2.log
fi
#kill_pid $UNBOUND_PID
kill_from_pidfile "unbound.pid"
if test -f unbound.log; then
echo ">>> unbound log"
cat unbound.log
fi
+34
View File
@@ -0,0 +1,34 @@
# #-- tls_reuse_auth.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
UPSTREAM_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "UPSTREAM_PORT=$UPSTREAM_PORT" >> .tpkg.var.test
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$UPSTREAM_PORT'/' < tls_reuse_auth.conf > ub.conf
# start unbound in the background
#$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
$PRE/unbound -d -c ub.conf 2>&1 | tee unbound.log &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
wait_unbound_up unbound.log
# make upstream config file
sed -e 's/@PORT\@/'$UPSTREAM_PORT'/' -e 's/@TOPORT\@/'$UPSTREAM_PORT'/' < tls_reuse_auth.conf2 > ub2.conf
# start upstream unbound in the background
#$PRE/unbound -d -c ub2.conf >unbound2.log 2>&1 &
$PRE/unbound -d -c ub2.conf 2>&1 | tee unbound2.log &
UPSTREAM_PID=$!
echo "UPSTREAM_PID=$UPSTREAM_PID" >> .tpkg.var.test
wait_unbound_up unbound2.log
cat .tpkg.var.test
+90
View File
@@ -0,0 +1,90 @@
# #-- tls_reuse_auth.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
get_make
(cd $PRE; $MAKE streamtcp)
echo "> query www1.example.com."
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN >outfile 2>&1
cat outfile
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "Not OK"
exit 1
fi
if grep "www1.example.com" outfile | grep "10.20.30.41"; then
echo "content OK"
else
echo "result contents not OK, for www1.example.com"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "result contents not OK, for www1.example.com"
exit 1
fi
echo "OK"
echo ""
# this should be reused on the same tcp stream:
echo "> query www2.example.com."
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www2.example.com. A IN >outfile 2>&1
cat outfile
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "Not OK"
exit 1
fi
if grep "www2.example.com" outfile | grep "10.20.30.42"; then
echo "content OK"
else
echo "result contents not OK, for www2.example.com"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "result contents not OK, for www2.example.com"
exit 1
fi
# bad query with different auth name.
echo "> query badname.example.org."
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT badname.example.org. A IN >outfile 2>&1
cat outfile
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "Not OK"
exit 1
fi
if grep "badname.example.org" outfile | grep "10.20.31.41"; then
echo "result contents not OK, for badname.example.org"
echo "> cat logfiles"
cat outfile
cat unbound2.log
cat unbound.log
echo "result contents not OK, for badname.example.org"
exit 1
else
echo "content OK"
fi
echo "OK"
exit 0
+39
View File
@@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA
1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ
F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR
ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm
vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb
IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL
cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr
lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov
15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf
LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+
Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57
YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9
whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c
lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax
tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ
U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9
Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc
Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3
ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+
1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN
b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz
ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C
TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF
tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y
aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0
A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU
LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U
R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy
7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj
7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw
jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1
BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar
kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR
qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3
VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9
MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa
C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g=
-----END RSA PRIVATE KEY-----
+22
View File
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
+i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
-----END CERTIFICATE-----
+39
View File
@@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI
0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq
GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z
uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K
WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5
FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP
q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL
A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP
7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf
XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6
iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7
2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo
MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj
WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz
O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI
IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN
qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU
dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs
bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr
YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km
7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr
gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z
5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG
ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN
oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+
s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW
zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx
ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1
oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3
BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS
mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8
kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93
7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8
RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O
jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp
O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre
MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A==
-----END RSA PRIVATE KEY-----
+22
View File
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
-----END CERTIFICATE-----
+2 -2
View File
@@ -199,7 +199,7 @@ ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ede=10
MATCH all ede=6
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
@@ -215,7 +215,7 @@ ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ede=10
MATCH all ede=6
REPLY QR RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
+1 -1
View File
@@ -328,7 +328,7 @@ size_t alloc_get_mem(struct alloc_cache* alloc)
struct regional*
alloc_reg_obtain(struct alloc_cache* alloc)
{
if(alloc->num_reg_blocks > 0) {
if(alloc->num_reg_blocks > 0 && alloc->reg_list) {
struct regional* r = alloc->reg_list;
alloc->reg_list = (struct regional*)r->next;
r->next = NULL;
+86 -3
View File
@@ -62,6 +62,9 @@
#include "sldns/wire2str.h"
#include "sldns/parseutil.h"
#include "iterator/iterator.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_GLOB_H
# include <glob.h>
#endif
@@ -129,7 +132,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;
if(!(cfg->tls_protocols = strdup("TLSv1.2 TLSv1.3"))) goto error_exit;
cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit;
cfg->http_max_streams = 100;
@@ -423,6 +426,7 @@ config_create(void)
cfg->dns_error_reporting = 0;
cfg->iter_scrub_ns = 20;
cfg->iter_scrub_cname = 11;
cfg->iter_scrub_rrsig = 8;
cfg->iter_scrub_promiscuous = 1;
cfg->max_global_quota = 200;
return cfg;
@@ -631,7 +635,11 @@ 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 if(strcmp(opt, "tls-protocols:") == 0) {
if(!cfg_tls_protocols_is_valid(val)) return 0;
free(cfg->tls_protocols);
return (cfg->tls_protocols = strdup(val)) != NULL;
}
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)
@@ -770,6 +778,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("dns-error-reporting:", dns_error_reporting)
else S_NUMBER_OR_ZERO("iter-scrub-ns:", iter_scrub_ns)
else S_NUMBER_OR_ZERO("iter-scrub-cname:", iter_scrub_cname)
else S_NUMBER_OR_ZERO("iter-scrub-rrsig:", iter_scrub_rrsig)
else S_YNO("iter-scrub-promiscuous:", iter_scrub_promiscuous)
else S_NUMBER_OR_ZERO("max-global-quota:", max_global_quota)
else S_YNO("serve-original-ttl:", serve_original_ttl)
@@ -1185,7 +1194,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_STR(opt, "tls-protocols", tls_protocols)
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)
@@ -1249,6 +1258,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "dns-error-reporting", dns_error_reporting)
else O_DEC(opt, "iter-scrub-ns", iter_scrub_ns)
else O_DEC(opt, "iter-scrub-cname", iter_scrub_cname)
else O_DEC(opt, "iter-scrub-rrsig", iter_scrub_rrsig)
else O_YNO(opt, "iter-scrub-promiscuous", iter_scrub_promiscuous)
else O_DEC(opt, "max-global-quota", max_global_quota)
else O_YNO(opt, "serve-original-ttl", serve_original_ttl)
@@ -1756,6 +1766,7 @@ config_delete(struct config_file* cfg)
config_delstrlist(cfg->tls_session_ticket_keys.first);
free(cfg->tls_ciphers);
free(cfg->tls_ciphersuites);
free(cfg->tls_protocols);
free(cfg->http_endpoint);
if(cfg->log_identity) {
log_ident_revert_to_default();
@@ -2981,3 +2992,75 @@ cfg_has_quic(struct config_file* cfg)
return 0;
#endif
}
int
cfg_tls_protocols_is_valid(const char* tls_protocols)
{
const char* s = tls_protocols;
while(*s && isspace((unsigned char)*s)) s++;
while(*s && !isspace((unsigned char)*s)) {
if(strncmp(s, "TLSv1.2", 7) == 0 ||
strncmp(s, "TLSv1.3", 7) == 0) {
s += 7;
if(*s && !isspace((unsigned char)*s)) {
/* something is attached; fail */
return 0;
}
while(*s && isspace((unsigned char)*s))
s++;
continue;
}
return 0;
}
return 1;
}
void
cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13)
{
const char* s = tls_protocols;
*allow12 = 0;
*allow13 = 0;
if(tls_protocols == NULL) return;
while(*s && isspace((unsigned char)*s)) s++;
while(*s && !isspace((unsigned char)*s)) {
if(strncmp(s, "TLSv1.2", 7) == 0) {
*allow12 = 1;
s += 7;
} else if(strncmp(s, "TLSv1.3", 7) == 0) {
*allow13 = 1;
s += 7;
} else {
/* Unknown word, this should never happen but skip to
* be safe */
while(*s && !isspace((unsigned char)*s))
s++;
}
while(*s && isspace((unsigned char)*s))
s++;
}
}
int
file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist)
{
struct stat s;
if(stat(file, &s) != 0) {
*mtime = 0;
*ns = 0;
if(nonexist)
*nonexist = (errno == ENOENT);
return 0;
}
if(nonexist)
*nonexist = 0;
*mtime = s.st_mtime;
#ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
*ns = s.st_mtimensec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
*ns = s.st_mtim.tv_nsec;
#else
*ns = 0;
#endif
return 1;
}
+22 -2
View File
@@ -148,8 +148,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;
/** TLS protocols */
char* tls_protocols;
/** port on which to provide DNS over HTTPS service */
int https_port;
@@ -794,6 +794,8 @@ struct config_file {
size_t iter_scrub_ns;
/** limit on CNAME, DNAME RRs in answer for the iterator scrubber. */
int iter_scrub_cname;
/** limit on RRSIGs for an RRset for the iterator scrubber. */
int iter_scrub_rrsig;
/** limit on upstream queries for an incoming query and subqueries. */
int max_global_quota;
/** Should the iterator scrub promiscuous NS rrsets, from positive
@@ -1493,4 +1495,22 @@ size_t getmem_str(char* str);
*/
int cfg_ports_list_contains(char* ports, int p);
/**
* Check if the configured string contains supported TLS protocols.
* @param tls_protocols: String with TLS protocols.
* @return true if all options are valid, else false.
*/
int cfg_tls_protocols_is_valid(const char* tls_protocols);
/**
* Based on the configured TLS protocols fill which ones are allowed.
* @param tls_protocols: String with TLS protocols.
* @param allow12: will be true if TLSv1.2 is configured.
* @param allow13: will be true if TLSv1.3 is configured.
*/
void cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13);
/** get the file mtime stat (or error, with errno and nonexist) */
int file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist);
#endif /* UTIL_CONFIG_FILE_H */
+2 -2
View File
@@ -13,7 +13,6 @@
#pragma GCC diagnostic ignored "-Wsign-compare"
#endif
#include <ctype.h>
#include <strings.h>
#ifdef HAVE_GLOB_H
# include <glob.h>
@@ -262,7 +261,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) }
tls-protocols{COLON} { YDVAR(1, VAR_TLS_PROTOCOLS) }
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) }
@@ -607,6 +606,7 @@ dns-error-reporting{COLON} { YDVAR(1, VAR_DNS_ERROR_REPORTING ) }
proxy-protocol-port{COLON} { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) }
iter-scrub-ns{COLON} { YDVAR(1, VAR_ITER_SCRUB_NS) }
iter-scrub-cname{COLON} { YDVAR(1, VAR_ITER_SCRUB_CNAME) }
iter-scrub-rrsig{COLON} { YDVAR(1, VAR_ITER_SCRUB_RRSIG) }
max-global-quota{COLON} { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) }
iter-scrub-promiscuous{COLON} { YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
+20 -10
View File
@@ -199,7 +199,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_TLS_PROTOCOLS
%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
@@ -215,6 +215,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
%token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME
%token VAR_ITER_SCRUB_RRSIG
%token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO
%token VAR_ITER_SCRUB_PROMISCUOUS VAR_LOG_THREAD_ID
@@ -347,8 +348,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_stream_wait_size | server_tls_ciphers |
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_tls_use_sni | server_edns_client_string | server_tls_protocols |
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 |
@@ -359,6 +359,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_harden_unknown_additional | server_disable_edns_do |
server_log_destaddr | server_cookie_secret_file |
server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota |
server_iter_scrub_rrsig |
server_harden_unverified_glue | server_log_time_iso | server_iter_scrub_promiscuous
;
stub_clause: stubstart contents_stub
@@ -1157,13 +1158,13 @@ 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
server_tls_protocols: VAR_TLS_PROTOCOLS 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);
OUTYY(("P(server_tls_protocols:%s)\n", $2));
if(!cfg_tls_protocols_is_valid($2))
yyerror("tls-protocols: valid values are 'TLSv1.2' and 'TLSv1.3'.");
free(cfg_parser->cfg->tls_protocols);
cfg_parser->cfg->tls_protocols = $2;
}
;
server_https_port: VAR_HTTPS_PORT STRING_ARG
@@ -2399,7 +2400,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
"typetransparent, inform, inform_deny, "
"inform_redirect, always_transparent, block_a,"
"inform_redirect, always_transparent, block_a, "
"always_refuse, always_nxdomain, "
"always_nodata, always_deny, always_null, "
"noview, nodefault or ipset");
@@ -4255,6 +4256,15 @@ server_iter_scrub_cname: VAR_ITER_SCRUB_CNAME STRING_ARG
free($2);
}
;
server_iter_scrub_rrsig: VAR_ITER_SCRUB_RRSIG STRING_ARG
{
OUTYY(("P(server_iter_scrub_rrsig:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->iter_scrub_rrsig = atoi($2);
free($2);
}
;
server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG
{
OUTYY(("P(server_max_global_quota:%s)\n", $2));
+3 -1
View File
@@ -1366,7 +1366,9 @@ msgparse_rrset_remove_rr(const char* str, sldns_buffer* pkt, struct rrset_parse*
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);
/* It is also called during the grace period for type DNAME,
* and then the 'SERVE_EXPIRED' boolean may not be on. */
log_assert(ttl_add <= ttl);
return (SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ?
SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add));
}
+10 -10
View File
@@ -261,25 +261,25 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
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 && ttl < MIN_TTL) {
ttl = MIN_TTL;
if(MIN_NEG_TTL <= 0 && ttl < (uint32_t)MIN_TTL) {
ttl = (uint32_t)MIN_TTL;
}
if(ttl > MAX_TTL) ttl = MAX_TTL;
if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL;
}
/* MAX_NEG_TTL overrides the min and max ttl of everything
* else; it is for a more specific record */
if(ttl > MAX_NEG_TTL) ttl = MAX_NEG_TTL;
if(ttl > (uint32_t)MAX_NEG_TTL) ttl = (uint32_t)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 && ttl < MIN_NEG_TTL) {
ttl = MIN_NEG_TTL;
if(MIN_NEG_TTL > 0 && ttl < (uint32_t)MIN_NEG_TTL) {
ttl = (uint32_t)MIN_NEG_TTL;
}
} else if(!SERVE_ORIGINAL_TTL) {
if(ttl < MIN_TTL) ttl = MIN_TTL;
if(ttl > MAX_TTL) ttl = MAX_TTL;
if(ttl < (uint32_t)MIN_TTL) ttl = (uint32_t)MIN_TTL;
if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL;
}
if(ttl < data->ttl)
data->ttl = ttl;
if((time_t)ttl < data->ttl)
data->ttl = (time_t)ttl;
/* We have concluded the TTL checks */
*rr_ttl = (time_t)ttl;
+5
View File
@@ -3978,6 +3978,7 @@
4791,
4792,
4793,
4794,
4800,
4801,
4802,
@@ -4170,6 +4171,7 @@
5313,
5314,
5315,
5319,
5343,
5344,
5349,
@@ -4947,6 +4949,7 @@
9162,
9163,
9164,
9183,
9191,
9200,
9201,
@@ -5431,6 +5434,8 @@
34962,
34963,
34964,
34965,
34966,
34980,
35001,
35004,
+27
View File
@@ -178,6 +178,30 @@ typedef pthread_key_t ub_thread_key_type;
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
#define ub_thread_key_get(key) pthread_getspecific(key)
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
#if defined(HAVE_PTHREAD_SET_NAME_NP)
#define ub_thread_setname(thread, name) do { \
(void)pthread_set_name_np(thread, name);\
} while(0)
#elif defined(HAVE_PTHREAD_SETNAME_NP1)
#define ub_thread_setname(thread, name) do { \
(void)pthread_setname_np(name); \
} while(0)
#elif defined(HAVE_PTHREAD_SETNAME_NP3)
#define ub_thread_setname(thread, name) do { \
(void)pthread_setname_np(thread, name, NULL); \
} while(0)
#elif defined(HAVE_PTHREAD_SETNAME_NP)
#define ub_thread_setname(thread, name) do { \
(void)pthread_setname_np(thread, name); \
} while(0)
#else
#define ub_thread_setname(thread, name) /* nop */
#endif /* HAVE_PTHREAD_SET_NAME_NP */
#else /* we do not HAVE_PTHREAD */
#ifdef HAVE_SOLARIS_THREADS
@@ -215,6 +239,7 @@ typedef thread_key_t ub_thread_key_type;
#define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f))
#define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v))
void* ub_thread_key_get(ub_thread_key_type key);
#define ub_thread_setname(thread, name) /* nop */
#else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
@@ -253,6 +278,7 @@ typedef DWORD ub_thread_key_type;
void ub_thread_key_create(ub_thread_key_type* key, void* f);
void ub_thread_key_set(ub_thread_key_type key, void* v);
void* ub_thread_key_get(ub_thread_key_type key);
#define ub_thread_setname(thread, name) /* nop */
#else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */
@@ -294,6 +320,7 @@ typedef void* ub_thread_key_type;
#define ub_thread_key_create(key, f) (*(key)) = NULL
#define ub_thread_key_set(key, v) (key) = (v)
#define ub_thread_key_get(key) (key)
#define ub_thread_setname(thread, name) /* nop */
#endif /* HAVE_WINDOWS_THREADS */
#endif /* HAVE_SOLARIS_THREADS */
+4
View File
@@ -698,6 +698,10 @@ struct module_qstate {
time_t qstarttime;
/** whether a message from cachedb will be used for the reply */
int is_cachedb_answer;
/** if the response as error is from error_response_cache, and is
* suitable for caching (briefly) the error response. Set by the
* iterator when no_cache_store is enabled, and there is an error. */
int error_response_cache;
/**
* Attributes of clients that share the qstate that may affect IP-based
+49 -31
View File
@@ -1226,10 +1226,13 @@ setup_ticket_keys_cb(void* sslctx)
#endif /* HAVE_SSL */
int
listen_sslctx_setup(void* ctxt, int use_system_versions)
listen_sslctx_setup(void* ctxt, const char* tls_protocols)
{
#ifdef HAVE_SSL
int allow12, allow13;
SSL_CTX* ctx = (SSL_CTX*)ctxt;
cfg_tls_protocols_allowed(tls_protocols, &allow12, &allow13);
/* no SSLv2, SSLv3 because has defects */
#if SSL_OP_NO_SSLv2 != 0
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
@@ -1238,37 +1241,47 @@ listen_sslctx_setup(void* ctxt, int use_system_versions)
return 0;
}
#endif
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((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 defined(SSL_OP_NO_TLSv1_2)
if(!allow12) {
/* we are not allowed to use TLS1.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
}
#endif
#if defined(SSL_OP_NO_TLSv1_3)
if(!allow13) {
/* we are not allowed to use TLS1.3 */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3) & SSL_OP_NO_TLSv1_3)
!= SSL_OP_NO_TLSv1_3){
log_crypto_err("could not set SSL_OP_NO_TLSv1_3");
return 0;
}
}
#endif
#if defined(SSL_OP_NO_RENEGOTIATION)
/* disable client renegotiation */
if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) &
@@ -1307,7 +1320,7 @@ listen_sslctx_setup(void* ctxt, int use_system_versions)
SSL_CTX_set_security_level(ctx, 0);
#endif
#else
(void)ctxt;
(void)ctxt; (void)tls_protocols;
#endif /* HAVE_SSL */
return 1;
}
@@ -1343,7 +1356,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 use_system_versions)
int is_dot, int is_doh, const char* tls_protocols)
{
#ifdef HAVE_SSL
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
@@ -1361,7 +1374,7 @@ void* listen_sslctx_create(const char* key, const char* pem,
SSL_CTX_free(ctx);
return NULL;
}
if(!listen_sslctx_setup(ctx, use_system_versions)) {
if(!listen_sslctx_setup(ctx, tls_protocols)) {
SSL_CTX_free(ctx);
return NULL;
}
@@ -1438,6 +1451,7 @@ void* listen_sslctx_create(const char* key, const char* pem,
(void)key; (void)pem; (void)verifypem;
(void)tls_ciphers; (void)tls_ciphersuites;
(void)set_ticket_keys_cb; (void)is_dot; (void)is_doh;
(void)tls_protocols;
return NULL;
#endif /* HAVE_SSL */
}
@@ -1799,7 +1813,7 @@ void ub_openssl_lock_delete(void)
#endif /* OPENSSL_THREADS */
}
int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys) {
int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys, char* chroot) {
#ifdef HAVE_SSL
size_t s = 1;
struct config_strlist* p;
@@ -1817,14 +1831,18 @@ int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_ke
size_t n;
unsigned char *data;
FILE *f;
char* fstr;
data = (unsigned char *)malloc(80);
if(!data)
return 0;
f = fopen(p->str, "rb");
fstr = p->str;
if(chroot && strncmp(fstr, chroot, strlen(chroot)) == 0)
fstr += strlen(chroot);
f = fopen(fstr, "rb");
if(!f) {
log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno));
log_err("could not read tls-session-ticket-key %s: %s", fstr, strerror(errno));
free(data);
return 0;
}
@@ -1832,11 +1850,11 @@ int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_ke
fclose(f);
if(n != 80) {
log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n);
log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", fstr, (int)n);
free(data);
return 0;
}
verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str);
verbose(VERB_OPS, "read tls-session-ticket-key: %s", fstr);
keys->key_name = data;
keys->aes_key = data + 16;
@@ -1847,7 +1865,7 @@ int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_ke
keys->key_name = NULL;
return 1;
#else
(void)tls_session_ticket_keys;
(void)tls_session_ticket_keys; (void)chroot;
return 0;
#endif
}
+7 -7
View File
@@ -478,11 +478,10 @@ 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
* @param tls_protocols: configure string with allowed TLS protocols to use.
* @return false on failure.
*/
int listen_sslctx_setup(void* ctxt, int use_system_versions);
int listen_sslctx_setup(void* ctxt, const char* tls_protocols);
/**
* Further setup of listening SSL context, after keys loaded.
@@ -501,14 +500,13 @@ 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
* @param tls_protocols: configure string with allowed TLS protocols to use.
* 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 use_system_versions);
int is_dot, int is_doh, const char* tls_protocols);
/**
* create SSL connect context
@@ -567,9 +565,11 @@ void ub_openssl_lock_delete(void);
/**
* setup TLS session ticket
* @param tls_session_ticket_keys: TLS ticket secret filenames
* @param chroot: if not NULL, the chroot that is in use.
* @return false on failure (alloc failure).
*/
int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys);
int listen_sslctx_setup_ticket_keys(
struct config_strlist* tls_session_ticket_keys, char* chroot);
/** Free memory used for TLS session ticket keys */
void listen_sslctx_delete_ticket_keys(void);
+19 -4
View File
@@ -4870,8 +4870,17 @@ http_process_initial_header(struct comm_point* c)
return 0;
}
} else if(strncasecmp(line, "Content-Length: ", 16) == 0) {
if(!c->http_is_chunked)
c->tcp_byte_count = (size_t)atoi(line+16);
if(!c->http_is_chunked) {
char* end = NULL;
long long cl;
errno = 0;
cl = strtoll(line+16, &end, 10);
if(end == line+16 || errno != 0 || cl < 0) {
verbose(VERB_ALGO, "http invalid Content-Length: " ARG_LL "d", cl);
return 0; /* reject */
}
c->tcp_byte_count = (size_t)cl;
}
} else if(strncasecmp(line, "Transfer-Encoding: chunked", 19+7) == 0) {
c->tcp_byte_count = 0;
c->http_is_chunked = 1;
@@ -4927,9 +4936,15 @@ http_process_chunk_header(struct comm_point* c)
if(c->http_in_chunk_headers == 1) {
/* read chunked start line */
char* end = NULL;
c->tcp_byte_count = (size_t)strtol(line, &end, 16);
if(end == line)
long chunk_sz;
errno = 0;
chunk_sz = strtol(line, &end, 16);
if(end == line || errno != 0 || chunk_sz < 0) {
verbose(VERB_ALGO, "http invalid chunk size: %ld",
chunk_sz);
return 0;
}
c->tcp_byte_count = (size_t)chunk_sz;
c->http_in_chunk_headers = 0;
/* remove header text from front of buffer */
http_moveover_buffer(c->buffer);
+155 -62
View File
@@ -185,6 +185,16 @@ int shm_main_init(struct daemon* daemon)
shm_stat = daemon->shm_info->ptr_ctl;
shm_stat->num_threads = daemon->num;
lock_basic_init(&daemon->shm_info->lock);
daemon->shm_info->volley_in_progress = 0;
daemon->shm_info->thread_volley = (int*)calloc(
daemon->num, sizeof(int));
if(!daemon->shm_info->thread_volley) {
log_err("shm fail: malloc failure");
free(daemon->shm_info);
daemon->shm_info = NULL;
return 0;
}
#else
(void)daemon;
#endif /* HAVE_SHMGET */
@@ -214,6 +224,9 @@ void shm_main_shutdown(struct daemon* daemon)
if (daemon->shm_info->ptr_arr)
shmdt(daemon->shm_info->ptr_arr);
lock_basic_destroy(&daemon->shm_info->lock);
free(daemon->shm_info->thread_volley);
free(daemon->shm_info);
daemon->shm_info = NULL;
#else
@@ -221,13 +234,123 @@ void shm_main_shutdown(struct daemon* daemon)
#endif /* HAVE_SHMGET */
}
#ifdef HAVE_SHMGET
/** Copy general info into the stat structure. */
static void
shm_general_info(struct worker* worker)
{
struct ub_shm_stat_info *shm_stat;
/* Point to data into SHM */
#ifndef S_SPLINT_S
shm_stat = worker->daemon->shm_info->ptr_ctl;
shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec;
shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec;
#endif
stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot);
stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat);
shm_stat->mem.msg = (long long)slabhash_get_mem(worker->env.msg_cache);
shm_stat->mem.rrset = (long long)slabhash_get_mem(&worker->env.rrset_cache->table);
shm_stat->mem.dnscrypt_shared_secret = 0;
#ifdef USE_DNSCRYPT
if(worker->daemon->dnscenv) {
shm_stat->mem.dnscrypt_shared_secret = (long long)slabhash_get_mem(
worker->daemon->dnscenv->shared_secrets_cache);
shm_stat->mem.dnscrypt_nonce = (long long)slabhash_get_mem(
worker->daemon->dnscenv->nonces_cache);
}
#endif
shm_stat->mem.val = (long long)mod_get_mem(&worker->env, "validator");
shm_stat->mem.iter = (long long)mod_get_mem(&worker->env, "iterator");
shm_stat->mem.respip = (long long)mod_get_mem(&worker->env, "respip");
/* subnet mem value is available in shm, also when not enabled,
* to make the struct easier to memmap by other applications,
* independent of the configuration of unbound */
shm_stat->mem.subnet = 0;
#ifdef CLIENT_SUBNET
shm_stat->mem.subnet = (long long)mod_get_mem(&worker->env,
"subnetcache");
#endif
/* ipsecmod mem value is available in shm, also when not enabled,
* to make the struct easier to memmap by other applications,
* independent of the configuration of unbound */
shm_stat->mem.ipsecmod = 0;
#ifdef USE_IPSECMOD
shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env,
"ipsecmod");
#endif
#ifdef WITH_DYNLIBMODULE
shm_stat->mem.dynlib = (long long)mod_get_mem(&worker->env, "dynlib");
#endif
}
#endif /* HAVE_SHMGET */
#ifdef HAVE_SHMGET
/** See if the thread is first. Caller has lock. */
static int
shm_thread_is_first(struct shm_main_info* shm_info, int thread_num,
struct daemon* daemon)
{
/* The usual method, all threads executed last time, and there
* is no statistics callback in progress. */
if(!shm_info->volley_in_progress)
return 1;
/* See if we are already active, if so, the timer seems to have fired
* twice for this thread which means other thread(s) have not gone
* through their stats callbacks yet.
* (There should have been a last thread to reset
* shm_info->volley_in_progress and shm_info->thread_volley)
* The other thread(s) are not yet active during this statistics round,
* so this thread must be the first of this new round disregarding the
* other busy thread(s).
* When the other thread(s) have time again, they will process their
* stats callback and hopefully properly end a stats round where all
* threads got to calculate their statistics. */
if(shm_info->thread_volley[thread_num] != 0) {
/* The new round starts and zeroes the total. The previous
* partial total is discarded. That means while other thread(s)
* are performing a long task, eg. loading a large zone
* perhaps, the total is not updated and stays the same in the
* shared memory area. Once that other thread(s) perform the
* statistic callback again, the total is updated again.
*
* The threads busy with long tasks have 0 in the array.
* The array is inited for a new round. */
memset(shm_info->thread_volley, 0,
((size_t)daemon->num) * sizeof(int));
return 1;
}
return 0;
}
#endif /* HAVE_SHMGET */
#ifdef HAVE_SHMGET
/** See if the thread is last. Caller has lock. */
static int
shm_thread_is_last(struct daemon* daemon)
{
/* Being last means that all threads have been active for this stats
* round and this thread is the last one; also active. All the
* thread_volley values should be true then. */
int i;
for(i=0; i<daemon->num; i++) {
if(!daemon->shm_info->thread_volley[i])
return 0;
}
return 1;
}
#endif /* HAVE_SHMGET */
void shm_main_run(struct worker *worker)
{
#ifdef HAVE_SHMGET
struct ub_shm_stat_info *shm_stat;
struct ub_stats_info *stat_total;
struct ub_stats_info *stat_info;
int offset;
double total_mesh_time_median;
struct shm_main_info* shm_info = worker->daemon->shm_info;
#ifndef S_SPLINT_S
verbose(VERB_DETAIL, "SHM run - worker [%d] - daemon [%p] - timenow(%u) - timeboot(%u)",
@@ -235,73 +358,43 @@ void shm_main_run(struct worker *worker)
#endif
offset = worker->thread_num + 1;
stat_total = worker->daemon->shm_info->ptr_arr;
stat_info = worker->daemon->shm_info->ptr_arr + offset;
stat_total = shm_info->ptr_arr;
stat_info = shm_info->ptr_arr + offset;
/* Copy data to the current position */
server_stats_compile(worker, stat_info, 0);
/* First thread, zero fill total, and copy general info */
if (worker->thread_num == 0) {
/* Copy data to the current position */
memset(stat_total, 0, sizeof(struct ub_stats_info));
/* Point to data into SHM */
#ifndef S_SPLINT_S
shm_stat = worker->daemon->shm_info->ptr_ctl;
shm_stat->time.now_sec = (long long)worker->env.now_tv->tv_sec;
shm_stat->time.now_usec = (long long)worker->env.now_tv->tv_usec;
#endif
stat_timeval_subtract(&shm_stat->time.up_sec, &shm_stat->time.up_usec, worker->env.now_tv, &worker->daemon->time_boot);
stat_timeval_subtract(&shm_stat->time.elapsed_sec, &shm_stat->time.elapsed_usec, worker->env.now_tv, &worker->daemon->time_last_stat);
shm_stat->mem.msg = (long long)slabhash_get_mem(worker->env.msg_cache);
shm_stat->mem.rrset = (long long)slabhash_get_mem(&worker->env.rrset_cache->table);
shm_stat->mem.dnscrypt_shared_secret = 0;
#ifdef USE_DNSCRYPT
if(worker->daemon->dnscenv) {
shm_stat->mem.dnscrypt_shared_secret = (long long)slabhash_get_mem(
worker->daemon->dnscenv->shared_secrets_cache);
shm_stat->mem.dnscrypt_nonce = (long long)slabhash_get_mem(
worker->daemon->dnscenv->nonces_cache);
}
#endif
shm_stat->mem.val = (long long)mod_get_mem(&worker->env,
"validator");
shm_stat->mem.iter = (long long)mod_get_mem(&worker->env,
"iterator");
shm_stat->mem.respip = (long long)mod_get_mem(&worker->env,
"respip");
/* subnet mem value is available in shm, also when not enabled,
* to make the struct easier to memmap by other applications,
* independent of the configuration of unbound */
shm_stat->mem.subnet = 0;
#ifdef CLIENT_SUBNET
shm_stat->mem.subnet = (long long)mod_get_mem(&worker->env,
"subnetcache");
#endif
/* ipsecmod mem value is available in shm, also when not enabled,
* to make the struct easier to memmap by other applications,
* independent of the configuration of unbound */
shm_stat->mem.ipsecmod = 0;
#ifdef USE_IPSECMOD
shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env,
"ipsecmod");
#endif
#ifdef WITH_DYNLIBMODULE
shm_stat->mem.dynlib = (long long)mod_get_mem(&worker->env,
"dynlib");
#endif
/* Lock the lock and see if this thread is first or last of the
* stat threads. It can then zero value or sum up values. */
lock_basic_lock(&shm_info->lock);
if(shm_thread_is_first(shm_info, worker->thread_num, worker->daemon)) {
/* First thread, zero fill total. */
memset(&shm_info->total_in_progress, 0,
sizeof(struct ub_stats_info));
shm_info->volley_in_progress = 1;
}
shm_info->thread_volley[worker->thread_num] = 1;
if(worker->thread_num == 0) {
/* Thread 0, copy general info. */
shm_general_info(worker);
}
/* Add thread data to the total */
total_mesh_time_median = shm_info->total_in_progress.mesh_time_median;
server_stats_add(&shm_info->total_in_progress, stat_info);
/* By adding the value/num per stat thread, for the median,
* it is going to add up to the sum/num. */
shm_info->total_in_progress.mesh_time_median = total_mesh_time_median +
(stat_info->mesh_time_median/(double)worker->daemon->num);
server_stats_add(stat_total, stat_info);
/* print the thread statistics */
stat_total->mesh_time_median /= (double)worker->daemon->num;
if(shm_thread_is_last(worker->daemon)) {
/* Copy over the total */
memcpy(stat_total, &shm_info->total_in_progress,
sizeof(struct ub_stats_info));
shm_info->volley_in_progress = 0;
memset(shm_info->thread_volley, 0,
((size_t)worker->daemon->num) * sizeof(int));
}
lock_basic_unlock(&shm_info->lock);
#else
(void)worker;
#endif /* HAVE_SHMGET */
+15
View File
@@ -47,6 +47,8 @@ struct worker;
/* get struct ub_shm_stat_info */
#include "libunbound/unbound.h"
#include "util/locks.h"
/**
* The SHM info.
*/
@@ -59,6 +61,19 @@ struct shm_main_info {
int key;
int id_ctl;
int id_arr;
/** This mutex is on the volley information. */
lock_basic_type lock;
/** If there is a volley, a number of stat timer callbacks by the
* threads, in progress. If not, there is no volley in progress and the
* previous stat run has terminated succesfully for all threads.
* Usually activated by the first thread and deactivated by the last
* thread that starts its stat callback. */
int volley_in_progress;
/** Per thread, if they have put in stats. 0 if not. */
int* thread_volley;
/** The total stats of the thread stat timers, it is in progress */
struct ub_stats_info total_in_progress;
};
int shm_main_init(struct daemon* daemon);
+8
View File
@@ -1289,6 +1289,8 @@ neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len,
if(!(msg = dns_msg_create(qname, qname_len,
LDNS_RR_TYPE_DS, zone->dclass, region, 1)))
return NULL;
/* The cache response means recursion is available. */
msg->rep->flags |= BIT_RA;
/* TTL reduced in grab_nsec */
if(!dns_msg_authadd(msg, region, ce_rrset, 0))
return NULL;
@@ -1323,6 +1325,8 @@ neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len,
if(!(msg = dns_msg_create(qname, qname_len,
LDNS_RR_TYPE_DS, zone->dclass, region, 3)))
return NULL;
/* The cache response means recursion is available. */
msg->rep->flags |= BIT_RA;
/* now=0 because TTL was reduced in grab_nsec */
if(!dns_msg_authadd(msg, region, ce_rrset, 0))
return NULL;
@@ -1413,6 +1417,8 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
qinfo->qtype, qinfo->qclass, region, 2)))
return NULL;
/* The cache response means recursion is available. */
msg->rep->flags |= BIT_RA;
if(!dns_msg_authadd(msg, region, nsec, 0))
return NULL;
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
@@ -1426,6 +1432,8 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
qinfo->qtype, qinfo->qclass, region, 3)))
return NULL;
/* The cache response means recursion is available. */
msg->rep->flags |= BIT_RA;
if(!(ce = nsec_closest_encloser(qinfo->qname, nsec)))
return NULL;
dname_count_size_labels(ce, &ce_len);
+12
View File
@@ -1570,6 +1570,18 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
*reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET;
return sec_status_bogus;
}
if((dnskey_get_flags(dnskey, dnskey_idx) & LDNS_KEY_REVOKE_KEY) &&
/* The REVOKE key is allowed to check sigs on itself. */
!(ntohs(rrset->rk.type) == LDNS_RR_TYPE_DNSKEY &&
query_dname_compare(rrset->rk.dname, dnskey->rk.dname)==0)
) {
verbose(VERB_QUERY, "verify: dnskey has REVOKE bit set, "
"not usable for data validation per RFC 5011 s2.1");
*reason = "dnskey revoked";
if(reason_bogus)
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
return sec_status_bogus;
}
if(dnskey_get_protocol(dnskey, dnskey_idx) != LDNS_DNSSEC_KEYPROTO) {
/* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */
+23
View File
@@ -1334,3 +1334,26 @@ val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c,
env->scratch_buffer, *env->now, 0, topname, env->cfg);
return msg;
}
int derive_cname_from_dname(struct ub_packed_rrset_key* cname,
struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen)
{
size_t prefix_len;
uint8_t* dname_target = NULL;
size_t dname_target_len = 0;
if(!dname_strict_subdomain_c(cname->rk.dname, dname->rk.dname))
return 0; /* Invalid: CNAME owner must be subdomain */
get_cname_target(dname, &dname_target, &dname_target_len);
if(!dname_target || !dname_target_len)
return 0; /* DNAME malformed */
if(cname->rk.dname_len < dname->rk.dname_len)
return 0; /* Not possible, due to subdomain, but check */
if(cname->rk.dname_len == 0)
return 0; /* Not possible, but check */
prefix_len = cname->rk.dname_len - dname->rk.dname_len;
if(prefix_len + dname_target_len > outlen)
return 0; /* Buffer too small */
memmove(out, cname->rk.dname, prefix_len);
memmove(out+prefix_len, dname_target, dname_target_len);
return 1;
}
+11
View File
@@ -427,4 +427,15 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset);
struct dns_msg* val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen,
uint16_t c, struct regional* region, uint8_t* topname);
/**
* Derive expected CNAME target from DNAME substitution per RFC 6672 s3.1
* @param cname: CNAME RRset, (e.g., b.d.a005.test CNAME 'some cname target')
* @param dname: DNAME RRset, (e.g., d.a005.test DNAME tgt.a005.test)
* @param out: Output buffer for expected CNAME target
* @param outlen: Output buffer size
* @return: 1 on success, 0 on error
*/
int derive_cname_from_dname(struct ub_packed_rrset_key* cname,
struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen);
#endif /* VALIDATOR_VAL_UTILS_H */
+90 -1
View File
@@ -710,6 +710,37 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
((struct packed_rrset_data*)chase_reply->rrsets[i-1]->entry.data)->security == sec_status_secure &&
dname_strict_subdomain_c(s->rk.dname, chase_reply->rrsets[i-1]->rk.dname)
) {
/* Check that the CNAME target matches the DNAME
* derivation. Zone changes during the redirection
* lookups or looped DNAMEs can have such a CNAME. */
uint8_t expected_target[LDNS_MAX_DOMAINLEN];
uint8_t* cname_target = NULL;
size_t cname_target_len = 0;
get_cname_target(s, &cname_target, &cname_target_len);
if(!cname_target ||
!derive_cname_from_dname(s, /* CNAME RRset */
chase_reply->rrsets[i-1], /* DNAME RRset */
expected_target, /* Output buffer */
sizeof(expected_target))) {
verbose(VERB_ALGO, "DNAME CNAME derivation failed");
errinf_ede(qstate, "DNAME CNAME derivation failed", reason_bogus);
errinf_origin(qstate, qstate->reply_origin);
chase_reply->security = sec_status_bogus;
update_reason_bogus(chase_reply, reason_bogus);
return 0;
}
if(query_dname_compare(cname_target, expected_target) != 0) {
verbose(VERB_ALGO, "CNAME target mismatch: not synthesized from DNAME");
errinf_ede(qstate, "CNAME target mismatch: not synthesized from DNAME", reason_bogus);
errinf_dname(qstate, ", for", s->rk.dname);
errinf_dname(qstate, "CNAME", cname_target);
errinf(qstate, ",");
errinf_origin(qstate, qstate->reply_origin);
chase_reply->security = sec_status_bogus;
update_reason_bogus(chase_reply, reason_bogus);
return 0;
}
/* CNAME was synthesized by our own iterator */
/* since the DNAME verified, mark the CNAME as secure */
((struct packed_rrset_data*)s->entry.data)->security =
@@ -2699,7 +2730,9 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
if(!needs_validation(qstate, qstate->return_rcode,
qstate->return_msg)) {
/* no need to validate this */
if(qstate->return_msg)
/* For valrec responses, leave at sec_status_unchecked,
* no security status has been requested for it. */
if(qstate->return_msg && !qstate->is_valrec)
qstate->return_msg->rep->security =
sec_status_indeterminate;
qstate->ext_state[id] = module_finished;
@@ -3090,6 +3123,62 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
sizeof(reasonbuf));
if(sec == sec_status_secure) {
/* Check for wildcard expansion */
uint8_t* wc = NULL;
size_t wl = 0;
if(!val_rrset_wildcard(cname, &wc, &wl)) {
verbose(VERB_ALGO, "CNAME has inconsistent wildcard signatures");
reason = "wildcard CNAME inconsistent signatures";
errinf_ede(qstate, reason, reason_bogus);
goto return_bogus;
}
if(wc != NULL) {
/* Wildcard expansion detected - require NSEC proof */
/* So this is a wildcard CNAME response to DS.
* If the wildcard is bogus then we have bogus.
* If the wildcard is true, then there is
* not a referral point here or lower,
* that can be insecure,
* and also no DS records, here or lower. */
/* For a valid chain, to DS, but this
* wildcard CNAME happens in a middle label,
* then that can not happen, because there is
* data under that label, and thus the wildcard
* should not expand.
* If we are going to the wildcard, that also
* does not expand the wildcard, when above it.
* So for valids lookup chains to DS, no
* wildcard CNAME is expected on middle labels.
* For lookups to an insecure point, the
* delegation is information under the label,
* and thus the wildcard does not expand.
* So, no insecure point is possible.
* Can not get a valid chain of trust, or
* to a delegation point for insecure.
* Or the wildcard, its nxdomain for the qname
* proof, is invalid, in which case this is
* a bogus reply.
* If this was a lookup where a wildcard
* expansion is genuinely expected, eg,
* a dnssec valid wildcard query, then the
* lookup should go to the right point, and
* not into the wildcard under the zone name.
* For insecure, or wildcard missing
* signatures, it would have to have found
* the DS or insecure point earlier, in the
* downwards search.
* So for missing signatures, it turns the
* missing signatures into a failure to the
* wildcard CNAME, as the reported log.
*/
verbose(VERB_ALGO, "wildcard CNAME in chain of trust means no DS can be found and it is also not a delegation point that can be insecure");
reason = "wildcard CNAME in chain of trust means no DS found and it is also not a delegation point that can be insecure";
errinf_ede(qstate, reason, reason_bogus);
goto return_bogus;
}
verbose(VERB_ALGO, "CNAME validated, "
"proof that DS does not exist");
/* and that it is not a referral point */

Some files were not shown because too many files have changed in this diff Show More