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
W.C.A. Wijngaards daa016e3e4 - Add test for allow-notify with a host name. 2026-01-27 13:49:33 +01:00
W.C.A. Wijngaards 039f69e735 - Fix to not skip allow-notify hostname lookups when there are only
urls.
2026-01-26 16:16:38 +01:00
W.C.A. Wijngaards b39009e487 Merge branch 'master' of github.com:NLnetLabs/unbound 2026-01-26 15:17:26 +01:00
W.C.A. Wijngaards 933769ee73 - Fix that allow-notify entries with hostnames are copied after IPv4
and IPv6 lookup.
2026-01-26 15:16:43 +01:00
Yorgos Thessalonikefs 57bff79627 - Update generated man pages. 2026-01-23 18:04:25 +01:00
Yorgos Thessalonikefs 1b5559d534 Changelog entry for #1396:
- Merge #1396: Log Linux thread ID.
- On Linux systems log the system-wide unique thread ID instead of
  Unbound's internal thread counter.
- Introduce the 'log-thread-id' configuration option to manage logging
  the system-wide Linux thread ID for easier debugging with system
  tools.
2026-01-23 17:46:14 +01:00
Yorgos ThessalonikefsandGitHub 9d271c5343 Merge pull request #1396 from NLnetLabs/features/thread-id 2026-01-23 17:42:30 +01:00
Yorgos Thessalonikefs 74cc49e6c4 - Introduce the 'log-thread-id' configuration option to manage logging
the system-wide Linux thread ID for easier debugging with system
  tools.
2026-01-23 17:15:14 +01:00
Yorgos Thessalonikefs d414ebf0c7 - On Linux systems log the system-wide unique thread ID instead of
Unbound's internal thread counter.
2026-01-23 17:08:55 +01:00
W.C.A. Wijngaards 9b123d1b78 - Fix http test tool petal to not print errors when there is no
error.
2026-01-22 14:19:35 +01:00
W.C.A. Wijngaards 37b71261a2 - Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
and max_global_quota options.
2026-01-22 09:42:56 +01:00
W.C.A. Wijngaards 4426db4d3d - Merge #1388: QNX Porting support for unbound. 2026-01-21 13:13:01 +01:00
nnarayanamurthyandGitHub fe10bc7682 QNX Porting support for unbound branch-1.24.1 (#1388)
* qnx Porting support for version release-1.24.1

* updating __QNXNTO__ with __QNX__
2026-01-21 13:12:13 +01:00
W.C.A. Wijngaards 67d2eae28c - Merge #1392: Include "V" (version) option in synopsis. 2026-01-19 09:09:47 +01:00
David H. GutteridgeandGitHub 9010a7075e Include "V" (version) option in synopsis (#1392) 2026-01-19 09:09:12 +01:00
W.C.A. Wijngaards cc6dbc9f38 - Fix documentation for requestlist.overwritten and
requestlist.exceeded, it explains which query was dropped.
2026-01-15 09:35:04 +01:00
W.C.A. Wijngaards 4198343dbe Compile fixup for #1381. 2026-01-08 14:19:06 +01:00
W.C.A. Wijngaards 08600d68e8 Changelog note for #1381, and man page explanation.
- Merge #1381: Do not initialize quic_table unless it is enabled.
2026-01-08 14:16:54 +01:00
Petr MenšíkandGitHub 18e098285e Do not initialize quic_table unless it is enabled (#1381)
* Do not initialize quic_table unless it is enabled

Fedora in FIPS mode might fail to initialize ngtcp2 library, because
some ciphers desired are not available.

Make it possible to skip initialization by setting explicitly quic_port
to 0. Unless we have some listeners for port 853 configured, skip its
initialization as well.

Related: https://pagure.io/freeipa/issue/9877

* Fix typo in logged function name
2026-01-08 14:12:32 +01:00
Yorgos Thessalonikefs f1b35bab4b Changelog entry for #1391:
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
  RFC5952.
2026-01-06 18:21:34 +01:00
Yorgos ThessalonikefsandGitHub 84ed77238d Merge pull request #1391 from GoetzGoerisch/docs
Fix documentation to adhere to RFC 5952
2026-01-06 18:19:47 +01:00
Goetz Goerisch adb0374a4d Fix documentation to adhere to RFC 5952
Update the text representations of IPv6 addresses.
2026-01-06 16:10:37 +01:00
W.C.A. Wijngaards b0b634558b - Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
  stub-no-cache option is set, it is not stored in cache due to
  the forward or stub option.
This has the changelog entry and test.
2026-01-06 09:33:00 +01:00
W.C.A. Wijngaards 8546247292 - Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
  stub-no-cache option is set, it is not stored in cache due to
  the forward or stub option.
2026-01-06 09:32:21 +01:00
Yorgos Thessalonikefs 44659cb3bf - Use the same EDE removal logic when encoding errors as when encoding
replies.
2025-12-31 16:22:15 +01:00
Yorgos Thessalonikefs a1ac2d0252 - Update the unbound-anchor man page to note write permissions of the
generated file if it is to be used with Unbound's
  auto-trust-anchor-file option.
2025-12-31 14:05:42 +01:00
Yorgos Thessalonikefs 5c7a26b615 - Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
categorization in the log output.
2025-12-30 13:15:37 +01:00
Yorgos Thessalonikefs 09d352b917 - More specific wording in the unbound.conf man page for stub-first
and forward-first options.
2025-12-24 14:57:44 +01:00
W.C.A. Wijngaards c0522043f0 - Fix http2 drop handling to clear the postpone_drop state so that
other streams on the http2 session are not affected by a drop,
  and can clean up properly if also dropped. Fix http2 send reply
  so that when there is a send failure is does not recurse into
  the mesh functions and also does not drop the connection due to
  the condition of one stream.
2025-12-03 14:41:10 +01:00
W.C.A. Wijngaards b858801feb - Fix to remove http2 stream mesh state when mesh new request is
dropping the new request.
2025-12-02 15:31:53 +01:00
W.C.A. Wijngaards 588db09928 - Fix header comment about EDE reference in validator/val_sigcrypt.h. 2025-12-01 16:04:41 +01:00
W.C.A. Wijngaards 5c66c48a1b - Fix to add EDNS CO flag to testbound and debug message log. 2025-12-01 15:29:41 +01:00
Yorgos Thessalonikefs 83336477c6 - For #1375, there is no DNSTAP environment if it wasn't configured. 2025-11-28 15:20:21 +01:00
Yorgos Thessalonikefs e3e5eb66cf - Tag for 1.24.2 release.
The repository continues with version 1.24.3.
2025-11-26 13:54:25 +01:00
Yorgos Thessalonikefs 00d3b97dbb Merge branch 'branch-1.24.2' 2025-11-26 13:50:49 +01:00
Yorgos Thessalonikefs f6269baa60 - Additional fix for CVE-2025-11411 (possible domain hijacking attack),
to include YXDOMAIN and non-referral nodata answers in the mitigation as
  well, reported by TaoFei Guo from Peking University, Yang Luo and JianJun
  Chen from Tsinghua University.
2025-11-26 11:09:40 +01:00
Yorgos Thessalonikefs 19154c6e58 - Set version to 1.24.2. 2025-11-26 10:58:06 +01:00
W.C.A. Wijngaards 0f43b0ea6c Changelog note for #1375, and lock for lockchecks and ifdef for compile fix.
- Merge #1375: Copy DNSTAP changes from daemon to workers after
  fast_reload.
2025-11-13 15:45:27 +01:00
smeddlepandGitHub e6d92f458f Copy DNSTAP changes from daemon to workers after fast_reload (#1375)
- On fast_reload, the identity and version strings are always freed and
  reallocated as part of dt_apply_cfg(). Add fr_worker_pickup_dnstap_changes()
  to copy any changes from daemon to workers.
2025-11-13 15:42:44 +01:00
W.C.A. Wijngaards a31b9d50e2 Changelog note for #1374
- Merge #1374: Mesh reply counters.
  This adds the statistics num.queries.replyaddr_limit and
  requestlist.current.replies.
2025-11-13 09:34:45 +01:00
Robert EdmondsandGitHub fceb4e8585 Mesh reply counters (#1374)
* Statistics counter for number of queries dropped by limit on reply addresses

Request list entries can be associated with multiple pending "reply
addresses". Basically each request list entry keeps its own list of
clients that should receive the response once the recursion is finished.
This requires keeping allocations around for each client, and there is
a global limit on the number of *additional* reply addresses that can
be allocated. (Each new request list entry seems to get its own initial
reply address which is not counted against the limit.)

This commit adds a statistics counter "num_queries_replyaddr_limit" that
counts the number of incoming client queries that have been dropped due
to the restriction on allocating additional reply addresses. This allows
distinguishing these drops from other kinds of drops.

* Statistics counter for number of mesh reply entries

Request list entries can be associated with multiple pending "reply
addresses". Since there is a limit on the number of additional reply
addresses that can be allocated which can cause incoming queries to be
dropped if exceeded, it would be nice to be able to track this number.

This commit basically exports the mesh_area's internal counter
`num_reply_addrs` as "threadX.requestlist.current.replies" /
"total.requestlist.current.replies".
2025-11-13 09:33:05 +01:00
W.C.A. Wijngaards 98f4257890 - iana portlist updated. 2025-11-12 11:49:21 +01:00
W.C.A. Wijngaards 0a15118aff - Fix that when discard timeout drops packet, they are accounted as
less reply addresses in use in the mesh area.
2025-11-12 11:49:04 +01:00
W.C.A. Wijngaards e887a79a92 - Fix configure test for nonstring attribute so that it does not
accept when the compiler prints a warning about an unknown
  attribute.
2025-11-06 15:03:17 +01:00
W.C.A. Wijngaards f9b9050ab8 - Fix configure test for noreturn attribute so it compiles without
warning.
2025-11-06 15:00:08 +01:00
W.C.A. Wijngaards 94735384fd - Fix add comment to worker_handle_request function that explain it. 2025-11-06 14:32:56 +01:00
W.C.A. Wijngaards 5dab0609e5 - Fix dns64 log output to log the default instead of a null string. 2025-11-04 10:19:03 +01:00
Yorgos Thessalonikefs 024c921dbf - Fix #1366: Infra cache does not work correctly for NAT64, by
moving the NAT64 synthesis from the iterator when selecting a target
  address, to the delegation point itself when adding target
  addresses.
2025-11-01 15:10:27 +01:00
140 changed files with 7365 additions and 705 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
+7 -1
View File
@@ -2,7 +2,9 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 50
# Version 51
# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
# a warning for 'unknown attribute' when nonstring is used.
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
# check by ACX_FUNC_MALLOC.
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
@@ -535,6 +537,9 @@ dnl result in HAVE_ATTR_NONSTRING.
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([ACX_CHECK_ERROR_FLAGS])
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ERRFLAG"
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
[ac_cv_c_nonstring_attribute=no
@@ -546,6 +551,7 @@ struct test {
struct test t = { "1" };
(void) t;
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
CFLAGS="$BAKCFLAGS"
])
dnl Setup ATTR_NONSTRING config.h parts.
+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;
+7
View File
@@ -38,6 +38,9 @@
#ifndef UB_ON_WINDOWS
#include <sys/mman.h>
#endif
#ifdef __QNX__
#include "util/log.h"
#endif /* __QNX__ */
#define KEYSTREAM_ONLY
#include "chacha_private.h"
@@ -187,7 +190,11 @@ _rs_stir(void)
if(errno != ENOSYS ||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
#ifdef SIGKILL
#ifndef __QNX__
raise(SIGKILL);
#else /* !__QNX__ */
fatal_exit("failed to getentropy");
#endif /* __QNX__ */
#else
exit(9); /* windows */
#endif
+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))
+20
View File
@@ -29,7 +29,9 @@
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#ifndef __QNX__
#include <sys/syscall.h>
#endif /* !__QNX__ */
#ifdef SYS__sysctl
#include <linux/sysctl.h>
#endif
@@ -42,7 +44,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#ifndef __QNX__
#include <link.h>
#endif /* __QNX__ */
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
@@ -60,12 +64,14 @@
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
#endif
#ifndef __QNX__
#include <linux/types.h>
#include <linux/random.h>
#ifdef HAVE_GETAUXVAL
#include <sys/auxv.h>
#endif
#include <sys/vfs.h>
#endif /* !__QNX__ */
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
@@ -94,8 +100,10 @@ static int getentropy_urandom(void *buf, size_t len);
#ifdef SYS__sysctl
static int getentropy_sysctl(void *buf, size_t len);
#endif
#ifndef __QNX__
static int getentropy_fallback(void *buf, size_t len);
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
#endif /* !__QNX__ */
int
getentropy(void *buf, size_t len)
@@ -178,6 +186,7 @@ getentropy(void *buf, size_t len)
* sysctl ABI, or consider providing a new failsafe API which
* works in a chroot or when file descriptors are exhausted.
*/
#ifndef __QNX__
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
raise(SIGKILL);
@@ -185,6 +194,9 @@ getentropy(void *buf, size_t len)
ret = getentropy_fallback(buf, len);
if (ret != -1)
return (ret);
#else /* !__QNX__ */
fatal_exit("failed to read from /dev/urandom");
#endif /* __QNX__ */
errno = EIO;
return (ret);
@@ -214,7 +226,11 @@ getentropy_urandom(void *buf, size_t len)
{
struct stat st;
size_t i;
#ifndef __QNX__
int fd, cnt, flags;
#else /* !__QNX__ */
int fd, flags;
#endif /* __QNX__ */
int save_errno = errno;
start:
@@ -241,10 +257,12 @@ start:
close(fd);
goto nodevrandom;
}
#ifndef __QNX__
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
close(fd);
goto nodevrandom;
}
#endif /* !__QNX__ */
for (i = 0; i < len; ) {
size_t wanted = len - i;
ssize_t ret = read(fd, (char *)buf + i, wanted);
@@ -265,6 +283,7 @@ nodevrandom:
return (-1);
}
#ifndef __QNX__
#ifdef SYS__sysctl
static int
getentropy_sysctl(void *buf, size_t len)
@@ -537,3 +556,4 @@ getentropy_fallback(void *buf, size_t len)
errno = save_errno;
return (0); /* satisfied */
}
#endif /* !__QNX__ */
+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
+208 -14
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.2.
# 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.2'
PACKAGE_STRING='unbound 1.24.2'
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.2 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.2:";;
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.2
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.2, 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,13 +3251,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=24
UNBOUND_VERSION_MINOR=25
UNBOUND_VERSION_MICRO=2
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=35
LIBUNBOUND_REVISION=36
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -3360,6 +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.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
@@ -6949,6 +6950,9 @@ printf "%s\n" "#define HAVE_ATTR_UNUSED 1" >>confdefs.h
fi
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ERRFLAG"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute" >&5
printf %s "checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute... " >&6; }
if test ${ac_cv_c_nonstring_attribute+y}
@@ -6981,6 +6985,7 @@ else $as_nop
ac_cv_c_nonstring_attribute="no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS="$BAKCFLAGS"
fi
@@ -7059,7 +7064,14 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
#ifdef STDC_HEADERS
# include <stdlib.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); }
int
main (void)
@@ -19068,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.
@@ -23252,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" "
@@ -25357,7 +25551,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.24.2
version=1.25.0
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
printf %s "checking for build time... " >&6; }
@@ -25887,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.2, 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
@@ -25955,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.2
unbound config.status 1.25.0
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+83 -4
View File
@@ -11,15 +11,15 @@ 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],[2])
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])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=35
LIBUNBOUND_REVISION=36
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -122,6 +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.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
@@ -361,7 +362,14 @@ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribu
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
[ac_cv_c_noreturn_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
#ifdef STDC_HEADERS
# include <stdlib.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); }
]], [[
f(1);
]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
@@ -723,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
@@ -1761,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;
+308 -18
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())
@@ -558,9 +815,11 @@ daemon_create_workers(struct daemon* daemon)
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
#ifdef HAVE_NGTCP2
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
if(!daemon->doq_table)
fatal_exit("could not create doq_table: out of memory");
if (cfg_has_quic(daemon->cfg)) {
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
if(!daemon->doq_table)
fatal_exit("could not create doq_table: out of memory");
}
#endif
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
@@ -631,6 +890,25 @@ static void close_other_pipes(struct daemon* daemon, int thr)
}
#endif /* THREADS_DISABLED */
/**
* Function to set the thread local log ID.
* Either the internal thread number, or the LWP ID on Linux based on
* configuration.
*/
static void
set_log_thread_id(struct worker* worker, struct config_file* cfg)
{
(void)cfg;
log_assert(worker);
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
worker->thread_tid = gettid();
if(cfg->log_thread_id)
log_thread_set(&worker->thread_tid);
else
#endif
log_thread_set(&worker->thread_num);
}
/**
* Function to start one thread.
* @param arg: user argument.
@@ -641,7 +919,14 @@ thread_start(void* arg)
{
struct worker* worker = (struct worker*)arg;
int port_num = 0;
log_thread_set(&worker->thread_num);
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 */
@@ -716,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 */
@@ -801,9 +1087,19 @@ daemon_fork(struct daemon* daemon)
fatal_exit("RPZ requires the respip module");
/* first create all the worker structures, so we can pass
* them to the newly created threads.
* them to the newly created threads.
*/
daemon_create_workers(daemon);
/* Set it for the first (main) worker since it does not take part in
* 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 */
@@ -917,8 +1213,10 @@ daemon_cleanup(struct daemon* daemon)
daemon->dnscenv = NULL;
#endif
#ifdef HAVE_NGTCP2
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
if (daemon->doq_table) {
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
}
#endif
daemon->cfg = NULL;
}
@@ -956,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 */
+310 -6
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) {
@@ -801,6 +821,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_discard_timeout)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_replyaddr_limit)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_wait_limit)) return 0;
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
@@ -845,6 +867,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->mesh_num_states)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
(unsigned long)s->mesh_num_reply_states)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm,
(unsigned long)s->mesh_num_reply_addrs)) return 0;
#ifndef S_SPLINT_S
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
@@ -4629,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 */
@@ -4932,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);
@@ -5043,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) {
@@ -5175,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);
@@ -5291,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);
@@ -5524,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,
@@ -5531,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;
@@ -5808,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. */
@@ -5869,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);
@@ -5968,6 +6161,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_int(log_servfail);
COPY_VAR_ptr(log_identity);
COPY_VAR_int(log_destaddr);
COPY_VAR_int(log_thread_id);
COPY_VAR_int(hide_identity);
COPY_VAR_int(hide_version);
COPY_VAR_int(hide_trustanchor);
@@ -6177,7 +6371,20 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(ipset_name_v6);
#endif
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 */
@@ -6403,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)
@@ -6627,7 +6837,19 @@ 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;
log_thread_set(&fast_reload_thread->threadnum);
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();
if(fast_reload_thread->thread_tid_log)
log_thread_set(&fast_reload_thread->thread_tid);
else
#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) {
@@ -7015,6 +7237,9 @@ fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause,
lock_basic_init(&fr->fr_output_lock);
lock_protect(&fr->fr_output_lock, fr->fr_output,
sizeof(*fr->fr_output));
#ifdef HAVE_GETTID
fr->thread_tid_log = worker->env.cfg->log_thread_id;
#endif
return 1;
}
@@ -7589,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)
@@ -7604,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;
@@ -7612,6 +7877,41 @@ fr_worker_pickup_outside_network(struct worker* worker)
}
}
#ifdef USE_DNSTAP
/** Fast reload, the worker picks up changes to DNSTAP configuration. */
static void
fr_worker_pickup_dnstap_changes(struct worker* worker)
{
struct dt_env* w_dtenv = &worker->dtenv;
struct dt_env* d_dtenv = worker->daemon->dtenv;
log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap);
if(d_dtenv == NULL) {
/* There is no environment when DNSTAP was not enabled
* in the configuration. */
return;
}
w_dtenv->identity = d_dtenv->identity;
w_dtenv->len_identity = d_dtenv->len_identity;
w_dtenv->version = d_dtenv->version;
w_dtenv->len_version = d_dtenv->len_version;
w_dtenv->log_resolver_query_messages =
d_dtenv->log_resolver_query_messages;
w_dtenv->log_resolver_response_messages =
d_dtenv->log_resolver_response_messages;
w_dtenv->log_client_query_messages =
d_dtenv->log_client_query_messages;
w_dtenv->log_client_response_messages =
d_dtenv->log_client_response_messages;
w_dtenv->log_forwarder_query_messages =
d_dtenv->log_forwarder_query_messages;
w_dtenv->log_forwarder_response_messages =
d_dtenv->log_forwarder_response_messages;
lock_basic_lock(&d_dtenv->sample_lock);
w_dtenv->sample_rate = d_dtenv->sample_rate;
lock_basic_unlock(&d_dtenv->sample_lock);
}
#endif /* USE_DNSTAP */
void
fast_reload_worker_pickup_changes(struct worker* worker)
{
@@ -7639,7 +7939,11 @@ 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);
#endif
}
/** fast reload thread, handle reload_stop notification, send reload stop
+8
View File
@@ -206,6 +206,12 @@ struct fast_reload_thread {
int commpair[2];
/** thread id, of the io thread */
ub_thread_type tid;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** if the thread has to quit */
@@ -249,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;
};
/**
+6
View File
@@ -262,6 +262,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr = worker->stats;
s->mesh_num_states = (long long)worker->env.mesh->all.count;
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs;
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
@@ -284,6 +285,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
NUM_BUCKETS_HIST);
s->svr.num_queries_discard_timeout +=
(long long)worker->env.mesh->num_queries_discard_timeout;
s->svr.num_queries_replyaddr_limit +=
(long long)worker->env.mesh->num_queries_replyaddr_limit;
s->svr.num_queries_wait_limit +=
(long long)worker->env.mesh->num_queries_wait_limit;
s->svr.num_dns_error_reports +=
@@ -448,6 +451,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
total->svr.num_queries_discard_timeout +=
a->svr.num_queries_discard_timeout;
total->svr.num_queries_replyaddr_limit +=
a->svr.num_queries_replyaddr_limit;
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
@@ -519,6 +524,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->mesh_num_states += a->mesh_num_states;
total->mesh_num_reply_states += a->mesh_num_reply_states;
total->mesh_num_reply_addrs += a->mesh_num_reply_addrs;
total->mesh_jostled += a->mesh_jostled;
total->mesh_dropped += a->mesh_dropped;
total->mesh_replies_sent += a->mesh_replies_sent;
+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.*/
+163 -85
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,
@@ -1444,6 +1449,24 @@ check_ip_ratelimit(struct worker* worker, struct sockaddr_storage* addr,
return 1;
}
/*
* This is the callback function when a request arrives. It is passed
* the packet and user argument. Return true to send a reply.
* This is of type comm_point_callback_type. The struct comm_point contains
* more comments on the comm_point.callback member about the function.
* @param c: the comm_point where the request arrives on.
* @param arg: the user argument for the callback, the worker.
* @param error: This can be NETEVENT_NOERROR, NETEVENT_TIMEOUT,
* NETEVENT_CLOSED or other comm point callback error values.
* @param repinfo: The reply info, use it to send a reply. If the reply
* is immediate, return 1. If the reply is later on return 0 and save
* the repinfo, to call comm_point_send_reply on.
* @return 1 to sent a reply straight away, for like cache response so that
* no allocation needs to be done. And only internal preallocated buffers
* are used. Return 0 and save the repinfo to reply later, for responses
* that need to be looked up. Return 0 and call comm_point_drop_reply on
* the repinfo to drop the response.
*/
int
worker_handle_request(struct comm_point* c, void* arg, int error,
struct comm_reply* repinfo)
@@ -1510,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;
}
@@ -1518,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 &&
@@ -1530,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);
@@ -1572,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);
@@ -1608,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) {
@@ -1624,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]++;
}
@@ -1646,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]++;
}
@@ -1657,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,
@@ -1680,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);
@@ -1725,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 *)
@@ -1739,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");
@@ -1765,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;
}
@@ -1857,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, "");
@@ -1865,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;
}
@@ -2106,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);
}
}
@@ -2184,9 +2265,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
struct dt_env* dtenv = &worker->dtenv;
#else
void* dtenv = NULL;
#endif
#ifdef HAVE_GETTID
worker->thread_tid = gettid();
#endif
worker->need_to_exit = 0;
worker->base = comm_base_create(do_sigs);
+8 -7
View File
@@ -366,22 +366,23 @@ static int
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
{
struct config_strlist* s;
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
const char* dns64_prefix = cfg->dns64_prefix ?
cfg->dns64_prefix : DEFAULT_DNS64_PREFIX;
verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix);
if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr,
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix);
return 0;
}
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
log_err("dns64_prefix is not IPv6: %s", dns64_prefix);
return 0;
}
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
cfg->dns64_prefix);
log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s",
dns64_prefix);
return 0;
}
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
+15 -1
View File
@@ -448,6 +448,9 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
dtio->tls_use_sni = cfg->tls_use_sni;
#endif /* HAVE_SSL */
}
#ifdef HAVE_GETTID
dtio->thread_tid_log = cfg->log_thread_id;
#endif
return 1;
}
@@ -2130,7 +2133,18 @@ static void* dnstap_io(void* arg)
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
time_t secs = 0;
struct timeval now;
log_thread_set(&dtio->threadnum);
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();
if(dtio->thread_tid_log)
log_thread_set(&dtio->thread_tid);
else
#endif
log_thread_set(&dtio->threadnum);
ub_thread_setname(dtio->tid, name);
/* setup */
verbose(VERB_ALGO, "start dnstap io thread");
+6
View File
@@ -131,6 +131,12 @@ struct dt_io_thread {
struct dt_io_list_item* io_list_iter;
/** thread id, of the io thread */
ub_thread_type tid;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
+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);
+369
View File
@@ -1,3 +1,372 @@
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.
26 January 2026: Wouter
- Fix that allow-notify entries with hostnames are copied after IPv4
and IPv6 lookup.
- Fix to not skip allow-notify hostname lookups when there are only
urls.
23 January 2026: Yorgos
- Merge #1396: Log Linux thread ID.
- On Linux systems log the system-wide unique thread ID instead of
Unbound's internal thread counter.
- Introduce the 'log-thread-id' configuration option to manage logging
the system-wide Linux thread ID for easier debugging with system
tools.
- Update generated man pages.
22 January 2026: Wouter
- Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
and max_global_quota options.
- Fix http test tool petal to not print errors when there is no
error.
21 January 2026: Wouter
- Merge #1388: QNX Porting support for unbound.
19 January 2026: Wouter
- Merge #1392: Include "V" (version) option in synopsis.
15 January 2026: Wouter
- Fix documentation for requestlist.overwritten and
requestlist.exceeded, it explains which query was dropped.
8 January 2026: Wouter
- Merge #1381: Do not initialize quic_table unless it is enabled.
6 January 2026: Wouter
- Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
stub-no-cache option is set, it is not stored in cache due to
the forward or stub option.
6 January 2026: Yorgos
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
RFC5952.
31 December 2025: Yorgos
- Update the unbound-anchor man page to note write permissions of the
generated file if it is to be used with Unbound's
auto-trust-anchor-file option.
- Use the same EDE removal logic when encoding errors as when encoding
replies.
30 December 2025: Yorgos
- Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
categorization in the log output.
24 December 2025: Yorgos
- More specific wording in the unbound.conf man page for stub-first
and forward-first options.
3 December 2025: Wouter
- Fix http2 drop handling to clear the postpone_drop state so that
other streams on the http2 session are not affected by a drop,
and can clean up properly if also dropped. Fix http2 send reply
so that when there is a send failure is does not recurse into
the mesh functions and also does not drop the connection due to
the condition of one stream.
2 December 2025: Wouter
- Fix to remove http2 stream mesh state when mesh new request is
dropping the new request.
1 December 2025: Wouter
- Fix to add EDNS CO flag to testbound and debug message log.
- Fix header comment about EDE reference in validator/val_sigcrypt.h.
28 November 2025: Yorgos
- For #1375, there is no DNSTAP environment if it wasn't configured.
26 November 2025: Yorgos
- Tag for 1.24.2 release.
The repository continues with version 1.24.3.
13 November 2025: Wouter
- Merge #1374: Mesh reply counters.
This adds the statistics num.queries.replyaddr_limit and
requestlist.current.replies.
- Merge #1375: Copy DNSTAP changes from daemon to workers after
fast_reload.
12 November 2025: Wouter
- Fix that when discard timeout drops packet, they are accounted as
less reply addresses in use in the mesh area.
- iana portlist updated.
6 November 2025: Wouter
- Fix add comment to worker_handle_request function that explain it.
- Fix configure test for noreturn attribute so it compiles without
warning.
- Fix configure test for nonstring attribute so that it does not
accept when the compiler prints a warning about an unknown
attribute.
4 November 2025: Wouter
- Fix dns64 log output to log the default instead of a null string.
1 November 2025: Yorgos
- Fix #1366: Infra cache does not work correctly for NAT64, by
moving the NAT64 synthesis from the iterator when selecting a target
address, to the delegation point itself when adding target
addresses.
27 October 2025: Yorgos
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
new $action, for SWIG.
+3 -3
View File
@@ -13,7 +13,7 @@ If you're not using DNSSEC then you may remove "validator".
2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
dns64-prefix: 64:FF9B::/96
dns64-prefix: 64:ff9b::/96
The prefix must be a /96 or shorter.
@@ -42,9 +42,9 @@ To enable NAT64 in Unbound, add to unbound.conf's "server" section:
do-nat64: yes
The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the
standard 64:FF9B::/96 prefix. You can reconfigure it with:
standard 64:ff9b::/96 prefix. You can reconfigure it with:
nat64-prefix: 64:FF9B::/96
nat64-prefix: 64:ff9b::/96
To test NAT64 operation, pick a domain that only has IPv4 reachability for its
nameservers and try resolving any names in that domain.
+18 -15
View File
@@ -54,7 +54,7 @@ server:
# interface: 192.0.2.153
# interface: 192.0.2.154
# interface: 192.0.2.154@5003
# interface: 2001:DB8::5
# interface: 2001:db8::5
# interface: eth0@5003
# enable this feature to copy the source address of queries to reply.
@@ -72,12 +72,12 @@ server:
# server from by ip-address. If none, the default (all) interface
# is used. Specify every interface on a 'outgoing-interface:' line.
# outgoing-interface: 192.0.2.153
# outgoing-interface: 2001:DB8::5
# outgoing-interface: 2001:DB8::6
# outgoing-interface: 2001:db8::5
# outgoing-interface: 2001:db8::6
# Specify a netblock to use remainder 64 bits as random bits for
# upstream queries. Uses freebind option (Linux).
# outgoing-interface: 2001:DB8::/64
# outgoing-interface: 2001:db8::/64
# Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
# And: ip -6 route add local 2001:db8::/64 dev lo
# And set prefer-ip6: yes to use the ip6 randomness from a netblock.
@@ -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
@@ -379,7 +382,7 @@ server:
# interface-action: 192.0.2.153 allow
# interface-action: 192.0.2.154 allow
# interface-action: 192.0.2.154@5003 allow
# interface-action: 2001:DB8::5 allow
# interface-action: 2001:db8::5 allow
# interface-action: eth0@5003 allow
# Similar to 'access-control-tag:' but for interfaces.
@@ -496,6 +499,10 @@ server:
# print log lines that say why queries return SERVFAIL to clients.
# log-servfail: no
# log system-wide Linux thread ID, insted of Unbound's internal thread
# counter. Only on Linux and only when threads are available.
# log-thread-id: no
# the pid file. Can be an absolute path outside of chroot/work dir.
# pidfile: "@UNBOUND_PIDFILE@"
@@ -658,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.
#
@@ -718,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
@@ -961,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.
+1 -1
View File
@@ -416,6 +416,6 @@ on a function return with file read failure.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+13 -4
View File
@@ -39,9 +39,17 @@ unbound-anchor \- Unbound @version@ anchor utility.
validation.
The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when
regular \fI\%RFC 5011\fP update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the \fI\%unbound(8)\fP DNS server.
It can be run from the commandline, or run as part of startup scripts before
you start the \fI\%unbound(8)\fP DNS server.
.sp
Note that if you want to use \fI\%RFC 5011\fP with Unbound (i.e., the
\fI\%auto\-trust\-anchor\-file\fP option) so
that trust anchor information is automatically tracked by Unbound during
operation, the user that Unbound runs under (by default \(aqunbound\(aq) must have
write permissions to the file and the directory the file lives in (for creating
temporary files).
In this case you would probably want to run this program as the designated
Unbound user.
.sp
Suggested usage:
.INDENT 0.0
@@ -52,6 +60,7 @@ Suggested usage:
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
@@ -295,6 +304,6 @@ Signature on the root key information.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+12 -3
View File
@@ -51,9 +51,17 @@ Description
validation.
The program fetches the trust anchor with the method from :rfc:`7958` when
regular :rfc:`5011` update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
It can be run from the commandline, or run as part of startup scripts before
you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
Note that if you want to use :rfc:`5011` with Unbound (i.e., the
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>` option) so
that trust anchor information is automatically tracked by Unbound during
operation, the user that Unbound runs under (by default 'unbound') must have
write permissions to the file and the directory the file lives in (for creating
temporary files).
In this case you would probably want to run this program as the designated
Unbound user.
Suggested usage:
@@ -62,6 +70,7 @@ Suggested usage:
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
+1 -1
View File
@@ -88,6 +88,6 @@ Unbound configuration file.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+40 -1
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
@@ -880,6 +882,11 @@ number of queries removed due to discard\-timeout by thread
.UNINDENT
.INDENT 0.0
.TP
.B threadX.num.queries_replyaddr_limit
number of queries removed due to replyaddr limits by thread
.UNINDENT
.INDENT 0.0
.TP
.B threadX.num.queries_wait_limit
number of queries removed due to wait\-limit by thread
.UNINDENT
@@ -973,6 +980,10 @@ Number of requests in the request list that were overwritten by newer
entries.
This happens if there is a flood of queries that recursive processing and
the server has a hard time.
The counter is increased when during the flood the
\fI\%jostle\-timeout\fP
allows a query to be removed in favor of a new incoming query.
The older query is then dropped to make space.
.UNINDENT
.INDENT 0.0
.TP
@@ -980,6 +991,12 @@ the server has a hard time.
Queries that were dropped because the request list was full.
This happens if a flood of queries need recursive processing, and the
server can not keep up.
The counter is increased when during the flood there is no space
to be made with the jostle out of an older query, and the new query
is dropped.
Since no older queries are removed, see
\fI\%jostle\-timeout\fP setting, there
is no space for the new query.
.UNINDENT
.INDENT 0.0
.TP
@@ -994,6 +1011,13 @@ Current size of the request list, only the requests from client queries.
.UNINDENT
.INDENT 0.0
.TP
.B threadX.requestlist.current.replies
Current count of the number of reply entries waiting on request list
entries. Because a request list entry can send results to multiple reply
addresses, this number may be larger than the size of the request list.
.UNINDENT
.INDENT 0.0
.TP
.B threadX.recursion.time.avg
Average time it took to answer queries that needed recursive processing.
Note that queries that were answered from the cache are not in this average.
@@ -1048,6 +1072,11 @@ summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.num.queries_replyaddr_limit
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.num.queries_wait_limit
summed over threads.
.UNINDENT
@@ -1138,6 +1167,16 @@ summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.requestlist.current.user
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.requestlist.current.replies
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.recursion.time.median
averaged over threads.
.UNINDENT
@@ -1543,6 +1582,6 @@ directory with private keys (\fBunbound_server.key\fP and
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+34
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
@@ -815,6 +817,10 @@ number of statistic counters:
number of queries removed due to discard-timeout by thread
@@UAHL@unbound-control.stats@threadX.num.queries_replyaddr_limit@@
number of queries removed due to replyaddr limits by thread
@@UAHL@unbound-control.stats@threadX.num.queries_wait_limit@@
number of queries removed due to wait-limit by thread
@@ -893,12 +899,22 @@ number of statistic counters:
entries.
This happens if there is a flood of queries that recursive processing and
the server has a hard time.
The counter is increased when during the flood the
:ref:`jostle-timeout<unbound.conf.jostle-timeout>`
allows a query to be removed in favor of a new incoming query.
The older query is then dropped to make space.
@@UAHL@unbound-control.stats@threadX.requestlist.exceeded@@
Queries that were dropped because the request list was full.
This happens if a flood of queries need recursive processing, and the
server can not keep up.
The counter is increased when during the flood there is no space
to be made with the jostle out of an older query, and the new query
is dropped.
Since no older queries are removed, see
:ref:`jostle-timeout<unbound.conf.jostle-timeout>` setting, there
is no space for the new query.
@@UAHL@unbound-control.stats@threadX.requestlist.current.all@@
@@ -910,6 +926,12 @@ number of statistic counters:
Current size of the request list, only the requests from client queries.
@@UAHL@unbound-control.stats@threadX.requestlist.current.replies@@
Current count of the number of reply entries waiting on request list
entries. Because a request list entry can send results to multiple reply
addresses, this number may be larger than the size of the request list.
@@UAHL@unbound-control.stats@threadX.recursion.time.avg@@
Average time it took to answer queries that needed recursive processing.
Note that queries that were answered from the cache are not in this average.
@@ -955,6 +977,10 @@ number of statistic counters:
summed over threads.
@@UAHL@unbound-control.stats@total.num.queries_replyaddr_limit@@
summed over threads.
@@UAHL@unbound-control.stats@total.num.queries_wait_limit@@
summed over threads.
@@ -1027,6 +1053,14 @@ number of statistic counters:
summed over threads.
@@UAHL@unbound-control.stats@total.requestlist.current.user@@
summed over threads.
@@UAHL@unbound-control.stats@total.requestlist.current.replies@@
summed over threads.
@@UAHL@unbound-control.stats@total.recursion.time.median@@
averaged over threads.
+1 -1
View File
@@ -185,6 +185,6 @@ encountered a fatal error.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+2 -2
View File
@@ -32,7 +32,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
unbound \- Unbound DNS validating resolver @version@.
.SH SYNOPSIS
.sp
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
\fBunbound\fP [\fB\-hdpVv\fP] [\fB\-c <cfgfile>\fP]
.SH DESCRIPTION
.sp
\fBunbound\fP is a caching DNS resolver.
@@ -118,6 +118,6 @@ Show the version number and build options, and exit.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+118 -31
View File
@@ -102,7 +102,7 @@ server:
interface: 0.0.0.0
interface: ::0
access\-control: 10.0.0.0/8 allow
access\-control: 2001:DB8::/64 allow
access\-control: 2001:db8::/64 allow
.ft P
.fi
.UNINDENT
@@ -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
@@ -1450,6 +1447,9 @@ The port number on which to provide DNS\-over\-QUIC service.
Only interfaces configured with that port number as @number get the QUIC
service.
The interface uses QUIC for the UDP traffic on that port number.
If it is set to 0, the server does not init QUIC code, and QUIC is
disabled.
This is similar to if QUIC is not in use, but then explicitly.
.sp
Default: 853
.UNINDENT
@@ -1927,6 +1927,16 @@ Default: no
.UNINDENT
.INDENT 0.0
.TP
.B log\-thread\-id: \fI<yes or no>\fP
(Only on Linux and only when threads are available)
Logs the system\-wide Linux thread ID instead of Unbound\(aqs internal thread
counter.
Can be useful when debugging with system tools.
.sp
Default: no
.UNINDENT
.INDENT 0.0
.TP
.B pidfile: \fI<filename>\fP
The process id is written to the file.
Default is \fB\(dq@UNBOUND_PIDFILE@\(dq\fP\&.
@@ -2259,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
@@ -2997,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
@@ -3055,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
@@ -3377,7 +3428,7 @@ zone section below.
Configure local data shorthand for a PTR record with the reversed IPv4 or
IPv6 address and the host name.
For example \fB\(dq192.0.2.4 www.example.com\(dq\fP\&.
TTL can be inserted like this: \fB\(dq2001:DB8::4 7200 www.example.com\(dq\fP
TTL can be inserted like this: \fB\(dq2001:db8::4 7200 www.example.com\(dq\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -3718,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
@@ -3745,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.
@@ -3926,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
@@ -4135,6 +4200,9 @@ Default: no
If enabled, a query is attempted without this stub section if it fails.
The data could not be retrieved and would have caused SERVFAIL because the
servers are unreachable, instead it is tried without this stub section.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
.sp
Default: no
.UNINDENT
@@ -4255,9 +4323,11 @@ The cert must also match a CA from the
.INDENT 0.0
.TP
.B forward\-first: \fI<yes or no>\fP
If a forwarded query is met with a SERVFAIL error, and this option is
enabled, Unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified.
If a forwarded query is met with a SERVFAIL error and this option is
enabled Unbound will fall back to less specific resolution.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
.sp
Default: no
.UNINDENT
@@ -4370,9 +4440,15 @@ does not support AXFR/IXFR for the zone, but if you used
\fI\%url\fP to download the zonefile as a text file
from a webserver that would work.
.sp
If you specify the hostname, you cannot use the domain from the zonefile,
because it may not have that when retrieving that data, instead use a plain
IP address to avoid a circular dependency on retrieving that IP address.
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
If you specify the hostname, you cannot use the domain from the
zonefile, because it may not have that when retrieving that data,
instead use a plain IP address to avoid a circular dependency on
retrieving that IP address.
.UNINDENT
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
@@ -4732,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
@@ -5907,6 +5994,6 @@ Default is to log to \fIsyslog(3)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+100 -22
View File
@@ -102,7 +102,7 @@ all the options.
interface: 0.0.0.0
interface: ::0
access-control: 10.0.0.0/8 allow
access-control: 2001:DB8::/64 allow
access-control: 2001:db8::/64 allow
.. _unbound.conf.clauses:
@@ -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>*
@@ -1306,6 +1308,9 @@ These options are part of the ``server:`` section.
Only interfaces configured with that port number as @number get the QUIC
service.
The interface uses QUIC for the UDP traffic on that port number.
If it is set to 0, the server does not init QUIC code, and QUIC is
disabled.
This is similar to if QUIC is not in use, but then explicitly.
Default: 853
@@ -1714,6 +1719,15 @@ These options are part of the ``server:`` section.
Default: no
@@UAHL@unbound.conf@log-thread-id@@: *<yes or no>*
(Only on Linux and only when threads are available)
Logs the system-wide Linux thread ID instead of Unbound's internal thread
counter.
Can be useful when debugging with system tools.
Default: no
@@UAHL@unbound.conf@pidfile@@: *<filename>*
The process id is written to the file.
Default is :file:`"@UNBOUND_PIDFILE@"`.
@@ -2000,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
@@ -2650,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>`.
@@ -2689,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
@@ -2896,7 +2945,7 @@ These options are part of the ``server:`` section.
Configure local data shorthand for a PTR record with the reversed IPv4 or
IPv6 address and the host name.
For example ``"192.0.2.4 www.example.com"``.
TTL can be inserted like this: ``"2001:DB8::4 7200 www.example.com"``
TTL can be inserted like this: ``"2001:db8::4 7200 www.example.com"``
@@UAHL@unbound.conf@local-zone-tag@@: *<zone> <"list of tags">*
@@ -3211,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.
@@ -3235,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.
@@ -3399,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
@@ -3587,6 +3649,9 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
If enabled, a query is attempted without this stub section if it fails.
The data could not be retrieved and would have caused SERVFAIL because the
servers are unreachable, instead it is tried without this stub section.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
Default: no
@@ -3699,9 +3764,11 @@ cache).
@@UAHL@unbound.conf.forward@forward-first@@: *<yes or no>*
If a forwarded query is met with a SERVFAIL error, and this option is
enabled, Unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified.
If a forwarded query is met with a SERVFAIL error and this option is
enabled Unbound will fall back to less specific resolution.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
Default: no
@@ -4144,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:
+1 -1
View File
@@ -42,7 +42,7 @@ unbound(8)
Synopsis
--------
**unbound** [``-hdpv``] [``-c <cfgfile>``]
**unbound** [``-hdpVv``] [``-c <cfgfile>``]
Description
-----------
+99 -5
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;
}
@@ -162,8 +165,15 @@ int ecs_whitelist_check(struct query_info* qinfo,
if(!ecs_is_whitelisted(sn_env->whitelist,
addr, addrlen, qinfo->qname, qinfo->qname_len,
qinfo->qclass)) {
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
qstate->no_cache_store = 0;
/* The stub or forward can have no_cache set.*/
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
verbose(VERB_ALGO, "subnet subquery is not stored globally, stuborfwd is no_cache");
} else {
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.%s",
(sq->started_no_cache_store?
" But the subnet module was started with no_cache_store for the super query, and that is still applied to this query":""));
qstate->no_cache_store = sq->started_no_cache_store;
}
}
}
return 1;
@@ -193,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
@@ -420,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);
@@ -463,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)
@@ -476,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));
@@ -489,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;
}
@@ -503,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;
@@ -563,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));
@@ -580,6 +665,7 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
}
subsq = (struct subnet_qstate*)subq->minfo[id];
subsq->is_subquery_nonsubnet = 1;
subsq->started_no_cache_store = sq->started_no_cache_store;
/* When the client asks 0.0.0.0/0 and the name is not treated
* as subnet, it is to be stored in the global cache.
@@ -632,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;
}
@@ -881,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;
}
+98 -11
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
@@ -418,12 +466,13 @@ shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
* @param qinfo: original query.
* @param region: where to allocate synthesized CNAMEs.
* @param env: module env with config options.
* @param zonename: name of server zone.
* @return 0 on error.
*/
static int
scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, struct regional* region,
struct module_env* env)
struct module_env* env, uint8_t* zonename)
{
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
@@ -431,7 +480,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_YXDOMAIN)
return 1;
/* For the ANSWER section, remove all "irrelevant" records and add
@@ -443,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
@@ -453,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;
@@ -470,6 +523,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
&aliaslen, pkt)) {
verbose(VERB_ALGO, "synthesized CNAME "
"too long");
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) {
prev = rrset;
rrset = rrset->rrset_all_next;
continue;
}
return 0;
}
cname_length++;
@@ -495,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;
@@ -518,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 */
@@ -613,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 */
@@ -650,6 +709,29 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* Also delete promiscuous NS for other RCODEs */
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR
&& env->cfg->iter_scrub_promiscuous) {
remove_rrset("normalize: removing promiscuous "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* Also delete promiscuous NS for NOERROR with nodata
* for authoritative answers, not for delegations.
* NOERROR with an_rrsets!=0 already handled.
* Also NOERROR and soa_in_auth already handled.
* NOERROR with an_rrsets==0, and not a referral.
* referral is (NS not the zonename, noSOA).
*/
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR
&& msg->an_rrsets == 0
&& !(dname_pkt_compare(pkt, rrset->dname,
zonename) != 0 && !soa_in_auth(msg))
&& env->cfg->iter_scrub_promiscuous) {
remove_rrset("normalize: removing promiscuous "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(nsset == NULL) {
nsset = rrset;
} else {
@@ -732,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;
}
@@ -942,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 */
@@ -1060,7 +1146,8 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
/* this is not required for basic operation but is a forgery
* resistance (security) feature */
if((FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR ||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN) &&
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN ||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) &&
msg->qdcount == 0)
return 0;
@@ -1074,7 +1161,7 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
}
/* normalize the response, this cleans up the additional. */
if(!scrub_normalize(pkt, msg, qinfo, region, env))
if(!scrub_normalize(pkt, msg, qinfo, region, env, zonename))
return 0;
/* delete all out-of-zone information */
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate))
+46 -4
View File
@@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
return 1;
}
/** filter out unsuitable targets
/** filter out unsuitable targets.
* Applies NAT64 if needed as well by replacing the IPv4 with the synthesized
* IPv6 address.
* @param iter_env: iterator environment with ipv6-support flag.
* @param env: module environment with infra cache.
* @param name: zone name
@@ -306,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 */
@@ -317,6 +340,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
!addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip4 available */
}
if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) {
struct sockaddr_storage real_addr;
socklen_t real_addrlen;
addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr,
iter_env->nat64.nat64_prefix_addrlen,
iter_env->nat64.nat64_prefix_net,
&real_addr, &real_addrlen);
log_name_addr(VERB_QUERY, "NAT64 apply: from: ",
name, &a->addr, a->addrlen);
log_name_addr(VERB_QUERY, "NAT64 apply: to: ",
name, &real_addr, real_addrlen);
a->addr = real_addr;
a->addrlen = real_addrlen;
}
/* check lameness - need zone , class info */
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
name, namelen, qtype, &lame, &dnsseclame, &reclame,
@@ -1511,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);
+1
View File
@@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
/**
* Select a valid, nice target to send query to.
* Sorting and removing unsuitable targets is combined.
* Adds records to the infra cache if not already there.
*
* @param iter_env: iterator module global state, with ip6 enabled and
* do-not-query-addresses.
+18 -19
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) {
@@ -2436,8 +2437,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int tf_policy;
struct delegpt_addr* target;
struct outbound_entry* outq;
struct sockaddr_storage real_addr;
socklen_t real_addrlen;
int auth_fallback = 0;
uint8_t* qout_orig = NULL;
size_t qout_orig_len = 0;
@@ -3060,17 +3059,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dnssec_lame_query?" but lame_query anyway": "");
}
real_addr = target->addr;
real_addrlen = target->addrlen;
if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
&real_addr, &real_addrlen);
log_name_addr(VERB_QUERY, "applied NAT64:",
iq->dp->name, &real_addr, real_addrlen);
}
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
@@ -3082,7 +3070,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen,
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
@@ -3099,7 +3087,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
log_addr(VERB_QUERY, "error sending query to auth server",
&real_addr, real_addrlen);
&target->addr, target->addrlen);
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = SKIP_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE);
@@ -3236,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;
@@ -3616,7 +3615,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, INIT_REQUEST_STATE);
} else if(type == RESPONSE_TYPE_LAME) {
/* Cache the LAMEness. */
verbose(VERB_DETAIL, "query response was %sLAME",
verbose(VERB_DETAIL, "query response was categorized as %sLAME",
dnsseclame?"DNSSEC ":"");
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
log_err("mark lame: mismatch in qname and dpname");
@@ -3655,7 +3654,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* In this case, the event is just sent directly back to
* the QUERYTARGETS_STATE without resetting anything,
* because, clearly, the next target must be tried. */
verbose(VERB_DETAIL, "query response was THROWAWAY");
verbose(VERB_DETAIL, "query response was categorized as THROWAWAY");
} else {
log_warn("A query response came back with an unknown type: %d",
(int)type);
+4
View File
@@ -853,6 +853,8 @@ struct ub_server_stats {
long long qquic;
/** number of queries removed due to discard-timeout */
long long num_queries_discard_timeout;
/** number of queries removed due to replyaddr limit */
long long num_queries_replyaddr_limit;
/** number of queries removed due to wait-limit */
long long num_queries_wait_limit;
/** number of dns error reports generated */
@@ -872,6 +874,8 @@ struct ub_stats_info {
long long mesh_num_states;
/** mesh stats: current number of reply (user) states */
long long mesh_num_reply_states;
/** mesh stats: current number of reply entries */
long long mesh_num_reply_addrs;
/** mesh stats: number of reply states overwritten with a new one */
long long mesh_jostled;
/** mesh stats: number of incoming queries dropped */
+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) {
+85 -22
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;
@@ -3990,6 +4015,22 @@ auth_master_copy(struct auth_master* o)
return m;
}
/** append the master to the copied list. */
static int
auth_master_copy_and_append(struct auth_master* p, struct auth_master** list,
struct auth_master** last)
{
struct auth_master* m = auth_master_copy(p);
if(!m) {
return 0;
}
m->next = NULL;
if(*last) (*last)->next = m;
if(!*list) *list = m;
*last = m;
return 1;
}
/** copy the master addresses from the task_probe lookups to the allow_notify
* list of masters */
static void
@@ -3998,17 +4039,27 @@ probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
struct auth_master* list = NULL, *last = NULL;
struct auth_master* p;
/* build up new list with copies */
for(p = xfr->task_transfer->masters; p; p=p->next) {
struct auth_master* m = auth_master_copy(p);
if(!m) {
/* The list in task probe has been looked up before the list in
* task transfer. */
for(p = xfr->task_probe->masters; p; p=p->next) {
if(!auth_master_copy_and_append(p, &list, &last)) {
auth_free_masters(list);
/* failed because of malloc failure, use old list */
return;
}
}
/* The list in task transfer also contains the http entries. */
for(p = xfr->task_transfer->masters; p; p=p->next) {
/* Copy the http entries from this lookup. The allow_notify
* entries are not looked up from this list. The other
* ones are already in from the probe lookups. */
if(!p->http)
continue;
if(!auth_master_copy_and_append(p, &list, &last)) {
auth_free_masters(list);
/* failed because of malloc failure, use old list */
return;
}
m->next = NULL;
if(last) last->next = m;
if(!list) list = m;
last = m;
}
/* success, replace list */
auth_free_masters(xfr->allow_notify_list);
@@ -6669,6 +6720,18 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
return 1;
}
/** return true if there are probe (SOA UDP query) targets in the master list*/
static int
have_probe_targets(struct auth_master* list)
{
struct auth_master* p;
for(p=list; p; p = p->next) {
if(!p->allow_notify && p->host)
return 1;
}
return 0;
}
/** move to sending the probe packets, next if fails. task_probe */
static void
xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
@@ -6708,6 +6771,16 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
}
xfr_probe_disown(xfr);
if(!have_probe_targets(xfr->task_probe->masters)) {
/* If there are no masters to probe, go to transfer. */
if(xfr->task_transfer->worker == NULL) {
xfr_start_transfer(xfr, env, NULL);
return;
}
/* The transfer is already in progress. */
lock_basic_unlock(&xfr->lock);
return;
}
if(xfr->task_nextprobe->worker == NULL)
xfr_set_timeout(xfr, env, 0, 0);
lock_basic_unlock(&xfr->lock);
@@ -6864,18 +6937,6 @@ auth_xfer_timer(void* arg)
}
}
/** return true if there are probe (SOA UDP query) targets in the master list*/
static int
have_probe_targets(struct auth_master* list)
{
struct auth_master* p;
for(p=list; p; p = p->next) {
if(!p->allow_notify && p->host)
return 1;
}
return 0;
}
/** start task_probe if possible, if no masters for probe start task_transfer
* returns true if task has been started, and false if the task is already
* in progress. */
@@ -6887,7 +6948,9 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
* progress (due to notify)) */
if(xfr->task_probe->worker == NULL) {
if(!have_probe_targets(xfr->task_probe->masters) &&
!(xfr->task_probe->only_lookup &&
xfr->task_probe->masters != NULL)
xfr->task_probe->only_lookup = 1;
if(!(xfr->task_probe->only_lookup &&
xfr->task_probe->masters != NULL)) {
/* useless to pick up task_probe, no masters to
* probe. Instead attempt to pick up task transfer */
+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;
}
+15 -21
View File
@@ -1564,7 +1564,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
cp = comm_point_create_udp(base, ports->fd,
front->udp_buff, ports->pp2_enabled, cb,
cb_arg, ports->socket);
} else if(ports->ftype == listen_type_doq) {
} else if(ports->ftype == listen_type_doq && doq_table) {
#ifndef HAVE_NGTCP2
log_warn("Unbound is not compiled with "
"ngtcp2. This is required to use DNS "
@@ -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
@@ -2884,6 +2871,7 @@ submit_http_error:
sldns_buffer_flip(h2_stream->qbuffer);
h2_session->postpone_drop = 1;
query_read_done = http2_query_read_done(h2_session, h2_stream);
h2_session->postpone_drop = 0;
if(query_read_done < 0)
return NGHTTP2_ERR_CALLBACK_FAILURE;
else if(!query_read_done) {
@@ -2893,11 +2881,9 @@ submit_http_error:
* failure will result in reclaiming (and closing)
* of comm point. */
verbose(VERB_QUERY, "http2 query dropped in worker cb");
h2_session->postpone_drop = 0;
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
/* nothing to submit right now, query added to mesh. */
h2_session->postpone_drop = 0;
return 0;
}
if(!http2_submit_dns_response(h2_session)) {
@@ -3275,14 +3261,18 @@ nghttp2_session_callbacks* http2_req_callbacks_create(void)
struct doq_table*
doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
{
struct doq_table* table = calloc(1, sizeof(*table));
struct doq_table* table;
if (!cfg->quic_port)
return NULL;
table = calloc(1, sizeof(*table));
if(!table)
return NULL;
#ifdef USE_NGTCP2_CRYPTO_OSSL
/* Initialize the ossl crypto, it is harmless to call twice,
* and this is before use of doq connections. */
if(ngtcp2_crypto_ossl_init() != 0) {
log_err("ngtcp2_crypto_oss_init failed");
log_err("ngtcp2_crypto_ossl_init failed");
free(table);
return NULL;
}
@@ -3354,7 +3344,7 @@ conn_tree_del(rbnode_type* node, void* arg)
{
struct doq_table* table = (struct doq_table*)arg;
struct doq_conn* conn;
if(!node)
if(!node || !table)
return;
conn = (struct doq_conn*)node->key;
if(conn->timer.timer_in_list) {
@@ -3413,6 +3403,7 @@ doq_timer_find_time(struct doq_table* table, struct timeval* tv)
{
struct doq_timer key;
struct rbnode_type* node;
log_assert(table != NULL);
memset(&key, 0, sizeof(key));
key.time.tv_sec = tv->tv_sec;
key.time.tv_usec = tv->tv_usec;
@@ -4922,6 +4913,7 @@ doq_conid_find(struct doq_table* table, const uint8_t* data, size_t datalen)
key.node.key = &key;
key.cid = (void*)data;
key.cidlen = datalen;
log_assert(table != NULL);
node = rbtree_search(table->conid_tree, &key);
if(node)
return (struct doq_conid*)node->key;
@@ -5662,6 +5654,8 @@ doq_table_quic_size_available(struct doq_table* table,
struct config_file* cfg, size_t mem)
{
size_t cur;
if (!table)
return 0;
lock_basic_lock(&table->size_lock);
cur = table->current_size;
lock_basic_unlock(&table->size_lock);
+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
+24 -3
View File
@@ -231,6 +231,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_replyaddr_limit = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
mesh->max_reply_states = env->cfg->num_queries_per_thread;
@@ -462,6 +463,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
verbose(VERB_ALGO, "Too many queries. dropping "
"incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
comm_point_drop_reply(rep);
mesh->stats_dropped++;
return;
@@ -473,8 +476,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
verbose(VERB_ALGO, "Too many requests queued. "
"dropping incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
comm_point_drop_reply(rep);
mesh->stats_dropped++;
mesh->num_queries_replyaddr_limit++;
return;
}
}
@@ -1031,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 */
@@ -1070,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 */
@@ -1077,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--;
@@ -1765,6 +1777,8 @@ void mesh_query_done(struct mesh_state* mstate)
http2_stream_remove_mesh_state(r->h2_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
mstate->s.env->mesh->num_reply_addrs--;
mstate->s.env->mesh->num_queries_discard_timeout++;
continue;
}
@@ -1801,6 +1815,8 @@ void mesh_query_done(struct mesh_state* mstate)
}
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
mstate->s.env->mesh->num_reply_addrs--;
} else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info) {
@@ -2291,6 +2307,7 @@ mesh_stats_clear(struct mesh_area* mesh)
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
mesh->ans_nodata = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_replyaddr_limit = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
}
@@ -2360,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;
+2
View File
@@ -141,6 +141,8 @@ struct mesh_area {
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
/** stats, number of queries removed due to discard-timeout */
size_t num_queries_discard_timeout;
/** stats, number of queries removed due to replyaddr limit */
size_t num_queries_replyaddr_limit;
/** stats, number of queries removed due to wait-limit */
size_t num_queries_wait_limit;
/** stats, number of dns error reports generated */
+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);
+7
View File
@@ -48,6 +48,10 @@
#include "util/regional.h"
#include "util/netevent.h"
#include "dnstap/dnstap_config.h"
#ifdef __QNX__
/* For struct timeval */
#include <sys/time.h>
#endif /* __QNX__ */
struct pending;
struct pending_timeout;
struct ub_randstate;
@@ -260,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:
+1
View File
@@ -486,6 +486,7 @@ enum sldns_enum_ede_code
typedef enum sldns_enum_ede_code sldns_ede_code;
#define LDNS_EDNS_MASK_DO_BIT 0x8000
#define LDNS_EDNS_MASK_CO_BIT 0x4000
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
#define LDNS_TSIG_ERROR_NOERROR 0
+2
View File
@@ -2486,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
w += sldns_str_print(str, str_len, " flags:");
if((edns_bits & LDNS_EDNS_MASK_DO_BIT))
w += sldns_str_print(str, str_len, " do");
if((edns_bits & LDNS_EDNS_MASK_CO_BIT))
w += sldns_str_print(str, str_len, " co");
/* the extended rcode is the value set, shifted four bits,
* and or'd with the original rcode */
if(ext_rcode) {
+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))
+13 -2
View File
@@ -236,6 +236,8 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
s->svr.num_queries_cookie_invalid);
PR_UL_NM("num.queries_discard_timeout",
s->svr.num_queries_discard_timeout);
PR_UL_NM("num.queries_replyaddr_limit",
s->svr.num_queries_replyaddr_limit);
PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit);
PR_UL_NM("num.cachehits",
s->svr.num_queries - s->svr.num_queries_missed_cache);
@@ -263,6 +265,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
PR_UL_NM("requestlist.exceeded", s->mesh_dropped);
PR_UL_NM("requestlist.current.all", s->mesh_num_states);
PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states);
PR_UL_NM("requestlist.current.replies", s->mesh_num_reply_addrs);
#ifndef S_SPLINT_S
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
@@ -1049,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);
+1 -1
View File
@@ -2255,7 +2255,7 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
/* Initialize the ossl crypto, it is harmless to call twice,
* and this is before use of doq connections. */
if(ngtcp2_crypto_ossl_init() != 0)
fatal_exit("ngtcp2_crypto_oss_init failed");
fatal_exit("ngtcp2_crypto_ossl_init failed");
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
if(ngtcp2_crypto_quictls_init() != 0)
fatal_exit("ngtcp2_crypto_quictls_init failed");
+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"
+31 -6
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') {
@@ -222,7 +237,8 @@ read_http_headers(SSL* ssl, char* file, size_t flen, char* host, size_t hlen,
if(verb>=2) printf("read: %s\n", buf);
if(buf[0] == 0) {
int e = ERR_peek_error();
printf("error string: %s\n", ERR_reason_error_string(e));
if(e)
printf("error string: %s\n", ERR_reason_error_string(e));
return 1;
}
if(!process_one_header(buf, file, flen, host, hlen, vs))
@@ -246,7 +262,8 @@ setup_ctx(char* key, char* cert)
#endif
if(!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
int e = ERR_peek_error();
printf("error string: %s\n", ERR_reason_error_string(e));
if(e)
printf("error string: %s\n", ERR_reason_error_string(e));
print_exit("cannot read cert");
}
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
@@ -673,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);
+4
View File
@@ -142,6 +142,10 @@
#include "util/netevent.h"
#include "testcode/testpkts.h"
#include "util/rbtree.h"
#ifdef __QNX__
/* For struct timeval */
#include <sys/time.h>
#endif /* __QNX__ */
struct replay_answer;
struct replay_moment;
struct replay_range;
+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);
+41 -9
View File
@@ -135,6 +135,8 @@ static void matchline(char* line, struct entry* e)
e->match_ttl = 1;
} else if(str_keyword(&parse, "DO")) {
e->match_do = 1;
} else if(str_keyword(&parse, "CO")) {
e->match_co = 1;
} else if(str_keyword(&parse, "noedns")) {
e->match_noedns = 1;
} else if(str_keyword(&parse, "ednsdata")) {
@@ -178,7 +180,7 @@ static void matchline(char* line, struct entry* e)
/** parse REPLY line */
static void replyline(char* line, uint8_t* reply, size_t reply_len,
int* do_flag)
int* do_flag, int* co_flag)
{
char* parse = line;
if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
@@ -236,6 +238,8 @@ static void replyline(char* line, uint8_t* reply, size_t reply_len,
LDNS_AD_SET(reply);
} else if(str_keyword(&parse, "DO")) {
*do_flag = 1;
} else if(str_keyword(&parse, "CO")) {
*co_flag = 1;
} else {
error("could not parse REPLY: '%s'", parse);
}
@@ -289,6 +293,7 @@ static struct entry* new_entry(void)
e->match_all_noedns = 0;
e->match_ttl = 0;
e->match_do = 0;
e->match_co = 0;
e->match_noedns = 0;
e->match_serial = 0;
e->ixfr_soa_serial = 0;
@@ -521,15 +526,17 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
/* add EDNS 4096 opt record */
static void
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
uint16_t ednslen, size_t* pktlen)
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, int co_flag,
uint8_t *ednsdata, uint16_t ednslen, size_t* pktlen)
{
uint8_t edns[] = {0x00, /* root label */
0x00, LDNS_RR_TYPE_OPT, /* type */
0x04, 0xD0, /* class is UDPSIZE 1232 */
0x00, /* TTL[0] is ext rcode */
0x00, /* TTL[1] is edns version */
(uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
(uint8_t)(do_flag?0x80:0x00)
| (uint8_t)(co_flag?0x40:0x00)
, 0x00, /* TTL[2-3] is edns flags, DO */
(uint8_t)((ednslen >> 8) & 0xff),
(uint8_t)(ednslen & 0xff), /* rdatalength */
};
@@ -561,6 +568,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
uint8_t pktbuf[MAX_PACKETLEN];
size_t pktlen = LDNS_HEADER_SIZE;
int do_flag = 0; /* DO flag in EDNS */
int co_flag = 0; /* CO flag in EDNS */
memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
while(fgets(line, (int)sizeof(line), in) != NULL) {
@@ -598,7 +606,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
if(str_keyword(&parse, "MATCH")) {
matchline(parse, current);
} else if(str_keyword(&parse, "REPLY")) {
replyline(parse, pktbuf, pktlen, &do_flag);
replyline(parse, pktbuf, pktlen, &do_flag, &co_flag);
} else if(str_keyword(&parse, "ADJUST")) {
adjustline(parse, current, cur_reply);
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
@@ -654,15 +662,16 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
if(hex_ednsdata_buffer)
sldns_buffer_free(hex_ednsdata_buffer);
if(pktlen != 0) {
if(do_flag || cur_reply->raw_ednsdata) {
if(do_flag || co_flag
|| cur_reply->raw_ednsdata) {
if(cur_reply->raw_ednsdata &&
sldns_buffer_limit(cur_reply->raw_ednsdata))
add_edns(pktbuf, sizeof(pktbuf), do_flag,
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
sldns_buffer_begin(cur_reply->raw_ednsdata),
(uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
&pktlen);
else
add_edns(pktbuf, sizeof(pktbuf), do_flag,
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
NULL, 0, &pktlen);
}
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
@@ -909,6 +918,22 @@ get_do_flag(uint8_t* pkt, size_t len)
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
}
/** return true if the CO flag is set */
static int
get_co_flag(uint8_t* pkt, size_t len)
{
uint16_t edns_bits;
uint8_t* walk = pkt;
size_t walk_len = len;
if(!pkt_find_edns_opt(&walk, &walk_len)) {
return 0;
}
if(walk_len < 6)
return 0; /* malformed */
edns_bits = sldns_read_uint16(walk+4);
return (int)(edns_bits&LDNS_EDNS_MASK_CO_BIT);
}
/** Snips the specified EDNS option out of the OPT record and puts it in the
* provided buffer. The buffer should be able to hold any opt data ie 65535.
* Returns the length of the option written,
@@ -1654,6 +1679,10 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
verbose(3, "no DO bit set\n");
continue;
}
if(p->match_co && !get_co_flag(query_pkt, len)) {
verbose(3, "no CO bit set\n");
continue;
}
if(p->match_noedns && get_has_edns(query_pkt, len)) {
verbose(3, "bad; EDNS OPT present\n");
continue;
@@ -1745,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;
}
+2
View File
@@ -218,6 +218,8 @@ struct entry {
uint8_t match_ttl;
/** match DO bit */
uint8_t match_do;
/** match CO bit */
uint8_t match_co;
/** match absence of EDNS OPT record in query */
uint8_t match_noedns;
/** match edns data field given in hex */
+4
View File
@@ -207,7 +207,11 @@ rr_test_file(const char* input, const char* check)
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
/** read rrs to and from string, to and from wireformat */
static void
+1 -1
View File
@@ -283,7 +283,7 @@ net_test(void)
unit_assert(strcmp(astr, "1.2.3.0") == 0);
unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
res = netblockstrtoaddr("2001:db8:33:44::/64", 53,
&a, &alen, &net);
unit_assert(res!=0 && net == 64);
addr_to_str(&a, alen, astr, sizeof(astr));
+4
View File
@@ -498,7 +498,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
void msgparse_test(void)
{
+4 -1
View File
@@ -513,8 +513,11 @@ nsec3_hash_test(const char* fname)
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
#if defined(HAVE_SSL) && defined(USE_SHA1)
/* Detect if openssl is configured to disable RSASHA1 signatures,
* with the rh-allow-sha1-signatures disabled. */
+4
View File
@@ -50,7 +50,11 @@
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
/** Add zone from file for testing */
struct auth_zone* authtest_addzone(struct auth_zones* az, const char* name,
+1 -1
View File
@@ -24,7 +24,7 @@ server:
# specify every interface on a new 'interface:' labelled line.
interface: 192.0.2.153
interface: 192.0.2.154
interface: 2001:DB8::5
interface: 2001:db8::5
# port to answer queries from
port: 53
+1 -1
View File
@@ -11,7 +11,7 @@ server:
# specify every interface on a new 'interface:' labelled line.
interface: 192.0.2.153
interface: 192.0.2.154
interface: 2001:DB8::5
interface: 2001:db8::5
interface: 0.0.0.0@5353
# config
+341
View File
@@ -0,0 +1,341 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
access-control: 1.2.3.0/24 allow
auth-zone:
name: "example.com."
## zonefile (or none).
## zonefile: "example.com.zone"
## master by IP address or hostname
## can list multiple masters, each on one line.
## master:
master: 1.2.3.44
## this is as a hostname, to test the hostname lookup.
allow-notify: svr.example.org
## url for http fetch
## url:
## queries from downstream clients get authoritative answers.
## for-downstream: yes
for-downstream: yes
## queries are used to fetch authoritative answers from this zone,
## instead of unbound itself sending queries there.
## for-upstream: yes
for-upstream: yes
## on failures with for-upstream, fallback to sending queries to
## the authority servers
## fallback-enabled: no
## this line generates zonefile: \n"/tmp/xxx.example.com"\n
zonefile:
TEMPFILE_NAME example.com
## this is the inline file /tmp/xxx.example.com
## the tempfiles are deleted when the testrun is over.
TEMPFILE_CONTENTS example.com
example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test authority zone with lookup for a NOTIFY
; The allow-notify is specified as a hostname.
; 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
org. IN NS
SECTION AUTHORITY
org. IN NS ns.org.
SECTION ADDITIONAL
ns.org. IN A 1.2.3.45
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.44
ENTRY_END
RANGE_END
; ns.org
RANGE_BEGIN 0 100
ADDRESS 1.2.3.45
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
org. IN NS
SECTION ANSWER
org. IN NS ns.org.
SECTION ADDITIONAL
ns.org. IN A 1.2.3.45
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.org. IN NS
SECTION AUTHORITY
example.org. IN NS ns.example.org.
SECTION ADDITIONAL
ns.example.org. IN A 1.2.3.46
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
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.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
www.example.net. IN A 1.2.3.44
ENTRY_END
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.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN SOA
SECTION ANSWER
; serial, refresh, retry, expire, minimum
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOTIMPL
SECTION QUESTION
example.com. IN IXFR
SECTION ANSWER
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN AXFR
SECTION ANSWER
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
example.com. IN NS ns.example.net.
EXTRA_PACKET
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN AXFR
SECTION ANSWER
www.example.com. IN A 1.2.3.4
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
ENTRY_END
RANGE_END
; ns.example.org.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.46
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.org. IN NS
SECTION ANSWER
example.org. IN NS ns.example.org.
SECTION ADDITIONAL
ns.example.org. IN A 1.2.3.46
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
svr.example.org. IN A
SECTION ANSWER
svr.example.org. IN A 1.2.3.47
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
svr.example.org. IN AAAA
SECTION AUTHORITY
example.org. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
ENTRY_END
RANGE_END
; lookups for notify hostnames.
STEP 1 TIME_PASSES ELAPSE 0
; now the query
STEP 2 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
ENTRY_END
; NOTIFY example.com
STEP 30 QUERY ADDRESS 1.2.3.47
ENTRY_BEGIN
REPLY NOTIFY
SECTION QUESTION
example.com. IN SOA
ENTRY_END
; notify reply
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOTIFY NOERROR
SECTION QUESTION
example.com. IN SOA
SECTION ANSWER
ENTRY_END
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 60 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 1.2.3.4
ENTRY_END
; the zonefile was updated with new contents
STEP 70 CHECK_TEMPFILE example.com
FILE_BEGIN
example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
example.com. 3600 IN NS ns.example.net.
www.example.com. 3600 IN A 1.2.3.4
FILE_END
SCENARIO_END
+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
+107
View File
@@ -16,6 +16,7 @@ SCENARIO_BEGIN Test iterator with scrub of promiscuous records
; The spoofed contents are ns.attacker.mesa and its IPs 5.6.7.8 and 5.6.7.9.
; The pollute1.mesa NS, ns.pollute2.mesa A, and test3.atkr.pollute3.mesa NS
; with ns.pollute3.mesa A records are tested for cache placement.
; pollute4.mesa uses YXDOMAIN.
; ns.root
RANGE_BEGIN 0 400
@@ -84,6 +85,18 @@ SECTION ADDITIONAL
ns.pollute3.mesa. IN A 1.2.4.3
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
pollute4.mesa. IN NS
SECTION AUTHORITY
pollute4.mesa. IN NS ns.pollute4.mesa.
SECTION ADDITIONAL
ns.pollute4.mesa. IN A 1.2.4.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
@@ -188,6 +201,54 @@ check.pollute3.mesa. IN A 1.8.9.3
ENTRY_END
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
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA YXDOMAIN
SECTION QUESTION
test4.atkr.pollute4.mesa. IN A
SECTION ANSWER
test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4
SECTION AUTHORITY
pollute4.mesa. 86400 IN NS ns.attacker.mesa.
ENTRY_END
; correct answer for the check query.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
check.pollute4.mesa. IN A
SECTION ANSWER
check.pollute4.mesa. IN A 1.8.9.4
ENTRY_END
RANGE_END
; ns.attacker.mesa
RANGE_BEGIN 0 400
ADDRESS 5.6.7.8
@@ -370,4 +431,50 @@ check.pollute3.mesa. IN A 1.8.9.3
;check.pollute3.mesa. IN A 5.6.7.9
ENTRY_END
; Test query 4
STEP 120 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
test4.atkr.pollute4.mesa. IN A
ENTRY_END
STEP 130 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
test4.atkr.pollute4.mesa. IN A
; 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.
STEP 140 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
check.pollute4.mesa. IN A
ENTRY_END
STEP 150 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
check.pollute4.mesa. IN A
SECTION ANSWER
; good answer
check.pollute4.mesa. IN A 1.8.9.4
; bad answer
;check.pollute4.mesa. IN A 5.6.7.9
ENTRY_END
SCENARIO_END
+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
+24 -6
View File
@@ -3,13 +3,31 @@ $ORIGIN example.com.
$TTL 3600
ENTRY_BEGIN
MATCH opcode qtype
MATCH opcode qname qtype
REPLY QR AA NOERROR
ADJUST copy_id copy_query
ADJUST copy_id
SECTION QUESTION
wild IN A
www1 IN A
SECTION ANSWER
wild IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
www1 IN A 1.1.1.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www2 IN A
SECTION ANSWER
www2 IN A 2.2.2.2
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www3 IN A
SECTION ANSWER
www3 IN A 3.3.3.3
ENTRY_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
+4 -2
View File
@@ -468,8 +468,10 @@ bring_up_alternate_configuration ub_discard_wait_limit.conf
teststep "Check discard-timeout and wait-limit"
echo "> dig www.unresponsive"
dig @127.0.0.1 -p $UNBOUND_PORT +retry=2 +timeout=1 www.unresponsive. | tee outfile
echo "> check answer"
if grep "no servers could be reached" outfile; then
# Wait for nonresponse servfail, that causes discards.
sleep 2
if grep "no servers could be reached" outfile ||
grep "Too many queries queued up and waiting" outfile; then
echo "OK"
else
end 1
+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

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