Compare commits

..
Author SHA1 Message Date
Willem Toorop c834ee635c Fix function signature for compiling test 2025-11-03 11:15:11 +01:00
Willem Toorop 7977ef28f5 distribute can send out responses tsig signed 2025-11-01 14:32:09 +01:00
Willem Toorop c86c267b8b Forgot to include util/allow_response_list.[ch] 2025-11-01 13:12:35 +01:00
Willem Toorop 3963af8d0b configurable ranges and tsig to allow responses
Configurable with the "allow-response:" option in the "server:" section.
Usage:
	allow-response: <IP netblock> <tsig key-name | NOKEY | BLOCKED>
2025-11-01 12:52:48 +01:00
Willem Toorop 3d6a4c7d6e Const string for tsig lookups 2025-10-31 15:45:34 +01:00
Willem Toorop 2217c9b96e Merge branch 'master' into update-with-branches/poisonlicious 2025-10-30 09:48:57 +01:00
Willem Toorop 6592c73d56 Merge branch 'xfr-tsig' into update-with-branches/poisonlicious 2025-10-30 09:45:11 +01:00
Yorgos Thessalonikefs 1a808e2978 - Fix typo; spotted by T3rm1. 2025-10-28 14:42:20 +01:00
Yorgos Thessalonikefs 56ded934de - Fix #1165, document the possible circular dependency when using
host names instead of IP addresses for name servers in stub/forward
  zones and log a warning when spotted in the configuration.
2025-10-27 14:01:10 +01:00
Yorgos Thessalonikefs 98952f11d1 Changelog entry for #1331:
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
  new $action, for SWIG.
2025-10-27 09:59:35 +01:00
Yorgos ThessalonikefsandGitHub cb4b3de62f Merge pull request #1331 from jplesnik/master
Replace deprecated $function by new $action
2025-10-27 09:57:59 +01:00
Yorgos Thessalonikefs c8dcfc0853 - For #1364, use OPENSSL_VERSION_TEXT instead of OPENSSL_VERSION_NUMBER
for part of the configure script. OPENSSL_VERSION_TEXT is more
  consistent across versions.
2025-10-24 15:43:22 +02:00
Yorgos Thessalonikefs 2bb28fdf12 - Fix unused attribute warning in redis.c when threads are not
supported.
2025-10-24 14:44:58 +02:00
Yorgos Thessalonikefs 6ad26909dd - Note Havard Eidnes for his suggestions on the mailing list. 2025-10-24 14:26:08 +02:00
Yorgos Thessalonikefs 9602973c86 - unbound.conf man page updates to include a preview of the section
clauses and some reformatting around the use of "clause", "option"
  and "attributes".
2025-10-24 14:23:53 +02:00
Yorgos Thessalonikefs 713b1783d4 - Tag for 1.24.1 release.
The repository continues with version 1.24.2.
2025-10-22 12:49:29 +02:00
Yorgos Thessalonikefs e06b7eb3f1 Merge branch 'branch-1.24.1' 2025-10-22 12:44:59 +02:00
Yorgos Thessalonikefs a33f0638e1 - Fix CVE-2025-11411 (possible domain hijacking attack), reported by Yuxiao Wu,
Yunyi Zhang, Baojun Liu and Haixin Duan from Tsinghua University.
2025-10-22 10:54:57 +02:00
Yorgos Thessalonikefs bbeee42e25 - Set version to 1.24.1. 2025-10-22 10:50:18 +02:00
Yorgos Thessalonikefs 1cb9595a42 - Update the unbound.conf online man page link and some text
reformatting in README.md.
2025-10-20 14:34:40 +02:00
Wouter WijngaardsandGitHub aa21e38b3a Fix for analysis and ports workflows iOS, Windows (#1361)
* - Remove SDK_VERSION and only run failed jobs, echo windows config.log

* Use commented out to fix syntax of ci.

* - Turn off succeeded tests, only link libssp for cross compile, use
no-shared for openssl ios.

* - Remove iPhone armv7s, and iPhoneSimulator i386 from ios ci.
  The lib system does not provide symbols for it on the new macos
  runner.
- Fix to exclude libssp for windows compiles.
2025-10-15 16:12:39 +02:00
W.C.A. Wijngaards 964848b94a - Fix unbound.conf man page entry for root-hints to say it can
be used without strongly recommending it.
2025-10-15 15:40:47 +02:00
Yorgos Thessalonikefs a4dd321fd8 - Remove extra gpg instructions from makedist.sh output. 2025-10-15 14:59:48 +02:00
Yorgos Thessalonikefs d23a28a693 - ci: don't fail fast for the analysis_port workflow. 2025-10-15 14:10:20 +02:00
W.C.A. Wijngaards 5423c0a8e9 Update ios ci with older sdk version to use. 2025-10-15 13:41:36 +02:00
W.C.A. Wijngaards 6a5385f291 - Fix to update openssl version in ios ci. 2025-10-15 12:25:44 +02:00
W.C.A. Wijngaards 16f3478048 - Add extended dns error code for invalid query type to definition
list.
2025-10-15 11:39:58 +02:00
W.C.A. Wijngaards c8860a5fb6 - Fix to reply with SERVFAIL when the wait-limit is exceeded. 2025-10-15 11:36:29 +02:00
W.C.A. Wijngaards 735c96aac7 - Fix to drop UDP for discard-timeout, but not stream connections. 2025-10-15 11:04:22 +02:00
W.C.A. Wijngaards a75ea01a15 - Fix #1358 Enabling FIPS in OpenSSL causes unit test to fail. 2025-10-10 09:17:08 +02:00
Yorgos Thessalonikefs 21f02a0865 - Note clearly that 'wait-limit: 0' disables all wait limits.
- 'wait-limit-cookie: 0' can now disable cookie validated wait
  limits.
2025-10-03 16:44:44 +02:00
Yorgos Thessalonikefs e017d66fc1 - Note 'respip' and 'dns64' module order in the unbound.conf
man page.
2025-10-03 11:27:26 +02:00
W.C.A. Wijngaards adaf5dab49 - Fix that https is set up as enabled when the port is listed in
interface-automatic-ports. Also for the set up of quic it is
  enabled when listed there.
2025-10-02 10:16:06 +02:00
W.C.A. Wijngaards 8687d69131 Merge branch 'master' into xfr-tsig 2025-10-01 15:52:40 +02:00
W.C.A. Wijngaards c622a71a28 - xfr-tsig, flip buffer after tsig_sign_reply, but not for error_encode. 2025-10-01 15:52:15 +02:00
W.C.A. Wijngaards feeebc95f8 - Fix for #1344: Fix that respip and dns64 can be enabled at the
same time, the client info is copied for attach_sub and add_sub
  calls. That makes respip work on dns64 synthesized answers, and
  also makes RPZ work with DNS64. The order for the modules is
  module-config: "respip dns64 validator iterator".
2025-09-30 11:28:15 +02:00
W.C.A. Wijngaards 187aa52859 - Fix #1344: module conf 'respip dns64 validator cachedb iterator'
is not known to work.
2025-09-29 16:11:50 +02:00
W.C.A. Wijngaards f1fea8dc46 - Fix #1353: auth-zone can not use empty label for $ORIGIN when
http download.
2025-09-29 14:24:31 +02:00
Yorgos Thessalonikefs 0c01257d1d Changelog entry for #1351:
- Merge #1351: ac_cv_func_malloc_0_nonnull for malloc(0) check.
2025-09-29 13:14:07 +02:00
W.C.A. Wijngaards 50a11ebcc8 - Rebuild configure script from its sources. 2025-09-29 13:13:15 +02:00
Yorgos ThessalonikefsandGitHub 1e2dc657a1 ac_cv_func_malloc_0_nonnull for malloc(0) check (#1351)
- For #1339, use the standard variable ac_cv_func_malloc_0_nonnull for
  the malloc(0) check during configure; patch from Helmut Grohne.
2025-09-29 13:12:27 +02:00
Yorgos Thessalonikefs 843124852f Changelog entry for #1349:
- Merge #1349: Fix #1346: [FR] Please allow back TLS 1.2.
2025-09-29 12:10:34 +02:00
W.C.A. Wijngaards 5e2fdff8e5 - Fix fr_atomic_copy_cfg. 2025-09-29 12:08:30 +02:00
499a3a7a61 Fix #1346: [FR] Please allow back TLS 1.2. (#1349)
* 'tls-use-system-policy-versions' is introduced to allow Unbound to use
  any system available TLS version when serving TLS.

* Apply suggestions from code review

---------

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2025-09-29 12:03:56 +02:00
W.C.A. Wijngaards 2024c1d050 - Neaten up the change in acx_nlnetlabs.m4 to version 49. 2025-09-29 11:40:14 +02:00
W.C.A. Wijngaards 6cd595a816 - Fix modstack_call_init to use the original string when it has
changed, to call modstack_config with. And skip the changed name
  in the string correctly. Thanks to Jan Komissar.
2025-09-29 11:31:50 +02:00
W.C.A. Wijngaards 74cf81e9a7 - Rebuild configure script from its sources. 2025-09-29 10:02:54 +02:00
Yorgos Thessalonikefs 35f6fd47fb - Test for nonstring attribute in configure and add
nonstring attribute annotations.
2025-09-26 16:23:55 +02:00
Alex BandandGitHub 270e099aab Update Mastodon shield 2025-09-25 21:39:39 +02:00
Yorgos Thessalonikefs 64645e1401 - Avoid calling mesh_detect_cycle_found() when there is no mesh state
to begin with.
2025-09-24 14:30:24 +02:00
Yorgos Thessalonikefs 421d317a64 - For #1350, same CAP_NET_ADMIN change for unbound_portable.service.in
as well.
2025-09-23 17:42:41 +02:00
Yorgos Thessalonikefs 0b8ed987de Changelog entry for #1350:
- Merge #1350 from Maryse47: unbound.service.in: allow CAP_NET_ADMIN.
2025-09-23 17:37:59 +02:00
Yorgos ThessalonikefsandGitHub 9511797487 Merge pull request #1350 from Maryse47/patch-1
unbound.service.in: allow CAP_NET_ADMIN and drop CAP_NET_RAW (redundant now).
2025-09-23 17:37:09 +02:00
Yorgos Thessalonikefs 0b7bb75152 - For #1352, align with the current Python<3 code. 2025-09-23 17:31:55 +02:00
Yorgos Thessalonikefs 88c688ec10 Changelog entry for #1352:
- Merge #1352 from Petr Vaganov: pythonmod: fix HANDLE_LEAK on
  pythonmod_init.
2025-09-23 17:15:16 +02:00
Maryse47andGitHub 81fd1dc71c unbound.service.in: drop CAP_NET_RAW
CAP_NET_RAW is unnecessary after CAP_NET_ADMIN was added
2025-09-23 17:13:31 +02:00
Yorgos ThessalonikefsandGitHub 69217cf675 Merge pull request #1352 from petrvaganoff/dev-52227
pythonmod: fix HANDLE_LEAK on pythonmod_init
2025-09-23 17:13:30 +02:00
Petr Vaganov 7c28f1b99c pythonmod: fix HANDLE_LEAK on pythonmod_init
Found by the static analyzer Svace (ISP RAS).

Handle 'script_py' is created at pythonmod.c:436
by calling function 'fopen' and lost at pythonmod.c:457,465.

Signed-off-by: Petr Vaganov <petrvaganoff@gmail.com>
2025-09-23 19:51:46 +05:00
Maryse47andGitHub fa6340cfa5 unbound.service.in: allow CAP_NET_ADMIN
Allowing CAP_NET_ADMIN is necessary for SO_SNDBUFFORCE and SO_RCVBUFFORCE calls.
2025-09-23 13:00:50 +02:00
Yorgos Thessalonikefs e471e15774 - unbound.conf manpage: explicitly mention RFC6891. 2025-09-19 15:49:07 +02:00
Yorgos Thessalonikefs ec3db03121 Changelog entry for #1337:
- Merge #1337: 0 TTL cached replies and some TTL behavior changes.
2025-09-19 15:01:30 +02:00
Yorgos Thessalonikefs e2bf773089 Merge branch 'features/no-ttl-zero-cacherep' 2025-09-19 14:56:04 +02:00
Yorgos Thessalonikefs 3017a0aa52 - Update README.man with clearer text. 2025-09-19 10:03:10 +02:00
W.C.A. Wijngaards 8419e9780e - Fix to remove configure~ from release tarballs. 2025-09-19 09:46:34 +02:00
W.C.A. Wijngaards c429c4ab96 - Tag for 1.24.0 release. Includes the fixes below after rc1.
The repository continues with version 1.24.1.
2025-09-18 10:57:37 +02:00
bc61034f60 code review: use proper roundrobin index
Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2025-09-17 12:19:20 +02:00
Yorgos Thessalonikefs 2dd821c257 - Too many quotes for the EDE message debug printout. 2025-09-17 11:27:16 +02:00
W.C.A. Wijngaards 713b5db537 - Fix to print warning for when so-sndbuf setsockopt is not granted. 2025-09-15 16:11:27 +02:00
Yorgos Thessalonikefs c3a8d5251f - Small debug output improvement when attaching an EDE. 2025-09-15 12:06:49 +02:00
Yorgos Thessalonikefs 73e408f1d0 A few changes for TTL processing:
- Cached messages that reach 0 TTL are considered expired. This prevents
  Unbound itself from issuing replies with TTL 0 and possibly causing a
  thundering herd at the last second. Upstream replies of TTL 0 still
  get the usual pass-through but they are not considered for caching
  from Unbound or any of its caching modules.
- 'serve-expired-reply-ttl' is changed and is now capped by the original
  TTL value of the record to try and make some sense when replying
  with expired records.
- TTL decoding was updated to adhere to RFC8767 section 4 where a set
  high-order bit means the value is positive instead of 0.
2025-09-15 10:03:35 +02:00
W.C.A. Wijngaards ecfc6a70ce - xfr-tsig, note tsig-key support for fast_reload. 2025-09-12 16:38:09 +02:00
W.C.A. Wijngaards a23c5347a7 - xfr-tsig, unit test shows zonefile that is created. 2025-09-12 15:43:45 +02:00
W.C.A. Wijngaards 1ae8be6847 - xfr-tsig, fast reload support for tsig keys. 2025-09-12 15:38:39 +02:00
Yorgos Thessalonikefs d521135f66 Merge branch 'master' into features/no-ttl-zero-cacherep 2025-09-12 15:24:06 +02:00
W.C.A. Wijngaards f0268d3e83 - xfr-tsig, log TSIG key name with zone and notify information. Clear tsig
data before making a new one.
2025-09-12 14:58:49 +02:00
W.C.A. Wijngaards c904a3d375 - xfr-tsig, remove rpl unit test. 2025-09-12 11:23:29 +02:00
W.C.A. Wijngaards b451cc4af7 - xfr-tsig, add tdir test that performs tsig signed zone transfer. 2025-09-12 10:40:23 +02:00
W.C.A. Wijngaards f9713f9fe5 Merge branch 'master' into xfr-tsig 2025-09-12 09:27:23 +02:00
W.C.A. Wijngaards dfac72edfc - xfr-tsig, unit test use to make tsig for rpl. 2025-09-11 17:05:58 +02:00
W.C.A. Wijngaards 64e102aacb - xfr-tsig, fix notify tsig answer, fix parse edns allows TSIG,
unit test for auth zone with notify with tsig and notify answer with tsig.
2025-09-11 16:21:38 +02:00
W.C.A. Wijngaards d71ead5598 - Update contrib/aaaa-filter-iterator.patch so it applies on 1.24.0. 2025-09-11 13:23:51 +02:00
W.C.A. Wijngaards cdbfadfb7b - version set to 1.24.0 for release.
- tag for 1.24.0rc1.
2025-09-11 09:03:40 +02:00
W.C.A. Wijngaards bebd6c0f96 - xfr-tsig, use tsig_parse_verify_reply_xfr for zone transfers with TSIG. 2025-09-10 15:45:37 +02:00
W.C.A. Wijngaards 63aa70ab32 - xfr-tsig, unit test for tsig sign every couple packets, and verify that. 2025-09-10 15:26:57 +02:00
W.C.A. Wijngaards 7b59014ba3 - xfr-tsig, unit test with another trace of tsig every couple packets. 2025-09-09 16:24:55 +02:00
W.C.A. Wijngaards 156846e6c4 - xfr-tsig, unit test to verify tsig every couple packets. 2025-09-09 15:50:14 +02:00
W.C.A. Wijngaards aea2a821b9 - xfr-tsig, unit test for tsig-verify-reply-xfr, with output that works
with dig and NSD.
2025-09-09 15:40:51 +02:00
W.C.A. Wijngaards cacdfee755 Merge branch 'master' into xfr-tsig 2025-09-09 14:38:03 +02:00
W.C.A. Wijngaards e3c1981a6a - xfr-tsig, fix algorithm name write in xfr reply tsig and unit test
that works with output that works with dig and NSD.
2025-09-09 14:36:33 +02:00
W.C.A. Wijngaards 4267de87b5 - Fix #1332: CNAME chains are sometimes not followed when RPZs add a
local CNAME rewrite.
2025-09-09 12:34:11 +02:00
Yorgos Thessalonikefs dd6200065f - Update man pages. 2025-09-08 14:50:27 +02:00
Yorgos Thessalonikefs a72177e73c - Update documentation for using "SET ... EX" in Redis.
- Document max buffer sizes for Redis commands.
2025-09-08 14:49:12 +02:00
Jitka Plesnikova 1d3d78dff5 Replace deprecated $function by new $action
The long-deprecated $function was removed from future SWIG 4.4.0.
It can be safely replaced by $action.
2025-09-08 10:11:49 +02:00
W.C.A. Wijngaards e2efd17007 - xfr-tsig, unit test tsig-sign-reply-xfr implementation. 2025-09-05 16:45:15 +02:00
W.C.A. Wijngaards 4a2dc1df48 Merge branch 'master' into xfr-tsig 2025-09-05 15:00:31 +02:00
W.C.A. Wijngaards 5c79fd9a0b - xfr-tsig, tsig_parse_verify_reply_xfr and tsig_sign_reply_xfr. 2025-09-05 14:55:36 +02:00
W.C.A. Wijngaards 5588f66bdb - For #1328: make depend. 2025-09-03 14:04:24 +02:00
W.C.A. Wijngaards 85e916e7e0 - Fix indentation in tcp-mss option parsing. 2025-09-02 17:12:14 +02:00
W.C.A. Wijngaards af96824642 - Fix #1324: Memory leak in 'msgparse.c' in
'parse_edns_options_from_query(...)'.
2025-09-02 17:10:42 +02:00
W.C.A. Wijngaards 8faa95354d - Fix #1235: Outdated Python2 code in
unbound/pythonmod/examples/log.py.
2025-09-02 12:54:03 +02:00
W.C.A. Wijngaards c57c39833e - Fix for #1324: Fix to free edns options scratch in ratelimit case. 2025-09-01 09:28:29 +02:00
Yorgos Thessalonikefs 44da5eee66 - Limit the number of consecutive reads on an HTTP/2 session.
Thanks to Gal Bar Nahum for exposing the possibility of infinite
  reads on the session.
2025-08-29 15:35:32 +02:00
W.C.A. Wijngaards 74bc8c9e77 - Fix setup_listen_sslctx warning for nettle compile. 2025-08-28 14:19:52 +02:00
W.C.A. Wijngaards 0c558cb805 - Fix unbound-control dump_cache for double unlock of lruhash table.
Changelog entry.
2025-08-27 16:55:55 +02:00
W.C.A. Wijngaards 533291dce9 - Fix unbound-control dump_cache for double unlock of lruhash table. 2025-08-27 16:55:38 +02:00
W.C.A. Wijngaards 4a3a4f474f Merge branch 'master' into xfr-tsig 2025-08-27 16:30:03 +02:00
W.C.A. Wijngaards 708581579c - xfr-tsig, add test case with AXFR packet with TSIG. 2025-08-27 15:52:08 +02:00
W.C.A. Wijngaards e613e27f35 - Fix ports workflow to install expat for macos. 2025-08-26 14:41:13 +02:00
W.C.A. Wijngaards f2f36a2733 - Fix that the zone acquired timestamp is set after the
zonefile is read.
2025-08-22 14:06:51 +02:00
W.C.A. Wijngaards 78d9bcacb6 - Fix #1319: [FR] zone status for Unbound auth-zones. 2025-08-22 12:40:00 +02:00
W.C.A. Wijngaards c170ed1b30 - Fix sha1 enable environment variable in test code on windows. 2025-08-22 10:04:57 +02:00
W.C.A. Wijngaards ebfa09e04f - For #1318: Fix compile warnings for DoH compile on windows. 2025-08-22 10:04:00 +02:00
W.C.A. Wijngaards 65be1d0ec3 - Fix for #1317: Fix contrib/unbound.service comment path for
systemd network configuration.
2025-08-21 15:49:42 +02:00
W.C.A. Wijngaards ca36e21f71 - Fix #1317: Unbound starts too early. Add
Wants=network-online.target under [Unit] in unbound.service.
2025-08-21 15:14:42 +02:00
W.C.A. Wijngaards 458c793012 - Fix to check for extraneous command arguments for unbound-control,
when the command takes no arguments but there are arguments present.
Changelog note for the fix.
2025-08-21 10:00:41 +02:00
W.C.A. Wijngaards 1341905de8 - Fix to check for extraneous command arguments for unbound-control,
when the command takes no arguments but there are arguments present.
2025-08-21 09:47:24 +02:00
W.C.A. Wijngaards af1d430759 - xfr-tsig, log rcode for received notifies. 2025-08-20 15:55:29 +02:00
W.C.A. Wijngaards da72734240 - xfr-tsig, tsig_get_mem function. 2025-08-19 16:46:12 +02:00
W.C.A. Wijngaards 54175a4180 Merge branch 'master' into xfr-tsig 2025-08-19 15:27:43 +02:00
W.C.A. Wijngaards 888d5ce9f9 - xfr-tsig, TSIG for SOA probe, notify, and on xfr first packet. 2025-08-19 15:27:16 +02:00
W.C.A. Wijngaards 1d877400ea - Fix cache_lookup subnet print to not print messages without rrsets
and perform in-depth check on node in the addrtree.
2025-08-15 16:04:34 +02:00
W.C.A. Wijngaards 8fd4b91afc - Fix cache_lookup subnet print to not print messages without rrsets
and perform in-depth check on node in the addrtree.
2025-08-15 16:04:23 +02:00
W.C.A. Wijngaards 523710f371 - Fix cache_lookup subnet printout to wipe zero part of the prefix.
Changelog entry.
2025-08-15 14:07:05 +02:00
W.C.A. Wijngaards 13bb78a740 - Fix cache_lookup subnet printout to wipe zero part of the prefix. 2025-08-15 14:06:54 +02:00
W.C.A. Wijngaards 1e37f86ef5 - unbound-control cache_lookup +t allows tld and root names. And
subnet cache contents are printed.
Changelog, documentation and unit test.
2025-08-15 13:03:31 +02:00
W.C.A. Wijngaards 81345fe1e3 - unbound-control cache_lookup +t allows tld and root names. And
subnet cache contents are printed.
2025-08-15 13:03:00 +02:00
W.C.A. Wijngaards 40877f46e5 - Fix to decouple file descriptor activity and cache lookups in
dump_cache.
Changelog note.
2025-08-14 12:20:22 +02:00
W.C.A. Wijngaards 991108af8d - Fix to decouple file descriptor activity and cache lookups in
dump_cache.
2025-08-14 12:20:10 +02:00
W.C.A. Wijngaards 4f790bd65e - Fix to increase responsiveness of dump_cache. 2025-08-14 11:25:40 +02:00
W.C.A. Wijngaards d122ae6490 - Fix to unlock cache_lookup message for malformed records. 2025-08-13 12:02:41 +02:00
W.C.A. Wijngaards 651a71fa76 - Fix to remove debug from cache_lookup. 2025-08-13 11:59:53 +02:00
W.C.A. Wijngaards 2f7890eb6e - unbound-control cache_lookup <domains> prints the cached rrsets
and messages for those.
Changelog and information.
2025-08-13 11:36:47 +02:00
W.C.A. Wijngaards fad747308f - unbound-control cache_lookup <domains> prints the cached rrsets
and messages for those.
2025-08-13 11:31:42 +02:00
W.C.A. Wijngaards d55f20fdcc - Fix that unbound-control dump_cache releases the cache locks
every so often, so that the server stays responsive.
Changelog entry for it.
2025-08-12 12:00:01 +02:00
W.C.A. Wijngaards 19b289feec - Fix that unbound-control dump_cache releases the cache locks
every so often, so that the server stays responsive.
2025-08-12 11:59:48 +02:00
W.C.A. Wijngaards 752a3f7f52 - Fix to whitespace in dname_str. 2025-08-07 16:19:10 +02:00
W.C.A. Wijngaards 3ec5d78ac9 - Fix that edns-subnet failure to create a subquery errors as
servfail, and not formerror.
2025-08-07 16:09:47 +02:00
W.C.A. Wijngaards 08d59c9a78 - Fix dname_str for printout of long names. Thanks to Jan Komissar
for the fix.
2025-08-07 09:45:02 +02:00
W.C.A. Wijngaards cdcc0337d1 - Fix edns subnet, so that the subquery without subnet is stored in
global cache if the querier used 0.0.0.0/0 and the name and address
  do not receive subnet treatment. If the name and address are
  configured for subnet, it is stored in the subnet cache.
2025-08-06 12:08:44 +02:00
W.C.A. Wijngaards 305adf12bf - Fix edns subnet, so that the subquery without subnet is stored in
global cache if the querier used 0.0.0.0/0 and the name and address
  do not receive subnet treatment. If the name and address are
  configured for subnet, it is stored in the subnet cache.
2025-08-06 12:01:42 +02:00
W.C.A. Wijngaards 3d7e847a5e - Fix to use assertions for consistency checks in #1309 reclaimed 2025-08-05 16:20:01 +02:00
W.C.A. Wijngaards da6b735ed9 - Fix #1309: incorrectly reclaimed tcp handler can cause data
corruption and segfault.
2025-08-05 15:46:54 +02:00
W.C.A. Wijngaards 5758427d86 - Fix testbound test program to accurately output packets from hex. 2025-08-01 10:34:12 +02:00
W.C.A. Wijngaards b1bb4a4592 - xfr-tsig, check that tsig keys exist at startup and in unbound-checkconf. 2025-07-31 17:02:55 +02:00
W.C.A. Wijngaards 3b88577dd1 Merge branch 'master' into xfr-tsig 2025-07-31 15:59:25 +02:00
W.C.A. Wijngaards 6634b8bcc5 - xfr-tsig, primary-tsig: addr tsig and allow-notify-tsig: addr tsig. 2025-07-31 14:43:43 +02:00
W.C.A. Wijngaards 4f12148af4 - Fix redis cachedb module gettimeofday init failure.
Changelog note for the fix.
2025-07-28 09:33:42 +02:00
W.C.A. Wijngaards f8f4779f1f - Fix redis cachedb module gettimeofday init failure. 2025-07-28 09:32:55 +02:00
W.C.A. Wijngaards da9ab59e10 - Redis checks for server down and throttles reconnects.
And unit test for redis reconnect interval.
2025-07-24 11:06:00 +02:00
W.C.A. Wijngaards 424f86466a - Redis checks for server down and throttles reconnects. 2025-07-24 11:05:25 +02:00
W.C.A. Wijngaards 3d7dfe2f36 - xfr-tsig, unit test for tsig_verify_reply for failed tsig. 2025-07-23 16:35:25 +02:00
W.C.A. Wijngaards baee7885bd Merge branch 'master' into xfr-tsig 2025-07-23 16:23:58 +02:00
W.C.A. Wijngaards e55b3a2a4c - xfr-tsig, unit test for tsig_verify_reply. 2025-07-23 16:16:41 +02:00
Willem Toorop b5a2de1292 allow-response: config option 2025-07-20 13:30:29 +02:00
Willem Toorop 5ed0840dc2 Poisonlicious PoC with new tsig code 2025-07-19 15:19:00 +02:00
Willem Toorop 9bbb34fc38 Link tsig.lo only once 2025-07-19 15:11:15 +02:00
Willem Toorop 433bb1c7bc Merge branch 'updated-with-master/xfr-tsig' into hackathon/poisonlicious-new-tsig-code 2025-07-19 15:02:30 +02:00
Willem Toorop f3b960e72b Merge branch 'master' into xfr-tsig-update 2025-07-19 14:42:44 +02:00
Willem Toorop 5bd31c9569 A typo and a reorder (without impact) 2025-07-19 14:35:38 +02:00
Willem Toorop 4f245e0e5b Merge branch 'master' into hackathon/poisonlicious-update 2025-07-19 14:23:50 +02:00
W.C.A. Wijngaards 910288c0d1 - iana portlist updated. 2025-07-17 14:50:29 +02:00
W.C.A. Wijngaards b6e52c0a52 - Fix #1303: [FR] Disable TLSv1.2. 2025-07-17 14:50:13 +02:00
W.C.A. Wijngaards b58af78b63 - Fix to not set rlimits in the unit tests. 2025-07-17 11:40:31 +02:00
W.C.A. Wijngaards a1150078f2 - Add unit tests for non-ecs aggregation. 2025-07-16 11:46:04 +02:00
W.C.A. Wijngaards f49e6ccecd - Fix for RebirthDay Attack CVE-2025-5994, reported by Xiang Li
from AOSP Lab Nankai University.
- Tag for 1.23.1 with the release of 1.23.0 and the CVE fix, the
  repository continues with the previous fixes, with 1.23.2.
2025-07-16 11:40:32 +02:00
W.C.A. Wijngaards ad0e0fc290 Merge branch 'branch-1.23.1' 2025-07-16 11:34:44 +02:00
Yorgos Thessalonikefs 46823f7bc3 - Update man page templates from rst. 2025-07-12 17:37:54 +02:00
Yorgos Thessalonikefs dd3ac53ff1 - For #1289: add num.valops in the unbound-control man page. 2025-07-12 17:35:16 +02:00
Yorgos Thessalonikefs 1a6052fcac - For #1289: test num.valops in existing stat_values.tdir. 2025-07-12 17:33:43 +02:00
Yorgos Thessalonikefs 6689f0b4da Changelog entry for #1289:
- Merge #1289 from Roland van Rijswijk-Deij: Add extra statistic to
  track the number of signature validation operations.
  Adds 'num.valops' to extended statistics.
2025-07-12 16:35:02 +02:00
44ac818f87 Add extra statistic to track the number of signature validation operations (#1289)
* Add extra statistic to track the number of signature validation operations performed by the validator module

* Move validation operation statistic to mesh as suggested

* Fix NULL pointer dereference in case the mesh is not used (and is `NULL`)

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>

* Fix NULL pointer dereference on qstate and qstate->env in unit test situation

---------

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2025-07-12 16:29:38 +02:00
W.C.A. Wijngaards b4e12030e7 - For #1301: configure cant find SSL_is_quic in OpenSSL 3.5.1. 2025-07-11 15:58:50 +02:00
W.C.A. Wijngaards 9fe92d1119 - Fix detection of SSL_CTX_set_tmp_ecdh function. 2025-07-11 15:47:59 +02:00
W.C.A. Wijngaards e4069e5619 Merge branch 'master' into xfr-tsig 2025-07-11 15:27:40 +02:00
W.C.A. Wijngaards a3ec9a974f - xfr-tsig, member comments for struct tsig_calc_state_crypto. 2025-07-11 15:18:11 +02:00
W.C.A. Wijngaards 479b954118 - xfr-tsig, implemented tsig_calc_state_crypto. 2025-07-11 10:08:48 +02:00
W.C.A. Wijngaards 6ba2d6840b - Fix to improve dnstap discovery on Fedora. 2025-07-08 09:29:27 +02:00
W.C.A. Wijngaards 1de9d6ec66 - Fix layout of comm_point_udp_ancil_callback. 2025-07-03 15:57:49 +02:00
W.C.A. Wijngaards cb919d5126 - For #1300: implement sock-queue-timeout for FreeBSD as well. 2025-07-03 15:54:33 +02:00
W.C.A. Wijngaards 444c839474 - Fix #1300: Is 'sock-queue-timeout' a linux only feature. 2025-07-03 14:10:46 +02:00
W.C.A. Wijngaards 0276bcbceb Changelog note for #1299
- Generate ltmain.sh and configure again.
2025-07-02 10:57:23 +02:00
Jose Luis DuranandGitHub 41c55ffac1 Fix typos (#1299) 2025-07-02 10:50:49 +02:00
W.C.A. Wijngaards 0955238cd3 - xfr-tsig, tsig_verify_reply function. 2025-06-27 14:26:15 +02:00
W.C.A. Wijngaards 57dd6a971d - xfr-tsig, extra unit tests for tsig_sign_reply. 2025-06-27 11:29:41 +02:00
W.C.A. Wijngaards 6a831e3063 - xfr-tsig, more explanation in testcode/unittsig.c. 2025-06-27 11:03:25 +02:00
W.C.A. Wijngaards 3807bf00da - xfr-tsig, unit test for tsig_sign_reply. 2025-06-27 10:59:36 +02:00
W.C.A. Wijngaards 9022381be4 - xfr-tsig, more explanation in testcode/unittsig.c. 2025-06-27 09:29:57 +02:00
W.C.A. Wijngaards ca147a147d - xfr-tsig, unit test for tsig_sign_shared and tsig_verify_shared. 2025-06-27 09:24:51 +02:00
W.C.A. Wijngaards 5147e5aee9 - xfr-tsig, tsig_sign_shared function. 2025-06-27 08:52:32 +02:00
W.C.A. Wijngaards 6466513cc5 - xfr-tsig, unit test argument parse code. 2025-06-26 16:59:44 +02:00
W.C.A. Wijngaards 7a1a615fd3 - xfr-tsig, tsig_verify_shared function. 2025-06-26 15:11:25 +02:00
W.C.A. Wijngaards 81d774fb11 - xfr-tsig, tsig_sign_reply function. 2025-06-26 12:41:10 +02:00
W.C.A. Wijngaards 0254317e0d - xfr-tsig, fix unit test parse of tsig error code. 2025-06-25 14:52:16 +02:00
W.C.A. Wijngaards dc37849546 - xfr-tsig, test cases for BADTRUNC and not parseable. 2025-06-25 14:19:22 +02:00
W.C.A. Wijngaards 766666139b Merge branch 'master' into xfr-tsig 2025-06-25 14:05:06 +02:00
W.C.A. Wijngaards 86e78fcacc xfr-tsig, remove debug 2025-06-25 14:03:52 +02:00
W.C.A. Wijngaards 47a2d71fd3 - xfr-tsig, unit test cases for tsig errors. 2025-06-25 14:03:12 +02:00
Yorgos Thessalonikefs 4200d23882 - For #1247, replay test (added tcp_transport to
outnet_serviced_query).
2025-06-25 14:02:47 +02:00
Yorgos Thessalonikefs e2814fe165 - For #1247, turn off fetch-policy for delegation when looking into
parent side name servers that may not update the addresses and hit
  NXNS limits.
2025-06-25 13:59:17 +02:00
Yorgos Thessalonikefs ca153f4657 - Fix #1247: forward-first: ssl handshake failed on root nameservers. 2025-06-25 13:56:50 +02:00
W.C.A. Wijngaards 0719ef21fa - xfr-tsig, unit test for tsig_verify_query. 2025-06-25 12:06:15 +02:00
W.C.A. Wijngaards 6d5f22b56d - xfr-tsig, fix tsig_verify_query. 2025-06-25 10:21:42 +02:00
W.C.A. Wijngaards b5beb800c8 - xfr-tsig, tsig_find_rr function. 2025-06-24 16:51:41 +02:00
W.C.A. Wijngaards fe63b25441 - xfr-tsig, parse and verify query tsig. 2025-06-24 16:31:18 +02:00
W.C.A. Wijngaards 0afbb68b40 - xfr-tsig, other data content matches the other len when written. 2025-06-20 16:57:24 +02:00
W.C.A. Wijngaards 4562cd372c - xfr-tsig, whitespace. 2025-06-20 14:43:19 +02:00
W.C.A. Wijngaards 418ef3765d Merge branch 'master' into xfr-tsig 2025-06-20 14:33:02 +02:00
W.C.A. Wijngaards 29c8b3edba - xfr-tsig, unit tests for md5, sha1, sha224, sha256, sha384 and sha512. 2025-06-20 14:31:44 +02:00
Yorgos Thessalonikefs ee607c0f72 Changelog entry for #1293:
- Fix #1293: EDE 6 is attached to insecure cached answers when client
  sends the CD bit.
2025-06-20 14:11:22 +02:00
Yorgos Thessalonikefs 2d90d5d729 - Fix #1293: EDE 6 is attached to insecure cached answers when client sends
the CD bit.
2025-06-20 14:09:30 +02:00
W.C.A. Wijngaards 5214912555 Merge branch 'master' into xfr-tsig 2025-06-20 12:14:13 +02:00
W.C.A. Wijngaards f2c609b9a5 - xfr-tsig, unit test for tsig_sign_query. 2025-06-20 12:13:51 +02:00
W.C.A. Wijngaards ce72770f61 - Fix rrset cache create allocation failure case. 2025-06-19 16:27:13 +02:00
W.C.A. Wijngaards de93a636da Changelog note for #1297
- Merge #1297: edns-subnet: fix NULL_AFTER_DEREF on subnetmod.
2025-06-19 16:24:54 +02:00
KostyaandGitHub d3f88d008f edns-subnet: fix NULL_AFTER_DEREF on subnetmod (#1297)
Found by static analyzer svace.
Static analyzer message: Redundant comparison with a NULL value at subnetmod.c:236 for pointer 'sn_env->subnet_msg_cache',
which was dereferenced at slabhash.c:228 by passing as 1st parameter to function 'slabhash_setmarkdel' at subnetmod.c:235.

Moved usage of sn_env->subnet_msg_cache in slabhash_setmarkdel after checking.

Signed-off-by: Konstantin Kamanin <bewflast@gmail.com>
2025-06-19 16:24:21 +02:00
W.C.A. Wijngaards a1d68cdc96 - Fix #1296: DNS over QUIC depends on a very outdated version of
ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.
2025-06-19 14:39:45 +02:00
W.C.A. Wijngaards aa22fd936e - xfr-tsig, test buffer size. 2025-06-18 17:01:35 +02:00
W.C.A. Wijngaards 4bbb74da39 - xfr-tsig, tsig test. 2025-06-18 16:41:10 +02:00
W.C.A. Wijngaards dd4ee42eb6 - xfr-tsig, tsig_sign_query. 2025-06-18 15:00:18 +02:00
W.C.A. Wijngaards 8b95785b8c - xfr-tsig, tsig functions. 2025-06-18 12:18:20 +02:00
W.C.A. Wijngaards bb4ddab77a Merge branch 'master' into xfr-tsig 2025-06-17 16:55:18 +02:00
W.C.A. Wijngaards 69354298fc - xfr-tsig, tsig_create and tsig_delete. 2025-06-17 16:54:52 +02:00
Yorgos Thessalonikefs 9201c75013 - Fix for consistent use of local zone CNAME alias for configured auth
zones. Now it also applies to downstream configured auth zones.
2025-06-17 15:03:29 +02:00
W.C.A. Wijngaards bbcf5d122a Merge branch 'master' into xfr-tsig 2025-06-16 17:00:12 +02:00
W.C.A. Wijngaards 497161f72f - xfr-tsig, tsig_verify return failure comment improved. 2025-06-16 16:59:53 +02:00
W.C.A. Wijngaards f066d6d453 - Fix #1295: Windows 32-bit binaries download seems to be missing dll
dependency.
2025-06-16 14:26:54 +02:00
W.C.A. Wijngaards a04bd5da29 - Fix to check control-interface addresses in unbound-checkconf. 2025-06-16 12:43:31 +02:00
W.C.A. Wijngaards 31e8118b76 - xfr-tsig, man page and example config. 2025-06-13 16:32:36 +02:00
W.C.A. Wijngaards 8811bd4844 - xfr-tsig, tsig-key, with name, algorithm and secret options. 2025-06-13 12:12:49 +02:00
W.C.A. Wijngaards 0f02479dea - xfr-tsig, fix algorithm lookup. 2025-06-13 10:17:47 +02:00
W.C.A. Wijngaards 364edccebc - xfr-tsig, algorithm table. 2025-06-13 10:15:41 +02:00
W.C.A. Wijngaards 3d9242b3d3 - xfr-tsig, key table. 2025-06-12 16:05:10 +02:00
W.C.A. Wijngaards 3f378c962f - xfr-tsig, check rdata length in tsig verify. 2025-06-12 14:34:56 +02:00
W.C.A. Wijngaards 4ca37bcadf Merge branch 'master' into xfr-tsig 2025-06-12 12:17:13 +02:00
W.C.A. Wijngaards e4cf7aeccf - Fix header return value description for skip_pkt_rrs and
parse_edns_from_query_pkt.
2025-06-12 12:17:01 +02:00
W.C.A. Wijngaards 19492da154 - xfr-tsig, check buffer remaining in tsig verify. 2025-06-12 11:50:11 +02:00
W.C.A. Wijngaards 182e580fe2 - xfr-tsig, fix warning in compile of declaration. 2025-06-12 09:57:23 +02:00
W.C.A. Wijngaards eefb417c09 - xfr-tsig, const for dname compare and fix warnings in compile. 2025-06-12 09:53:56 +02:00
W.C.A. Wijngaards 4fd0d84e66 - xfr-tsig, update header comment. 2025-06-12 09:49:20 +02:00
W.C.A. Wijngaards ea0973002f - xfr-tsig, constant time memcmp is used. 2025-06-12 09:34:07 +02:00
W.C.A. Wijngaards 8fcc4c98b6 Merge branch 'master' into xfr-tsig 2025-06-12 09:29:28 +02:00
W.C.A. Wijngaards 7edc1e0fc4 - xfr-tsig, import the tsig verify code from hackathon/poisonlicious branch. 2025-06-12 09:25:54 +02:00
W.C.A. Wijngaards a8aa1dbbe1 - Fix conditional expressions with parentheses for bitwise and. 2025-06-11 16:42:43 +02:00
W.C.A. Wijngaards 9f29292839 - Fix bitwise operators in conditional expressions with parentheses. 2025-06-11 15:46:31 +02:00
W.C.A. Wijngaards 1cc1e0b89e - iana portlist updated. 2025-06-05 11:11:56 +02:00
W.C.A. Wijngaards 565bce670c - Fix comment for the dname_remove_label_limit_len function. 2025-06-05 11:11:32 +02:00
W.C.A. Wijngaards c0563f43b0 - Fix unbound-anchor certificate file read for line ends and end of
file.
2025-06-05 11:09:53 +02:00
Yorgos Thessalonikefs 81f3de4da2 - Small man page corrections for the 'disable-dnssec-lame-check' option. 2025-06-03 14:12:27 +02:00
W.C.A. Wijngaards ff7dfd52a2 - Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound
program.
2025-05-21 12:41:54 +02:00
Yorgos Thessalonikefs 342a0f48e3 - Add more checks about respip in unbound-checkconf.
Also fixes #310: unbound-checkconf not reporting RPZ configuration
  error.
2025-05-20 16:21:02 +02:00
Yorgos Thessalonikefs 71ac59e6f4 Changelog entry for #1285:
- Merge #1285:  RST man pages.
2025-05-20 12:23:32 +02:00
Yorgos ThessalonikefsandGitHub 6662f71732 RST man pages (#1285)
Introduce restructuredText man pages to sync the online and source code man page documentation.
The templated man pages (*.in) are still part of the repo but generated with docutils from their .rst counterpart.
Documentation on how to generate those (mainly for core developers) are in README.man.
2025-05-20 12:20:20 +02:00
W.C.A. Wijngaards 32644937b0 - Fix for cname chain length with qtype ANY and qname minimisation.
Thanks to Jim Greenwood from Nominet for the report.
2025-05-19 13:17:21 +02:00
W.C.A. Wijngaards 1634beb4a0 - Fix config of slab values when there is no config file. 2025-05-15 14:34:18 +02:00
W.C.A. Wijngaards 1ef7b4a246 - Adjusted so-sndbuf default to 4m. 2025-05-13 15:31:05 +02:00
W.C.A. Wijngaards 03772d10fb - Change default for so-sndbuf to 1m, to mitigate a cross-layer
issue where the UDP socket send buffers are exhausted waiting
  for ARP/NDP resolution. Thanks to Reflyable for the report.
2025-05-13 15:04:32 +02:00
Yorgos Thessalonikefs 9152c914af - Fix #1282: log-destaddr fail on long ipv6 addresses. 2025-05-13 11:02:58 +02:00
Yorgos Thessalonikefs a35ac5d82e - Fix #1284: NULL pointer deref in az_find_nsec_cover() (latent bug)
by adding a log_assert() to safeguard future development.
2025-05-13 11:00:23 +02:00
W.C.A. Wijngaards 21e3278400 - Fix #1283: Unsafe usage of atoi() while parsing the configuration
file.
2025-05-12 14:57:42 +02:00
Yorgos Thessalonikefs 8e1deede08 Changelog entry for #1280:
- Merge #1280: Fix auth nsec3 code. Fixes NSEC3 code to not break on
  broken auth zones that include unsigned out of zone (above apex)
  data. Could lead to hang while trying to prove a wildcard answer.
2025-05-12 14:29:11 +02:00
Yorgos ThessalonikefsandGitHub 4e23523d1a Fix auth nsec3 code (#1280)
- Fix NSEC3 code to not break on broken auth zones that include unsigned
  out of zone (above apex) data. Could lead to hang while trying to
  prove a wildcard answer.
  Reported by Dmitrii Kuvaiskii from Amazon Web Services.

- Tests for NSEC3 auth zones with out of zone data.
2025-05-12 14:26:47 +02:00
W.C.A. Wijngaards 8190526250 - Fix #1281: forward-zone "name: ." conflicts with auth-zone "name: ."
in 1.23.0, but worked in 1.22.0.
2025-05-09 16:01:41 +02:00
Yorgos Thessalonikefs 5dd14e2644 - Sync unbound and unbound-checkconf log output for unknown modules. 2025-05-05 14:47:12 +02:00
Yorgos Thessalonikefs b50faccb1d Changelog entry for #1276:
- Merge #1276: Auto-configure '-slabs' values.
2025-04-29 15:23:07 +02:00
fcc21885e4 Auto-configure '-slabs' values (#1276)
- Auto-configure '-slabs' values to a power of 2 value close to num-threads
  by default for multi-threaded environments.

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2025-04-29 15:21:47 +02:00
W.C.A. Wijngaards a904a3a2c2 - Fix dnstap to use protoc. 2025-04-29 12:43:56 +02:00
W.C.A. Wijngaards c253c8367a - Fix for parallel build of dnstap protoc-c output. 2025-04-29 12:38:41 +02:00
Yorgos Thessalonikefs 0f95fae445 Changelog entry for #1275:
- Merge #1275: Use macros for the fr_check_changed* functions.
2025-04-28 15:50:03 +02:00
Yorgos ThessalonikefsandGitHub e5bbc36ae0 Use macros for the fr_check_changed* functions (#1275) 2025-04-28 15:48:45 +02:00
W.C.A. Wijngaards c88fa02c18 - Fix #1272: assertion failure testcode/unitverify.c:202. 2025-04-25 11:12:28 +02:00
W.C.A. Wijngaards e794234ac8 - Tag for 1.23.0rc2. This became the release of 1.23.0 on 24 April
2025. The code repository continues with 1.23.1 in development.
2025-04-24 10:17:45 +02:00
W.C.A. Wijngaards db53ebb798 Merge branch 'branch-1.23.0' 2025-04-24 10:14:02 +02:00
W.C.A. Wijngaards fe835f9d52 - Increase default to num-queries-per-thread: 2048, when unbound is
compiled with libevent. It makes saturation of the task queue more
  resource intensive and less practical. Thanks to Shiming Liu,
  Network and Information Security Lab, Tsinghua University for the
  report.
2025-04-16 12:03:08 +02:00
Yorgos Thessalonikefs 9c99b404a1 Changelog entry for #1265:
- Merge #1265: Fix WSAPoll.
2025-04-11 15:07:25 +02:00
Yorgos ThessalonikefsandGitHub 75e8fd7539 Fix WSAPoll (#1265)
* Fix calling WSAPoll.

* fast_reload: explicitly set tcp_wouldblock on Windows when there is no
  command to read from the fast_reload thread.

* For poll(), also check for ENOMEM (Linux).

* Remove ifdefs for ENOMEM.
* Some systems return EAGAIN for poll.
2025-04-11 15:05:52 +02:00
Willem Toorop 3674e4813c A bit better TSIG handling 2025-03-25 16:46:42 +01:00
Willem Toorop 5d11af34dc Verification of incoming responses with TSIG
For now with a hardcoded TSIG key
2025-03-17 09:25:13 +01:00
Willem Toorop e29ee129a3 Fix CI 2025-03-16 10:17:53 +01:00
Willem Toorop 86526c75a3 Send responses just before they enter the cache
Configured with the `distribute:` option in the `server:` section in the config.
2025-03-16 09:21:11 +01:00
Willem Toorop d9d6dd31dc Store responses received on listen interface in cache 2025-03-15 16:22:29 +01:00
W.C.A. Wijngaards c88eed83d9 - ttl-zero-cacherep, unit test for ttl zero for a cache response. 2024-11-11 17:08:38 +01:00
W.C.A. Wijngaards 50fcf71f04 - ttl-zero-cacherep, Responses in the last second of their cache TTL,
get an extra second. That makes the TTL not 0, since they are from
  cache and can be cached by the client.
2024-11-11 15:43:10 +01:00
W.C.A. Wijngaards e6573fc337 - xfr-tsig, create util/tsig.c and util/tsig.h. 2023-04-14 14:05:15 +02:00
344 changed files with 34212 additions and 6620 deletions
+3 -20
View File
@@ -12,6 +12,7 @@ jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: GCC on Linux
@@ -31,12 +32,12 @@ jobs:
clang_analysis: "yes"
- name: OS X
os: macos-latest
install_expat: "no"
install_expat: "yes"
config: "--enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat"
make_test: "yes"
- name: Clang on OS X
os: macos-latest
install_expat: "no"
install_expat: "yes"
config: "CC=clang --enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat --disable-static"
make_test: "yes"
clang_analysis: "yes"
@@ -48,15 +49,6 @@ jobs:
os: ubuntu-latest
config: 'CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address" --disable-flto --disable-static'
make_test: "yes"
- name: Apple iPhone on iOS, armv7
os: macos-latest
AUTOTOOLS_HOST: armv7-apple-ios
OPENSSL_HOST: ios-cross
IOS_SDK: iPhoneOS
IOS_CPU: armv7s
test_ios: "yes"
config: "no"
make: "no"
- name: Apple iPhone on iOS, arm64
os: macos-latest
AUTOTOOLS_HOST: aarch64-apple-ios
@@ -84,15 +76,6 @@ jobs:
test_ios: "yes"
config: "no"
make: "no"
- name: iPhoneSimulator on OS X, i386
os: macos-latest
AUTOTOOLS_HOST: i386-apple-ios
OPENSSL_HOST: iphoneos-cross
IOS_SDK: iPhoneSimulator
IOS_CPU: i386
test_ios: "yes"
config: "no"
make: "no"
- name: iPhoneSimulator on OS X, x86_64
os: macos-latest
AUTOTOOLS_HOST: x86_64-apple-ios
+543 -440
View File
File diff suppressed because it is too large Load Diff
+12 -9
View File
@@ -4,7 +4,7 @@
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/109262826617293067?domain=https%3A%2F%2Ffosstodon.org&style=social)](https://fosstodon.org/@nlnetlabs)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/114692612288811644?domain=social.nlnetlabs.nl&style=social)](https://social.nlnetlabs.nl/@nlnetlabs)
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
fast and lean and incorporates modern features based on open standards. If you
@@ -25,18 +25,21 @@ Unbound can be compiled and installed using:
./configure && make && make install
```
You can use libevent if you want. libevent is useful when using many (10000)
outgoing ports. By default max 256 ports are opened at the same time and the
builtin alternative is equally capable and a little faster.
You can use libevent if you want. libevent is useful when using many (e.g.,
10000) outgoing ports.
Use the `--with-libevent` configure option to compile Unbound with libevent
support.
If not, the default builtin alternative opens max 256 ports at the same time
and is equally capable and a little faster.
## Unbound configuration
All of Unbound's configuration options are described in the man pages, which
will be installed and are available on the Unbound
[documentation page](https://unbound.docs.nlnetlabs.nl/).
All of Unbound's configuration options are described in the `unbound.conf(5)`
man page, which will be installed and is also available on the Unbound
[documentation page](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html)
for the latest version.
An example configuration file is located in
An example configuration file, with minimal documentation, is located in
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
Vendored
+202 -146
View File
@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,8 @@
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software
# Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -45,7 +46,7 @@ m4_define([_LT_COPYING], [dnl
# along with this program. If not, see <http://www.gnu.org/licenses/>.
])
# serial 58 LT_INIT
# serial 59 LT_INIT
# LT_PREREQ(VERSION)
@@ -195,6 +196,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
m4_require([_LT_CMD_RELOAD])dnl
m4_require([_LT_DECL_FILECMD])dnl
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
@@ -233,8 +235,8 @@ esac
ofile=libtool
can_build_shared=yes
# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
# All known linkers require a '.a' archive for static linking (except MSVC and
# ICC, which need '.lib').
libext=a
with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -736,7 +738,6 @@ _LT_CONFIG_SAVE_COMMANDS([
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -786,7 +787,7 @@ _LT_EOF
# if finds mixed CR/LF and LF-only lines. Since sed operates in
# text mode, it properly converts lines to CR/LF. This bash problem
# is reportedly fixed, but why not run on old versions too?
sed '$q' "$ltmain" >> "$cfgfile" \
$SED '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
mv -f "$cfgfile" "$ofile" ||
@@ -1048,8 +1049,8 @@ int forced_loaded() { return 2;}
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
$AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
cat > conftest.c << _LT_EOF
@@ -1073,17 +1074,12 @@ _LT_EOF
_lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
darwin1.*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[[012]][[,.]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
10.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
darwin*)
case $MACOSX_DEPLOYMENT_TARGET,$host in
10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
@@ -1132,12 +1128,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
output_verbose_link_cmd=func_echo_all
_LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
_LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
m4_if([$1], [CXX],
[ if test yes != "$lt_cv_apple_cc_single_mod"; then
_LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
fi
],[])
else
@@ -1251,7 +1247,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
# _LT_WITH_SYSROOT
# ----------------
AC_DEFUN([_LT_WITH_SYSROOT],
[AC_MSG_CHECKING([for sysroot])
[m4_require([_LT_DECL_SED])dnl
AC_MSG_CHECKING([for sysroot])
AC_ARG_WITH([sysroot],
[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
[Search for dependent libraries within DIR (or the compiler's sysroot
@@ -1268,7 +1265,7 @@ case $with_sysroot in #(
fi
;; #(
/*)
lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`
;; #(
no|'')
;; #(
@@ -1298,7 +1295,7 @@ ia64-*-hpux*)
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*ELF-32*)
HPUX_IA64_MODE=32
;;
@@ -1315,7 +1312,7 @@ ia64-*-hpux*)
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
if test yes = "$lt_cv_prog_gnu_ld"; then
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
;;
@@ -1327,7 +1324,7 @@ ia64-*-hpux*)
;;
esac
else
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -32"
;;
@@ -1349,7 +1346,7 @@ mips64*-*linux*)
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
emul=elf
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*32-bit*)
emul="${emul}32"
;;
@@ -1357,7 +1354,7 @@ mips64*-*linux*)
emul="${emul}64"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*MSB*)
emul="${emul}btsmip"
;;
@@ -1365,7 +1362,7 @@ mips64*-*linux*)
emul="${emul}ltsmip"
;;
esac
case `/usr/bin/file conftest.$ac_objext` in
case `$FILECMD conftest.$ac_objext` in
*N32*)
emul="${emul}n32"
;;
@@ -1385,14 +1382,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# not appear in the list.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*32-bit*)
case $host in
x86_64-*kfreebsd*-gnu)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*x86-64*)
LD="${LD-ld} -m elf32_x86_64"
;;
@@ -1460,7 +1457,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
case `$FILECMD conftest.o` in
*64-bit*)
case $lt_cv_prog_gnu_ld in
yes*)
@@ -1499,9 +1496,22 @@ need_locks=$enable_libtool_lock
m4_defun([_LT_PROG_AR],
[AC_CHECK_TOOLS(AR, [ar], false)
: ${AR=ar}
: ${AR_FLAGS=cru}
_LT_DECL([], [AR], [1], [The archiver])
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
# Use ARFLAGS variable as AR's operation code to sync the variable naming with
# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
# higher priority because thats what people were doing historically (setting
# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
# variable obsoleted/removed.
test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
lt_ar_flags=$AR_FLAGS
_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
[Flags to create an archive])
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[lt_cv_ar_at_file=no
@@ -1720,7 +1730,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1763,7 +1773,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
sysv5* | sco5v6* | sysv4.2uw2*)
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
if test -n "$kargmax"; then
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'`
else
lt_cv_sys_max_cmd_len=32768
fi
@@ -2213,26 +2223,35 @@ m4_defun([_LT_CMD_STRIPLIB],
striplib=
old_striplib=
AC_MSG_CHECKING([whether stripping libraries is possible])
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
if test -z "$STRIP"; then
AC_MSG_RESULT([no])
else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
if test -n "$STRIP"; then
if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
old_striplib="$STRIP --strip-debug"
striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
else
case $host_os in
darwin*)
# FIXME - insert some real tests, host_os isn't really good enough
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
else
;;
freebsd*)
if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
old_striplib="$STRIP --strip-debug"
striplib="$STRIP --strip-unneeded"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
;;
*)
AC_MSG_RESULT([no])
fi
;;
*)
AC_MSG_RESULT([no])
;;
esac
;;
esac
fi
fi
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
_LT_DECL([], [striplib], [1])
@@ -2555,7 +2574,7 @@ cygwin* | mingw* | pw32* | cegcc*)
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
@@ -2565,14 +2584,14 @@ m4_if([$1], [],[
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
esac
dynamic_linker='Win32 ld.exe'
;;
*,cl*)
# Native MSVC
*,cl* | *,icl*)
# Native MSVC or ICC
libname_spec='$name'
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
library_names_spec='$libname.dll.lib'
@@ -2591,7 +2610,7 @@ m4_if([$1], [],[
done
IFS=$lt_save_ifs
# Convert to MSYS style.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
;;
cygwin*)
# Convert to unix form, then to dos form, then back to unix form
@@ -2628,7 +2647,7 @@ m4_if([$1], [],[
;;
*)
# Assume MSVC wrapper
# Assume MSVC and ICC wrapper
library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
@@ -2661,7 +2680,7 @@ dgux*)
shlibpath_var=LD_LIBRARY_PATH
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# DragonFly does not have aout. When/if they implement a new
# versioning mechanism, adjust this.
if test -x /usr/bin/objformat; then
@@ -2873,9 +2892,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# before this can be enabled.
hardcode_into_libs=yes
# Add ABI-specific directories to the system library path.
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
@@ -2884,7 +2900,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -2896,6 +2912,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
dynamic_linker='GNU/Linux ld.so'
;;
netbsdelf*-gnu)
version_type=linux
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='NetBSD ld.elf_so'
;;
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -3463,7 +3491,7 @@ beos*)
bsdi[[45]]*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_cmd='$FILECMD -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
@@ -3497,14 +3525,14 @@ darwin* | rhapsody*)
lt_cv_deplibs_check_method=pass_all
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
esac
@@ -3518,7 +3546,7 @@ haiku*)
;;
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
@@ -3555,7 +3583,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -3565,7 +3593,7 @@ netbsd*)
newos6*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_cmd=$FILECMD
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
@@ -3692,13 +3720,13 @@ else
mingw*) lt_bad_file=conftest.nm/nofile ;;
*) lt_bad_file=/dev/null ;;
esac
case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
*$lt_bad_file* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
break 2
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
break 2
@@ -3724,7 +3752,7 @@ else
# Let the user override the test.
else
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in
*COFF*)
DUMPBIN="$DUMPBIN -symbols -headers"
;;
@@ -3964,7 +3992,7 @@ esac
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Gets list of data symbols to import.
lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"
# Adjust the below global symbol transforms to fixup imported variables.
lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
@@ -3982,20 +4010,20 @@ fi
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
lt_cv_sys_global_symbol_to_cdecl="sed -n"\
lt_cv_sys_global_symbol_to_cdecl="$SED -n"\
$lt_cdecl_hook\
" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\
$lt_c_name_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
# Transform an extracted symbol line into symbol name with lib prefix and
# symbol address.
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\
$lt_c_name_lib_hook\
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
@@ -4019,7 +4047,7 @@ for ac_symprfx in "" "_"; do
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
# Fake it for dumpbin and say T for any non-static function,
# D for any global variable and I for any imported variable.
# Also find C++ and __fastcall symbols from MSVC++,
# Also find C++ and __fastcall symbols from MSVC++ or ICC,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
@@ -4037,9 +4065,9 @@ for ac_symprfx in "" "_"; do
" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
fi
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -4061,7 +4089,8 @@ _LT_EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
$ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -4326,7 +4355,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# FreeBSD uses GNU C++
;;
hpux9* | hpux10* | hpux11*)
@@ -4409,7 +4438,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4433,7 +4462,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4701,6 +4730,12 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# flang / f18. f95 an alias for gfortran or flang on Debian
flang* | f18* | f95*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
@@ -4745,7 +4780,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
# Sun Fortran 8.3 passes all unrecognized flags to the linker
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4928,7 +4963,7 @@ m4_if([$1], [CXX], [
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
@@ -4936,7 +4971,7 @@ m4_if([$1], [CXX], [
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
cl*)
cl* | icl*)
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
;;
*)
@@ -4945,6 +4980,9 @@ m4_if([$1], [CXX], [
;;
esac
;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
@@ -4993,20 +5031,23 @@ dnl Note also adjust exclude_expsyms for C++ above.
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# Microsoft Visual C++ or Intel C++ Compiler.
if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
# we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
with_gnu_ld=yes
;;
openbsd* | bitrig*)
with_gnu_ld=no
;;
linux* | k*bsd*-gnu | gnu*)
_LT_TAGVAR(link_all_deplibs, $1)=no
;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5053,7 +5094,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
supports_anon_versioning=no
case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5165,6 +5206,7 @@ _LT_EOF
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
interix[[3-9]]*)
@@ -5179,7 +5221,7 @@ _LT_EOF
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
@@ -5222,7 +5264,7 @@ _LT_EOF
_LT_TAGVAR(compiler_needs_object, $1)=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*) # Sun C 5.9
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
@@ -5234,13 +5276,14 @@ _LT_EOF
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
tcc*)
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
;;
xlf* | bgf* | bgxlf* | mpixlf*)
@@ -5250,7 +5293,7 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
@@ -5261,7 +5304,7 @@ _LT_EOF
fi
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -5382,7 +5425,7 @@ _LT_EOF
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
@@ -5565,12 +5608,12 @@ _LT_EOF
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# Microsoft Visual C++ or Intel C++ Compiler.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
case $cc_basename in
cl*)
# Native MSVC
cl* | icl*)
# Native MSVC or ICC
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5611,7 +5654,7 @@ _LT_EOF
fi'
;;
*)
# Assume MSVC wrapper
# Assume MSVC and ICC wrapper
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Tell ltmain to make .lib files, not .a files.
@@ -5659,7 +5702,7 @@ _LT_EOF
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_direct, $1)=yes
@@ -5782,6 +5825,7 @@ _LT_EOF
if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
_LT_TAGVAR(link_all_deplibs, $1)=no
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5799,11 +5843,12 @@ _LT_EOF
# Fabrice Bellard et al's Tiny C Compiler
_LT_TAGVAR(ld_shlibs, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
;;
esac
;;
netbsd*)
netbsd* | netbsdelf*-gnu)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -5870,6 +5915,7 @@ _LT_EOF
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
osf3*)
@@ -6425,7 +6471,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
GXX=no
@@ -6636,8 +6682,8 @@ if test yes != "$_lt_caught_CXX_error"; then
cygwin* | mingw* | pw32* | cegcc*)
case $GXX,$cc_basename in
,cl* | no,cl*)
# Native MSVC
,cl* | no,cl* | ,icl* | no,icl*)
# Native MSVC or ICC
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6735,6 +6781,7 @@ if test yes != "$_lt_caught_CXX_error"; then
emximp -o $lib $output_objdir/$libname.def'
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
_LT_TAGVAR(file_list_spec, $1)='@'
;;
dgux*)
@@ -6765,7 +6812,7 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -6800,7 +6847,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6865,7 +6912,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6902,7 +6949,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
irix5* | irix6*)
case $cc_basename in
@@ -7042,13 +7089,13 @@ if test yes != "$_lt_caught_CXX_error"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
echo "local: *; };" >> $output_objdir/$libname.ver~
$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
;;
*)
case `$CC -V 2>&1 | sed 5q` in
case `$CC -V 2>&1 | $SED 5q` in
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
@@ -7204,7 +7251,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# FIXME: insert proper C++ library support
@@ -7288,7 +7335,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
@@ -7299,7 +7346,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
@@ -8186,6 +8233,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program])
AC_SUBST([DLLTOOL])
])
# _LT_DECL_FILECMD
# ----------------
# Check for a file(cmd) program that can be used to detect file type and magic
m4_defun([_LT_DECL_FILECMD],
[AC_CHECK_TOOL([FILECMD], [file], [:])
_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])
])# _LD_DECL_FILECMD
# _LT_DECL_SED
# ------------
# Check for a fully-functional sed program, that truncates
@@ -8365,8 +8420,8 @@ _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -8797,7 +8852,7 @@ LT_OPTION_DEFINE([LTDL_INIT], [convenience],
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
@@ -8922,7 +8977,8 @@ m4_define([lt_dict_filter],
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation,
# Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -8931,23 +8987,23 @@ m4_define([lt_dict_filter],
# @configure_input@
# serial 4179 ltversion.m4
# serial 4245 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
m4_define([LT_PACKAGE_VERSION], [2.4.7])
m4_define([LT_PACKAGE_REVISION], [2.4.7])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
[macro_version='2.4.7'
macro_revision='2.4.7'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free
# Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
@@ -9044,8 +9100,8 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 11 (pkg-config-0.29.1)
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@@ -9087,7 +9143,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
@@ -9132,7 +9188,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
@@ -9188,7 +9244,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -9198,17 +9254,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
@@ -9219,8 +9275,8 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
@@ -9230,10 +9286,10 @@ _PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
@@ -9390,7 +9446,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9477,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
+59 -12
View File
@@ -2,7 +2,10 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 48
# Version 50
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
# check by ACX_FUNC_MALLOC.
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
# and check for getaddrinfo with only header.
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
@@ -71,6 +74,7 @@
# ACX_DEPFLAG - find cc dependency flags.
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax.
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
@@ -92,6 +96,7 @@
# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably.
# ACX_FUNC_MALLOC - check malloc, define replacement .
# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format.
# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring.
# AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused.
# AHX_CONFIG_FSEEKO - define fseeko, ftello fallback.
# AHX_CONFIG_RAND_MAX - define RAND_MAX if needed.
@@ -490,7 +495,7 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
])
dnl Check how to mark function arguments as unused.
dnl result in HAVE_ATTR_UNUSED.
dnl result in HAVE_ATTR_UNUSED.
dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
@@ -525,6 +530,45 @@ if test $ac_cv_c_unused_attribute = yes; then
fi
])dnl
dnl Check how to mark function arguments as nonstring.
dnl result in HAVE_ATTR_NONSTRING.
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
[ac_cv_c_nonstring_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
struct test {
char __attribute__((nonstring)) s[1];
};
]], [[
struct test t = { "1" };
(void) t;
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
])
dnl Setup ATTR_NONSTRING config.h parts.
dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also.
AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE],
[
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
])
AC_MSG_RESULT($ac_cv_c_nonstring_attribute)
if test $ac_cv_c_nonstring_attribute = yes; then
AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute])
fi
])dnl
dnl Pre-fun for ACX_LIBTOOL_C_ONLY
AC_DEFUN([ACX_LIBTOOL_C_PRE], [
# skip these tests, we do not need them.
@@ -1190,8 +1234,9 @@ dnl detect malloc and provide malloc compat prototype.
dnl $1: unique name for compat code
AC_DEFUN([ACX_FUNC_MALLOC],
[
AC_MSG_CHECKING([for GNU libc compatible malloc])
AC_RUN_IFELSE([AC_LANG_PROGRAM(
AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull],
[
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
#include <stdlib.h>
#else
@@ -1199,14 +1244,16 @@ char *malloc ();
#endif
]], [ if(malloc(0) != 0) return 1;])
],
[AC_MSG_RESULT([no])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
[AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[AC_MSG_RESULT([no (crosscompile)])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
[ac_cv_func_malloc_0_nonnull=no],
[ac_cv_func_malloc_0_nonnull=yes],
[ac_cv_func_malloc_0_nonnull="no (crosscompile)"])
])
AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes],
[AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
])
])
dnl Define fallback for fseeko and ftello if needed.
+51 -42
View File
@@ -401,12 +401,9 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
/* We don't store the reply if its TTL is 0 unless serve-expired is
* enabled. Such a reply won't be reusable and simply be a waste for
* the backend. It's also compatible with the default behavior of
* dns_cache_store_msg(). */
if(qstate->return_msg->rep->ttl == 0 &&
!qstate->env->cfg->serve_expired)
/* We don't store the reply if its TTL is 0. This is probably coming
* from upstream and it is not meant to be stored. */
if(qstate->return_msg->rep->ttl == 0)
return 0;
/* The EDE is added to the out-list so it is encoded in the cached message */
@@ -460,7 +457,7 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
* - serve_expired needs to be set
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
* than that. */
if((time_t)expiry < *qstate->env->now &&
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now) &&
(!qstate->env->cfg->serve_expired ||
(SERVE_EXPIRED_TTL &&
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
@@ -472,7 +469,8 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
* negative, set the TTL to 0. */
static void
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract,
time_t timestamp)
{
size_t i;
size_t total = data->count + data->rrsig_count;
@@ -484,13 +482,13 @@ packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0;
}
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
data->ttl_add = timestamp;
}
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
* negative, set the TTLs to 0. */
static void
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
adjust_msg_ttl(struct dns_msg* msg, time_t adjust, time_t timestamp)
{
size_t i;
if(adjust >= 0 && msg->rep->ttl > adjust)
@@ -502,13 +500,13 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, adjust);
rep->rrsets[i]->entry.data, adjust, timestamp);
}
}
/* Set the TTL of the given RRset to fixed value. */
static void
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl, time_t timestamp)
{
size_t i;
size_t total = data->count + data->rrsig_count;
@@ -516,12 +514,12 @@ packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
for(i=0; i<total; i++) {
data->rr_ttl[i] = ttl;
}
data->ttl_add = 0;
data->ttl_add = timestamp;
}
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
static void
set_msg_ttl(struct dns_msg* msg, time_t ttl)
set_msg_ttl(struct dns_msg* msg, time_t ttl, time_t timestamp)
{
size_t i;
msg->rep->ttl = ttl;
@@ -530,14 +528,14 @@ set_msg_ttl(struct dns_msg* msg, time_t ttl)
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, ttl);
rep->rrsets[i]->entry.data, ttl, timestamp);
}
}
/** convert dns message in buffer to return_msg */
static int
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
int* msg_expired)
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
{
struct msg_parse* prs;
struct edns_data edns;
@@ -554,6 +552,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
&timestamp, sizeof(timestamp));
expiry = be64toh(expiry);
timestamp = be64toh(timestamp);
log_assert(timestamp <= expiry);
*msg_expiry = (time_t)expiry;
*msg_timestamp = (time_t)timestamp;
/* parse DNS packet */
regional_free_all(qstate->env->scratch);
@@ -605,11 +606,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
return 1; /* message from the future (clock skew?) */
}
adjust = *qstate->env->now - (time_t)timestamp;
if(qstate->return_msg->rep->ttl < adjust) {
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now)) {
verbose(VERB_ALGO, "cachedb msg expired");
*msg_expired = 1;
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
if(!qstate->env->cfg->serve_expired ||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NOERROR &&
@@ -618,23 +617,21 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */
else
adjust = -1;
/* If serve-expired is enabled, we still use an expired message.
* Set the TTL to 0 now and it will be handled specially later
* when we need to store it internally. */
adjust = -1;
}
adjust_msg_ttl(qstate->return_msg, adjust, timestamp);
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(qstate->return_msg);
}
/* Similar to the unbound worker, if serve-expired is enabled and
* the msg would be considered to be expired, mark the state so a
* refetch will be scheduled. The comparison between 'expiry' and
* 'now' should be redundant given how these values were calculated,
* but we check it just in case as does good_expiry_and_qinfo(). */
if(qstate->env->cfg->serve_expired &&
!qstate->env->cfg->serve_expired_client_timeout &&
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
* refetch will be scheduled. */
if(*msg_expired && !qstate->env->cfg->serve_expired_client_timeout) {
qstate->need_refetch = 1;
}
@@ -647,7 +644,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
*/
static int
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
int* msg_expired)
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
@@ -664,7 +661,8 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
}
/* parse dns message into return_msg */
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired) ) {
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired,
msg_timestamp, msg_expiry) ) {
return 0;
}
return 1;
@@ -736,20 +734,24 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
* Store query into the internal cache of unbound.
*/
static void
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
time_t msg_timestamp, time_t msg_expiry)
{
uint32_t store_flags = qstate->query_flags;
int serve_expired = qstate->env->cfg->serve_expired;
if(qstate->env->cfg->serve_expired)
store_flags |= DNSCACHE_STORE_ZEROTTL;
if(!qstate->return_msg)
return;
if(serve_expired && msg_expired) {
/* Set TTLs to a value such that value + *env->now is
* going to be now-3 seconds. Making it expired
* in the cache. */
set_msg_ttl(qstate->return_msg, (time_t)-3);
time_t original_ttl = msg_expiry - msg_timestamp;
store_flags |= DNSCACHE_STORE_EXPIRED_MSG_CACHEDB;
/* Pass the original TTL of the expired message and signal with
* the DNSCACHE_STORE_EXPIRED_MSG_CACHEDB flag that
* dns_cache_store_msg() needs to set absolute expired TTLs
* based on the original message TTL.
* Results as expired message in the cache */
set_msg_ttl(qstate->return_msg, original_ttl, 0);
verbose(VERB_ALGO, "cachedb expired msg set to be expired now "
"(original ttl: %d)", (int)original_ttl);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
@@ -767,12 +769,14 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
* of cache. */
return;
}
/* set TTLs to zero again */
adjust_msg_ttl(qstate->return_msg, -1);
/* Send serve expired responses based on the cachedb
* returned message, that was just stored in the cache.
* It can then continue to work on this query. */
mesh_respond_serve_expired(qstate->mesh_info);
/* set TTLs as expired for this return_msg in case it is used
* later on */
set_msg_ttl(qstate->return_msg,
EXPIRED_REPLY_TTL_CALC(msg_expiry, msg_timestamp), 0);
}
}
@@ -790,6 +794,7 @@ cachedb_handle_query(struct module_qstate* qstate,
struct cachedb_env* ie, int id)
{
int msg_expired = 0;
time_t msg_timestamp, msg_expiry;
qstate->is_cachedb_answer = 0;
/* check if we are enabled, and skip if so */
if(!ie->enabled) {
@@ -824,13 +829,15 @@ cachedb_handle_query(struct module_qstate* qstate,
}
/* ask backend cache to see if we have data */
if(cachedb_extcache_lookup(qstate, ie, &msg_expired)) {
if(cachedb_extcache_lookup(qstate, ie, &msg_expired, &msg_timestamp,
&msg_expiry)) {
if(verbosity >= VERB_ALGO)
log_dns_msg(ie->backend->name,
&qstate->return_msg->qinfo,
qstate->return_msg->rep);
/* store this result in internal cache */
cachedb_intcache_store(qstate, msg_expired);
cachedb_intcache_store(qstate,
msg_expired, msg_timestamp, msg_expiry);
/* In case we have expired data but there is a client timer for expired
* answers, pass execution to next module in order to try updating the
* data first.
@@ -850,6 +857,8 @@ cachedb_handle_query(struct module_qstate* qstate,
qstate->ext_state[id] = module_wait_module;
return;
}
/* No 0TTL answers escaping from external cache. */
log_assert(qstate->return_msg->rep->ttl > 0);
qstate->is_cachedb_answer = 1;
/* we are done with the query */
qstate->ext_state[id] = module_finished;
+136 -14
View File
@@ -46,6 +46,8 @@
#include "cachedb/cachedb.h"
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/locks.h"
#include "util/timeval_func.h"
#include "sldns/sbuffer.h"
#ifdef USE_REDIS
@@ -75,6 +77,18 @@ struct redis_moddata {
/* timeout for connection setup */
struct timeval connect_timeout;
struct timeval replica_connect_timeout;
/* the reconnect interval time. */
struct timeval reconnect_interval;
struct timeval replica_reconnect_interval;
/* reconnect attempts, 0 if connected, counts up failed reconnects. */
int reconnect_attempts;
int replica_reconnect_attempts;
/* Lock on reconnect_wait time. */
lock_basic_type wait_lock;
lock_basic_type replica_wait_lock;
/* reconnect wait time, wait until it has passed before reconnect. */
struct timeval reconnect_wait;
struct timeval replica_reconnect_wait;
/* the redis logical database to use */
int logical_db;
int replica_logical_db;
@@ -82,6 +96,10 @@ struct redis_moddata {
int set_with_ex_available;
};
/** The limit on the number of redis connect attempts. After failure if
* the number is exceeded, the reconnects are throttled by the wait time. */
#define REDIS_RECONNECT_ATTEMPT_LIMIT 3
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t, int);
@@ -105,6 +123,8 @@ moddata_clean(struct redis_moddata** moddata) {
}
free((*moddata)->replica_ctxs);
}
lock_basic_destroy(&(*moddata)->wait_lock);
lock_basic_destroy(&(*moddata)->replica_wait_lock);
free(*moddata);
*moddata = NULL;
}
@@ -113,9 +133,44 @@ static redisContext*
redis_connect(const char* host, int port, const char* path,
const char* password, int logical_db,
const struct timeval connect_timeout,
const struct timeval command_timeout)
const struct timeval command_timeout,
const struct timeval* reconnect_interval,
int* reconnect_attempts,
struct timeval* reconnect_wait,
lock_basic_type* wait_lock,
struct timeval* now_tv,
const char* infostr)
{
struct timeval now_val;
redisContext* ctx;
#ifdef THREADS_DISABLED
/* Fix attribute unused warning.
* wait_lock is only used with lock_basic_* functions that are nop'ed
* when compiled without thread support. */
(void)wait_lock;
#endif /* THREADS_DISABLED */
/* See if the redis server is down, and reconnect has to wait. */
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Acquire lock to look at timeval, the integer has atomic
* integrity. */
struct timeval wait_tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
lock_basic_lock(wait_lock);
wait_tv = *reconnect_wait;
lock_basic_unlock(wait_lock);
if(timeval_smaller(&now_val, &wait_tv)) {
verbose(VERB_ALGO, "redis %sdown, reconnect wait",
infostr);
return NULL;
}
}
if(path && path[0]!=0) {
ctx = redisConnectUnixWithTimeout(path, connect_timeout);
@@ -126,18 +181,18 @@ redis_connect(const char* host, int port, const char* path,
const char *errstr = "out of memory";
if(ctx)
errstr = ctx->errstr;
log_err("failed to connect to redis server: %s", errstr);
log_err("failed to connect to redis %sserver: %s", infostr, errstr);
goto fail;
}
if(redisSetTimeout(ctx, command_timeout) != REDIS_OK) {
log_err("failed to set redis timeout, %s", ctx->errstr);
log_err("failed to set redis %stimeout, %s", infostr, ctx->errstr);
goto fail;
}
if(password && password[0]!=0) {
redisReply* rep;
rep = redisCommand(ctx, "AUTH %s", password);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to authenticate with password");
log_err("failed to authenticate %swith password", infostr);
freeReplyObject(rep);
goto fail;
}
@@ -147,18 +202,20 @@ redis_connect(const char* host, int port, const char* path,
redisReply* rep;
rep = redisCommand(ctx, "SELECT %d", logical_db);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to set logical database (%d)",
logical_db);
log_err("failed %sto set logical database (%d)",
infostr, logical_db);
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
*reconnect_attempts = 0;
if(verbosity >= VERB_OPS) {
char port_str[6+1];
port_str[0] = ' ';
(void)snprintf(port_str+1, sizeof(port_str)-1, "%d", port);
verbose(VERB_OPS, "Connection to Redis established (%s%s)",
verbose(VERB_OPS, "Connection to Redis %sestablished (%s%s)",
infostr,
path&&path[0]!=0?path:host,
path&&path[0]!=0?"":port_str);
}
@@ -167,6 +224,25 @@ redis_connect(const char* host, int port, const char* path,
fail:
if(ctx)
redisFree(ctx);
(*reconnect_attempts)++;
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Wait for the reconnect interval before trying again. */
struct timeval tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
tv = now_val;
timeval_add(&tv, reconnect_interval);
lock_basic_lock(wait_lock);
*reconnect_wait = tv;
lock_basic_unlock(wait_lock);
verbose(VERB_ALGO, "redis %sreconnect wait until %d.%6.6d",
infostr, (int)tv.tv_sec, (int)tv.tv_usec);
}
return NULL;
}
@@ -191,6 +267,13 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("out of memory");
goto fail;
}
lock_basic_init(&moddata->wait_lock);
lock_protect(&moddata->wait_lock, &moddata->reconnect_wait,
sizeof(moddata->reconnect_wait));
lock_basic_init(&moddata->replica_wait_lock);
lock_protect(&moddata->replica_wait_lock,
&moddata->replica_reconnect_wait,
sizeof(moddata->replica_reconnect_wait));
moddata->numctxs = env->cfg->num_threads;
/* note: server_host and similar string configuration options are
* shallow references to configured strings; we don't have to free them
@@ -219,6 +302,8 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
set_timeout(&moddata->replica_connect_timeout,
env->cfg->redis_replica_timeout,
env->cfg->redis_replica_connect_timeout);
set_timeout(&moddata->reconnect_interval, 1000, 0);
set_timeout(&moddata->replica_reconnect_interval, 1000, 0);
moddata->logical_db = env->cfg->redis_logical_db;
moddata->replica_logical_db = env->cfg->redis_replica_logical_db;
@@ -245,7 +330,13 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->server_password,
moddata->logical_db,
moddata->connect_timeout,
moddata->command_timeout);
moddata->command_timeout,
&moddata->reconnect_interval,
&moddata->reconnect_attempts,
&moddata->reconnect_wait,
&moddata->wait_lock,
env->now_tv,
"");
if(!ctx) {
log_err("redis_init: failed to init redis "
"(for thread %d)", i);
@@ -263,7 +354,13 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->replica_server_password,
moddata->replica_logical_db,
moddata->replica_connect_timeout,
moddata->replica_command_timeout);
moddata->replica_command_timeout,
&moddata->replica_reconnect_interval,
&moddata->replica_reconnect_attempts,
&moddata->replica_reconnect_wait,
&moddata->replica_wait_lock,
env->now_tv,
"replica ");
if(!ctx) {
log_err("redis_init: failed to init redis "
"replica (for thread %d)", i);
@@ -301,7 +398,7 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
set_with_ex_fail:
log_err("redis_init: failure during redis_init, the "
"redis-expire-records option requires the SET with EX command "
"(redis >= 2.6.2)");
"(redis >= 2.6.12)");
return 1;
fail:
moddata_clean(&moddata);
@@ -364,7 +461,13 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
d->replica_server_password,
d->replica_logical_db,
d->replica_connect_timeout,
d->replica_command_timeout);
d->replica_command_timeout,
&d->replica_reconnect_interval,
&d->replica_reconnect_attempts,
&d->replica_reconnect_wait,
&d->replica_wait_lock,
env->now_tv,
"replica ");
} else {
ctx = redis_connect(
d->server_host,
@@ -373,7 +476,13 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
d->server_password,
d->logical_db,
d->connect_timeout,
d->command_timeout);
d->command_timeout,
&d->reconnect_interval,
&d->reconnect_attempts,
&d->reconnect_wait,
&d->wait_lock,
env->now_tv,
"");
}
ctx_selector[env->alloc->thread_num] = ctx;
}
@@ -405,7 +514,14 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, struct sldns_buffer* result_buffer)
{
redisReply* rep;
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
/* Supported commands:
* - "GET " + key
*/
#define REDIS_LOOKUP_MAX_BUF_LEN \
4 /* "GET " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 1 /* \0 */
char cmdbuf[REDIS_LOOKUP_MAX_BUF_LEN];
int n;
int ret = 0;
@@ -465,7 +581,13 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
* older redis 2.0.0 was "SETEX " + key + " " + ttl + " %b"
* - "EXPIRE " + key + " 0"
*/
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
#define REDIS_STORE_MAX_BUF_LEN \
7 /* "EXPIRE " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 7 /* " %b EX " */ \
+ 20 /* ttl (uint64_t) */ \
+ 1 /* \0 */
char cmdbuf[REDIS_STORE_MAX_BUF_LEN];
if (!set_ttl) {
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
+3 -3
View File
@@ -57,7 +57,7 @@ int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host
}
if (host != NULL) {
if (flags & NI_NUMERICHOST) {
if ((flags & NI_NUMERICHOST)) {
if (strlcpy(host, inet_ntoa(sin->sin_addr),
hostlen) >= hostlen)
return (EAI_MEMORY);
@@ -168,7 +168,7 @@ getaddrinfo(const char *hostname, const char *servname,
port = 0;
}
if (hints && hints->ai_flags & AI_PASSIVE) {
if (hints && (hints->ai_flags & AI_PASSIVE)) {
addr = htonl(0x00000000);
if (hostname && inet_aton(hostname, &in) != 0)
addr = in.s_addr;
@@ -193,7 +193,7 @@ getaddrinfo(const char *hostname, const char *servname,
}
/* Don't try DNS if AI_NUMERICHOST is set */
if (hints && hints->ai_flags & AI_NUMERICHOST)
if (hints && (hints->ai_flags & AI_NUMERICHOST))
return (EAI_NONAME);
hp = gethostbyname(hostname);
+33
View File
@@ -66,6 +66,9 @@
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "nonstring" attribute */
#undef HAVE_ATTR_NONSTRING
/* Whether the C compiler accepts the "noreturn" attribute */
#undef HAVE_ATTR_NORETURN
@@ -173,6 +176,10 @@
0 if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0
if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
don't. */
#undef HAVE_DECL_STRLCAT
@@ -249,6 +256,9 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MAC_CTX_new' function. */
#undef HAVE_EVP_MAC_CTX_NEW
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
@@ -330,6 +340,9 @@
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
#undef HAVE_HIREDIS_HIREDIS_H
/* Define to 1 if you have the `HMAC_CTX_new' function. */
#undef HAVE_HMAC_CTX_NEW
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX
@@ -477,6 +490,9 @@
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
/* Define to 1 if you have the `ngtcp2_crypto_quictls_init' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_INIT
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
@@ -484,6 +500,9 @@
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_ossl.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
@@ -1023,6 +1042,9 @@
/* Define this to enable client TCP Fast Open. */
#undef USE_MSG_FASTOPEN
/* Define this to use ngtcp2_crypto_ossl. */
#undef USE_NGTCP2_CRYPTO_OSSL
/* Define this to enable client TCP Fast Open. */
#undef USE_OSX_MSG_FASTOPEN
@@ -1371,6 +1393,17 @@
#endif /* !HAVE_ATTR_UNUSED */
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
#ifndef HAVE_FSEEKO
#define fseeko fseek
#define ftello ftell
Vendored
+653 -194
View File
File diff suppressed because it is too large Load Diff
+45 -24
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],[23])
m4_define([VERSION_MICRO],[1])
m4_define([VERSION_MINOR],[24])
m4_define([VERSION_MICRO],[2])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=32
LIBUNBOUND_REVISION=35
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -119,6 +119,9 @@ LIBUNBOUND_AGE=1
# 1.22.0 had 9:30:1
# 1.23.0 had 9:31:1
# 1.23.1 had 9:32:1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# 1.24.2 had 9:35:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -327,6 +330,7 @@ fi
AC_C_INLINE
ACX_CHECK_FORMAT_ATTRIBUTE
ACX_CHECK_UNUSED_ATTRIBUTE
ACX_CHECK_NONSTRING_ATTRIBUTE
AC_DEFUN([CHECK_WEAK_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
@@ -632,19 +636,19 @@ AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ e
if test x_$enable_alloc_nonregional = x_yes; then
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
fi
if test x_$enable_alloc_checks = x_yes; then
AS_IF([test x_$enable_alloc_checks = x_yes],[
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
else
if test x_$enable_alloc_lite = x_yes; then
],[
AS_IF([test x_$enable_alloc_lite = x_yes],[
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
else
],[
ACX_FUNC_MALLOC([unbound])
fi
fi
])
])
# check windows threads (we use them, not pthreads, on windows).
if test "$on_mingw" = "yes"; then
@@ -996,7 +1000,7 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh HMAC_CTX_new EVP_MAC_CTX_new])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
@@ -1004,7 +1008,7 @@ LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
@@ -1250,7 +1254,7 @@ case "$enable_ecdsa" in
# see if OPENSSL 1.0.0 or later (has EVP MD and Verify independency)
AC_MSG_CHECKING([if openssl supports SHA2 and ECDSA with EVP])
if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then
if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then
if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then
AC_MSG_RESULT([no])
AC_DEFINE_UNQUOTED([USE_ECDSA_EVP_WORKAROUND], [1], [Define this to enable an EVP workaround for older openssl])
else
@@ -1610,17 +1614,29 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
if test x_$found_libngtcp2 != x_yes; then
AC_MSG_ERROR([Could not find libngtcp2, ngtcp2.h])
fi
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_ossl.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([ngtcp2_conn_server_new], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_CHECK_DECLS([ngtcp2_crypto_encrypt_cb], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2_crypto.h>
])
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ])
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
AC_CHECK_LIB([ngtcp2_crypto_ossl], [ngtcp2_crypto_encrypt_cb], [
LIBS="$LIBS -lngtcp2_crypto_ossl"
AC_DEFINE(USE_NGTCP2_CRYPTO_OSSL, 1, [Define this to use ngtcp2_crypto_ossl.])
], [
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ], [
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
])
])
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_crypto_quictls_init ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])])
LIBS="$BAKLIBS"
AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
@@ -1658,10 +1674,12 @@ if test x_$enable_static_exe = x_yes; then
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
if echo "$host" | $GREP -i -e linux >/dev/null; then
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
fi
fi
fi
fi
@@ -1679,10 +1697,12 @@ if test x_$enable_fully_static = x_yes; then
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
if echo "$host" | $GREP -i -e linux >/dev/null; then
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
fi
fi
fi
fi
@@ -2278,6 +2298,7 @@ dnl includes
AHX_CONFIG_FORMAT_ATTRIBUTE
AHX_CONFIG_UNUSED_ATTRIBUTE
AHX_CONFIG_NONSTRING_ATTRIBUTE
AHX_CONFIG_FSEEKO
AHX_CONFIG_MAXHOSTNAMELEN
#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
+49 -49
View File
@@ -1,10 +1,10 @@
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index 5a75e319..c6c6dbe2 100644
index 172eb26c..2921c87f 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -970,6 +970,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is no.
@@ -2146,6 +2146,13 @@ Default: no
.UNINDENT
.INDENT 0.0
.TP
+.B aaaa\-filter: \fI<yes or no>
+Activate behavior similar to BIND's AAAA-filter.
@@ -13,14 +13,14 @@ index 5a75e319..c6c6dbe2 100644
+This also causes an additional A query to be sent for each AAAA query.
+This breaks DNSSEC!
+.TP
.B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
and other denials, using information from previous NXDOMAINs answers.
.B aggressive\-nsec: \fI<yes or no>\fP
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN and other
denials, using information from previous NXDOMAINs answers.
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
index f093c1bf..e55a2246 100644
index 49a5f5da..fbe434fa 100644
--- a/iterator/iter_scrub.c
+++ b/iterator/iter_scrub.c
@@ -679,6 +679,32 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
@@ -849,6 +849,32 @@ scrub_sanitize_rr_length(sldns_buffer* pkt, struct msg_parse* msg,
return 0;
}
@@ -53,15 +53,15 @@ index f093c1bf..e55a2246 100644
/**
* Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects
@@ -698,6 +724,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
@@ -869,6 +895,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie)
struct iter_env* ie, struct module_qstate* qstate)
{
+ int found_a_record = 0; /* ASN: do we have a A record? */
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
struct rrset_parse* rrset, *prev;
@@ -733,6 +760,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
uint8_t* ns_rrset_dname = NULL;
@@ -906,6 +933,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = rrset->rrset_all_next;
}
@@ -75,9 +75,9 @@ index f093c1bf..e55a2246 100644
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
@@ -744,6 +778,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = msg->rrset_first;
while(rrset) {
@@ -925,6 +959,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
+ /* ASN: For AAAA records only... */
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
@@ -101,10 +101,10 @@ index f093c1bf..e55a2246 100644
if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA)) {
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 2482a1f4..bd5ba243 100644
index 1da21896..6583dd0e 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -177,6 +177,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
@@ -250,6 +250,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
@@ -113,12 +113,12 @@ index 2482a1f4..bd5ba243 100644
}
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 54006940..768fe202 100644
index 71e64655..735f4ca0 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -2155,6 +2155,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
return 0;
@@ -2412,6 +2412,53 @@ check_waiting_queries(struct iter_qstate* iq, struct module_qstate* qstate,
qstate->ext_state[id] = module_wait_reply;
}
}
+
+/**
@@ -170,8 +170,8 @@ index 54006940..768fe202 100644
/**
* This is the request event state where the request will be sent to one of
@@ -2216,6 +2263,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
@@ -2554,6 +2601,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
+ /* ASN: If we have a AAAA query, then also query for A records */
@@ -184,7 +184,7 @@ index 54006940..768fe202 100644
/* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */
if(!iq->dp) {
@@ -3648,6 +3702,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -4178,6 +4232,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
@@ -246,7 +246,7 @@ index 54006940..768fe202 100644
/*
* Return priming query results to interested super querystates.
*
@@ -3667,6 +3776,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
@@ -4197,6 +4306,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super);
@@ -256,7 +256,7 @@ index 54006940..768fe202 100644
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super);
else if(qstate->is_priming)
@@ -3704,6 +3816,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -4234,6 +4346,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id);
break;
@@ -266,7 +266,7 @@ index 54006940..768fe202 100644
case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id);
break;
@@ -4040,6 +4155,8 @@ iter_state_to_string(enum iter_state state)
@@ -4578,6 +4693,8 @@ iter_state_to_string(enum iter_state state)
return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)";
@@ -275,7 +275,7 @@ index 54006940..768fe202 100644
case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE";
case PRIME_RESP_STATE :
@@ -4064,6 +4181,7 @@ iter_state_is_responsestate(enum iter_state s)
@@ -4602,6 +4719,7 @@ iter_state_is_responsestate(enum iter_state s)
case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE :
@@ -284,10 +284,10 @@ index 54006940..768fe202 100644
case COLLECT_CLASS_STATE :
return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h
index 8b840528..a61c4195 100644
index ae4b4e45..a44f9d27 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -133,6 +133,9 @@ struct iter_env {
@@ -157,6 +157,9 @@ struct iter_env {
*/
int* target_fetch_policy;
@@ -297,7 +297,7 @@ index 8b840528..a61c4195 100644
/** lock on ratelimit counter */
lock_basic_type queries_ratelimit_lock;
/** number of queries that have been ratelimited */
@@ -187,6 +190,14 @@ enum iter_state {
@@ -217,6 +220,14 @@ enum iter_state {
*/
INIT_REQUEST_3_STATE,
@@ -312,9 +312,9 @@ index 8b840528..a61c4195 100644
/**
* Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited.
@@ -376,6 +387,13 @@ struct iter_qstate {
*/
int refetch_glue;
@@ -434,6 +445,13 @@ struct iter_qstate {
* already so that it is accepted later. */
int empty_nodata_found;
+ /**
+ * ASN: This is a flag that, if true, means that this query is
@@ -327,10 +327,10 @@ index 8b840528..a61c4195 100644
struct outbound_list outlist;
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index 1ca8686a..d91b19ec 100644
index 2040fb9e..f073c3dc 100644
--- a/pythonmod/interface.i
+++ b/pythonmod/interface.i
@@ -995,6 +995,7 @@ struct config_file {
@@ -1013,6 +1013,7 @@ struct config_file {
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
@@ -339,23 +339,23 @@ index 1ca8686a..d91b19ec 100644
struct config_strlist* private_domain;
size_t unwanted_threshold;
diff --git a/util/config_file.c b/util/config_file.c
index 969d664b..8d94b008 100644
index b1e767b3..5eb3c099 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -231,6 +231,7 @@ config_create(void)
cfg->harden_referral_path = 0;
@@ -247,6 +247,7 @@ config_create(void)
cfg->harden_algo_downgrade = 0;
cfg->harden_unknown_additional = 0;
cfg->use_caps_bits_for_id = 0;
+ cfg->aaaa_filter = 0; /* ASN: default is disabled */
cfg->caps_whitelist = NULL;
cfg->private_address = NULL;
cfg->private_domain = NULL;
diff --git a/util/config_file.h b/util/config_file.h
index c7c9a0a4..e3aa15b0 100644
index 44ac036b..1e59ab07 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -285,6 +285,8 @@ struct config_file {
int harden_algo_downgrade;
@@ -311,6 +311,8 @@ struct config_file {
int harden_unknown_additional;
/** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id;
+ /** ASN: enable AAAA filter? */
@@ -364,10 +364,10 @@ index c7c9a0a4..e3aa15b0 100644
struct config_strlist* caps_whitelist;
/** strip away these private addrs from answers, no DNS Rebinding */
diff --git a/util/configlexer.lex b/util/configlexer.lex
index 34a0e5dd..c890be2a 100644
index bc258673..76aab170 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -317,6 +317,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
@@ -327,6 +327,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
@@ -376,10 +376,10 @@ index 34a0e5dd..c890be2a 100644
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
diff --git a/util/configparser.y b/util/configparser.y
index d4f965f9..8cc237c6 100644
index 82e1d878..dc19bed5 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
@@ -100,6 +100,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
@@ -387,7 +387,7 @@ index d4f965f9..8cc237c6 100644
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -247,6 +248,7 @@ content_server: server_num_threads | server_verbosity | server_port |
@@ -276,6 +277,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics |
@@ -395,7 +395,7 @@ index d4f965f9..8cc237c6 100644
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
@@ -1754,6 +1756,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
@@ -1932,6 +1934,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
yyerror("out of memory");
}
;
+7 -5
View File
@@ -1,21 +1,22 @@
#!/usr/bin/env bash
OPENSSL_VERSION=1.1.1d
echo "Downloading OpenSSL"
if ! curl -L -k -s -o openssl-1.1.1d.tar.gz https://www.openssl.org/source/openssl-1.1.1d.tar.gz;
if ! curl -L -k -s -o openssl-$OPENSSL_VERSION.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz;
then
echo "Failed to download OpenSSL"
exit 1
fi
echo "Unpacking OpenSSL"
rm -rf ./openssl-1.1.1d
if ! tar -xf openssl-1.1.1d.tar.gz;
rm -rf ./openssl-$OPENSSL_VERSION
if ! tar -xf openssl-$OPENSSL_VERSION.tar.gz;
then
echo "Failed to unpack OpenSSL"
exit 1
fi
cd openssl-1.1.1d || exit 1
cd openssl-$OPENSSL_VERSION || exit 1
if ! cp ../contrib/ios/15-ios.conf Configurations/; then
echo "Failed to copy OpenSSL ios config"
@@ -27,7 +28,8 @@ fi
# Also see https://github.com/openssl/openssl/issues/7607.
if ! patch -u -p0 < ../contrib/ios/openssl.patch; then
echo "Failed to patch OpenSSL"
exit 1
# the partial patch may be useful.
#exit 1
fi
echo "Configuring OpenSSL"
+5
View File
@@ -175,6 +175,7 @@ fi
# For example, remove 4.3, 6.2, and 6.1 if they are not installed. We go back to
# the 1.0 SDKs because Apple WatchOS uses low numbers, like 2.0 and 2.1.
XCODE_SDK=
if test -z "$SDK_VERSION"; then
for i in $(seq -f "%.1f" 30.0 -0.1 1.0)
do
if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then
@@ -182,6 +183,10 @@ do
break
fi
done
else
i="$SDK_VERSION"
XCODE_SDK="$IOS_SDK$i.sdk"
fi
# Error checking
if [ -z "$XCODE_SDK" ]; then
+7 -1
View File
@@ -38,11 +38,17 @@
; - `LockPersonality=yes` locks down the personality system call so that the
; kernel execution domain may not be changed from the default.
;
; - With /etc/systemd/network/*.network a setting to make sure the network
; is not considered online too early, can reduce network unreachable
; errors on server start:
; [Link]
; RequiredForOnline=routable
;
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Wants=network-online.target
Before=nss-lookup.target
[Install]
@@ -53,7 +59,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+1 -1
View File
@@ -26,7 +26,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+234 -105
View File
@@ -62,84 +62,231 @@
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
static void spool_txt_printf(struct config_strlist_head* txt,
const char* format, ...) ATTR_FORMAT(printf, 2, 3);
/** Append to strlist at end, and log error if out of memory. */
static void
spool_txt_string(struct config_strlist_head* txt, char* str)
{
if(!cfg_strlist_append(txt, strdup(str))) {
log_err("out of memory in spool text");
}
}
/** Spool txt to spool list. */
static void
spool_txt_vmsg(struct config_strlist_head* txt, const char* format,
va_list args)
{
char msg[65535];
vsnprintf(msg, sizeof(msg), format, args);
spool_txt_string(txt, msg);
}
/** Print item to spool list. On alloc failure the list is as before. */
static void
spool_txt_printf(struct config_strlist_head* txt, const char* format, ...)
{
va_list args;
va_start(args, format);
spool_txt_vmsg(txt, format, args);
va_end(args);
}
/** dump one rrset zonefile line */
static int
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
static void
dump_rrset_line(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
time_t now, size_t i)
{
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
return ssl_printf(ssl, "BADRR\n");
spool_txt_string(txt, "BADRR\n");
return;
}
return ssl_printf(ssl, "%s", s);
spool_txt_string(txt, s);
}
/** dump rrset key and data info */
static int
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
static void
dump_rrset(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now)
{
size_t i;
/* rd lock held by caller */
if(!k || !d) return 1;
if(k->id == 0) return 1; /* deleted */
if(d->ttl < now) return 1; /* expired */
if(!k || !d) return;
if(k->id == 0) return; /* deleted */
if(d->ttl < now) return; /* expired */
/* meta line */
if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
spool_txt_printf(txt, ";rrset%s " ARG_LL "d %u %u %d %d\n",
(k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
(long long)(d->ttl - now),
(unsigned)d->count, (unsigned)d->rrsig_count,
(int)d->trust, (int)d->security
))
return 0;
);
for(i=0; i<d->count + d->rrsig_count; i++) {
if(!dump_rrset_line(ssl, k, now, i))
dump_rrset_line(txt, k, now, i);
}
}
/** Spool strlist to the output. */
static int
spool_strlist(RES* ssl, struct config_strlist* list)
{
struct config_strlist* s;
for(s=list; s; s=s->next) {
if(!ssl_printf(ssl, "%s", s->str))
return 0;
}
return 1;
}
/** dump lruhash rrset cache */
/** dump lruhash cache and call callback for every item. */
static int
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
dump_lruhash(struct lruhash* table,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
{
struct lruhash_entry* e;
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
lock_rw_rdlock(&e->lock);
if(!dump_rrset(ssl, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data, now)) {
lock_rw_unlock(&e->lock);
int just_started = 1;
int not_done = 1;
hashvalue_type hash;
size_t num = 0; /* number of entries processed. */
size_t max = 2; /* number of entries after which it unlocks. */
struct config_strlist_head txt; /* Text strings spooled. */
memset(&txt, 0, sizeof(txt));
while(not_done) {
size_t i; /* hash bin. */
/* Process a number of items. */
num = 0;
lock_quick_lock(&table->lock);
if(just_started) {
i = 0;
} else {
i = hash&table->size_mask;
}
while(num < max) {
/* Process bin. */
int found = 0;
size_t num_bin = 0;
struct lruhash_bin* bin = &table->array[i];
struct lruhash_entry* e;
lock_quick_lock(&bin->lock);
for(e = bin->overflow_list; e; e = e->overflow_next) {
/* Entry e is locked by the func. */
func(e, &txt, arg);
num_bin++;
}
lock_quick_unlock(&bin->lock);
/* This addition of bin number of entries may take
* it over the max. */
num += num_bin;
/* Move to next bin. */
/* Find one with an entry, with a hash value, so we
* can continue from the hash value. The hash value
* can be indexed also if the array changes size. */
i++;
while(i < table->size) {
bin = &table->array[i];
lock_quick_lock(&bin->lock);
if(bin->overflow_list) {
hash = bin->overflow_list->hash;
lock_quick_unlock(&bin->lock);
found = 1;
just_started = 0;
break;
}
lock_quick_unlock(&bin->lock);
i++;
}
if(!found) {
not_done = 0;
break;
}
}
lock_quick_unlock(&table->lock);
/* Print the spooled items, that are collected while the
* locks are locked. The print happens while they are not
* locked. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
return 0;
}
config_delstrlist(txt.first);
memset(&txt, 0, sizeof(txt));
}
}
/* Print the final spooled items. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
return 0;
}
lock_rw_unlock(&e->lock);
config_delstrlist(txt.first);
}
return 1;
}
/** dump slabhash cache and call callback for every item. */
static int
dump_slabhash(struct slabhash* sh,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
{
/* Process a number of items at a time, then unlock the cache,
* so that ordinary processing can continue. Keep an iteration marker
* to continue the loop. That means the cache can change, items
* could be inserted and deleted. And, for example, the hash table
* can grow. */
size_t slab;
for(slab=0; slab<sh->size; slab++) {
if(!dump_lruhash(sh->array[slab], func, ssl, arg))
return 0;
}
return 1;
}
/** Struct for dump information. */
struct dump_info {
/** The worker. */
struct worker* worker;
/** The printout connection. */
RES* ssl;
};
/** Dump the rrset cache entry */
static void
dump_rrset_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
{
struct dump_info* dump_info = (struct dump_info*)arg;
lock_rw_rdlock(&e->lock);
dump_rrset(txt, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data,
*dump_info->worker->env.now);
lock_rw_unlock(&e->lock);
}
/** dump rrset cache */
static int
dump_rrset_cache(RES* ssl, struct worker* worker)
{
struct rrset_cache* r = worker->env.rrset_cache;
size_t slab;
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
if(!ssl_printf(ssl, "START_RRSET_CACHE\n")) return 0;
for(slab=0; slab<r->table.size; slab++) {
lock_quick_lock(&r->table.array[slab]->lock);
if(!dump_rrset_lruhash(ssl, r->table.array[slab],
*worker->env.now)) {
lock_quick_unlock(&r->table.array[slab]->lock);
return 0;
}
lock_quick_unlock(&r->table.array[slab]->lock);
}
if(!dump_slabhash(&r->table, &dump_rrset_entry, ssl, &dump_info))
return 0;
return ssl_printf(ssl, "END_RRSET_CACHE\n");
}
/** dump message to rrset reference */
static int
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
static void
dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
{
char* nm, *tp, *cl;
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
@@ -149,30 +296,25 @@ dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
free(nm);
free(tp);
free(cl);
return ssl_printf(ssl, "BADREF\n");
}
if(!ssl_printf(ssl, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags)) {
free(nm);
free(tp);
free(cl);
return 0;
spool_txt_string(txt, "BADREF\n");
return;
}
spool_txt_printf(txt, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags);
free(nm);
free(tp);
free(cl);
return 1;
}
/** dump message entry */
static int
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
static void
dump_msg(struct config_strlist_head* txt, struct query_info* k,
struct reply_info* d, time_t now)
{
size_t i;
char* nm, *tp, *cl;
if(!k || !d) return 1;
if(d->ttl < now) return 1; /* expired */
if(!k || !d) return;
if(d->ttl < now) return; /* expired */
nm = sldns_wire2str_dname(k->qname, k->qname_len);
tp = sldns_wire2str_type(k->qtype);
cl = sldns_wire2str_class(k->qclass);
@@ -180,45 +322,35 @@ dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
free(nm);
free(tp);
free(cl);
return 1; /* skip this entry */
return; /* skip this entry */
}
if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
/* rrsets have timed out or do not exist */
free(nm);
free(tp);
free(cl);
return 1; /* skip this entry */
return; /* skip this entry */
}
/* meta line */
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"")) {
free(nm);
free(tp);
free(cl);
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
spool_txt_printf(txt,
"msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"");
free(nm);
free(tp);
free(cl);
for(i=0; i<d->rrset_count; i++) {
if(!dump_msg_ref(ssl, d->rrsets[i])) {
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
dump_msg_ref(txt, d->rrsets[i]);
}
rrset_array_unlock(d->ref, d->rrset_count);
return 1;
}
/** copy msg to worker pad */
@@ -247,49 +379,40 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
return (*k)->qname != NULL;
}
/** dump lruhash msg cache */
static int
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
/** Dump the msg entry. */
static void
dump_msg_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
{
struct lruhash_entry* e;
struct dump_info* dump_info = (struct dump_info*)arg;
struct query_info* k;
struct reply_info* d;
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
regional_free_all(worker->scratchpad);
lock_rw_rdlock(&e->lock);
/* make copy of rrset in worker buffer */
if(!copy_msg(worker->scratchpad, e, &k, &d)) {
lock_rw_unlock(&e->lock);
return 0;
}
regional_free_all(dump_info->worker->scratchpad);
/* Make copy of rrset in worker buffer. */
lock_rw_rdlock(&e->lock);
if(!copy_msg(dump_info->worker->scratchpad, e, &k, &d)) {
lock_rw_unlock(&e->lock);
/* release lock so we can lookup the rrset references
* in the rrset cache */
if(!dump_msg(ssl, k, d, *worker->env.now)) {
return 0;
}
log_err("out of memory in dump_msg_entry");
return;
}
return 1;
lock_rw_unlock(&e->lock);
/* Release lock so we can lookup the rrset references
* in the rrset cache. */
dump_msg(txt, k, d, *dump_info->worker->env.now);
}
/** dump msg cache */
static int
dump_msg_cache(RES* ssl, struct worker* worker)
{
struct slabhash* sh = worker->env.msg_cache;
size_t slab;
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
if(!ssl_printf(ssl, "START_MSG_CACHE\n")) return 0;
for(slab=0; slab<sh->size; slab++) {
lock_quick_lock(&sh->array[slab]->lock);
if(!dump_msg_lruhash(ssl, worker, sh->array[slab])) {
lock_quick_unlock(&sh->array[slab]->lock);
return 0;
}
lock_quick_unlock(&sh->array[slab]->lock);
}
if(!dump_slabhash(worker->env.msg_cache, &dump_msg_entry, ssl,
&dump_info))
return 0;
return ssl_printf(ssl, "END_MSG_CACHE\n");
}
@@ -811,12 +934,18 @@ print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
struct packed_rrset_data* d =
(struct packed_rrset_data*)k->entry.data;
struct config_strlist_head txt;
memset(&txt, 0, sizeof(txt));
if(d->security == sec_status_bogus) {
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
return;
}
if(!dump_rrset(ssl, k, d, 0))
dump_rrset(&txt, k, d, 0);
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
return;
}
config_delstrlist(txt.first);
}
delegpt_count_ns(dp, &n_ns, &n_miss);
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
+36 -1
View File
@@ -77,6 +77,7 @@
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h"
#include "util/allow_response_list.h"
#include "util/edns.h"
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
@@ -89,6 +90,7 @@
#include "util/random.h"
#include "util/tube.h"
#include "util/net_help.h"
#include "util/tsig.h"
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include "iterator/iter_fwd.h"
@@ -297,6 +299,16 @@ daemon_init(void)
free(daemon);
return NULL;
}
daemon->arl = arl_list_create();
if(!daemon->arl) {
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
listen_setup_locks();
if(gettimeofday(&daemon->time_boot, NULL) < 0)
log_err("gettimeofday: %s", strerror(errno));
@@ -305,6 +317,7 @@ daemon_init(void)
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
@@ -315,11 +328,24 @@ daemon_init(void)
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
if(!(daemon->env->tsig_key_table = tsig_key_table_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
edns_known_options_delete(daemon->env);
edns_strings_delete(daemon->env->edns_strings);
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@@ -729,6 +755,8 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not setup interface control list");
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
if(!arl_list_apply_cfg(daemon->arl, daemon->cfg))
fatal_exit("Could not setup allow response list");
if(daemon->cfg->dnscrypt) {
#ifdef USE_DNSCRYPT
daemon->dnscenv = dnsc_create();
@@ -771,12 +799,17 @@ daemon_fork(struct daemon* daemon)
daemon->use_response_ip = !respip_set_is_empty(
daemon->env->respip_set) || have_view_respip_cfg;
/* setup tsig keys */
if(!tsig_key_table_apply_cfg(daemon->env->tsig_key_table, daemon->cfg))
fatal_exit("Could not set up TSIG keys");
/* setup modules */
daemon_setup_modules(daemon);
/* read auth zonefiles */
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
&daemon->use_rpz, daemon->env, &daemon->mods))
&daemon->use_rpz, daemon->env, &daemon->mods,
daemon->env->tsig_key_table))
fatal_exit("auth_zones could not be setup");
/* Set-up EDNS strings */
@@ -944,12 +977,14 @@ daemon_delete(struct daemon* daemon)
edns_known_options_delete(daemon->env);
edns_strings_delete(daemon->env->edns_strings);
auth_zones_delete(daemon->env->auth_zones);
tsig_key_table_delete(daemon->env->tsig_key_table);
}
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
acl_list_delete(daemon->acl);
acl_list_delete(daemon->acl_interface);
tcl_list_delete(daemon->tcl);
arl_list_delete(daemon->arl);
cookie_secrets_delete(daemon->cookie_secrets);
listen_desetup_locks();
free(daemon->chroot);
+2
View File
@@ -133,6 +133,8 @@ struct daemon {
struct acl_list* acl_interface;
/** TCP connection limit, limit connections from client IPs */
struct tcl_list* tcl;
/** allow response list, to cache responses send by client IPs */
struct arl_list* arl;
/** local authority zones */
struct local_zones* local_zones;
/** last time of statistics printout */
+615 -207
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -273,6 +273,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
/* add in the values from the mesh */
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.val_ops += (long long)worker->env.mesh->val_ops;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
for(i=0; i<UB_STATS_RCODE_NUM; i++)
@@ -495,6 +496,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
total->svr.ans_secure += a->svr.ans_secure;
total->svr.ans_bogus += a->svr.ans_bogus;
total->svr.val_ops += a->svr.val_ops;
total->svr.unwanted_replies += a->svr.unwanted_replies;
total->svr.unwanted_queries += a->svr.unwanted_queries;
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
+5 -6
View File
@@ -174,7 +174,7 @@ static void
checkrlimits(struct config_file* cfg)
{
#ifndef S_SPLINT_S
#ifdef HAVE_GETRLIMIT
#if defined(HAVE_GETRLIMIT) && !defined(unbound_testbound)
/* list has number of ports to listen to, ifs number addresses */
int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 +
(int)cfg->incoming_num_tcp:0));
@@ -463,23 +463,21 @@ detach(void)
#endif /* HAVE_DAEMON */
}
#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)
{
#ifdef HAVE_SSL
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))) {
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen SSL_CTX");
}
#else /* HAVE_SSL */
(void)ctx;(void)is_dot;(void)is_doh;(void)cfg;
#endif /* HAVE_SSL */
}
#endif /* HAVE_SSL */
/* setups the needed ssl contexts, fatal_exit() on any failure */
static void
@@ -747,6 +745,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
"the commandline to see more errors, "
"or unbound-checkconf", cfgfile);
log_warn("Continuing with default config settings");
config_auto_slab_values(cfg);
}
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
if(!done_setup)
+200 -43
View File
@@ -43,6 +43,7 @@
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
#include "util/tsig.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
#include "daemon/remote.h"
@@ -67,6 +68,7 @@
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#include "util/proxy_protocol.h"
#include "util/tsig.h"
#include "util/tube.h"
#include "util/edns.h"
#include "util/timeval_func.h"
@@ -78,11 +80,13 @@
#include "respip/respip.h"
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
#include "dnstap/dtstream.h"
#include "util/allow_response_list.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -272,6 +276,11 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
return 0;
}
#define REQUEST_OK 0
#define DROP_REQUEST -1
#define RESPONSE_MESSAGE -2
/** ratelimit error replies
* @param worker: the worker struct with ratelimit counter
* @param err: error code that would be wanted.
@@ -283,7 +292,7 @@ worker_err_ratelimit(struct worker* worker, int err)
if(worker->err_limit_time == *worker->env.now) {
/* see if limit is exceeded for this second */
if(worker->err_limit_count++ > ERROR_RATELIMIT)
return -1;
return DROP_REQUEST;
} else {
/* new second, new limits */
worker->err_limit_time = *worker->env.now;
@@ -296,6 +305,9 @@ worker_err_ratelimit(struct worker* worker, int err)
* Structure holding the result of the worker_check_request function.
* Based on configuration it could be called up to four times; ideally should
* be called once.
* When value is a positive number, it contains the error to return.
* Otherwise DROP_REQUEST (-1) is returned, or RESPONSE_MESSAGE (-2) in
* case the qr bit was set. Value is set to REQUEST_OK (0) if all is good.
*/
struct check_request_result {
int checked;
@@ -314,18 +326,18 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
out->checked = 1;
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
verbose(VERB_QUERY, "request too short, discarded");
out->value = -1;
out->value = DROP_REQUEST;
return;
}
if(sldns_buffer_limit(pkt) > NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_large_queries) {
verbose(VERB_QUERY, "request too large, discarded");
out->value = -1;
out->value = DROP_REQUEST;
return;
}
if(LDNS_QR_WIRE(sldns_buffer_begin(pkt))) {
verbose(VERB_QUERY, "request has QR bit on, discarded");
out->value = -1;
/* verbose(VERB_QUERY, "request has QR bit on, discarded"); */
out->value = RESPONSE_MESSAGE;
return;
}
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
@@ -367,10 +379,39 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
out->value = worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
return;
}
out->value = 0;
out->value = REQUEST_OK;
return;
}
/** check response sanity.
* @param pkt: the wire packet to examine for sanity.
* @param worker: parameters for checking.
* @param out: 1 on success, otherwise 0.
*/
static int
worker_check_response(sldns_buffer* pkt, struct worker* worker)
{
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
LDNS_TC_CLR(sldns_buffer_begin(pkt));
verbose(VERB_QUERY, "response bad, has TC bit on");
return 0;
}
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
verbose(VERB_QUERY, "not a query response");
return 0;
}
if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
verbose(VERB_QUERY, "request wrong nr qd=%d",
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
return 0;
}
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) {
verbose(VERB_QUERY, "response must be an answer message");
return 0;
}
return 1;
}
/**
* Send fast-reload acknowledgement to the mainthread in one byte.
* This signals that this worker has received the previous command.
@@ -746,7 +787,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
*partial_repp = NULL; /* avoid accidental further pass */
/* Check TTL */
if(rep->ttl < timenow) {
if(TTL_IS_EXPIRED(rep->ttl, timenow)) {
/* Check if we need to serve expired now */
if(worker->env.cfg->serve_expired &&
/* if serve-expired-client-timeout is set, serve
@@ -1157,35 +1198,54 @@ answer_notify(struct worker* w, struct query_info* qinfo,
int rcode = LDNS_RCODE_NOERROR;
uint32_t serial = 0;
int has_serial;
struct tsig_data* tsig = NULL;
int tsig_rcode = 0;
if(!w->env.auth_zones) return;
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
qinfo->qname_len, qinfo->qclass, addr,
addrlen, has_serial, serial, &refused)) {
qinfo->qname_len, qinfo->qclass, addr, addrlen, has_serial,
serial, &refused, pkt, &tsig, &tsig_rcode, w->scratchpad)) {
rcode = LDNS_RCODE_NOERROR;
} else {
if(refused)
if(tsig_rcode != 0) {
rcode = tsig_rcode;
} else if(refused) {
rcode = LDNS_RCODE_REFUSED;
else rcode = LDNS_RCODE_SERVFAIL;
} else {
rcode = LDNS_RCODE_SERVFAIL;
}
}
if(verbosity >= VERB_DETAIL) {
char buf[380];
char zname[LDNS_MAX_DOMAINLEN];
char sr[25];
char buf[380+LDNS_MAX_DOMAINLEN];
char zname[LDNS_MAX_DOMAINLEN], tsigkey[LDNS_MAX_DOMAINLEN];
char sr[25], rcode_str[32], tsigtxt[16];;
dname_str(qinfo->qname, zname);
tsigkey[0]=0;
tsigtxt[0]=0;
if(tsig && tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(tsig->key_name, tsigkey);
}
sr[0]=0;
if(has_serial)
snprintf(sr, sizeof(sr), "serial %u ",
(unsigned)serial);
if(rcode == LDNS_RCODE_REFUSED)
if(rcode == LDNS_RCODE_REFUSED) {
snprintf(buf, sizeof(buf),
"refused NOTIFY %sfor %s from", sr, zname);
else if(rcode == LDNS_RCODE_SERVFAIL)
"refused NOTIFY %sfor %s%s%s from", sr, zname,
tsigtxt, tsigkey);
} else if(rcode != LDNS_RCODE_NOERROR) {
sldns_wire2str_rcode_buf(rcode, rcode_str,
sizeof(rcode_str));
snprintf(buf, sizeof(buf),
"servfail for NOTIFY %sfor %s from", sr, zname);
else snprintf(buf, sizeof(buf),
"received NOTIFY %sfor %s from", sr, zname);
"%s for NOTIFY %sfor %s%s%s from",
rcode_str, sr, zname, tsigtxt, tsigkey);
} else {
snprintf(buf, sizeof(buf),
"received NOTIFY %sfor %s%s%s from", sr, zname,
tsigtxt, tsigkey);
}
log_addr(VERB_DETAIL, buf, addr, addrlen);
}
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -1196,6 +1256,24 @@ answer_notify(struct worker* w, struct query_info* qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
sldns_buffer_read_u16_at(pkt, 2), edns);
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
if(tsig) {
size_t pos = sldns_buffer_limit(pkt);
sldns_buffer_clear(pkt);
sldns_buffer_set_position(pkt, pos);
if(!tsig_sign_reply(tsig, pkt, w->env.tsig_key_table,
(uint64_t)*w->env.now)) {
/* Failed to TSIG sign the reply */
verbose(VERB_ALGO, "Failed to TSIG sign notify reply");
error_encode(pkt, LDNS_RCODE_SERVFAIL, qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
sldns_buffer_read_u16_at(pkt, 2), edns);
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
} else {
/* Flip to delimit buffer after tsig_sign_reply. */
sldns_buffer_flip(pkt);
}
/* The tsig veriable is allocated in the scratch region. */
}
}
static int
@@ -1227,8 +1305,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
if(check_result->value != REQUEST_OK) {
if(check_result->value > 0) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
@@ -1505,7 +1583,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
char buf[LDNS_MAX_DOMAINLEN];
/* Check if this is unencrypted and asking for certs */
worker_check_request(c->buffer, worker, &check_result);
if(check_result.value != 0) {
if(check_result.value != REQUEST_OK) {
verbose(VERB_ALGO,
"dnscrypt: worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
@@ -1568,10 +1646,95 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
worker_check_request(c->buffer, worker, &check_result);
if(check_result.value != 0) {
if (check_result.value == RESPONSE_MESSAGE) {
/* Start accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
struct reply_info *rep = NULL;
int r;
struct arl_addr* arl_addr;
struct tsig_key* key;
if (!worker_check_response(c->buffer, worker)) {
verbose(VERB_ALGO, "bad response");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
arl_addr = arl_addr_lookup(worker->daemon->arl,
&repinfo->client_addr, repinfo->client_addrlen);
if(!arl_addr) {
verbose(VERB_ALGO, "ip not in \"allow-response:\" list");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if(arl_addr->tsig_key_name == NULL ||
arl_addr->tsig_key_name == TSIG_BLOCKED) {
verbose(VERB_ALGO, "ip blocked in \"allow-response:\" list");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if(arl_addr->tsig_key_name != TSIG_NOKEY) {
/* TODO: Link directly to the tsig_key from arl_addr,
* and update the arl_addr entries in the arl list
* when the tsig_key_table has changes
*/
lock_rw_rdlock(&worker->env.tsig_key_table->lock);
key = tsig_key_table_search_fromstr(worker->env.tsig_key_table,
arl_addr->tsig_key_name);
if (!key) {
verbose(VERB_ALGO, "tsig key to authenticate response,"
"\"%s\", not found",
arl_addr->tsig_key_name);
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
}
if((r = tsig_verify_shared(c->buffer, key->name,
key->algo->wireformat_name,
key->data, key->data_len,
*worker->env.now))) {
lock_rw_unlock(&worker->env.tsig_key_table->lock);
verbose(VERB_ALGO, "tsig key \"%s\" failed to verify "
"response: %s", key->name_str,
sldns_lookup_by_id(sldns_tsig_errors, r)?
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
lock_rw_unlock(&worker->env.tsig_key_table->lock);
}
if((r = reply_info_parse(c->buffer, worker->env.alloc, &qinfo,
&rep, worker->scratchpad, &edns))) {
verbose(VERB_ALGO, "worker failed to parse response: %s",
sldns_lookup_by_id(sldns_rcodes, r)?
sldns_lookup_by_id(sldns_rcodes, r)->name:"??");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
comm_point_drop_reply(repinfo);
return 0;
}
log_query_info(VERB_ALGO, "storing response in cache", &qinfo);
log_addr(VERB_CLIENT,"for",&repinfo->client_addr, repinfo->client_addrlen);
dns_cache_store(&worker->env, &qinfo, rep, 0 /* is_referral */,
0 /* leeway */, 0 /* pside */,
NULL /* region */, 0 /* flags */,
*worker->env.now, 0 /* is_valrec */);
comm_point_drop_reply(repinfo);
return 0;
/* End accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
} else if(check_result.value != REQUEST_OK) {
verbose(VERB_ALGO, "worker check request: bad query.");
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
if(check_result.value != -1) {
if(check_result.value > REQUEST_OK) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result.value);
@@ -1707,6 +1870,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
repinfo->client_addrlen, edns.cookie_valid,
c->buffer)) {
worker->stats.num_queries_ip_ratelimited++;
regional_free_all(worker->scratchpad);
comm_point_drop_reply(repinfo);
return 0;
}
@@ -1818,8 +1982,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
goto send_reply;
}
if(worker->env.auth_zones &&
auth_zones_answer(worker->env.auth_zones, &worker->env,
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
auth_zones_downstream_answer(worker->env.auth_zones,
&worker->env, &qinfo, &edns, repinfo, c->buffer,
worker->scratchpad)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
@@ -1872,20 +2037,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* If we've found a local alias, replace the qname with the alias
* target before resolving it. */
if(qinfo.local_alias) {
struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset;
struct packed_rrset_data* d = rrset->entry.data;
/* Sanity check: our current implementation only supports
* a single CNAME RRset as a local alias. */
if(qinfo.local_alias->next ||
rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
d->count != 1) {
log_err("assumption failure: unexpected local alias");
if(!local_alias_shallow_copy_qname(qinfo.local_alias, &qinfo.qname,
&qinfo.qname_len)) {
regional_free_all(worker->scratchpad);
return 0; /* drop it */
}
qinfo.qname = d->rr_data[0] + 2;
qinfo.qname_len = d->rr_len[0] - 2;
}
/* If we may apply IP-based actions to the answer, build the client
@@ -1936,11 +2092,11 @@ lookup_cache:
if((worker->env.cfg->prefetch &&
rep->prefetch_ttl <= *worker->env.now) ||
(worker->env.cfg->serve_expired &&
rep->ttl < *worker->env.now &&
TTL_IS_EXPIRED(rep->ttl, *worker->env.now) &&
!(*worker->env.now < rep->serve_expired_norec_ttl))) {
time_t leeway = rep->ttl - *worker->env.now;
if(rep->ttl < *worker->env.now)
leeway = 0;
time_t leeway =
TTL_IS_EXPIRED(rep->ttl, *worker->env.now)
? 0 : rep->ttl - *worker->env.now;
lock_rw_unlock(&e->lock);
reply_and_prefetch(worker, lookup_qinfo,
@@ -2284,7 +2440,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->daemon->connect_dot_sslctx, cfg->delay_close,
cfg->tls_use_sni, dtenv, cfg->udp_connect,
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
cfg->tcp_auth_query_timeout);
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
(const char**)cfg->dist_tsig, cfg->num_dist);
if(!worker->back) {
log_err("could not create outgoing sockets");
worker_delete(worker);
+5 -5
View File
@@ -496,8 +496,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
/* Create the new sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
&subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
return module_error;
if (subq) {
subq->curmod = id;
@@ -522,8 +522,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
/* Start the sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
0, &subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
{
verbose(VERB_ALGO, "dns64: sub-query creation failed");
return module_error;
@@ -631,7 +631,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
/* When an AAAA query completes check if we want to perform DNS64
* synthesis. We skip queries with DNSSEC enabled (!CD) and
* ones generated by us to retrive the A/PTR record to use for
* ones generated by us to retrieve the A/PTR record to use for
* synth. */
int could_synth =
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
+2 -2
View File
@@ -542,7 +542,7 @@ dt_msg_send_outside_query(struct dt_env *env,
qflags = sldns_buffer_read_u16_at(qmsg, 2);
/* type */
if (qflags & BIT_RD) {
if ((qflags & BIT_RD)) {
if (!env->log_forwarder_query_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY);
@@ -599,7 +599,7 @@ dt_msg_send_outside_response(struct dt_env *env,
qflags = ntohs(qflags);
/* type */
if (qflags & BIT_RD) {
if ((qflags & BIT_RD)) {
if (!env->log_forwarder_response_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
+35 -4
View File
@@ -18,10 +18,41 @@ AC_DEFUN([dt_DNSTAP],
[opt_dnstap_socket_path="$1"])
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi
AC_PATH_PROG([PROTOC], [protoc])
# 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be
# found, try 'protoc-c'.
if test -z "$PROTOC"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
else
PROTOC_C="$PROTOC"
fi
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([[The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c]])
fi
# Check for protoc-gen-c plugin
AC_PATH_PROG([PROTOC_GEN_C], [protoc-gen-c])
if test -z "$PROTOC_GEN_C"; then
AC_MSG_ERROR([[The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c]])
fi
# Test that protoc-gen-c actually works
AC_MSG_CHECKING([if protoc-gen-c plugin works])
cat > conftest.proto << EOF
syntax = "proto2";
message TestMessage {
optional string test_field = 1;
}
EOF
if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then
AC_MSG_RESULT([yes])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
else
AC_MSG_RESULT([no])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
AC_MSG_ERROR([[The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed]])
fi
AC_ARG_WITH([protobuf-c],
AS_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]),
[
+1 -1
View File
@@ -98,7 +98,7 @@ message Policy {
// rule: the rule matched by the message.
//
// In a RPZ context, this is the owner name of the rule in
// the Reponse Policy Zone in wire format.
// the Response Policy Zone in wire format.
optional bytes rule = 2;
// action: the policy action taken in response to the
+1 -1
View File
@@ -1509,7 +1509,7 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
}
#endif
if((bits&UB_EV_READ || dtio->ssl_brief_write)) {
if((bits&UB_EV_READ) || dtio->ssl_brief_write) {
#ifdef HAVE_SSL
if(dtio->ssl_brief_write)
(void)dtio_disable_brief_write(dtio);
+1 -1
View File
@@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
s->ev_cb = ev_cb;
s->data = data;
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
NULL, NULL, 0, 0, 0);
NULL, NULL, 0, 0, 0, 0);
if(!s->sslctx) {
log_err("could not create ssl context");
free(s->ip);
+399 -22
View File
@@ -1,3 +1,380 @@
27 October 2025: Yorgos
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
new $action, for SWIG.
- Fix #1165, document the possible circular dependency when using
host names instead of IP addresses for name servers in stub/forward
zones and log a warning when spotted in the configuration.
24 October 2025: Yorgos
- unbound.conf man page updates to include a preview of the section
clauses and some reformatting around the use of "clause", "option"
and "attributes". Based on Havard Eidnes' suggestions on the
mailing list.
- Fix unused attribute warning in redis.c when threads are not
supported.
- For #1364, use OPENSSL_VERSION_TEXT instead of OPENSSL_VERSION_NUMBER
for part of the configure script. OPENSSL_VERSION_TEXT is more
consistent across versions.
22 October 2025: Yorgos
- Tag for 1.24.1 release.
The repository continues with version 1.24.2.
15 October 2025: Wouter
- Fix to drop UDP for discard-timeout, but not stream connections.
- Fix to reply with SERVFAIL when the wait-limit is exceeded.
- Add extended dns error code for invalid query type to definition
list.
- Fix unbound.conf man page entry for root-hints to say it can
be used without strongly recommending it.
- Remove iPhone armv7s, and iPhoneSimulator i386 from ios ci.
The lib system does not provide symbols for it on the new macos
runner.
- Fix to exclude libssp for windows compiles.
10 October 2025: Wouter
- Fix #1358 Enabling FIPS in OpenSSL causes unit test to fail.
3 October 2025: Yorgos
- Note 'respip' and 'dns64' module order in the unbound.conf
man page.
- Note clearly that 'wait-limit: 0' disables all wait limits.
- 'wait-limit-cookie: 0' can now disable cookie validated wait
limits.
2 October 2025: Wouter
- Fix that https is set up as enabled when the port is listed in
interface-automatic-ports. Also for the set up of quic it is
enabled when listed there.
30 September 2025: Wouter
- Fix for #1344: Fix that respip and dns64 can be enabled at the
same time, the client info is copied for attach_sub and add_sub
calls. That makes respip work on dns64 synthesized answers, and
also makes RPZ work with DNS64. The order for the modules is
module-config: "respip dns64 validator iterator".
29 September 2025: Wouter
- Rebuild configure script from its sources.
- Fix modstack_call_init to use the original string when it has
changed, to call modstack_config with. And skip the changed name
in the string correctly. Thanks to Jan Komissar.
- Neaten up the change in acx_nlnetlabs.m4 to version 49.
- Fix fr_atomic_copy_cfg.
- Rebuild configure script from its sources.
- Fix #1353: auth-zone can not use empty label for $ORIGIN when
http download.
- Fix #1344: module conf 'respip dns64 validator cachedb iterator'
is not known to work.
29 September 2025: Yorgos
- Merge #1349: Fix #1346: [FR] Please allow back TLS 1.2.
- Merge #1351: ac_cv_func_malloc_0_nonnull for malloc(0) check.
26 September 2025: Yorgos
- Test for nonstring attribute in configure and add
nonstring attribute annotations.
24 September 2025: Yorgos
- Avoid calling mesh_detect_cycle_found() when there is no mesh state
to begin with.
23 September 2025: Yorgos
- Merge #1352 from Petr Vaganov: pythonmod: fix HANDLE_LEAK on
pythonmod_init.
- For #1352, align with the current Python<3 code.
- Merge #1350 from Maryse47: unbound.service.in: allow CAP_NET_ADMIN.
- For #1350, same CAP_NET_ADMIN change for unbound_portable.service.in
as well.
19 September 2025: Wouter
- Fix to remove configure~ from release tarballs.
19 September 2025: Yorgos
- Update README.man with clearer text.
- Merge #1337: 0 TTL cached replies and some TTL behavior changes.
- TTL change: Cached records that reach TTL 0 are expired.
- TTL change: TTL 0 upstream answers are no longer cached by
cachedb, as they should.
- TTL change: 'serve-expired-reply-ttl' is now capped by the original
TTL value of the record to try and make some sense when replying
with expired records.
- TTL change: TTL decoding was updated to adhere to RFC8767 section 4
where a 'set high-order bit' means the value is positive instead of
0.
- unbound.conf manpage: explicitly mention RFC6891.
18 September 2025: Wouter
- Tag for 1.24.0 release. Includes the fixes below after rc1.
The repository continues with version 1.24.1.
17 September 2025: Yorgos
- Too many quotes for the EDE message debug printout.
15 September 2025: Yorgos
- Small debug output improvement when attaching an EDE.
15 September 2025: Wouter
- Fix to print warning for when so-sndbuf setsockopt is not granted.
11 September 2025: Wouter
- version set to 1.24.0 for release.
- tag for 1.24.0rc1.
- Update contrib/aaaa-filter-iterator.patch so it applies on 1.24.0.
9 September 2025: Wouter
- Fix #1332: CNAME chains are sometimes not followed when RPZs add a
local CNAME rewrite.
8 September 2025: Yorgos
- Update documentation for using "SET ... EX" in Redis.
- Document max buffer sizes for Redis commands.
- Update man pages.
3 September 2025: Wouter
- For #1328: make depend.
2 September 2025: Wouter
- Fix #1235: Outdated Python2 code in
unbound/pythonmod/examples/log.py.
- Fix #1324: Memory leak in 'msgparse.c' in
'parse_edns_options_from_query(...)'.
- Fix indentation in tcp-mss option parsing.
1 September 2025: Wouter
- Fix for #1324: Fix to free edns options scratch in ratelimit case.
29 August 2025: Yorgos
- Limit the number of consecutive reads on an HTTP/2 session.
Thanks to Gal Bar Nahum for exposing the possibility of infinite
reads on the session.
28 August 2025: Wouter
- Fix setup_listen_sslctx warning for nettle compile.
27 August 2025: Wouter
- Fix unbound-control dump_cache for double unlock of lruhash table.
26 August 2025: Wouter
- Fix ports workflow to install expat for macos.
22 August 2025: Wouter
- For #1318: Fix compile warnings for DoH compile on windows.
- Fix sha1 enable environment variable in test code on windows.
- Fix #1319: [FR] zone status for Unbound auth-zones.
- Fix that the zone acquired timestamp is set after the
zonefile is read.
21 August 2025: Wouter
- Fix to check for extraneous command arguments for unbound-control,
when the command takes no arguments but there are arguments present.
- Fix #1317: Unbound starts too early. Add
Wants=network-online.target under [Unit] in unbound.service.
- Fix for #1317: Fix contrib/unbound.service comment path for
systemd network configuration.
15 August 2025: Wouter
- unbound-control cache_lookup +t allows tld and root names. And
subnet cache contents are printed.
- Fix cache_lookup subnet printout to wipe zero part of the prefix.
- Fix cache_lookup subnet print to not print messages without rrsets
and perform in-depth check on node in the addrtree.
14 August 2025: Wouter
- Fix to increase responsiveness of dump_cache.
- Fix to decouple file descriptor activity and cache lookups in
dump_cache.
13 August 2025: Wouter
- unbound-control cache_lookup <domains> prints the cached rrsets
and messages for those.
- Fix to remove debug from cache_lookup.
- Fix to unlock cache_lookup message for malformed records.
12 August 2025: Wouter
- Fix that unbound-control dump_cache releases the cache locks
every so often, so that the server stays responsive.
7 August 2025: Wouter
- Fix dname_str for printout of long names. Thanks to Jan Komissar
for the fix.
- Fix that edns-subnet failure to create a subquery errors as
servfail, and not formerror.
- Fix to whitespace in dname_str.
6 August 2025: Wouter
- Fix edns subnet, so that the subquery without subnet is stored in
global cache if the querier used 0.0.0.0/0 and the name and address
do not receive subnet treatment. If the name and address are
configured for subnet, it is stored in the subnet cache.
5 August 2025: Wouter
- Fix #1309: incorrectly reclaimed tcp handler can cause data
corruption and segfault.
- Fix to use assertions for consistency checks in #1309 reclaimed
tcp handlers.
1 August 2025: Wouter
- Fix testbound test program to accurately output packets from hex.
28 July 2025: Wouter
- Fix redis cachedb module gettimeofday init failure.
24 July 2025: Wouter
- Redis checks for server down and throttles reconnects.
17 July 2025: Wouter
- Fix to not set rlimits in the unit tests.
- Fix #1303: [FR] Disable TLSv1.2.
- iana portlist updated.
16 July 2025: Wouter
- Fix for RebirthDay Attack CVE-2025-5994, reported by Xiang Li
from AOSP Lab Nankai University.
- Tag for 1.23.1 with the release of 1.23.0 and the CVE fix, the
repository continues with the previous fixes, with 1.23.2.
- Add unit tests for non-ecs aggregation.
12 July 2025: Yorgos
- Merge #1289 from Roland van Rijswijk-Deij: Add extra statistic to
track the number of signature validation operations.
Adds 'num.valops' to extended statistics.
- For #1289: test num.valops in existing stat_values.tdir.
- For #1289: add num.valops in the unbound-control man page.
11 July 2025: Wouter
- Fix detection of SSL_CTX_set_tmp_ecdh function.
- For #1301: configure cant find SSL_is_quic in OpenSSL 3.5.1.
8 July 2025: Wouter
- Fix to improve dnstap discovery on Fedora.
3 July 2025: Wouter
- Fix #1300: Is 'sock-queue-timeout' a linux only feature.
- For #1300: implement sock-queue-timeout for FreeBSD as well.
- Fix layout of comm_point_udp_ancil_callback.
2 July 2025: Wouter
- Merge #1299: Fix typos.
- Generate ltmain.sh and configure again.
25 June 2025: Yorgos
- Fix #1247: forward-first: ssl handshake failed on root nameservers.
- For #1247, turn off fetch-policy for delegation when looking into
parent side name servers that may not update the addresses and hit
NXNS limits.
- For #1247, replay test (added tcp_transport to
outnet_serviced_query).
20 June 2025: Yorgos
- Fix #1293: EDE 6 is attached to insecure cached answers when client
sends the CD bit.
19 June 2025: Wouter
- Fix #1296: DNS over QUIC depends on a very outdated version of
ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.
- Merge #1297: edns-subnet: fix NULL_AFTER_DEREF on subnetmod.
- Fix rrset cache create allocation failure case.
17 June 2025: Yorgos
- Fix for consistent use of local zone CNAME alias for configured auth
zones. Now it also applies to downstream configured auth zones.
16 June 2025: Wouter
- Fix to check control-interface addresses in unbound-checkconf.
- Fix #1295: Windows 32-bit binaries download seems to be missing dll
dependency.
12 June 2025: Wouter
- Fix header return value description for skip_pkt_rrs and
parse_edns_from_query_pkt.
11 June 2025: Wouter
- Fix bitwise operators in conditional expressions with parentheses.
- Fix conditional expressions with parentheses for bitwise and.
5 June 2025: Wouter
- Fix unbound-anchor certificate file read for line ends and end of
file.
- Fix comment for the dname_remove_label_limit_len function.
- iana portlist updated.
3 June 2025: Yorgos
- Small manpage corrections for the 'disable-dnssec-lame-check' option.
21 May 2025: Wouter
- Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound
program.
20 May 2025: Yorgos
- Merge #1285: RST man pages. It introduces restructuredText man pages
to sync the online and source code man page documentation.
The templated man pages (*.in) are still part of the repo but
generated with docutils from their .rst counterpart.
Documentation on how to generate those (mainly for core developers)
is in README.man.
- Add more checks about respip in unbound-checkconf.
Also fixes #310: unbound-checkconf not reporting RPZ configuration
error.
19 May 2025: Wouter
- Fix for cname chain length with qtype ANY and qname minimisation.
Thanks to Jim Greenwood from Nominet for the report.
15 May 2025: Wouter
- Fix config of slab values when there is no config file.
13 May 2025: Yorgos
- Fix #1284: NULL pointer deref in az_find_nsec_cover() (latent bug)
by adding a log_assert() to safeguard future development.
- Fix #1282: log-destaddr fail on long ipv6 addresses.
13 May 2025: Wouter
- Change default for so-sndbuf to 1m, to mitigate a cross-layer
issue where the UDP socket send buffers are exhausted waiting
for ARP/NDP resolution. Thanks to Reflyable for the report.
- Adjusted so-sndbuf default to 4m.
12 May 2025: Yorgos
- Merge #1280: Fix auth nsec3 code. Fixes NSEC3 code to not break on
broken auth zones that include unsigned out of zone (above apex)
data. Could lead to hang while trying to prove a wildcard answer.
12 May 2025: Wouter
- Fix #1283: Unsafe usage of atoi() while parsing the configuration
file.
9 May 2025: Wouter
- Fix #1281: forward-zone "name: ." conflicts with auth-zone "name: ."
in 1.23.0, but worked in 1.22.0.
5 May 2025: Yorgos
- Sync unbound and unbound-checkconf log output for unknown modules.
29 April 2025: Wouter
- Fix for parallel build of dnstap protoc-c output.
- Fix dnstap to use protoc.
29 April 2025: Yorgos
- Merge #1276: Auto-configure '-slabs' values.
28 April 2025: Yorgos
- Merge #1275: Use macros for the fr_check_changed* functions.
25 April 2025: Wouter
- Fix #1272: assertion failure testcode/unitverify.c:202.
16 April 2025: Wouter
- Increase default to `num-queries-per-thread: 2048`, when unbound is
compiled with libevent. It makes saturation of the task queue more
resource intensive and less practical. Thanks to Shiming Liu,
Network and Information Security Lab, Tsinghua University for the
report.
11 April 2025: Wouter
- Tag for 1.23.0rc2. This became the release of 1.23.0 on 24 April
2025. The code repository continues with 1.23.1 in development.
11 April 2025: Yorgos
- Merge #1265: Fix WSAPoll.
@@ -651,7 +1028,7 @@
now checks both single and multi process/thread operation.
16 May 2024: Yorgos
- Merge #1070: Fix rtt assignement for low values of
- Merge #1070: Fix rtt assignment for low values of
infra-cache-max-rtt.
16 May 2024: Wouter
@@ -1059,7 +1436,7 @@
13 October 2023: George
- Better fix for infinite loop when reading multiple lines of input on
a broken remote control socket, by treating a zero byte line the
same as transmission end. Addesses #947 and #948.
same as transmission end. Addresses #947 and #948.
12 October 2023: Wouter
- Merge #944: Disable EDNS DO.
@@ -1082,7 +1459,7 @@
10 October 2023: George
- Fix infinite loop when reading multiple lines of input on a broken
remote control socket. Addesses #947 and #948.
remote control socket. Addresses #947 and #948.
9 October 2023: Wouter
- Fix edns subnet so that queries with a source prefix of zero cause
@@ -1515,7 +1892,7 @@
- Ignore expired error responses.
11 November 2022: Wouter
- Fix #779: [doc] Missing documention in ub_resolve_event() for
- Fix #779: [doc] Missing documentation in ub_resolve_event() for
callback parameter was_ratelimited.
9 November 2022: George
@@ -2479,7 +2856,7 @@
not hang. removed trailing slashes from configure paths. Moved iOS
tests to allow-failure.
- travis, analyzer disabled on test without debug, that does not
run anway. Turn off failing tests except one. Update iOS test
run anyway. Turn off failing tests except one. Update iOS test
to xcode image 12.2.
22 March 2021: George
@@ -2568,7 +2945,7 @@
- Fix build on Python 3.10.
10 February 2021: Wouter
- Merge PR #420 from dyunwei: DOH not responsing with
- Merge PR #420 from dyunwei: DOH not responding with
"http2_query_read_done failure" logged.
9 February 2021: Wouter
@@ -2968,7 +3345,7 @@
6 August 2020: Wouter
- Merge PR #284 and Fix #246: Remove DLV entirely from Unbound.
The DLV has been decommisioned and in unbound 1.5.4, in 2015, there
The DLV has been decommissioned and in unbound 1.5.4, in 2015, there
was advise to stop using it. The current code base does not contain
DLV code any more. The use of dlv options displays a warning.
@@ -3517,7 +3894,7 @@
3 December 2019: Wouter
- Merge pull request #124 from rmetrich: Changed log lock
from 'quick' to 'basic' because this is an I/O lock.
- Fix text around serial arithmatic used for RRSIG times to refer
- Fix text around serial arithmetic used for RRSIG times to refer
to correct RFC number.
- Fix Assert Causing DoS in synth_cname(),
reported by X41 D-Sec.
@@ -3780,7 +4157,7 @@
- For #52 #53, second context does not close logfile override.
- Fix #52 #53, fix for example fail program.
- Fix to return after failed auth zone http chunk write.
- Fix to remove unused test for task_probe existance.
- Fix to remove unused test for task_probe existence.
- Fix to timeval_add for remaining second in microseconds.
- Check repinfo in worker_handle_request, if null, drop it.
@@ -5037,7 +5414,7 @@
1 February 2018: Wouter
- fix unaligned structure making a false positive in checklock
unitialised memory.
uninitialised memory.
29 January 2018: Ralph
- Use NSEC with longest ce to prove wildcard absence.
@@ -5640,8 +6017,8 @@
- Remove (now unused) event2 include from dnscrypt code.
24 March 2017: George
- Fix to prevent non-referal query from being cached as referal when the
no_cache_store flag was set.
- Fix to prevent non-referral query from being cached as referral when
the no_cache_store flag was set.
23 March 2017: Wouter
- Fix #1239: configure fails to find python distutils if python
@@ -5704,7 +6081,7 @@
7 March 2017: Wouter
- Fix #1230: swig version 2.0.0 is required for pythonmod, with
1.3.40 it crashes when running repeatly unbound-control reload.
1.3.40 it crashes when running repeatedly unbound-control reload.
- Response actions based on IP address from Jinmei Tatuya (Infoblox).
6 March 2017: Wouter
@@ -5720,7 +6097,7 @@
known vulns.
27 February 2017: Wouter
- Fix #1227: Fix that Unbound control allows weak ciphersuits.
- Fix #1227: Fix that Unbound control allows weak ciphersuites.
- Fix #1226: provide official 32bit binary for windows.
24 February 2017: Wouter
@@ -6709,7 +7086,7 @@
- Fix #674: Do not free pointers given by getenv.
29 May 2015: Wouter
- Fix that unparseable error responses are ratelimited.
- Fix that unparsable error responses are ratelimited.
- SOA negative TTL is capped at minimumttl in its rdata section.
- cache-max-negative-ttl config option, default 3600.
@@ -6727,7 +7104,7 @@
10 May 2015: Wouter
- Change syntax of particular validator error to be easier for
machine parse, swap rrset and ip adres info so it looks like:
machine parse, swap rrset and ip address info so it looks like:
validation failure <www.example.nl. TXT IN>: signature crypto
failed from 2001:DB8:7:bba4::53 for <*.example.nl. NSEC IN>
@@ -8307,7 +8684,7 @@
- fix that --enable-static-exe does not complain about it unknown.
30 June 2011: Wouter
- tag relase 1.4.11, trunk is 1.4.12 development.
- tag release 1.4.11, trunk is 1.4.12 development.
- iana portlist updated.
- fix bug#395: id bits of other query may leak out under conditions
- fix replyaddr count wrong after jostled queries, which leads to
@@ -9637,7 +10014,7 @@
8 June 2009: Wouter
- Removed RFC5011 REVOKE flag support. Partial 5011 support may cause
inadvertant behaviour.
inadvertent behaviour.
- 1.3.0 tarball for release created.
- 1.3.1 development in svn trunk.
- iana portlist updated.
@@ -9986,7 +10363,7 @@
- initgroups(3) is called to drop secondary group permissions, if
applicable.
- configure option --with-ldns-builtin forces the use of the
inluded ldns package with the unbound source. The -I include
included ldns package with the unbound source. The -I include
is put before the others, so it avoids bad include files from
an older ldns install.
- daemon(3) posix call is used when available.
@@ -10291,7 +10668,7 @@
please ranlib, stop file without symbols warning.
- harden referral path now also validates the root after priming.
It looks up the root NS authoritatively as well as the root servers
and attemps to validate the entries.
and attempts to validate the entries.
16 October 2008: Wouter
- Fixup negative TTL values appearing (reported by Attila Nagy).
@@ -11070,7 +11447,7 @@
- please doxygen, put doxygen comment in one place.
- asynclook -b blocking mode and test.
- refactor asynclook, nicer code.
- fixup race problems from opensll in rand init from library, with
- fixup race problems from openssl in rand init from library, with
a mutex around the rand init.
- fix pass async_id=NULL to _async resolve().
- rewrote _wait() routine, so that it is threadsafe.
@@ -12043,7 +12420,7 @@
11 June 2007: Wouter
- replies on TCP queries have the address field set in replyinfo,
for serviced queries, because the initiator does not know that
a TCP fallback has occured.
a TCP fallback has occurred.
- omit DNSSEC types from nonDO replies, except if qtype is ANY or
if qtype directly queries for the type (and then only show that
'unknown type' in the answer section).
+21
View File
@@ -0,0 +1,21 @@
After Unbound 1.23.0, the source of the man pages is in reStructuredText format.
This helps with the online documentation at https://unbound.docs.nlnetlabs.nl
and makes it easier to maintain and contribute to the documentation.
The templated man pages (*.in) are still part of the code repository as to not
alter current procedures that could be in place by users/packagers.
These man pages (*.in) are still the ones being used when
configuring/installing Unbound.
Packagers/users do not have to generate any man pages themselves, this is done
by the core developers during development and upon releasing new versions.
The templated man pages (*.in) are generated by Sphinx (used for the online
documentation).
The online documentation has its own repository at
https://github.com/NLnetLabs/unbound-manual.
In that README.md (https://github.com/NLnetLabs/unbound-manual/README.md)
there are further simple instructions on how to generate the templated man
pages there and update them in this repository.
+63 -18
View File
@@ -116,8 +116,8 @@ server:
# so-rcvbuf: 0
# buffer size for UDP port 53 outgoing (SO_SNDBUF socket option).
# 0 is system default. Use 4m to handle spikes on very busy servers.
# so-sndbuf: 0
# 0 is system default. Set larger to handle spikes on very busy servers.
# so-sndbuf: 4m
# use SO_REUSEPORT to distribute queries over threads.
# at extreme load it could be better to turn it off to distribute even.
@@ -163,7 +163,7 @@ server:
# msg-cache-slabs: 4
# the number of queries that a thread gets to service.
# num-queries-per-thread: 1024
# num-queries-per-thread: 2048
# if very busy, 50% queries run to completion, 50% get timeout in msec
# jostle-timeout: 200
@@ -196,6 +196,10 @@ server:
# Limit on upstream queries for an incoming query and its recursion.
# max-global-quota: 200
# Should the scrubber remove promiscuous NS from positive answers,
# protects against poison attempts.
# iter-scrub-promiscuous: yes
# msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376
@@ -279,7 +283,7 @@ server:
# do-ip6: yes
# If running unbound on an IPv6-only host, domains that only have
# IPv4 servers would become unresolveable. If NAT64 is available in
# IPv4 servers would become unresolvable. If NAT64 is available in
# the network, unbound can use NAT64 to reach these servers with
# the following option. This is NOT needed for enabling DNS64 on a
# system that has IPv4 connectivity.
@@ -752,6 +756,7 @@ server:
# serve-expired-ttl-reset: no
#
# TTL value to use when replying with expired data.
# Capped by the original TTL of the record.
# serve-expired-reply-ttl: 30
#
# Time in milliseconds before replying to the client with expired data.
@@ -921,6 +926,22 @@ server:
# add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse
# Action to apply when the IP address in an AAAA or A RR in the answer
# section of a response matches the specified IP netblock.
# Requires use of the respip module.
# response-ip: 192.0.2.0/24 redirect
# Redirect as specified by the "resource record string" when the IP
# address in an AAAA or A RR in the answer section of a response
# matches the specified IP netblock.
# Requires use of the respip module.
# response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1"
# Apply tag(s) when the IP address in an AAAA or A RR in the answer
# section of a response matches the specified IP netblock.
# Requires use of the respip module.
# response-ip-tag: 192.0.2.0/24 "tag1 tag2"
# service clients over TLS (on the TCP sockets) with plain DNS inside
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
# Give the certificate to use and private key.
@@ -931,21 +952,26 @@ server:
# https-port: 443
# quic-port: 853
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers.
# cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
# cipher setting for TLSv1.3
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload.
# tls-use-sni: yes
# Allow general-purpose version-flexible TLS server configuration that
# may be further restricted by the system's policy.
# Use only if you want to support legacy TLS client connections.
# Default is no and Unbound will only use the latest available TLS
# version.
# Changing the value requires a reload.
# tls-use-system-policy-versions: no
# Add the secret file for TLS Session Ticket.
# Secret file must be 80 bytes of random data.
# First key use to encrypt and decrypt TLS session tickets.
@@ -966,15 +992,18 @@ server:
# and on other systems, the default openssl certificates
# tls-system-cert: no
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Pad queries over TLS upstreams
# pad-queries: yes
# Padded queries will be padded to the closest multiple of this size.
# pad-queries-block-size: 128
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers.
# HTTP endpoint to provide DNS-over-HTTPS service on.
# http-endpoint: "/dns-query"
@@ -1226,7 +1255,8 @@ remote-control:
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), primary: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from primaries and urls)
# sources of notifies.
# sources of notifies. primary-tsig: and allow-notify-tsig: use addr keyname,
# with the name of the TSIG key to use, declared as a tsig-key:.
# auth-zone:
# name: "."
# primary: 170.247.170.2 # b.root-servers.net
@@ -1257,10 +1287,11 @@ remote-control:
# zonefile: "example.org.zone"
# Views
# Create named views. Name must be unique. Map views to requests using
# the access-control-view option. Views can contain zero or more local-zone
# and local-data options. Options from matching views will override global
# options. Global options will be used if no matching view is found.
# Create named views. Name must be unique.
# Map views to requests using the access-control-view/interface-view options.
# Views can contain zero or more local-zone and local-data options.
# Options from matching views will override global options.
# Global options will be used if no matching view is found.
# With view-first yes, it will try to answer using the global local-zone and
# local-data elements if there is no view specific match.
# view:
@@ -1268,6 +1299,8 @@ remote-control:
# local-zone: "example.com" redirect
# local-data: "example.com A 192.0.2.3"
# local-data-ptr: "192.0.2.3 www.example.com"
# response-ip: 192.0.2.0/24 redirect
# response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1"
# view-first: no
# view:
# name: "anotherview"
@@ -1405,6 +1438,7 @@ remote-control:
# and drop. Policies can be loaded from a file, or using zone
# transfer, or using HTTP. The respip module needs to be added
# to the module-config, e.g.: module-config: "respip validator iterator".
# Can also use primary-tsig: and allow-notify-tsig:
# rpz:
# name: "rpz.example.com"
# zonefile: "rpz.example.com"
@@ -1418,3 +1452,14 @@ remote-control:
# rpz-signal-nxdomain-ra: no
# for-downstream: no
# tags: "example"
# TSIG keys
# tsig-key:
# # The key name is sent to the other party, it must be the same
# name: "keyname"
# # algorithm hmac-md5, or sha1, sha256, sha224, sha384, sha512
# algorithm: sha256
# # secret material, must be the same as the other party uses.
# # base64 encoded random number.
# # e.g. from dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64
# secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
+330 -343
View File
@@ -1,335 +1,306 @@
.TH "libunbound" "3" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B libunbound,
.B unbound.h,
.B ub_ctx,
.B ub_result,
.B ub_callback_type,
.B ub_ctx_create,
.B ub_ctx_delete,
.B ub_ctx_set_option,
.B ub_ctx_get_option,
.B ub_ctx_config,
.B ub_ctx_set_fwd,
.B ub_ctx_set_stub,
.B ub_ctx_set_tls,
.B ub_ctx_resolvconf,
.B ub_ctx_hosts,
.B ub_ctx_add_ta,
.B ub_ctx_add_ta_autr,
.B ub_ctx_add_ta_file,
.B ub_ctx_trustedkeys,
.B ub_ctx_debugout,
.B ub_ctx_debuglevel,
.B ub_ctx_async,
.B ub_poll,
.B ub_wait,
.B ub_fd,
.B ub_process,
.B ub_resolve,
.B ub_resolve_async,
.B ub_cancel,
.B ub_resolve_free,
.B ub_strerror,
.B ub_ctx_print_local_zones,
.B ub_ctx_zone_add,
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
\- Unbound DNS validating resolver @version@ functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
\fIstruct ub_ctx *\fR
\fBub_ctx_create\fR(\fIvoid\fR);
.LP
\fIvoid\fR
\fBub_ctx_delete\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_ctx_set_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar*\fR val);
.LP
\fIint\fR
\fBub_ctx_get_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar**\fR val);
.LP
\fIint\fR
\fBub_ctx_config\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_set_fwd\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR addr);
.LP
\fIint\fR
\fBub_ctx_set_stub\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone,
\fIchar*\fR addr,
.br
\fIint\fR isprime);
.LP
\fIint\fR
\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
.LP
\fIint\fR
\fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_hosts\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta);
.LP
\fIint\fR
\fBub_ctx_add_ta_autr\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_trustedkeys\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_debugout\fR(\fIstruct ub_ctx*\fR ctx, \fIFILE*\fR out);
.LP
\fIint\fR
\fBub_ctx_debuglevel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR d);
.LP
\fIint\fR
\fBub_ctx_async\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR dothread);
.LP
\fIint\fR
\fBub_poll\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_wait\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_fd\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_process\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_resolve\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
.br
\fIint\fR rrtype, \fIint\fR rrclass, \fIstruct ub_result**\fR result);
.LP
\fIint\fR
\fBub_resolve_async\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
.br
\fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata,
.br
\fIub_callback_type\fR callback, \fIint*\fR async_id);
.LP
\fIint\fR
\fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id);
.LP
\fIvoid\fR
\fBub_resolve_free\fR(\fIstruct ub_result*\fR result);
.LP
\fIconst char *\fR
\fBub_strerror\fR(\fIint\fR err);
.LP
\fIint\fR
\fBub_ctx_print_local_zones\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_ctx_zone_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name, \fIchar*\fR zone_type);
.LP
\fIint\fR
\fBub_ctx_zone_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name);
.LP
\fIint\fR
\fBub_ctx_data_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
.LP
\fIint\fR
\fBub_ctx_data_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
.SH "DESCRIPTION"
.B Unbound
is an implementation of a DNS resolver, that does caching and
DNSSEC validation. This is the library API, for using the \-lunbound library.
The server daemon is described in \fIunbound\fR(8).
The library works independent from a running unbound server, and
can be used to convert hostnames to ip addresses, and back,
and obtain other information from the DNS. The library performs public\-key
validation of results with DNSSEC.
.P
The library uses a variable of type \fIstruct ub_ctx\fR to keep context
between calls. The user must maintain it, creating it with
.B ub_ctx_create
and deleting it with
.B ub_ctx_delete\fR.
It can be created and deleted at any time. Creating it anew removes any
previous configuration (such as trusted keys) and clears any cached results.
.P
The functions are thread\-safe, and a context can be used in a threaded (as
well as in a non\-threaded) environment. Also resolution (and validation)
can be performed blocking and non\-blocking (also called asynchronous).
The async method returns from the call immediately, so that processing
can go on, while the results become available later.
.P
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "LIBUNBOUND" "3" "@date@" "@version@" "Unbound"
.SH NAME
libunbound \- Unbound DNS validating resolver @version@ functions.
.SH SYNOPSIS
.sp
\fB#include <unbound.h>\fP
.sp
struct ub_ctx * \fBub_ctx_create\fP(void);
.sp
void \fBub_ctx_delete\fP(struct ub_ctx* ctx);
.sp
int \fBub_ctx_set_option\fP(struct ub_ctx* ctx, char* opt, char* val);
.sp
int \fBub_ctx_get_option\fP(struct ub_ctx* ctx, char* opt, char** val);
.sp
int \fBub_ctx_config\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_set_fwd\fP(struct ub_ctx* ctx, char* addr);
.INDENT 0.0
.TP
int \fBub_ctx_set_stub\fP(struct ub_ctx* ctx, char* zone, char* addr,
int isprime);
.UNINDENT
.sp
int \fBub_ctx_set_tls\fP(struct ub_ctx* ctx, int tls);
.sp
int \fBub_ctx_resolvconf\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_hosts\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_add_ta\fP(struct ub_ctx* ctx, char* ta);
.sp
int \fBub_ctx_add_ta_autr\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_add_ta_file\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_trustedkeys\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_debugout\fP(struct ub_ctx* ctx, FILE* out);
.sp
int \fBub_ctx_debuglevel\fP(struct ub_ctx* ctx, int d);
.sp
int \fBub_ctx_async\fP(struct ub_ctx* ctx, int dothread);
.sp
int \fBub_poll\fP(struct ub_ctx* ctx);
.sp
int \fBub_wait\fP(struct ub_ctx* ctx);
.sp
int \fBub_fd\fP(struct ub_ctx* ctx);
.sp
int \fBub_process\fP(struct ub_ctx* ctx);
.INDENT 0.0
.TP
int \fBub_resolve\fP(struct ub_ctx* ctx, char* name,
int rrtype, int rrclass, struct ub_result** result);
.TP
int \fBub_resolve_async\fP(struct ub_ctx* ctx, char* name,
int rrtype, int rrclass, void* mydata,
ub_callback_type* callback, int* async_id);
.UNINDENT
.sp
int \fBub_cancel\fP(struct ub_ctx* ctx, int async_id);
.sp
void \fBub_resolve_free\fP(struct ub_result* result);
.sp
const char * \fBub_strerror\fP(int err);
.sp
int \fBub_ctx_print_local_zones\fP(struct ub_ctx* ctx);
.sp
int \fBub_ctx_zone_add\fP(struct ub_ctx* ctx, char* zone_name, char* zone_type);
.sp
int \fBub_ctx_zone_remove\fP(struct ub_ctx* ctx, char* zone_name);
.sp
int \fBub_ctx_data_add\fP(struct ub_ctx* ctx, char* data);
.sp
int \fBub_ctx_data_remove\fP(struct ub_ctx* ctx, char* data);
.SH DESCRIPTION
.sp
Unbound is an implementation of a DNS resolver, that does caching and DNSSEC
validation.
This is the library API, for using the \fB\-lunbound\fP library.
The server daemon is described in \fI\%unbound(8)\fP\&.
The library works independent from a running unbound server, and can be used to
convert hostnames to ip addresses, and back, and obtain other information from
the DNS.
The library performs public\-key validation of results with DNSSEC.
.sp
The library uses a variable of type \fIstruct ub_ctx\fP to keep context between
calls.
The user must maintain it, creating it with \fBub_ctx_create\fP and deleting it
with \fBub_ctx_delete\fP\&.
It can be created and deleted at any time.
Creating it anew removes any previous configuration (such as trusted keys) and
clears any cached results.
.sp
The functions are thread\-safe, and a context can be used in a threaded (as well
as in a non\-threaded) environment.
Also resolution (and validation) can be performed blocking and non\-blocking
(also called asynchronous).
The async method returns from the call immediately, so that processing can go
on, while the results become available later.
.sp
The functions are discussed in turn below.
.SH "FUNCTIONS"
.TP
.SH FUNCTIONS
.INDENT 0.0
.TP
.B ub_ctx_create
Create a new context, initialised with defaults.
The information from /etc/resolv.conf and /etc/hosts is not utilised
by default. Use
.B ub_ctx_resolvconf
and
.B ub_ctx_hosts
to read them.
Before you call this, use the openssl functions CRYPTO_set_id_callback and
CRYPTO_set_locking_callback to set up asynchronous operation if you use
lib openssl (the application calls these functions once for initialisation).
Openssl 1.0.0 or later uses the CRYPTO_THREADID_set_callback function.
The information from \fB/etc/resolv.conf\fP and \fB/etc/hosts\fP is
not utilised by default.
Use \fBub_ctx_resolvconf\fP and \fBub_ctx_hosts\fP to read them.
Before you call this, use the openssl functions
\fBCRYPTO_set_id_callback\fP and \fBCRYPTO_set_locking_callback\fP to set
up asynchronous operation if you use lib openssl (the application calls
these functions once for initialisation).
Openssl 1.0.0 or later uses the \fBCRYPTO_THREADID_set_callback\fP
function.
.TP
.B ub_ctx_delete
Delete validation context and free associated resources.
Outstanding async queries are killed and callbacks are not called for them.
Outstanding async queries are killed and callbacks are not called for
them.
.TP
.B ub_ctx_set_option
A power\-user interface that lets you specify one of the options from the
config file format, see \fIunbound.conf\fR(5). Not all options are
relevant. For some specific options, such as adding trust anchors, special
routines exist. Pass the option name with the trailing ':'.
A power\-user interface that lets you specify one of the options from
the config file format, see \fI\%unbound.conf(5)\fP\&.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
Pass the option name with the trailing \fB\(aq:\(aq\fP\&.
.TP
.B ub_ctx_get_option
A power\-user interface that gets an option value. Some options cannot be
gotten, and others return a newline separated list. Pass the option name
without trailing ':'. The returned value must be free(2)d by the caller.
A power\-user interface that gets an option value.
Some options cannot be gotten, and others return a newline separated
list.
Pass the option name without trailing \fB\(aq:\(aq\fP\&.
The returned value must be free(2)d by the caller.
.TP
.B ub_ctx_config
A power\-user interface that lets you specify an unbound config file, see
\fIunbound.conf\fR(5), which is read for configuration. Not all options are
relevant. For some specific options, such as adding trust anchors, special
routines exist. This function is thread\-safe only if a single instance of
ub_ctx* exists in the application. If several instances exist the
application has to ensure that ub_ctx_config is not called in parallel by
the different instances.
A power\-user interface that lets you specify an unbound config file,
see \fI\%unbound.conf(5)\fP, which is read for
configuration.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
This function is thread\-safe only if a single instance of \fBub_ctx\fP*
exists in the application.
If several instances exist the application has to ensure that
\fBub_ctx_config\fP is not called in parallel by the different instances.
.TP
.B ub_ctx_set_fwd
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address. Forwards all DNS requests to that machine, which
is expected to run a recursive resolver. If the proxy is not
DNSSEC capable, validation may fail. Can be called several times, in
that case the addresses are used as backup servers.
At this time it is only possible to set configuration before the
first resolve is done.
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address.
Forwards all DNS requests to that machine, which is expected to run a
recursive resolver.
If the proxy is not DNSSEC capable, validation may fail.
Can be called several times, in that case the addresses are used as
backup servers.
At this time it is only possible to set configuration before the first
resolve is done.
.TP
.B ub_ctx_set_stub
Set a stub zone, authoritative dns servers to use for a particular zone.
IP4 or IP6 address. If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it. Otherwise similar to
the stub zone item from unbound's config file. Can be called several times,
for different zones, or to add multiple addresses for a particular zone.
At this time it is only possible to set configuration before the
first resolve is done.
Set a stub zone, authoritative dns servers to use for a particular
zone.
IP4 or IP6 address.
If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it.
Otherwise similar to the stub zone item from unbound\(aqs config file.
Can be called several times, for different zones, or to add multiple
addresses for a particular zone.
At this time it is only possible to set configuration before the first
resolve is done.
.TP
.B ub_ctx_set_tls
Enable DNS over TLS (DoT) for machines set with
.B ub_ctx_set_fwd.
At this time it is only possible to set configuration before the
first resolve is done.
Enable DNS over TLS (DoT) for machines set with \fBub_ctx_set_fwd\fP\&.
At this time it is only possible to set configuration before the first
resolve is done.
.TP
.B ub_ctx_resolvconf
By default the root servers are queried and full resolver mode is used, but
you can use this call to read the list of nameservers to use from the
filename given.
Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
By default the root servers are queried and full resolver mode is used,
but you can use this call to read the list of nameservers to use from
the filename given.
Usually \fB\(dq/etc/resolv.conf\(dq\fP\&.
Uses those nameservers as caching proxies.
If they do not support DNSSEC, validation may fail.
Only nameservers are picked up, the searchdomain, ndots and other
settings from \fIresolv.conf\fR(5) are ignored.
If fname NULL is passed, "/etc/resolv.conf" is used (if on Windows,
the system\-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the
first resolve is done.
settings from \fIresolv.conf(5)\fP are ignored.
If fname NULL is passed, \fB\(dq/etc/resolv.conf\(dq\fP is used (if on
Windows, the system\-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
.TP
.B ub_ctx_hosts
Read list of hosts from the filename given.
Usually "/etc/hosts". When queried for, these addresses are not marked
DNSSEC secure. If fname NULL is passed, "/etc/hosts" is used
(if on Windows, etc/hosts from WINDIR is picked instead).
At this time it is only possible to set configuration before the
first resolve is done.
Usually \fB\(dq/etc/hosts\(dq\fP\&.
When queried for, these addresses are not marked DNSSEC secure.
If fname NULL is passed, \fB\(dq/etc/hosts\(dq\fP is used (if on Windows,
\fBetc/hosts\fP from WINDIR is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
.TP
.B
ub_ctx_add_ta
.B ub_ctx_add_ta
Add a trust anchor to the given context.
At this time it is only possible to add trusted keys before the
first resolve is done.
At this time it is only possible to add trusted keys before the first
resolve is done.
The format is a string, similar to the zone\-file format,
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
\fB[domainname]\fP \fB[type]\fP \fB[rdata contents]\fP\&.
Both DS and DNSKEY records are accepted.
.TP
.B ub_ctx_add_ta_autr
Add filename with automatically tracked trust anchor to the given context.
Pass name of a file with the managed trust anchor. You can create this
file with \fIunbound\-anchor\fR(8) for the root anchor. You can also
create it with an initial file with one line with a DNSKEY or DS record.
Add filename with automatically tracked trust anchor to the given
context.
Pass name of a file with the managed trust anchor.
You can create this file with
\fI\%unbound\-anchor(8)\fP for the root anchor.
You can also create it with an initial file with one line with a DNSKEY
or DS record.
If the file is writable, it is updated when the trust anchor changes.
At this time it is only possible to add trusted keys before the
first resolve is done.
At this time it is only possible to add trusted keys before the first
resolve is done.
.TP
.B ub_ctx_add_ta_file
Add trust anchors to the given context.
Pass name of a file with DS and DNSKEY records in zone file format.
At this time it is only possible to add trusted keys before the
first resolve is done.
At this time it is only possible to add trusted keys before the first
resolve is done.
.TP
.B ub_ctx_trustedkeys
Add trust anchors to the given context.
Pass the name of a bind\-style config file with trusted\-keys{}.
At this time it is only possible to add trusted keys before the
first resolve is done.
Pass the name of a bind\-style config file with \fBtrusted\-keys{}\fP\&.
At this time it is only possible to add trusted keys before the first
resolve is done.
.TP
.B ub_ctx_debugout
Set debug and error log output to the given stream. Pass NULL to disable
output. Default is stderr. File\-names or using syslog can be enabled
using config options, this routine is for using your own stream.
Set debug and error log output to the given stream.
Pass NULL to disable output.
Default is stderr.
File\-names or using syslog can be enabled using config options, this
routine is for using your own stream.
.TP
.B ub_ctx_debuglevel
Set debug verbosity for the context. Output is directed to stderr.
Set debug verbosity for the context.
Output is directed to stderr.
Higher debug level gives more output.
.TP
.B ub_ctx_async
Set a context behaviour for asynchronous action.
if set to true, enables threading and a call to
.B ub_resolve_async
if set to true, enables threading and a call to \fBub_resolve_async\fP
creates a thread to handle work in the background.
If false, a process is forked to handle work in the background.
Changes to this setting after
.B ub_resolve_async
calls have been made have no effect (delete and re\-create the context
to change).
Changes to this setting after \fBub_resolve_async\fP calls have been made
have no effect (delete and re\-create the context to change).
.TP
.B ub_poll
Poll a context to see if it has any new results.
Do not poll in a loop, instead extract the fd below to poll for readiness,
and then check, or wait using the wait routine.
Do not poll in a loop, instead extract the \fBfd\fP below to poll for
readiness, and then check, or wait using the wait routine.
Returns 0 if nothing to read, or nonzero if a result is available.
If nonzero, call
.B ub_process
to do callbacks.
If nonzero, call \fBub_process\fP to do callbacks.
.TP
.B ub_wait
Wait for a context to finish with results. Calls
.B ub_process
after the wait for you. After the wait, there are no more outstanding
asynchronous queries.
Wait for a context to finish with results.
Calls \fBub_process\fP after the wait for you.
After the wait, there are no more outstanding asynchronous queries.
.TP
.B ub_fd
Get file descriptor. Wait for it to become readable, at this point
answers are returned from the asynchronous validating resolver.
Then call the \fBub_process\fR to continue processing.
Get file descriptor.
Wait for it to become readable, at this point answers are returned from
the asynchronous validating resolver.
Then call the \fBub_process\fP to continue processing.
.TP
.B ub_process
Call this routine to continue processing results from the validating
resolver (when the fd becomes readable).
resolver (when the \fBfd\fP becomes readable).
Will perform necessary callbacks.
.TP
.B ub_resolve
@@ -340,95 +311,111 @@ The result structure is newly allocated with the resulting data.
.TP
.B ub_resolve_async
Perform asynchronous resolution and validation of the target name.
Arguments mean the same as for \fBub_resolve\fR except no
data is returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to pass
information to the callback. The callback type is a function pointer to
a function declared as
.IP
void my_callback_function(void* my_arg, int err,
.br
struct ub_result* result);
.IP
The async_id is returned so you can (at your option) decide to track it
and cancel the request if needed. If you pass a NULL pointer the async_id
is not returned.
Arguments mean the same as for \fBub_resolve\fP except no data is
returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to
pass information to the callback.
The callback type is a function pointer to a function declared as:
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
void my_callback_function(void* my_arg, int err,
struct ub_result* result);
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
The \fBasync_id\fP is returned so you can (at your option) decide to
track it and cancel the request if needed.
If you pass a NULL pointer the \fBasync_id\fP is not returned.
.TP
.B ub_cancel
Cancel an async query in progress. This may return an error if the query
does not exist, or the query is already being delivered, in that case you
may still get a callback for the query.
Cancel an async query in progress.
This may return an error if the query does not exist, or the query is
already being delivered, in that case you may still get a callback for
the query.
.TP
.B ub_resolve_free
Free struct ub_result contents after use.
Free struct \fBub_result\fP contents after use.
.TP
.B ub_strerror
Convert error value from one of the unbound library functions
to a human readable string.
Convert error value from one of the unbound library functions to a
human readable string.
.TP
.B ub_ctx_print_local_zones
Debug printout the local authority information to debug output.
.TP
.B ub_ctx_zone_add
Add new zone to local authority info, like local\-zone \fIunbound.conf\fR(5)
statement.
Add new zone to local authority info, like local\-zone
\fI\%unbound.conf(5)\fP statement.
.TP
.B ub_ctx_zone_remove
Delete zone from local authority info.
.TP
.B ub_ctx_data_add
Add resource record data to local authority info, like local\-data
\fIunbound.conf\fR(5) statement.
\fI\%unbound.conf(5)\fP statement.
.TP
.B ub_ctx_data_remove
Delete local authority data from the name given.
.SH "RESULT DATA STRUCTURE"
The result of the DNS resolution and validation is returned as
\fIstruct ub_result\fR. The result structure contains the following entries.
.P
.UNINDENT
.SH RESULT DATA STRUCTURE
.sp
The result of the DNS resolution and validation is returned as \fIstruct
ub_result\fP\&.
The result structure contains the following entries:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
.ft C
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
.ft P
.fi
.P
If both secure and bogus are false, security was not enabled for the
domain of the query. Else, they are not both true, one of them is true.
.SH "RETURN VALUES"
Many routines return an error code. The value 0 (zero) denotes no error
happened. Other values can be passed to
.B ub_strerror
to obtain a readable error string.
.B ub_strerror
returns a zero terminated string.
.B ub_ctx_create
returns NULL on an error (a malloc failure).
.B ub_poll
returns true if some information may be available, false otherwise.
.B ub_fd
returns a file descriptor or \-1 on error.
.B ub_ctx_config
and
.B ub_ctx_resolvconf
attempt to leave errno informative on a function return with file read failure.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
.SH "AUTHORS"
.B Unbound
developers are mentioned in the CREDITS file in the distribution.
.UNINDENT
.UNINDENT
.sp
If both secure and bogus are false, security was not enabled for the domain of
the query.
Else, they are not both true, one of them is true.
.SH RETURN VALUES
.sp
Many routines return an error code.
The value 0 (zero) denotes no error happened.
Other values can be passed to \fBub_strerror\fP to obtain a readable error
string.
\fBub_strerror\fP returns a zero terminated string.
\fBub_ctx_create\fP returns NULL on an error (a malloc failure).
\fBub_poll\fP returns true if some information may be available, false otherwise.
\fBub_fd\fP returns a file descriptor or \-1 on error.
\fBub_ctx_config\fP and \fBub_ctx_resolvconf\fP attempt to leave errno informative
on a function return with file read failure.
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP, \fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
+491
View File
@@ -0,0 +1,491 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
libunbound(3)
=============
Synopsis
--------
.. only:: html
.. code-block:: c
#include <unbound.h>
struct ub_ctx * ub_ctx_create(void);
void ub_ctx_delete(struct ub_ctx* ctx);
int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** val);
int ub_ctx_config(struct ub_ctx* ctx, char* fname);
int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr);
int ub_ctx_set_stub(struct ub_ctx* ctx, char* zone, char* addr,
int isprime);
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname);
int ub_ctx_hosts(struct ub_ctx* ctx, char* fname);
int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta);
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, char* fname);
int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname);
int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname);
int ub_ctx_debugout(struct ub_ctx* ctx, FILE* out);
int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
int ub_ctx_async(struct ub_ctx* ctx, int dothread);
int ub_poll(struct ub_ctx* ctx);
int ub_wait(struct ub_ctx* ctx);
int ub_fd(struct ub_ctx* ctx);
int ub_process(struct ub_ctx* ctx);
int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
int rrclass, struct ub_result** result);
int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
int rrclass, void* mydata, ub_callback_type callback,
int* async_id);
int ub_cancel(struct ub_ctx* ctx, int async_id);
void ub_resolve_free(struct ub_result* result);
const char * ub_strerror(int err);
int ub_ctx_print_local_zones(struct ub_ctx* ctx);
int ub_ctx_zone_add(struct ub_ctx* ctx, char* zone_name, char* zone_type);
int ub_ctx_zone_remove(struct ub_ctx* ctx, char* zone_name);
int ub_ctx_data_add(struct ub_ctx* ctx, char* data);
int ub_ctx_data_remove(struct ub_ctx* ctx, char* data);
.. only:: man
**#include <unbound.h>**
struct ub_ctx \* **ub_ctx_create**\ (void);
void **ub_ctx_delete**\ (struct ub_ctx\* ctx);
int **ub_ctx_set_option**\ (struct ub_ctx\* ctx, char\* opt, char\* val);
int **ub_ctx_get_option**\ (struct ub_ctx\* ctx, char\* opt, char\*\* val);
int **ub_ctx_config**\ (struct ub_ctx\* ctx, char* fname);
int **ub_ctx_set_fwd**\ (struct ub_ctx\* ctx, char\* addr);
int **ub_ctx_set_stub**\ (struct ub_ctx\* ctx, char\* zone, char\* addr,
int isprime);
int **ub_ctx_set_tls**\ (struct ub_ctx\* ctx, int tls);
int **ub_ctx_resolvconf**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_hosts**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_add_ta**\ (struct ub_ctx\* ctx, char\* ta);
int **ub_ctx_add_ta_autr**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_add_ta_file**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_trustedkeys**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_debugout**\ (struct ub_ctx\* ctx, FILE\* out);
int **ub_ctx_debuglevel**\ (struct ub_ctx\* ctx, int d);
int **ub_ctx_async**\ (struct ub_ctx\* ctx, int dothread);
int **ub_poll**\ (struct ub_ctx\* ctx);
int **ub_wait**\ (struct ub_ctx\* ctx);
int **ub_fd**\ (struct ub_ctx\* ctx);
int **ub_process**\ (struct ub_ctx\* ctx);
int **ub_resolve**\ (struct ub_ctx\* ctx, char\* name,
int rrtype, int rrclass, struct ub_result\*\* result);
int **ub_resolve_async**\ (struct ub_ctx\* ctx, char\* name,
int rrtype, int rrclass, void\* mydata,
ub_callback_type\* callback, int\* async_id);
int **ub_cancel**\ (struct ub_ctx\* ctx, int async_id);
void **ub_resolve_free**\ (struct ub_result\* result);
const char \* **ub_strerror**\ (int err);
int **ub_ctx_print_local_zones**\ (struct ub_ctx\* ctx);
int **ub_ctx_zone_add**\ (struct ub_ctx\* ctx, char\* zone_name, char\* zone_type);
int **ub_ctx_zone_remove**\ (struct ub_ctx\* ctx, char\* zone_name);
int **ub_ctx_data_add**\ (struct ub_ctx\* ctx, char\* data);
int **ub_ctx_data_remove**\ (struct ub_ctx\* ctx, char\* data);
Description
-----------
Unbound is an implementation of a DNS resolver, that does caching and DNSSEC
validation.
This is the library API, for using the ``-lunbound`` library.
The server daemon is described in :doc:`unbound(8)</manpages/unbound>`.
The library works independent from a running unbound server, and can be used to
convert hostnames to ip addresses, and back, and obtain other information from
the DNS.
The library performs public-key validation of results with DNSSEC.
The library uses a variable of type *struct ub_ctx* to keep context between
calls.
The user must maintain it, creating it with **ub_ctx_create** and deleting it
with **ub_ctx_delete**.
It can be created and deleted at any time.
Creating it anew removes any previous configuration (such as trusted keys) and
clears any cached results.
The functions are thread-safe, and a context can be used in a threaded (as well
as in a non-threaded) environment.
Also resolution (and validation) can be performed blocking and non-blocking
(also called asynchronous).
The async method returns from the call immediately, so that processing can go
on, while the results become available later.
The functions are discussed in turn below.
Functions
---------
.. glossary::
ub_ctx_create
Create a new context, initialised with defaults.
The information from :file:`/etc/resolv.conf` and :file:`/etc/hosts` is
not utilised by default.
Use **ub_ctx_resolvconf** and **ub_ctx_hosts** to read them.
Before you call this, use the openssl functions
**CRYPTO_set_id_callback** and **CRYPTO_set_locking_callback** to set
up asynchronous operation if you use lib openssl (the application calls
these functions once for initialisation).
Openssl 1.0.0 or later uses the **CRYPTO_THREADID_set_callback**
function.
ub_ctx_delete
Delete validation context and free associated resources.
Outstanding async queries are killed and callbacks are not called for
them.
ub_ctx_set_option
A power-user interface that lets you specify one of the options from
the config file format, see :doc:`unbound.conf(5)</manpages/unbound.conf>`.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
Pass the option name with the trailing ``':'``.
ub_ctx_get_option
A power-user interface that gets an option value.
Some options cannot be gotten, and others return a newline separated
list.
Pass the option name without trailing ``':'``.
The returned value must be free(2)d by the caller.
ub_ctx_config
A power-user interface that lets you specify an unbound config file,
see :doc:`unbound.conf(5)</manpages/unbound.conf>`, which is read for
configuration.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
This function is thread-safe only if a single instance of **ub_ctx**\*
exists in the application.
If several instances exist the application has to ensure that
**ub_ctx_config** is not called in parallel by the different instances.
ub_ctx_set_fwd
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address.
Forwards all DNS requests to that machine, which is expected to run a
recursive resolver.
If the proxy is not DNSSEC capable, validation may fail.
Can be called several times, in that case the addresses are used as
backup servers.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_set_stub
Set a stub zone, authoritative dns servers to use for a particular
zone.
IP4 or IP6 address.
If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it.
Otherwise similar to the stub zone item from unbound's config file.
Can be called several times, for different zones, or to add multiple
addresses for a particular zone.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_set_tls
Enable DNS over TLS (DoT) for machines set with **ub_ctx_set_fwd**.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_resolvconf
By default the root servers are queried and full resolver mode is used,
but you can use this call to read the list of nameservers to use from
the filename given.
Usually :file:`"/etc/resolv.conf"`.
Uses those nameservers as caching proxies.
If they do not support DNSSEC, validation may fail.
Only nameservers are picked up, the searchdomain, ndots and other
settings from *resolv.conf(5)* are ignored.
If fname NULL is passed, :file:`"/etc/resolv.conf"` is used (if on
Windows, the system-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_hosts
Read list of hosts from the filename given.
Usually :file:`"/etc/hosts"`.
When queried for, these addresses are not marked DNSSEC secure.
If fname NULL is passed, :file:`"/etc/hosts"` is used (if on Windows,
:file:`etc/hosts` from WINDIR is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_add_ta
Add a trust anchor to the given context.
At this time it is only possible to add trusted keys before the first
resolve is done.
The format is a string, similar to the zone-file format,
**[domainname]** **[type]** **[rdata contents]**.
Both DS and DNSKEY records are accepted.
ub_ctx_add_ta_autr
Add filename with automatically tracked trust anchor to the given
context.
Pass name of a file with the managed trust anchor.
You can create this file with
:doc:`unbound-anchor(8)</manpages/unbound-anchor>` for the root anchor.
You can also create it with an initial file with one line with a DNSKEY
or DS record.
If the file is writable, it is updated when the trust anchor changes.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_add_ta_file
Add trust anchors to the given context.
Pass name of a file with DS and DNSKEY records in zone file format.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_trustedkeys
Add trust anchors to the given context.
Pass the name of a bind-style config file with ``trusted-keys{}``.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_debugout
Set debug and error log output to the given stream.
Pass NULL to disable output.
Default is stderr.
File-names or using syslog can be enabled using config options, this
routine is for using your own stream.
ub_ctx_debuglevel
Set debug verbosity for the context.
Output is directed to stderr.
Higher debug level gives more output.
ub_ctx_async
Set a context behaviour for asynchronous action.
if set to true, enables threading and a call to **ub_resolve_async**
creates a thread to handle work in the background.
If false, a process is forked to handle work in the background.
Changes to this setting after **ub_resolve_async** calls have been made
have no effect (delete and re-create the context to change).
ub_poll
Poll a context to see if it has any new results.
Do not poll in a loop, instead extract the **fd** below to poll for
readiness, and then check, or wait using the wait routine.
Returns 0 if nothing to read, or nonzero if a result is available.
If nonzero, call **ub_process** to do callbacks.
ub_wait
Wait for a context to finish with results.
Calls **ub_process** after the wait for you.
After the wait, there are no more outstanding asynchronous queries.
ub_fd
Get file descriptor.
Wait for it to become readable, at this point answers are returned from
the asynchronous validating resolver.
Then call the **ub_process** to continue processing.
ub_process
Call this routine to continue processing results from the validating
resolver (when the **fd** becomes readable).
Will perform necessary callbacks.
ub_resolve
Perform resolution and validation of the target name.
The name is a domain name in a zero terminated text string.
The rrtype and rrclass are DNS type and class codes.
The result structure is newly allocated with the resulting data.
ub_resolve_async
Perform asynchronous resolution and validation of the target name.
Arguments mean the same as for **ub_resolve** except no data is
returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to
pass information to the callback.
The callback type is a function pointer to a function declared as:
.. code-block:: c
void my_callback_function(void* my_arg, int err,
struct ub_result* result);
The **async_id** is returned so you can (at your option) decide to
track it and cancel the request if needed.
If you pass a NULL pointer the **async_id** is not returned.
ub_cancel
Cancel an async query in progress.
This may return an error if the query does not exist, or the query is
already being delivered, in that case you may still get a callback for
the query.
ub_resolve_free
Free struct **ub_result** contents after use.
ub_strerror
Convert error value from one of the unbound library functions to a
human readable string.
ub_ctx_print_local_zones
Debug printout the local authority information to debug output.
ub_ctx_zone_add
Add new zone to local authority info, like local-zone
:doc:`unbound.conf(5)</manpages/unbound.conf>` statement.
ub_ctx_zone_remove
Delete zone from local authority info.
ub_ctx_data_add
Add resource record data to local authority info, like local-data
:doc:`unbound.conf(5)</manpages/unbound.conf>` statement.
ub_ctx_data_remove
Delete local authority data from the name given.
Result Data structure
---------------------
The result of the DNS resolution and validation is returned as *struct
ub_result*.
The result structure contains the following entries:
.. code-block:: c
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
If both secure and bogus are false, security was not enabled for the domain of
the query.
Else, they are not both true, one of them is true.
Return Values
-------------
Many routines return an error code.
The value 0 (zero) denotes no error happened.
Other values can be passed to **ub_strerror** to obtain a readable error
string.
**ub_strerror** returns a zero terminated string.
**ub_ctx_create** returns NULL on an error (a malloc failure).
**ub_poll** returns true if some information may be available, false otherwise.
**ub_fd** returns a file descriptor or -1 on error.
**ub_ctx_config** and **ub_ctx_resolvconf** attempt to leave errno informative
on a function return with file read failure.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`, :doc:`unbound(8)</manpages/unbound>`.
+245 -134
View File
@@ -1,189 +1,300 @@
.TH "unbound-anchor" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
.\" Copyright (c) 2008, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound\-anchor
\- Unbound anchor utility.
.SH "SYNOPSIS"
.B unbound\-anchor
.RB [ opts ]
.SH "DESCRIPTION"
.B Unbound\-anchor
performs setup or update of the root trust anchor for DNSSEC validation.
The program fetches the trust anchor with the method from RFC7958 when
regular RFC5011 update fails to bring it up to date.
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-ANCHOR" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound-anchor \- Unbound @version@ anchor utility.
.SH SYNOPSIS
.sp
\fBunbound\-anchor\fP [\fBopts\fP]
.SH DESCRIPTION
.sp
\fBunbound\-anchor\fP performs setup or update of the root trust anchor for DNSSEC
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 \fIunbound\fR(8) DNS server.
.P
scripts.
Before you start the \fI\%unbound(8)\fP DNS server.
.sp
Suggested usage:
.P
.INDENT 0.0
.INDENT 3.5
.sp
.nf
# 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).
#
# start validating resolver
# the unbound.conf contains:
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
unbound \-c unbound.conf
.ft C
# 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).
#
# start validating resolver
# the unbound.conf contains:
# auto\-trust\-anchor\-file: \(dq@UNBOUND_ROOTKEY_FILE@\(dq
unbound \-c unbound.conf
.ft P
.fi
.P
This tool provides builtin default contents for the root anchor and root
update certificate files.
.P
.UNINDENT
.UNINDENT
.sp
This tool provides builtin default contents for the root anchor and root update
certificate files.
.sp
It tests if the root anchor file works, and if not, and an update is possible,
attempts to update the root anchor using the root update certificate.
It performs a https fetch of root-anchors.xml and checks the results (RFC7958),
if all checks are successful, it updates the root anchor file. Otherwise
the root anchor file is unchanged. It performs RFC5011 tracking if the
DNSSEC information available via the DNS makes that possible.
.P
It does not perform an update if the certificate is expired, if the network
is down or other errors occur.
.P
It performs a https fetch of
\fI\%root\-anchors.xml\fP
and checks the results (\fI\%RFC 7958\fP); if all checks are successful, it updates
the root anchor file.
Otherwise the root anchor file is unchanged.
It performs \fI\%RFC 5011\fP tracking if the DNSSEC information available via the
DNS makes that possible.
.sp
It does not perform an update if the certificate is expired, if the network is
down or other errors occur.
.sp
The available options are:
.INDENT 0.0
.TP
.B \-a \fIfile
.B \-a <file>
The root anchor key file, that is read in and written out.
Default is @UNBOUND_ROOTKEY_FILE@.
If the file does not exist, or is empty, a builtin root key is written to it.
Default is \fB@UNBOUND_ROOTKEY_FILE@\fP\&.
If the file does not exist, or is empty, a builtin root key is written
to it.
.UNINDENT
.INDENT 0.0
.TP
.B \-c \fIfile
.B \-c <file>
The root update certificate file, that is read in.
Default is @UNBOUND_ROOTCERT_FILE@.
Default is \fB@UNBOUND_ROOTCERT_FILE@\fP\&.
If the file does not exist, or is empty, a builtin certificate is used.
.UNINDENT
.INDENT 0.0
.TP
.B \-l
List the builtin root key and builtin root update certificate on stdout.
.UNINDENT
.INDENT 0.0
.TP
.B \-u \fIname
The server name, it connects to https://name. Specify without https:// prefix.
The default is "data.iana.org". It connects to the port specified with \-P.
.B \-u <name>
The server name, it connects to \fBhttps://name\fP\&.
Specify without \fBhttps://\fP prefix.
The default is \fB\(dqdata.iana.org\(dq\fP\&.
It connects to the port specified with \fI\%\-P\fP\&.
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
.UNINDENT
.INDENT 0.0
.TP
.B \-S
Do not use SNI for the HTTPS connection. Default is to use SNI.
Do not use SNI for the HTTPS connection.
Default is to use SNI.
.UNINDENT
.INDENT 0.0
.TP
.B \-b \fIaddress
The source address to bind to for domain resolution and contacting the server
on https. May be either an IPv4 address or IPv6 address (no brackets).
.B \-b <address>
The source address to bind to for domain resolution and contacting the
server on https.
May be either an IPv4 address or IPv6 address (no brackets).
.UNINDENT
.INDENT 0.0
.TP
.B \-x \fIpath
The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
The default is /root\-anchors/root\-anchors.xml.
.B \-x <path>
The pathname to the root\-anchors.xml file on the server.
(forms URL with \fI\%\-u\fP).
The default is \fB/root\-anchors/root\-anchors.xml\fP\&.
.UNINDENT
.INDENT 0.0
.TP
.B \-s \fIpath
The pathname to the root\-anchors.p7s file on the server. (forms URL with \-u).
The default is /root\-anchors/root\-anchors.p7s. This file has to be a PKCS7
signature over the xml file, using the pem file (\-c) as trust anchor.
.B \-s <path>
The pathname to the root\-anchors.p7s file on the server.
(forms URL with \fI\%\-u\fP).
The default is \fB/root\-anchors/root\-anchors.p7s\fP\&.
This file has to be a PKCS7 signature over the xml file, using the pem
file (\fI\%\-c\fP) as trust anchor.
.UNINDENT
.INDENT 0.0
.TP
.B \-n \fIname
The emailAddress for the Subject of the signer's certificate from the p7s
signature file. Only signatures from this name are allowed. default is
dnssec@iana.org. If you pass "" then the emailAddress is not checked.
.B \-n <name>
The emailAddress for the Subject of the signer\(aqs certificate from the
p7s signature file.
Only signatures from this name are allowed.
The default is \fBdnssec@iana.org\fP\&.
If you pass \fB\(dq\(dq\fP then the emailAddress is not checked.
.UNINDENT
.INDENT 0.0
.TP
.B \-4
Use IPv4 for domain resolution and contacting the server on https. Default is
to use IPv4 and IPv6 where appropriate.
Use IPv4 for domain resolution and contacting the server on
https.
Default is to use IPv4 and IPv6 where appropriate.
.UNINDENT
.INDENT 0.0
.TP
.B \-6
Use IPv6 for domain resolution and contacting the server on https. Default is
to use IPv4 and IPv6 where appropriate.
Use IPv6 for domain resolution and contacting the server on https.
Default is to use IPv4 and IPv6 where appropriate.
.UNINDENT
.INDENT 0.0
.TP
.B \-f \fIresolv.conf
Use the given resolv.conf file. Not enabled by default, but you could try to
pass /etc/resolv.conf on some systems. It contains the IP addresses of the
recursive nameservers to use. However, since this tool could be used to
bootstrap that very recursive nameserver, it would not be useful (since
that server is not up yet, since we are bootstrapping it). It could be
useful in a situation where you know an upstream cache is deployed (and
running) and in captive portal situations.
.B \-f <resolv.conf>
Use the given resolv.conf file.
Not enabled by default, but you could try to pass
\fB/etc/resolv.conf\fP on some systems.
It contains the IP addresses of the recursive nameservers to use.
However, since this tool could be used to bootstrap that very recursive
nameserver, it would not be useful (since that server is not up yet,
since we are bootstrapping it).
It could be useful in a situation where you know an upstream cache is
deployed (and running) and in captive portal situations.
.UNINDENT
.INDENT 0.0
.TP
.B \-r \fIroot.hints
Use the given root.hints file (same syntax as the BIND and Unbound root hints
file) to bootstrap domain resolution. By default a list of builtin root
hints is used. Unbound\-anchor goes to the network itself for these roots,
to resolve the server (\-u option) and to check the root DNSKEY records.
.B \-r <root.hints>
Use the given root.hints file (same syntax as the BIND and Unbound root
hints file) to bootstrap domain resolution.
By default a list of builtin root hints is used.
unbound\-anchor goes to the network itself for these roots, to resolve
the server (\fI\%\-u\fP option) and to check the root DNSKEY records.
It does so, because the tool when used for bootstrapping the recursive
resolver, cannot use that recursive resolver itself because it is bootstrapping
that server.
resolver, cannot use that recursive resolver itself because it is
bootstrapping that server.
.UNINDENT
.INDENT 0.0
.TP
.B \-R
Allow fallback from \-f resolv.conf file to direct root servers query.
It allows you to prefer local resolvers, but fallback automatically
to direct root query if they do not respond or do not support DNSSEC.
Allow fallback from \fI\%\-f\fP \fB<resolv.conf>\fP file to direct root
servers query.
It allows you to prefer local resolvers, but fallback automatically to
direct root query if they do not respond or do not support DNSSEC.
.UNINDENT
.INDENT 0.0
.TP
.B \-v
More verbose. Once prints informational messages, multiple times may enable
large debug amounts (such as full certificates or byte\-dumps of downloaded
files). By default it prints almost nothing. It also prints nothing on
errors by default; in that case the original root anchor file is simply
left undisturbed, so that a recursive server can start right after it.
More verbose.
Once prints informational messages, multiple times may enable large
debug amounts (such as full certificates or byte\-dumps of downloaded
files).
By default it prints almost nothing.
It also prints nothing on errors by default; in that case the original
root anchor file is simply left undisturbed, so that a recursive server
can start right after it.
.UNINDENT
.INDENT 0.0
.TP
.B \-C \fIunbound.conf
Debug option to read unbound.conf into the resolver process used.
.B \-C <unbound.conf>
Debug option to read \fB<unbound.conf>\fP into the resolver process
used.
.UNINDENT
.INDENT 0.0
.TP
.B \-P \fIport
Set the port number to use for the https connection. The default is 443.
.B \-P <port>
Set the port number to use for the https connection.
The default is 443.
.UNINDENT
.INDENT 0.0
.TP
.B \-F
Debug option to force update of the root anchor through downloading the xml
file and verifying it with the certificate. By default it first tries to
update by contacting the DNS, which uses much less bandwidth, is much
faster (200 msec not 2 sec), and is nicer to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell you),
but then ignores the result and goes on to use the xml fallback method.
Debug option to force update of the root anchor through downloading the
xml file and verifying it with the certificate.
By default it first tries to update by contacting the DNS, which uses
much less bandwidth, is much faster (200 msec not 2 sec), and is nicer
to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell
you), but then ignores the result and goes on to use the xml fallback
method.
.UNINDENT
.INDENT 0.0
.TP
.B \-h
Show the version and commandline option help.
.SH "EXIT CODE"
.UNINDENT
.SH EXIT CODE
.sp
This tool exits with value 1 if the root anchor was updated using the
certificate or if the builtin root-anchor was used. It exits with code
0 if no update was necessary, if the update was possible with RFC5011
tracking, or if an error occurred.
.P
certificate or if the builtin root\-anchor was used.
It exits with code 0 if no update was necessary, if the update was possible
with \fI\%RFC 5011\fP tracking, or if an error occurred.
.sp
You can check the exit value in this manner:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
unbound-anchor \-a "root.key" || logger "Please check root.key"
.ft C
unbound\-anchor \-a \(dqroot.key\(dq || logger \(dqPlease check root.key\(dq
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Or something more suitable for your operational environment.
.SH "TRUST"
The root keys and update certificate included in this tool
are provided for convenience and under the terms of our
license (see the LICENSE file in the source distribution or
https://github.com/NLnetLabs/unbound/blob/master/LICENSE) and might be stale or
not suitable to your purpose.
.P
By running "unbound\-anchor \-l" the keys and certificate that are
.SH TRUST
.sp
The root keys and update certificate included in this tool are provided for
convenience and under the terms of our license (see the LICENSE file in the
source distribution or \fI\%https://github.com/NLnetLabs/unbound/blob/master/LICENSE\fP
and might be stale or not suitable to your purpose.
.sp
By running \fI\%unbound\-anchor \-l\fP the keys and certificate that are
configured in the code are printed for your convenience.
.P
The build\-in configuration can be overridden by providing a root\-cert
file and a rootkey file.
.SH "FILES"
.sp
The built\-in configuration can be overridden by providing a root\-cert file and
a rootkey file.
.SH FILES
.INDENT 0.0
.TP
.I @UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written to.
.B @UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written
to.
The file is created if it does not exist.
.TP
.I @UNBOUND_ROOTCERT_FILE@
The trusted self\-signed certificate that is used to verify the downloaded
DNSSEC root trust anchor. You can update it by fetching it from
https://data.iana.org/root\-anchors/icannbundle.pem (and validate it).
.B @UNBOUND_ROOTCERT_FILE@
The trusted self\-signed certificate that is used to verify the
downloaded DNSSEC root trust anchor.
You can update it by fetching it from
\fI\%https://data.iana.org/root\-anchors/icannbundle.pem\fP (and validate it).
If the file does not exist or is empty, a builtin version is used.
.TP
.I https://data.iana.org/root\-anchors/root\-anchors.xml
.B \fI\%https://data.iana.org/root\-anchors/root\-anchors.xml\fP
Source for the root key information.
.TP
.I https://data.iana.org/root\-anchors/root\-anchors.p7s
.B \fI\%https://data.iana.org/root\-anchors/root\-anchors.p7s\fP
Signature on the root key information.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
+281
View File
@@ -0,0 +1,281 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-anchor
unbound-anchor(8)
=================
Synopsis
--------
**unbound-anchor** [``opts``]
Description
-----------
``unbound-anchor`` performs setup or update of the root trust anchor for DNSSEC
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.
Suggested usage:
.. code-block:: text
# 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).
#
# start validating resolver
# the unbound.conf contains:
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
unbound -c unbound.conf
This tool provides builtin default contents for the root anchor and root update
certificate files.
It tests if the root anchor file works, and if not, and an update is possible,
attempts to update the root anchor using the root update certificate.
It performs a https fetch of
`root-anchors.xml <http://data.iana.org/root-anchors/root-anchors.xml>`__
and checks the results (:rfc:`7958`); if all checks are successful, it updates
the root anchor file.
Otherwise the root anchor file is unchanged.
It performs :rfc:`5011` tracking if the DNSSEC information available via the
DNS makes that possible.
It does not perform an update if the certificate is expired, if the network is
down or other errors occur.
The available options are:
.. option:: -a <file>
The root anchor key file, that is read in and written out.
Default is :file:`@UNBOUND_ROOTKEY_FILE@`.
If the file does not exist, or is empty, a builtin root key is written
to it.
.. option:: -c <file>
The root update certificate file, that is read in.
Default is :file:`@UNBOUND_ROOTCERT_FILE@`.
If the file does not exist, or is empty, a builtin certificate is used.
.. option:: -l
List the builtin root key and builtin root update certificate on stdout.
.. option:: -u <name>
The server name, it connects to ``https://name``.
Specify without ``https://`` prefix.
The default is ``"data.iana.org"``.
It connects to the port specified with :option:`-P`.
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
.. option:: -S
Do not use SNI for the HTTPS connection.
Default is to use SNI.
.. option:: -b <address>
The source address to bind to for domain resolution and contacting the
server on https.
May be either an IPv4 address or IPv6 address (no brackets).
.. option:: -x <path>
The pathname to the root-anchors.xml file on the server.
(forms URL with :option:`-u`).
The default is :file:`/root-anchors/root-anchors.xml`.
.. option:: -s <path>
The pathname to the root-anchors.p7s file on the server.
(forms URL with :option:`-u`).
The default is :file:`/root-anchors/root-anchors.p7s`.
This file has to be a PKCS7 signature over the xml file, using the pem
file (:option:`-c`) as trust anchor.
.. option:: -n <name>
The emailAddress for the Subject of the signer's certificate from the
p7s signature file.
Only signatures from this name are allowed.
The default is ``dnssec@iana.org``.
If you pass ``""`` then the emailAddress is not checked.
.. option:: -4
Use IPv4 for domain resolution and contacting the server on
https.
Default is to use IPv4 and IPv6 where appropriate.
.. option:: -6
Use IPv6 for domain resolution and contacting the server on https.
Default is to use IPv4 and IPv6 where appropriate.
.. option:: -f <resolv.conf>
Use the given resolv.conf file.
Not enabled by default, but you could try to pass
:file:`/etc/resolv.conf` on some systems.
It contains the IP addresses of the recursive nameservers to use.
However, since this tool could be used to bootstrap that very recursive
nameserver, it would not be useful (since that server is not up yet,
since we are bootstrapping it).
It could be useful in a situation where you know an upstream cache is
deployed (and running) and in captive portal situations.
.. option:: -r <root.hints>
Use the given root.hints file (same syntax as the BIND and Unbound root
hints file) to bootstrap domain resolution.
By default a list of builtin root hints is used.
unbound-anchor goes to the network itself for these roots, to resolve
the server (:option:`-u` option) and to check the root DNSKEY records.
It does so, because the tool when used for bootstrapping the recursive
resolver, cannot use that recursive resolver itself because it is
bootstrapping that server.
.. option:: -R
Allow fallback from :option:`-f` ``<resolv.conf>`` file to direct root
servers query.
It allows you to prefer local resolvers, but fallback automatically to
direct root query if they do not respond or do not support DNSSEC.
.. option:: -v
More verbose.
Once prints informational messages, multiple times may enable large
debug amounts (such as full certificates or byte-dumps of downloaded
files).
By default it prints almost nothing.
It also prints nothing on errors by default; in that case the original
root anchor file is simply left undisturbed, so that a recursive server
can start right after it.
.. option:: -C <unbound.conf>
Debug option to read :file:`<unbound.conf>` into the resolver process
used.
.. option:: -P <port>
Set the port number to use for the https connection.
The default is 443.
.. option:: -F
Debug option to force update of the root anchor through downloading the
xml file and verifying it with the certificate.
By default it first tries to update by contacting the DNS, which uses
much less bandwidth, is much faster (200 msec not 2 sec), and is nicer
to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell
you), but then ignores the result and goes on to use the xml fallback
method.
.. option:: -h
Show the version and commandline option help.
Exit Code
---------
This tool exits with value 1 if the root anchor was updated using the
certificate or if the builtin root-anchor was used.
It exits with code 0 if no update was necessary, if the update was possible
with :rfc:`5011` tracking, or if an error occurred.
You can check the exit value in this manner:
.. code-block:: text
unbound-anchor -a "root.key" || logger "Please check root.key"
Or something more suitable for your operational environment.
Trust
-----
The root keys and update certificate included in this tool are provided for
convenience and under the terms of our license (see the LICENSE file in the
source distribution or https://github.com/NLnetLabs/unbound/blob/master/LICENSE
and might be stale or not suitable to your purpose.
By running :option:`unbound-anchor -l` the keys and certificate that are
configured in the code are printed for your convenience.
The built-in configuration can be overridden by providing a root-cert file and
a rootkey file.
Files
-----
@UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written
to.
The file is created if it does not exist.
@UNBOUND_ROOTCERT_FILE@
The trusted self-signed certificate that is used to verify the
downloaded DNSSEC root trust anchor.
You can update it by fetching it from
https://data.iana.org/root-anchors/icannbundle.pem (and validate it).
If the file does not exist or is empty, a builtin version is used.
https://data.iana.org/root-anchors/root-anchors.xml
Source for the root key information.
https://data.iana.org/root-anchors/root-anchors.p7s
Signature on the root key information.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+79 -42
View File
@@ -1,56 +1,93 @@
.TH "unbound-checkconf" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
unbound\-checkconf
\- Check Unbound configuration file for errors.
.SH "SYNOPSIS"
.B unbound\-checkconf
.RB [ \-h ]
.RB [ \-f ]
.RB [ \-q ]
.RB [ \-o
.IR option ]
.RI [ cfgfile ]
.SH "DESCRIPTION"
.B Unbound\-checkconf
checks the configuration file for the
\fIunbound\fR(8)
DNS resolver for syntax and other errors.
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-CHECKCONF" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound-checkconf \- Check Unbound @version@ configuration file for errors.
.SH SYNOPSIS
.sp
\fBunbound\-checkconf\fP [\fB\-hf\fP] [\fB\-o option\fP] [cfgfile]
.SH DESCRIPTION
.sp
\fBunbound\-checkconf\fP checks the configuration file for the
\fI\%unbound(8)\fP DNS resolver for syntax and other errors.
The config file syntax is described in
\fIunbound.conf\fR(5).
.P
\fI\%unbound.conf(5)\fP\&.
.sp
The available options are:
.INDENT 0.0
.TP
.B \-h
Show the version and commandline option help.
.UNINDENT
.INDENT 0.0
.TP
.B \-f
Print full pathname, with chroot applied to it. Use with the \-o option.
.TP
.B \-o\fI option
If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed.
Print full pathname, with chroot applied to it.
Use with the \fI\%\-o\fP option.
.UNINDENT
.INDENT 0.0
.TP
.B \-q
Make the operation quiet, suppress output on success.
.UNINDENT
.INDENT 0.0
.TP
.I cfgfile
The config file to read with settings for Unbound. It is checked.
.B \-o <option>
If given, after checking the config file the value of this option is
printed to stdout.
For \fB\(dq\(dq\fP (disabled) options an empty line is printed.
.UNINDENT
.INDENT 0.0
.TP
.B cfgfile
The config file to read with settings for Unbound.
It is checked.
If omitted, the config file at the default location is checked.
.SH "EXIT CODE"
The unbound\-checkconf program exits with status code 1 on error,
0 for a correct config file.
.SH "FILES"
.UNINDENT
.SH EXIT CODE
.sp
The \fBunbound\-checkconf\fP program exits with status code 1 on error, 0 for a
correct config file.
.SH FILES
.INDENT 0.0
.TP
.I @ub_conf_file@
.B @ub_conf_file@
Unbound configuration file.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
+98
View File
@@ -0,0 +1,98 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-checkconf
unbound-checkconf(8)
====================
Synopsis
--------
**unbound-checkconf** [``-hf``] [``-o option``] [cfgfile]
Description
-----------
``unbound-checkconf`` checks the configuration file for the
:doc:`unbound(8)</manpages/unbound>` DNS resolver for syntax and other errors.
The config file syntax is described in
:doc:`unbound.conf(5)</manpages/unbound.conf>`.
The available options are:
.. option:: -h
Show the version and commandline option help.
.. option:: -f
Print full pathname, with chroot applied to it.
Use with the :option:`-o` option.
.. option:: -q
Make the operation quiet, suppress output on success.
.. option:: -o <option>
If given, after checking the config file the value of this option is
printed to stdout.
For ``""`` (disabled) options an empty line is printed.
.. option:: cfgfile
The config file to read with settings for Unbound.
It is checked.
If omitted, the config file at the default location is checked.
Exit Code
---------
The ``unbound-checkconf`` program exits with status code 1 on error, 0 for a
correct config file.
Files
-----
@ub_conf_file@
Unbound configuration file.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+1203 -637
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+157 -85
View File
@@ -1,118 +1,190 @@
.TH "unbound\-host" "1" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound\-host
\- unbound DNS lookup utility
.SH "SYNOPSIS"
.B unbound\-host
.RB [ \-C
.IR configfile ]
.RB [ \-vdhr46D ]
.RB [ \-c
.IR class ]
.RB [ \-t
.IR type ]
.RB [ \-y
.IR key ]
.RB [ \-f
.IR keyfile ]
.RB [ \-F
.IR namedkeyfile ]
.I hostname
.SH "DESCRIPTION"
.B Unbound\-host
uses the Unbound validating resolver to query for the hostname and display
results. With the \fB\-v\fR option it displays validation
status: secure, insecure, bogus (security failure).
.P
By default it reads no configuration file whatsoever. It attempts to reach
the internet root servers. With \fB\-C\fR an Unbound config file and with
\fB\-r\fR resolv.conf can be read.
.P
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-HOST" "1" "@date@" "@version@" "Unbound"
.SH NAME
unbound-host \- Unbound @version@ DNS lookup utility.
.SH SYNOPSIS
.sp
\fBunbound\-host\fP [\fB\-C configfile\fP] [\fB\-vdhr46D\fP] [\fB\-c class\fP]
[\fB\-t type\fP] [\fB\-y key\fP] [\fB\-f keyfile\fP] [\fB\-F namedkeyfile\fP] hostname
.SH DESCRIPTION
.sp
\fBunbound\-host\fP uses the Unbound validating resolver to query for the hostname
and display results.
With the \fI\%\-v\fP option it displays validation status: secure, insecure,
bogus (security failure).
.sp
By default it reads no configuration file whatsoever.
It attempts to reach the internet root servers.
With \fI\%\-C\fP an unbound config file and with \fI\%\-r\fP \fBresolv.conf\fP
can be read.
.sp
The available options are:
.INDENT 0.0
.TP
.I hostname
.B hostname
This name is resolved (looked up in the DNS).
If a IPv4 or IPv6 address is given, a reverse lookup is performed.
.UNINDENT
.INDENT 0.0
.TP
.B \-h
Show the version and commandline option help.
.UNINDENT
.INDENT 0.0
.TP
.B \-v
Enable verbose output and it shows validation results, on every line.
Secure means that the NXDOMAIN (no such domain name), nodata (no such data)
or positive data response validated correctly with one of the keys.
Secure means that the NXDOMAIN (no such domain name), nodata (no such
data) or positive data response validated correctly with one of the
keys.
Insecure means that that domain name has no security set up for it.
Bogus (security failure) means that the response failed one or more checks,
it is likely wrong, outdated, tampered with, or broken.
Bogus (security failure) means that the response failed one or more
checks, it is likely wrong, outdated, tampered with, or broken.
.UNINDENT
.INDENT 0.0
.TP
.B \-d
Enable debug output to stderr. One \-d shows what the resolver and validator
are doing and may tell you what is going on. More times, \-d \-d, gives a
lot of output, with every packet sent and received.
Enable debug output to stderr.
One \fI\%\-d\fP shows what the resolver and validator are doing and may
tell you what is going on.
More times, \fI\%\-d\fP \fI\%\-d\fP, gives a lot of output, with every
packet sent and received.
.UNINDENT
.INDENT 0.0
.TP
.B \-c \fIclass
Specify the class to lookup for, the default is IN the internet class.
.B \-c <class>
Specify the class to lookup for, the default is IN the internet
class.
.UNINDENT
.INDENT 0.0
.TP
.B \-t \fItype
Specify the type of data to lookup. The default looks for IPv4, IPv6 and
mail handler data, or domain name pointers for reverse queries.
.B \-t <type>
Specify the type of data to lookup.
The default looks for IPv4, IPv6 and mail handler data, or domain name
pointers for reverse queries.
.UNINDENT
.INDENT 0.0
.TP
.B \-y \fIkey
Specify a public key to use as trust anchor. This is the base for a chain
of trust that is built up from the trust anchor to the response, in order
to validate the response message. Can be given as a DS or DNSKEY record.
For example \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD".
.B \-y <key>
Specify a public key to use as trust anchor.
This is the base for a chain of trust that is built up from the trust
anchor to the response, in order to validate the response message.
Can be given as a DS or DNSKEY record.
For example:
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
\-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq
.ft P
.fi
.UNINDENT
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B \-D
Enables DNSSEC validation. Reads the root anchor from the default configured
root anchor at the default location, \fI@UNBOUND_ROOTKEY_FILE@\fR.
Enables DNSSEC validation.
Reads the root anchor from the default configured root anchor at the
default location, \fB@UNBOUND_ROOTKEY_FILE@\fP\&.
.UNINDENT
.INDENT 0.0
.TP
.B \-f \fIkeyfile
Reads keys from a file. Every line has a DS or DNSKEY record, in the format
as for \-y. The zone file format, the same as dig and drill produce.
.B \-f <keyfile>
Reads keys from a file.
Every line has a DS or DNSKEY record, in the format as for \fI\%\-y\fP\&.
The zone file format, the same as \fBdig\fP and \fBdrill\fP produce.
.UNINDENT
.INDENT 0.0
.TP
.B \-F \fInamedkeyfile
Reads keys from a BIND\-style named.conf file. Only the trusted\-key {}; entries
are read.
.B \-F <namedkeyfile>
Reads keys from a BIND\-style \fBnamed.conf\fP file.
Only the \fBtrusted\-key {};\fP entries are read.
.UNINDENT
.INDENT 0.0
.TP
.B \-C \fIconfigfile
Uses the specified unbound.conf to prime
.IR libunbound (3).
.B \-C <configfile>
Uses the specified unbound.conf to prime \fI\%libunbound(3)\fP\&.
Pass it as first argument if you want to override some options from the
config file with further arguments on the commandline.
.UNINDENT
.INDENT 0.0
.TP
.B \-r
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
have been set by DHCP). More info in
.IR resolv.conf (5).
Read \fB/etc/resolv.conf\fP, and use the forward DNS servers from
there (those could have been set by DHCP).
More info in \fIresolv.conf(5)\fP\&.
Breaks validation if those servers do not support DNSSEC.
.UNINDENT
.INDENT 0.0
.TP
.B \-4
Use solely the IPv4 network for sending packets.
.UNINDENT
.INDENT 0.0
.TP
.B \-6
Use solely the IPv6 network for sending packets.
.SH "EXAMPLES"
Some examples of use. The keys shown below are fakes, thus a security failure
is encountered.
.P
.UNINDENT
.SH EXAMPLES
.sp
Some examples of use.
The keys shown below are fakes, thus a security failure is encountered.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ unbound\-host www.example.com
.P
$ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" www.example.com
.P
$ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" 192.0.2.153
.SH "EXIT CODE"
The unbound\-host program exits with status code 1 on error,
0 on no error. The data may not be available on exit code 0, exit code 1
means the lookup encountered a fatal error.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
$ unbound\-host \-v \-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq www.example.com
$ unbound\-host \-v \-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq 192.0.2.153
.ft P
.fi
.UNINDENT
.UNINDENT
.SH EXIT CODE
.sp
The \fBunbound\-host\fP program exits with status code 1 on error, 0 on no error.
The data may not be available on exit code 0, exit code 1 means the lookup
encountered a fatal error.
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
+176
View File
@@ -0,0 +1,176 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-host
unbound-host(1)
===============
Synopsis
--------
**unbound-host** [``-C configfile``] [``-vdhr46D``] [``-c class``]
[``-t type``] [``-y key``] [``-f keyfile``] [``-F namedkeyfile``] hostname
Description
-----------
``unbound-host`` uses the Unbound validating resolver to query for the hostname
and display results.
With the :option:`-v` option it displays validation status: secure, insecure,
bogus (security failure).
By default it reads no configuration file whatsoever.
It attempts to reach the internet root servers.
With :option:`-C` an unbound config file and with :option:`-r` ``resolv.conf``
can be read.
The available options are:
.. option:: hostname
This name is resolved (looked up in the DNS).
If a IPv4 or IPv6 address is given, a reverse lookup is performed.
.. option:: -h
Show the version and commandline option help.
.. option:: -v
Enable verbose output and it shows validation results, on every line.
Secure means that the NXDOMAIN (no such domain name), nodata (no such
data) or positive data response validated correctly with one of the
keys.
Insecure means that that domain name has no security set up for it.
Bogus (security failure) means that the response failed one or more
checks, it is likely wrong, outdated, tampered with, or broken.
.. option:: -d
Enable debug output to stderr.
One :option:`-d` shows what the resolver and validator are doing and may
tell you what is going on.
More times, :option:`-d` :option:`-d`, gives a lot of output, with every
packet sent and received.
.. option:: -c <class>
Specify the class to lookup for, the default is IN the internet
class.
.. option:: -t <type>
Specify the type of data to lookup.
The default looks for IPv4, IPv6 and mail handler data, or domain name
pointers for reverse queries.
.. option:: -y <key>
Specify a public key to use as trust anchor.
This is the base for a chain of trust that is built up from the trust
anchor to the response, in order to validate the response message.
Can be given as a DS or DNSKEY record.
For example:
.. code-block:: text
-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD"
.. option:: -D
Enables DNSSEC validation.
Reads the root anchor from the default configured root anchor at the
default location, :file:`@UNBOUND_ROOTKEY_FILE@`.
.. option:: -f <keyfile>
Reads keys from a file.
Every line has a DS or DNSKEY record, in the format as for :option:`-y`.
The zone file format, the same as ``dig`` and ``drill`` produce.
.. option:: -F <namedkeyfile>
Reads keys from a BIND-style :file:`named.conf` file.
Only the ``trusted-key {};`` entries are read.
.. option:: -C <configfile>
Uses the specified unbound.conf to prime :doc:`libunbound(3)</manpages/libunbound>`.
Pass it as first argument if you want to override some options from the
config file with further arguments on the commandline.
.. option:: -r
Read :file:`/etc/resolv.conf`, and use the forward DNS servers from
there (those could have been set by DHCP).
More info in *resolv.conf(5)*.
Breaks validation if those servers do not support DNSSEC.
.. option:: -4
Use solely the IPv4 network for sending packets.
.. option:: -6
Use solely the IPv6 network for sending packets.
Examples
--------
Some examples of use.
The keys shown below are fakes, thus a security failure is encountered.
.. code-block:: text
$ unbound-host www.example.com
$ unbound-host -v -y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" www.example.com
$ unbound-host -v -y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" 192.0.2.153
Exit Code
---------
The ``unbound-host`` program exits with status code 1 on error, 0 on no error.
The data may not be available on exit code 0, exit code 1 means the lookup
encountered a fatal error.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+102 -67
View File
@@ -1,88 +1,123 @@
.TH "unbound" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound.8 -- unbound manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver @version@.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
.RB [ \-d ]
.RB [ \-p ]
.RB [ \-v ]
.RB [ \-c
.IR cfgfile ]
.SH "DESCRIPTION"
.B Unbound
is a caching DNS resolver.
.P
It uses a built in list of authoritative nameservers for the root zone (.),
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound \- Unbound DNS validating resolver @version@.
.SH SYNOPSIS
.sp
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
.SH DESCRIPTION
.sp
\fBunbound\fP is a caching DNS resolver.
.sp
It uses a built in list of authoritative nameservers for the root zone (\fB\&.\fP),
the so called root hints.
On receiving a DNS query it will ask the root nameservers for
an answer and will in almost all cases receive a delegation to a top level
domain (TLD) authoritative nameserver.
On receiving a DNS query it will ask the root nameservers for an answer and
will in almost all cases receive a delegation to a top level domain (TLD)
authoritative nameserver.
It will then ask that nameserver for an answer.
It will recursively continue until an answer is found or no answer is
available (NXDOMAIN).
For performance and efficiency reasons that answer is cached for a
certain time (the answer's time\-to\-live or TTL).
It will recursively continue until an answer is found or no answer is available
(NXDOMAIN).
For performance and efficiency reasons that answer is cached for a certain time
(the answer\(aqs time\-to\-live or TTL).
A second query for the same name will then be answered from the cache.
Unbound can also do DNSSEC validation.
.P
To use a locally running
.B Unbound
for resolving put
.sp
.RS 6n
To use a locally running Unbound for resolving put:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
nameserver 127.0.0.1
.RE
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
into \fIresolv.conf(5)\fP\&.
.sp
If authoritative DNS is needed as well using \fI\%nsd(8)\fP,
careful setup is required because authoritative nameservers and resolvers are
using the same port number (53).
.sp
into
.IR resolv.conf (5).
.P
If authoritative DNS is needed as well using
.IR nsd (8),
careful setup is required because authoritative nameservers and
resolvers are using the same port number (53).
.P
The available options are:
.INDENT 0.0
.TP
.B \-h
Show the version number and commandline option help, and exit.
.UNINDENT
.INDENT 0.0
.TP
.B \-c\fI cfgfile
Set the config file with settings for Unbound to read instead of reading the
file at the default location, @ub_conf_file@. The syntax is
described in \fIunbound.conf\fR(5).
.B \-c <cfgfile>
Set the config file with settings for unbound to read instead of reading the
file at the default location, \fB@ub_conf_file@\fP\&.
The syntax is described in \fI\%unbound.conf(5)\fP\&.
.UNINDENT
.INDENT 0.0
.TP
.B \-d
Debug flag: do not fork into the background, but stay attached to
the console. This flag will also delay writing to the log file until
the thread\-spawn time, so that most config and setup errors appear on
stderr. If given twice or more, logging does not switch to the log file
or to syslog, but the log messages are printed to stderr all the time.
Debug flag: do not fork into the background, but stay attached to the
console.
This flag will also delay writing to the log file until the thread\-spawn
time, so that most config and setup errors appear on stderr.
If given twice or more, logging does not switch to the log file or to
syslog, but the log messages are printed to stderr all the time.
.UNINDENT
.INDENT 0.0
.TP
.B \-p
Don't use a pidfile. This argument should only be used by supervision
systems which can ensure that only one instance of Unbound will run
concurrently.
Don\(aqt use a pidfile.
This argument should only be used by supervision systems which can ensure
that only one instance of Unbound will run concurrently.
.UNINDENT
.INDENT 0.0
.TP
.B \-v
Increase verbosity. If given multiple times, more information is logged.
This is added to the verbosity (if any) from the config file.
Increase verbosity.
If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.UNINDENT
.INDENT 0.0
.TP
.B \-V
Show the version number and build options, and exit.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\-checkconf\fR(8),
\fInsd\fR(8).
.SH "AUTHORS"
.B Unbound
developers are mentioned in the CREDITS file in the distribution.
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound\-checkconf(8)\fP,
\fI\%nsd(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
+5225 -2552
View File
File diff suppressed because it is too large Load Diff
+5235
View File
File diff suppressed because it is too large Load Diff
+119
View File
@@ -0,0 +1,119 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound
unbound(8)
==========
Synopsis
--------
**unbound** [``-hdpv``] [``-c <cfgfile>``]
Description
-----------
``unbound`` is a caching DNS resolver.
It uses a built in list of authoritative nameservers for the root zone (``.``),
the so called root hints.
On receiving a DNS query it will ask the root nameservers for an answer and
will in almost all cases receive a delegation to a top level domain (TLD)
authoritative nameserver.
It will then ask that nameserver for an answer.
It will recursively continue until an answer is found or no answer is available
(NXDOMAIN).
For performance and efficiency reasons that answer is cached for a certain time
(the answer's time-to-live or TTL).
A second query for the same name will then be answered from the cache.
Unbound can also do DNSSEC validation.
To use a locally running Unbound for resolving put:
.. code-block:: text
nameserver 127.0.0.1
into *resolv.conf(5)*.
If authoritative DNS is needed as well using :external+nsd:doc:`manpages/nsd`,
careful setup is required because authoritative nameservers and resolvers are
using the same port number (53).
The available options are:
.. option:: -h
Show the version number and commandline option help, and exit.
.. option:: -c <cfgfile>
Set the config file with settings for unbound to read instead of reading the
file at the default location, :file:`@ub_conf_file@`.
The syntax is described in :doc:`unbound.conf(5)</manpages/unbound.conf>`.
.. option:: -d
Debug flag: do not fork into the background, but stay attached to the
console.
This flag will also delay writing to the log file until the thread-spawn
time, so that most config and setup errors appear on stderr.
If given twice or more, logging does not switch to the log file or to
syslog, but the log messages are printed to stderr all the time.
.. option:: -p
Don't use a pidfile.
This argument should only be used by supervision systems which can ensure
that only one instance of Unbound will run concurrently.
.. option:: -v
Increase verbosity.
If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.. option:: -V
Show the version number and build options, and exit.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound-checkconf(8)</manpages/unbound-checkconf>`,
:external+nsd:doc:`manpages/nsd`.
+1 -1
View File
@@ -116,7 +116,7 @@ struct addredge {
addrlen_t len;
/** child node this edge is connected to */
struct addrnode *node;
/** Parent node this ege is connected to */
/** Parent node this edge is connected to */
struct addrnode *parent_node;
/** Index of this edge in parent_node */
int parent_index;
+40 -11
View File
@@ -154,6 +154,21 @@ int ecs_whitelist_check(struct query_info* qinfo,
return 1;
sn_env = (struct subnet_env*)qstate->env->modinfo[id];
if(sq->is_subquery_nonsubnet) {
if(sq->is_subquery_scopezero) {
/* Check if the result can be stored in the global cache,
* this is okay if the address and name are not configured
* as subnet address and subnet zone. */
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;
}
}
return 1;
}
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)
@@ -234,13 +249,13 @@ subnetmod_init(struct module_env *env, int id)
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
msg_cache_sizefunc, query_info_compare, query_entry_delete,
subnet_data_delete, NULL);
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
if(!sn_env->subnet_msg_cache) {
log_err("subnetcache: could not create cache");
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
/* whitelist for edns subnet capable servers */
sn_env->whitelist = ecs_whitelist_create();
if(!sn_env->whitelist ||
@@ -527,11 +542,12 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
/**
* Create sub request that looks up the query.
* @param qstate: query state
* @param id: module id.
* @param sq: subnet qstate
* @return false on failure.
*/
static int
generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate* sq)
{
struct module_qstate* subq = NULL;
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
@@ -551,16 +567,28 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
&subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, qstate->client_info,
qflags, prime, valrec, &subq)) {
return 0;
}
if(subq) {
/* It is possible to access the subquery module state. */
struct subnet_qstate* subsq;
if(!subnet_new_qstate(subq, id)) {
verbose(VERB_ALGO, "Could not allocate new subnet qstate");
return 0;
}
subsq = (struct subnet_qstate*)subq->minfo[id];
subsq->is_subquery_nonsubnet = 1;
/* 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.
* Store that the client asked for that, if so. */
if(sq->ecs_client_in.subnet_source_mask == 0 &&
edns_opt_list_find(qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode)) {
subq->no_cache_store = 1;
subsq->is_subquery_scopezero = 1;
}
}
return 1;
@@ -569,17 +597,18 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
/**
* Perform the query without subnet
* @param qstate: query state
* @param id: module id.
* @param sq: subnet qstate
* @return module state
*/
static enum module_ext_state
generate_lookup_without_subnet(struct module_qstate *qstate,
generate_lookup_without_subnet(struct module_qstate *qstate, int id,
struct subnet_qstate* sq)
{
verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet");
if(!generate_sub_request(qstate, sq)) {
if(!generate_sub_request(qstate, id, sq)) {
verbose(VERB_ALGO, "Could not generate sub query");
qstate->return_rcode = LDNS_RCODE_FORMERR;
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
qstate->return_msg = NULL;
return module_finished;
}
@@ -622,7 +651,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
* is still useful to put it in the edns subnet cache for
* when a client explicitly asks for subnet specific answer. */
verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
return generate_lookup_without_subnet(qstate, sq);
return generate_lookup_without_subnet(qstate, id, sq);
}
/* Purposefully there was no sent subnet, and there is consequently
@@ -654,7 +683,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
sq->subnet_sent_no_subnet = 0;
return generate_lookup_without_subnet(qstate, sq);
return generate_lookup_without_subnet(qstate, id, sq);
}
lock_rw_wrlock(&sne->biglock);
@@ -945,7 +974,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
/* aggregated this deaggregated state */
qstate->ext_state[id] =
generate_lookup_without_subnet(
qstate, sq);
qstate, id, sq);
return;
}
verbose(VERB_ALGO, "subnetcache: pass to next module");
@@ -993,7 +1022,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
qstate->env->cfg->client_subnet_opcode)) {
/* client asked for resolution without edns subnet */
qstate->ext_state[id] = generate_lookup_without_subnet(
qstate, sq);
qstate, id, sq);
return;
}
+4
View File
@@ -106,6 +106,10 @@ struct subnet_qstate {
int wait_subquery;
/** The subquery waited for is done. */
int wait_subquery_done;
/** The subnet state is a subquery state for nonsubnet lookup. */
int is_subquery_nonsubnet;
/** This is a subquery, and it is made due to a scope zero request. */
int is_subquery_scopezero;
};
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
+1 -1
View File
@@ -163,7 +163,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
if(!(*qstate->env->attach_sub)(qstate, &ask, NULL,
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
log_err("Could not generate request: out of memory");
return 0;
+10
View File
@@ -79,6 +79,16 @@ struct delegpt {
* Also true if the delegationpoint was created from a delegation
* message and thus contains the parent-side-info already. */
uint8_t has_parent_side_NS;
/** if true, the delegation point has reached last resort processing
* and the parent side information has been possibly added to the
* delegation point.
* For now this signals that further target lookups will ignore
* the configured target-fetch-policy and only resolve on
* demand to try and avoid triggering limits at this stage (.i.e, it
* is very likely that the A/AAAA queries for the newly added name
* servers will not yield new IP addresses and trigger NXNS
* countermeasures. */
uint8_t fallback_to_parent_side_NS;
/** for assertions on type of delegpt */
uint8_t dp_type_mlc;
/** use SSL for upstream query */
+26 -11
View File
@@ -139,6 +139,17 @@ forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
return 1;
}
static struct iter_forward_zone*
fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
{
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = c;
key.name = nm;
key.namelabs = dname_count_size_labels(nm, &key.namelen);
return (struct iter_forward_zone*)rbtree_search(fwd->tree, &key);
}
/** insert new info into forward structure given dp */
static int
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
@@ -217,6 +228,11 @@ read_fwds_host(struct config_stub* s, struct delegpt* dp)
s->name, p->str);
return 0;
}
if(dname_subdomain_c(dname, dp->name)) {
log_warn("forward-host '%s' may have a circular "
"dependency on forward-zone '%s'",
p->str, s->name);
}
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(tls_auth_name)
log_err("no name verification functionality in "
@@ -321,6 +337,11 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
log_err("cannot parse stub name '%s'", s->name);
return 0;
}
if(fwd_zone_find(fwd, LDNS_RR_CLASS_IN, dname) != NULL) {
/* Already a forward zone there. */
free(dname);
continue;
}
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
free(dname);
log_err("out of memory");
@@ -345,6 +366,11 @@ make_auth_holes(struct iter_forwards* fwd, struct config_file* cfg)
log_err("cannot parse auth name '%s'", a->name);
return 0;
}
if(fwd_zone_find(fwd, LDNS_RR_CLASS_IN, dname) != NULL) {
/* Already a forward zone there. */
free(dname);
continue;
}
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
free(dname);
log_err("out of memory");
@@ -537,17 +563,6 @@ forwards_get_mem(struct iter_forwards* fwd)
return s;
}
static struct iter_forward_zone*
fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
{
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = c;
key.name = nm;
key.namelabs = dname_count_size_labels(nm, &key.namelen);
return (struct iter_forward_zone*)rbtree_search(fwd->tree, &key);
}
int
forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp,
int nolock)
+5
View File
@@ -231,6 +231,11 @@ read_stubs_host(struct config_stub* s, struct delegpt* dp)
s->name, p->str);
return 0;
}
if(dname_subdomain_c(dname, dp->name)) {
log_warn("stub-host '%s' may have a circular "
"dependency on stub-zone '%s'",
p->str, s->name);
}
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(tls_auth_name)
log_err("no name verification functionality in "
+16
View File
@@ -634,6 +634,22 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* If the NS set is a promiscuous NS set, scrub that
* to remove potential for poisonous contents that
* affects other names in the same zone. Remove
* promiscuous NS sets in positive answers, that
* thus have records in the answer section. Nodata
* and nxdomain promiscuous NS sets have been removed
* already. Since the NS rrset is scrubbed, its
* address records are also not marked to be allowed
* and are removed later. */
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR &&
msg->an_rrsets != 0 &&
env->cfg->iter_scrub_promiscuous) {
remove_rrset("normalize: removing promiscuous "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(nsset == NULL) {
nsset = rrset;
} else {
+28 -10
View File
@@ -829,7 +829,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
struct mesh_state* sub = NULL;
fptr_ok(fptr_whitelist_modenv_add_sub(
qstate->env->add_sub));
if(!(*qstate->env->add_sub)(qstate, &qinf,
if(!(*qstate->env->add_sub)(qstate, &qinf, NULL,
qflags, prime, valrec, &subq, &sub)){
return 0;
}
@@ -838,8 +838,8 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
/* attach subquery, lookup existing or make a new one */
fptr_ok(fptr_whitelist_modenv_attach_sub(
qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
valrec, &subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, NULL, qflags,
prime, valrec, &subq)) {
return 0;
}
}
@@ -2152,6 +2152,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->dp->fallback_to_parent_side_NS = 1;
if(qstate->env->cfg->harden_unverified_glue) {
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, PACKED_RRSET_UNVERIFIED_GLUE))
@@ -2180,6 +2181,10 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
a->lame, a->tls_auth_name, -1, NULL);
}
lock_rw_unlock(&qstate->env->hints->lock);
/* copy over some configuration since we update the
* delegation point in place */
iq->dp->tcp_upstream = dp->tcp_upstream;
iq->dp->ssl_upstream = dp->ssl_upstream;
}
iq->dp->has_parent_side_NS = 1;
} else if(!iq->dp->has_parent_side_NS) {
@@ -2768,7 +2773,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* if the mesh query list is full, then do not waste cpu and sockets to
* fetch promiscuous targets. They can be looked up when needed. */
if(can_do_promisc && !mesh_jostle_exceeded(qstate->env->mesh)) {
if(!iq->dp->fallback_to_parent_side_NS && can_do_promisc
&& !mesh_jostle_exceeded(qstate->env->mesh)) {
tf_policy = ie->target_fetch_policy[iq->depth];
}
@@ -3247,13 +3253,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
if(type == RESPONSE_TYPE_CNAME &&
iq->qchase.qtype == LDNS_RR_TYPE_CNAME &&
(iq->qchase.qtype == LDNS_RR_TYPE_CNAME ||
iq->qchase.qtype == LDNS_RR_TYPE_ANY) &&
iq->minimisation_state == MINIMISE_STATE &&
query_dname_compare(iq->qchase.qname, iq->qinfo_out.qname) == 0) {
/* The minimised query for full QTYPE and hidden QTYPE can be
* classified as CNAME response type, even when the original
* QTYPE=CNAME. This should be treated as answer response type.
*/
/* For QTYPE=ANY, it is also considered the response, that
* is what the classifier would say, if it saw qtype ANY,
* and this same response was returned for that. The response
* can already be treated as such an answer, without having
* to send another query with a new qtype. */
type = RESPONSE_TYPE_ANSWER;
}
@@ -3510,6 +3522,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_target_queries = 0;
return processDSNSFind(qstate, iq, id);
}
if(iq->minimisation_state == MINIMISE_STATE &&
query_dname_compare(iq->qchase.qname,
iq->qinfo_out.qname) != 0) {
verbose(VERB_ALGO, "continue query minimisation, "
"downwards, after CNAME response for "
"intermediate label");
/* continue query minimisation, downwards */
return next_state(iq, QUERYTARGETS_STATE);
}
/* Process the CNAME response. */
if(!handle_cname_response(qstate, iq, iq->response,
&sname, &snamelen)) {
@@ -3572,10 +3593,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->auth_zone_response = 0;
iq->sent_count = 0;
iq->dp_target_count = 0;
if(iq->minimisation_state != MINIMISE_STATE)
/* Only count as query restart when it is not an extra
* query as result of qname minimisation. */
iq->query_restart_count++;
iq->query_restart_count++;
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
@@ -4147,7 +4165,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
/* store message with the finished prepended items,
* but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
if(!qstate->no_cache_store && (qstate->query_flags&BIT_RD)) {
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
+4 -1
View File
@@ -52,6 +52,7 @@
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "util/edns.h"
#include "util/tsig.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
@@ -81,13 +82,15 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL;
listen_setup_locks();
log_edns_known_options(VERB_ALGO, ctx->env);
if(!tsig_key_table_apply_cfg(ctx->env->tsig_key_table, cfg))
return UB_INITFAIL;
ctx->local_zones = local_zones_create();
if(!ctx->local_zones)
return UB_NOMEM;
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
ctx->env, &ctx->mods))
ctx->env, &ctx->mods, ctx->env->tsig_key_table))
return UB_INITFAIL;
if(!(ctx->env->fwds = forwards_create()) ||
!forwards_apply_cfg(ctx->env->fwds, cfg))
+14
View File
@@ -59,6 +59,7 @@
#include "util/tube.h"
#include "util/ub_event.h"
#include "util/edns.h"
#include "util/tsig.h"
#include "services/modstack.h"
#include "services/localzone.h"
#include "services/cache/infra.h"
@@ -168,6 +169,18 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
ctx->env->tsig_key_table = tsig_key_table_create();
if(!ctx->env->tsig_key_table) {
auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
config_delete(ctx->env->cfg);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL;
@@ -388,6 +401,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
tsig_key_table_delete(ctx->env->tsig_key_table);
forwards_delete(ctx->env->fwds);
hints_delete(ctx->env->hints);
auth_zones_delete(ctx->env->auth_zones);
+12 -7
View File
@@ -229,7 +229,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
cfg->tcp_auth_query_timeout);
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
(const char**)cfg->dist_tsig,
cfg->num_dist);
w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
@@ -630,8 +632,9 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
free(qinfo.qname);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
if(ctx->env->auth_zones && auth_zones_downstream_answer(
ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL, 0);
@@ -709,8 +712,9 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
w->back->udp_buff, sec_status_insecure, NULL, 0);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
if(ctx->env->auth_zones && auth_zones_downstream_answer(
ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
@@ -847,8 +851,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
free(qinfo.qname);
return;
}
if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
if(w->ctx->env->auth_zones && auth_zones_downstream_answer(
w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
+1 -1
View File
@@ -853,7 +853,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
%{
//printf("resolve_start(%lX)\n",(long unsigned int)arg1);
Py_BEGIN_ALLOW_THREADS
$function
$action
Py_END_ALLOW_THREADS
//printf("resolve_stop()\n");
%}
+2
View File
@@ -772,6 +772,8 @@ struct ub_server_stats {
long long ans_bogus;
/** rrsets marked bogus by validator */
long long rrset_bogus;
/** number of signature validation operations performed by validator */
long long val_ops;
/** number of queries that have been ratelimited by domain recursion. */
long long queries_ratelimited;
/** unwanted traffic received on server-facing ports */
Regular → Executable
+602 -315
View File
File diff suppressed because it is too large Load Diff
+10 -3
View File
@@ -59,7 +59,7 @@ Generate a distribution tar file for unbound.
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
-wdir directory Build openssl and expat in a persistent directory for
windows dist. If builds are already in that directory
they are used right away. Useful when debuggin windows
they are used right away. Useful when debugging windows
builds.
-w32 32bit windows compile.
-w ... Build windows binary dist. last args passed to configure.
@@ -440,6 +440,7 @@ if [ "$DOWIN" = "yes" ]; then
autoheader -f || error_cleanup "Autoheader failed."
rm -r autom4te* || echo "ignored"
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
fi
if test "`uname`" = "Linux"; then
@@ -539,6 +540,12 @@ if [ "$DOWIN" = "yes" ]; then
if test -f "$sspdll"; then
cp "$sspdll" libunbound/.
fi
if test "$W64" = "no"; then
# This could be solved with -static -static-libgcc -static-libstdc++.
# The dependency on c++ is probably due to libexpat. But the copy
# of the dll should work too. It may be needed for the libunbound.dll.
cp /usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_dw2-1.dll libunbound/.
fi
# zipfile
zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound
info "Testing $file"
@@ -615,6 +622,7 @@ autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
info "Building lexer and parser."
echo "#include \"config.h\"" > util/configlexer.c || error_cleanup "Failed to create configlexer"
@@ -660,6 +668,7 @@ if [ "$RECONFIGURE" = "yes" ]; then
autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
rm -f configure~ || echo "ignore absence of configure~ file."
fi
replace_all doc/README
@@ -691,7 +700,5 @@ cleanup
storehash unbound-$version.tar.gz
echo "create unbound-$version.tar.gz.asc with:"
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.tar.gz"
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.zip"
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound_setup_$version.exe"
info "Unbound distribution created successfully."
+17 -15
View File
@@ -38,12 +38,14 @@ import os
def dataHex(data, prefix=""):
"""Converts binary string data to display representation form"""
res = ""
for i in range(0, (len(data)+15)/16):
for i in range(0, int((len(data)+15)/16)):
res += "%s0x%02X | " % (prefix, i*16)
d = map(lambda x:ord(x), data[i*16:i*16+17])
d = map(lambda x:x, data[i*16:i*16+17])
count=0
for ch in d:
res += "%02X " % ch
for i in range(0,17-len(d)):
count+=1
for i in range(0,17-count):
res += " "
res += "| "
for ch in d:
@@ -60,31 +62,31 @@ def logDnsMsg(qstate):
r = qstate.return_msg.rep
q = qstate.return_msg.qinfo
print "-"*100
print("-"*100)
print("Query: %s, type: %s (%d), class: %s (%d) " % (
qstate.qinfo.qname_str, qstate.qinfo.qtype_str, qstate.qinfo.qtype,
qstate.qinfo.qclass_str, qstate.qinfo.qclass))
print "-"*100
print "Return reply :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (r.flags, r.qdcount, r.security, r.ttl)
print " qinfo :: qname: %s %s, qtype: %s, qclass: %s" % (str(q.qname_list), q.qname_str, q.qtype_str, q.qclass_str)
print("-"*100)
print("Return reply :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (r.flags, r.qdcount, r.security, r.ttl))
print(" qinfo :: qname: %s %s, qtype: %s, qclass: %s" % (str(q.qname_list), q.qname_str, q.qtype_str, q.qclass_str))
if (r):
print "Reply:"
print("Reply:")
for i in range(0, r.rrset_count):
rr = r.rrsets[i]
rk = rr.rk
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
print(i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,)
print("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
d = rr.entry.data
for j in range(0,d.count+d.rrsig_count):
print " ",j,":","TTL=",d.rr_ttl[j],
if (j >= d.count): print "rrsig",
print
print dataHex(d.rr_data[j]," ")
print(" ",j,":","TTL=",d.rr_ttl[j],)
if (j >= d.count): print("rrsig",)
print()
print(dataHex(d.rr_data[j]," "))
print "-"*100
print("-"*100)
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
+2 -2
View File
@@ -732,8 +732,8 @@ struct module_env {
char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
struct query_info* qinfo, struct respip_client_info* cinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
void (*kill_sub)(struct module_qstate* newq);
int (*detect_cycle)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t flags, int prime,
+15 -32
View File
@@ -454,7 +454,7 @@ int pythonmod_init(struct module_env* env, int id)
if(PyDict_SetItemString(pe->data, "script", fname) < 0) {
log_err("pythonmod: could not add item to dictionary");
Py_XDECREF(fname);
goto python_init_fail;
goto fail_close_file;
}
Py_XDECREF(fname);
Py_XINCREF(pe->data); /* reference will be stolen below */
@@ -462,7 +462,7 @@ int pythonmod_init(struct module_env* env, int id)
log_err("pythonmod: could not add mod_env object");
Py_XDECREF(pe->data); /* 2 times, here and on python_init_fail; */
/* on failure the reference is not stolen */
goto python_init_fail;
goto fail_close_file;
}
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
@@ -493,31 +493,15 @@ int pythonmod_init(struct module_env* env, int id)
flen = (size_t)ftell(script_py);
fstr = malloc(flen+1);
if(!fstr) {
log_err("malloc failure to print parse error");
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
goto python_init_fail;
log_err("malloc failure to print parse error");
goto fail_close_file;
}
fseek(script_py, 0, SEEK_SET);
if(fread(fstr, flen, 1, script_py) < 1) {
log_err("file read failed to print parse error: %s: %s",
log_err("file read failed to print parse error: %s: %s",
pe->fname, strerror(errno));
free(fstr);
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
goto python_init_fail;
free(fstr);
goto fail_close_file;
}
fstr[flen] = 0;
/* we compile the string, but do not run it, to stop side-effects */
@@ -527,21 +511,13 @@ int pythonmod_init(struct module_env* env, int id)
#endif
log_py_err();
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
/* no cleanup needed for python before 3.9 */
#else
/* cleanup for python 3.9 and newer */
free(fstr);
#endif
goto python_init_fail;
goto fail_close_file;
}
/* close the file */
@@ -602,6 +578,13 @@ int pythonmod_init(struct module_env* env, int id)
PyGILState_Release(gil);
return 1;
fail_close_file:
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
python_init_fail:
Py_XDECREF(pe->module);
Py_XDECREF(pe->dict);
+4 -2
View File
@@ -1074,7 +1074,8 @@ generate_cname_request(struct module_qstate* qstate,
subqi.qtype = qstate->qinfo.qtype;
subqi.qclass = qstate->qinfo.qclass;
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq);
return (*qstate->env->attach_sub)(qstate, &subqi,
qstate->client_info, BIT_RD, 0, 0, &subq);
}
void
@@ -1233,7 +1234,8 @@ respip_inform_super(struct module_qstate* qstate, int id,
struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id];
struct reply_info* new_rep = NULL;
rq->state = RESPIP_SUBQUERY_FINISHED;
if(rq)
rq->state = RESPIP_SUBQUERY_FINISHED;
/* respip subquery should have always been created with a valid reply
* in super. */
+1 -1
View File
@@ -276,7 +276,7 @@ void respip_inform_print(struct respip_action_info* respip_actinfo,
* @param addrlen: length of addr.
* @param net: netblock to lookup.
* @param create: create node if it does not exist when 1.
* @param ipstr: human redable ip string, for logging.
* @param ipstr: human readable ip string, for logging.
* @return newly created of found node, not holding lock.
*/
struct resp_addr*
+364 -85
View File
@@ -55,6 +55,7 @@
#include "util/log.h"
#include "util/module.h"
#include "util/random.h"
#include "util/tsig.h"
#include "services/cache/dns.h"
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
@@ -171,7 +172,7 @@ get_rrset_ttl(struct ub_packed_rrset_key* k)
/** Copy rrset into region from domain-datanode and packet rrset */
static struct ub_packed_rrset_key*
auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
struct auth_rrset* rrset, struct regional* region, time_t adjust)
struct auth_rrset* rrset, struct regional* region)
{
struct ub_packed_rrset_key key;
memset(&key, 0, sizeof(key));
@@ -182,7 +183,7 @@ auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
key.rk.type = htons(rrset->type);
key.rk.rrset_class = htons(z->dclass);
key.entry.hash = rrset_key_hash(&key.rk);
return packed_rrset_copy_region(&key, region, adjust);
return packed_rrset_copy_region(&key, region, 0);
}
/** fix up msg->rep TTL and prefetch ttl */
@@ -236,7 +237,7 @@ msg_add_rrset_an(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->an_numrrsets++;
@@ -260,7 +261,7 @@ msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->ns_numrrsets++;
@@ -283,7 +284,7 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
return 0;
/* copy it */
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
auth_packed_rrset_copy_region(z, node, rrset, region)))
return 0;
msg->rep->rrset_count++;
msg->rep->ar_numrrsets++;
@@ -2091,7 +2092,8 @@ auth_zones_setup_zones(struct auth_zones* az)
/** set config items and create zones */
static int
auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
struct tsig_key_table* tsig_key_table)
{
struct auth_zone* z;
struct auth_xfer* x = NULL;
@@ -2110,7 +2112,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
}
return 0;
}
if(c->masters || c->urls) {
if(c->masters || c->masters_tsig || c->urls) {
if(!(x=auth_zones_find_or_add_xfer(az, z))) {
lock_rw_unlock(&az->lock);
lock_rw_unlock(&z->lock);
@@ -2171,12 +2173,14 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
if(x) {
z->zone_is_slave = 1;
/* set options on xfer zone */
if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
if(!xfer_set_masters(&x->task_probe->masters, c, 0,
tsig_key_table)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
}
if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
if(!xfer_set_masters(&x->task_transfer->masters, c, 1,
tsig_key_table)) {
lock_basic_unlock(&x->lock);
lock_rw_unlock(&z->lock);
return 0;
@@ -2244,7 +2248,7 @@ az_delete_deleted_zones(struct auth_zones* az)
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, int* is_rpz, struct module_env* env,
struct module_stack* mods)
struct module_stack* mods, struct tsig_key_table* tsig_key_table)
{
struct config_auth* p;
az_setall_deleted(az);
@@ -2254,7 +2258,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
continue;
}
*is_rpz = (*is_rpz || p->isrpz);
if(!auth_zones_cfg(az, p)) {
if(!auth_zones_cfg(az, p, tsig_key_table)) {
log_err("cannot config auth zone %s", p->name);
return 0;
}
@@ -2312,6 +2316,7 @@ auth_free_masters(struct auth_master* list)
auth_free_master_addrs(list->list);
free(list->host);
free(list->file);
free(list->tsig_key_name);
free(list);
list = n;
}
@@ -2331,12 +2336,14 @@ auth_xfer_delete(struct auth_xfer* xfr)
auth_free_masters(xfr->task_probe->masters);
comm_point_delete(xfr->task_probe->cp);
comm_timer_delete(xfr->task_probe->timer);
tsig_delete(xfr->task_probe->tsig);
free(xfr->task_probe);
}
if(xfr->task_transfer) {
auth_free_masters(xfr->task_transfer->masters);
comm_point_delete(xfr->task_transfer->cp);
comm_timer_delete(xfr->task_transfer->timer);
tsig_delete(xfr->task_transfer->tsig);
if(xfr->task_transfer->chunks_first) {
auth_chunks_delete(xfr->task_transfer);
}
@@ -2413,14 +2420,12 @@ az_find_wildcard(struct auth_zone* z, struct query_info* qinfo,
if(!dname_subdomain_c(nm, z->name))
return NULL; /* out of zone */
while((node=az_find_wildcard_domain(z, nm, nmlen))==NULL) {
/* see if we can go up to find the wildcard */
if(nmlen == z->namelen)
return NULL; /* top of zone reached */
if(ce && nmlen == ce->namelen)
return NULL; /* ce reached */
if(dname_is_root(nm))
return NULL; /* cannot go up */
dname_remove_label(&nm, &nmlen);
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
}
return node;
}
@@ -2442,9 +2447,8 @@ az_find_candidate_ce(struct auth_zone* z, struct query_info* qinfo,
n = az_find_name(z, nm, nmlen);
/* delete labels and go up on name */
while(!n) {
if(dname_is_root(nm))
return NULL; /* cannot go up */
dname_remove_label(&nm, &nmlen);
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
n = az_find_name(z, nm, nmlen);
}
return n;
@@ -2456,8 +2460,7 @@ az_domain_go_up(struct auth_zone* z, struct auth_data* n)
{
uint8_t* nm = n->name;
size_t nmlen = n->namelen;
while(!dname_is_root(nm)) {
dname_remove_label(&nm, &nmlen);
while(dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) {
if((n=az_find_name(z, nm, nmlen)) != NULL)
return n;
}
@@ -2771,26 +2774,23 @@ az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname,
}
}
/** find NSEC record covering the query */
/** find NSEC record covering the query, with the given node in the zone */
static struct auth_rrset*
az_find_nsec_cover(struct auth_zone* z, struct auth_data** node)
{
uint8_t* nm = (*node)->name;
size_t nmlen = (*node)->namelen;
uint8_t* nm;
size_t nmlen;
struct auth_rrset* rrset;
log_assert(*node); /* we already have a node when calling this */
nm = (*node)->name;
nmlen = (*node)->namelen;
/* find the NSEC for the smallest-or-equal node */
/* if node == NULL, we did not find a smaller name. But the zone
* name is the smallest name and should have an NSEC. So there is
* no NSEC to return (for a properly signed zone) */
/* for empty nonterminals, the auth-data node should not exist,
* and thus we don't need to go rbtree_previous here to find
* a domain with an NSEC record */
/* but there could be glue, and if this is node, then it has no NSEC.
/* But there could be glue, and then it has no NSEC.
* Go up to find nonglue (previous) NSEC-holding nodes */
while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) {
if(dname_is_root(nm)) return NULL;
if(nmlen == z->namelen) return NULL;
dname_remove_label(&nm, &nmlen);
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
/* adjust *node for the nsec rrset to find in */
*node = az_find_name(z, nm, nmlen);
}
@@ -3018,12 +3018,9 @@ az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen,
struct auth_data* node;
while((node = az_nsec3_find_exact(z, *cenm, *cenmlen,
algo, iter, salt, saltlen)) == NULL) {
if(*cenmlen == z->namelen) {
/* next step up would take us out of the zone. fail */
return NULL;
}
if(!dname_remove_label_limit_len(cenm, cenmlen, z->namelen))
return NULL; /* can't go up */
*no_exact_ce = 1;
dname_remove_label(cenm, cenmlen);
}
return node;
}
@@ -3340,7 +3337,8 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
} else if(ce) {
uint8_t* wildup = wildcard->name;
size_t wilduplen= wildcard->namelen;
dname_remove_label(&wildup, &wilduplen);
if(!dname_remove_label_limit_len(&wildup, &wilduplen, z->namelen))
return 0; /* can't go up */
if(!az_add_nsec3_proof(z, region, msg, wildup,
wilduplen, msg->qinfo.qname,
msg->qinfo.qname_len, 0, insert_ce, 1, 0))
@@ -3399,7 +3397,7 @@ az_generate_answer_with_node(struct auth_zone* z, struct query_info* qinfo,
}
/** Generate answer without an existing-node that we can use.
* So it'll be a referral, DNAME or nxdomain */
* So it'll be a referral, DNAME, notype, wildcard or nxdomain */
static int
az_generate_answer_nonexistnode(struct auth_zone* z, struct query_info* qinfo,
struct regional* region, struct dns_msg* msg, struct auth_data* ce,
@@ -3565,14 +3563,17 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env,
sldns_buffer_read_u16_at(buf, 2), edns);
}
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp)
struct comm_reply* repinfo, struct sldns_buffer* buf,
struct regional* temp)
{
struct dns_msg* msg = NULL;
struct auth_zone* z;
int r;
int fallback = 0;
/* Copy the qinfo in case of cname aliasing from local-zone */
struct query_info zqinfo = *qinfo;
lock_rw_rdlock(&az->lock);
if(!az->have_downstream) {
@@ -3580,6 +3581,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
lock_rw_unlock(&az->lock);
return 0;
}
if(qinfo->qtype == LDNS_RR_TYPE_DS) {
uint8_t* delname = qinfo->qname;
size_t delnamelen = qinfo->qname_len;
@@ -3587,8 +3589,14 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
z = auth_zones_find_zone(az, delname, delnamelen,
qinfo->qclass);
} else {
z = auth_zones_find_zone(az, qinfo->qname, qinfo->qname_len,
qinfo->qclass);
if(zqinfo.local_alias && !local_alias_shallow_copy_qname(
zqinfo.local_alias, &zqinfo.qname,
&zqinfo.qname_len)) {
lock_rw_unlock(&az->lock);
return 0;
}
z = auth_zones_find_zone(az, zqinfo.qname, zqinfo.qname_len,
zqinfo.qclass);
}
if(!z) {
/* no zone above it */
@@ -3614,7 +3622,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
}
/* answer it from zone z */
r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
r = auth_zone_generate_answer(z, &zqinfo, temp, &msg, &fallback);
lock_rw_unlock(&z->lock);
if(!r && fallback) {
/* fallback to regular answering (recursive) */
@@ -3717,11 +3725,30 @@ addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
* addresses in the addr list) */
static int
addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
socklen_t addrlen, struct auth_master** fromhost)
socklen_t addrlen, struct auth_master** fromhost,
struct tsig_data* tsig)
{
struct sockaddr_storage a;
socklen_t alen = 0;
int net = 0;
if(master->tsig_key_name && master->tsig_key_name[0]) {
uint8_t keyname[LDNS_MAX_DOMAINLEN+1];
size_t keynamelen = sizeof(keyname);
if(!tsig) {
/* This needs a TSIG key, but no TSIG present. */
return 0;
}
if(sldns_str2wire_dname_buf(master->tsig_key_name, keyname,
&keynamelen) != 0) {
verbose(VERB_ALGO, "could not parse allow-notify-tsig '%s'",
master->tsig_key_name);
return 0;
}
if(query_dname_compare(keyname, tsig->key_name) != 0) {
/* The TSIG is a different key name, not matched. */
return 0;
}
}
if(addr_in_list(master->list, addr, addrlen)) {
*fromhost = master;
return 1;
@@ -3754,11 +3781,12 @@ addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
/** check access list for notifies */
static int
az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr,
socklen_t addrlen, struct auth_master** fromhost)
socklen_t addrlen, struct auth_master** fromhost,
struct tsig_data* tsig)
{
struct auth_master* p;
for(p=xfr->allow_notify_list; p; p=p->next) {
if(addr_matches_master(p, addr, addrlen, fromhost)) {
if(addr_matches_master(p, addr, addrlen, fromhost, tsig)) {
return 1;
}
}
@@ -3828,7 +3856,8 @@ xfr_process_notify(struct auth_xfer* xfr, struct module_env* env,
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
uint8_t* nm, size_t nmlen, uint16_t dclass,
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
uint32_t serial, int* refused)
uint32_t serial, int* refused, struct sldns_buffer* pkt,
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad)
{
struct auth_xfer* xfr;
struct auth_master* fromhost = NULL;
@@ -3843,9 +3872,20 @@ int auth_zones_notify(struct auth_zones* az, struct module_env* env,
}
lock_basic_lock(&xfr->lock);
lock_rw_unlock(&az->lock);
/* check tsig */
if(tsig_in_packet(pkt)) {
*tsig_rcode = tsig_parse_verify_query(env->tsig_key_table,
pkt, tsig, scratchpad, (uint64_t)*env->now);
if(*tsig_rcode != 0) {
/* The tsig failed to verify. */
lock_basic_unlock(&xfr->lock);
return 0;
}
}
/* check access list for notifies */
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) {
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost, *tsig)) {
lock_basic_unlock(&xfr->lock);
/* notify not allowed, refuse the notify */
*refused = 1;
@@ -3977,9 +4017,20 @@ auth_master_copy(struct auth_master* o)
return NULL;
}
}
if(m->tsig_key_name) {
m->tsig_key_name = strdup(m->tsig_key_name);
if(!m->tsig_key_name) {
free(m->file);
free(m->host);
free(m);
log_err("malloc failure");
return NULL;
}
}
if(m->list) {
m->list = auth_addr_list_copy(m->list);
if(!m->list) {
free(m->tsig_key_name);
free(m->file);
free(m->host);
free(m);
@@ -4239,6 +4290,37 @@ xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
sldns_buffer_write_u16_at(buf, 0, id);
}
/** sign a query for xfr. */
static int
xfr_sign_query(struct tsig_data** tsig, sldns_buffer* pkt,
struct module_env* env, char* tsig_key_name)
{
size_t pos;
if(*tsig) {
tsig_delete(*tsig);
*tsig = NULL;
}
*tsig = tsig_create_fromstr(env->tsig_key_table, tsig_key_name);
if(!*tsig) {
log_err("tsig key '%s' not found or out of memory",
tsig_key_name);
return 0;
}
/* Position the buffer after the packet contents. */
pos = sldns_buffer_limit(pkt);
sldns_buffer_clear(pkt);
sldns_buffer_set_position(pkt, pos);
if(!tsig_sign_query(*tsig, pkt, env->tsig_key_table,
(uint64_t)*env->now)) {
sldns_buffer_flip(pkt);
log_err("tsig key '%s': could not sign query", tsig_key_name);
return 0;
}
sldns_buffer_flip(pkt);
return 1;
}
/** create IXFR/AXFR packet for xfr */
static void
xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
@@ -4297,7 +4379,7 @@ xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
/** check if returned packet is OK */
static int
check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
uint32_t* serial)
uint32_t* serial, struct module_env* env)
{
/* parse to see if packet worked, valid reply */
@@ -4371,6 +4453,20 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
return 0;
*serial = sldns_buffer_read_u32(pkt);
}
if(xfr->task_probe->tsig) {
/* There could be authority or additional RRs in the reply for the
* SOA query, if so skip them by tsig_find_rr. */
if(!tsig_find_rr(pkt)) {
verbose(VERB_ALGO, "TSIG expected, but not found in reply");
return 0;
}
if(!tsig_parse_verify_reply(xfr->task_probe->tsig, pkt,
env->tsig_key_table, (uint64_t)*env->now)) {
verbose(VERB_ALGO, "valid TSIG expected in SOA probe reply, but it was not valid");
return 0;
}
}
return 1;
}
@@ -4555,6 +4651,23 @@ http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
return 0;
}
/** remove newlines from collated line */
static void
chunkline_newline_removal(sldns_buffer* buf)
{
size_t i, end=sldns_buffer_limit(buf);
for(i=0; i<end; i++) {
char c = (char)sldns_buffer_read_u8_at(buf, i);
if(c == '\n' && i==end-1) {
sldns_buffer_write_u8_at(buf, i, 0);
sldns_buffer_set_limit(buf, end-1);
return;
}
if(c == '\n')
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
}
}
/** find noncomment RR line in chunks, collates lines if ( ) format */
static int
chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
@@ -4562,6 +4675,7 @@ chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
{
int ret;
while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
chunkline_newline_removal(buf);
if(chunkline_is_comment_line_or_empty(buf)) {
/* a comment, go to next line */
continue;
@@ -4637,23 +4751,6 @@ chunklist_sum(struct auth_chunk* list)
return s;
}
/** remove newlines from collated line */
static void
chunkline_newline_removal(sldns_buffer* buf)
{
size_t i, end=sldns_buffer_limit(buf);
for(i=0; i<end; i++) {
char c = (char)sldns_buffer_read_u8_at(buf, i);
if(c == '\n' && i==end-1) {
sldns_buffer_write_u8_at(buf, i, 0);
sldns_buffer_set_limit(buf, end-1);
return;
}
if(c == '\n')
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
}
}
/** for http download, parse and add RR to zone */
static int
http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z,
@@ -5023,6 +5120,7 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
xfr->soa_zone_acquired = 0;
/* insert all RRs in to the zone */
/* insert the SOA only once, skip the last one */
@@ -5124,6 +5222,7 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
xfr->soa_zone_acquired = 0;
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
@@ -5334,6 +5433,8 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
" (or malformed RR)", xfr->task_transfer->master->host);
return 0;
}
z->soa_zone_acquired = *env->now;
xfr->soa_zone_acquired = *env->now;
/* release xfr lock while verifying zonemd because it may have
* to spawn lookups in the state machines */
@@ -5373,10 +5474,18 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
lock_rw_unlock(&z->lock);
if(verbosity >= VERB_QUERY && xfr->have_zone) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[LDNS_MAX_DOMAINLEN], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_transfer->tsig &&
xfr->task_transfer->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
(unsigned)xfr->serial);
verbose(VERB_QUERY, "auth zone %s updated%s%s to serial %u",
zname, tsigtxt, tsigkey, (unsigned)xfr->serial);
}
/* see if we need to write to a zonefile */
xfr_write_after_update(xfr, env);
@@ -5393,6 +5502,9 @@ xfr_transfer_disown(struct auth_xfer* xfr)
/* remove the commpoint */
comm_point_delete(xfr->task_transfer->cp);
xfr->task_transfer->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_transfer->tsig);
xfr->task_transfer->tsig = NULL;
/* we don't own this item anymore */
xfr->task_transfer->worker = NULL;
xfr->task_transfer->env = NULL;
@@ -5481,6 +5593,10 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
int timeout;
if(!master) return 0;
if(master->allow_notify) return 0; /* only for notify */
if(xfr->task_transfer->tsig) {
tsig_delete(xfr->task_transfer->tsig);
xfr->task_transfer->tsig = NULL;
}
/* get master addr */
if(xfr->task_transfer->scan_addr) {
@@ -5555,6 +5671,17 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
xfr->task_transfer->id = GET_RANDOM_ID(env->rnd);
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
xfr->task_transfer->id, master);
if(master->tsig_key_name) {
if(!xfr_sign_query(&xfr->task_transfer->tsig,
env->scratch_buffer, env, master->tsig_key_name)) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to TSIG sign xfr "
"for %s to %s", zname, as);
return 0;
}
}
/* connect on fd */
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
@@ -5571,11 +5698,20 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
}
comm_timer_set(xfr->task_transfer->timer, &t);
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_transfer->tsig &&
xfr->task_transfer->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch%s%s from %s started",
zname, (xfr->task_transfer->on_ixfr?"IXFR":"AXFR"),
tsigtxt, tsigkey, as);
}
return 1;
}
@@ -5760,9 +5896,10 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
*/
static int
check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
int* gonextonfail, int* transferdone)
struct module_env* env, int* gonextonfail, int* transferdone)
{
uint8_t* wire = sldns_buffer_begin(pkt);
size_t initial_rr_scan_num = xfr->task_transfer->rr_scan_num;
int i;
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
verbose(VERB_ALGO, "xfr to %s failed, packet too small",
@@ -6046,6 +6183,28 @@ check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
sldns_buffer_skip(pkt, (ssize_t)rdlen);
}
/* check tsig */
if(xfr->task_transfer->tsig) {
sldns_buffer_rewind(pkt);
if(!tsig_find_rr(pkt)) {
/* Check TSIG reply on first packet. */
if(initial_rr_scan_num == 0) {
verbose(VERB_ALGO, "TSIG expected, but not found in reply for xfr to %s",
xfr->task_transfer->master->host);
return 0;
}
/* No TSIG could be for sign every NTH packet. */
sldns_buffer_set_position(pkt, sldns_buffer_limit(pkt));
}
if(!tsig_parse_verify_reply_xfr(xfr->task_transfer->tsig,
pkt, env->tsig_key_table, (uint64_t)*env->now,
*transferdone)) {
verbose(VERB_ALGO, "valid TSIG expected in xfr reply to %s, but it was not valid",
xfr->task_transfer->master->host);
return 0;
}
}
return 1;
}
@@ -6222,7 +6381,8 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
/* handle returned packet */
/* if it fails, cleanup and end this transfer */
/* if it needs to fallback from IXFR to AXFR, do that */
if(!check_xfer_packet(c->buffer, xfr, &gonextonfail, &transferdone)) {
if(!check_xfer_packet(c->buffer, xfr, env, &gonextonfail,
&transferdone)) {
goto failed;
}
/* if it is good, link it into the list of data */
@@ -6348,6 +6508,9 @@ xfr_probe_disown(struct auth_xfer* xfr)
/* remove the commpoint */
comm_point_delete(xfr->task_probe->cp);
xfr->task_probe->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
/* we don't own this item anymore */
xfr->task_probe->worker = NULL;
xfr->task_probe->env = NULL;
@@ -6368,6 +6531,10 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
if(master->allow_notify) return 0; /* only for notify */
if(master->http) return 0; /* only masters get SOA UDP probe,
not urls, if those are in this list */
if(xfr->task_probe->tsig) {
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
}
/* get master addr */
if(xfr->task_probe->scan_addr) {
@@ -6405,6 +6572,17 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
xfr->task_probe->id = GET_RANDOM_ID(env->rnd);
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
xfr->task_probe->id);
if(master->tsig_key_name) {
if(!xfr_sign_query(&xfr->task_probe->tsig, env->scratch_buffer,
env, master->tsig_key_name)) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to TSIG sign soa probe "
"for %s to %s", zname, as);
return 0;
}
}
/* we need to remove the cp if we have a different ip4/ip6 type now */
if(xfr->task_probe->cp &&
((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
@@ -6448,11 +6626,19 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
return 0;
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_probe->tsig &&
xfr->task_probe->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
dname_str(xfr->task_probe->tsig->key_name, tsigkey);
}
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
as);
verbose(VERB_ALGO, "auth zone %s soa probe%s%s sent to %s",
zname, tsigtxt, tsigkey, as);
}
xfr->task_probe->timeout = timeout;
#ifndef S_SPLINT_S
@@ -6524,13 +6710,24 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
if(err == NETEVENT_NOERROR) {
uint32_t serial = 0;
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
&serial)) {
&serial, env)) {
/* successful lookup */
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN], tsigtxt[16],
tsigkey[LDNS_MAX_DOMAINLEN];
tsigkey[0]=0;
tsigtxt[0]=0;
if(xfr->task_probe->tsig &&
xfr->task_probe->tsig->key_name) {
snprintf(tsigtxt, sizeof(tsigtxt),
" with TSIG ");
dname_str(xfr->task_probe->tsig->
key_name, tsigkey);
}
dname_str(xfr->name, buf);
verbose(VERB_ALGO, "auth zone %s: soa probe "
"serial is %u", buf, (unsigned)serial);
verbose(VERB_ALGO, "auth zone %s: soa probe"
"%s%s serial is %u", buf, tsigtxt,
tsigkey, (unsigned)serial);
}
/* see if this serial indicates that the zone has
* to be updated */
@@ -6583,6 +6780,9 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
/* delete commpoint so a new one is created, with a fresh port nr */
comm_point_delete(xfr->task_probe->cp);
xfr->task_probe->cp = NULL;
/* remove the tsig data */
tsig_delete(xfr->task_probe->tsig);
xfr->task_probe->tsig = NULL;
/* if the result was not a successful probe, we need
* to send the next one */
@@ -7003,13 +7203,23 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
comm_timer_set(xfr->task_nextprobe->timer, &tv);
}
void auth_zone_pickup_initial_zone(struct auth_zone* z, struct module_env* env)
{
/* Set the time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired. */
z->soa_zone_acquired = *env->now;
}
void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env)
{
/* set lease_time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired */
if(x->have_zone)
if(x->have_zone) {
x->lease_time = *env->now;
x->soa_zone_acquired = *env->now;
}
if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
xfr_set_timeout(x, env, 0, 1);
}
@@ -7020,7 +7230,13 @@ void
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
{
struct auth_xfer* x;
struct auth_zone* z;
lock_rw_wrlock(&az->lock);
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
lock_rw_wrlock(&z->lock);
auth_zone_pickup_initial_zone(z, env);
lock_rw_unlock(&z->lock);
}
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&x->lock);
auth_xfer_pickup_initial_zone(x, env);
@@ -7105,6 +7321,7 @@ auth_xfer_new(struct auth_zone* z)
lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial));
lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired));
lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone));
lock_protect(&xfr->lock, &xfr->soa_zone_acquired, sizeof(xfr->soa_zone_acquired));
lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial));
lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry));
lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh));
@@ -7271,12 +7488,34 @@ parse_url(char* url, char** host, char** file, int* port, int* ssl)
return 1;
}
/** Check the tsig key exists */
static int
check_tsig_key_exists(struct tsig_key_table* tsig_key_table,
const char* optname, char* str, char* str2)
{
struct tsig_key* key;
if(!tsig_key_table)
return 1;
lock_rw_rdlock(&tsig_key_table->lock);
key = tsig_key_table_search_fromstr(tsig_key_table, str2);
lock_rw_unlock(&tsig_key_table->lock);
if(!key) {
log_err("could not find tsig-key for %s: %s %s",
optname, str, str2);
return 0;
}
return 1;
}
int
xfer_set_masters(struct auth_master** list, struct config_auth* c,
int with_http)
int with_http, struct tsig_key_table* tsig_key_table)
{
struct auth_master* m;
struct config_strlist* p;
struct config_str2list* p2;
/* list points to the first, or next pointer for the new element */
while(*list) {
list = &( (*list)->next );
@@ -7299,6 +7538,24 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
return 0;
}
}
for(p2 = c->masters_tsig; p2; p2 = p2->next) {
m = auth_master_new(&list);
if(!m) return 0;
m->ixfr = 1; /* this flag is not configurable */
m->host = strdup(p2->str);
if(!m->host) {
log_err("malloc failure");
return 0;
}
if(!check_tsig_key_exists(tsig_key_table, "primary-tsig",
p2->str, p2->str2))
return 0;
m->tsig_key_name = strdup(p2->str2);
if(!m->tsig_key_name) {
log_err("malloc failure");
return 0;
}
}
for(p = c->allow_notify; p; p = p->next) {
m = auth_master_new(&list);
if(!m) return 0;
@@ -7309,6 +7566,24 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
return 0;
}
}
for(p2 = c->allow_notify_tsig; p2; p2 = p2->next) {
m = auth_master_new(&list);
if(!m) return 0;
m->allow_notify = 1;
m->host = strdup(p2->str);
if(!m->host) {
log_err("malloc failure");
return 0;
}
if(!check_tsig_key_exists(tsig_key_table, "allow-notify-tsig",
p2->str, p2->str2))
return 0;
m->tsig_key_name = strdup(p2->str2);
if(!m->tsig_key_name) {
log_err("malloc failure");
return 0;
}
}
return 1;
}
@@ -8644,6 +8919,8 @@ auth_primaries_get_mem(struct auth_master* list)
m += strlen(n->host)+1;
if(n->file)
m += strlen(n->file)+1;
if(n->tsig_key_name)
m += strlen(n->tsig_key_name)+1;
}
return m;
}
@@ -8673,12 +8950,14 @@ auth_xfer_get_mem(struct auth_xfer* xfr)
m += auth_primaries_get_mem(xfr->task_probe->masters);
m += comm_point_get_mem(xfr->task_probe->cp);
m += comm_timer_get_mem(xfr->task_probe->timer);
m += tsig_get_mem(xfr->task_probe->tsig);
/* auth_transfer */
m += auth_chunks_get_mem(xfr->task_transfer->chunks_first);
m += auth_primaries_get_mem(xfr->task_transfer->masters);
m += comm_point_get_mem(xfr->task_transfer->cp);
m += comm_timer_get_mem(xfr->task_transfer->timer);
m += tsig_get_mem(xfr->task_transfer->tsig);
/* allow_notify_list */
m += auth_primaries_get_mem(xfr->allow_notify_list);
+36 -5
View File
@@ -55,6 +55,8 @@ struct query_info;
struct dns_msg;
struct edns_data;
struct module_env;
struct tsig_data;
struct tsig_key_table;
struct worker;
struct comm_point;
struct comm_timer;
@@ -118,6 +120,8 @@ struct auth_zone {
char* zonefile;
/** fallback to the internet on failure or ttl-expiry of auth zone */
int fallback_enabled;
/** the time when zone was transferred from upstream */
time_t soa_zone_acquired;
/** the zone has expired (enabled by the xfer worker), fallback
* happens if that option is enabled. */
int zone_expired;
@@ -261,6 +265,8 @@ struct auth_xfer {
int zone_expired;
/** do we have a zone (if 0, no zone data at all) */
int have_zone;
/** the time when zone was transferred from upstream */
time_t soa_zone_acquired;
/** current serial (from SOA), if we have no zone, 0 */
uint32_t serial;
@@ -357,6 +363,8 @@ struct auth_probe {
struct comm_timer* timer;
/** timeout in msec */
int timeout;
/** the tsig data for the packet */
struct tsig_data* tsig;
};
/**
@@ -426,6 +434,8 @@ struct auth_transfer {
/** timeout for the transfer.
* on the workers event base. */
struct comm_timer* timer;
/** the tsig data for the transfer */
struct tsig_data* tsig;
};
/** list of addresses */
@@ -457,6 +467,8 @@ struct auth_master {
int ssl;
/** the port number (for urls) */
int port;
/** the tsig key name (if any, or NULL) */
char* tsig_key_name;
/** if the host is a hostname, the list of resolved addrs, if any*/
struct auth_addr* list;
};
@@ -486,11 +498,13 @@ struct auth_zones* auth_zones_create(void);
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
* @param env: environment for offline verification.
* @param mods: modules in environment.
* @param tsig_key_table: tsig key table to check if tsig keys exist.
* If NULL, no check is performed.
* @return false on failure.
*/
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup, int* is_rpz, struct module_env* env,
struct module_stack* mods);
struct module_stack* mods, struct tsig_key_table* tsig_key_table);
/** initial pick up of worker timeouts, ties events to worker event loop
* @param az: auth zones structure
@@ -550,9 +564,10 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
* @param temp: temporary storage region.
* @return false if not answered
*/
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
struct comm_reply* repinfo, struct sldns_buffer* buf,
struct regional* temp);
/**
* Find the auth zone that is above the given qname.
@@ -614,13 +629,19 @@ int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
* @param has_serial: if true, the notify has a serial attached.
* @param serial: the serial number, if has_serial is true.
* @param refused: is set to true on failure to note refused access.
* @param pkt: the packet for TSIG verify.
* @param tsig: if TSIG, the structure is returned here, allocated in
* the worker scratch region.
* @param tsig_rcode: if not NOERROR it is the TSIG error code, TSIG failed.
* @param scratchpad: region to allocate tsig in.
* @return fail on failures (refused is false) and when access is
* denied (refused is true). True when processed.
*/
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
uint8_t* nm, size_t nmlen, uint16_t dclass,
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
uint32_t serial, int* refused);
uint32_t serial, int* refused, struct sldns_buffer* pkt,
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad);
/** process notify packet and read serial number from SOA.
* returns 0 if no soa record in the notify */
@@ -666,10 +687,12 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
* @param list: pointer to start of list. The malloced list is returned here.
* @param c: the config items to copy over.
* @param with_http: if true, http urls are also included, before the masters.
* @param tsig_key_table: if nonNULL, used to check that tsig keys exist in
* the key table.
* @return false on failure.
*/
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
int with_http);
int with_http, struct tsig_key_table* tsig_key_table);
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
void auth_xfer_timer(void* arg);
@@ -799,6 +822,14 @@ size_t auth_zones_get_mem(struct auth_zones* zones);
void auth_xfer_pickup_initial_zone(struct auth_xfer* x,
struct module_env* env);
/**
* Initial pick up of the auth zone, it sets the acquired time.
* @param z: the zone, write locked by caller.
* @param env: environment of the worker, with current time.
*/
void auth_zone_pickup_initial_zone(struct auth_zone* z,
struct module_env* env);
/**
* Delete auth xfer structure
* @param xfr: delete this xfer and its tasks.
+59 -27
View File
@@ -60,10 +60,10 @@
* @param rep: contains list of rrsets to store.
* @param now: current time.
* @param leeway: during prefetch how much leeway to update TTLs.
* This makes rrsets (other than type NS) timeout sooner so they get
* updated with a new full TTL.
* Type NS does not get this, because it must not be refreshed from the
* child domain, but keep counting down properly.
* This makes rrsets expire sooner so they get updated with a new full
* TTL.
* Child side type NS does get this but TTL checks are done using the time
* the query was created rather than the time the answer was received.
* @param pside: if from parentside discovered NS, so that its NS is okay
* in a prefetch situation to be updated (without becoming sticky).
* @param qrep: update rrsets here if cache is better
@@ -100,11 +100,20 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
rep->ref[i].id != rep->ref[i].key->id)
ck = NULL;
else ck = packed_rrset_copy_region(
rep->ref[i].key, region, now);
rep->ref[i].key, region,
((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?qstarttime:now));
lock_rw_unlock(&rep->ref[i].key->entry.lock);
if(ck) {
/* use cached copy if memory allows */
qrep->rrsets[i] = ck;
ttl = ((struct packed_rrset_data*)
ck->entry.data)->ttl;
if(ttl < qrep->ttl) {
qrep->ttl = ttl;
qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl);
qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL;
}
}
}
/* no break: also copy key item */
@@ -169,10 +178,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
/* there was a reply_info_sortref(rep) here but it seems to be
* unnecessary, because the cache gets locked per rrset. */
reply_info_set_ttls(rep, *env->now);
if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) {
reply_info_absolute_ttls(rep, *env->now, *env->now - ttl);
} else reply_info_set_ttls(rep, *env->now);
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
qstarttime);
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
if(ttl == 0) {
/* we do not store the message, but we did store the RRs,
* which could be useful for delegation information */
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
@@ -272,8 +283,10 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
{
if((msg->rep->rrsets[msg->rep->rrset_count] =
packed_rrset_copy_region(rrset, region, now))) {
struct packed_rrset_data* d = rrset->entry.data;
msg->rep->ar_numrrsets++;
msg->rep->rrset_count++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
}
@@ -456,8 +469,10 @@ find_add_ds(struct module_env* env, struct regional* region,
/* add it to auth section. This is the second rrset. */
if((msg->rep->rrsets[msg->rep->rrset_count] =
packed_rrset_copy_region(rrset, region, now))) {
struct packed_rrset_data* d = rrset->entry.data;
msg->rep->ns_numrrsets++;
msg->rep->rrset_count++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
lock_rw_unlock(&rrset->entry.lock);
}
@@ -487,6 +502,8 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
return NULL; /* integer overflow protection */
msg->rep->flags = BIT_QR; /* with QR, no AA */
msg->rep->qdcount = 1;
msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add
* rrsets to the message */
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->rrsets = (struct ub_packed_rrset_key**)
regional_alloc(region,
@@ -497,24 +514,28 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
}
int
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now)
{
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
struct packed_rrset_data* d = rrset->entry.data;
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
packed_rrset_copy_region(rrset, region, now)))
return 0;
msg->rep->ns_numrrsets++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
return 1;
}
int
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
struct ub_packed_rrset_key* rrset, time_t now)
{
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
struct packed_rrset_data* d = rrset->entry.data;
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
packed_rrset_copy_region(rrset, region, now)))
return 0;
msg->rep->an_numrrsets++;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
return 1;
}
@@ -585,6 +606,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
sizeof(struct reply_info) - sizeof(struct rrset_ref));
if(!msg->rep)
return NULL;
msg->rep->ttl = MAX_TTL;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->reason_bogus_str = NULL;
if(num > RR_COUNT_MAX)
@@ -606,13 +628,13 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
size_t i;
int is_expired = 0;
time_t now_control = now;
if(now > r->ttl) {
if(TTL_IS_EXPIRED(r->ttl, now)) {
/* Check if we are allowed to serve expired */
if(!allow_expired || !reply_info_can_answer_expired(r, now))
return NULL;
/* Change the current time so we can pass the below TTL checks when
* serving expired data. */
now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
/* Change the current time so we can pass the below TTL checks
* when serving expired data. */
now_control = 0;
is_expired = 1;
}
@@ -620,15 +642,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
if(!msg) return NULL;
msg->rep->flags = r->flags;
msg->rep->qdcount = r->qdcount;
msg->rep->ttl = is_expired
?SERVE_EXPIRED_REPLY_TTL
:r->ttl - now;
if(r->prefetch_ttl > now)
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
else
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
msg->rep->security = r->security;
msg->rep->an_numrrsets = r->an_numrrsets;
msg->rep->ns_numrrsets = r->ns_numrrsets;
@@ -656,13 +669,30 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
return NULL;
}
for(i=0; i<msg->rep->rrset_count; i++) {
struct packed_rrset_data* d;
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
region, now);
if(!msg->rep->rrsets[i]) {
rrset_array_unlock(r->ref, r->rrset_count);
return NULL;
}
d = msg->rep->rrsets[i]->entry.data;
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
}
if(msg->rep->rrset_count < 1) {
msg->rep->ttl = is_expired
?SERVE_EXPIRED_REPLY_TTL
:r->ttl - now;
if(r->prefetch_ttl > now)
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
else
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
} else {
/* msg->rep->ttl has been updated through the RRSets above */
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
}
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
if(env)
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
r->rrset_count);
@@ -701,7 +731,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
struct dns_msg* msg;
struct packed_rrset_data* d = (struct packed_rrset_data*)
rrset->entry.data;
if(now > d->ttl)
if(TTL_IS_EXPIRED(d->ttl, now))
return NULL;
msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */
if(!msg)
@@ -736,7 +766,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
rrset->entry.data;
uint8_t* newname, *dtarg = NULL;
size_t newlen, dtarglen;
if(now > d->ttl)
if(TTL_IS_EXPIRED(d->ttl, now))
return NULL;
/* only allow validated (with DNSSEC) DNAMEs used from cache
* for insecure DNAMEs, query again. */
@@ -844,6 +874,8 @@ fill_any(struct module_env* env,
/* set NOTIMPL for RFC 8482 */
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
msg->rep->security = sec_status_indeterminate;
msg->rep->ttl = 1; /* empty NOTIMPL response will never be
* updated with rrsets, set TTL to 1 */
return msg;
}
@@ -1069,7 +1101,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
msgqinf->qclass, flags, 0, 1);
if(e) {
struct reply_info* cached = e->entry.data;
if(cached->ttl < *env->now
if(TTL_IS_EXPIRED(cached->ttl, *env->now)
&& reply_info_could_use_expired(cached, *env->now)
/* If we are validating make sure only
* validating modules can update such messages.
+1 -1
View File
@@ -53,7 +53,7 @@ struct delegpt;
* Must be an unsigned 32-bit value larger than 0xffff */
/** Allow caching a DNS message with a zero TTL. */
#define DNSCACHE_STORE_ZEROTTL 0x100000
#define DNSCACHE_STORE_EXPIRED_MSG_CACHEDB 0x100000
/**
* Region allocated message reply
+2 -1
View File
@@ -1269,7 +1269,8 @@ int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
int cookie_valid, struct config_file* cfg)
{
struct lruhash_entry* entry;
if(cfg->wait_limit == 0)
if(cfg->wait_limit == 0 ||
(cookie_valid && cfg->wait_limit_cookie == 0))
return 1;
entry = infra_find_ip_ratedata(infra, &rep->client_addr,
+12 -9
View File
@@ -68,6 +68,8 @@ struct rrset_cache* rrset_cache_create(struct config_file* cfg,
struct rrset_cache *r = (struct rrset_cache*)slabhash_create(slabs,
startarray, maxmem, ub_rrset_sizefunc, ub_rrset_compare,
ub_rrset_key_delete, rrset_data_delete, alloc);
if(!r)
return NULL;
slabhash_setmarkdel(&r->table, &rrset_markdel);
return r;
}
@@ -129,7 +131,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
/* o if new data is expired, cached data is better */
if( newd->ttl < timenow && timenow <= cached->ttl)
if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow))
return 0;
/* o store if rrset has been validated
* everything better than bogus data
@@ -144,13 +146,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if( newd->trust > cached->trust ) {
/* if the cached rrset is bogus, and new is equal,
* do not update the TTL - let it expire. */
if(equal && cached->ttl >= timenow &&
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
cached->security == sec_status_bogus)
return 0;
return 1;
}
/* o item in cache has expired */
if( cached->ttl < timenow )
if( TTL_IS_EXPIRED(cached->ttl, timenow) )
return 1;
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal ) {
@@ -298,7 +300,7 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
/* check TTL */
struct packed_rrset_data* data =
(struct packed_rrset_data*)e->data;
if(timenow > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
lock_rw_unlock(&e->lock);
return NULL;
}
@@ -308,17 +310,18 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
return NULL;
}
int
int
rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow)
{
size_t i;
struct packed_rrset_data* d;
for(i=0; i<count; i++) {
if(i>0 && ref[i].key == ref[i-1].key)
continue; /* only lock items once */
lock_rw_rdlock(&ref[i].key->entry.lock);
if(ref[i].id != ref[i].key->id || timenow >
((struct packed_rrset_data*)(ref[i].key->entry.data))
->ttl) {
d = ref[i].key->entry.data;
if(ref[i].id != ref[i].key->id ||
TTL_IS_EXPIRED(d->ttl, timenow)) {
/* failure! rollback our readlocks */
rrset_array_unlock(ref, i+1);
return 0;
@@ -509,7 +512,7 @@ rrset_cache_expired_above(struct rrset_cache* r, uint8_t** qname, size_t*
*qnamelen, searchtype, qclass, 0, 0, 0))) {
struct packed_rrset_data* data =
(struct packed_rrset_data*)rrset->entry.data;
if(now > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, now)) {
/* it is expired, this is not wanted */
lock_rw_unlock(&rrset->entry.lock);
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
+94 -23
View File
@@ -90,10 +90,13 @@
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
#include <ngtcp2/ngtcp2_crypto_ossl.h>
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
#include <ngtcp2/ngtcp2_crypto_quictls.h>
#else
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
#include <ngtcp2/ngtcp2_crypto_openssl.h>
#define MAKE_QUIC_METHOD 1
#endif
#endif
@@ -447,7 +450,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
* /proc/sys/net/core/wmem_max or sysctl net.core.wmem_max */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
if(errno != EPERM) {
if(errno != EPERM && errno != ENOBUFS) {
log_err("setsockopt(..., SO_SNDBUFFORCE, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
@@ -455,15 +458,23 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
*inuse = 0;
return -1;
}
if(errno != EPERM) {
verbose(VERB_ALGO, "setsockopt(..., SO_SNDBUFFORCE, "
"...) was not granted: %s", sock_strerror(errno));
}
# endif /* SO_SNDBUFFORCE */
if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&snd,
(socklen_t)sizeof(snd)) < 0) {
log_err("setsockopt(..., SO_SNDBUF, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
if(errno != ENOSYS && errno != ENOBUFS) {
log_err("setsockopt(..., SO_SNDBUF, "
"...) failed: %s", sock_strerror(errno));
sock_close(s);
*noproto = 0;
*inuse = 0;
return -1;
}
log_warn("setsockopt(..., SO_SNDBUF, "
"...) was not granted: %s", sock_strerror(errno));
}
/* check if we got the right thing or if system
* reduced to some system max. Warn if so */
@@ -473,7 +484,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
"Got %u. To fix: start with "
"root permissions(linux) or sysctl "
"bigger net.core.wmem_max(linux) or "
"kern.ipc.maxsockbuf(bsd) values.",
"kern.ipc.maxsockbuf(bsd) values. or "
"set so-sndbuf: 0 (use system value).",
(unsigned)snd, (unsigned)got);
}
# ifdef SO_SNDBUFFORCE
@@ -902,7 +914,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
against IP spoofing attacks as suggested in RFC7413 */
#ifdef __APPLE__
/* OS X implementation only supports qlen of 1 via this call. Actual
value is configured by the net.inet.tcp.fastopen_backlog kernel parm. */
value is configured by the net.inet.tcp.fastopen_backlog kernel param. */
qlen = 1;
#else
/* 5 is recommended on linux */
@@ -1179,6 +1191,15 @@ set_recvtimestamp(int s)
return 0;
}
return 1;
#elif defined(SO_TIMESTAMP) && defined(SCM_TIMESTAMP)
int on = 1;
/* FreeBSD and also Linux. */
if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, (void*)&on, (socklen_t)sizeof(on)) < 0) {
log_err("setsockopt(..., SO_TIMESTAMP, ...) failed: %s",
strerror(errno));
return 0;
}
return 1;
#else
log_err("packets timestamping is not supported on this platform");
(void)s;
@@ -1598,7 +1619,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
front->udp_buff, ports->pp2_enabled, cb,
cb_arg, ports->socket);
#else
log_warn("This system does not support UDP ancilliary data.");
log_warn("This system does not support UDP ancillary data.");
#endif
}
if(!cp) {
@@ -3099,7 +3120,7 @@ static int http2_req_header_cb(nghttp2_session* session,
return 0;
}
/* Content type is a SHOULD (rfc7231#section-3.1.1.5) when using POST,
* and not needed when using GET. Don't enfore.
* and not needed when using GET. Don't enforce.
* If set only allow lowercase "application/dns-message".
*
* Clients SHOULD (rfc8484#section-4.1) set an accept header, but MUST
@@ -3161,7 +3182,7 @@ static int http2_req_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
qlen = h2_stream->content_length;
} else if(len <= h2_session->c->http2_stream_max_qbuffer_size) {
/* setting this to msg-buffer-size can result in a lot
* of memory consuption. Most queries should fit in a
* of memory consumption. Most queries should fit in a
* single DATA frame, and most POST queries will
* contain content-length which does not impose this
* limit. */
@@ -3187,7 +3208,7 @@ static int http2_req_data_chunk_recv_cb(nghttp2_session* ATTR_UNUSED(session),
if(!h2_stream->qbuffer ||
sldns_buffer_remaining(h2_stream->qbuffer) < len) {
verbose(VERB_ALGO, "http2 data_chunck_recv failed. Not enough "
verbose(VERB_ALGO, "http2 data_chunk_recv failed. Not enough "
"buffer space for POST query. Can happen on multi "
"frame requests without content-length header");
h2_stream->query_too_large = 1;
@@ -3257,6 +3278,21 @@ doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
struct doq_table* 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");
free(table);
return NULL;
}
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
if(ngtcp2_crypto_quictls_init() != 0) {
log_err("ngtcp2_crypto_quictls_init failed");
free(table);
return NULL;
}
#endif
table->idle_timeout = ((uint64_t)cfg->tcp_idle_timeout)*
NGTCP2_MILLISECONDS;
table->sv_scidlen = 16;
@@ -3596,12 +3632,18 @@ doq_conn_delete(struct doq_conn* conn, struct doq_table* table)
lock_rw_wrlock(&conn->table->conid_lock);
doq_conn_clear_conids(conn);
lock_rw_unlock(&conn->table->conid_lock);
ngtcp2_conn_del(conn->conn);
/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
* because the ngtcp2 conn is deleted. */
SSL_set_app_data(conn->ssl, NULL);
if(conn->stream_tree.count != 0) {
traverse_postorder(&conn->stream_tree, stream_tree_del, table);
}
free(conn->key.dcid);
SSL_free(conn->ssl);
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_crypto_ossl_ctx_del(conn->ossl_ctx);
#endif
ngtcp2_conn_del(conn->conn);
free(conn->close_pkt);
free(conn);
}
@@ -4459,7 +4501,7 @@ doq_log_printf_cb(void* ATTR_UNUSED(user_data), const char* fmt, ...)
va_end(ap);
}
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
#ifdef MAKE_QUIC_METHOD
/** the doq application tx key callback, false on failure */
static int
doq_application_tx_key_cb(struct doq_conn* conn)
@@ -4493,7 +4535,9 @@ doq_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
ngtcp2_crypto_level
#endif
level =
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
#else
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
@@ -4539,7 +4583,9 @@ doq_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
ngtcp2_crypto_level
#endif
level =
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
#else
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
@@ -4574,7 +4620,7 @@ doq_send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
doq_conn->tls_alert = alert;
return 1;
}
#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
#endif /* MAKE_QUIC_METHOD */
/** ALPN select callback for the doq SSL context */
static int
@@ -4596,7 +4642,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
{
#ifdef HAVE_NGTCP2
char* sid_ctx = "unbound server";
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
#ifdef MAKE_QUIC_METHOD
SSL_QUIC_METHOD* quic_method;
#endif
SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
@@ -4669,7 +4715,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
SSL_CTX_free(ctx);
return NULL;
}
#else /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
#elif defined(MAKE_QUIC_METHOD)
/* The quic_method needs to remain valid during the SSL_CTX
* lifetime, so we allocate it. It is freed with the
* doq_server_socket. */
@@ -4704,12 +4750,29 @@ static ngtcp2_conn* doq_conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
static SSL*
doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
{
#ifdef USE_NGTCP2_CRYPTO_OSSL
int ret;
#endif
SSL* ssl = SSL_new(ctx);
if(!ssl) {
log_crypto_err("doq: SSL_new failed");
return NULL;
}
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
#ifdef USE_NGTCP2_CRYPTO_OSSL
if((ret=ngtcp2_crypto_ossl_ctx_new(&conn->ossl_ctx, NULL)) != 0) {
log_err("doq: ngtcp2_crypto_ossl_ctx_new failed: %s",
ngtcp2_strerror(ret));
SSL_free(ssl);
return NULL;
}
ngtcp2_crypto_ossl_ctx_set_ssl(conn->ossl_ctx, ssl);
if(ngtcp2_crypto_ossl_configure_server_session(ssl) != 0) {
log_err("doq: ngtcp2_crypto_ossl_configure_server_session failed");
SSL_free(ssl);
return NULL;
}
#endif
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
conn->conn_ref.get_conn = &doq_conn_ref_get_conn;
conn->conn_ref.user_data = conn;
SSL_set_app_data(ssl, &conn->conn_ref);
@@ -4717,7 +4780,11 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
SSL_set_app_data(ssl, conn);
#endif
SSL_set_accept_state(ssl);
#ifdef USE_NGTCP2_CRYPTO_OSSL
SSL_set_quic_tls_early_data_enabled(ssl, 1);
#else
SSL_set_quic_early_data_enabled(ssl, 1);
#endif
return ssl;
}
@@ -4838,7 +4905,11 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
log_err("doq_ssl_server_setup failed");
return 0;
}
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ossl_ctx);
#else
ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ssl);
#endif
doq_conn_write_enable(conn);
return 1;
}
+8 -1
View File
@@ -52,6 +52,9 @@
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#ifdef USE_NGTCP2_CRYPTO_OSSL
struct ngtcp2_crypto_ossl_ctx;
#endif
#endif
struct listen_list;
struct config_file;
@@ -606,9 +609,13 @@ struct doq_conn {
uint8_t tls_alert;
/** the ssl context, SSL* */
void* ssl;
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
/** the connection reference for ngtcp2_conn and userdata in ssl */
struct ngtcp2_crypto_conn_ref conn_ref;
#endif
#ifdef USE_NGTCP2_CRYPTO_OSSL
/** the per-connection state for ngtcp2_crypto_ossl */
struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
#endif
/** closure packet, if any */
uint8_t* close_pkt;
+129 -42
View File
@@ -45,6 +45,7 @@
#include "config.h"
#include "services/mesh.h"
#include "services/outbound_list.h"
#include "services/outside_network.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
@@ -58,6 +59,7 @@
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/edns.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "services/localzone.h"
@@ -65,6 +67,8 @@
#include "respip/respip.h"
#include "services/listen_dnsport.h"
#include "util/timeval_func.h"
#include "util/allow_response_list.h"
#include "util/tsig.h"
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
@@ -348,7 +352,7 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
key = (struct msgreply_entry*)e->key;
data = (struct reply_info*)e->data;
if(data->ttl < timenow) *is_expired = 1;
if(TTL_IS_EXPIRED(data->ttl, timenow)) *is_expired = 1;
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
qstate->env->cfg->serve_expired, qstate->env->scratch);
if(!msg)
@@ -441,9 +445,18 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep,
edns->cookie_valid, mesh->env->cfg)) {
verbose(VERB_ALGO, "Too many queries waiting from the IP. "
"dropping incoming query.");
comm_point_drop_reply(rep);
"servfail incoming query.");
mesh->num_queries_wait_limit++;
edns_opt_list_append_ede(&edns->opt_list_out,
mesh->env->scratch, LDNS_EDE_OTHER,
"Too many queries queued up and waiting from the IP");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
edns->opt_list_inplace_cb_out = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
regional_free_all(mesh->env->scratch);
comm_point_send_reply(rep);
return;
}
if(!unique)
@@ -1152,8 +1165,7 @@ mesh_detect_cycle_found(struct module_qstate* qstate, struct mesh_state* dep_m)
{
struct mesh_state* cyc_m = qstate->mesh_info;
size_t counter = 0;
if(!dep_m)
return 0;
log_assert(dep_m);
if(dep_m == cyc_m || find_in_subsub(dep_m, cyc_m, &counter)) {
if(counter > MESH_MAX_SUBSUB)
return 2;
@@ -1190,24 +1202,19 @@ void mesh_detach_subs(struct module_qstate* qstate)
}
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub)
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub)
{
/* find it, if not, create it */
struct mesh_area* mesh = qstate->env->mesh;
*sub = mesh_area_find(mesh, NULL, qinfo, qflags,
prime, valrec);
if(mesh_detect_cycle_found(qstate, *sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
return 0;
}
*sub = mesh_area_find(mesh, cinfo, qinfo, qflags, prime, valrec);
if(!*sub) {
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
#endif
/* create a new one */
*sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime,
valrec);
*sub = mesh_state_create(qstate->env, qinfo, cinfo, qflags,
prime, valrec);
if(!*sub) {
log_err("mesh_attach_sub: out of memory");
return 0;
@@ -1230,18 +1237,25 @@ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
rbtree_insert(&mesh->run, &(*sub)->run_node);
log_assert(n != NULL);
*newq = &(*sub)->s;
} else
} else {
*newq = NULL;
if(mesh_detect_cycle_found(qstate, *sub)) {
verbose(VERB_ALGO, "attach failed, cycle detected");
return 0;
}
}
return 1;
}
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq)
{
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* sub = NULL;
int was_detached;
if(!mesh_add_sub(qstate, qinfo, qflags, prime, valrec, newq, &sub))
if(!mesh_add_sub(qstate, qinfo, cinfo, qflags, prime, valrec, newq,
&sub))
return 0;
was_detached = (sub->super_set.count == 0);
if(!mesh_state_attachment(qstate->mesh_info, sub))
@@ -1684,7 +1698,7 @@ static void dns_error_reporting(struct module_qstate* qstate,
log_query_info(VERB_ALGO, "DNS Error Reporting: generating report "
"query for", &qinfo);
if(mesh_add_sub(qstate, &qinfo, BIT_RD, 0, 0, &newq, &sub)) {
if(mesh_add_sub(qstate, &qinfo, NULL, BIT_RD, 0, 0, &newq, &sub)) {
qstate->env->mesh->num_dns_error_reports++;
}
return;
@@ -1726,29 +1740,101 @@ void mesh_query_done(struct mesh_state* mstate)
if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting)
dns_error_reporting(&mstate->s, rep);
if(mstate->reply_list && rep) {
uint8_t data[8192];
struct sldns_buffer dest;
int i;
sldns_buffer_init_frm_data(&dest, data, sizeof(data));
reply_info_answer_encode(&mstate->s.qinfo, rep, 0 /* id */,
0 /* qflags */, &dest, 0 /* current time */,
1 /* cached */, mstate->s.env->scratch,
sizeof(data) /* udpsize */, NULL /* edns */,
1 /* dnssec */, 0 /* secure */);
log_err("Answer to be send to %d other unbounds, size: %d",
mstate->s.env->outnet->num_dist,
(int)sldns_buffer_limit(&dest));
for(i = 0; i < mstate->s.env->outnet->num_dist; i++) {
struct tsig_key* key;
int r;
uint8_t data_signed[8192];
struct sldns_buffer dest_signed;
if(mstate->s.env->outnet->dist[i] == -1
|| mstate->s.env->outnet->dist_tsig[i] == NULL)
continue;
if(mstate->s.env->outnet->dist_tsig[i] == TSIG_NOKEY) {
send(mstate->s.env->outnet->dist[i],
data, sldns_buffer_limit(&dest), 0);
continue;
}
lock_rw_rdlock(&mstate->s.env->tsig_key_table->lock);
key = tsig_key_table_search_fromstr(
mstate->s.env->tsig_key_table,
mstate->s.env->outnet->dist_tsig[i]);
if(!key) {
lock_rw_unlock(
&mstate->s.env->tsig_key_table->lock);
log_err("tsig key \"%s\" not found when "
"distributing responses",
mstate->s.env->outnet->dist_tsig[i]);
continue;
}
sldns_buffer_init_frm_data(&dest_signed,
data_signed, sizeof(data_signed));
sldns_buffer_write(&dest_signed,
data, sldns_buffer_limit(&dest));
if((r = tsig_sign_shared(&dest_signed, key->name,
key->algo->wireformat_name,
key->data, key->data_len,
*mstate->s.env->now))) {
lock_rw_unlock(
&mstate->s.env->tsig_key_table->lock);
log_err("tsig key \"%s\" failed to sign"
"distributing response: %s",
key->name_str,
sldns_lookup_by_id(sldns_tsig_errors, r)?
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
continue;
}
lock_rw_unlock(&mstate->s.env->tsig_key_table->lock);
send(mstate->s.env->outnet->dist[i], data_signed,
sldns_buffer_position(&dest_signed), 0);
}
}
for(r = mstate->reply_list; r; r = r->next) {
struct timeval old;
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
if(mstate->s.env->cfg->discard_timeout != 0 &&
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
mstate->s.env->cfg->discard_timeout) {
/* Drop the reply, it is too old */
/* briefly set the reply_list to NULL, so that the
* tcp req info cleanup routine that calls the mesh
* to deregister the meshstate for it is not done
* because the list is NULL and also accounting is not
* done there, but instead we do that here. */
struct mesh_reply* reply_list = mstate->reply_list;
verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
infra_wait_limit_dec(mstate->s.env->infra_cache,
&r->query_reply, mstate->s.env->cfg);
mstate->reply_list = NULL;
if(r->query_reply.c->use_h2)
http2_stream_remove_mesh_state(r->h2_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
mstate->s.env->mesh->num_queries_discard_timeout++;
continue;
if(mesh_is_udp(r)) {
/* For UDP queries, the old replies are discarded.
* This stops a large volume of old replies from
* building up.
* The stream replies, are not discarded. The
* stream is open, the other side is waiting.
* Some answer is needed, even if servfail, but the
* real reply is ready to go, so that is given. */
struct timeval old;
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
if(mstate->s.env->cfg->discard_timeout != 0 &&
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
mstate->s.env->cfg->discard_timeout) {
/* Drop the reply, it is too old */
/* briefly set the reply_list to NULL, so that the
* tcp req info cleanup routine that calls the mesh
* to deregister the meshstate for it is not done
* because the list is NULL and also accounting is not
* done there, but instead we do that here. */
struct mesh_reply* reply_list = mstate->reply_list;
verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
infra_wait_limit_dec(mstate->s.env->infra_cache,
&r->query_reply, mstate->s.env->cfg);
mstate->reply_list = NULL;
if(r->query_reply.c->use_h2)
http2_stream_remove_mesh_state(r->h2_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
mstate->s.env->mesh->num_queries_discard_timeout++;
continue;
}
}
i++;
@@ -2265,6 +2351,7 @@ mesh_stats_clear(struct mesh_area* mesh)
timehist_clear(mesh->histogram);
mesh->ans_secure = 0;
mesh->ans_bogus = 0;
mesh->val_ops = 0;
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
@@ -2296,7 +2383,7 @@ mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
struct mesh_area* mesh = qstate->env->mesh;
struct mesh_state* dep_m = NULL;
dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
return mesh_detect_cycle_found(qstate, dep_m);
return dep_m?mesh_detect_cycle_found(qstate, dep_m):0;
}
void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp,
+10 -3
View File
@@ -131,6 +131,8 @@ struct mesh_area {
size_t ans_secure;
/** (extended stats) bogus replies */
size_t ans_bogus;
/** (extended stats) number of validation operations */
size_t val_ops;
/** (extended stats) rcodes in replies */
size_t ans_rcode[UB_STATS_RCODE_NUM];
/** (extended stats) rcode nodata in replies */
@@ -397,6 +399,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -405,7 +409,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @return: false on error, true if success (and init may be needed).
*/
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
/**
* Add detached query.
@@ -424,6 +429,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -433,8 +440,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @return: false on error, true if success (and init may be needed).
*/
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub);
/**
* Query state is done, send messages to reply entries.
+7 -4
View File
@@ -138,8 +138,8 @@ modstack_config(struct module_stack* stack, const char* module_conf)
if(strchr(s, ' ')) *(strchr(s, ' ')) = 0;
if(strchr(s, '\t')) *(strchr(s, '\t')) = 0;
log_err("Unknown value in module-config, module: '%s'."
" This module is not present (not compiled in),"
" See the list of linked modules with unbound -V", s);
" This module is not present (not compiled in);"
" see the list of linked modules with unbound -V", s);
return 0;
}
}
@@ -262,6 +262,7 @@ int
modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
const char* orig_module_conf = module_conf;
int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
@@ -276,11 +277,13 @@ modstack_call_init(struct module_stack* stack, const char* module_conf,
changed = 1;
}
}
module_conf += strlen(stack->mod[i]->name);
/* Skip this module name in module_conf. */
while(*module_conf && !isspace((unsigned char)*module_conf))
module_conf++;
}
if(changed) {
modstack_free(stack);
if(!modstack_config(stack, module_conf)) {
if(!modstack_config(stack, orig_module_conf)) {
return 0;
}
}
+1 -1
View File
@@ -67,7 +67,7 @@ void modstack_init(struct module_stack* stack);
void modstack_free(struct module_stack* stack);
/**
* Initialises modules and assignes ids. Calls module_startup().
* Initialises modules and assigns ids. Calls module_startup().
* @param stack: Expected empty, filled according to module_conf
* @param module_conf: string what modules to initialize
* @param env: module environment which is inited by the modules.
+34 -4
View File
@@ -59,6 +59,7 @@
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "util/edns.h"
#include "util/allow_response_list.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
#ifdef HAVE_OPENSSL_SSL_H
@@ -1678,7 +1679,8 @@ outside_network_create(struct comm_base *base, size_t bufsize,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv,
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
int tcp_auth_query_timeout)
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
int num_dist)
{
struct outside_network* outnet = (struct outside_network*)
calloc(1, sizeof(struct outside_network));
@@ -1819,6 +1821,32 @@ outside_network_create(struct comm_base *base, size_t bufsize,
}
}
}
if (!(outnet->num_dist = num_dist))
outnet->dist = NULL;
else if ((outnet->dist = calloc(num_dist, sizeof(int))) &&
(outnet->dist_tsig = calloc(num_dist, sizeof(const char*)))) {
int i;
for(i = 0; i < num_dist; i++) {
struct sockaddr_storage addr;
socklen_t addrlen;
int s = -1;
if(!extstrtoaddr(dist[i], &addr, &addrlen, UNBOUND_DNS_PORT)
|| (s = socket(addr.ss_family, SOCK_DGRAM, 0)) == -1
|| !fd_set_nonblock(s)
|| connect(s, (struct sockaddr*)&addr, addrlen)) {
if(s != -1)
close(s);
s = -1;
}
outnet->dist[i] = s;
outnet->dist_tsig[i] = dist_tsig[i] == NULL ? NULL
: strcmp(dist_tsig[i], TSIG_NOKEY)
? strdup(dist_tsig[i])
: TSIG_NOKEY;
}
}
return outnet;
}
@@ -1949,6 +1977,8 @@ outside_network_delete(struct outside_network* outnet)
p = np;
}
}
if(outnet->num_dist > 0 && outnet->dist != NULL)
free(outnet->dist);
free(outnet);
}
@@ -2827,7 +2857,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
random = ub_random(rnd);
bits = 30;
}
if(random & 0x1) {
if((random & 0x1)) {
*d = (uint8_t)toupper((unsigned char)*d);
} else {
*d = (uint8_t)tolower((unsigned char)*d);
@@ -2890,9 +2920,9 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
edns.opt_list_inplace_cb_out = NULL;
edns.udp_size = serviced_query_udp_size(sq, sq->status);
edns.bits = 0;
if(sq->dnssec & EDNS_DO)
if((sq->dnssec & EDNS_DO))
edns.bits = EDNS_DO;
if(sq->dnssec & BIT_CD)
if((sq->dnssec & BIT_CD))
LDNS_CD_SET(sldns_buffer_begin(buff));
if (sq->ssl_upstream && sq->padding_block_size) {
padding_option.opt_code = LDNS_EDNS_PADDING;
+8 -1
View File
@@ -190,6 +190,12 @@ struct outside_network {
struct waiting_tcp* tcp_wait_first;
/** last of waiting query list */
struct waiting_tcp* tcp_wait_last;
/** number of IP addresses to send to be cached responses to */
int num_dist;
/** udp sockets to the addresses to send to be cached responses to */
int* dist;
/** names of TSIG keys with which to sign the outgoing responses */
const char** dist_tsig;
};
/**
@@ -570,7 +576,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
int tcp_auth_query_timeout);
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
int num_dist);
/**
* Delete outside_network structure.
+19 -1
View File
@@ -2121,8 +2121,17 @@ rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
rpz_log_dname("nsdname local data", key.name, key.namelen);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
if(ld == NULL && dname_is_wild(z->name)) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
/* rpz_synthesize_localdata_from_rrset is going to make
* the rrset source name equal to the query name. So no need
* to make the wildcard rrset here. */
}
if(ld == NULL) {
verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
verbose(VERB_ALGO, "rpz: nsdname: qname not found");
return NULL;
}
@@ -2148,6 +2157,15 @@ rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
key.namelen = qinfo->qname_len;
key.namelabs = dname_count_labels(qinfo->qname);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
if(ld == NULL && dname_is_wild(z->name)) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
/* rpz_synthesize_localdata_from_rrset is going to make
* the rrset source name equal to the query name. So no need
* to make the wildcard rrset here. */
}
if(ld == NULL) {
verbose(VERB_ALGO, "rpz: qname: name not found");
return NULL;
+2 -2
View File
@@ -124,7 +124,7 @@ uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
size_t i;
uint32_t ac32 = 0;
for (i = 0; i < keysize; ++i) {
ac32 += (i & 1) ? key[i] : key[i] << 8;
ac32 += ((i & 1)) ? key[i] : key[i] << 8;
}
ac32 += (ac32 >> 16) & 0xFFFF;
return (uint16_t) (ac32 & 0xFFFF);
@@ -272,7 +272,7 @@ sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
return NULL;
}
if (!DSA_set0_key(dsa, Y, NULL)) {
/* QPG attached, cleaned up by DSA_fre() */
/* QPG attached, cleaned up by DSA_free() */
DSA_free(dsa);
BN_free(Y);
return NULL;
+3 -1
View File
@@ -480,7 +480,8 @@ enum sldns_enum_ede_code
LDNS_EDE_TOO_EARLY = 26,
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
LDNS_EDE_BADPROXYPOLICY = 28,
LDNS_EDE_SYNTHESIZED = 29
LDNS_EDE_SYNTHESIZED = 29,
LDNS_EDE_INVALID_QUERY_TYPE = 30
};
typedef enum sldns_enum_ede_code sldns_ede_code;
@@ -494,6 +495,7 @@ typedef enum sldns_enum_ede_code sldns_ede_code;
#define LDNS_TSIG_ERROR_BADMODE 19
#define LDNS_TSIG_ERROR_BADNAME 20
#define LDNS_TSIG_ERROR_BADALG 21
#define LDNS_TSIG_ERROR_BADTRUNC 22
/** DNS Cookie extended rcode */
#define LDNS_EXT_RCODE_BADCOOKIE 23
+38
View File
@@ -56,6 +56,18 @@ sldns_read_uint32(const void *src)
#endif
}
INLINE uint64_t
sldns_read_uint48(const void *src)
{
const uint8_t *p = (const uint8_t *) src;
return ( ((uint64_t) p[0] << 40)
| ((uint64_t) p[1] << 32)
| ((uint64_t) p[2] << 24)
| ((uint64_t) p[3] << 16)
| ((uint64_t) p[4] << 8)
| (uint64_t) p[5]);
}
/*
* Copy data allowing for unaligned accesses in network byte order
* (big endian).
@@ -693,6 +705,32 @@ sldns_buffer_read_u32(sldns_buffer *buffer)
return result;
}
/**
* returns the 6-byte integer value at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at position in the buffer
* \return 6 byte integer
*/
INLINE uint64_t
sldns_buffer_read_u48_at(sldns_buffer *buffer, size_t at)
{
assert(sldns_buffer_available_at(buffer, at, 6));
return sldns_read_uint48(buffer->_data + at);
}
/**
* returns the 6-byte integer value at the current position in the buffer
* \param[in] buffer the buffer
* \return 6 byte integer
*/
INLINE uint64_t
sldns_buffer_read_u48(sldns_buffer *buffer)
{
uint64_t result = sldns_buffer_read_u48_at(buffer, buffer->_position);
buffer->_position += 6;
return result;
}
/**
* returns the status of the buffer
* \param[in] buffer
+1 -1
View File
@@ -857,7 +857,7 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
while (rdata_len && *rdata != 0) {
uint8_t label_len;
if (*rdata & 0xC0)
if ((*rdata & 0xC0))
return LDNS_WIREPARSE_ERR_OK;
label_len = *rdata + 1;
+2
View File
@@ -233,6 +233,7 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
{ LDNS_EDE_INVALID_QUERY_TYPE, "Invalid Query Type" },
{ 0, NULL}
};
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
@@ -255,6 +256,7 @@ static sldns_lookup_table sldns_tsig_errors_data[] = {
{ LDNS_TSIG_ERROR_BADMODE, "BADMODE" },
{ LDNS_TSIG_ERROR_BADNAME, "BADNAME" },
{ LDNS_TSIG_ERROR_BADALG, "BADALG" },
{ LDNS_TSIG_ERROR_BADTRUNC, "BADTRUNC" },
{ 0, NULL }
};
sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
+1 -1
View File
@@ -262,7 +262,7 @@ int sldns_wire2str_rdata_unknown_scan(uint8_t** data, size_t* data_len,
* @param pkt: packet for decompression, if NULL no decompression.
* @param pktlen: length of packet buffer.
* @param comprloop: inout bool, that is set true if compression loop failure
* happens. Pass in 0, if passsed in as true, a lower bound is set
* happens. Pass in 0, if passed in as true, a lower bound is set
* on compression loops to stop arbitrary long packet parse times.
* This is meant so you can set it to 0 at the start of a list of dnames,
* and then scan all of them in sequence, if a loop happens, it becomes
+9 -3
View File
@@ -382,7 +382,7 @@ read_cert_file(const char* file)
STACK_OF(X509)* sk;
FILE* in;
int content = 0;
char buf[128];
long flen;
if(file == NULL || strcmp(file, "") == 0) {
return NULL;
}
@@ -399,6 +399,11 @@ read_cert_file(const char* file)
#endif
return NULL;
}
if(fseek(in, 0, SEEK_END) < 0)
printf("%s fseek: %s\n", file, strerror(errno));
flen = ftell(in);
if(fseek(in, 0, SEEK_SET) < 0)
printf("%s fseek: %s\n", file, strerror(errno));
while(!feof(in)) {
X509* x = PEM_read_X509(in, NULL, NULL, NULL);
if(x == NULL) {
@@ -414,8 +419,9 @@ read_cert_file(const char* file)
exit(0);
}
content = 1;
/* read away newline after --END CERT-- */
if(!fgets(buf, (int)sizeof(buf), in))
/* feof may not be true yet, but if the position is
* at end of file, stop reading more certificates. */
if(ftell(in) == flen)
break;
}
fclose(in);
+60 -6
View File
@@ -49,6 +49,7 @@
#include "util/module.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/tsig.h"
#include "iterator/iterator.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
@@ -294,7 +295,8 @@ view_and_respipchecks(struct config_file* cfg)
{
struct views* views = NULL;
struct respip_set* respip = NULL;
int ignored = 0;
int have_view_respip_cfg = 0;
int use_response_ip = 0;
if(!(views = views_create()))
fatal_exit("Could not create views: out of memory");
if(!(respip = respip_set_create()))
@@ -303,8 +305,11 @@ view_and_respipchecks(struct config_file* cfg)
fatal_exit("Could not set up views");
if(!respip_global_apply_cfg(respip, cfg))
fatal_exit("Could not setup respip set");
if(!respip_views_apply_cfg(views, cfg, &ignored))
if(!respip_views_apply_cfg(views, cfg, &have_view_respip_cfg))
fatal_exit("Could not setup per-view respip sets");
use_response_ip = !respip_set_is_empty(respip) || have_view_respip_cfg;
if(use_response_ip && !strstr(cfg->module_conf, "respip"))
fatal_exit("response-ip options require respip module");
acl_view_tag_checks(cfg, views);
views_delete(views);
respip_set_delete(respip);
@@ -450,6 +455,39 @@ ifautomaticportschecks(char* ifautomaticports)
}
}
/** check control interface strings */
static void
controlinterfacechecks(struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->control_ifs.first; p; p = p->next) {
struct sockaddr_storage a;
socklen_t alen;
char** rcif = NULL;
int i, num_rcif = 0;
/* See if it is a local socket, starts with a '/'. */
if(p->str && p->str[0] == '/')
continue;
if(!resolve_interface_names(&p->str, 1, NULL, &rcif,
&num_rcif)) {
fatal_exit("could not resolve interface names, for control-interface: %s",
p->str);
}
for(i=0; i<num_rcif; i++) {
if(!extstrtoaddr(rcif[i], &a, &alen,
cfg->control_port)) {
if(strcmp(p->str, rcif[i])!=0)
fatal_exit("cannot parse control-interface address '%s' from the control-interface specified as '%s'",
rcif[i], p->str);
else
fatal_exit("cannot parse control-interface specified as '%s'",
p->str);
}
}
config_del_strarray(rcif, num_rcif);
}
}
/** check acl ips */
static void
aclchecks(struct config_file* cfg)
@@ -636,8 +674,10 @@ check_modules_exist(const char* module_conf)
}
n[j] = s[j];
}
fatal_exit("module_conf lists module '%s' but that "
"module is not available.", n);
fatal_exit("Unknown value in module-config, module: "
"'%s'. This module is not present (not "
"compiled in); see the list of linked modules "
"with unbound -V", n);
}
s += strlen(names[i]);
}
@@ -744,7 +784,6 @@ morechecks(struct config_file* cfg)
/* check that the modules listed in module_conf exist */
check_modules_exist(cfg->module_conf);
/* Respip is known to *not* work with dns64. */
if(strcmp(cfg->module_conf, "iterator") != 0
&& strcmp(cfg->module_conf, "validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
@@ -830,6 +869,7 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip dns64 validator cachedb iterator") != 0
#endif
#if defined(WITH_PYTHONMODULE) && defined(USE_CACHEDB)
&& strcmp(cfg->module_conf, "python dns64 cachedb iterator") != 0
@@ -926,6 +966,8 @@ morechecks(struct config_file* cfg)
fatal_exit("control-cert-file: \"%s\" does not exist",
cfg->control_cert_file);
}
if(cfg->remote_control_enable)
controlinterfacechecks(cfg);
donotquerylocalhostcheck(cfg);
localzonechecks(cfg);
@@ -962,11 +1004,23 @@ static void
check_auth(struct config_file* cfg)
{
int is_rpz = 0;
struct tsig_key_table* tsig_key_table;
struct auth_zones* az = auth_zones_create();
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL)) {
/* construct tsig key table for tsig key name checks, and it
* also checks the TSIG key name and algorithm and base64 syntax. */
tsig_key_table = tsig_key_table_create();
if(!tsig_key_table || !tsig_key_table_apply_cfg(tsig_key_table, cfg))
fatal_exit("Could not set up TSIG keys");
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL,
tsig_key_table)) {
fatal_exit("Could not setup authority zones");
}
if(is_rpz && !strstr(cfg->module_conf, "respip"))
fatal_exit("RPZ requires the respip module");
auth_zones_delete(az);
tsig_key_table_delete(tsig_key_table);
}
/** check config file */
+3
View File
@@ -143,6 +143,8 @@ usage(void)
printf(" load_cache load cache from stdin\n");
printf(" (not supported in remote unbounds in\n");
printf(" multi-process operation)\n");
printf(" cache_lookup [+t] <names> print rrsets and msgs at or under the names\n");
printf(" +t allow tld and root names.\n");
printf(" lookup <name> print nameservers for name\n");
printf(" flush [+c] <name> flushes common types for name from cache\n");
printf(" types: A, AAAA, MX, PTR, NS,\n");
@@ -409,6 +411,7 @@ static void print_extended(struct ub_stats_info* s, int inhibit_zero)
PR_UL("num.answer.secure", s->svr.ans_secure);
PR_UL("num.answer.bogus", s->svr.ans_bogus);
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
PR_UL("num.valops", s->svr.val_ops);
PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror);
PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain);
/* threat detection */
+1 -1
View File
@@ -388,7 +388,7 @@ static int http2_frame_recv_cb(nghttp2_session *session,
}
if(((frame->hd.type != NGHTTP2_DATA &&
frame->hd.type != NGHTTP2_HEADERS) ||
frame->hd.flags & NGHTTP2_FLAG_END_STREAM) &&
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) &&
h2_stream->res_status == 200) {
char* pktstr;
sldns_buffer_flip(h2_stream->buf);
+60 -11
View File
@@ -48,10 +48,13 @@
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
#include <ngtcp2/ngtcp2_crypto_ossl.h>
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
#include <ngtcp2/ngtcp2_crypto_quictls.h>
#else
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
#include <ngtcp2/ngtcp2_crypto_openssl.h>
#define MAKE_QUIC_METHOD 1
#endif
#include <openssl/ssl.h>
#include <openssl/rand.h>
@@ -107,9 +110,13 @@ struct doq_client_data {
SSL_CTX* ctx;
/** SSL object */
SSL* ssl;
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
/** the connection reference for ngtcp2_conn and userdata in ssl */
struct ngtcp2_crypto_conn_ref conn_ref;
#endif
#ifdef USE_NGTCP2_CRYPTO_OSSL
/** the per-connection state for ngtcp2_crypto_ossl */
struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
#endif
/** the quic version to use */
uint32_t quic_version;
@@ -197,11 +204,12 @@ struct doq_client_stream {
int query_is_done;
};
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#ifdef MAKE_QUIC_METHOD
/** the quic method struct, must remain valid during the QUIC connection. */
static SSL_QUIC_METHOD quic_method;
#endif
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
/** Get the connection ngtcp2_conn from the ssl app data
* ngtcp2_crypto_conn_ref */
static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
@@ -210,11 +218,12 @@ static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
conn_ref->user_data;
return data->conn;
}
#endif
static void
set_app_data(SSL* ssl, struct doq_client_data* data)
{
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
data->conn_ref.get_conn = &conn_ref_get_conn;
data->conn_ref.user_data = data;
SSL_set_app_data(ssl, &data->conn_ref);
@@ -227,7 +236,7 @@ static struct doq_client_data*
get_app_data(SSL* ssl)
{
struct doq_client_data* data;
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
data = (struct doq_client_data*)((struct ngtcp2_crypto_conn_ref*)
SSL_get_app_data(ssl))->user_data;
#else
@@ -893,7 +902,7 @@ handshake_completed(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
verbose(1, "early data was accepted by the server");
}
}
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
if(data->transport_file) {
early_data_write_transport(data);
}
@@ -1207,7 +1216,7 @@ early_data_write_transport(struct doq_client_data* data)
#endif
}
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
#ifdef MAKE_QUIC_METHOD
/** applicatation rx key callback, this is where the rx key is set,
* and streams can be opened, like http3 unidirectional streams, like
* the http3 control and http3 qpack encode and decoder streams. */
@@ -1317,7 +1326,7 @@ send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
data->tls_alert = alert;
return 1;
}
#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT */
#endif /* MAKE_QUIC_METHOD */
/** new session callback. We can write it to file for resumption later. */
static int
@@ -1357,7 +1366,7 @@ ctx_client_setup(void)
log_err("ngtcp2_crypto_quictls_configure_client_context failed");
exit(1);
}
#else
#elif defined(MAKE_QUIC_METHOD)
memset(&quic_method, 0, sizeof(quic_method));
quic_method.set_encryption_secrets = &set_encryption_secrets;
quic_method.add_handshake_data = &add_handshake_data;
@@ -1373,22 +1382,39 @@ ctx_client_setup(void)
static SSL*
ssl_client_setup(struct doq_client_data* data)
{
#ifdef USE_NGTCP2_CRYPTO_OSSL
int ret;
#endif
SSL* ssl = SSL_new(data->ctx);
if(!ssl) {
log_crypto_err("Could not SSL_new");
exit(1);
}
#ifdef USE_NGTCP2_CRYPTO_OSSL
if((ret=ngtcp2_crypto_ossl_ctx_new(&data->ossl_ctx, NULL)) != 0) {
log_err("ngtcp2_crypto_ossl_ctx_new failed: %s",
ngtcp2_strerror(ret));
exit(1);
}
ngtcp2_crypto_ossl_ctx_set_ssl(data->ossl_ctx, ssl);
if(ngtcp2_crypto_ossl_configure_client_session(ssl) != 0) {
log_err("ngtcp2_crypto_ossl_configure_client_session failed");
exit(1);
}
#endif
set_app_data(ssl, data);
SSL_set_connect_state(ssl);
if(!SSL_set_fd(ssl, data->fd)) {
log_crypto_err("Could not SSL_set_fd");
exit(1);
}
#ifndef USE_NGTCP2_CRYPTO_OSSL
if((data->quic_version & 0xff000000) == 0xff000000) {
SSL_set_quic_use_legacy_codepoint(ssl, 1);
} else {
SSL_set_quic_use_legacy_codepoint(ssl, 0);
}
#endif
SSL_set_alpn_protos(ssl, (const unsigned char *)"\x03""doq", 4);
/* send the SNI host name */
SSL_set_tlsext_host_name(ssl, "localhost");
@@ -2072,7 +2098,11 @@ early_data_setup_session(struct doq_client_data* data)
SSL_SESSION_free(session);
return 0;
}
#ifdef USE_NGTCP2_CRYPTO_OSSL
SSL_set_quic_tls_early_data_enabled(data->ssl, 1);
#else
SSL_set_quic_early_data_enabled(data->ssl, 1);
#endif
SSL_SESSION_free(session);
return 1;
}
@@ -2221,6 +2251,15 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
data = calloc(1, sizeof(*data));
if(!data) fatal_exit("calloc failed: out of memory");
data->base = base;
#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)
fatal_exit("ngtcp2_crypto_oss_init failed");
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
if(ngtcp2_crypto_quictls_init() != 0)
fatal_exit("ngtcp2_crypto_quictls_init failed");
#endif
data->rnd = ub_initstate(NULL);
if(!data->rnd) fatal_exit("ub_initstate failed: out of memory");
data->svr = svr;
@@ -2255,7 +2294,11 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
SSL_CTX_sess_set_new_cb(data->ctx, new_session_cb);
}
data->ssl = ssl_client_setup(data);
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_conn_set_tls_native_handle(data->conn, data->ossl_ctx);
#else
ngtcp2_conn_set_tls_native_handle(data->conn, data->ssl);
#endif
if(data->early_data_enabled)
early_data_setup(data);
@@ -2301,8 +2344,14 @@ delete_doq_client_data(struct doq_client_data* data)
}
}
#endif
ngtcp2_conn_del(data->conn);
/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
* because the ngtcp2 conn is deleted. */
SSL_set_app_data(data->ssl, NULL);
SSL_free(data->ssl);
#ifdef USE_NGTCP2_CRYPTO_OSSL
ngtcp2_crypto_ossl_ctx_del(data->ossl_ctx);
#endif
ngtcp2_conn_del(data->conn);
sldns_buffer_free(data->pkt_buf);
sldns_buffer_free(data->blocked_pkt);
if(data->fd != -1)
+36 -13
View File
@@ -188,6 +188,22 @@ delete_replay_answer(struct replay_answer* a)
free(a);
}
/** Log the packet for a reply_packet from testpkts. */
static void
log_testpkt_reply_pkt(const char* txt, struct reply_packet* reppkt)
{
if(!reppkt) {
log_info("%s <null>", txt);
return;
}
if(reppkt->reply_from_hex) {
log_pkt(txt, sldns_buffer_begin(reppkt->reply_from_hex),
sldns_buffer_limit(reppkt->reply_from_hex));
return;
}
log_pkt(txt, reppkt->reply_pkt, reppkt->reply_len);
}
/**
* return: true if pending query matches the now event.
*/
@@ -240,9 +256,8 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
p->start_step, p->end_step, (*entry)->lineno);
if(p->addrlen != 0)
log_addr(0, "matched ip", &p->addr, p->addrlen);
log_pkt("matched pkt: ",
(*entry)->reply_list->reply_pkt,
(*entry)->reply_list->reply_len);
log_testpkt_reply_pkt("matched pkt: ",
(*entry)->reply_list);
return 1;
}
p = p->next_range;
@@ -330,7 +345,7 @@ fill_buffer_with_reply(sldns_buffer* buffer, struct entry* entry, uint8_t* q,
while(reppkt && i--)
reppkt = reppkt->next;
if(!reppkt) fatal_exit("extra packet read from TCP stream but none is available");
log_pkt("extra_packet ", reppkt->reply_pkt, reppkt->reply_len);
log_testpkt_reply_pkt("extra packet ", reppkt);
}
if(reppkt->reply_from_hex) {
c = sldns_buffer_begin(reppkt->reply_from_hex);
@@ -462,8 +477,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
repinfo.c->type = comm_udp;
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
log_info("testbound: incoming QUERY");
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
todo->match->reply_list->reply_len);
log_testpkt_reply_pkt("query pkt ", todo->match->reply_list);
/* call the callback for incoming queries */
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
NETEVENT_NOERROR, &repinfo)) {
@@ -900,8 +914,10 @@ run_scenario(struct replay_runtime* runtime)
runtime->now->evt_type == repevt_front_reply) {
answer_check_it(runtime);
advance_moment(runtime);
} else if(pending_matches_range(runtime, &entry, &pending)) {
answer_callback_from_entry(runtime, entry, pending);
} else if(runtime->now && pending_matches_range(runtime,
&entry, &pending)) {
if(entry)
answer_callback_from_entry(runtime, entry, pending);
} else {
do_moment_and_advance(runtime);
}
@@ -1118,7 +1134,8 @@ outside_network_create(struct comm_base* base, size_t bufsize,
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect),
int ATTR_UNUSED(max_reuse_tcp_queries), int ATTR_UNUSED(tcp_reuse_timeout),
int ATTR_UNUSED(tcp_auth_query_timeout))
int ATTR_UNUSED(tcp_auth_query_timeout), const char** ATTR_UNUSED(dist),
const char** ATTR_UNUSED(dist_tsig), int ATTR_UNUSED(num_dist))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
@@ -1254,7 +1271,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec,
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
int tcp_upstream, int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen,
struct module_qstate* qstate, comm_point_callback_type* callback,
@@ -1274,7 +1291,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
(flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":"");
/* create packet with EDNS */
pend->buffer = sldns_buffer_new(512);
pend->buffer = sldns_buffer_new(4096);
log_assert(pend->buffer);
sldns_buffer_write_u16(pend->buffer, 0); /* id */
sldns_buffer_write_u16(pend->buffer, flags);
@@ -1334,7 +1351,13 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
edns.opt_list_in = NULL;
edns.opt_list_out = per_upstream_opt_list;
edns.opt_list_inplace_cb_out = NULL;
attach_edns_record(pend->buffer, &edns);
if(sldns_buffer_capacity(pend->buffer) >=
sldns_buffer_limit(pend->buffer)
+calc_edns_field_size(&edns)) {
attach_edns_record(pend->buffer, &edns);
} else {
verbose(VERB_ALGO, "edns field too large to fit");
}
}
memcpy(&pend->addr, addr, addrlen);
pend->addrlen = addrlen;
@@ -1345,7 +1368,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
pend->callback = callback;
pend->cb_arg = callback_arg;
pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
pend->transport = transport_udp; /* pretend UDP */
pend->transport = tcp_upstream?transport_tcp:transport_udp;
pend->pkt = NULL;
pend->runtime = runtime;
pend->serviced = 1;
+1 -1
View File
@@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert)
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
if (!SSL_CTX_set_ecdh_auto(ctx,1))
if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
#elif defined(USE_ECDSA) && HAVE_DECL_SSL_CTX_SET_TMP_ECDH
if(1) {
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
if (!ecdh) {
+3 -1
View File
@@ -795,7 +795,7 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
char buf[10240];
char* at = *text;
size_t len = macro_length(at);
int dofunc = 0;
int tries = 0, dofunc = 0;
char* arithstart = NULL;
if(len >= sizeof(buf))
return NULL; /* too long */
@@ -834,6 +834,8 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
/* actual macro text expansion */
while(*at) {
size_t remain = sizeof(buf)-strlen(buf);
if(tries++ > 10000)
return NULL; /* looks like got into an infinite loop, bail out */
if(strncmp(at, "${", 2) == 0) {
at = do_macro_recursion(store, runtime, at, remain);
} else if(*at == '$') {
+135 -15
View File
@@ -293,6 +293,16 @@ setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
fclose(cfg);
return;
}
if(strncmp(parse, "fake-sha1: yes", 14) == 0) {
/* Allow the use of SHA1 signatures for the test,
* in case that OpenSSL disallows use of RSASHA1
* with rh-allow-sha1-signatures disabled. */
#ifndef UB_ON_WINDOWS
setenv("OPENSSL_ENABLE_SHA1_SIGNATURES", "1", 0);
#else
_putenv("OPENSSL_ENABLE_SHA1_SIGNATURES=1");
#endif
}
fputs(line, cfg);
}
fatal_exit("No CONFIG_END in input file");
@@ -333,6 +343,35 @@ static void remove_configfile(void)
cfgfiles = NULL;
}
/** perform the playback on the playback_file with the args. */
static int
perform_playback(char* playback_file, int pass_argc, char** pass_argv)
{
struct replay_scenario* scen = NULL;
int c, res;
/* setup test environment */
scen = setup_playback(playback_file, &pass_argc, pass_argv);
/* init fake event backend */
fake_event_init(scen);
pass_argv[pass_argc] = NULL;
echo_cmdline(pass_argc, pass_argv);
/* run the normal daemon */
res = daemon_main(pass_argc, pass_argv);
fake_event_cleanup();
for(c=1; c<pass_argc; c++)
free(pass_argv[c]);
return res;
}
/* For fuzzing the main routine is replaced with
* LLVMFuzzerTestOneInput. */
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#define main dummy_main
#endif
/**
* Main fake event test program. Setup, teardown and report errors.
* @param argc: arg count.
@@ -348,7 +387,6 @@ main(int argc, char* argv[])
char* playback_file = NULL;
int init_optind = optind;
char* init_optarg = optarg;
struct replay_scenario* scen = NULL;
/* we do not want the test to depend on the timezone */
(void)putenv("TZ=UTC");
@@ -456,24 +494,11 @@ main(int argc, char* argv[])
if(atexit(&remove_configfile) != 0)
fatal_exit("atexit() failed: %s", strerror(errno));
/* setup test environment */
scen = setup_playback(playback_file, &pass_argc, pass_argv);
/* init fake event backend */
fake_event_init(scen);
pass_argv[pass_argc] = NULL;
echo_cmdline(pass_argc, pass_argv);
/* reset getopt processing */
optind = init_optind;
optarg = init_optarg;
/* run the normal daemon */
res = daemon_main(pass_argc, pass_argv);
fake_event_cleanup();
for(c=1; c<pass_argc; c++)
free(pass_argv[c]);
res = perform_playback(playback_file, pass_argc, pass_argv);
if(res == 0) {
log_info("Testbound Exit Success\n");
/* remove configfile from here, the atexit() is for when
@@ -493,6 +518,101 @@ main(int argc, char* argv[])
return res;
}
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
static int delete_file(const char *pathname) {
int ret = unlink(pathname);
free((void *)pathname);
return ret;
}
static char *buf_to_file(const uint8_t *buf, size_t size) {
int fd;
size_t pos;
char *pathname = strdup("/tmp/fuzz-XXXXXX");
if (pathname == NULL)
return NULL;
fd = mkstemp(pathname);
if (fd == -1) {
log_err("mkstemp of file %s failed: %s", pathname, strerror(errno));
free(pathname);
return NULL;
}
pos = 0;
while (pos < size) {
int nbytes = write(fd, &buf[pos], size - pos);
if (nbytes <= 0) {
if (nbytes == -1 && errno == EINTR)
continue;
log_err("write to file %s failed: %s", pathname, strerror(errno));
goto err;
}
pos += nbytes;
}
if (close(fd) == -1) {
log_err("close of file %s failed: %s", pathname, strerror(errno));
goto err;
}
return pathname;
err:
delete_file(pathname);
return NULL;
}
/* based on main() above, but with: hard-coded passed args, file created from fuzz input */
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
int c, res;
int pass_argc = 0;
char* pass_argv[MAXARG];
char* playback_file = NULL;
/* we do not want the test to depend on the timezone */
(void)putenv("TZ=UTC");
memset(pass_argv, 0, sizeof(pass_argv));
#ifdef HAVE_SYSTEMD
/* we do not want the test to use systemd daemon startup notification*/
(void)unsetenv("NOTIFY_SOCKET");
#endif /* HAVE_SYSTEMD */
checklock_start();
log_init(NULL, 0, NULL);
/* determine commandline options for the daemon */
pass_argc = 1;
pass_argv[0] = "unbound";
add_opts("-d", &pass_argc, pass_argv);
playback_file = buf_to_file(Data, Size);
if (playback_file) {
log_info("Start of %s testbound program.", PACKAGE_STRING);
res = perform_playback(playback_file, pass_argc, pass_argv);
if(res == 0) {
log_info("Testbound Exit Success\n");
/* remove configfile from here, the atexit() is for when
* there is a crash to remove the tmpdir file.
* This one removes the file while alloc and log locks are
* still valid, and can be logged (for memory calculation),
* it leaves the ptr NULL so the atexit does nothing. */
remove_configfile();
#ifdef HAVE_PTHREAD
/* dlopen frees its thread state (dlopen of gost engine) */
pthread_exit(NULL);
#endif
}
delete_file(playback_file);
}
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
return res;
}
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
/* fake remote control */
struct listen_port* daemon_remote_open_ports(struct config_file*
ATTR_UNUSED(cfg))
+19 -2
View File
@@ -923,10 +923,14 @@ pkt_snip_edns_option(uint8_t* pkt, size_t len, sldns_edns_option code,
if(!pkt_find_edns_opt(&opt_position, &remaining)) return 0;
if(remaining < 8) return -1; /* malformed */
rdlen = sldns_read_uint16(opt_position+6);
if(remaining < ((size_t)rdlen)+8)
return -1; /* malformed */
rdata = opt_position + 8;
while(rdlen > 0) {
if(rdlen < 4) return -1; /* malformed */
optlen = sldns_read_uint16(rdata+2);
if((size_t)rdlen < 4+((size_t)optlen))
return -1; /* malformed */
if(sldns_read_uint16(rdata) == code) {
/* save data to buf for caller inspection */
memmove(buf, rdata+4, optlen);
@@ -1134,8 +1138,9 @@ static void lowercase_dname(uint8_t** p, size_t* remain)
while(**p != 0) {
/* compressed? */
if((**p & 0xc0) == 0xc0) {
*p += 2;
*remain -= 2;
llen = *remain < 2 ? (unsigned int)*remain : 2;
*p += llen;
*remain -= llen;
return;
}
llen = (unsigned int)**p;
@@ -1178,6 +1183,12 @@ static void lowercase_rdata(uint8_t** p, size_t* remain,
uint8_t len;
if(rdataremain == 0) return;
len = **p;
if(rdataremain < ((size_t)len)+1) {
/* malformed LDNS_RDF_TYPE_STR, skip remainder */
*p += rdataremain;
*remain -= rdatalen;
return;
}
*p += len+1;
rdataremain -= len+1;
} else {
@@ -1207,6 +1218,12 @@ static void lowercase_rdata(uint8_t** p, size_t* remain,
break;
default: error("bad rdf type in lowercase %d", (int)f);
}
if (rdataremain < (size_t)len) {
/* malformed RDF, skip remainder */
*p += rdataremain;
*remain -= rdatalen;
return;
}
*p += len;
rdataremain -= len;
}
+1
View File
@@ -670,6 +670,7 @@ authtest_addzone(struct auth_zones* az, const char* name, char* fname)
auth_zone_set_zonefile(z, fname);
z->for_upstream = 1;
cfg = config_create();
config_auto_slab_values(cfg);
free(cfg->chrootdir);
cfg->chrootdir = NULL;
+277
View File
@@ -45,6 +45,7 @@
#include "util/data/dname.h"
#include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"
/** put dname into buffer */
static sldns_buffer*
@@ -476,6 +477,23 @@ dname_test_removelabel(void)
unit_assert( l == 1 );
}
/** test dname_remove_label_limit_len */
static void
dname_test_removelabellimitlen(void)
{
uint8_t* orig = (uint8_t*)"\007example\003com\000";
uint8_t* n = orig;
size_t l = 13;
size_t lenlimit = 5; /* com.*/
unit_show_func("util/data/dname.c", "dname_remove_label_limit_len");
unit_assert(dname_remove_label_limit_len(&n, &l, lenlimit) == 1);
unit_assert( n == orig+8 );
unit_assert( l == 5 );
unit_assert(dname_remove_label_limit_len(&n, &l, lenlimit) == 0);
unit_assert( n == orig+8 );
unit_assert( l == 5 );
}
/** test dname_signame_label_count */
static void
dname_test_sigcount(void)
@@ -859,6 +877,262 @@ dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
sldns_buffer_flip(boundbuf);
}
/* Test strings for the test_long_names test. */
/* Each label begins with the length of the label including the length octet. */
char desc_1[] = "Domain is 1 octet too long.";
uint8_t wire_dom_1[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.0007ab. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x06, 0x30, 0x30, 0x30, 0x37, 0x61, 0x62, 0x00
};
char desc_2[] = "Domain has the maximum allowed length (255).";
uint8_t wire_dom_2[] = { /* Good: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.00076a. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Good: */ 0x05, 0x30, 0x30, 0x30, 0x36, 0x61, 0x00
};
char desc_3[] = "Domain has a length one label in the 255th position for a total of 257.";
uint8_t wire_dom_3[] = { /* Bad: Domain: (8x(0031abcdefghijklmnopqrstuvwxyz.0006ab.1. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x05, 0x30, 0x30, 0x30, 0x36, 0x61, 0x01, 0x32, 0x00
};
char desc_4[] = "Domain has the maximum allowed length (255).";
uint8_t wire_dom_4[] = { /* Good: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Good: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x00
};
char desc_5[] = "Domain has a maximum length label (63) in the 255th position.";
uint8_t wire_dom_5[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03.65abc...zab...zab...ghi. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x3f, 0x36,
0x33, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00
};
char desc_6[] = "Domain has a too long label (65) in the 255th position.";
uint8_t wire_dom_6[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03.66abc...zab...zab...ijk. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x41, 0x36,
0x36, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x00
};
char desc_7[] = "Domain has a too long label (65) in the 187th position.";
uint8_t wire_dom_7[] = { /* Bad: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.65abc..zab...zab...ijk. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
/* Bad: */ 0x41, 0x36,
0x36, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x00
};
char desc_8[] = "Domains has the maximum allowed length and ends with a maximum length label.";
uint8_t wire_dom_8[] = { /* Good: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.0004.0064abc..zab...zabcdefg. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x03, 0x30, 0x30, 0x34 ,/* Good: */ 0x3f, 0x30,
0x30, 0x36, 0x34, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x00
};
char desc_9[] = "Domains has 254 octets, one less than the maximum allowed length.";
uint8_t wire_dom_9[] = { /* Good: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.0004.0064abc..zab...zabcdef. */
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x03, 0x30, 0x30, 0x34 ,/* Good: */ 0x3e, 0x30,
0x30, 0x35, 0x34, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63,
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x00
};
/** Test dname to string with long domain names. */
static void
test_long_names(void)
{
/* Set to 1 for verbose output, 0 turns it off. */
int verbtest = 0;
uint8_t* wire_doms[] = {wire_dom_1, wire_dom_2, wire_dom_3,
wire_dom_4, wire_dom_5, wire_dom_6, wire_dom_7, wire_dom_8,
wire_dom_9, 0};
char* descs[] = {desc_1, desc_2, desc_3, desc_4, desc_5, desc_6,
desc_7, desc_8, desc_9, 0};
int n;
char string_domain[260];
uint8_t** wd = wire_doms;
int di = 0;
int skip = 5; /* 0..6 */
while (*wd) {
if(verbtest)
printf("Test: %s\n", descs[di++]);
memset(string_domain, 0xff, sizeof(string_domain));
dname_str(*wd, string_domain);
for (n = 0 ; n < (int)sizeof(string_domain); ++n) {
if ((uint8_t)string_domain[n] == 0xff)
break;
}
if(verbtest)
printf("dname_str: L=%d, S=Skipping %d labels...%s\n",
n, skip, string_domain + skip*31);
unit_assert(n <= 255);
memset(string_domain, 0xff, sizeof(string_domain));
sldns_wire2str_dname_buf(*wd,
strlen((char*)*wd)+1 /* strlen works with these test strings */,
string_domain,
255 /* for comparable result to dname_str */ );
for (n = 0 ; n < (int)sizeof(string_domain); ++n) {
if ((uint8_t)string_domain[n] == 0xff)
break;
}
if(verbtest)
printf("sldns_wire2str_dname_buf: L=%d, S=Skipping %d labels...%s\n",
n, skip, string_domain + skip*31);
unit_assert(n <= 255);
++wd;
}
}
static void
dname_test_str(sldns_buffer* buff)
{
@@ -1002,6 +1276,8 @@ dname_test_str(sldns_buffer* buff)
unit_assert(0);
}
}
test_long_names();
}
void dname_test(void)
@@ -1024,6 +1300,7 @@ void dname_test(void)
dname_test_subdomain();
dname_test_isroot();
dname_test_removelabel();
dname_test_removelabellimitlen();
dname_test_sigcount();
dname_test_iswild();
dname_test_canoncmp();

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