Compare commits

...
Author SHA1 Message Date
W.C.A. Wijngaards d67ca6bfed Disallow $INCLUDE for secondary zones. This matches the change
in the code repository, and is meant for after merge of the
simdzone change.
2026-06-16 09:32:24 +02:00
W.C.A. Wijngaards 9735e34f89 - rpz-zone-load, fix comment for the rrset_insert_rr_wol function. 2026-01-28 14:35:40 +01:00
W.C.A. Wijngaards ac9ca8c5af - rpz-zone-load, fix signedness of name character comparisons. 2026-01-28 14:13:13 +01:00
W.C.A. Wijngaards 1d18f34c79 - rpz-zone-load, handle alloc failures from dname_rdata_to_str. 2026-01-28 13:58:09 +01:00
W.C.A. Wijngaards 17f64b818e - rpz-zone-load, optimise canonical name compare tolower calls. 2026-01-28 12:47:03 +01:00
W.C.A. Wijngaards 9cf1344960 Merge branch 'master' into rpz-zone-load 2026-01-28 11:50:45 +01:00
W.C.A. Wijngaards 098200ba5a - rpz-zone-load, optimise rpz_insert_local_zones_trigger to remove second
local zones tree lookup for non local data cases.
2026-01-28 11:48:53 +01:00
W.C.A. Wijngaards daa016e3e4 - Add test for allow-notify with a host name. 2026-01-27 13:49:33 +01:00
W.C.A. Wijngaards 039f69e735 - Fix to not skip allow-notify hostname lookups when there are only
urls.
2026-01-26 16:16:38 +01:00
W.C.A. Wijngaards b39009e487 Merge branch 'master' of github.com:NLnetLabs/unbound 2026-01-26 15:17:26 +01:00
W.C.A. Wijngaards 933769ee73 - Fix that allow-notify entries with hostnames are copied after IPv4
and IPv6 lookup.
2026-01-26 15:16:43 +01:00
Yorgos Thessalonikefs 57bff79627 - Update generated man pages. 2026-01-23 18:04:25 +01:00
Yorgos Thessalonikefs 1b5559d534 Changelog entry for #1396:
- Merge #1396: Log Linux thread ID.
- On Linux systems log the system-wide unique thread ID instead of
  Unbound's internal thread counter.
- Introduce the 'log-thread-id' configuration option to manage logging
  the system-wide Linux thread ID for easier debugging with system
  tools.
2026-01-23 17:46:14 +01:00
Yorgos ThessalonikefsandGitHub 9d271c5343 Merge pull request #1396 from NLnetLabs/features/thread-id 2026-01-23 17:42:30 +01:00
Yorgos Thessalonikefs 74cc49e6c4 - Introduce the 'log-thread-id' configuration option to manage logging
the system-wide Linux thread ID for easier debugging with system
  tools.
2026-01-23 17:15:14 +01:00
Yorgos Thessalonikefs d414ebf0c7 - On Linux systems log the system-wide unique thread ID instead of
Unbound's internal thread counter.
2026-01-23 17:08:55 +01:00
W.C.A. Wijngaards 08a2734e91 - rpz-zone-load, rpz load does not pass unwanted string, and rr data. 2026-01-23 16:40:52 +01:00
W.C.A. Wijngaards 14264c9ed9 - rpz-zone-load, authzone changes to not spool data into rr from simdzone
rdata, for rpz load.
2026-01-23 15:21:26 +01:00
W.C.A. Wijngaards 76f0bb8ba2 - simdzone-zone-load, use_simdzone variable to switch sldns and simdzone parse. 2026-01-23 11:33:27 +01:00
W.C.A. Wijngaards 051fef8456 - simdzone-zone-load, update simdzone version. 2026-01-22 14:46:07 +01:00
W.C.A. Wijngaards b8c96862cb Merge branch 'master' into simdzone-zone-load 2026-01-22 14:20:08 +01:00
W.C.A. Wijngaards 9b123d1b78 - Fix http test tool petal to not print errors when there is no
error.
2026-01-22 14:19:35 +01:00
W.C.A. Wijngaards 37b71261a2 - Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
and max_global_quota options.
2026-01-22 09:42:56 +01:00
W.C.A. Wijngaards d99a4375bf Merge branch 'master' into simdzone-zone-load 2026-01-21 14:55:50 +01:00
W.C.A. Wijngaards 4426db4d3d - Merge #1388: QNX Porting support for unbound. 2026-01-21 13:13:01 +01:00
nnarayanamurthyandGitHub fe10bc7682 QNX Porting support for unbound branch-1.24.1 (#1388)
* qnx Porting support for version release-1.24.1

* updating __QNXNTO__ with __QNX__
2026-01-21 13:12:13 +01:00
W.C.A. Wijngaards 67d2eae28c - Merge #1392: Include "V" (version) option in synopsis. 2026-01-19 09:09:47 +01:00
David H. GutteridgeandGitHub 9010a7075e Include "V" (version) option in synopsis (#1392) 2026-01-19 09:09:12 +01:00
W.C.A. Wijngaards 5582fbc443 - simdzone-zone-load, update simdzone version. 2026-01-16 14:08:34 +01:00
W.C.A. Wijngaards a72374000e - simdzone-zone-load, fix to use chrootdir adjustment when dealing with
$INCLUDE in a zonefile read.
2026-01-16 13:46:03 +01:00
W.C.A. Wijngaards cea8f493b2 - simdzone-zone-load, update simdzone version. 2026-01-16 13:43:56 +01:00
W.C.A. Wijngaards 285b5aa461 - sidzone-zone-load, set no_includes option for http transferred files. 2026-01-16 13:43:16 +01:00
W.C.A. Wijngaards cc6dbc9f38 - Fix documentation for requestlist.overwritten and
requestlist.exceeded, it explains which query was dropped.
2026-01-15 09:35:04 +01:00
W.C.A. Wijngaards a50dd4e407 - simdzone-zone-load, implement that the auth http transferred zone files are
parsed with simdzone parse from callback.
2026-01-13 16:25:46 +01:00
W.C.A. Wijngaards 966801a984 - simdzone-zone-load, move sldns auth https download parse to another routine. 2026-01-13 15:35:17 +01:00
W.C.A. Wijngaards 6084171db7 Merge branch 'master' into simdzone-zone-load 2026-01-13 15:21:58 +01:00
W.C.A. Wijngaards 4baa2ccc9c - simdzone-zone-load, update simdzone version. 2026-01-13 15:21:38 +01:00
W.C.A. Wijngaards 4198343dbe Compile fixup for #1381. 2026-01-08 14:19:06 +01:00
W.C.A. Wijngaards 08600d68e8 Changelog note for #1381, and man page explanation.
- Merge #1381: Do not initialize quic_table unless it is enabled.
2026-01-08 14:16:54 +01:00
Petr MenšíkandGitHub 18e098285e Do not initialize quic_table unless it is enabled (#1381)
* Do not initialize quic_table unless it is enabled

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

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

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

* Fix typo in logged function name
2026-01-08 14:12:32 +01:00
Yorgos Thessalonikefs f1b35bab4b Changelog entry for #1391:
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
  RFC5952.
2026-01-06 18:21:34 +01:00
Yorgos ThessalonikefsandGitHub 84ed77238d Merge pull request #1391 from GoetzGoerisch/docs
Fix documentation to adhere to RFC 5952
2026-01-06 18:19:47 +01:00
Goetz Goerisch adb0374a4d Fix documentation to adhere to RFC 5952
Update the text representations of IPv6 addresses.
2026-01-06 16:10:37 +01:00
W.C.A. Wijngaards b0b634558b - Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
  stub-no-cache option is set, it is not stored in cache due to
  the forward or stub option.
This has the changelog entry and test.
2026-01-06 09:33:00 +01:00
W.C.A. Wijngaards 8546247292 - Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
  stub-no-cache option is set, it is not stored in cache due to
  the forward or stub option.
2026-01-06 09:32:21 +01:00
Yorgos Thessalonikefs 44659cb3bf - Use the same EDE removal logic when encoding errors as when encoding
replies.
2025-12-31 16:22:15 +01:00
Yorgos Thessalonikefs a1ac2d0252 - Update the unbound-anchor man page to note write permissions of the
generated file if it is to be used with Unbound's
  auto-trust-anchor-file option.
2025-12-31 14:05:42 +01:00
Yorgos Thessalonikefs 5c7a26b615 - Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
categorization in the log output.
2025-12-30 13:15:37 +01:00
Yorgos Thessalonikefs 09d352b917 - More specific wording in the unbound.conf man page for stub-first
and forward-first options.
2025-12-24 14:57:44 +01:00
W.C.A. Wijngaards 0793bb9835 - simdzone-zone-load, fix makedist to make a directory in /tmp, so that
autoconf does not go up to the directory of the working copy for files.
2025-12-12 15:44:46 +01:00
W.C.A. Wijngaards 10b8398f02 - simdzone-zone-load, fix to have makedist remove unneeded simdzone autoconf
temporary files.
2025-12-12 14:03:35 +01:00
W.C.A. Wijngaards 797d9569c3 - simdzone-zone-load, fix to remove double checks for simdzone and its
configure script in configure.ac.
2025-12-12 13:35:38 +01:00
W.C.A. Wijngaards dfa358dc8d - simdzone-zone-load, remove config.h.in from the repository, it is generated
by autoreconf, since that has to be called to initialise the simdzone repo.
  Add config.h.in to gitignore.
2025-12-11 08:50:15 +01:00
W.C.A. Wijngaards 6dd48dadc9 - simdzone-zone-load, remove install-sh from the repository, the configure.ac
requires it, and it is pulled in with autoreconf -fi, the configure script
  checks and warns when it is missing, or if the simdzone module is missing.
  Add install-sh to gitignore.
2025-12-10 16:48:40 +01:00
W.C.A. Wijngaards d34733a69b - simdzone-zone-load, stat the zonefile, instead of opening it, and then
clear the data.
2025-12-10 16:27:33 +01:00
W.C.A. Wijngaards e1faea02de - simdzone-zone-load, use cfg for _state struct in az_parse_file_simdzone
function.
2025-12-10 16:12:21 +01:00
W.C.A. Wijngaards fdd0ada3c9 - simdzone-zone-load, document to get git submodule and autoreconf,
and add generated files to gitignore.
2025-12-10 16:09:35 +01:00
W.C.A. Wijngaards ed3606d99d - simdzone-zone-load, remove configure, aclocal.m4, ltmain.sh, config.guess,
and config.sub from the repository. Because of the simdzone submodule,
  the repository needs to have autoreconf -fi for it.
2025-12-10 16:00:40 +01:00
W.C.A. Wijngaards b9df07d8bb - simdzone-zone-load, fix return value and variable name for rdata. 2025-12-10 11:56:40 +01:00
W.C.A. Wijngaards ea9c957213 - simdzone-zone-load, remove copy of rdata from simdzone accept path for
ordinary zone read.
2025-12-10 11:39:24 +01:00
W.C.A. Wijngaards 828b05c956 - simdzone-zone-load, fix doc unit test to omit simdzone source code warnings. 2025-12-08 15:19:42 +01:00
W.C.A. Wijngaards 3b2a2e2440 Merge branch 'master' into simdzone-zone-load 2025-12-08 14:59:56 +01:00
W.C.A. Wijngaards 0557fdb940 - simdzone-zone-load, use simdzone for auth-zone and rpz zone read.
Fix unittest for ZONEMD to have correct digest length for test entry.
2025-12-08 14:51:37 +01:00
W.C.A. Wijngaards c0522043f0 - Fix http2 drop handling to clear the postpone_drop state so that
other streams on the http2 session are not affected by a drop,
  and can clean up properly if also dropped. Fix http2 send reply
  so that when there is a send failure is does not recurse into
  the mesh functions and also does not drop the connection due to
  the condition of one stream.
2025-12-03 14:41:10 +01:00
W.C.A. Wijngaards b858801feb - Fix to remove http2 stream mesh state when mesh new request is
dropping the new request.
2025-12-02 15:31:53 +01:00
W.C.A. Wijngaards 588db09928 - Fix header comment about EDE reference in validator/val_sigcrypt.h. 2025-12-01 16:04:41 +01:00
W.C.A. Wijngaards 5c66c48a1b - Fix to add EDNS CO flag to testbound and debug message log. 2025-12-01 15:29:41 +01:00
Yorgos Thessalonikefs 83336477c6 - For #1375, there is no DNSTAP environment if it wasn't configured. 2025-11-28 15:20:21 +01:00
Yorgos Thessalonikefs e3e5eb66cf - Tag for 1.24.2 release.
The repository continues with version 1.24.3.
2025-11-26 13:54:25 +01:00
Yorgos Thessalonikefs 00d3b97dbb Merge branch 'branch-1.24.2' 2025-11-26 13:50:49 +01:00
W.C.A. Wijngaards 0f43b0ea6c Changelog note for #1375, and lock for lockchecks and ifdef for compile fix.
- Merge #1375: Copy DNSTAP changes from daemon to workers after
  fast_reload.
2025-11-13 15:45:27 +01:00
smeddlepandGitHub e6d92f458f Copy DNSTAP changes from daemon to workers after fast_reload (#1375)
- On fast_reload, the identity and version strings are always freed and
  reallocated as part of dt_apply_cfg(). Add fr_worker_pickup_dnstap_changes()
  to copy any changes from daemon to workers.
2025-11-13 15:42:44 +01:00
W.C.A. Wijngaards a31b9d50e2 Changelog note for #1374
- Merge #1374: Mesh reply counters.
  This adds the statistics num.queries.replyaddr_limit and
  requestlist.current.replies.
2025-11-13 09:34:45 +01:00
Robert EdmondsandGitHub fceb4e8585 Mesh reply counters (#1374)
* Statistics counter for number of queries dropped by limit on reply addresses

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

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

* Statistics counter for number of mesh reply entries

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

This commit basically exports the mesh_area's internal counter
`num_reply_addrs` as "threadX.requestlist.current.replies" /
"total.requestlist.current.replies".
2025-11-13 09:33:05 +01:00
W.C.A. Wijngaards 98f4257890 - iana portlist updated. 2025-11-12 11:49:21 +01:00
W.C.A. Wijngaards 0a15118aff - Fix that when discard timeout drops packet, they are accounted as
less reply addresses in use in the mesh area.
2025-11-12 11:49:04 +01:00
W.C.A. Wijngaards e887a79a92 - Fix configure test for nonstring attribute so that it does not
accept when the compiler prints a warning about an unknown
  attribute.
2025-11-06 15:03:17 +01:00
W.C.A. Wijngaards f9b9050ab8 - Fix configure test for noreturn attribute so it compiles without
warning.
2025-11-06 15:00:08 +01:00
W.C.A. Wijngaards 94735384fd - Fix add comment to worker_handle_request function that explain it. 2025-11-06 14:32:56 +01:00
W.C.A. Wijngaards 5dab0609e5 - Fix dns64 log output to log the default instead of a null string. 2025-11-04 10:19:03 +01:00
Yorgos Thessalonikefs 024c921dbf - Fix #1366: Infra cache does not work correctly for NAT64, by
moving the NAT64 synthesis from the iterator when selecting a target
  address, to the delegation point itself when adding target
  addresses.
2025-11-01 15:10:27 +01:00
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 1cb9595a42 - Update the unbound.conf online man page link and some text
reformatting in README.md.
2025-10-20 14:34:40 +02:00
W.C.A. Wijngaards fbed3f30b2 - simdzone-zone-load, fix ci, enable platforms. 2025-10-17 16:44:03 +02:00
W.C.A. Wijngaards 2001d9fd15 - simdzone-zone-load, ci change. 2025-10-17 16:12:39 +02:00
W.C.A. Wijngaards b3be0fe943 - simdzone-zone-load, update simdzone version. 2025-10-17 16:11:24 +02:00
W.C.A. Wijngaards f04ee9767e - simdzone-zone-load, ci change. 2025-10-17 15:47:32 +02:00
W.C.A. Wijngaards 899ad30ad9 - simdzone-zone-load, ci change. 2025-10-17 15:20:40 +02:00
W.C.A. Wijngaards 6c501b9aa2 - simdzone-zone-load, ci change to fix windows. 2025-10-17 14:51:57 +02:00
W.C.A. Wijngaards 1cde7b2cbb - simdzone-zone-load, ci change. 2025-10-17 14:46:34 +02:00
W.C.A. Wijngaards 72e2e711c2 - simdzone-zone-load, ci change. 2025-10-17 14:41:17 +02:00
W.C.A. Wijngaards cdb4b7c3b0 - simdzone-zone-load, ci change. 2025-10-17 14:35:45 +02:00
W.C.A. Wijngaards e6657ae284 - simdzone-zone-load, ci change. 2025-10-17 14:33:58 +02:00
W.C.A. Wijngaards 9cf702f09f - simdzone-zone-load, ci change. 2025-10-17 14:32:45 +02:00
W.C.A. Wijngaards a0e33aa77d - simdzone-zone-load, ci change. 2025-10-17 14:19:30 +02:00
W.C.A. Wijngaards ded06e8b60 - simdzone-zone-load, ci change. 2025-10-17 14:16:21 +02:00
W.C.A. Wijngaards c0a06a5d24 - simdzone-zone-load, ci change. 2025-10-17 14:13:38 +02:00
W.C.A. Wijngaards 0fec18796a - simdzone-zone-load, ci change. 2025-10-17 14:11:53 +02:00
W.C.A. Wijngaards 990b27550e - simdzone-zone-load, ci change. 2025-10-17 13:26:09 +02:00
W.C.A. Wijngaards 7742270e39 - simdzone-zone-load, ci change. 2025-10-17 13:20:00 +02:00
W.C.A. Wijngaards 7021d91348 - simdzone-zone-load, ci change. 2025-10-17 13:13:19 +02:00
W.C.A. Wijngaards 150cf78ff2 - simdzone-zone-load, ci change. 2025-10-17 13:07:41 +02:00
W.C.A. Wijngaards 5e1a98027c - simdzone-zone-load, ci change. 2025-10-17 12:00:20 +02:00
W.C.A. Wijngaards 1140e39a78 - simdzone-zone-load, ci change, bsd works, moving to windows. 2025-10-17 11:52:41 +02:00
W.C.A. Wijngaards 13f7893805 - simdzone-zone-load, ci change. 2025-10-17 11:36:47 +02:00
W.C.A. Wijngaards 87f5a51618 - simdzone-zone-load, fix ci to include pkg-config to build configure,
since that is used for scanning for some of the dependencies.
2025-10-17 11:33:08 +02:00
W.C.A. Wijngaards 7672d9768b - simdzone-zone-load, ci change. 2025-10-17 09:57:35 +02:00
W.C.A. Wijngaards 5b46b5a972 - simdzone-zone-load, ci change. 2025-10-17 09:33:21 +02:00
W.C.A. Wijngaards 0827064414 - simdzone-zone-load, ci change. 2025-10-17 09:31:16 +02:00
W.C.A. Wijngaards 8284af6690 - simdzone-zone-load, ci change. 2025-10-17 09:30:17 +02:00
W.C.A. Wijngaards b89eed2902 - simdzone-zone-load, ci change. 2025-10-17 09:27:38 +02:00
W.C.A. Wijngaards 0dcaaf332d - simdzone-zone-load, ci change. 2025-10-17 09:24:34 +02:00
W.C.A. Wijngaards 2bd88e8f70 - simdzone-zone-load, fix ci with automakedir for windows and aclocal for bsd. 2025-10-16 16:27:08 +02:00
W.C.A. Wijngaards 5d9cc00f0a - simdzone-zone-load, fix ci, aclocal for windows, rm import file for bsd. 2025-10-16 16:06:31 +02:00
W.C.A. Wijngaards 2536b35d38 - simdzone-zone-load, fix ci, debug exclusions, lib path for automake
for windows, automake version for openbsd, aclocal for freebsd, netbsd
  and openbsd.
2025-10-16 15:44:30 +02:00
W.C.A. Wijngaards e312575b87 - simdzone-zone-load, fix ci, debug exclusions, separate lib path for
windows, aclocal and autoconf rerun for freebsd, openbsd, netbsd.
2025-10-16 15:31:22 +02:00
W.C.A. Wijngaards 5cd0c63593 - simdzone-zone-load, fix ci, autoreconf on windows. 2025-10-16 15:11:04 +02:00
W.C.A. Wijngaards 152e4e9e63 - simdzone-zone-load, fix for autoconf 2.72 and no Makefile in simdzone. 2025-10-16 15:01:07 +02:00
W.C.A. Wijngaards 30bc4e5bd7 - simdzone-zone-load, fix ci, ignore working ones, autoreconf on windows,
autoconf for freebsd, netbsd, openbsd.
2025-10-16 14:47:11 +02:00
W.C.A. Wijngaards e70edac733 - simdzone-zone-load, fix ci, ignore working ones, autoreconf for ios,
noconfirm for pacman on windows, autoconf-archive on freebsd, netbsd,
  openbsd, on openbsd also set the AUTOMAKE_VERSION.
2025-10-16 14:21:01 +02:00
W.C.A. Wijngaards 4e1f1db6c9 - simdzone-zone-load, fix ci, ignore working ones, install autotools for
windows, install automake for aclocal for freebsd, openbsd, netbsd,
  install autoconf for macos.
2025-10-16 14:02:43 +02:00
W.C.A. Wijngaards e45531d68f - simdzone-zone-load, update simdzone version. 2025-10-16 13:46:19 +02:00
W.C.A. Wijngaards 1a898ff9bc - simdzone-zone-load, fix makefile for disable-static build. 2025-10-16 12:55:59 +02:00
W.C.A. Wijngaards f190903e3b - simdzone-zone-load, add submodule to ci, and autoconf. 2025-10-16 12:28:48 +02:00
W.C.A. Wijngaards f6b4582eec Merge branch 'master' into simdzone-zone-load 2025-10-16 12:11:55 +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 3e71cf89cb - simdzone-zone-load, function call to simdzone and build fix for export.h. 2025-10-14 16:33:07 +02:00
W.C.A. Wijngaards 0929d0e2e4 - simdzone-zone-load, remove git information and autoconf temporaries from
release tarball.
2025-10-10 14:27:11 +02:00
W.C.A. Wijngaards 0c3b3d00f9 - simdzone-zone-load, update simdzone version. 2025-10-10 13:35:52 +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
W.C.A. Wijngaards 3bb8888e9e - simdzone-zone-load, fix dnstap/dnstap_config.h file from configure. 2025-10-09 14:39:39 +02:00
W.C.A. Wijngaards d8c5dbd6d8 - simdzone-zone-load, update simdzone version. 2025-10-08 17:15:38 +02:00
W.C.A. Wijngaards eef91474cd - simdzone-zone-load, fix makedist.sh cross compile for simdzone. 2025-10-08 17:12:45 +02:00
W.C.A. Wijngaards 426d56795f - simdzone-zone-load, configure checks that the simdzone directory has the
submodule files and prints an error otherwise.
2025-10-08 16:40:50 +02:00
W.C.A. Wijngaards 54ac686476 - simdzone-zone-load, update simdzone version. 2025-10-07 15:57:49 +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 09efa55f81 Merge branch 'master' into simdzone-zone-load 2025-10-02 15:36:31 +02:00
W.C.A. Wijngaards 3018f073d2 - simdzone-zone-load, update simdzone version. 2025-10-02 15:06:05 +02:00
W.C.A. Wijngaards a489ad2b4f - simdzone-zone-load, Add configure~ to gitignore. 2025-10-02 14:50:11 +02:00
W.C.A. Wijngaards a48d1a51b5 - simdzone-zone-load, update simdzone version. 2025-10-02 14:47:50 +02:00
W.C.A. Wijngaards 25e7e6ec72 - simdzone-zone-load, modify configure and Makefile to link with simdzone. 2025-10-02 14:33:31 +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 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 f2af8a3cd7 - simdzone-zone-load, add submodule with simdzone. 2025-09-18 13:49:05 +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 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
Yorgos Thessalonikefs d521135f66 Merge branch 'master' into features/no-ttl-zero-cacherep 2025-09-12 15:24:06 +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 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
159 changed files with 5034 additions and 55402 deletions
+53 -25
View File
@@ -12,6 +12,7 @@ jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: GCC on Linux
@@ -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
@@ -192,8 +175,38 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: false
submodules: recursive
persist-credentials: false
- name: test_windows_configure
if: ${{ matrix.test_windows == 'yes' }}
shell: bash
run: |
# The run starts with mount points for /c, /d, and
# C:/Program Files/Git on /
# C:/Program Files/Git/usr/bin on /bin
# C:/Users/RUNNER~1/AppData/Local/Temp on /tmp
echo "mount"
mount || echo "ignored"
echo "mount -o bind /c/msys64/usr /usr"
mount -o bind /c/msys64/usr /usr || echo "ignored"
# Now there is:
# C:/msys64 on /
# C:/msys64/usr/bin on /bin
# And those mount points should go away for the next 'run:' shell.
echo "mount"
mount || echo "ignored"
# probably installs to C:\msys64\usr\bin\bash.exe
echo "pacman -S --noconfirm autotools"
C:/msys64/usr/bin/pacman -S --noconfirm autotools
echo "rm -f aclocal.m4"
rm -f aclocal.m4
# The paths are mounted, so that /c/msys64/usr/share/autoconf-..,
# /c/msys64/usr/share/aclocal-.., /c/msys64/usr/share/automake-..
# are in /usr. Also for /usr/bin, autoreconf is from
# /c/msys64/usr/bin.
echo "autoreconf -fi"
#PATH="/c/msys64/usr/bin:$PATH" autoreconf -fi || echo "ignored"
autoreconf -fi
- name: test_windows
if: ${{ matrix.test_windows == 'yes' }}
env:
@@ -206,6 +219,9 @@ jobs:
cd ..
export prepath=`pwd`
echo prepath=${prepath}
# The mount should have the git directories.
echo "mount"
mount || echo "ignored"
echo "choco install winflexbison3"
choco install winflexbison3
echo 'LEX="win_flex"'
@@ -223,7 +239,7 @@ jobs:
#sed -e 's/use Pod::Usage//' < Configure > Configure.fix
# ./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl"
# pacman is used to install for msys2, with
# C:/msys64/usr/bin/pacman -S perl
# C:/msys64/usr/bin/pacman -S --noconfirm perl
echo "C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix=\""$prepath/openssl"\" PERL=\"C:/msys64/usr/bin/perl\""
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
# make the libs only, build faster
@@ -312,6 +328,8 @@ jobs:
./contrib/android/install_expat.sh
echo "::endgroup::"
echo "::group::configure"
echo "autoreconf -fi"
autoreconf -fi
echo "./configure ${CONFIG_OPTS}"
./configure ${CONFIG_OPTS}
echo "::endgroup::"
@@ -331,6 +349,7 @@ jobs:
IOS_CPU: ${{ matrix.IOS_CPU }}
run: |
#(already installed) ./contrib/ios/install_tools.sh
brew install autoconf automake libtool make
export AUTOTOOLS_BUILD="$(./config.guess)"
echo AUTOTOOLS_BUILD=${AUTOTOOLS_BUILD}
export IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
@@ -352,6 +371,8 @@ jobs:
./contrib/ios/install_expat.sh
echo "::endgroup::"
echo "::group::configure"
echo "autoreconf -fi"
autoreconf -fi
echo "./configure ${CONFIG_OPTS}"
./configure ${CONFIG_OPTS}
echo "::endgroup::"
@@ -377,10 +398,12 @@ jobs:
cpu_count: 2
run: |
set -e -x
if test "$CROSS_PLATFORM_OS" = "freebsd"; then sudo pkg install -y openssl libevent expat; fi
if test "$CROSS_PLATFORM_OS" = "openbsd"; then sudo pkg_add libevent; fi
if test "$CROSS_PLATFORM_OS" = "netbsd"; then sudo pkgin -y install libevent; fi
if test "$CROSS_PLATFORM_OS" = "freebsd"; then sudo pkg install -y autoconf automake libtool pkgconf openssl libevent expat; fi
if test "$CROSS_PLATFORM_OS" = "openbsd"; then sudo pkg_add autoconf-2.71 automake-1.16.5 libtool pkgconf libevent; export AUTOCONF_VERSION="2.71"; export AUTOMAKE_VERSION="1.16"; fi
if test "$CROSS_PLATFORM_OS" = "netbsd"; then sudo pkgin -y install autoconf automake libtool pkgconf libevent; export LDFLAGS="-Wl,--rpath=/usr/pkg/lib"; fi
echo "::group::configure"
rm -f aclocal.m4
autoreconf -fi
./configure ${{ matrix.cross_platform_config }}
echo "::endgroup::"
echo "::group::make"
@@ -394,10 +417,15 @@ jobs:
run: sudo apt-get install libevent-dev
- name: install expat
if: ${{ matrix.install_expat == 'yes' }}
run: brew install expat
run: |
brew install expat
brew install autoconf automake libtool make
- name: configure
if: ${{ matrix.config != 'no' }}
run: ./configure ${{ matrix.config }}
run: |
if test `uname` = "Linux"; then sudo apt-get install autoconf automake libtool make; fi
autoreconf -fi
./configure ${{ matrix.config }}
- name: make
if: ${{ matrix.make != 'no' }}
run: make
+6 -1
View File
@@ -14,9 +14,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
- name: install packages
run: sudo apt-get install autoconf automake libtool make
- name: configure
run: ./configure --enable-debug
run: |
autoreconf -fi
./configure --enable-debug
- name: make
run: make
- name: make test
+8
View File
@@ -3,11 +3,17 @@
/.libs/
/.source
/Makefile
/aclocal.m4
/autom4te.cache/
/config.guess
/config.h
/config.h.in
/config.h.in~
/config.log
/config.status
/config.sub
/configure
/configure~
/dnstap/dnstap_config.h
/dnscrypt/dnscrypt_config.h
/util/configlexer.c
@@ -22,8 +28,10 @@
/doc/unbound-host.1
/doc/unbound.8
/doc/unbound.conf.5
/install-sh
/libtool
/libunbound.la
/ltmain.sh
/_unbound.la
/smallapp/unbound-control-setup.sh
/unbound
+3
View File
@@ -0,0 +1,3 @@
[submodule "simdzone"]
path = simdzone
url = https://github.com/NLnetLabs/simdzone.git
+52 -23
View File
@@ -56,7 +56,7 @@ YACC=@YACC@
LEX=@LEX@
STRIP=@STRIP@
CC=@CC@
CPPFLAGS=-I. @CPPFLAGS@
CPPFLAGS=-I. @CPPFLAGS@ -Isimdzone/include -I@srcdir@/simdzone/include
PYTHON_CPPFLAGS=-I. -I$(srcdir) @PYTHON_CPPFLAGS@
CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
LDFLAGS=@LDFLAGS@
@@ -267,6 +267,7 @@ LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
libunbound/libworker.c
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
LIBUNBOUND_OBJ_LINK=$(LIBUNBOUND_OBJ) $(COMMON_OBJ_WITHOUT_UB_EVENT) $(SLDNS_OBJ) $(COMPAT_OBJ)
SIMDZONE_OBJ=@SIMDZONE_OBJ@
# win apps or "" if not on windows
WINAPPS=@WINAPPS@
@@ -364,19 +365,24 @@ longtest: tests
if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir $(srcdir)/testdata/*.rpl $(srcdir)/testdata/*.crpl testdata; cp $(srcdir)/testcode/*.sh testcode; if test ! -d util; then mkdir util; fi; cp $(srcdir)/util/iana_ports.inc util; fi
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
simdzone/libzone.la:
$(MAKE) -C simdzone
simdzone/include/zone/export.h: simdzone/libzone.la
lib: libunbound.la unbound.h
libunbound.la: $(LIBUNBOUND_OBJ_LINK)
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS)
libunbound.la: simdzone/libzone.la $(LIBUNBOUND_OBJ_LINK)
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) $(SIMDZONE_OBJ) -rpath $(libdir) $(SSLLIB) $(LIBS)
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
unbound-control$(EXEEXT): $(CONTROL_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(HOST_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
@@ -394,43 +400,43 @@ anchor-update$(EXEEXT): $(ANCHORUPD_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) libunbound.la $(LIBS)
unittest$(EXEEXT): $(UNITTEST_OBJ_LINK)
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
testbound$(EXEEXT): $(TESTBOUND_OBJ_LINK)
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ_LINK)
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
petal$(EXEEXT): $(PETAL_OBJ_LINK)
$(LINK) -o $@ $(PETAL_OBJ_LINK) $(SSLLIB) $(LIBS)
pktview$(EXEEXT): $(PKTVIEW_OBJ_LINK)
$(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
memstats$(EXEEXT): $(MEMSTATS_OBJ_LINK)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
doqclient$(EXEEXT): $(DOQCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
perf$(EXEEXT): $(PERF_OBJ_LINK)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
delayer$(EXEEXT): $(DELAYER_OBJ_LINK)
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
readzone$(EXEEXT): $(READZONE_OBJ_LINK)
$(LINK) -o $@ $(READZONE_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(READZONE_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
signit$(EXEEXT): testcode/signit.c
$(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ -o $@ testcode/signit.c $(LDFLAGS) -lldns $(SSLLIB) $(LIBS)
@@ -458,7 +464,7 @@ dnstap/dnstap.pb-c.h: dnstap/dnstap.pb-c.c
touch $@
unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK)
$(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h
@@ -522,7 +528,9 @@ util/configparser.c: $(srcdir)/util/configparser.y
util/configparser.h: util/configparser.c
touch $@
clean:
.PHONY: .clean .distclean .maintainer-clean .realclean .devclean
.clean:
rm -f *.o *.d *.lo *~ tags
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
rm -f $(ALL_SRC:.c=.lint)
@@ -530,19 +538,37 @@ clean:
rm -f libunbound.a
rm -rf autom4te.cache .libs build doc/html doc/xml
distclean: clean
.distclean: .clean
rm -f config.status config.log config.h
rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1
rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service
rm -f $(TEST_BIN)
rm -f Makefile
maintainer-clean: distclean
.maintainer-clean: .distclean
rm -f util/configlexer.c util/configparser.c util/configparser.h
realclean: maintainer-clean
.realclean: .maintainer-clean
rm -f configure config.h.in config.sub config.guess ltmain.sh aclocal.m4 libtool
.devclean: .realclean
rm -f config.h.in configure
clean: .clean
$(MAKE) -C simdzone clean
distclean: .distclean
$(MAKE) -C simdzone distclean
realclean: .realclean
$(MAKE) -C simdzone realclean
maintainer-clean: .maintainer-clean
$(MAKE) -C simdzone maintainer-clean
devclean: .devclean
$(MAKE) -C simdzone devclean
.SUFFIXES: .lint
.c.lint:
$(LINT) $(LINTFLAGS) -I. -I$(srcdir) $<
@@ -703,6 +729,7 @@ depend:
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
-e 's?$$(srcdir)/dynlibmod/dynlibmod.h?$$(DYNLIBMOD_HEADER)?g' \
-e 's?$$(srcdir)/simdzone/include/zone/export.h?simdzone/include/zone/export.h?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
@@ -1000,7 +1027,9 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
$(srcdir)/services/listen_dnsport.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \
$(srcdir)/simdzone/include/zone.h $(srcdir)/simdzone/include/zone/attributes.h \
simdzone/include/zone/export.h
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+1
View File
@@ -1,4 +1,5 @@
Unbound README
* From source repository: git submodule update --init && autoreconf -fi
* ./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
+20 -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
@@ -19,24 +19,35 @@ You can learn more about Unbound by reading our
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
installed.
If building from the repository source you also need flex and bison installed.
If building from the repository source, also init the git submodule and
create the configure script with:
```
git submodule update --init
autoreconf -fi
```
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
-9440
View File
File diff suppressed because it is too large Load Diff
+65 -12
View File
@@ -2,7 +2,12 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 48
# Version 51
# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
# a warning for 'unknown attribute' when nonstring is used.
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
# check by ACX_FUNC_MALLOC.
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
# 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 +76,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 +98,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 +497,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 +532,49 @@ 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_REQUIRE([ACX_CHECK_ERROR_FLAGS])
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ERRFLAG"
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
[ac_cv_c_nonstring_attribute=no
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"])
CFLAGS="$BAKCFLAGS"
])
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 +1240,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 +1250,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;
+6
View File
@@ -143,6 +143,12 @@ redis_connect(const char* host, int port, const char* path,
{
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) {
+7
View File
@@ -38,6 +38,9 @@
#ifndef UB_ON_WINDOWS
#include <sys/mman.h>
#endif
#ifdef __QNX__
#include "util/log.h"
#endif /* __QNX__ */
#define KEYSTREAM_ONLY
#include "chacha_private.h"
@@ -187,7 +190,11 @@ _rs_stir(void)
if(errno != ENOSYS ||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
#ifdef SIGKILL
#ifndef __QNX__
raise(SIGKILL);
#else /* !__QNX__ */
fatal_exit("failed to getentropy");
#endif /* __QNX__ */
#else
exit(9); /* windows */
#endif
+20
View File
@@ -29,7 +29,9 @@
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#ifndef __QNX__
#include <sys/syscall.h>
#endif /* !__QNX__ */
#ifdef SYS__sysctl
#include <linux/sysctl.h>
#endif
@@ -42,7 +44,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#ifndef __QNX__
#include <link.h>
#endif /* __QNX__ */
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
@@ -60,12 +64,14 @@
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
#endif
#ifndef __QNX__
#include <linux/types.h>
#include <linux/random.h>
#ifdef HAVE_GETAUXVAL
#include <sys/auxv.h>
#endif
#include <sys/vfs.h>
#endif /* !__QNX__ */
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
@@ -94,8 +100,10 @@ static int getentropy_urandom(void *buf, size_t len);
#ifdef SYS__sysctl
static int getentropy_sysctl(void *buf, size_t len);
#endif
#ifndef __QNX__
static int getentropy_fallback(void *buf, size_t len);
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
#endif /* !__QNX__ */
int
getentropy(void *buf, size_t len)
@@ -178,6 +186,7 @@ getentropy(void *buf, size_t len)
* sysctl ABI, or consider providing a new failsafe API which
* works in a chroot or when file descriptors are exhausted.
*/
#ifndef __QNX__
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
raise(SIGKILL);
@@ -185,6 +194,9 @@ getentropy(void *buf, size_t len)
ret = getentropy_fallback(buf, len);
if (ret != -1)
return (ret);
#else /* !__QNX__ */
fatal_exit("failed to read from /dev/urandom");
#endif /* __QNX__ */
errno = EIO;
return (ret);
@@ -214,7 +226,11 @@ getentropy_urandom(void *buf, size_t len)
{
struct stat st;
size_t i;
#ifndef __QNX__
int fd, cnt, flags;
#else /* !__QNX__ */
int fd, flags;
#endif /* __QNX__ */
int save_errno = errno;
start:
@@ -241,10 +257,12 @@ start:
close(fd);
goto nodevrandom;
}
#ifndef __QNX__
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
close(fd);
goto nodevrandom;
}
#endif /* !__QNX__ */
for (i = 0; i < len; ) {
size_t wanted = len - i;
ssize_t ret = read(fd, (char *)buf + i, wanted);
@@ -265,6 +283,7 @@ nodevrandom:
return (-1);
}
#ifndef __QNX__
#ifdef SYS__sysctl
static int
getentropy_sysctl(void *buf, size_t len)
@@ -537,3 +556,4 @@ getentropy_fallback(void *buf, size_t len)
errno = save_errno;
return (0); /* satisfied */
}
#endif /* !__QNX__ */
-1812
View File
File diff suppressed because it is too large Load Diff
-1640
View File
File diff suppressed because it is too large Load Diff
Vendored
-1971
View File
File diff suppressed because it is too large Load Diff
Vendored
-27461
View File
File diff suppressed because it is too large Load Diff
+70 -19
View File
@@ -12,14 +12,14 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[24])
m4_define([VERSION_MICRO],[2])
m4_define([VERSION_MICRO],[3])
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=34
LIBUNBOUND_REVISION=36
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -122,6 +122,7 @@ LIBUNBOUND_AGE=1
# 1.24.0 had 9:33:1
# 1.24.1 had 9:34:1
# 1.24.2 had 9:35:1
# 1.24.3 had 9:36:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -176,6 +177,12 @@ else
else on_mingw="no"; fi
fi
dnl install the install-sh file with libtoolize -ci, and autoreconf -fi.
AC_REQUIRE_AUX_FILE([install-sh])
if test ! -f install-sh; then
AC_MSG_WARN([./install-sh is missing, use `libtoolize -ci` or `autoreconf -fi` to add it])
fi
#
# Determine configuration file
# the eval is to evaluate shell expansion twice
@@ -330,6 +337,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])
@@ -360,7 +368,14 @@ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribu
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
[ac_cv_c_noreturn_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
#ifdef STDC_HEADERS
# include <stdlib.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); }
]], [[
f(1);
]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
@@ -635,19 +650,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
@@ -1253,7 +1268,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
@@ -1673,10 +1688,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
@@ -1694,10 +1711,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
@@ -2023,6 +2042,9 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
AC_SUBST([ENABLE_DNSTAP], [0])
]
)
dnstap_config="dnstap/dnstap_config.h.tmp:dnstap/dnstap_config.h.in"
dnstap_config_tmp="dnstap/dnstap_config.h.tmp"
dnstap_config_out="dnstap/dnstap_config.h"
# check for dnscrypt if requested
dnsc_DNSCRYPT([
@@ -2293,6 +2315,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)
@@ -2476,6 +2499,34 @@ AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
AX_BUILD_DATE_EPOCH(date, [[%b %e, %Y]])
AC_SUBST(date)
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh $dnstap_config dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
AC_CONFIG_HEADERS([config.h])
# Arguments introduced specifically for simdzone.
AC_ARG_ENABLE(westmere, AS_HELP_STRING([--disable-westmere], [Disable Westmere (SSE4.2) parser kernel]))
AC_ARG_ENABLE(haswell, AS_HELP_STRING([--disable-haswell], [Disable Haswell (AVX2) parser kernel]))
if test ! -f simdzone/configure.ac; then AC_MSG_ERROR([There is no "simdzone/configure.ac" file. The simdzone directory has not been fetched, perhaps get it with 'git submodule update --init'.]); fi
if test ! -f simdzone/configure; then AC_MSG_ERROR([There is no "simdzone/configure" file. The simdzone directory has no configure script file, perhaps run 'autoreconf -fi'.]); fi
AC_CONFIG_SUBDIRS([simdzone])
AC_OUTPUT
# Pick up the objects for simdzone.
SIMDZONE_OBJ=`(cd simdzone; make list_objs) | sed -e 's?src?simdzone/src?g'`
AC_SUBST(SIMDZONE_OBJ)
sed -e 's?^SIMDZONE_OBJ=.*$?SIMDZONE_OBJ='"$SIMDZONE_OBJ"'?' < Makefile > Makefile.tmp.$$
mv -f Makefile.tmp.$$ Makefile
# If dnstap config has changed, overwrite it.
if test -n "$dnstap_config"; then
if test ! -f "$dnstap_config_out"; then
mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out])
else if diff "$dnstap_config_out" "$dnstap_config_tmp" >/dev/null 2>&1; then
if test "x$opt_dnstap" != "xno"; then
AC_MSG_NOTICE([In $srcdir: $dnstap_config_out is unchanged])
fi
rm -f "$dnstap_config_tmp"
else
rm -f "$dnstap_config_out"
mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out])
fi
fi
fi
+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
+1 -1
View File
@@ -59,7 +59,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+1 -1
View File
@@ -26,7 +26,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
+34 -7
View File
@@ -558,9 +558,11 @@ daemon_create_workers(struct daemon* daemon)
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
#ifdef HAVE_NGTCP2
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
if(!daemon->doq_table)
fatal_exit("could not create doq_table: out of memory");
if (cfg_has_quic(daemon->cfg)) {
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
if(!daemon->doq_table)
fatal_exit("could not create doq_table: out of memory");
}
#endif
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
@@ -631,6 +633,25 @@ static void close_other_pipes(struct daemon* daemon, int thr)
}
#endif /* THREADS_DISABLED */
/**
* Function to set the thread local log ID.
* Either the internal thread number, or the LWP ID on Linux based on
* configuration.
*/
static void
set_log_thread_id(struct worker* worker, struct config_file* cfg)
{
(void)cfg;
log_assert(worker);
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
worker->thread_tid = gettid();
if(cfg->log_thread_id)
log_thread_set(&worker->thread_tid);
else
#endif
log_thread_set(&worker->thread_num);
}
/**
* Function to start one thread.
* @param arg: user argument.
@@ -641,7 +662,7 @@ thread_start(void* arg)
{
struct worker* worker = (struct worker*)arg;
int port_num = 0;
log_thread_set(&worker->thread_num);
set_log_thread_id(worker, worker->daemon->cfg);
ub_thread_blocksigs();
#ifdef THREADS_DISABLED
/* close pipe ends used by main */
@@ -801,9 +822,13 @@ daemon_fork(struct daemon* daemon)
fatal_exit("RPZ requires the respip module");
/* first create all the worker structures, so we can pass
* them to the newly created threads.
* them to the newly created threads.
*/
daemon_create_workers(daemon);
/* Set it for the first (main) worker since it does not take part in
* the thread_start() procedure.
*/
set_log_thread_id(daemon->workers[0], daemon->cfg);
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
/* in libev the first inited base gets signals */
@@ -917,8 +942,10 @@ daemon_cleanup(struct daemon* daemon)
daemon->dnscenv = NULL;
#endif
#ifdef HAVE_NGTCP2
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
if (daemon->doq_table) {
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
}
#endif
daemon->cfg = NULL;
}
+60 -3
View File
@@ -153,7 +153,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
log_crypto_err("could not SSL_CTX_new");
return 0;
}
if(!listen_sslctx_setup(rc->ctx)) {
if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
return 0;
}
@@ -801,6 +801,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_discard_timeout)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_replyaddr_limit)) return 0;
if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm,
(unsigned long)s->svr.num_queries_wait_limit)) return 0;
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
@@ -845,6 +847,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
(unsigned long)s->mesh_num_states)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
(unsigned long)s->mesh_num_reply_states)) return 0;
if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm,
(unsigned long)s->mesh_num_reply_addrs)) return 0;
#ifndef S_SPLINT_S
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
@@ -1335,7 +1339,7 @@ perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
return 1;
}
if(!local_zones_add_zone(zones, nm, nmlen,
nmlabs, LDNS_RR_CLASS_IN, t)) {
nmlabs, LDNS_RR_CLASS_IN, t, NULL)) {
lock_rw_unlock(&zones->lock);
ssl_printf(ssl, "error out of memory\n");
return 0;
@@ -5870,6 +5874,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(tls_ciphers);
COPY_VAR_ptr(tls_ciphersuites);
COPY_VAR_int(tls_use_sni);
COPY_VAR_int(tls_use_system_policy_versions);
COPY_VAR_int(https_port);
COPY_VAR_ptr(http_endpoint);
COPY_VAR_uint32_t(http_max_streams);
@@ -5967,6 +5972,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_int(log_servfail);
COPY_VAR_ptr(log_identity);
COPY_VAR_int(log_destaddr);
COPY_VAR_int(log_thread_id);
COPY_VAR_int(hide_identity);
COPY_VAR_int(hide_version);
COPY_VAR_int(hide_trustanchor);
@@ -6176,6 +6182,9 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
COPY_VAR_ptr(ipset_name_v6);
#endif
COPY_VAR_int(ede);
COPY_VAR_int(iter_scrub_ns);
COPY_VAR_int(iter_scrub_cname);
COPY_VAR_int(max_global_quota);
COPY_VAR_int(iter_scrub_promiscuous);
}
#endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */
@@ -6626,7 +6635,14 @@ static void* fast_reload_thread_main(void* arg)
struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg;
struct timeval time_start, time_read, time_construct, time_reload,
time_end;
log_thread_set(&fast_reload_thread->threadnum);
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
fast_reload_thread->thread_tid = gettid();
if(fast_reload_thread->thread_tid_log)
log_thread_set(&fast_reload_thread->thread_tid);
else
#endif
log_thread_set(&fast_reload_thread->threadnum);
verbose(VERB_ALGO, "start fast reload thread");
if(fast_reload_thread->fr_verb >= 1) {
@@ -7014,6 +7030,9 @@ fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause,
lock_basic_init(&fr->fr_output_lock);
lock_protect(&fr->fr_output_lock, fr->fr_output,
sizeof(*fr->fr_output));
#ifdef HAVE_GETTID
fr->thread_tid_log = worker->env.cfg->log_thread_id;
#endif
return 1;
}
@@ -7611,6 +7630,41 @@ fr_worker_pickup_outside_network(struct worker* worker)
}
}
#ifdef USE_DNSTAP
/** Fast reload, the worker picks up changes to DNSTAP configuration. */
static void
fr_worker_pickup_dnstap_changes(struct worker* worker)
{
struct dt_env* w_dtenv = &worker->dtenv;
struct dt_env* d_dtenv = worker->daemon->dtenv;
log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap);
if(d_dtenv == NULL) {
/* There is no environment when DNSTAP was not enabled
* in the configuration. */
return;
}
w_dtenv->identity = d_dtenv->identity;
w_dtenv->len_identity = d_dtenv->len_identity;
w_dtenv->version = d_dtenv->version;
w_dtenv->len_version = d_dtenv->len_version;
w_dtenv->log_resolver_query_messages =
d_dtenv->log_resolver_query_messages;
w_dtenv->log_resolver_response_messages =
d_dtenv->log_resolver_response_messages;
w_dtenv->log_client_query_messages =
d_dtenv->log_client_query_messages;
w_dtenv->log_client_response_messages =
d_dtenv->log_client_response_messages;
w_dtenv->log_forwarder_query_messages =
d_dtenv->log_forwarder_query_messages;
w_dtenv->log_forwarder_response_messages =
d_dtenv->log_forwarder_response_messages;
lock_basic_lock(&d_dtenv->sample_lock);
w_dtenv->sample_rate = d_dtenv->sample_rate;
lock_basic_unlock(&d_dtenv->sample_lock);
}
#endif /* USE_DNSTAP */
void
fast_reload_worker_pickup_changes(struct worker* worker)
{
@@ -7639,6 +7693,9 @@ fast_reload_worker_pickup_changes(struct worker* worker)
worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled;
#endif
fr_worker_pickup_outside_network(worker);
#ifdef USE_DNSTAP
fr_worker_pickup_dnstap_changes(worker);
#endif
}
/** fast reload thread, handle reload_stop notification, send reload stop
+6
View File
@@ -206,6 +206,12 @@ struct fast_reload_thread {
int commpair[2];
/** thread id, of the io thread */
ub_thread_type tid;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** if the thread has to quit */
+6
View File
@@ -262,6 +262,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr = worker->stats;
s->mesh_num_states = (long long)worker->env.mesh->all.count;
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs;
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
@@ -284,6 +285,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
NUM_BUCKETS_HIST);
s->svr.num_queries_discard_timeout +=
(long long)worker->env.mesh->num_queries_discard_timeout;
s->svr.num_queries_replyaddr_limit +=
(long long)worker->env.mesh->num_queries_replyaddr_limit;
s->svr.num_queries_wait_limit +=
(long long)worker->env.mesh->num_queries_wait_limit;
s->svr.num_dns_error_reports +=
@@ -448,6 +451,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
total->svr.num_queries_discard_timeout +=
a->svr.num_queries_discard_timeout;
total->svr.num_queries_replyaddr_limit +=
a->svr.num_queries_replyaddr_limit;
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
@@ -519,6 +524,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->mesh_num_states += a->mesh_num_states;
total->mesh_num_reply_states += a->mesh_num_reply_states;
total->mesh_num_reply_addrs += a->mesh_num_reply_addrs;
total->mesh_jostled += a->mesh_jostled;
total->mesh_dropped += a->mesh_dropped;
total->mesh_replies_sent += a->mesh_replies_sent;
+1 -1
View File
@@ -473,7 +473,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
cfg->tls_ciphers, cfg->tls_ciphersuites,
(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0),
is_dot, is_doh))) {
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
fatal_exit("could not set up listen SSL_CTX");
}
}
+23 -8
View File
@@ -746,7 +746,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
@@ -1444,6 +1444,24 @@ check_ip_ratelimit(struct worker* worker, struct sockaddr_storage* addr,
return 1;
}
/*
* This is the callback function when a request arrives. It is passed
* the packet and user argument. Return true to send a reply.
* This is of type comm_point_callback_type. The struct comm_point contains
* more comments on the comm_point.callback member about the function.
* @param c: the comm_point where the request arrives on.
* @param arg: the user argument for the callback, the worker.
* @param error: This can be NETEVENT_NOERROR, NETEVENT_TIMEOUT,
* NETEVENT_CLOSED or other comm point callback error values.
* @param repinfo: The reply info, use it to send a reply. If the reply
* is immediate, return 1. If the reply is later on return 0 and save
* the repinfo, to call comm_point_send_reply on.
* @return 1 to sent a reply straight away, for like cache response so that
* no allocation needs to be done. And only internal preallocated buffers
* are used. Return 0 and save the repinfo to reply later, for responses
* that need to be looked up. Return 0 and call comm_point_drop_reply on
* the repinfo to drop the response.
*/
int
worker_handle_request(struct comm_point* c, void* arg, int error,
struct comm_reply* repinfo)
@@ -1929,11 +1947,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,
@@ -2184,9 +2202,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
struct dt_env* dtenv = &worker->dtenv;
#else
void* dtenv = NULL;
#endif
#ifdef HAVE_GETTID
worker->thread_tid = gettid();
#endif
worker->need_to_exit = 0;
worker->base = comm_base_create(do_sigs);
+12 -11
View File
@@ -366,22 +366,23 @@ static int
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
{
struct config_strlist* s;
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
const char* dns64_prefix = cfg->dns64_prefix ?
cfg->dns64_prefix : DEFAULT_DNS64_PREFIX;
verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix);
if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr,
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix);
return 0;
}
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
log_err("dns64_prefix is not IPv6: %s", dns64_prefix);
return 0;
}
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
cfg->dns64_prefix);
log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s",
dns64_prefix);
return 0;
}
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
@@ -496,8 +497,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 +523,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;
+11 -1
View File
@@ -448,6 +448,9 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
dtio->tls_use_sni = cfg->tls_use_sni;
#endif /* HAVE_SSL */
}
#ifdef HAVE_GETTID
dtio->thread_tid_log = cfg->log_thread_id;
#endif
return 1;
}
@@ -2130,7 +2133,14 @@ static void* dnstap_io(void* arg)
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
time_t secs = 0;
struct timeval now;
log_thread_set(&dtio->threadnum);
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
dtio->thread_tid = gettid();
if(dtio->thread_tid_log)
log_thread_set(&dtio->thread_tid);
else
#endif
log_thread_set(&dtio->threadnum);
/* setup */
verbose(VERB_ALGO, "start dnstap io thread");
+6
View File
@@ -131,6 +131,12 @@ struct dt_io_thread {
struct dt_io_list_item* io_list_iter;
/** thread id, of the io thread */
ub_thread_type tid;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
+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);
+224
View File
@@ -1,3 +1,227 @@
27 January 2026: Wouter
- Add test for allow-notify with a host name.
26 January 2026: Wouter
- Fix that allow-notify entries with hostnames are copied after IPv4
and IPv6 lookup.
- Fix to not skip allow-notify hostname lookups when there are only
urls.
23 January 2026: Yorgos
- Merge #1396: Log Linux thread ID.
- On Linux systems log the system-wide unique thread ID instead of
Unbound's internal thread counter.
- Introduce the 'log-thread-id' configuration option to manage logging
the system-wide Linux thread ID for easier debugging with system
tools.
- Update generated man pages.
22 January 2026: Wouter
- Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
and max_global_quota options.
- Fix http test tool petal to not print errors when there is no
error.
21 January 2026: Wouter
- Merge #1388: QNX Porting support for unbound.
19 January 2026: Wouter
- Merge #1392: Include "V" (version) option in synopsis.
15 January 2026: Wouter
- Fix documentation for requestlist.overwritten and
requestlist.exceeded, it explains which query was dropped.
8 January 2026: Wouter
- Merge #1381: Do not initialize quic_table unless it is enabled.
6 January 2026: Wouter
- Fix edns subnet, that scope zero queries, when there is a
subquery without subnet, and the forward-no-cache or
stub-no-cache option is set, it is not stored in cache due to
the forward or stub option.
6 January 2026: Yorgos
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
RFC5952.
31 December 2025: Yorgos
- Update the unbound-anchor man page to note write permissions of the
generated file if it is to be used with Unbound's
auto-trust-anchor-file option.
- Use the same EDE removal logic when encoding errors as when encoding
replies.
30 December 2025: Yorgos
- Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
categorization in the log output.
24 December 2025: Yorgos
- More specific wording in the unbound.conf man page for stub-first
and forward-first options.
3 December 2025: Wouter
- Fix http2 drop handling to clear the postpone_drop state so that
other streams on the http2 session are not affected by a drop,
and can clean up properly if also dropped. Fix http2 send reply
so that when there is a send failure is does not recurse into
the mesh functions and also does not drop the connection due to
the condition of one stream.
2 December 2025: Wouter
- Fix to remove http2 stream mesh state when mesh new request is
dropping the new request.
1 December 2025: Wouter
- Fix to add EDNS CO flag to testbound and debug message log.
- Fix header comment about EDE reference in validator/val_sigcrypt.h.
28 November 2025: Yorgos
- For #1375, there is no DNSTAP environment if it wasn't configured.
26 November 2025: Yorgos
- Tag for 1.24.2 release.
The repository continues with version 1.24.3.
13 November 2025: Wouter
- Merge #1374: Mesh reply counters.
This adds the statistics num.queries.replyaddr_limit and
requestlist.current.replies.
- Merge #1375: Copy DNSTAP changes from daemon to workers after
fast_reload.
12 November 2025: Wouter
- Fix that when discard timeout drops packet, they are accounted as
less reply addresses in use in the mesh area.
- iana portlist updated.
6 November 2025: Wouter
- Fix add comment to worker_handle_request function that explain it.
- Fix configure test for noreturn attribute so it compiles without
warning.
- Fix configure test for nonstring attribute so that it does not
accept when the compiler prints a warning about an unknown
attribute.
4 November 2025: Wouter
- Fix dns64 log output to log the default instead of a null string.
1 November 2025: Yorgos
- Fix #1366: Infra cache does not work correctly for NAT64, by
moving the NAT64 synthesis from the iterator when selecting a target
address, to the delegation point itself when adding target
addresses.
27 October 2025: Yorgos
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
new $action, for SWIG.
- 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.
+3 -3
View File
@@ -13,7 +13,7 @@ If you're not using DNSSEC then you may remove "validator".
2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
dns64-prefix: 64:FF9B::/96
dns64-prefix: 64:ff9b::/96
The prefix must be a /96 or shorter.
@@ -42,9 +42,9 @@ To enable NAT64 in Unbound, add to unbound.conf's "server" section:
do-nat64: yes
The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the
standard 64:FF9B::/96 prefix. You can reconfigure it with:
standard 64:ff9b::/96 prefix. You can reconfigure it with:
nat64-prefix: 64:FF9B::/96
nat64-prefix: 64:ff9b::/96
To test NAT64 operation, pick a domain that only has IPv4 reachability for its
nameservers and try resolving any names in that domain.
+8 -3
View File
@@ -6,11 +6,16 @@ and makes it easier to maintain and contribute to the documentation.
The templated man pages (*.in) are still part of the code repository as to not
alter current procedures that could be in place by users/packagers.
These man pages (*.in) are still the ones being used when
configuring/installing Unbound.
Packagers/users do not have to generate any man pages themselves, this is done
by the core developers during development and upon releasing new versions.
The templated man pages (*.in) are generated by Sphinx (used for the online
documentation).
The online documentation has its own repository at
https://github.com/NLnetLabs/unbound-manual.
In the README.md there (branch test-auto for now), there are further simple
instructions on how to generate the templated man pages there and update them
in this repository.
In that README.md (https://github.com/NLnetLabs/unbound-manual/README.md)
there are further simple instructions on how to generate the templated man
pages there and update them in this repository.
+50 -18
View File
@@ -54,7 +54,7 @@ server:
# interface: 192.0.2.153
# interface: 192.0.2.154
# interface: 192.0.2.154@5003
# interface: 2001:DB8::5
# interface: 2001:db8::5
# interface: eth0@5003
# enable this feature to copy the source address of queries to reply.
@@ -72,12 +72,12 @@ server:
# server from by ip-address. If none, the default (all) interface
# is used. Specify every interface on a 'outgoing-interface:' line.
# outgoing-interface: 192.0.2.153
# outgoing-interface: 2001:DB8::5
# outgoing-interface: 2001:DB8::6
# outgoing-interface: 2001:db8::5
# outgoing-interface: 2001:db8::6
# Specify a netblock to use remainder 64 bits as random bits for
# upstream queries. Uses freebind option (Linux).
# outgoing-interface: 2001:DB8::/64
# outgoing-interface: 2001:db8::/64
# Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
# And: ip -6 route add local 2001:db8::/64 dev lo
# And set prefer-ip6: yes to use the ip6 randomness from a netblock.
@@ -379,7 +379,7 @@ server:
# interface-action: 192.0.2.153 allow
# interface-action: 192.0.2.154 allow
# interface-action: 192.0.2.154@5003 allow
# interface-action: 2001:DB8::5 allow
# interface-action: 2001:db8::5 allow
# interface-action: eth0@5003 allow
# Similar to 'access-control-tag:' but for interfaces.
@@ -496,6 +496,10 @@ server:
# print log lines that say why queries return SERVFAIL to clients.
# log-servfail: no
# log system-wide Linux thread ID, insted of Unbound's internal thread
# counter. Only on Linux and only when threads are available.
# log-thread-id: no
# the pid file. Can be an absolute path outside of chroot/work dir.
# pidfile: "@UNBOUND_PIDFILE@"
@@ -756,6 +760,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.
@@ -925,6 +930,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.
@@ -935,21 +956,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.
@@ -970,15 +996,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"
@@ -1261,10 +1290,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:
@@ -1272,6 +1302,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"
+1 -1
View File
@@ -416,6 +416,6 @@ on a function return with file read failure.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+13 -4
View File
@@ -39,9 +39,17 @@ unbound-anchor \- Unbound @version@ anchor utility.
validation.
The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when
regular \fI\%RFC 5011\fP update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the \fI\%unbound(8)\fP DNS server.
It can be run from the commandline, or run as part of startup scripts before
you start the \fI\%unbound(8)\fP DNS server.
.sp
Note that if you want to use \fI\%RFC 5011\fP with Unbound (i.e., the
\fI\%auto\-trust\-anchor\-file\fP option) so
that trust anchor information is automatically tracked by Unbound during
operation, the user that Unbound runs under (by default \(aqunbound\(aq) must have
write permissions to the file and the directory the file lives in (for creating
temporary files).
In this case you would probably want to run this program as the designated
Unbound user.
.sp
Suggested usage:
.INDENT 0.0
@@ -52,6 +60,7 @@ Suggested usage:
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
@@ -295,6 +304,6 @@ Signature on the root key information.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+12 -3
View File
@@ -51,9 +51,17 @@ Description
validation.
The program fetches the trust anchor with the method from :rfc:`7958` when
regular :rfc:`5011` update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
It can be run from the commandline, or run as part of startup scripts before
you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
Note that if you want to use :rfc:`5011` with Unbound (i.e., the
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>` option) so
that trust anchor information is automatically tracked by Unbound during
operation, the user that Unbound runs under (by default 'unbound') must have
write permissions to the file and the directory the file lives in (for creating
temporary files).
In this case you would probably want to run this program as the designated
Unbound user.
Suggested usage:
@@ -62,6 +70,7 @@ Suggested usage:
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
+1 -1
View File
@@ -88,6 +88,6 @@ Unbound configuration file.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+38 -1
View File
@@ -880,6 +880,11 @@ number of queries removed due to discard\-timeout by thread
.UNINDENT
.INDENT 0.0
.TP
.B threadX.num.queries_replyaddr_limit
number of queries removed due to replyaddr limits by thread
.UNINDENT
.INDENT 0.0
.TP
.B threadX.num.queries_wait_limit
number of queries removed due to wait\-limit by thread
.UNINDENT
@@ -973,6 +978,10 @@ Number of requests in the request list that were overwritten by newer
entries.
This happens if there is a flood of queries that recursive processing and
the server has a hard time.
The counter is increased when during the flood the
\fI\%jostle\-timeout\fP
allows a query to be removed in favor of a new incoming query.
The older query is then dropped to make space.
.UNINDENT
.INDENT 0.0
.TP
@@ -980,6 +989,12 @@ the server has a hard time.
Queries that were dropped because the request list was full.
This happens if a flood of queries need recursive processing, and the
server can not keep up.
The counter is increased when during the flood there is no space
to be made with the jostle out of an older query, and the new query
is dropped.
Since no older queries are removed, see
\fI\%jostle\-timeout\fP setting, there
is no space for the new query.
.UNINDENT
.INDENT 0.0
.TP
@@ -994,6 +1009,13 @@ Current size of the request list, only the requests from client queries.
.UNINDENT
.INDENT 0.0
.TP
.B threadX.requestlist.current.replies
Current count of the number of reply entries waiting on request list
entries. Because a request list entry can send results to multiple reply
addresses, this number may be larger than the size of the request list.
.UNINDENT
.INDENT 0.0
.TP
.B threadX.recursion.time.avg
Average time it took to answer queries that needed recursive processing.
Note that queries that were answered from the cache are not in this average.
@@ -1048,6 +1070,11 @@ summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.num.queries_replyaddr_limit
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.num.queries_wait_limit
summed over threads.
.UNINDENT
@@ -1138,6 +1165,16 @@ summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.requestlist.current.user
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.requestlist.current.replies
summed over threads.
.UNINDENT
.INDENT 0.0
.TP
.B total.recursion.time.median
averaged over threads.
.UNINDENT
@@ -1543,6 +1580,6 @@ directory with private keys (\fBunbound_server.key\fP and
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+32
View File
@@ -815,6 +815,10 @@ number of statistic counters:
number of queries removed due to discard-timeout by thread
@@UAHL@unbound-control.stats@threadX.num.queries_replyaddr_limit@@
number of queries removed due to replyaddr limits by thread
@@UAHL@unbound-control.stats@threadX.num.queries_wait_limit@@
number of queries removed due to wait-limit by thread
@@ -893,12 +897,22 @@ number of statistic counters:
entries.
This happens if there is a flood of queries that recursive processing and
the server has a hard time.
The counter is increased when during the flood the
:ref:`jostle-timeout<unbound.conf.jostle-timeout>`
allows a query to be removed in favor of a new incoming query.
The older query is then dropped to make space.
@@UAHL@unbound-control.stats@threadX.requestlist.exceeded@@
Queries that were dropped because the request list was full.
This happens if a flood of queries need recursive processing, and the
server can not keep up.
The counter is increased when during the flood there is no space
to be made with the jostle out of an older query, and the new query
is dropped.
Since no older queries are removed, see
:ref:`jostle-timeout<unbound.conf.jostle-timeout>` setting, there
is no space for the new query.
@@UAHL@unbound-control.stats@threadX.requestlist.current.all@@
@@ -910,6 +924,12 @@ number of statistic counters:
Current size of the request list, only the requests from client queries.
@@UAHL@unbound-control.stats@threadX.requestlist.current.replies@@
Current count of the number of reply entries waiting on request list
entries. Because a request list entry can send results to multiple reply
addresses, this number may be larger than the size of the request list.
@@UAHL@unbound-control.stats@threadX.recursion.time.avg@@
Average time it took to answer queries that needed recursive processing.
Note that queries that were answered from the cache are not in this average.
@@ -955,6 +975,10 @@ number of statistic counters:
summed over threads.
@@UAHL@unbound-control.stats@total.num.queries_replyaddr_limit@@
summed over threads.
@@UAHL@unbound-control.stats@total.num.queries_wait_limit@@
summed over threads.
@@ -1027,6 +1051,14 @@ number of statistic counters:
summed over threads.
@@UAHL@unbound-control.stats@total.requestlist.current.user@@
summed over threads.
@@UAHL@unbound-control.stats@total.requestlist.current.replies@@
summed over threads.
@@UAHL@unbound-control.stats@total.recursion.time.median@@
averaged over threads.
+1 -1
View File
@@ -185,6 +185,6 @@ encountered a fatal error.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+2 -2
View File
@@ -32,7 +32,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
unbound \- Unbound DNS validating resolver @version@.
.SH SYNOPSIS
.sp
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
\fBunbound\fP [\fB\-hdpVv\fP] [\fB\-c <cfgfile>\fP]
.SH DESCRIPTION
.sp
\fBunbound\fP is a caching DNS resolver.
@@ -118,6 +118,6 @@ Show the version number and build options, and exit.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+342 -141
View File
@@ -36,44 +36,49 @@ unbound.conf \- Unbound @version@ configuration file.
.SH DESCRIPTION
.sp
\fBunbound.conf\fP is used to configure \fI\%unbound(8)\fP\&.
The file format has attributes and values.
Some attributes have attributes inside them.
The notation is: \fBattribute: value\fP\&.
.sp
Comments start with \fB#\fP and last to the end of line.
Empty lines are ignored as is whitespace at the beginning of a line.
.sp
The utility \fI\%unbound\-checkconf(8)\fP can be
used to check \fBunbound.conf\fP prior to usage.
.SH FILE FORMAT
.sp
Whitespace is used to separate keywords.
Whitespace indentation is insignificant, but is still recommended for visual
clarity.
Comments start with \fB#\fP and last to the end of line.
Empty lines are ignored, as is whitespace at the beginning of a line.
.sp
Attribute keywords end with a colon (\fB:\fP) and they are either options or
section clauses (group options together).
.sp
The configuration file is logically divided into \fBsections\fP where each section
is introduced by a \fI\%section clause\fP\&.
.SH EXAMPLE
.sp
An example config file is shown below.
Copy this to \fB/etc/unbound/unbound.conf\fP and start the server with:
An example minimal config file is shown below; most settings are the defaults.
Copy this to \fB@ub_conf_file@\fP and start the server with:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ unbound \-c /etc/unbound/unbound.conf
$ unbound \-c @ub_conf_file@
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Most settings are the defaults.
Stop the server with:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
$ kill \(gacat /etc/unbound/unbound.pid\(ga
$ kill \(gacat @UNBOUND_PIDFILE@\(ga
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Below is a minimal config file.
The source distribution contains an extensive \fBexample.conf\fP file with
all the options.
.INDENT 0.0
@@ -83,33 +88,87 @@ all the options.
.ft C
# unbound.conf(5) config file for unbound(8).
server:
directory: \(dq/etc/unbound\(dq
directory: \(dq@UNBOUND_RUN_DIR@\(dq
username: unbound
# make sure unbound can access entropy from inside the chroot.
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
# mount \-\-bind \-n /dev/urandom /etc/unbound/dev/urandom
# and mount \-\-bind \-n /dev/log /etc/unbound/dev/log
chroot: \(dq/etc/unbound\(dq
# logfile: \(dq/etc/unbound/unbound.log\(dq #uncomment to use logfile.
pidfile: \(dq/etc/unbound/unbound.pid\(dq
# mount \-\-bind \-n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom
# and mount \-\-bind \-n /dev/log @UNBOUND_RUN_DIR@/dev/log
chroot: \(dq@UNBOUND_CHROOT_DIR@\(dq
# logfile: \(dq@UNBOUND_RUN_DIR@/unbound.log\(dq #uncomment to use logfile.
pidfile: \(dq@UNBOUND_PIDFILE@\(dq
# verbosity: 1 # uncomment and increase to get more logging.
# listen on all interfaces, answer queries from the local subnet.
interface: 0.0.0.0
interface: ::0
access\-control: 10.0.0.0/8 allow
access\-control: 2001:DB8::/64 allow
access\-control: 2001:db8::/64 allow
.ft P
.fi
.UNINDENT
.UNINDENT
.SH FILE FORMAT
.SH SECTION CLAUSES
.sp
There must be whitespace between keywords.
Attribute keywords end with a colon \fB\(aq:\(aq\fP\&.
An attribute is followed by a value, or its containing attributes in which case
it is referred to as a clause.
Clauses can be repeated throughout the file (or included files) to group
attributes under the same clause.
The recognized section clauses are:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.TP
.B \fI\%server:\fP
Most of the configuration is found in this section.
.TP
.B \fI\%remote\-control:\fP
Configuration for the facility used by
\fI\%unbound\-control(8)\fP\&.
.TP
.B \fI\%stub\-zone:\fP
Configuration for a zone that redirects to specific authoritative name
servers, e.g. for zones not generally available on the greater
Internet.
.TP
.B \fI\%forward\-zone:\fP
Configuration for a zone that forwards to specific DNS resolvers.
.TP
.B \fI\%auth\-zone:\fP
Configuration for local authoritative zones.
.TP
.B \fI\%view:\fP
Overriding a small subset of configuration for incoming requests.
Requests are mapped to views with
\fI\%access\-control\-view\fP and
\fI\%interface\-view\fP\&.
.TP
.B \fI\%python:\fP
Configuration for the optional \fBpython\fP script module.
.TP
.B \fI\%dynlib:\fP
Configuration for the optional \fBdynlib\fP module that loads dynamic
libraries into Unbound.
.TP
.B \fI\%dnscrypt:\fP
Configuration for the optional DNSCrypt feature.
.TP
.B \fI\%cachedb:\fP
Configuration for the optional \fBcachedb\fP module that can interface
with second level caches, currently Redis or Redis\-complatible
databases.
.TP
.B \fI\%dnstap:\fP
Configuration of the optional dnstap logging feature; a flexible,
structured binary log format for DNS software.
.TP
.B \fI\%rpz:\fP
Configuration for Response Policy Zones that allows for DNS filtering.
Requires the \fBrespip\fP module.
.UNINDENT
.UNINDENT
.UNINDENT
.sp
Section clauses can be repeated throughout the file (or included files) to
logically group options in one visually cohesive group.
This may be particularly useful for the \fBserver:\fP clause with its myriad of
options.
.SH INCLUDING FILES
.sp
Files can be included using the \fBinclude:\fP directive.
It can appear anywhere, it accepts a single file name as argument.
@@ -124,11 +183,11 @@ Wildcards can be used to include multiple files, see \fIglob(7)\fP\&.
.sp
For a more structural include option, the \fBinclude\-toplevel:\fP directive can
be used.
This closes whatever clause is currently active (if any) and forces the use of
clauses in the included files and right after this directive.
.SS Server Options
This closes whatever section clause is currently active (if any) and forces the
use of section clauses in the included files and right after this directive.
.SH SERVER OPTIONS
.sp
These options are part of the \fBserver:\fP clause.
These options are part of the \fBserver:\fP section.
.INDENT 0.0
.TP
.B verbosity: \fI<number>\fP
@@ -539,6 +598,9 @@ Default: 376
The wait time in msec where recursion requests are dropped.
This is to stop a large number of replies from accumulating.
They receive no reply, the work item continues to recurse.
For UDP the replies are dropped, for stream connections the reply
is not dropped if the stream connection is still open ready to receive
answers.
It is nice to be a bit larger than
\fI\%serve\-expired\-client\-timeout\fP
if that is enabled.
@@ -554,7 +616,7 @@ The number of replies that can wait for recursion, for an IP address.
This makes a ratelimit per IP address of waiting replies for recursion.
It stops very large amounts of queries waiting to be returned to one
destination.
The value \fB0\fP disables wait limits.
The value \fB0\fP disables all wait limits.
.sp
Default: 1000
.UNINDENT
@@ -563,7 +625,11 @@ Default: 1000
.B wait\-limit\-cookie: \fI<number>\fP
The number of replies that can wait for recursion, for an IP address
that sent the query with a valid DNS Cookie.
Since the cookie validates the client address, this limit can be higher.
Since the cookie already validates the client address, this option allows
to override a configured
\fI\%wait\-limit\fP value usually with a higher one
for cookie validated queries.
The value \fB0\fP disables wait limits for cookie validated queries.
.sp
Default: 10000
.UNINDENT
@@ -1153,8 +1219,8 @@ Default: no
.INDENT 0.0
.TP
.B tls\-system\-cert: \fI<yes or no>\fP
This the same attribute as the
\fI\%tls\-win\-cert\fP attribute, under a
This the same as the
\fI\%tls\-win\-cert\fP option, under a
different name.
Because it is not windows specific.
.UNINDENT
@@ -1218,6 +1284,47 @@ Default: \(dq\(dq
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-sni: \fI<yes or no>\fP
Enable or disable sending the SNI extension on TLS connections.
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: yes
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP
Enable or disable general\-puspose version\-flexible TLS server configuration
when serving TLS.
This will allow the whole list of available TLS versions provided by the
crypto library, which may have been further restricted by the system\(aqs
crypto policy.
.sp
By default Unbound only uses the latest available TLS version.
.sp
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
Use only if you want to support legacy TLS client connections.
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: no
.UNINDENT
.INDENT 0.0
.TP
.B pad\-responses: \fI<yes or no>\fP
If enabled, TLS serviced queries that contained an EDNS Padding option will
cause responses padded to the closest multiple of the size specified in
@@ -1251,20 +1358,6 @@ Default: 128
.UNINDENT
.INDENT 0.0
.TP
.B tls\-use\-sni: \fI<yes or no>\fP
Enable or disable sending the SNI extension on TLS connections.
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
Changing the value requires a reload.
.UNINDENT
.UNINDENT
.sp
Default: yes
.UNINDENT
.INDENT 0.0
.TP
.B https\-port: \fI<number>\fP
The port number on which to provide DNS\-over\-HTTPS service.
Only interfaces configured with that port number as @number get the HTTPS
@@ -1357,6 +1450,9 @@ The port number on which to provide DNS\-over\-QUIC service.
Only interfaces configured with that port number as @number get the QUIC
service.
The interface uses QUIC for the UDP traffic on that port number.
If it is set to 0, the server does not init QUIC code, and QUIC is
disabled.
This is similar to if QUIC is not in use, but then explicitly.
.sp
Default: 853
.UNINDENT
@@ -1580,8 +1676,8 @@ implicit default \(dqaccess\-control: 127.0.0.0/8 allow\(dq option.
.INDENT 3.5
The interface needs to be already specified with
\fI\%interface\fP and that any
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
attributes for targeted clients.
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
options for targeted clients.
.UNINDENT
.UNINDENT
.UNINDENT
@@ -1596,8 +1692,8 @@ for interfaces.
.INDENT 3.5
The interface needs to be already specified with
\fI\%interface\fP and that any
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
attributes for targeted clients.
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
options for targeted clients.
.UNINDENT
.UNINDENT
.UNINDENT
@@ -1613,8 +1709,8 @@ but for interfaces.
.INDENT 3.5
The interface needs to be already specified with
\fI\%interface\fP and that any
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
attributes for targeted clients.
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
options for targeted clients.
.UNINDENT
.UNINDENT
.UNINDENT
@@ -1630,8 +1726,8 @@ for interfaces.
.INDENT 3.5
The interface needs to be already specified with
\fI\%interface\fP and that any
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
attributes for targeted clients.
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
options for targeted clients.
.UNINDENT
.UNINDENT
.UNINDENT
@@ -1646,8 +1742,8 @@ but for interfaces.
.INDENT 3.5
The interface needs to be already specified with
\fI\%interface\fP and that any
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
attributes for targeted clients.
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
options for targeted clients.
.UNINDENT
.UNINDENT
.UNINDENT
@@ -1724,7 +1820,7 @@ The logfile is appended to, in the following format:
.UNINDENT
.sp
If this option is given, the \fI\%use\-syslog\fP
attribute is internally set to \fBno\fP\&.
option is internally set to \fBno\fP\&.
.sp
The logfile is reopened (for append) when the config file is reread, on
SIGHUP.
@@ -1834,6 +1930,16 @@ Default: no
.UNINDENT
.INDENT 0.0
.TP
.B log\-thread\-id: \fI<yes or no>\fP
(Only on Linux and only when threads are available)
Logs the system\-wide Linux thread ID instead of Unbound\(aqs internal thread
counter.
Can be useful when debugging with system tools.
.sp
Default: no
.UNINDENT
.INDENT 0.0
.TP
.B pidfile: \fI<filename>\fP
The process id is written to the file.
Default is \fB\(dq@UNBOUND_PIDFILE@\(dq\fP\&.
@@ -1872,8 +1978,8 @@ Read the root hints from this file.
Default is nothing, using builtin hints for the IN class.
The file has the format of zone files, with root nameserver names and
addresses only.
The default may become outdated, when servers change, therefore it is good
practice to use a root hints file.
The default may become outdated, when servers change, and then it is
possible to use a root hints file with specific servers.
.sp
Default: \(dq\(dq
.UNINDENT
@@ -1969,7 +2075,7 @@ Default: \(dq3 2 1 0 0\(dq
.B harden\-short\-bufsize: \fI<yes or no>\fP
Very small EDNS buffer sizes from queries are ignored.
.sp
Default: yes (as described in the standard)
Default: yes (per \fI\%RFC 6891\fP)
.UNINDENT
.INDENT 0.0
.TP
@@ -2600,6 +2706,12 @@ If
\fI\%serve\-expired\-client\-timeout\fP
is also used then it is RECOMMENDED to use 30 as the value (\fI\%RFC 8767\fP).
.sp
This value is capped by the original TTL of the record.
This means that records with higher original TTL than this value will use
this value for expired replies.
Records with lower original TTL than this value will use their original TTL
for expired replies.
.sp
Default: 30
.UNINDENT
.INDENT 0.0
@@ -3278,7 +3390,7 @@ zone section below.
Configure local data shorthand for a PTR record with the reversed IPv4 or
IPv6 address and the host name.
For example \fB\(dq192.0.2.4 www.example.com\(dq\fP\&.
TTL can be inserted like this: \fB\(dq2001:DB8::4 7200 www.example.com\(dq\fP
TTL can be inserted like this: \fB\(dq2001:db8::4 7200 www.example.com\(dq\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -3335,7 +3447,7 @@ This specifies the action data for
\fI\%response\-ip\fP with action being to redirect
as specified by \fI<\(dqresource record string\(dq>\fP\&.
\fI<\(dqResource record string\(dq>\fP is similar to that of
\fI\%access\-control\-tag\-action\fP,
\fI\%access\-control\-tag\-data\fP,
but it must be of either AAAA, A or CNAME types.
If the \fI<IP\-netblock>\fP is an IPv6/IPv4 prefix, the record must be AAAA/A
respectively, unless it is a CNAME (which can be used for both versions of
@@ -3805,17 +3917,18 @@ enabled to increase privacy on the outgoing reports.
.sp
Default: no
.UNINDENT
.SS Remote Control Options
.SH REMOTE CONTROL OPTIONS
.sp
These options are part of the \fBremote\-control:\fP section and are the
declarations for the remote control facility.
.sp
In the \fBremote\-control:\fP clause are the declarations for the remote control
facility.
If this is enabled, the \fI\%unbound\-control(8)\fP
utility can be used to send commands to the running Unbound server.
The server uses these clauses to setup TLSv1 security for the connection.
The \fI\%unbound\-control(8)\fP utility also reads the
\fBremote\-control:\fP section for options.
The server uses these options to setup TLS security for the connection.
The \fI\%unbound\-control(8)\fP utility also reads
this \fBremote\-control:\fP section for options.
To setup the correct self\-signed certificates use the
\fIunbound\-control\-setup(8)\fP utility.
\fBunbound\-control\-setup(8)\fP utility.
.INDENT 0.0
.TP
.B control\-enable: \fI<yes or no>\fP
@@ -3915,9 +4028,11 @@ This file is used by \fI\%unbound\-control(8)\fP\&.
.sp
Default: unbound_control.pem
.UNINDENT
.SS Stub Zone Options
.SH STUB ZONE OPTIONS
.sp
There may be multiple \fBstub\-zone:\fP clauses.
These options are part of the \fBstub\-zone:\fP section.
.sp
There may be multiple \fBstub\-zone:\fP sections.
Each with a \fI\%name\fP and zero or more hostnames or
IP addresses.
For the stub zone this list of nameservers is used.
@@ -3956,9 +4071,10 @@ Consider adding \fI\%server\fP statements for
\fI\%domain\-insecure\fP and for
\fI\%local\-zone: <name> nodefault\fP
for the zone if it is a locally served zone.
The insecure clause stops DNSSEC from invalidating the zone.
The \fI\%domain\-insecure\fP option stops DNSSEC
from invalidating the zone.
The \fI\%local\-zone: nodefault\fP (or
\fI\%transparent\fP) clause makes the
\fI\%transparent\fP) option makes the
(reverse\-) zone bypass Unbound\(aqs filtering of \fI\%RFC 1918\fP zones.
.INDENT 0.0
.TP
@@ -3972,6 +4088,23 @@ This is the full domain name of the zone.
Name of stub zone nameserver.
Is itself resolved before it is used.
.sp
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
If the domain (or a subdomain) from this zone is used as the host, it
will unavoidably introduce a circular dependency on retrieving the IP
addresses of the name server.
In that case, it is suggested to use
\fI\%stub\-addr\fP instead.
Alternatively,
\fI\%stub\-first: yes\fP can also work
around the circular dependency by trying resolution outside of this
zone.
However this has the caveat that it would allow escaping this zone when
any resolution attempt fails within this zone.
.UNINDENT
.UNINDENT
.sp
To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the
port number.
.sp
@@ -4012,9 +4145,12 @@ Default: no
.INDENT 0.0
.TP
.B stub\-first: \fI<yes or no>\fP
If enabled, a query is attempted without the stub clause if it fails.
If enabled, a query is attempted without this stub section if it fails.
The data could not be retrieved and would have caused SERVFAIL because the
servers are unreachable, instead it is tried without this clause.
servers are unreachable, instead it is tried without this stub section.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
.sp
Default: no
.UNINDENT
@@ -4047,9 +4183,11 @@ This is useful when you want immediate changes to be visible.
.sp
Default: no
.UNINDENT
.SS Forward Zone Options
.SH FORWARD ZONE OPTIONS
.sp
There may be multiple \fBforward\-zone:\fP clauses.
These options are part of the \fBforward\-zone:\fP section.
.sp
There may be multiple \fBforward\-zone:\fP sections.
Each with a \fI\%name\fP and zero or more hostnames
or IP addresses.
For the forward zone this list of nameservers is used to forward the queries
@@ -4080,6 +4218,23 @@ This is the full domain name of the zone.
Name of server to forward to.
Is itself resolved before it is used.
.sp
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
If the domain (or a subdomain) from this zone is used as the host, it
will unavoidably introduce a circular dependency on retrieving the IP
addresses of the name server.
In that case, it is suggested to use
\fI\%forward\-addr\fP instead.
Alternatively,
\fI\%forward\-first: yes\fP can also
work around the circular dependency by trying resolution outside of
this zone.
However this has the caveat that it would allow escaping this zone when
any resolution attempt fails within this zone.
.UNINDENT
.UNINDENT
.sp
To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the
port number.
.sp
@@ -4116,9 +4271,11 @@ The cert must also match a CA from the
.INDENT 0.0
.TP
.B forward\-first: \fI<yes or no>\fP
If a forwarded query is met with a SERVFAIL error, and this option is
enabled, Unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified.
If a forwarded query is met with a SERVFAIL error and this option is
enabled Unbound will fall back to less specific resolution.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
.sp
Default: no
.UNINDENT
@@ -4156,12 +4313,14 @@ This is useful when you want immediate changes to be visible.
.sp
Default: no
.UNINDENT
.SS Authority Zone Options
.SH AUTHORITY ZONE OPTIONS
.sp
These options are part of the \fBauth\-zone:\fP section.
.sp
Authority zones are configured with \fBauth\-zone:\fP, and each one must have a
\fI\%name\fP\&.
There can be multiple ones, by listing multiple auth\-zone clauses, each with a
different name, pertaining to that part of the namespace.
There can be multiple ones, by listing multiple \fBauth\-zone\fP section clauses,
each with a different name, pertaining to that part of the namespace.
The authority zone with the name closest to the name looked up is used.
Authority zones can be processed on two distinct, non\-exclusive, configurable
stages.
@@ -4192,7 +4351,7 @@ consult the local zone data while resolving.
In this case, the aforementioned CNAME example will result in a thoroughly
resolved answer.
.sp
Authority zones can be read from zonefile.
Authority zones can be read from a zonefile.
And can be kept updated via AXFR and IXFR.
After update the zonefile is rewritten.
The update mechanism uses the SOA timer values and performs SOA UDP queries to
@@ -4229,9 +4388,15 @@ does not support AXFR/IXFR for the zone, but if you used
\fI\%url\fP to download the zonefile as a text file
from a webserver that would work.
.sp
If you specify the hostname, you cannot use the domain from the zonefile,
because it may not have that when retrieving that data, instead use a plain
IP address to avoid a circular dependency on retrieving that IP address.
\fBCAUTION:\fP
.INDENT 7.0
.INDENT 3.5
If you specify the hostname, you cannot use the domain from the
zonefile, because it may not have that when retrieving that data,
instead use a plain IP address to avoid a circular dependency on
retrieving that IP address.
.UNINDENT
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
@@ -4377,18 +4542,20 @@ If not given then no zonefile is used.
If the file does not exist or is empty, Unbound will attempt to fetch zone
data (eg. from the primary servers).
.UNINDENT
.SS View Options
.SH VIEW OPTIONS
.sp
There may be multiple \fBview:\fP clauses.
These options are part of the \fBview:\fP section.
.sp
There may be multiple \fBview:\fP sections.
Each with a \fI\%name\fP and zero or more
\fI\%local\-zone\fP and
\fI\%local\-data\fP attributes.
\fI\%local\-data\fP options.
Views can also contain \fI\%view\-first\fP,
\fI\%response\-ip\fP,
\fI\%response\-ip\-data\fP and
\fI\%local\-data\-ptr\fP attributes.
\fI\%local\-data\-ptr\fP options.
View can be mapped to requests by specifying the view name in an
\fI\%access\-control\-view\fP attribute.
\fI\%access\-control\-view\fP option.
Options from matching views will override global options.
Global options will be used if no matching view is found, or when the matching
view does not have the option specified.
@@ -4398,7 +4565,7 @@ view does not have the option specified.
Name of the view.
Must be unique.
This name is used in the
\fI\%access\-control\-view\fP attribute.
\fI\%access\-control\-view\fP option.
.UNINDENT
.INDENT 0.0
.TP
@@ -4431,6 +4598,22 @@ Has the same behaviour as the global
.UNINDENT
.INDENT 0.0
.TP
.B response\-ip: \fI<IP\-netblock> <action>\fP
This requires use of the \fBrespip\fP module.
.sp
Similar to \fI\%response\-ip\fP but
only applies to this view.
.UNINDENT
.INDENT 0.0
.TP
.B response\-ip\-data: \fI<IP\-netblock> <\(dqresource record string\(dq>\fP
This requires use of the \fBrespip\fP module.
.sp
Similar to \fI\%response\-ip\-data\fP but
only applies to this view.
.UNINDENT
.INDENT 0.0
.TP
.B view\-first: \fI<yes or no>\fP
If enabled, it attempts to use the global
\fI\%local\-zone\fP and
@@ -4439,9 +4622,11 @@ view specific options.
.sp
Default: no
.UNINDENT
.SS Python Module Options
.SH PYTHON MODULE OPTIONS
.sp
The \fBpython:\fP clause gives the settings for the \fIpython(1)\fP script module.
These options are part of the \fBpython:\fP section.
.sp
The \fBpython:\fP section gives the settings for the \fIpython(1)\fP script module.
This module acts like the iterator and validator modules do, on queries and
answers.
To enable the script module it has to be compiled into the daemon, and the word
@@ -4464,14 +4649,16 @@ The script file to load.
Repeat this option for every python module instance added to the
\fI\%module\-config\fP option.
.UNINDENT
.SS Dynamic Library Module Options
.SH DYNAMIC LIBRARY MODULE OPTIONS
.sp
The \fBdynlib:\fP clause gives the settings for the \fBdynlib\fP module.
These options are part of the \fBdynlib:\fP section.
.sp
The \fBdynlib:\fP section gives the settings for the \fBdynlib\fP module.
This module is only a very small wrapper that allows dynamic modules to be
loaded on runtime instead of being compiled into the application.
To enable the dynlib module it has to be compiled into the daemon, and the word
\fBdynlib\fP has to be put in the
\fI\%module\-config\fP attribute.
\fI\%module\-config\fP option.
Multiple instances of dynamic libraries are supported by adding the word
\fBdynlib\fP more than once.
.sp
@@ -4486,7 +4673,9 @@ The dynamic library file to load.
Repeat this option for every dynlib module instance added to the
\fI\%module\-config\fP option.
.UNINDENT
.SS DNS64 Module Options
.SH DNS64 MODULE OPTIONS
.sp
These options are part of the \fBserver:\fP section.
.sp
The \fBdns64\fP module must be configured in the
\fI\%module\-config\fP directive, e.g.:
@@ -4506,7 +4695,11 @@ and be compiled into the daemon to be enabled.
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
These settings go in the \fI\%server:\fP section.
If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module
needs to appear before the \fBdns64\fP module in the
\fI\%module\-config\fP
configuration option so that response IP and/or RPZ feeds can properly
filter responses regardless of DNS64 synthesis.
.UNINDENT
.UNINDENT
.INDENT 0.0
@@ -4542,12 +4735,12 @@ Can be entered multiple times, list a new domain for which it applies, one
per line.
Applies also to names underneath the name given.
.UNINDENT
.SS NAT64 Operation
.SH NAT64 OPTIONS
.sp
These options are part of the \fBserver:\fP section.
.sp
NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4\-only
servers.
It is controlled by two options in the
\fI\%server:\fP section:
.INDENT 0.0
.TP
.B do\-nat64: \fI<yes or no>\fP
@@ -4565,9 +4758,11 @@ The prefix length must be one of /32, /40, /48, /56, /64 or /96.
.sp
Default: 64:ff9b::/96 (same as \fI\%dns64\-prefix\fP)
.UNINDENT
.SS DNSCrypt Options
.SH DNSCRYPT OPTIONS
.sp
The \fBdnscrypt:\fP clause gives the settings of the dnscrypt channel.
These options are part of the \fBdnscrypt:\fP section.
.sp
The \fBdnscrypt:\fP section gives the settings of the dnscrypt channel.
While those options are available, they are only meaningful if Unbound was
compiled with \fB\-\-enable\-dnscrypt\fP\&.
Currently certificate and secret/public keys cannot be generated by Unbound.
@@ -4697,7 +4892,9 @@ If left unconfigured, it will be configured automatically to be a power of
.sp
Default: (unconfigured)
.UNINDENT
.SS EDNS Client Subnet Module Options
.SH EDNS CLIENT SUBNET MODULE OPTIONS
.sp
These options are part of the \fBserver:\fP section.
.sp
The ECS module must be configured in the
\fI\%module\-config\fP directive, e.g.:
@@ -4714,13 +4911,6 @@ module\-config: \(dqsubnetcache validator iterator\(dq
.sp
and be compiled into the daemon to be enabled.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
These settings go in the \fI\%server:\fP section.
.UNINDENT
.UNINDENT
.sp
If the destination address is allowed in the configuration Unbound will add the
EDNS0 option to the query containing the relevant part of the client\(aqs address.
When an answer contains the ECS option the response and the option are placed
@@ -4842,7 +5032,9 @@ This number applies for each qname/qclass/qtype tuple.
.sp
Default: 100
.UNINDENT
.SS Opportunistic IPsec Support Module Options
.SH OPPORTUNISTIC IPSEC SUPPORT MODULE OPTIONS
.sp
These options are part of the \fBserver:\fP section.
.sp
The IPsec module must be configured in the
\fI\%module\-config\fP directive, e.g.:
@@ -4859,13 +5051,6 @@ module\-config: \(dqipsecmod validator iterator\(dq
.sp
and be compiled into Unbound by using \fB\-\-enable\-ipsecmod\fP to be enabled.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
These settings go in the \fI\%server:\fP section.
.UNINDENT
.UNINDENT
.sp
When Unbound receives an A/AAAA query that is not in the cache and finds a
valid answer, it will withhold returning the answer and instead will generate
an IPSECKEY subquery for the same domain name.
@@ -4963,7 +5148,9 @@ If the option is not specified, all domains are treated as being allowed
.B ipsecmod\-whitelist: \fI<domain>\fP
Alternate syntax for \fI\%ipsecmod\-allow\fP\&.
.UNINDENT
.SS Cache DB Module Options
.SH CACHE DB MODULE OPTIONS
.sp
These options are part of the \fBcachedb:\fP section.
.sp
The Cache DB module must be configured in the
\fI\%module\-config\fP directive, e.g.:
@@ -5025,7 +5212,7 @@ If connection close or timeout happens too often, Unbound will be effectively
unusable with this backend.
It\(aqs the administrator\(aqs responsibility to make the assumption hold.
.sp
The \fBcachedb:\fP clause gives custom settings of the cache DB module.
The \fBcachedb:\fP section gives custom settings of the cache DB module.
.INDENT 0.0
.TP
.B backend: \fI<backend name>\fP
@@ -5253,10 +5440,13 @@ for the Redis replica server.
.sp
Default: 0
.UNINDENT
.SS DNSTAP Logging Options
.SH DNSTAP OPTIONS
.sp
DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fP, is enabled in
the \fBdnstap:\fP section.
These options are part of the \fBdnstap:\fP section.
.sp
DNSTAP is a flexible, structured binary log format for DNS software.
When compiled in by using \fB\-\-enable\-dnstap\fP, it can be enabled in the
\fBdnstap:\fP section.
This starts an extra thread (when compiled with threading) that writes the log
information to the destination.
If Unbound is compiled without threading it does not spawn a thread, but
@@ -5422,15 +5612,18 @@ Enable to log forwarder response messages.
.sp
Default: no
.UNINDENT
.SS Response Policy Zone Options
.SH RESPONSE POLICY ZONE OPTIONS
.sp
Response Policy Zones are configured with \fBrpz:\fP, and each one must have a
\fI\%name\fP attribute.
There can be multiple ones, by listing multiple RPZ clauses, each with a
different name.
RPZ clauses are applied in order of configuration and any match from an earlier
RPZ zone will terminate the RPZ lookup.
These options are part of the \fBrpz:\fP section.
.sp
Response Policy Zones are configured with \fBrpz:\fP section clauses, and each
one must have a \fI\%name\fP option.
There can be multiple ones, by listing multiple \fBrpz:\fP section clauses, each
with a different name.
RPZ sections are applied in order of configuration and any match from an
earlier RPZ zone will terminate the RPZ lookup.
Note that a PASSTHRU action is still considered a match.
.sp
The respip module needs to be added to the
\fI\%module\-config\fP, e.g.:
.INDENT 0.0
@@ -5444,6 +5637,17 @@ module\-config: \(dqrespip validator iterator\(dq
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module
needs to appear before the \fBdns64\fP module in the
\fI\%module\-config\fP
configuration option so that response IP and/or RPZ feeds can properly
filter responses regardless of DNS64 synthesis.
.UNINDENT
.UNINDENT
.sp
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
and drop.
@@ -5512,9 +5716,6 @@ A 192.0.2.1 answer with this IP address
.sp
Other records like AAAA, TXT and other CNAMEs (not rpz\-..) can also be used to
answer queries with that content.
.sp
The RPZ zones can be configured in the config file with these settings in the
\fBrpz:\fP block.
.INDENT 0.0
.TP
.B name: \fI<zone name>\fP
@@ -5653,7 +5854,7 @@ Default: no
.INDENT 0.0
.TP
.B tags: \fI\(dq<list of tags>\(dq\fP
Limit the policies from this RPZ clause to clients with a matching tag.
Limit the policies from this RPZ section to clients with a matching tag.
.sp
Tags need to be defined in \fI\%define\-tag\fP and
can be assigned to client addresses using
@@ -5661,7 +5862,7 @@ can be assigned to client addresses using
\fI\%interface\-tag\fP\&.
Enclose list of tags in quotes (\fB\(dq\(dq\fP) and put spaces between tags.
.sp
If no tags are specified the policies from this clause will be applied for
If no tags are specified the policies from this section will be applied for
all clients.
.UNINDENT
.SH MEMORY CONTROL EXAMPLE
@@ -5730,6 +5931,6 @@ Default is to log to \fIsyslog(3)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
1999-2026, NLnet Labs
.\" Generated by docutils manpage writer.
.
+323 -136
View File
@@ -46,34 +46,41 @@ Description
-----------
**unbound.conf** is used to configure :doc:`unbound(8)</manpages/unbound>`.
The file format has attributes and values.
Some attributes have attributes inside them.
The notation is: ``attribute: value``.
Comments start with ``#`` and last to the end of line.
Empty lines are ignored as is whitespace at the beginning of a line.
The utility :doc:`unbound-checkconf(8)</manpages/unbound-checkconf>` can be
used to check ``unbound.conf`` prior to usage.
File Format
-----------
Whitespace is used to separate keywords.
Whitespace indentation is insignificant, but is still recommended for visual
clarity.
Comments start with ``#`` and last to the end of line.
Empty lines are ignored, as is whitespace at the beginning of a line.
Attribute keywords end with a colon (``:``) and they are either options or
section clauses (group options together).
The configuration file is logically divided into **sections** where each section
is introduced by a :ref:`section clause<unbound.conf.clauses>`.
Example
-------
An example config file is shown below.
Copy this to :file:`/etc/unbound/unbound.conf` and start the server with:
An example minimal config file is shown below; most settings are the defaults.
Copy this to ``@ub_conf_file@`` and start the server with:
.. code-block:: text
$ unbound -c /etc/unbound/unbound.conf
$ unbound -c @ub_conf_file@
Most settings are the defaults.
Stop the server with:
.. code-block:: text
$ kill `cat /etc/unbound/unbound.pid`
$ kill `cat @UNBOUND_PIDFILE@`
Below is a minimal config file.
The source distribution contains an extensive :file:`example.conf` file with
all the options.
@@ -81,35 +88,87 @@ all the options.
# unbound.conf(5) config file for unbound(8).
server:
directory: "/etc/unbound"
directory: "@UNBOUND_RUN_DIR@"
username: unbound
# make sure unbound can access entropy from inside the chroot.
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
# mount --bind -n /dev/urandom /etc/unbound/dev/urandom
# and mount --bind -n /dev/log /etc/unbound/dev/log
chroot: "/etc/unbound"
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
pidfile: "/etc/unbound/unbound.pid"
# mount --bind -n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom
# and mount --bind -n /dev/log @UNBOUND_RUN_DIR@/dev/log
chroot: "@UNBOUND_CHROOT_DIR@"
# logfile: "@UNBOUND_RUN_DIR@/unbound.log" #uncomment to use logfile.
pidfile: "@UNBOUND_PIDFILE@"
# verbosity: 1 # uncomment and increase to get more logging.
# listen on all interfaces, answer queries from the local subnet.
interface: 0.0.0.0
interface: ::0
access-control: 10.0.0.0/8 allow
access-control: 2001:DB8::/64 allow
access-control: 2001:db8::/64 allow
File Format
-----------
.. _unbound.conf.clauses:
There must be whitespace between keywords.
Attribute keywords end with a colon ``':'``.
An attribute is followed by a value, or its containing attributes in which case
it is referred to as a clause.
Clauses can be repeated throughout the file (or included files) to group
attributes under the same clause.
Section Clauses
---------------
The recognized section clauses are:
:ref:`server:<unbound.conf.server>`
Most of the configuration is found in this section.
:ref:`remote-control:<unbound.conf.remote>`
Configuration for the facility used by
:doc:`unbound-control(8)</manpages/unbound-control>`.
:ref:`stub-zone:<unbound.conf.stub>`
Configuration for a zone that redirects to specific authoritative name
servers, e.g. for zones not generally available on the greater
Internet.
:ref:`forward-zone:<unbound.conf.forward>`
Configuration for a zone that forwards to specific DNS resolvers.
:ref:`auth-zone:<unbound.conf.auth>`
Configuration for local authoritative zones.
:ref:`view:<unbound.conf.view>`
Overriding a small subset of configuration for incoming requests.
Requests are mapped to views with
:ref:`access-control-view<unbound.conf.access-control-view>` and
:ref:`interface-view<unbound.conf.interface-view>`.
:ref:`python:<unbound.conf.python>`
Configuration for the optional ``python`` script module.
:ref:`dynlib:<unbound.conf.dynlib>`
Configuration for the optional ``dynlib`` module that loads dynamic
libraries into Unbound.
:ref:`dnscrypt:<unbound.conf.dnscrypt>`
Configuration for the optional DNSCrypt feature.
:ref:`cachedb:<unbound.conf.cachedb>`
Configuration for the optional ``cachedb`` module that can interface
with second level caches, currently Redis or Redis-complatible
databases.
:ref:`dnstap:<unbound.conf.dnstap>`
Configuration of the optional dnstap logging feature; a flexible,
structured binary log format for DNS software.
:ref:`rpz:<unbound.conf.rpz>`
Configuration for Response Policy Zones that allows for DNS filtering.
Requires the ``respip`` module.
Section clauses can be repeated throughout the file (or included files) to
logically group options in one visually cohesive group.
This may be particularly useful for the ``server:`` clause with its myriad of
options.
.. _unbound.conf.include:
Files can be included using the **include:** directive.
Including Files
---------------
Files can be included using the ``include:`` directive.
It can appear anywhere, it accepts a single file name as argument.
Processing continues as if the text from the included file was copied into the
config file at that point.
@@ -122,17 +181,17 @@ Wildcards can be used to include multiple files, see *glob(7)*.
.. _unbound.conf.include-toplevel:
For a more structural include option, the **include-toplevel:** directive can
For a more structural include option, the ``include-toplevel:`` directive can
be used.
This closes whatever clause is currently active (if any) and forces the use of
clauses in the included files and right after this directive.
This closes whatever section clause is currently active (if any) and forces the
use of section clauses in the included files and right after this directive.
.. _unbound.conf.server:
Server Options
^^^^^^^^^^^^^^
--------------
These options are part of the **server:** clause.
These options are part of the ``server:`` section.
@@UAHL@unbound.conf@verbosity@@: *<number>*
@@ -496,6 +555,9 @@ These options are part of the **server:** clause.
The wait time in msec where recursion requests are dropped.
This is to stop a large number of replies from accumulating.
They receive no reply, the work item continues to recurse.
For UDP the replies are dropped, for stream connections the reply
is not dropped if the stream connection is still open ready to receive
answers.
It is nice to be a bit larger than
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
if that is enabled.
@@ -510,7 +572,7 @@ These options are part of the **server:** clause.
This makes a ratelimit per IP address of waiting replies for recursion.
It stops very large amounts of queries waiting to be returned to one
destination.
The value ``0`` disables wait limits.
The value ``0`` disables all wait limits.
Default: 1000
@@ -518,7 +580,11 @@ These options are part of the **server:** clause.
@@UAHL@unbound.conf@wait-limit-cookie@@: *<number>*
The number of replies that can wait for recursion, for an IP address
that sent the query with a valid DNS Cookie.
Since the cookie validates the client address, this limit can be higher.
Since the cookie already validates the client address, this option allows
to override a configured
:ref:`wait-limit<unbound.conf.wait-limit>` value usually with a higher one
for cookie validated queries.
The value ``0`` disables wait limits for cookie validated queries.
Default: 10000
@@ -1049,8 +1115,8 @@ These options are part of the **server:** clause.
@@UAHL@unbound.conf@tls-system-cert@@: *<yes or no>*
This the same attribute as the
:ref:`tls-win-cert<unbound.conf.tls-win-cert>` attribute, under a
This the same as the
:ref:`tls-win-cert<unbound.conf.tls-win-cert>` option, under a
different name.
Because it is not windows specific.
@@ -1103,6 +1169,30 @@ These options are part of the **server:** clause.
Default: ""
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
Enable or disable sending the SNI extension on TLS connections.
.. note:: Changing the value requires a reload.
Default: yes
@@UAHL@unbound.conf@tls-use-system-policy-versions@@: *<yes or no>*
Enable or disable general-puspose version-flexible TLS server configuration
when serving TLS.
This will allow the whole list of available TLS versions provided by the
crypto library, which may have been further restricted by the system's
crypto policy.
By default Unbound only uses the latest available TLS version.
.. caution:: Use only if you want to support legacy TLS client connections.
.. note:: Changing the value requires a reload.
Default: no
@@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
If enabled, TLS serviced queries that contained an EDNS Padding option will
cause responses padded to the closest multiple of the size specified in
@@ -1132,14 +1222,6 @@ These options are part of the **server:** clause.
Default: 128
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
Enable or disable sending the SNI extension on TLS connections.
.. note:: Changing the value requires a reload.
Default: yes
@@UAHL@unbound.conf@https-port@@: *<number>*
The port number on which to provide DNS-over-HTTPS service.
Only interfaces configured with that port number as @number get the HTTPS
@@ -1224,6 +1306,9 @@ These options are part of the **server:** clause.
Only interfaces configured with that port number as @number get the QUIC
service.
The interface uses QUIC for the UDP traffic on that port number.
If it is set to 0, the server does not init QUIC code, and QUIC is
disabled.
This is similar to if QUIC is not in use, but then explicitly.
Default: 853
@@ -1421,8 +1506,8 @@ These options are part of the **server:** clause.
.. note::
The interface needs to be already specified with
:ref:`interface<unbound.conf.interface>` and that any
**access-control\*:** attribute overrides all **interface-\*:**
attributes for targeted clients.
**access-control\*:** option overrides all **interface-\*:**
options for targeted clients.
@@UAHL@unbound.conf@interface-tag@@: *<ip address or interface name [@port]> <"list of tags">*
@@ -1432,8 +1517,8 @@ These options are part of the **server:** clause.
.. note::
The interface needs to be already specified with
:ref:`interface<unbound.conf.interface>` and that any
**access-control\*:** attribute overrides all **interface-\*:**
attributes for targeted clients.
**access-control\*:** option overrides all **interface-\*:**
options for targeted clients.
@@UAHL@unbound.conf@interface-tag-action@@: *<ip address or interface name [@port]> <tag> <action>*
@@ -1444,8 +1529,8 @@ These options are part of the **server:** clause.
.. note::
The interface needs to be already specified with
:ref:`interface<unbound.conf.interface>` and that any
**access-control\*:** attribute overrides all **interface-\*:**
attributes for targeted clients.
**access-control\*:** option overrides all **interface-\*:**
options for targeted clients.
@@UAHL@unbound.conf@interface-tag-data@@: *<ip address or interface name [@port]> <tag> <"resource record string">*
@@ -1456,8 +1541,8 @@ These options are part of the **server:** clause.
.. note::
The interface needs to be already specified with
:ref:`interface<unbound.conf.interface>` and that any
**access-control\*:** attribute overrides all **interface-\*:**
attributes for targeted clients.
**access-control\*:** option overrides all **interface-\*:**
options for targeted clients.
@@UAHL@unbound.conf@interface-view@@: *<ip address or interface name [@port]> <view name>*
@@ -1467,8 +1552,8 @@ These options are part of the **server:** clause.
.. note::
The interface needs to be already specified with
:ref:`interface<unbound.conf.interface>` and that any
**access-control\*:** attribute overrides all **interface-\*:**
attributes for targeted clients.
**access-control\*:** option overrides all **interface-\*:**
options for targeted clients.
@@UAHL@unbound.conf@chroot@@: *<directory>*
@@ -1533,7 +1618,7 @@ These options are part of the **server:** clause.
[seconds since 1970] unbound[pid:tid]: type: message.
If this option is given, the :ref:`use-syslog<unbound.conf.use-syslog>`
attribute is internally set to ``no``.
option is internally set to ``no``.
The logfile is reopened (for append) when the config file is reread, on
SIGHUP.
@@ -1632,6 +1717,15 @@ These options are part of the **server:** clause.
Default: no
@@UAHL@unbound.conf@log-thread-id@@: *<yes or no>*
(Only on Linux and only when threads are available)
Logs the system-wide Linux thread ID instead of Unbound's internal thread
counter.
Can be useful when debugging with system tools.
Default: no
@@UAHL@unbound.conf@pidfile@@: *<filename>*
The process id is written to the file.
Default is :file:`"@UNBOUND_PIDFILE@"`.
@@ -1657,8 +1751,8 @@ These options are part of the **server:** clause.
Default is nothing, using builtin hints for the IN class.
The file has the format of zone files, with root nameserver names and
addresses only.
The default may become outdated, when servers change, therefore it is good
practice to use a root hints file.
The default may become outdated, when servers change, and then it is
possible to use a root hints file with specific servers.
Default: ""
@@ -1744,7 +1838,7 @@ These options are part of the **server:** clause.
@@UAHL@unbound.conf@harden-short-bufsize@@: *<yes or no>*
Very small EDNS buffer sizes from queries are ignored.
Default: yes (as described in the standard)
Default: yes (per :rfc:`6891`)
@@UAHL@unbound.conf@harden-large-queries@@: *<yes or no>*
@@ -2306,6 +2400,12 @@ These options are part of the **server:** clause.
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
is also used then it is RECOMMENDED to use 30 as the value (:rfc:`8767`).
This value is capped by the original TTL of the record.
This means that records with higher original TTL than this value will use
this value for expired replies.
Records with lower original TTL than this value will use their original TTL
for expired replies.
Default: 30
@@ -2808,7 +2908,7 @@ These options are part of the **server:** clause.
Configure local data shorthand for a PTR record with the reversed IPv4 or
IPv6 address and the host name.
For example ``"192.0.2.4 www.example.com"``.
TTL can be inserted like this: ``"2001:DB8::4 7200 www.example.com"``
TTL can be inserted like this: ``"2001:db8::4 7200 www.example.com"``
@@UAHL@unbound.conf@local-zone-tag@@: *<zone> <"list of tags">*
@@ -2861,7 +2961,7 @@ These options are part of the **server:** clause.
:ref:`response-ip<unbound.conf.response-ip>` with action being to redirect
as specified by *<"resource record string">*.
*<"Resource record string">* is similar to that of
:ref:`access-control-tag-action<unbound.conf.access-control-tag-action>`,
:ref:`access-control-tag-data<unbound.conf.access-control-tag-data>`,
but it must be of either AAAA, A or CNAME types.
If the *<IP-netblock>* is an IPv6/IPv4 prefix, the record must be AAAA/A
respectively, unless it is a CNAME (which can be used for both versions of
@@ -3290,17 +3390,18 @@ These options are part of the **server:** clause.
.. _unbound.conf.remote:
Remote Control Options
^^^^^^^^^^^^^^^^^^^^^^
----------------------
These options are part of the ``remote-control:`` section and are the
declarations for the remote control facility.
In the **remote-control:** clause are the declarations for the remote control
facility.
If this is enabled, the :doc:`unbound-control(8)</manpages/unbound-control>`
utility can be used to send commands to the running Unbound server.
The server uses these clauses to setup TLSv1 security for the connection.
The :doc:`unbound-control(8)</manpages/unbound-control>` utility also reads the
**remote-control:** section for options.
The server uses these options to setup TLS security for the connection.
The :doc:`unbound-control(8)</manpages/unbound-control>` utility also reads
this ``remote-control:`` section for options.
To setup the correct self-signed certificates use the
*unbound-control-setup(8)* utility.
``unbound-control-setup(8)`` utility.
@@UAHL@unbound.conf.remote@control-enable@@: *<yes or no>*
@@ -3392,9 +3493,11 @@ To setup the correct self-signed certificates use the
.. _unbound.conf.stub:
Stub Zone Options
^^^^^^^^^^^^^^^^^
-----------------
There may be multiple **stub-zone:** clauses.
These options are part of the ``stub-zone:`` section.
There may be multiple ``stub-zone:`` sections.
Each with a :ref:`name<unbound.conf.stub.name>` and zero or more hostnames or
IP addresses.
For the stub zone this list of nameservers is used.
@@ -3427,9 +3530,10 @@ Consider adding :ref:`server<unbound.conf.server>` statements for
:ref:`domain-insecure<unbound.conf.domain-insecure>` and for
:ref:`local-zone: \<name\> nodefault<unbound.conf.local-zone.type.nodefault>`
for the zone if it is a locally served zone.
The insecure clause stops DNSSEC from invalidating the zone.
The :ref:`domain-insecure<unbound.conf.domain-insecure>` option stops DNSSEC
from invalidating the zone.
The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
:ref:`transparent<unbound.conf.local-zone.type.transparent>`) clause makes the
:ref:`transparent<unbound.conf.local-zone.type.transparent>`) option makes the
(reverse-) zone bypass Unbound's filtering of :rfc:`1918` zones.
@@ -3442,6 +3546,19 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
Name of stub zone nameserver.
Is itself resolved before it is used.
.. caution::
If the domain (or a subdomain) from this zone is used as the host, it
will unavoidably introduce a circular dependency on retrieving the IP
addresses of the name server.
In that case, it is suggested to use
:ref:`stub-addr<unbound.conf.stub.stub-addr>` instead.
Alternatively,
:ref:`stub-first: yes<unbound.conf.stub.stub-first>` can also work
around the circular dependency by trying resolution outside of this
zone.
However this has the caveat that it would allow escaping this zone when
any resolution attempt fails within this zone.
To use a non-default port for DNS communication append ``'@'`` with the
port number.
@@ -3479,9 +3596,12 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
@@UAHL@unbound.conf.stub@stub-first@@: *<yes or no>*
If enabled, a query is attempted without the stub clause if it fails.
If enabled, a query is attempted without this stub section if it fails.
The data could not be retrieved and would have caused SERVFAIL because the
servers are unreachable, instead it is tried without this clause.
servers are unreachable, instead it is tried without this stub section.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
Default: no
@@ -3513,9 +3633,11 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
.. _unbound.conf.forward:
Forward Zone Options
^^^^^^^^^^^^^^^^^^^^
--------------------
There may be multiple **forward-zone:** clauses.
These options are part of the ``forward-zone:`` section.
There may be multiple ``forward-zone:`` sections.
Each with a :ref:`name<unbound.conf.forward.name>` and zero or more hostnames
or IP addresses.
For the forward zone this list of nameservers is used to forward the queries
@@ -3545,6 +3667,19 @@ cache).
Name of server to forward to.
Is itself resolved before it is used.
.. caution::
If the domain (or a subdomain) from this zone is used as the host, it
will unavoidably introduce a circular dependency on retrieving the IP
addresses of the name server.
In that case, it is suggested to use
:ref:`forward-addr<unbound.conf.forward.forward-addr>` instead.
Alternatively,
:ref:`forward-first: yes<unbound.conf.forward.forward-first>` can also
work around the circular dependency by trying resolution outside of
this zone.
However this has the caveat that it would allow escaping this zone when
any resolution attempt fails within this zone.
To use a non-default port for DNS communication append ``'@'`` with the
port number.
@@ -3579,9 +3714,11 @@ cache).
@@UAHL@unbound.conf.forward@forward-first@@: *<yes or no>*
If a forwarded query is met with a SERVFAIL error, and this option is
enabled, Unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified.
If a forwarded query is met with a SERVFAIL error and this option is
enabled Unbound will fall back to less specific resolution.
This can lead to using less specific configured forward/stub/auth zones if
any, or end up to otherwise normal recursive resolution for that particular
query.
Default: no
@@ -3618,12 +3755,14 @@ cache).
.. _unbound.conf.auth:
Authority Zone Options
^^^^^^^^^^^^^^^^^^^^^^
----------------------
Authority zones are configured with **auth-zone:**, and each one must have a
These options are part of the ``auth-zone:`` section.
Authority zones are configured with ``auth-zone:``, and each one must have a
:ref:`name<unbound.conf.auth.name>`.
There can be multiple ones, by listing multiple auth-zone clauses, each with a
different name, pertaining to that part of the namespace.
There can be multiple ones, by listing multiple ``auth-zone`` section clauses,
each with a different name, pertaining to that part of the namespace.
The authority zone with the name closest to the name looked up is used.
Authority zones can be processed on two distinct, non-exclusive, configurable
stages.
@@ -3654,7 +3793,7 @@ consult the local zone data while resolving.
In this case, the aforementioned CNAME example will result in a thoroughly
resolved answer.
Authority zones can be read from zonefile.
Authority zones can be read from a zonefile.
And can be kept updated via AXFR and IXFR.
After update the zonefile is rewritten.
The update mechanism uses the SOA timer values and performs SOA UDP queries to
@@ -3690,9 +3829,11 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
:ref:`url<unbound.conf.auth.url>` to download the zonefile as a text file
from a webserver that would work.
If you specify the hostname, you cannot use the domain from the zonefile,
because it may not have that when retrieving that data, instead use a plain
IP address to avoid a circular dependency on retrieving that IP address.
.. caution::
If you specify the hostname, you cannot use the domain from the
zonefile, because it may not have that when retrieving that data,
instead use a plain IP address to avoid a circular dependency on
retrieving that IP address.
@@UAHL@unbound.conf.auth@master@@: *<IP address or host name>*
@@ -3823,18 +3964,20 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
.. _unbound.conf.view:
View Options
^^^^^^^^^^^^
------------
There may be multiple **view:** clauses.
These options are part of the ``view:`` section.
There may be multiple ``view:`` sections.
Each with a :ref:`name<unbound.conf.view.name>` and zero or more
:ref:`local-zone<unbound.conf.view.local-zone>` and
:ref:`local-data<unbound.conf.view.local-data>` attributes.
:ref:`local-data<unbound.conf.view.local-data>` options.
Views can also contain :ref:`view-first<unbound.conf.view.view-first>`,
:ref:`response-ip<unbound.conf.response-ip>`,
:ref:`response-ip-data<unbound.conf.response-ip-data>` and
:ref:`local-data-ptr<unbound.conf.view.local-data-ptr>` attributes.
:ref:`local-data-ptr<unbound.conf.view.local-data-ptr>` options.
View can be mapped to requests by specifying the view name in an
:ref:`access-control-view<unbound.conf.access-control-view>` attribute.
:ref:`access-control-view<unbound.conf.access-control-view>` option.
Options from matching views will override global options.
Global options will be used if no matching view is found, or when the matching
view does not have the option specified.
@@ -3844,7 +3987,7 @@ view does not have the option specified.
Name of the view.
Must be unique.
This name is used in the
:ref:`access-control-view<unbound.conf.access-control-view>` attribute.
:ref:`access-control-view<unbound.conf.access-control-view>` option.
@@UAHL@unbound.conf.view@local-zone@@: *<zone> <type>*
@@ -3873,6 +4016,20 @@ view does not have the option specified.
:ref:`local-data-ptr<unbound.conf.local-data-ptr>` elements.
@@UAHL@unbound.conf.view@response-ip@@: *<IP-netblock> <action>*
This requires use of the ``respip`` module.
Similar to :ref:`response-ip<unbound.conf.response-ip>` but
only applies to this view.
@@UAHL@unbound.conf.view@response-ip-data@@: *<IP-netblock> <"resource record string">*
This requires use of the ``respip`` module.
Similar to :ref:`response-ip-data<unbound.conf.response-ip-data>` but
only applies to this view.
@@UAHL@unbound.conf.view@view-first@@: *<yes or no>*
If enabled, it attempts to use the global
:ref:`local-zone<unbound.conf.local-zone>` and
@@ -3881,10 +4038,14 @@ view does not have the option specified.
Default: no
Python Module Options
^^^^^^^^^^^^^^^^^^^^^
.. _unbound.conf.python:
The **python:** clause gives the settings for the *python(1)* script module.
Python Module Options
---------------------
These options are part of the ``python:`` section.
The ``python:`` section gives the settings for the *python(1)* script module.
This module acts like the iterator and validator modules do, on queries and
answers.
To enable the script module it has to be compiled into the daemon, and the word
@@ -3907,15 +4068,19 @@ path to the working directory.
Repeat this option for every python module instance added to the
:ref:`module-config<unbound.conf.module-config>` option.
Dynamic Library Module Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. _unbound.conf.dynlib:
The **dynlib:** clause gives the settings for the ``dynlib`` module.
Dynamic Library Module Options
------------------------------
These options are part of the ``dynlib:`` section.
The ``dynlib:`` section gives the settings for the ``dynlib`` module.
This module is only a very small wrapper that allows dynamic modules to be
loaded on runtime instead of being compiled into the application.
To enable the dynlib module it has to be compiled into the daemon, and the word
``dynlib`` has to be put in the
:ref:`module-config<unbound.conf.module-config>` attribute.
:ref:`module-config<unbound.conf.module-config>` option.
Multiple instances of dynamic libraries are supported by adding the word
``dynlib`` more than once.
@@ -3931,7 +4096,9 @@ directory.
:ref:`module-config<unbound.conf.module-config>` option.
DNS64 Module Options
^^^^^^^^^^^^^^^^^^^^
--------------------
These options are part of the ``server:`` section.
The ``dns64`` module must be configured in the
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
@@ -3943,7 +4110,11 @@ The ``dns64`` module must be configured in the
and be compiled into the daemon to be enabled.
.. note::
These settings go in the :ref:`server:<unbound.conf.server>` section.
If combining the ``respip`` and ``dns64`` modules, the ``respip`` module
needs to appear before the ``dns64`` module in the
:ref:`module-config<unbound.conf.module-config>`
configuration option so that response IP and/or RPZ feeds can properly
filter responses regardless of DNS64 synthesis.
@@UAHL@unbound.conf.dns64@dns64-prefix@@: *<IPv6 prefix>*
@@ -3969,13 +4140,13 @@ and be compiled into the daemon to be enabled.
per line.
Applies also to names underneath the name given.
NAT64 Operation
^^^^^^^^^^^^^^^
NAT64 Options
-------------
These options are part of the ``server:`` section.
NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4-only
servers.
It is controlled by two options in the
:ref:`server:<unbound.conf.server>` section:
@@UAHL@unbound.conf.nat64@do-nat64@@: *<yes or no>*
@@ -3992,10 +4163,14 @@ It is controlled by two options in the
Default: 64:ff9b::/96 (same as :ref:`dns64-prefix<unbound.conf.dns64.dns64-prefix>`)
DNSCrypt Options
^^^^^^^^^^^^^^^^
.. _unbound.conf.dnscrypt:
The **dnscrypt:** clause gives the settings of the dnscrypt channel.
DNSCrypt Options
----------------
These options are part of the ``dnscrypt:`` section.
The ``dnscrypt:`` section gives the settings of the dnscrypt channel.
While those options are available, they are only meaningful if Unbound was
compiled with ``--enable-dnscrypt``.
Currently certificate and secret/public keys cannot be generated by Unbound.
@@ -4102,7 +4277,9 @@ https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
Default: (unconfigured)
EDNS Client Subnet Module Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
---------------------------------
These options are part of the ``server:`` section.
The ECS module must be configured in the
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
@@ -4113,9 +4290,6 @@ The ECS module must be configured in the
and be compiled into the daemon to be enabled.
.. note::
These settings go in the :ref:`server:<unbound.conf.server>` section.
If the destination address is allowed in the configuration Unbound will add the
EDNS0 option to the query containing the relevant part of the client's address.
When an answer contains the ECS option the response and the option are placed
@@ -4230,7 +4404,9 @@ This module does not interact with the
Default: 100
Opportunistic IPsec Support Module Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
------------------------------------------
These options are part of the ``server:`` section.
The IPsec module must be configured in the
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
@@ -4241,9 +4417,6 @@ The IPsec module must be configured in the
and be compiled into Unbound by using ``--enable-ipsecmod`` to be enabled.
.. note::
These settings go in the :ref:`server:<unbound.conf.server>` section.
When Unbound receives an A/AAAA query that is not in the cache and finds a
valid answer, it will withhold returning the answer and instead will generate
an IPSECKEY subquery for the same domain name.
@@ -4333,8 +4506,12 @@ answer given from cache is still relevant for opportunistic IPsec.
@@UAHL@unbound.conf@ipsecmod-whitelist@@: *<domain>*
Alternate syntax for :ref:`ipsecmod-allow<unbound.conf.ipsecmod-allow>`.
.. _unbound.conf.cachedb:
Cache DB Module Options
^^^^^^^^^^^^^^^^^^^^^^^
-----------------------
These options are part of the ``cachedb:`` section.
The Cache DB module must be configured in the
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
@@ -4386,7 +4563,7 @@ If connection close or timeout happens too often, Unbound will be effectively
unusable with this backend.
It's the administrator's responsibility to make the assumption hold.
The **cachedb:** clause gives custom settings of the cache DB module.
The ``cachedb:`` section gives custom settings of the cache DB module.
@@UAHL@unbound.conf.cachedb@backend@@: *<backend name>*
@@ -4434,7 +4611,7 @@ The **cachedb:** clause gives custom settings of the cache DB module.
Default: yes
The following **cachedb:** options are specific to the ``redis`` backend.
The following ``cachedb:`` options are specific to the ``redis`` backend.
@@UAHL@unbound.conf.cachedb@redis-server-host@@: *<server address or name>*
@@ -4593,11 +4770,14 @@ The following **cachedb:** options are specific to the ``redis`` backend.
.. _unbound.conf.dnstap:
DNSTAP Logging Options
^^^^^^^^^^^^^^^^^^^^^^
DNSTAP Options
--------------
DNSTAP support, when compiled in by using ``--enable-dnstap``, is enabled in
the **dnstap:** section.
These options are part of the ``dnstap:`` section.
DNSTAP is a flexible, structured binary log format for DNS software.
When compiled in by using ``--enable-dnstap``, it can be enabled in the
``dnstap:`` section.
This starts an extra thread (when compiled with threading) that writes the log
information to the destination.
If Unbound is compiled without threading it does not spawn a thread, but
@@ -4747,15 +4927,18 @@ connects per-process to the destination.
.. _unbound.conf.rpz:
Response Policy Zone Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
----------------------------
Response Policy Zones are configured with **rpz:**, and each one must have a
:ref:`name<unbound.conf.rpz.name>` attribute.
There can be multiple ones, by listing multiple RPZ clauses, each with a
different name.
RPZ clauses are applied in order of configuration and any match from an earlier
RPZ zone will terminate the RPZ lookup.
These options are part of the ``rpz:`` section.
Response Policy Zones are configured with ``rpz:`` section clauses, and each
one must have a :ref:`name<unbound.conf.rpz.name>` option.
There can be multiple ones, by listing multiple ``rpz:`` section clauses, each
with a different name.
RPZ sections are applied in order of configuration and any match from an
earlier RPZ zone will terminate the RPZ lookup.
Note that a PASSTHRU action is still considered a match.
The respip module needs to be added to the
:ref:`module-config<unbound.conf.module-config>`, e.g.:
@@ -4763,6 +4946,13 @@ The respip module needs to be added to the
module-config: "respip validator iterator"
.. note::
If combining the ``respip`` and ``dns64`` modules, the ``respip`` module
needs to appear before the ``dns64`` module in the
:ref:`module-config<unbound.conf.module-config>`
configuration option so that response IP and/or RPZ feeds can properly
filter responses regardless of DNS64 synthesis.
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
and drop.
@@ -4814,9 +5004,6 @@ The actions are specified with the record on the right
Other records like AAAA, TXT and other CNAMEs (not rpz-..) can also be used to
answer queries with that content.
The RPZ zones can be configured in the config file with these settings in the
**rpz:** block.
@@UAHL@unbound.conf.rpz@name@@: *<zone name>*
Name of the authority zone.
@@ -4932,7 +5119,7 @@ The RPZ zones can be configured in the config file with these settings in the
@@UAHL@unbound.conf.rpz@tags@@: *"<list of tags>"*
Limit the policies from this RPZ clause to clients with a matching tag.
Limit the policies from this RPZ section to clients with a matching tag.
Tags need to be defined in :ref:`define-tag<unbound.conf.define-tag>` and
can be assigned to client addresses using
@@ -4940,7 +5127,7 @@ The RPZ zones can be configured in the config file with these settings in the
:ref:`interface-tag<unbound.conf.interface-tag>`.
Enclose list of tags in quotes (``""``) and put spaces between tags.
If no tags are specified the policies from this clause will be applied for
If no tags are specified the policies from this section will be applied for
all clients.
Memory Control Example
+1
View File
@@ -1007,6 +1007,7 @@ EXCLUDE = ./build \
libunbound/python/doc \
libunbound/python/examples \
./ldns-src \
./simdzone \
README.md \
doc/control_proto_spec.txt \
doc/requirements.txt
+1 -1
View File
@@ -42,7 +42,7 @@ unbound(8)
Synopsis
--------
**unbound** [``-hdpv``] [``-c <cfgfile>``]
**unbound** [``-hdpVv``] [``-c <cfgfile>``]
Description
-----------
+12 -4
View File
@@ -162,8 +162,15 @@ int ecs_whitelist_check(struct query_info* qinfo,
if(!ecs_is_whitelisted(sn_env->whitelist,
addr, addrlen, qinfo->qname, qinfo->qname_len,
qinfo->qclass)) {
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
qstate->no_cache_store = 0;
/* The stub or forward can have no_cache set.*/
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
verbose(VERB_ALGO, "subnet subquery is not stored globally, stuborfwd is no_cache");
} else {
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.%s",
(sq->started_no_cache_store?
" But the subnet module was started with no_cache_store for the super query, and that is still applied to this query":""));
qstate->no_cache_store = sq->started_no_cache_store;
}
}
}
return 1;
@@ -567,8 +574,8 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
&subq)) {
if(!(*qstate->env->attach_sub)(qstate, &qinf, qstate->client_info,
qflags, prime, valrec, &subq)) {
return 0;
}
if(subq) {
@@ -580,6 +587,7 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
}
subsq = (struct subnet_qstate*)subq->minfo[id];
subsq->is_subquery_nonsubnet = 1;
subsq->started_no_cache_store = sq->started_no_cache_store;
/* When the client asks 0.0.0.0/0 and the name is not treated
* as subnet, it is to be stored in the global cache.
-501
View File
@@ -1,501 +0,0 @@
#!/usr/bin/sh
# install - install a program, script, or datafile
scriptversion=2013-12-25.23; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
+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;
+5
View File
@@ -228,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 "
+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 "
+17 -1
View File
@@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
return 1;
}
/** filter out unsuitable targets
/** filter out unsuitable targets.
* Applies NAT64 if needed as well by replacing the IPv4 with the synthesized
* IPv6 address.
* @param iter_env: iterator environment with ipv6-support flag.
* @param env: module environment with infra cache.
* @param name: zone name
@@ -317,6 +319,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
!addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip4 available */
}
if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) {
struct sockaddr_storage real_addr;
socklen_t real_addrlen;
addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr,
iter_env->nat64.nat64_prefix_addrlen,
iter_env->nat64.nat64_prefix_net,
&real_addr, &real_addrlen);
log_name_addr(VERB_QUERY, "NAT64 apply: from: ",
name, &a->addr, a->addrlen);
log_name_addr(VERB_QUERY, "NAT64 apply: to: ",
name, &real_addr, real_addrlen);
a->addr = real_addr;
a->addrlen = real_addrlen;
}
/* check lameness - need zone , class info */
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
name, namelen, qtype, &lame, &dnsseclame, &reclame,
+1
View File
@@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
/**
* Select a valid, nice target to send query to.
* Sorting and removing unsuitable targets is combined.
* Adds records to the infra cache if not already there.
*
* @param iter_env: iterator module global state, with ip6 enabled and
* do-not-query-addresses.
+7 -20
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;
}
}
@@ -2436,8 +2436,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int tf_policy;
struct delegpt_addr* target;
struct outbound_entry* outq;
struct sockaddr_storage real_addr;
socklen_t real_addrlen;
int auth_fallback = 0;
uint8_t* qout_orig = NULL;
size_t qout_orig_len = 0;
@@ -3060,17 +3058,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dnssec_lame_query?" but lame_query anyway": "");
}
real_addr = target->addr;
real_addrlen = target->addrlen;
if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
&real_addr, &real_addrlen);
log_name_addr(VERB_QUERY, "applied NAT64:",
iq->dp->name, &real_addr, real_addrlen);
}
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
@@ -3082,7 +3069,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen,
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
@@ -3099,7 +3086,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
log_addr(VERB_QUERY, "error sending query to auth server",
&real_addr, real_addrlen);
&target->addr, target->addrlen);
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = SKIP_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE);
@@ -3616,7 +3603,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, INIT_REQUEST_STATE);
} else if(type == RESPONSE_TYPE_LAME) {
/* Cache the LAMEness. */
verbose(VERB_DETAIL, "query response was %sLAME",
verbose(VERB_DETAIL, "query response was categorized as %sLAME",
dnsseclame?"DNSSEC ":"");
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
log_err("mark lame: mismatch in qname and dpname");
@@ -3655,7 +3642,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* In this case, the event is just sent directly back to
* the QUERYTARGETS_STATE without resetting anything,
* because, clearly, the next target must be tried. */
verbose(VERB_DETAIL, "query response was THROWAWAY");
verbose(VERB_DETAIL, "query response was categorized as THROWAWAY");
} else {
log_warn("A query response came back with an unknown type: %d",
(int)type);
+1 -1
View File
@@ -1385,7 +1385,7 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
return UB_NOERROR;
}
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
LDNS_RR_CLASS_IN, t)) {
LDNS_RR_CLASS_IN, t, NULL)) {
lock_rw_unlock(&ctx->local_zones->lock);
return UB_NOMEM;
}
+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");
%}
+4
View File
@@ -853,6 +853,8 @@ struct ub_server_stats {
long long qquic;
/** number of queries removed due to discard-timeout */
long long num_queries_discard_timeout;
/** number of queries removed due to replyaddr limit */
long long num_queries_replyaddr_limit;
/** number of queries removed due to wait-limit */
long long num_queries_wait_limit;
/** number of dns error reports generated */
@@ -872,6 +874,8 @@ struct ub_stats_info {
long long mesh_num_states;
/** mesh stats: current number of reply (user) states */
long long mesh_num_reply_states;
/** mesh stats: current number of reply entries */
long long mesh_num_reply_addrs;
/** mesh stats: number of reply states overwritten with a new one */
long long mesh_jostled;
/** mesh stats: number of incoming queries dropped */
-11149
View File
File diff suppressed because it is too large Load Diff
+35 -10
View File
@@ -142,7 +142,7 @@ check_git_repo () {
create_temp_dir () {
# Creating temp directory
info "Creating temporary working directory"
temp_dir=`mktemp -d unbound-dist-XXXXXX`
temp_dir=`mktemp -t -d unbound-dist-XXXXXX`
info "Directory '$temp_dir' created."
cd $temp_dir
}
@@ -409,7 +409,14 @@ if [ "$DOWIN" = "yes" ]; then
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
cd unbound || error_cleanup "Unbound not exported correctly from git"
rm -rf .git .travis.yml .gitattributes .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
git submodule update --init || error_cleanup "Could not fetch submodule"
rm -rf .git .travis.yml .gitattributes .gitmodules .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
rm -rf simdzone/.git simdzone/.github simdzone/.gitignore \
simdzone/configure~ simdzone/config.h.in~ simdzone/autom4te.cache \
simdzone/cmake simdzone/CMakeLists.txt simdzone/simdzoneConfig.cmake.in \
simdzone/conanfile.txt simdzone/tests simdzone/.readthedocs.yaml \
simdzone/doc simdzone/scripts || \
error_cleanup "Failed to remove simdzone .git tracking and ci information"
# on a re-configure the cache may no longer be valid...
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
@@ -436,10 +443,14 @@ if [ "$DOWIN" = "yes" ]; then
replace_version "configure.ac" "$version" "$version2"
version="$version2"
info "Rebuilding configure script (autoconf) snapshot."
autoconf -f || error_cleanup "Autoconf failed."
autoreconf -fi || error_cleanup "Autoconf failed."
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."
rm -r simdzone/autom4te* || echo "ignored"
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
fi
if test "`uname`" = "Linux"; then
@@ -597,7 +608,15 @@ info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
cd unbound || error_cleanup "Unbound not exported correctly from git"
rm -rf .git .travis.yml .gitattributes .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
git submodule update --init || error_cleanup "Could not fetch submodule"
rm -rf .git .travis.yml .gitattributes .gitmodules .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
rm -rf simdzone/.git simdzone/.github simdzone/.gitignore \
simdzone/configure~ simdzone/config.h.in~ simdzone/autom4te.cache \
simdzone/cmake simdzone/CMakeLists.txt simdzone/simdzoneConfig.cmake.in \
simdzone/conanfile.txt simdzone/tests simdzone/.readthedocs.yaml \
simdzone/doc simdzone/scripts || \
error_cleanup "Failed to remove simdzone .git tracking and ci information"
info "Adding libtool utils (libtoolize)."
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
@@ -617,10 +636,14 @@ if [ `uname -s | grep -i -c darwin` -ne 0 ]; then
fi
info "Building configure script (autoreconf)."
autoreconf -f || error_cleanup "Autoconf failed."
autoreconf -fi || 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."
rm -r simdzone/autom4te* || echo "ignored"
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
info "Building lexer and parser."
echo "#include \"config.h\"" > util/configlexer.c || error_cleanup "Failed to create configlexer"
@@ -663,9 +686,13 @@ fi
if [ "$RECONFIGURE" = "yes" ]; then
info "Rebuilding configure script (autoconf) snapshot."
autoreconf -f || error_cleanup "Autoconf failed."
autoreconf -fi || 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."
rm -r simdzone/autom4te* || echo "ignored"
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
fi
replace_all doc/README
@@ -682,7 +709,7 @@ info "Renaming Unbound directory to unbound-$version."
cd ..
mv unbound unbound-$version || error_cleanup "Failed to rename unbound directory."
tarfile="../unbound-$version.tar.gz"
tarfile="$cwd/unbound-$version.tar.gz"
if [ -f $tarfile ]; then
(question "The file $tarfile already exists. Overwrite?" \
@@ -690,14 +717,12 @@ if [ -f $tarfile ]; then
fi
info "Creating tar unbound-$version.tar.gz"
tar czf ../unbound-$version.tar.gz unbound-$version || error_cleanup "Failed to create tar file."
tar czf $tarfile unbound-$version || error_cleanup "Failed to create tar file."
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."
+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);
+53 -6
View File
@@ -102,7 +102,7 @@ respip_set_get_tree(struct respip_set* set)
struct resp_addr*
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, int create, const char* ipstr)
socklen_t addrlen, int net, int create)
{
struct resp_addr* node;
log_assert(set);
@@ -119,7 +119,10 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage*
addrlen, net)) {
/* We know we didn't find it, so this should be
* impossible. */
log_warn("unexpected: duplicate address: %s", ipstr);
char a[128];
addr_to_str(addr, addrlen, a, sizeof(a));
log_warn("unexpected: duplicate address: %s/%d",
a, net);
}
}
return node;
@@ -154,8 +157,7 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
log_err("cannot parse netblock: '%s'", ipstr);
return NULL;
}
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
ipstr);
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create);
}
static int
@@ -291,6 +293,49 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
}
int
respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata_wol,
size_t rdata_len, const char* netblockstr)
{
struct packed_rrset_data* pd;
struct sockaddr* sa;
sa = (struct sockaddr*)&raddr->node.addr;
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
log_err("CNAME response-ip data (%s) can not co-exist with other "
"response-ip data for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
free(rrstr);
return 0;
} else if (raddr->data &&
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
log_err("response-ip data (%s) can not be added; CNAME response-ip "
"data already in place for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
free(rrstr);
return 0;
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
log_err("response-ip data %s record type does not correspond "
"to netblock %s address family", (rrstr?rrstr:"<out of memory>"), netblockstr);
free(rrstr);
return 0;
}
if(!raddr->data) {
raddr->data = new_rrset(region, rrtype, rrclass);
if(!raddr->data)
return 0;
}
pd = raddr->data->entry.data;
return rrset_insert_rr_wol(region, pd, rdata_wol, rdata_len, ttl);
}
static int
respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
const char* rrstr, const char* netblock)
@@ -1074,7 +1119,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 +1279,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. */
+17 -2
View File
@@ -276,12 +276,11 @@ 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 readable ip string, for logging.
* @return newly created of found node, not holding lock.
*/
struct resp_addr*
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, int create, const char* ipstr);
socklen_t addrlen, int net, int create);
/**
* Add RR to resp_addr's RRset. Create RRset if not existing.
@@ -301,6 +300,22 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
size_t rdata_len, const char* rrstr, const char* netblockstr);
/**
* Add RR to resp_addr's RRset. Create RRset if not existing.
* @param region: region to alloc RR(set).
* @param raddr: resp_addr containing RRset. Must hold write lock.
* @param rrtype: RR type.
* @param rrclass: RR class.
* @param ttl: TTL.
* @param rdata: RDATA. Without prefix len.
* @param rdata_len: length of rdata.
* @param netblockstr: netblock as string, for logging
* @return 0 on error
*/
int respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
size_t rdata_len, const char* netblockstr);
/**
* Delete resp_addr node from tree.
* @param set: struct containing tree. Must hold write lock.
+526 -139
View File
@@ -72,7 +72,11 @@
#include "validator/val_sigcrypt.h"
#include "validator/val_anchor.h"
#include "validator/val_utils.h"
#include "zone.h"
#include <ctype.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
/** bytes to use for NSEC3 hash buffer. 20 for sha1 */
#define N3HASHBUFLEN 32
@@ -171,7 +175,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 +186,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 +240,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 +264,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 +287,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++;
@@ -702,13 +706,15 @@ az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
/** see if rdata is duplicate */
static int
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata, size_t len)
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata_wol, size_t len)
{
size_t i;
size_t i, rdatawl_len = len+2;
uint16_t len16 = htons(len);
for(i=0; i<d->count + d->rrsig_count; i++) {
if(d->rr_len[i] != len)
if(d->rr_len[i] != rdatawl_len)
continue;
if(memcmp(d->rr_data[i], rdata, len) == 0)
if(memcmp(d->rr_data[i], &len16, 2) == 0 &&
memcmp(d->rr_data[i]+2, rdata_wol, len) == 0)
return 1;
}
return 0;
@@ -727,6 +733,19 @@ rrsig_rdata_get_type_covered(uint8_t* rdata, size_t rdatalen)
return sldns_read_uint16(rdata+2);
}
/** get rrsig type covered from rdata.
* @param rdata_wol: rdata in wireformat, without the prefix rdlength.
* @param rdatalen: length of rdata buffer.
* @return type covered (or 0).
*/
static uint16_t
rrsig_rdata_get_type_covered_wol(uint8_t* rdata_wol, size_t rdatalen)
{
if(rdatalen < 2)
return 0;
return sldns_read_uint16(rdata_wol);
}
/** remove RR from existing RRset. Also sig, if it is a signature.
* reallocates the packed rrset for a new one, false on alloc failure */
static int
@@ -792,7 +811,7 @@ rrset_remove_rr(struct auth_rrset* rrset, size_t index)
/** add RR to existing RRset. If insert_sig is true, add to rrsigs.
* This reallocates the packed rrset for a new one */
static int
rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata_wol,
size_t rdatalen, int insert_sig)
{
struct packed_rrset_data* d, *old = rrset->data;
@@ -800,7 +819,7 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old)
+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t)
+ rdatalen);
+ 2 /* rdlen */ + rdatalen);
if(!d) {
log_err("out of memory");
return 0;
@@ -823,8 +842,8 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
memmove(d->rr_len+d->count, old->rr_len+old->count,
old->rrsig_count*sizeof(size_t));
if(!insert_sig)
d->rr_len[d->count-1] = rdatalen;
else d->rr_len[total-1] = rdatalen;
d->rr_len[d->count-1] = rdatalen + 2;
else d->rr_len[total-1] = rdatalen + 2;
packed_rrset_ptr_fixup(d);
if((time_t)rr_ttl < d->ttl)
d->ttl = rr_ttl;
@@ -849,10 +868,12 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
/* insert new value */
if(!insert_sig) {
d->rr_ttl[d->count-1] = rr_ttl;
memmove(d->rr_data[d->count-1], rdata, rdatalen);
sldns_write_uint16(d->rr_data[d->count-1], rdatalen);
memmove(d->rr_data[d->count-1]+2, rdata_wol, rdatalen);
} else {
d->rr_ttl[total-1] = rr_ttl;
memmove(d->rr_data[total-1], rdata, rdatalen);
sldns_write_uint16(d->rr_data[total-1], rdatalen);
memmove(d->rr_data[total-1]+2, rdata_wol, rdatalen);
}
rrset->data = d;
@@ -860,10 +881,11 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
return 1;
}
/** Create new rrset for node with packed rrset with one RR element */
/** Create new rrset for node with packed rrset with one RR element.
* rdata_wol is the rdata without prefixed rdlength. */
static struct auth_rrset*
rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
uint8_t* rdata, size_t rdatalen)
uint8_t* rdata_wol, size_t rdatalen)
{
struct auth_rrset* rrset = (struct auth_rrset*)calloc(1,
sizeof(*rrset));
@@ -878,7 +900,7 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
/* the rrset data structure, with one RR */
d = (struct packed_rrset_data*)calloc(1,
sizeof(struct packed_rrset_data) + sizeof(size_t) +
sizeof(uint8_t*) + sizeof(time_t) + rdatalen);
sizeof(uint8_t*) + sizeof(time_t) + 2 /* rdlen*/ + rdatalen);
if(!d) {
free(rrset);
log_err("out of memory");
@@ -893,9 +915,10 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
d->rr_data[0] = (uint8_t*)&(d->rr_ttl[1]);
/* insert the RR */
d->rr_len[0] = rdatalen;
d->rr_len[0] = rdatalen + 2;
d->rr_ttl[0] = rr_ttl;
memmove(d->rr_data[0], rdata, rdatalen);
sldns_write_uint16(d->rr_data[0], rdatalen);
memmove(d->rr_data[0]+2, rdata_wol, rdatalen);
d->count++;
/* insert rrset into linked list for domain */
@@ -1079,14 +1102,14 @@ rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset,
* duplicates are ignored */
for(i=rrset->data->count;
i<rrset->data->count+rrset->data->rrsig_count; i++) {
uint8_t* rdata = rrset->data->rr_data[i];
size_t rdatalen = rrset->data->rr_len[i];
uint8_t* rdata_wol = rrset->data->rr_data[i]+2;
size_t rdatalen = rrset->data->rr_len[i]-2;
time_t rr_ttl = rrset->data->rr_ttl[i];
if(rdata_duplicate(rrsigset->data, rdata, rdatalen)) {
if(rdata_duplicate(rrsigset->data, rdata_wol, rdatalen)) {
continue;
}
if(!rrset_add_rr(rrsigset, rr_ttl, rdata, rdatalen, 0))
if(!rrset_add_rr(rrsigset, rr_ttl, rdata_wol, rdatalen, 0))
return 0;
}
return 1;
@@ -1096,32 +1119,35 @@ rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset,
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
static int
az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
uint8_t* rdata, size_t rdatalen, int* duplicate)
uint8_t* rdata_wol, size_t rdatalen, int* duplicate)
{
struct auth_rrset* rrset;
/* packed rrsets have their rrsigs along with them, sort them out */
if(rr_type == LDNS_RR_TYPE_RRSIG) {
uint16_t ctype = rrsig_rdata_get_type_covered(rdata, rdatalen);
uint16_t ctype = rrsig_rdata_get_type_covered_wol(rdata_wol,
rdatalen);
if((rrset=az_domain_rrset(node, ctype))!= NULL) {
/* a node of the correct type exists, add the RRSIG
* to the rrset of the covered data type */
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
if(duplicate) *duplicate = 1;
return 1;
}
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 1))
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
1))
return 0;
} else if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
/* add RRSIG to rrset of type RRSIG */
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
if(duplicate) *duplicate = 1;
return 1;
}
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
0))
return 0;
} else {
/* create rrset of type RRSIG */
if(!rrset_create(node, rr_type, rr_ttl, rdata,
if(!rrset_create(node, rr_type, rr_ttl, rdata_wol,
rdatalen))
return 0;
}
@@ -1129,17 +1155,18 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
/* normal RR type */
if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
/* add data to existing node with data type */
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
if(duplicate) *duplicate = 1;
return 1;
}
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
0))
return 0;
} else {
struct auth_rrset* rrsig;
/* create new node with data type */
if(!(rrset=rrset_create(node, rr_type, rr_ttl, rdata,
rdatalen)))
if(!(rrset=rrset_create(node, rr_type, rr_ttl,
rdata_wol, rdatalen)))
return 0;
/* see if node of type RRSIG has signatures that
@@ -1156,21 +1183,15 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
return 1;
}
/** insert RR into zone, ignore duplicates */
/** insert RR as name,rdata into zone, ignore duplicates.
* The rdata_wol is the rdata without the prefix rdlength, because simdzone
* returns that as the parsed rdata byte string. */
static int
az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
size_t dname_len, int* duplicate)
az_insert_rr_as_rdata(struct auth_zone* z, uint8_t* dname, size_t dname_len,
uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
uint8_t* rdata_wol, size_t rdatalen, int* duplicate)
{
struct auth_data* node;
uint8_t* dname = rr;
uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len);
uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len);
uint32_t rr_ttl = sldns_wirerr_get_ttl(rr, rr_len, dname_len);
size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len,
dname_len))+2;
/* rdata points to rdata prefixed with uint16 rdatalength */
uint8_t* rdata = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len);
if(rr_class != z->dclass) {
log_err("wrong class for RR");
return 0;
@@ -1179,20 +1200,38 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
log_err("cannot create domain");
return 0;
}
if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen,
if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata_wol, rdatalen,
duplicate)) {
log_err("cannot add RR to domain");
return 0;
}
if(z->rpz) {
if(!(rpz_insert_rr(z->rpz, z->name, z->namelen, dname,
dname_len, rr_type, rr_class, rr_ttl, rdata, rdatalen,
rr, rr_len)))
dname_len, rr_type, rr_class, rr_ttl, rdata_wol,
rdatalen)))
return 0;
}
return 1;
}
/** insert RR into zone, ignore duplicates */
static int
az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
size_t dname_len, int* duplicate)
{
uint8_t* dname = rr;
uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len);
uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len);
uint32_t rr_ttl = sldns_wirerr_get_ttl(rr, rr_len, dname_len);
size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len,
dname_len));
/* rdata points to rdata without prefix rdlength. */
uint8_t* rdata_wol = sldns_wirerr_get_rdata(rr, rr_len, dname_len);
return az_insert_rr_as_rdata(z, dname, dname_len, rr_type, rr_class,
rr_ttl, rdata_wol, rdatalen, duplicate);
}
/** Remove rr from node, ignores nonexisting RRs,
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
static int
@@ -1563,13 +1602,157 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
return 1;
}
/** Structure for simdzone parse state */
struct az_parse_state {
/** The zone that is processed. */
struct auth_zone* z;
/** number of errors, if 0 it was read successfully. */
int errors;
/** for http parse, chunk iterator. */
struct auth_chunk* chunk;
/** for http parse, position in chunk. */
size_t chunk_pos;
};
/** Callback for simdzone parse, log an error */
static void
az_parse_log(zone_parser_t *parser, uint32_t category,
const char *file, size_t line, const char *message, void *user_data)
{
struct az_parse_state* state = (struct az_parse_state*)user_data;
(void)parser;
switch (category) {
case ZONE_INFO:
if (file)
log_info("%s:%d: %s", file, (int)line, message);
else
log_info("%s", message);
break;
case ZONE_WARNING:
if (file)
log_warn("%s:%d: %s", file, (int)line, message);
else
log_warn("%s", message);
break;
default:
if (file)
log_err("%s:%d: %s", file, (int)line, message);
else
log_err("%s", message);
state->errors++;
break;
}
}
/** Callback for simdzone parse, accept an RR that has been read in. */
int32_t
az_parse_accept(zone_parser_t *parser, const zone_name_t *owner,
uint16_t type, uint16_t dclass, uint32_t ttl, uint16_t rdlength,
const uint8_t *rdata, void *user_data)
{
struct az_parse_state* state = (struct az_parse_state*)user_data;
if(verbosity >= 7) {
char dname[LDNS_MAX_DOMAINLEN], t[16], c[16];
dname_str((uint8_t*)owner->octets, dname);
sldns_wire2str_type_buf(type, t, sizeof(t));
sldns_wire2str_class_buf(dclass, c, sizeof(c));
verbose(7, "zone parse record %s %s %s", dname, c, t);
}
/* Duplicates can be ignored, do not insert them twice. */
if(!az_insert_rr_as_rdata(state->z, (uint8_t*)owner->octets,
owner->length, type, dclass, ttl, (uint8_t*)rdata, rdlength,
NULL)) {
char dname[LDNS_MAX_DOMAINLEN], t[16], c[16];
dname_str((uint8_t*)owner->octets, dname);
sldns_wire2str_type_buf(type, t, sizeof(t));
sldns_wire2str_class_buf(dclass, c, sizeof(c));
log_err("record insert allocation failed, %s %s %s",
dname, c, t);
return ZONE_OUT_OF_MEMORY;
}
(void)parser;
return 0;
}
/**
* Callback for simdzone parse, include a zone file.
* It is called for every $INCLUDE entry. It could be used to save
* the file names, so that it can track if the files have changed, later.
*/
static int32_t
az_parse_include(zone_parser_t *parser, const char *file,
const char *path, void *user_data)
{
struct az_parse_state* state = (struct az_parse_state*)user_data;
(void)parser;
if(state->z->zone_is_slave) {
/* A $INCLUDE is not expected for a secondary zone. */
log_err("$INCLUDE not allowed for secondary zone");
return ZONE_SEMANTIC_ERROR;
}
verbose(6, "zone parse descended into include file %s (full path %s)",
file, path);
return 0;
}
/**
* Parse file with simdzone.
*/
static int
az_parse_file_simdzone(struct auth_zone* z, char* zfilename,
struct config_file* cfg)
{
zone_parser_t parser;
zone_options_t options;
zone_name_buffer_t name_buffer;
zone_rdata_buffer_t rdata_buffer;
zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer };
struct az_parse_state state;
memset(&options, 0, sizeof(options));
options.origin.octets = z->name;
options.origin.length = z->namelen;
options.default_ttl = 3600;
options.default_class = LDNS_RR_CLASS_IN;
options.secondary = z->zone_is_slave;
options.pretty_ttls = true; /* non-standard, for backwards compatibility */
if(cfg->chrootdir && cfg->chrootdir[0])
options.chrootdir = cfg->chrootdir;
else options.chrootdir = NULL;
options.log.callback = &az_parse_log;
options.accept.callback = &az_parse_accept;
options.include.callback = &az_parse_include;
memset(&state, 0, sizeof(state));
state.z = z;
/* Parse and process all RRs. */
if (zone_parse(&parser, &options, &buffers, zfilename, &state) != 0) {
return 0;
}
return 1;
}
/** See if the file can be accessed, or if it does not exist. Look at errno. */
static int
file_exists(char* filename)
{
struct stat buf;
if(stat(filename, &buf) < 0) {
return 0;
}
return 1;
}
int
auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
{
int use_simdzone = 1;
uint8_t rr[LDNS_RR_BUF_SIZE];
struct sldns_file_parse_state state;
char* zfilename;
FILE* in;
if(!z || !z->zonefile || z->zonefile[0]==0)
return 1; /* no file, or "", nothing to read */
@@ -1582,8 +1765,7 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
dname_str(z->name, nm);
verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm);
}
in = fopen(zfilename, "r");
if(!in) {
if(!file_exists(zfilename)) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
if(z->zone_is_slave && errno == ENOENT) {
/* we fetch the zone contents later, no file yet */
@@ -1614,15 +1796,36 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
state.origin_len = z->namelen;
}
/* parse the (toplevel) file */
if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
log_err("error parsing zonefile %s for %s",
zfilename, n?n:"error");
free(n);
if(use_simdzone) {
/* Use simdzone. */
if(!az_parse_file_simdzone(z, zfilename, cfg)) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
log_err("error parsing zonefile %s for %s",
zfilename, n?n:"error");
free(n);
return 0;
}
} else {
/* Read with sldns_str2wire functions. */
FILE* in;
in = fopen(zfilename, "r");
if(!in) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
log_err("cannot open zonefile %s for %s: %s",
zfilename, n?n:"error", strerror(errno));
free(n);
return 0;
}
if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
char* n = sldns_wire2str_dname(z->name, z->namelen);
log_err("error parsing zonefile %s for %s",
zfilename, n?n:"error");
free(n);
fclose(in);
return 0;
}
fclose(in);
return 0;
}
fclose(in);
if(z->rpz)
rpz_finish_config(z->rpz);
@@ -3990,6 +4193,22 @@ auth_master_copy(struct auth_master* o)
return m;
}
/** append the master to the copied list. */
static int
auth_master_copy_and_append(struct auth_master* p, struct auth_master** list,
struct auth_master** last)
{
struct auth_master* m = auth_master_copy(p);
if(!m) {
return 0;
}
m->next = NULL;
if(*last) (*last)->next = m;
if(!*list) *list = m;
*last = m;
return 1;
}
/** copy the master addresses from the task_probe lookups to the allow_notify
* list of masters */
static void
@@ -3998,17 +4217,27 @@ probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
struct auth_master* list = NULL, *last = NULL;
struct auth_master* p;
/* build up new list with copies */
for(p = xfr->task_transfer->masters; p; p=p->next) {
struct auth_master* m = auth_master_copy(p);
if(!m) {
/* The list in task probe has been looked up before the list in
* task transfer. */
for(p = xfr->task_probe->masters; p; p=p->next) {
if(!auth_master_copy_and_append(p, &list, &last)) {
auth_free_masters(list);
/* failed because of malloc failure, use old list */
return;
}
}
/* The list in task transfer also contains the http entries. */
for(p = xfr->task_transfer->masters; p; p=p->next) {
/* Copy the http entries from this lookup. The allow_notify
* entries are not looked up from this list. The other
* ones are already in from the probe lookups. */
if(!p->http)
continue;
if(!auth_master_copy_and_append(p, &list, &last)) {
auth_free_masters(list);
/* failed because of malloc failure, use old list */
return;
}
m->next = NULL;
if(last) last->next = m;
if(!list) list = m;
last = m;
}
/* success, replace list */
auth_free_masters(xfr->allow_notify_list);
@@ -4556,6 +4785,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,
@@ -4563,6 +4809,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;
@@ -4638,23 +4885,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,
@@ -5070,14 +5300,11 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
return 1;
}
/** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */
/** parse http zone with sldns. */
static int
apply_http(struct auth_xfer* xfr, struct auth_zone* z,
parse_http_sldns(struct auth_xfer* xfr, struct auth_zone* z,
struct sldns_buffer* scratch_buffer)
{
/* parse data in chunks */
/* parse RR's and read into memory. ignore $INCLUDE from the
* downloaded file*/
struct sldns_file_parse_state pstate;
struct auth_chunk* chunk;
size_t chunk_pos;
@@ -5089,6 +5316,184 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
memmove(pstate.origin, xfr->name, xfr->namelen);
}
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
pstate.lineno = 0;
while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) {
/* process this line */
pstate.lineno++;
chunkline_newline_removal(scratch_buffer);
if(chunkline_is_comment_line_or_empty(scratch_buffer)) {
continue;
}
/* parse line and add RR */
if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $ORIGIN has been handled */
}
if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $TTL has been handled */
}
if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
verbose(VERB_ALGO, "error parsing line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
}
return 1;
}
/**
* Callback for simdzone parse of http, include a zone file.
* It is called for every $INCLUDE entry.
*/
static int32_t
az_http_parse_include(zone_parser_t *parser, const char *file,
const char *path, void *user_data)
{
struct az_parse_state* state = (struct az_parse_state*)user_data;
char dname[LDNS_MAX_DOMAINLEN];
(void)parser;
verbose(6, "zone parse has include file %s (full path %s)",
file, path);
dname_str(state->z->name, dname);
verbose(1, "zone parse for zonefile of %s has $INCLUDE %s, but $INCLUDE not followed",
dname, file);
/* Not expecting a secondary zone file with includes. */
return ZONE_SEMANTIC_ERROR;
}
int32_t az_http_read_data(zone_parser_t* parser, char* data, size_t len,
size_t* outlen, void* user_data)
{
struct az_parse_state* state = (struct az_parse_state*)user_data;
size_t written = 0;
(void)parser;
if(state->chunk == NULL) {
/* End of the chunk list */
*outlen = 0;
return 0;
}
if(state->chunk_pos == state->chunk->len) {
/* The end of the chunk list is reached, with 0 data. */
state->chunk = NULL;
*outlen = 0;
return 0;
}
if(len == 0) {
*outlen = 0;
return 0;
}
/* Fill up the data buffer with the requested amount. */
while(written < len) {
/* The amount that is wanted. */
size_t wanted = len - written;
/* That amount that is in this chunk. */
size_t avail = state->chunk->len - state->chunk_pos;
if(wanted < avail) {
/* Write a piece of this chunk. */
memmove(data+written,
state->chunk->data+state->chunk_pos, wanted);
state->chunk_pos += wanted;
*outlen = len;
return 0;
}
/* Write the entire chunk and continue on. */
if(avail > 0)
memmove(data+written,
state->chunk->data+state->chunk_pos, avail);
written += avail;
/* move to next chunk */
state->chunk = state->chunk->next;
state->chunk_pos = 0;
/* Is this the exact amount requested. */
if(written == len) {
/* continue later. */
*outlen = len;
return 0;
}
/* Is there no more data. */
if(state->chunk == NULL) {
/* End of data. */
*outlen = written;
return 0;
}
}
*outlen = written;
return 0;
}
/** parse http zone with simdzone. */
static int
parse_http_simdzone(struct auth_xfer* xfr, struct auth_zone* z)
{
zone_parser_t parser;
zone_options_t options;
zone_name_buffer_t name_buffer;
zone_rdata_buffer_t rdata_buffer;
zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer };
struct az_parse_state state;
memset(&options, 0, sizeof(options));
options.origin.octets = z->name;
options.origin.length = z->namelen;
options.default_ttl = 3600;
options.default_class = LDNS_RR_CLASS_IN;
options.secondary = z->zone_is_slave;
options.pretty_ttls = true; /* non-standard, for backwards compatibility */
options.no_includes = true; /* the secondary zone file transferred over https is not expected to have $INCLUDE files. */
/* The log callback for file read prints the error and can be used
* here too. */
options.log.callback = &az_parse_log;
/* The parse accept callback for file inserts the RR, and can be
* used here too. */
options.accept.callback = &az_parse_accept;
options.include.callback = &az_http_parse_include;
memset(&state, 0, sizeof(state));
state.z = z;
state.chunk = xfr->task_transfer->chunks_first;
state.chunk_pos = 0;
/* Parse and process all RRs. */
if (zone_parse_from_callback(&parser, &options, &buffers,
az_http_read_data, &state) != 0) {
return 0;
}
return 1;
}
/** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */
static int
apply_http(struct auth_xfer* xfr, struct auth_zone* z,
struct sldns_buffer* scratch_buffer)
{
int use_simdzone = 1;
/* parse data in chunks */
/* parse RR's and read into memory. ignore $INCLUDE from the
* downloaded file*/
if(verbosity >= VERB_ALGO)
verbose(VERB_ALGO, "http download %s of size %d",
xfr->task_transfer->master->file,
@@ -5128,44 +5533,14 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
xfr->serial = 0;
xfr->soa_zone_acquired = 0;
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
pstate.lineno = 0;
while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) {
/* process this line */
pstate.lineno++;
chunkline_newline_removal(scratch_buffer);
if(chunkline_is_comment_line_or_empty(scratch_buffer)) {
continue;
}
/* parse line and add RR */
if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $ORIGIN has been handled */
}
if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $TTL has been handled */
}
if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
verbose(VERB_ALGO, "error parsing line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
if(use_simdzone) {
/* Use simdzone for parse. */
if(!parse_http_simdzone(xfr, z))
return 0;
} else {
/* Parse with sldns. */
if(!parse_http_sldns(xfr, z, scratch_buffer))
return 0;
}
}
return 1;
}
@@ -6668,6 +7043,18 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
return 1;
}
/** return true if there are probe (SOA UDP query) targets in the master list*/
static int
have_probe_targets(struct auth_master* list)
{
struct auth_master* p;
for(p=list; p; p = p->next) {
if(!p->allow_notify && p->host)
return 1;
}
return 0;
}
/** move to sending the probe packets, next if fails. task_probe */
static void
xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
@@ -6707,6 +7094,16 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
}
xfr_probe_disown(xfr);
if(!have_probe_targets(xfr->task_probe->masters)) {
/* If there are no masters to probe, go to transfer. */
if(xfr->task_transfer->worker == NULL) {
xfr_start_transfer(xfr, env, NULL);
return;
}
/* The transfer is already in progress. */
lock_basic_unlock(&xfr->lock);
return;
}
if(xfr->task_nextprobe->worker == NULL)
xfr_set_timeout(xfr, env, 0, 0);
lock_basic_unlock(&xfr->lock);
@@ -6863,18 +7260,6 @@ auth_xfer_timer(void* arg)
}
}
/** return true if there are probe (SOA UDP query) targets in the master list*/
static int
have_probe_targets(struct auth_master* list)
{
struct auth_master* p;
for(p=list; p; p = p->next) {
if(!p->allow_notify && p->host)
return 1;
}
return 0;
}
/** start task_probe if possible, if no masters for probe start task_transfer
* returns true if task has been started, and false if the task is already
* in progress. */
@@ -6886,7 +7271,9 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
* progress (due to notify)) */
if(xfr->task_probe->worker == NULL) {
if(!have_probe_targets(xfr->task_probe->masters) &&
!(xfr->task_probe->only_lookup &&
xfr->task_probe->masters != NULL)
xfr->task_probe->only_lookup = 1;
if(!(xfr->task_probe->only_lookup &&
xfr->task_probe->masters != NULL)) {
/* useless to pick up task_probe, no masters to
* probe. Instead attempt to pick up task transfer */
+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,
+10 -9
View File
@@ -131,7 +131,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
/* o if new data is expired, cached data is better */
if( newd->ttl < timenow && timenow <= cached->ttl)
if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow))
return 0;
/* o store if rrset has been validated
* everything better than bogus data
@@ -146,13 +146,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if( newd->trust > cached->trust ) {
/* if the cached rrset is bogus, and new is equal,
* do not update the TTL - let it expire. */
if(equal && cached->ttl >= timenow &&
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
cached->security == sec_status_bogus)
return 0;
return 1;
}
/* o item in cache has expired */
if( cached->ttl < timenow )
if( TTL_IS_EXPIRED(cached->ttl, timenow) )
return 1;
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal ) {
@@ -300,7 +300,7 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
/* check TTL */
struct packed_rrset_data* data =
(struct packed_rrset_data*)e->data;
if(timenow > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
lock_rw_unlock(&e->lock);
return NULL;
}
@@ -310,17 +310,18 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
return NULL;
}
int
int
rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow)
{
size_t i;
struct packed_rrset_data* d;
for(i=0; i<count; i++) {
if(i>0 && ref[i].key == ref[i-1].key)
continue; /* only lock items once */
lock_rw_rdlock(&ref[i].key->entry.lock);
if(ref[i].id != ref[i].key->id || timenow >
((struct packed_rrset_data*)(ref[i].key->entry.data))
->ttl) {
d = ref[i].key->entry.data;
if(ref[i].id != ref[i].key->id ||
TTL_IS_EXPIRED(d->ttl, timenow)) {
/* failure! rollback our readlocks */
rrset_array_unlock(ref, i+1);
return 0;
@@ -511,7 +512,7 @@ rrset_cache_expired_above(struct rrset_cache* r, uint8_t** qname, size_t*
*qnamelen, searchtype, qclass, 0, 0, 0))) {
struct packed_rrset_data* data =
(struct packed_rrset_data*)rrset->entry.data;
if(now > data->ttl) {
if(TTL_IS_EXPIRED(data->ttl, now)) {
/* it is expired, this is not wanted */
lock_rw_unlock(&rrset->entry.lock);
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
+13 -6
View File
@@ -1564,7 +1564,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
cp = comm_point_create_udp(base, ports->fd,
front->udp_buff, ports->pp2_enabled, cb,
cb_arg, ports->socket);
} else if(ports->ftype == listen_type_doq) {
} else if(ports->ftype == listen_type_doq && doq_table) {
#ifndef HAVE_NGTCP2
log_warn("Unbound is not compiled with "
"ngtcp2. This is required to use DNS "
@@ -2884,6 +2884,7 @@ submit_http_error:
sldns_buffer_flip(h2_stream->qbuffer);
h2_session->postpone_drop = 1;
query_read_done = http2_query_read_done(h2_session, h2_stream);
h2_session->postpone_drop = 0;
if(query_read_done < 0)
return NGHTTP2_ERR_CALLBACK_FAILURE;
else if(!query_read_done) {
@@ -2893,11 +2894,9 @@ submit_http_error:
* failure will result in reclaiming (and closing)
* of comm point. */
verbose(VERB_QUERY, "http2 query dropped in worker cb");
h2_session->postpone_drop = 0;
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
/* nothing to submit right now, query added to mesh. */
h2_session->postpone_drop = 0;
return 0;
}
if(!http2_submit_dns_response(h2_session)) {
@@ -3275,14 +3274,18 @@ nghttp2_session_callbacks* http2_req_callbacks_create(void)
struct doq_table*
doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
{
struct doq_table* table = calloc(1, sizeof(*table));
struct doq_table* table;
if (!cfg->quic_port)
return NULL;
table = calloc(1, sizeof(*table));
if(!table)
return NULL;
#ifdef USE_NGTCP2_CRYPTO_OSSL
/* Initialize the ossl crypto, it is harmless to call twice,
* and this is before use of doq connections. */
if(ngtcp2_crypto_ossl_init() != 0) {
log_err("ngtcp2_crypto_oss_init failed");
log_err("ngtcp2_crypto_ossl_init failed");
free(table);
return NULL;
}
@@ -3354,7 +3357,7 @@ conn_tree_del(rbnode_type* node, void* arg)
{
struct doq_table* table = (struct doq_table*)arg;
struct doq_conn* conn;
if(!node)
if(!node || !table)
return;
conn = (struct doq_conn*)node->key;
if(conn->timer.timer_in_list) {
@@ -3413,6 +3416,7 @@ doq_timer_find_time(struct doq_table* table, struct timeval* tv)
{
struct doq_timer key;
struct rbnode_type* node;
log_assert(table != NULL);
memset(&key, 0, sizeof(key));
key.time.tv_sec = tv->tv_sec;
key.time.tv_usec = tv->tv_usec;
@@ -4922,6 +4926,7 @@ doq_conid_find(struct doq_table* table, const uint8_t* data, size_t datalen)
key.node.key = &key;
key.cid = (void*)data;
key.cidlen = datalen;
log_assert(table != NULL);
node = rbtree_search(table->conid_tree, &key);
if(node)
return (struct doq_conid*)node->key;
@@ -5662,6 +5667,8 @@ doq_table_quic_size_available(struct doq_table* table,
struct config_file* cfg, size_t mem)
{
size_t cur;
if (!table)
return 0;
lock_basic_lock(&table->size_lock);
cur = table->current_size;
lock_basic_unlock(&table->size_lock);
+202 -3
View File
@@ -41,6 +41,7 @@
#include "config.h"
#include "services/localzone.h"
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/data/dname.h"
@@ -356,6 +357,22 @@ rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
return 0;
}
/** see if rdata is duplicate */
static int
rr_is_duplicate_wol(struct packed_rrset_data* d, uint8_t* rdata_wol, size_t len)
{
size_t i, rdatawl_len = len+2;
uint16_t len16 = htons(len);
for(i=0; i<d->count + d->rrsig_count; i++) {
if(d->rr_len[i] != rdatawl_len)
continue;
if(memcmp(d->rr_data[i], &len16, 2) == 0 &&
memcmp(d->rr_data[i]+2, rdata_wol, len) == 0)
return 1;
}
return 0;
}
/** new local_rrset */
static struct local_rrset*
new_local_rrset(struct regional* region, struct local_data* node,
@@ -393,6 +410,49 @@ new_local_rrset(struct regional* region, struct local_data* node,
return rrset;
}
/** insert RR into RRset data structure; Wastes a couple of bytes */
int
rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
{
size_t* oldlen = pd->rr_len;
time_t* oldttl = pd->rr_ttl;
uint8_t** olddata = pd->rr_data;
/* add RR to rrset */
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
log_warn("RRset has more than %d records, record ignored",
LOCALZONE_RRSET_COUNT_MAX);
return 1;
}
pd->count++;
pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count);
if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
log_err("out of memory");
return 0;
}
if(pd->count > 1) {
memcpy(pd->rr_len+1, oldlen,
sizeof(*pd->rr_len)*(pd->count-1));
memcpy(pd->rr_ttl+1, oldttl,
sizeof(*pd->rr_ttl)*(pd->count-1));
memcpy(pd->rr_data+1, olddata,
sizeof(*pd->rr_data)*(pd->count-1));
}
pd->rr_len[0] = rdata_len+2;
pd->rr_ttl[0] = ttl;
pd->rr_data[0] = regional_alloc(region, rdata_len+2);
if(!pd->rr_data[0]) {
log_err("out of memory");
return 0;
}
sldns_write_uint16(pd->rr_data[0], rdata_len);
memmove(pd->rr_data[0]+2, rdata_wol, rdata_len);
return 1;
}
/** insert RR into RRset data structure; Wastes a couple of bytes */
int
rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
@@ -503,6 +563,48 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
return 1;
}
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
* for the RR is entered later on local_zone_enter_rr() as with the other
* records. An artificial soa_negative record with a modified TTL (minimum of
* the TTL and the SOA.MINIMUM) is also created and marked for usage with
* negative answers and to avoid allocations during those answers. */
static int
lz_mark_soa_for_zone_wol(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset,
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
{
struct packed_rrset_data* pd = (struct packed_rrset_data*)
regional_alloc_zero(z->region, sizeof(*pd));
struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*)
regional_alloc_zero(z->region, sizeof(*rrset_negative));
time_t minimum;
if(!rrset_negative||!pd) {
log_err("out of memory");
return 0;
}
/* Mark the original SOA record and then continue with the negative one. */
z->soa = soa_rrset;
rrset_negative->entry.key = rrset_negative;
pd->trust = rrset_trust_prim_noglue;
pd->security = sec_status_insecure;
rrset_negative->entry.data = pd;
rrset_negative->rk.dname = soa_rrset->rk.dname;
rrset_negative->rk.dname_len = soa_rrset->rk.dname_len;
rrset_negative->rk.type = soa_rrset->rk.type;
rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class;
if(!rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl))
return 0;
/* last 4 bytes are minimum ttl in network format */
if(pd->count == 0 || pd->rr_len[0] < 2+4)
return 0;
minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4));
minimum = ttl<minimum?ttl:minimum;
pd->ttl = minimum;
pd->rr_ttl[0] = minimum;
z->soa_negative = rrset_negative;
return 1;
}
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
* for the RR is entered later on local_zone_enter_rr() as with the other
* records. An artificial soa_negative record with a modified TTL (minimum of
@@ -545,6 +647,96 @@ lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset
return 1;
}
/**
* Convert dname, type, class, ttl, rdata to an rr string.
* rdata without prefixed length. returned string is malloced.
*/
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
{
char buf[65536], t[32], c[32], d[1024], result[65536+32+32+1024+1024];
buf[0]=0; buf[sizeof(buf)-1]=0;
d[0]=0; d[sizeof(d)-1]=0;
(void)sldns_wire2str_rdata_buf(rdata, rdata_len, buf, sizeof(buf),
rrtype);
(void)sldns_wire2str_type_buf(rrtype, t, sizeof(t));
(void)sldns_wire2str_class_buf(rrclass, c, sizeof(c));
if(dname)
(void)sldns_wire2str_dname_buf(dname, dnamelen, d, sizeof(d));
snprintf(result, sizeof(result), "%s%s%u %s %s %s",
dname, (dname?" ":""), (unsigned)ttl, c, t, d);
return strdup(result);
}
int
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
uint8_t* rdata_wol, size_t rdata_len)
{
struct local_data* node;
struct local_rrset* rrset;
struct packed_rrset_data* pd;
if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
return 0;
}
log_assert(node);
/* Reject it if we would end up having CNAME and other data (including
* another CNAME) for a redirect zone. */
if((z->type == local_zone_redirect ||
z->type == local_zone_inform_redirect) && node->rrsets) {
const char* othertype = NULL;
if (rrtype == LDNS_RR_TYPE_CNAME)
othertype = "other";
else if (node->rrsets->rrset->rk.type ==
htons(LDNS_RR_TYPE_CNAME)) {
othertype = "CNAME";
}
if(othertype) {
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
log_err("local-data '%s' in redirect zone must not "
"coexist with %s local-data", (rrstr?rrstr:"<out of memory>"), othertype);
free(rrstr);
return 0;
}
}
rrset = local_data_find_type(node, rrtype, 0);
if(!rrset) {
rrset = new_local_rrset(z->region, node, rrtype, rrclass);
if(!rrset)
return 0;
if(query_dname_compare(node->name, z->name) == 0) {
if(rrtype == LDNS_RR_TYPE_NSEC)
rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
if(rrtype == LDNS_RR_TYPE_SOA &&
!lz_mark_soa_for_zone_wol(z, rrset->rrset, rdata_wol, rdata_len, ttl))
return 0;
}
}
pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
log_assert(rrset && pd);
/* check for duplicate RR */
if(rr_is_duplicate_wol(pd, rdata_wol, rdata_len)) {
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
verbose(VERB_ALGO, "ignoring duplicate RR: %s", (rrstr?rrstr:"<out of memory>"));
free(rrstr);
return 1;
}
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
rrclass, ttl, rdata_wol, rdata_len);
log_warn("RRset %s has more than %d records, record ignored",
(rrstr?rrstr:"<out of memory>"), LOCALZONE_RRSET_COUNT_MAX);
free(rrstr);
return 1;
}
return rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl);
}
int
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
@@ -2039,7 +2231,7 @@ set_kiddo_parents(struct local_zone* z, struct local_zone* match,
struct local_zone* local_zones_add_zone(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
enum localzone_type tp)
enum localzone_type tp, int* duplicate)
{
int exact;
/* create */
@@ -2047,6 +2239,7 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
if(!z) {
free(name);
if(duplicate) *duplicate = 0;
return NULL;
}
lock_rw_wrlock(&z->lock);
@@ -2060,8 +2253,14 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
/* duplicate entry! */
lock_rw_unlock(&z->lock);
if(duplicate) {
*duplicate = 1;
z->name = NULL; /* Do not delete the name in
local_zone_delete. */
}
local_zone_delete(z);
log_err("internal: duplicate entry in local_zones_add_zone");
if(duplicate == NULL)
log_err("internal: duplicate entry in local_zones_add_zone");
return NULL;
}
@@ -2105,7 +2304,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
if(!z) {
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
local_zone_transparent);
local_zone_transparent, NULL);
if(!z) {
lock_rw_unlock(&zones->lock);
return 0;
+45 -1
View File
@@ -403,11 +403,17 @@ local_zones_find_le(struct local_zones* zones,
* @param labs: labelcount of name.
* @param dclass: class to add.
* @param tp: type.
* @param duplicate: Allows to check if a NULL return from the function is a
* memory error, or a duplicate entry. Pass NULL to have it not returned,
* the name is freed on errors, and for a duplicate a log message is
* printed. Pass not NULL, and when the error is a duplicate, the function
* returns NULL, and the variable is set true. The name is not freed
* when there is a duplicate, no error is printed by this function.
* @return local_zone or NULL on error, caller must printout memory error.
*/
struct local_zone* local_zones_add_zone(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
enum localzone_type tp);
enum localzone_type tp, int* duplicate);
/**
* Delete a zone. Caller must hold the zones lock.
@@ -526,6 +532,18 @@ int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
/**
* Insert specified rdata into the specified resource record.
* @param region: allocator
* @param pd: data portion of the destination resource record
* @param rdata_wol: source rdata, without prefix len.
* @param rdata_len: source rdata length
* @param ttl: time to live
* @return 1 on success; 0 otherwise.
*/
int rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
uint8_t* rdata_wol, size_t rdata_len, time_t ttl);
/**
* Remove RR from rrset that is created using localzone's rrset_insert_rr.
* @param pd: the RRset containing the RR to remove
@@ -631,6 +649,24 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
uint8_t* rdata, size_t rdata_len, const char* rrstr);
/**
* Add RR to local zone. Without prefix length on rdata.
* @param z: local zone to add RR to
* @param nm: dname of RR
* @param nmlen: length of nm
* @param nmlabs: number of labels of nm
* @param rrtype: RR type
* @param rrclass: RR class
* @param ttl: TTL of RR to add
* @param rdata_wol: RDATA of RR to add, without prefix length.
* @param rdata_len: length of rdata, without prefix length.
* @return: 1 on success
*/
int
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
uint8_t* rdata_wol, size_t rdata_len);
/**
* Find a data node by exact name for a local zone
* @param z: local_zone containing data tree
@@ -674,4 +710,12 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
*/
void
lz_init_parents(struct local_zones* zones);
/**
* Convert dname, type, class, ttl, rdata to an rr string.
* rdata without prefixed length. returned string is malloced.
*/
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len);
#endif /* SERVICES_LOCALZONE_H */
+72 -43
View File
@@ -231,6 +231,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_replyaddr_limit = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
mesh->max_reply_states = env->cfg->num_queries_per_thread;
@@ -348,7 +349,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 +442,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)
@@ -453,6 +463,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
verbose(VERB_ALGO, "Too many queries. dropping "
"incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
comm_point_drop_reply(rep);
mesh->stats_dropped++;
return;
@@ -464,8 +476,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
verbose(VERB_ALGO, "Too many requests queued. "
"dropping incoming query.");
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
comm_point_drop_reply(rep);
mesh->stats_dropped++;
mesh->num_queries_replyaddr_limit++;
return;
}
}
@@ -1152,8 +1166,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 +1203,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 +1238,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 +1699,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;
@@ -1727,28 +1742,39 @@ void mesh_query_done(struct mesh_state* mstate)
dns_error_reporting(&mstate->s, rep);
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;
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
mstate->s.env->mesh->num_reply_addrs--;
mstate->s.env->mesh->num_queries_discard_timeout++;
continue;
}
}
i++;
@@ -1782,6 +1808,8 @@ void mesh_query_done(struct mesh_state* mstate)
}
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
mstate->s.env->mesh->num_reply_addrs--;
} else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info) {
@@ -2272,6 +2300,7 @@ mesh_stats_clear(struct mesh_area* mesh)
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
mesh->ans_nodata = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_replyaddr_limit = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
}
@@ -2297,7 +2326,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
@@ -141,6 +141,8 @@ struct mesh_area {
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
/** stats, number of queries removed due to discard-timeout */
size_t num_queries_discard_timeout;
/** stats, number of queries removed due to replyaddr limit */
size_t num_queries_replyaddr_limit;
/** stats, number of queries removed due to wait-limit */
size_t num_queries_wait_limit;
/** stats, number of dns error reports generated */
@@ -399,6 +401,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -407,7 +411,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
* @return: false on error, true if success (and init may be needed).
*/
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq);
/**
* Add detached query.
@@ -426,6 +431,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @param qstate: the state to find mesh state, and that wants to receive
* the results from the new subquery.
* @param qinfo: what to query for (copied).
* @param cinfo: if non-NULL client specific info that may affect IP-based
* actions that apply to the query result. It is copied.
* @param qflags: what flags to use (RD / CD flag or not).
* @param prime: if it is a (stub) priming query.
* @param valrec: if it is a validation recursion query (lookup of key, DS).
@@ -435,8 +442,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
* @return: false on error, true if success (and init may be needed).
*/
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
struct mesh_state** sub);
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec, struct module_qstate** newq, struct mesh_state** sub);
/**
* Query state is done, send messages to reply entries.
+5 -2
View File
@@ -262,6 +262,7 @@ int
modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
const char* orig_module_conf = module_conf;
int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
@@ -276,11 +277,13 @@ modstack_call_init(struct module_stack* stack, const char* module_conf,
changed = 1;
}
}
module_conf += strlen(stack->mod[i]->name);
/* Skip this module name in module_conf. */
while(*module_conf && !isspace((unsigned char)*module_conf))
module_conf++;
}
if(changed) {
modstack_free(stack);
if(!modstack_config(stack, module_conf)) {
if(!modstack_config(stack, orig_module_conf)) {
return 0;
}
}
+4
View File
@@ -48,6 +48,10 @@
#include "util/regional.h"
#include "util/netevent.h"
#include "dnstap/dnstap_config.h"
#ifdef __QNX__
/* For struct timeval */
#include <sys/time.h>
#endif /* __QNX__ */
struct pending;
struct pending_timeout;
struct ub_randstate;
+86 -82
View File
@@ -170,15 +170,14 @@ rpz_type_ignored(uint16_t rr_type)
/**
* Classify RPZ action for RR type/rdata
* @param rr_type: the RR type
* @param rdatawl: RDATA with 2 bytes length
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
* @param rdata: RDATA without 2 bytes length
* @param rdatalen: the length of rdatawl (not including its 2 bytes length)
* @return: the RPZ action
*/
static enum rpz_action
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
rpz_rr_to_action_wol(uint16_t rr_type, uint8_t* rdata, size_t rdatalen)
{
char* endptr;
uint8_t* rdata;
int rdatalabs;
uint8_t* tldlab = NULL;
@@ -202,11 +201,10 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
/* use CNAME target to determine RPZ action */
log_assert(rr_type == LDNS_RR_TYPE_CNAME);
if(rdatalen < 3)
if(rdatalen < 1)
return RPZ_INVALID_ACTION;
rdata = rdatawl + 2; /* 2 bytes of rdata length */
if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
if(dname_valid(rdata, rdatalen) != rdatalen)
return RPZ_INVALID_ACTION;
rdatalabs = dname_count_labels(rdata);
@@ -226,7 +224,7 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
}
/* all other TLDs starting with "rpz-" are invalid */
tldlab = get_tld_label(rdata, rdatalen-2);
tldlab = get_tld_label(rdata, rdatalen);
if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
return RPZ_INVALID_ACTION;
@@ -234,6 +232,21 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
return RPZ_LOCAL_DATA_ACTION;
}
/**
* Classify RPZ action for RR type/rdata
* @param rr_type: the RR type
* @param rdatawl: RDATA with 2 bytes length
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
* @return: the RPZ action
*/
static enum rpz_action
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
{
if(rdatalen < 2)
return RPZ_INVALID_ACTION;
return rpz_rr_to_action_wol(rr_type, rdatawl+2, rdatalen-2);
}
static enum localzone_type
rpz_action_to_localzone_type(enum rpz_action a)
{
@@ -658,7 +671,7 @@ strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
static void
rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint32_t ttl, uint8_t* rdata, size_t rdata_len)
{
struct local_zone* z;
enum localzone_type tp = local_zone_always_transparent;
@@ -685,20 +698,41 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
return;
}
/* For not a local-data action.
* Insert the zone, then detect a duplicate, instead of find it first,
* for speed of searching the tree once. */
if(a != RPZ_LOCAL_DATA_ACTION) {
int duplicate = 0;
lock_rw_wrlock(&lz->lock);
tp = rpz_action_to_localzone_type(a);
z = local_zones_add_zone(lz, dname, dnamelen,
dnamelabs, rrclass, tp, &duplicate);
if(z == NULL) {
if(duplicate) {
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
rrclass, ttl, rdata, rdata_len);
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
free(rrstr);
free(dname);
lock_rw_unlock(&lz->lock);
return;
}
log_warn("rpz: create failed, out of memory");
lock_rw_unlock(&lz->lock);
/* dname will be free'd in failed local_zone_create() */
return;
}
lock_rw_unlock(&lz->lock);
return;
}
lock_rw_wrlock(&lz->lock);
/* exact match */
z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
char* rrstr = sldns_wire2str_rr(rr, rr_len);
if(rrstr == NULL) {
log_err("malloc error while inserting rpz nsdname trigger");
free(dname);
lock_rw_unlock(&lz->lock);
return;
}
if(rrstr[0])
rrstr[strlen(rrstr)-1]=0; /* remove newline */
verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
rrclass, ttl, rdata, rdata_len);
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
free(rrstr);
free(dname);
lock_rw_unlock(&lz->lock);
@@ -707,7 +741,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
if(z == NULL) {
tp = rpz_action_to_localzone_type(a);
z = local_zones_add_zone(lz, dname, dnamelen,
dnamelabs, rrclass, tp);
dnamelabs, rrclass, tp, NULL);
if(z == NULL) {
log_warn("rpz: create failed");
lock_rw_unlock(&lz->lock);
@@ -717,18 +751,10 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
newzone = 1;
}
if(a == RPZ_LOCAL_DATA_ACTION) {
char* rrstr = sldns_wire2str_rr(rr, rr_len);
if(rrstr == NULL) {
log_err("malloc error while inserting rpz nsdname trigger");
free(dname);
lock_rw_unlock(&lz->lock);
return;
}
lock_rw_wrlock(&z->lock);
local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
rrclass, ttl, rdata, rdata_len, rrstr);
local_zone_enter_rr_wol(z, dname, dnamelen, dnamelabs, rrtype,
rrclass, ttl, rdata, rdata_len);
lock_rw_unlock(&z->lock);
free(rrstr);
}
if(!newzone) {
free(dname);
@@ -748,7 +774,7 @@ rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
static void
rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint8_t* rdata, size_t rdata_len)
{
if(a == RPZ_INVALID_ACTION) {
verbose(VERB_ALGO, "rpz: skipping invalid action");
@@ -757,7 +783,7 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
}
rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
rrclass, ttl, rdata, rdata_len, rr, rr_len);
rrclass, ttl, rdata, rdata_len);
}
static int
@@ -799,7 +825,7 @@ rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
static void
rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint8_t* rdata, size_t rdata_len)
{
uint8_t* dname_stripped = NULL;
size_t dnamelen_stripped = 0;
@@ -814,32 +840,22 @@ rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
/* dname_stripped is consumed or freed by the insert routine */
rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
rr, rr_len);
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len);
}
static int
rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
uint8_t* rr, size_t rr_len)
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
{
struct resp_addr* node;
char* rrstr;
enum respip_action respa = rpz_action_to_respip_action(a);
lock_rw_wrlock(&set->lock);
rrstr = sldns_wire2str_rr(rr, rr_len);
if(rrstr == NULL) {
log_err("malloc error while inserting rpz ipaddr based trigger");
lock_rw_unlock(&set->lock);
return 0;
}
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1);
if(node == NULL) {
lock_rw_unlock(&set->lock);
free(rrstr);
return 0;
}
@@ -849,12 +865,11 @@ rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage*
node->action = respa;
if(a == RPZ_LOCAL_DATA_ACTION) {
respip_enter_rr(set->region, node, rrtype,
rrclass, ttl, rdata, rdata_len, rrstr, "");
respip_enter_rr_wol(set->region, node, rrtype,
rrclass, ttl, rdata, rdata_len, "");
}
lock_rw_unlock(&node->lock);
free(rrstr);
return 1;
}
@@ -890,17 +905,6 @@ rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
return node;
}
static void
rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
char* rrstr = sldns_wire2str_rr(rr, rr_len);
if(rrstr == NULL) {
log_err("malloc error while inserting rpz clientip based record");
return;
}
log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
free(rrstr);
}
/* from localzone.c; difference is we don't have a dname */
static struct local_rrset*
rpz_clientip_new_rrset(struct regional* region,
@@ -958,14 +962,13 @@ rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* r
return 0;
}
return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
return rrset_insert_rr_wol(region, rrset->rrset->entry.data, rdata, rdata_len, ttl);
}
static int
rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
uint8_t* rr, size_t rr_len)
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
{
struct clientip_synthesized_rr* node;
@@ -973,8 +976,14 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
if(node == NULL) {
char as[64], *rrstr;
lock_rw_unlock(&set->lock);
rpz_report_rrset_error("client ip address", rr, rr_len);
addr_to_str(addr, addrlen, as, sizeof(as));
rrstr = dname_rdata_to_str(NULL, 0, rrtype, rrclass, ttl,
rdata, rdata_len);
log_err("rpz: unexpected: unable to insert %s: %s/%d %s",
"client ip address", as, net, (rrstr?rrstr:"<out of memory>"));
free(rrstr);
return 0;
}
@@ -1000,7 +1009,7 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
static int
rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint8_t* rdata, size_t rdata_len)
{
struct sockaddr_storage addr;
socklen_t addrlen;
@@ -1016,13 +1025,13 @@ rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
}
return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
a, rrtype, rrclass, ttl, rdata, rdata_len);
}
static int
rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint8_t* rdata, size_t rdata_len)
{
struct sockaddr_storage addr;
socklen_t addrlen;
@@ -1038,14 +1047,14 @@ rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
}
return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
a, rrtype, rrclass, ttl, rdata, rdata_len);
}
/** Insert RR into RPZ's respip_set */
static int
rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
uint8_t* rdata, size_t rdata_len)
{
struct sockaddr_storage addr;
socklen_t addrlen;
@@ -1070,13 +1079,13 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
}
return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
a, rrtype, rrclass, ttl, rdata, rdata_len);
}
int
rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
uint8_t* rdatawol, size_t rdatalen)
{
size_t policydnamelen;
/* name is free'd in local_zone delete */
@@ -1110,7 +1119,7 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
return 0;
}
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
a = rpz_rr_to_action_wol(rr_type, rdatawol, rdatalen);
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
policydname, (dnamelen-aznamelen)+1))) {
free(policydname);
@@ -1125,27 +1134,22 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
if(t == RPZ_QNAME_TRIGGER) {
/* policydname will be consumed, no free */
rpz_insert_qname_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
free(policydname);
} else if(t == RPZ_CLIENT_IP_TRIGGER) {
rpz_insert_clientip_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
free(policydname);
} else if(t == RPZ_NSIP_TRIGGER) {
rpz_insert_nsip_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
free(policydname);
} else if(t == RPZ_NSDNAME_TRIGGER) {
rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
free(policydname);
} else {
free(policydname);
+3 -5
View File
@@ -136,15 +136,13 @@ struct rpz {
* @param rr_type: RR type of the RR
* @param rr_class: RR class of the RR
* @param rr_ttl: TTL of the RR
* @param rdatawl: rdata of the RR, prepended with the rdata size
* @param rdatalen: length if the RR, including the prepended rdata size
* @param rr: the complete RR, for logging purposes
* @param rr_len: the length of the complete RR
* @param rdatawol: rdata of the RR, not prepended with the rdata size
* @param rdatalen: length if the RR, not including the prepended rdata size
* @return: 0 on error
*/
int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
uint8_t* rdatawol, size_t rdatalen);
/**
* Delete policy matching RR, used for IXFR.
Submodule
+1
Submodule simdzone added at eca67807d0
+3 -1
View File
@@ -480,11 +480,13 @@ 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;
#define LDNS_EDNS_MASK_DO_BIT 0x8000
#define LDNS_EDNS_MASK_CO_BIT 0x4000
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
#define LDNS_TSIG_ERROR_NOERROR 0
+3
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;
@@ -2485,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
w += sldns_str_print(str, str_len, " flags:");
if((edns_bits & LDNS_EDNS_MASK_DO_BIT))
w += sldns_str_print(str, str_len, " do");
if((edns_bits & LDNS_EDNS_MASK_CO_BIT))
w += sldns_str_print(str, str_len, " co");
/* the extended rcode is the value set, shifted four bits,
* and or'd with the original rcode */
if(ext_rcode) {
+1 -1
View File
@@ -783,7 +783,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
@@ -869,6 +868,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
+3
View File
@@ -236,6 +236,8 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
s->svr.num_queries_cookie_invalid);
PR_UL_NM("num.queries_discard_timeout",
s->svr.num_queries_discard_timeout);
PR_UL_NM("num.queries_replyaddr_limit",
s->svr.num_queries_replyaddr_limit);
PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit);
PR_UL_NM("num.cachehits",
s->svr.num_queries - s->svr.num_queries_missed_cache);
@@ -263,6 +265,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
PR_UL_NM("requestlist.exceeded", s->mesh_dropped);
PR_UL_NM("requestlist.current.all", s->mesh_num_states);
PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states);
PR_UL_NM("requestlist.current.replies", s->mesh_num_reply_addrs);
#ifndef S_SPLINT_S
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
+1 -1
View File
@@ -2255,7 +2255,7 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
/* Initialize the ossl crypto, it is harmless to call twice,
* and this is before use of doq connections. */
if(ngtcp2_crypto_ossl_init() != 0)
fatal_exit("ngtcp2_crypto_oss_init failed");
fatal_exit("ngtcp2_crypto_ossl_init failed");
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
if(ngtcp2_crypto_quictls_init() != 0)
fatal_exit("ngtcp2_crypto_quictls_init failed");
+4 -2
View File
@@ -222,7 +222,8 @@ read_http_headers(SSL* ssl, char* file, size_t flen, char* host, size_t hlen,
if(verb>=2) printf("read: %s\n", buf);
if(buf[0] == 0) {
int e = ERR_peek_error();
printf("error string: %s\n", ERR_reason_error_string(e));
if(e)
printf("error string: %s\n", ERR_reason_error_string(e));
return 1;
}
if(!process_one_header(buf, file, flen, host, hlen, vs))
@@ -246,7 +247,8 @@ setup_ctx(char* key, char* cert)
#endif
if(!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
int e = ERR_peek_error();
printf("error string: %s\n", ERR_reason_error_string(e));
if(e)
printf("error string: %s\n", ERR_reason_error_string(e));
print_exit("cannot read cert");
}
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
+4
View File
@@ -142,6 +142,10 @@
#include "util/netevent.h"
#include "testcode/testpkts.h"
#include "util/rbtree.h"
#ifdef __QNX__
/* For struct timeval */
#include <sys/time.h>
#endif /* __QNX__ */
struct replay_answer;
struct replay_moment;
struct replay_range;
+37 -8
View File
@@ -135,6 +135,8 @@ static void matchline(char* line, struct entry* e)
e->match_ttl = 1;
} else if(str_keyword(&parse, "DO")) {
e->match_do = 1;
} else if(str_keyword(&parse, "CO")) {
e->match_co = 1;
} else if(str_keyword(&parse, "noedns")) {
e->match_noedns = 1;
} else if(str_keyword(&parse, "ednsdata")) {
@@ -178,7 +180,7 @@ static void matchline(char* line, struct entry* e)
/** parse REPLY line */
static void replyline(char* line, uint8_t* reply, size_t reply_len,
int* do_flag)
int* do_flag, int* co_flag)
{
char* parse = line;
if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
@@ -236,6 +238,8 @@ static void replyline(char* line, uint8_t* reply, size_t reply_len,
LDNS_AD_SET(reply);
} else if(str_keyword(&parse, "DO")) {
*do_flag = 1;
} else if(str_keyword(&parse, "CO")) {
*co_flag = 1;
} else {
error("could not parse REPLY: '%s'", parse);
}
@@ -289,6 +293,7 @@ static struct entry* new_entry(void)
e->match_all_noedns = 0;
e->match_ttl = 0;
e->match_do = 0;
e->match_co = 0;
e->match_noedns = 0;
e->match_serial = 0;
e->ixfr_soa_serial = 0;
@@ -521,15 +526,17 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
/* add EDNS 4096 opt record */
static void
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
uint16_t ednslen, size_t* pktlen)
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, int co_flag,
uint8_t *ednsdata, uint16_t ednslen, size_t* pktlen)
{
uint8_t edns[] = {0x00, /* root label */
0x00, LDNS_RR_TYPE_OPT, /* type */
0x04, 0xD0, /* class is UDPSIZE 1232 */
0x00, /* TTL[0] is ext rcode */
0x00, /* TTL[1] is edns version */
(uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
(uint8_t)(do_flag?0x80:0x00)
| (uint8_t)(co_flag?0x40:0x00)
, 0x00, /* TTL[2-3] is edns flags, DO */
(uint8_t)((ednslen >> 8) & 0xff),
(uint8_t)(ednslen & 0xff), /* rdatalength */
};
@@ -561,6 +568,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
uint8_t pktbuf[MAX_PACKETLEN];
size_t pktlen = LDNS_HEADER_SIZE;
int do_flag = 0; /* DO flag in EDNS */
int co_flag = 0; /* CO flag in EDNS */
memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
while(fgets(line, (int)sizeof(line), in) != NULL) {
@@ -598,7 +606,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
if(str_keyword(&parse, "MATCH")) {
matchline(parse, current);
} else if(str_keyword(&parse, "REPLY")) {
replyline(parse, pktbuf, pktlen, &do_flag);
replyline(parse, pktbuf, pktlen, &do_flag, &co_flag);
} else if(str_keyword(&parse, "ADJUST")) {
adjustline(parse, current, cur_reply);
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
@@ -654,15 +662,16 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
if(hex_ednsdata_buffer)
sldns_buffer_free(hex_ednsdata_buffer);
if(pktlen != 0) {
if(do_flag || cur_reply->raw_ednsdata) {
if(do_flag || co_flag
|| cur_reply->raw_ednsdata) {
if(cur_reply->raw_ednsdata &&
sldns_buffer_limit(cur_reply->raw_ednsdata))
add_edns(pktbuf, sizeof(pktbuf), do_flag,
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
sldns_buffer_begin(cur_reply->raw_ednsdata),
(uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
&pktlen);
else
add_edns(pktbuf, sizeof(pktbuf), do_flag,
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
NULL, 0, &pktlen);
}
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
@@ -909,6 +918,22 @@ get_do_flag(uint8_t* pkt, size_t len)
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
}
/** return true if the CO flag is set */
static int
get_co_flag(uint8_t* pkt, size_t len)
{
uint16_t edns_bits;
uint8_t* walk = pkt;
size_t walk_len = len;
if(!pkt_find_edns_opt(&walk, &walk_len)) {
return 0;
}
if(walk_len < 6)
return 0; /* malformed */
edns_bits = sldns_read_uint16(walk+4);
return (int)(edns_bits&LDNS_EDNS_MASK_CO_BIT);
}
/** Snips the specified EDNS option out of the OPT record and puts it in the
* provided buffer. The buffer should be able to hold any opt data ie 65535.
* Returns the length of the option written,
@@ -1654,6 +1679,10 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
verbose(3, "no DO bit set\n");
continue;
}
if(p->match_co && !get_co_flag(query_pkt, len)) {
verbose(3, "no CO bit set\n");
continue;
}
if(p->match_noedns && get_has_edns(query_pkt, len)) {
verbose(3, "bad; EDNS OPT present\n");
continue;
+2
View File
@@ -218,6 +218,8 @@ struct entry {
uint8_t match_ttl;
/** match DO bit */
uint8_t match_do;
/** match CO bit */
uint8_t match_co;
/** match absence of EDNS OPT record in query */
uint8_t match_noedns;
/** match edns data field given in hex */
+4
View File
@@ -207,7 +207,11 @@ rr_test_file(const char* input, const char* check)
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
/** read rrs to and from string, to and from wireformat */
static void
+2 -2
View File
@@ -283,7 +283,7 @@ net_test(void)
unit_assert(strcmp(astr, "1.2.3.0") == 0);
unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
res = netblockstrtoaddr("2001:db8:33:44::/64", 53,
&a, &alen, &net);
unit_assert(res!=0 && net == 64);
addr_to_str(&a, alen, astr, sizeof(astr));
@@ -1265,7 +1265,7 @@ static void localzone_parents_test(void)
nmlabs = dname_count_size_labels(nm, &nmlen);
lock_rw_wrlock(&z2->lock);
local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
local_zone_always_nxdomain);
local_zone_always_nxdomain, NULL);
lock_rw_unlock(&z2->lock);
}
/* The trees should be the same, iterate and check the nodes */
+4
View File
@@ -498,7 +498,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
void msgparse_test(void)
{
+34 -13
View File
@@ -513,8 +513,11 @@ nsec3_hash_test(const char* fname)
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
#if defined(HAVE_SSL) && defined(USE_SHA1)
/* Detect if openssl is configured to disable RSASHA1 signatures,
* with the rh-allow-sha1-signatures disabled. */
@@ -631,6 +634,7 @@ rh_allow_sha1_signatures_disabled(void)
void
verify_test(void)
{
int do_sha1 = 1;
unit_show_feature("signature verify");
#if defined(HAVE_SSL) && defined(USE_SHA1)
@@ -643,27 +647,40 @@ verify_test(void)
#else
_putenv("OPENSSL_ENABLE_SHA1_SIGNATURES=1");
#endif
do_sha1 = 1;
}
#ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED
if (EVP_default_properties_is_fips_enabled(NULL))
do_sha1 = 0;
#endif
#endif /* HAVE_SSL and USE_SHA1 */
#ifdef USE_SHA1
verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
if(do_sha1) {
verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
}
#endif
#if defined(USE_DSA) && defined(USE_SHA1)
verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
if(do_sha1) {
verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
}
#endif /* USE_DSA */
#ifdef USE_SHA1
verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
if(do_sha1) {
verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
}
#endif
#if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256", "20070829144150");
# ifdef USE_SHA1
verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
if(do_sha1) {
verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
}
# endif
verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256_draft", "20090101000000");
#endif
@@ -672,8 +689,10 @@ verify_test(void)
verifytest_file(SRCDIRSTR "/testdata/test_signatures.9", "20171215000000");
#endif
#ifdef USE_SHA1
verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
if(do_sha1) {
verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
}
#endif
#ifdef USE_GOST
if(sldns_key_EVP_load_gost_id())
@@ -699,7 +718,9 @@ verify_test(void)
}
#endif
#ifdef USE_SHA1
dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
if(do_sha1) {
dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
}
#endif
nsectest();
nsec3_hash_test(SRCDIRSTR "/testdata/test_nsec3_hash.1");
+4
View File
@@ -50,7 +50,11 @@
#define xstr(s) str(s)
#define str(s) #s
#ifndef __QNX__
#define SRCDIRSTR xstr(SRCDIR)
#else /* !__QNX__ */
#define SRCDIRSTR "."
#endif /* __QNX__ */
/** Add zone from file for testing */
struct auth_zone* authtest_addzone(struct auth_zones* az, const char* name,
+2
View File
@@ -40,6 +40,8 @@ grep -F -v -e "dnstap" hlist > ilist; mv ilist hlist
grep -F -v -e "util/siphash.c" hlist > ilist; mv ilist hlist
# filter out compat
grep -F -v -e "compat/" hlist > ilist; mv ilist hlist
# filter out simdzone
grep -F -v -e "simdzone/" hlist > ilist; mv ilist hlist
for h in `cat hlist`; do
if grep -F "`basename $h`" $PRE/doc/html/files.html >/dev/null; then
: # ok
+1 -1
View File
@@ -24,7 +24,7 @@ server:
# specify every interface on a new 'interface:' labelled line.
interface: 192.0.2.153
interface: 192.0.2.154
interface: 2001:DB8::5
interface: 2001:db8::5
# port to answer queries from
port: 53
+1 -1
View File
@@ -11,7 +11,7 @@ server:
# specify every interface on a new 'interface:' labelled line.
interface: 192.0.2.153
interface: 192.0.2.154
interface: 2001:DB8::5
interface: 2001:db8::5
interface: 0.0.0.0@5353
# config
@@ -0,0 +1,5 @@
$ORIGIN .
$TTL 7200
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
example.com. IN NS ns.example.net.
www.example.com. IN A 1.2.3.4
+17
View File
@@ -0,0 +1,17 @@
server:
verbosity: 7
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
auth-zone:
name: "example.com"
for-upstream: yes
for-downstream: yes
url: "https://127.0.0.1:@TOPORT@/example.com.zone"
+16
View File
@@ -0,0 +1,16 @@
BaseName: auth_https_origin
Version: 1.0
Description: Perform https for authority zone with $ORIGIN
CreationDate: Mon 29 September 14:35:40 CEST 2025
Maintainer: dr. W.C.A. Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: auth_https_origin.pre
Post: auth_https_origin.post
Test: auth_https_origin.test
AuxFiles:
Passed:
Failure:

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