Compare commits

...
145 Commits
Author SHA1 Message Date
W.C.A. Wijngaards 0076736fc4 - Fix for dnstap with dnscrypt and dnstap without dnsoverquic. 2024-10-16 11:52:49 +02:00
Yorgos Thessalonikefs f8e45ed696 - Fix for dnsoverquic and dnstap to use the correct dnstap
environment.
2024-10-16 11:02:31 +02:00
W.C.A. Wijngaards 2a28c7389c - Fix dnsoverquic to extend the number of streams when one is closed. 2024-10-14 13:53:55 +02:00
W.C.A. Wijngaards 114edf2c38 - Fix to display warning if quic-port is set but dnsoverquic is not
enabled when compiled.
2024-10-14 11:34:26 +02:00
W.C.A. Wijngaards e0c93e300b - Fix contrib/aaaa-filter-iterator.patch for change in call
signature for cache_fill_missing.
2024-10-11 11:42:30 +02:00
W.C.A. Wijngaards bd1813b126 - Fix harden-unverified-glue for AAAA cache_fill_missing lookups. 2024-10-11 09:03:11 +02:00
W.C.A. Wijngaards 1b7e14dc39 - Fix to disable detection of quic configured ports when quic is
not compiled in.
2024-10-11 08:51:14 +02:00
W.C.A. Wijngaards 8b7782e8fc - Fix add reallocarray to alloc stats unit test, and disable
override of strdup in unbound-host, and the result of config
  get option is freed properly.
2024-10-10 10:43:23 +02:00
W.C.A. Wijngaards e0201435a4 - Fix cookie_file test sporadic fails for time change during
the test.
2024-10-10 09:45:48 +02:00
W.C.A. Wijngaards 66fb3ff670 - Fix for dnstap compile of doqclient with doq disabled. 2024-10-09 15:52:33 +02:00
W.C.A. Wijngaards 36461ea73d Changelog entry and unit test for fix of NSEC TTL and prefetch ttl.
- Fix to limit NSEC TTL for messages from cachedb. Fix to limit the
  prefetch ttl for messages after a CNAME with short TTL.
2024-10-09 15:29:23 +02:00
W.C.A. Wijngaards 5679c8b1df - Fix to limit NSEC TTL for messages from cachedb. Fix to limit the
prefetch ttl for messages after a CNAME with short TTL.
2024-10-09 15:28:55 +02:00
W.C.A. Wijngaards a4d8c0c43b Changelog note for #871
- Merge #871: DNS over QUIC. This adds `quic-port: 853` and
  `quic-size: 8m` that enable dnsoverquic, and the counters
  `num.query.quic` and `mem.quic` in the statistics output.
  The feature needs to be enabled by compiling with libngtcp2,
  with `--with-libngtcp2=path` and libngtcp2 needs openssl+quic,
  pass that with `--with-ssl=path` to compile unbound as well.
2024-10-09 10:35:45 +02:00
3d89c26d32 DNSoverQUIC (#871)
* - dnsoverquic, configure --with-libngtcp2 option.

* - dnsoverquic, create comm_point for doq and receive cmsg local address.

* - dnsoverquic, less obtrusive debug.

* - dnsoverquic, log and fix local port number. Neater subroutines and ifdefs.

* - dnsoverquic, add testcode/doqclient.

* - dnsoverquic, review fixes on doqclient.

* - dnsoverquic, fix unit test testbound link.

* - dnsoverquic, parse query in doqclient.

* - dnsoverquic, link with libngtcp2_crypto_openssl and code for doqclient.

* - dnsoverquic, random routine for doqclient and fix ngaddr allocation, and
  check ub_initstate return.

* - dnsoverquic, fix doqclient free of allocated ngaddr addresses.

* - dnsoverquic, enable debug output with -v for doqclient.

* - dnsoverquic, create and set TLS object and TLS context in doqclient.

* - dnsoverquic, work on quic tls context in doqclient.

* - dnsoverquic, set default dnsoverquic port to the standardized 853 port.

* - dnsoverquic, remove debug comment.

* - dnsoverquic, dns-over-quic quic-port: 853 config option.

* - dnsoverquic, log type of interface created at start of unbound.

* - dnsoverquic, log type of no tls https as https when interface is created.

* - dnsoverquic, setup client quic tls methods.

* - dnsoverquic, event work in doqclient.

* - dnsoverquic, explain in documentation that QUIC uses UDP.

* - dnsoverquic, make doqclient exit.

* - dnsoverquic, doqclient cleanup run routine.

* - dnsoverquic, doqclient code nicer.

* - dnsoverquic, doqclient read and timer.

* - dnsoverquic, doqclient write work.

* - dnsoverquic, review fixes.

* - dnsoverquic, detect openssl quic support at configure time.

* - dnsoverquic, do not allow QUIC on port 53 to stop confusion of DoQ and DNS.

* - dnsoverquic, in doqclient, when idle close is returned, drop the connection
  without calling ngtcp2_conn_write_connection_close.

* - dnsoverquic, in doqclient, log callbacks.

* - dnsoverquic, in doqclient add extend_max_local_streams_bidi callback.

* - dnsoverquic, in doqclient add client query lists.

* - dnsoverquic, in doqclient, code cleaner, log text nicer.

* - dnsoverquic, in doqclient, work on write_streams.

* - dnsoverquic, in doqclient, use signed int for stream_id, work on the
  ngtcp2_recv_stream_data callback.

* - dnsoverquic, in doqclient, print result and fixes for recv data.

* - dnsoverquic, in doqclient, add the event callbacks to fptr wlist.

* - dnsoverquic, in doqclient, when already expired, use zero timeout timer.

* - dnsoverquic, in doqclient, ignore unused return codes from
  ngtcp2_conn_writev_stream.

* - dnsoverquic, add doqclient event functions to the unbound-dnstap-socket
  test tool for linking.

* - dnsoverquic, in doqclient, fix multiple operands for the commandline.
  neater dns message output.

* - dnsoverquic, in doqclient, store packet when write blocks and try later.

* - dnsoverquic, in doqclient, limit number of packets and number of bytes sent.

* - dnsoverquic, in doqclient, better size estimate for outgoing packet.

* - dnsoverquic, in doqclient, fix that already written next packet is not
  counted for data length to send.

* - dnsoverquic, in doqclient, early data transmission and session resumption.

* - dnsoverquic, send version negotiation packet.

* - dnsoverquic, send retry and accept the connection.

* - dnsoverquic, storage structures.

* - dnsoverquic, doq connection setup.

* - dnsoverquic, neater code layout for new conn. Fix verbosity of log print.

* - dnsoverquic, doq conn callback functions.

* - dnsoverquic, doq_fill_rand routine in header file.

* - dnsoverquic, keep track of connection ids.

* - dnsoverquic, get_new_connection_id callback.

* - dnsoverquic, create doq_conid tree.

* - dnsoverquic, settings for server connection.

* - dnsoverquic, tls context.

* - dnsoverquic, sendmsg error handling.

* - dnsoverquic, neat code.

* - dnsoverquic, track doq connection last error.

* - dnsoverquic, neater packet address parameters.

* - dnsoverquic, fix uninitialized bytes in msg control in doq sendmsg, and
  fix tree cleanup of conid tree.

* - dnsoverquic, better usage text for doqclient.

* - dnsoverquic, neat code.

* - dnsoverquic, connection receive packet handling.

* - dnsoverquic, debug output.

* - dnsoverquic, debug switched meaning of scid and dcid gives
  ERR_TRANSPORT_PARAM.

* - dnsoverquic, remove debug output.

* - dnsoverquic, connection delete routine and error from connection read in
  more detail with less clutter.

* - dnsoverquic, write to stream, and receive stream data, log packet.

* - dnsoverquic, alpn set up.

* - dnsoverquic, connection close.

* - dnsoverquic, doq_table and locks.

* - dnsoverquic, fix tests.

* - dnsoverquic, better locking.

* - dnsoverquic, doq_stream.

* - dnsoverquic, remove compile warning.

* - dnsoverquic, doq_stream receive data.

* - dnsoverquic, fixes for locks and keep length bytes allocated.

* - dnsoverquic, lock connection on initial insertion.

* - dnsoverquic, reply information, and reply buffer.

* - dnsoverquic, reply info from cache, local-zone and recursion lookups.

* - dnsoverquic, spelling in comment about buffer storage.

* - dnsoverquic, stream write list and doqclient fixes to exit and printout.

* - dnsoverquic, doqclient -q option for short printout.

* - dnsoverquic, unit test with local data reply.

* - dnsoverquic, write connection and write event is set.

* - dnsoverquic, neater logging for write event connection stream writes.

* - dnsoverquic, log remote connection when the streams are written for it.

* - dnsoverquic, better threaded use, threads can write to doq connections at
  the same time.

* - dnsoverquic, unit test for the calculation of connection size with a query.

* - dnsoverquic, use less memory per connection.

* - dnsoverquic, remove unit test output.

* - dnsoverquic, add MSG_DONTWAIT so that there is no mistakenly blocking
  socket operations.

* - dnsoverquic, doqclient logs address on connection failures.

* - dnsoverquic, compat code for clock get time routine.

* - dnsoverquic, use skip_test for doq unit test.

* - dnsoverquic, fixes for proxyprotocol, use remote_addr and set proxyprotocol
  disabled on the doq connection.

* - dnsoverquic, doqclient sets log identity to its name, instead of "unbound".

* - dnsoverquic, handle blocked udp packet writes.

* - dnsoverquic, fix function documentation for verbose_print_addr from
  services/listen_dnsport.c.

* - dnsoverquic, fix doq_conn lock protection. The checklock allows to set
  the output file name, and doqclient uses that. Print place of lock_protect.

* - dnsoverquic, neater buffer clear when write of blocked packet fails, make
  sure that memory area does not overlap for blocked packet addresses when
  write of blocked packet fails, and size blocked packet buffer to the pkt buf.

* - dnsoverquic, move lock check after the test to test script in doq test.

* - dnsoverquic, the doq test uses valgrind when enabled.

* - dnsoverquic, git ignore the doqclient test.

* - dnsoverquic, limit the buffer for packets to max packet size with some more.

* - dnsoverquic, spelling fix.

* - dnsoverquic, timer work, structure and adds and deletes.

* - dnsoverquic, timer_tree uses table.lock.

* - dnsoverquic, fix timer tree remove and spelling in header file comment.

* - dnsoverquic, fix testbound for timer compare function linkage.

* - dnsoverquic, timer set add debug output.

* - dnsoverquic, doq_conn_check_timer function.

* - dnsoverquic, doq_done_setup_timer_and_write function.

* - dnsoverquic, fix that doq conn is not deleted whilst editing write and timer.

* - dnsoverquic, Fix #861 make ERROR netevent.h:1073:32: error: field 'blocked_pkt_pi' has incomplete type

* - dnsoverquic, timer element has timeout setup when socket callback complete.

* - dnsoverquic, fix unit test compile.

* - dnsoverquic, timer callback routine, handle timeout and close and delete the
  connection if necessary.

* - dnsoverquic, timer pickup stops at current time.

* - dnsoverquic, timer comparable with the event base time.

* - dnsoverquic, erase marked time when timer disabled.

* - dnsoverquic, fix timer to set correctly and lock popped write connection
  early, before it is modified.

* - dnsoverquic, fix to unlock connection lock when it is unlinked and deleted.

* - dnsoverquic, fix to unlock connection lock when it is deleted because it is
  a duplicate connection.

* - dnsoverquic, fix that doq timer is not disabled when not set.

* - dnsoverquic, quic-size: 8m maximum number of bytes for QUIC buffers.

* - dnsoverquic, flex and bison.

* - dnsoverquic, quic-size turn away new connections when full.

* - dnsoverquic, doqclient outputs stream reset information.

* - dnsoverquic, detect stream close and reset.

* - dnsoverquic, free stream buffers when data is acked and stream is closed.

* - dnsoverquic, delete stream when closed. Unlink it. Allow stream_id 4 as first.

* - dnsoverquic, stats output for mem.quic and num.query.quic.

* - dnsoverquic, review fix.

* - dnsoverquic, fix when compiled without ngtcp2.

* - dnsoverquic, fix to detect ngtcp2_crypto_quictls for openssl crypto, after
  change in libngtcp2.

* - dnsoverquic, fix for newer ngtcp2 versions. detect ngtcp2_ccerr_default,
  ngtcp2/ngtcp2_crypto_quictls.h, struct ngtcp2_pkt_hd.tokenlen,
  struct ngtcp2_settings.tokenlen and struct ngtcp2_version_cid.

* - dnsoverquic, fix for newer ngtcp2 version, detect number of arguments for
  ngtcp2_conn_shutdown_stream.

* - dnsoverquic, fix for newer ngtcp2.

* - dnsoverquic, use the functions from util/timeval_func.h.

* - dnsoverquic, fix in doqclient only write transport parameters once.

* - dnsoverquic, debug log output removed.

* - dnsoverquic, fix in doqclient to work with renamed NGTCP2_CC_ALGO_BBR_V2
  from ngtcp2.

* - dnsoverquic, fix to check in doq_server_socket_create that tls-service-key
  and tls-service-pem have a value.

* - dnsoverquic, fix to error when doq_server_socket_create fails.

* - dnsoverquic, improve linebreaks in configparser additions.

* - dnsoverquic, fix port from interface pickup after main branch change.

* Fix getting user data from SSL, fix calloc warning.

* Fix fwrite return value check in doqclient

* - timeval_substruct from timeval_func.h
- lock_protect also for HAVE_NGTCP2_CCERR_DEFAULT
- fix doq logging for inet_ntop failures

* - memset for consistency
- no value returned from msghdr_get_ecn when S_SPLINT_S is defined

* - dnsoverquic, rerun autoconf.

---------

Co-authored-by: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
2024-10-09 10:32:03 +02:00
W.C.A. Wijngaards dcf7afd722 - Fix #1128: Cannot override tcp-upstream and tls-upstream with
forward-tcp-upstream and forward-tls-upstream.
2024-10-08 15:29:03 +02:00
W.C.A. Wijngaards e67171612b - Fix #1149: unbound-control-setup hangs sometimes depending on
the openssl version.
2024-10-08 11:54:07 +02:00
Yorgos Thessalonikefs a1b25f0296 - The fix for CVE-2024-8508 was part of 1.21.1, a security point release
on 1.21.0. The code repository continues with this fix and the version
  number 1.22.0.
2024-10-03 18:19:01 +02:00
Yorgos Thessalonikefs 490585bf29 Merge branch 'release-1.21.1' 2024-10-03 18:14:01 +02:00
Yorgos Thessalonikefs b7c61d7cc2 - Fix CVE-2024-8508, unbounded name compression could lead to denial of
service.
2024-10-03 17:41:20 +02:00
Yorgos Thessalonikefs 01883fb017 - Set version to 1.21.1 2024-10-03 14:11:57 +02:00
W.C.A. Wijngaards 5bb3b9cc83 - Fix unbound dnstap socket test program analyzer warnings about
unused variable assignments and variable initialization.
2024-09-30 16:36:01 +02:00
W.C.A. Wijngaards 3a1b79f6a1 - Fix negative cache NSEC3 parameter compares for zero length NSEC3
salt.
2024-09-30 09:25:51 +02:00
W.C.A. Wijngaards 84eeb9b97c - Fix #1144: [FR] log timestamps in ISO8601 format with timezone.
This adds the option `log-time-iso: yes` that logs in ISO8601
  format.
2024-09-25 11:16:46 +02:00
Yorgos Thessalonikefs d88eeb4c32 Changelog entry for #1143:
- Merge #1143: Fix cache update when serve expired is used. Expired
  records are favored over resolution and validation failures when
  serve-expired is used.
2024-09-24 16:49:34 +02:00
Yorgos ThessalonikefsandGitHub 2e398d51ba Fix cache update when serve expired is used (#1143)
- Fix cache update when serve expired is used in order to not evict
  still usable expired records. Modules are forbidden to update the
  cache if their answer is DNSSEC unchecked or bogus and a valid
  (expired) entry already exists. Bogus replies from the validator are
  also discarded in favor of existing (expired) valid replies.

- serve-expired-ttl-reset should try to keep expired records in the
  cache in case they are reset.
2024-09-24 16:47:04 +02:00
Yorgos Thessalonikefs 24ebca7df6 - More clear text for prefetch and minimal-responses in the
unbound.conf man page.
2024-09-24 15:10:21 +02:00
Yorgos Thessalonikefs 7f4a61e6fc - Attempt to further fix doh_downstream_buffer_size.tdir flakiness. 2024-09-24 12:21:03 +02:00
Yorgos Thessalonikefs db719d404f - Fix doxygen warnings by commenting out CLANG_ASSISTED_PARSING,
CLANG_ADD_INC_PATHS, CLANG_OPTIONS and CLANG_DATABASE_PATH; they were
  already disabled.
2024-09-23 15:31:32 +02:00
W.C.A. Wijngaards a35a0c49da - Fix dns64 with prefetch that the prefetch is stored in cache. 2024-09-23 12:19:43 +02:00
W.C.A. Wijngaards 5e9b6296b7 - Add redis-command-timeout: 20 and redis-connect-timeout: 200,
that can set the timeout separately for commands and the
  connection set up to the redis server. If they are not
  specified, the redis-timeout value is used.
2024-09-17 13:10:34 +02:00
W.C.A. Wijngaards 606e262fdd Changelog comment for #1140.
- Merge #1140: Fix spelling mistake in comments.
2024-09-16 12:15:04 +02:00
TochusandGitHub 819764663b Fix spelling mistake in comments (#1140)
I noticed a spelling mistake in the comments. The term “chain of trust” was incorrectly written as “chainoftrust”. This change corrects the spelling to “chain of trust” which is the correct term used in English.
2024-09-16 12:14:28 +02:00
Yorgos Thessalonikefs 6bf2b2ac56 - Fix and add comments in testdata/val_negcache_ttl.rpl. 2024-09-11 12:16:02 +02:00
W.C.A. Wijngaards 5767b0933f - Add unit test for ttl limit for aggressive nsec. 2024-09-10 10:17:31 +02:00
W.C.A. Wijngaards 24e0f0ab7e - Fix to limit NSEC and NSEC3 TTL when aggressive nsec is
enabled (RFC9077).
2024-09-10 10:13:48 +02:00
Yorgos Thessalonikefs d3fdbba877 - Fix comment to not trigger doxygen unknown command. 2024-09-06 16:03:20 +02:00
Yorgos Thessalonikefs c36ce2a390 - Fix alloc-size and calloc-transposed-args compiler warnings. 2024-09-06 16:01:30 +02:00
W.C.A. Wijngaards 7ecff4113c - Fix config file read for dnstap-sample-rate. 2024-09-05 09:35:54 +02:00
W.C.A. Wijngaards 99824bc0e6 Changelog note for #1135
- Merge #1135: Add new IANA trust anchor.
2024-09-02 09:25:44 +02:00
9f09c36401 Add new IANA trust anchor (#1135)
Signed-off-by: Keelan Cannoo <keelan.cannoo@cyberstorm.mu>
Co-authored-by: Keelan10 <keelan.cannoo@cyberstorm.mu>
2024-09-02 09:24:55 +02:00
W.C.A. Wijngaards a887284703 - Fix for #1132, comment about adjusted copy of reference check. 2024-08-30 08:56:00 +02:00
W.C.A. Wijngaards fb198b96f1 Changelog note for #1132 and fix for #1132.
- Merge #1132: b.root renumbering.
- Fix for #1132, adjusted unit test for change in the test file.
2024-08-30 08:51:56 +02:00
Loganaden VelvindronandGitHub 30bf996f39 b.root renumbering (#1132)
https://b.root-servers.org/news/2023/05/16/new-addresses.html

Worked together with Jaykishan Muktawoa <jay@cyberstorm.mu>
2024-08-30 08:48:31 +02:00
W.C.A. Wijngaards 52154e658a - Fix to print port number in logs for auth zone transfer activities. 2024-08-29 13:04:03 +02:00
W.C.A. Wijngaards c06d3646a9 - Unit test for auth zone transfer TLS, and TLS failure. 2024-08-29 10:40:31 +02:00
W.C.A. Wijngaards 42d421a305 - Fix that stub-zone and forward-zone clauses do not exhaust memory
for long content.
2024-08-28 13:16:29 +02:00
W.C.A. Wijngaards b5951ce1fa - Fix that when rpz is applied the message does not get picked up by
the validator. That stops validation failures for the message.
2024-08-28 10:51:22 +02:00
W.C.A. Wijngaards 6b37309705 - Fix #1130: Loads of logs: "validation failure: key for validation
<domain>. is marked as invalid because of a previous" for
  non-DNSSEC signed zone.
2024-08-27 17:00:27 +02:00
W.C.A. Wijngaards dc274fef9b - Fix documentation for cache_fill_missing function. 2024-08-23 13:19:15 +02:00
W.C.A. Wijngaards db1167c8b3 - Fix #1127: error: "memory exhausted" when defining more than 9994
local-zones.
2024-08-23 09:22:07 +02:00
W.C.A. Wijngaards 1e0cf1e86b - Merge patch to fix for glue that is outside of zone, with
`harden-unverified-glue`, from Karthik Umashankar (Microsoft).
  Enabling this option protects the Unbound resolver against bad
  glue, that is unverified out of zone glue, by resolving them.
  It uses the records as last resort if there is no other working
  glue.
2024-08-23 08:56:48 +02:00
W.C.A. Wijngaards 348df52e05 Enable ci back after debug. 2024-08-21 14:20:04 +02:00
W.C.A. Wijngaards 6b3266aaf8 - Fix for char signedness warnings on NetBSD. 2024-08-21 14:15:23 +02:00
W.C.A. Wijngaards 4f52461e81 - Add cross platform netbsd to github ci. 2024-08-21 14:03:11 +02:00
W.C.A. Wijngaards 06d5031d22 - Add cross platform openbsd to github ci. 2024-08-21 13:50:55 +02:00
W.C.A. Wijngaards 12119e2d3e ci for freebsd nicer, with libevent, faster without static compile, and
with grouped output, also the pkg install is conditional on the platform.
2024-08-21 13:37:42 +02:00
W.C.A. Wijngaards 19d53d5663 Fix for freebsd ci. 2024-08-21 13:24:54 +02:00
W.C.A. Wijngaards 04e6f9e03b - Add cross platform freebsd to github ci. 2024-08-21 13:20:00 +02:00
W.C.A. Wijngaards 3d350fa73d - Add iter-scrub-ns, iter-scrub-cname and max-global-quota
configuration options.
2024-08-20 14:08:52 +02:00
W.C.A. Wijngaards 015b2b0daf - Fix #1126: unbound-control-setup hangs while testing for openssl
presence starting from version 1.21.0.
2024-08-19 15:51:47 +02:00
W.C.A. Wijngaards 5fa84d50bf - Tag for release 1.21.0, the repository continues with 1.21.1
in development.
2024-08-15 11:01:41 +02:00
W.C.A. Wijngaards 79e4c57851 - Fix spelling for the cache-min-negative-ttl entry in the
example.conf.
2024-08-09 14:04:25 +02:00
W.C.A. Wijngaards 5abdd09095 - Fix that for windows the module startup is called and sets up
the module-config.
2024-08-08 16:14:09 +02:00
W.C.A. Wijngaards 158c1defe3 - Set version number to 1.21.0 for release. 2024-08-08 09:30:53 +02:00
W.C.A. Wijngaards b4519012dc - Fix CacheFlush issues with limit on NS RRs. Thanks to Yehuda Afek,
Anat Bremler-Barr, Shoham Danino and Yuval Shavitt (Tel-Aviv
  University and Reichman University).
2024-08-08 09:28:44 +02:00
W.C.A. Wijngaards ed883238fd - Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco
Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich.
2024-08-08 09:27:45 +02:00
W.C.A. Wijngaards 0f2f6025e7 - Fix that alloc stats for forwards and hints are printed, and when
alloc stats is enabled, the unit test for unbound control waits for
  reloads to complete.
2024-08-02 15:51:40 +02:00
W.C.A. Wijngaards 3cbf554e3b Changelog note for #1090
- Merge #1090: Cookie secret file. Adds
  `cookie-secret-file: "unbound_cookiesecrets.txt"` option to store
  cookie secrets for EDNS COOKIE secret rollover. The remote control
  add_cookie_secret, activate_cookie_secret and drop_cookie_secret
  commands can be used for rollover, the command print_cookie_secrets
  shows the values in use.
2024-08-02 13:36:06 +02:00
ad21dbd1c2 Cookie secret file (#1090)
* - cookie-secret-file, define struct.

* - cookie-secret-file, add config option, create, read and delete struct.

* - cookie-secret-file, check cookie secrets for cookie validation.

* - cookie-secret-file, unbound-control add_cookie_secret, drop_cookie_secret,
  activate_cookie_secret and print_cookie_secrets.

* - cookie-secret-file, test and fix locks, renew writes a fresh cookie,
  staging cookies get a fresh cookie and spelling in error message.

* - cookie-secret-file, remove unused variable from cookie file unit test.

* Remove unshare and faketime dependencies for cookie_file test; documentation nits.

---------

Co-authored-by: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
2024-08-02 13:32:08 +02:00
W.C.A. Wijngaards 50cf55bdac Update changelog.
- Fix testbound for alloc stats strdup in util/alloc.c.
2024-08-02 08:59:47 +02:00
W.C.A. Wijngaards 6106528a50 - Fix testbound for alloc stats strdup in util/alloc.c. 2024-08-02 08:58:22 +02:00
W.C.A. Wijngaards befa7d8cd8 - Fix that alloc stats has strdup checks, it stops debuggers from
complaining about mismatch at free time.
2024-08-02 08:54:54 +02:00
W.C.A. Wijngaards 92be76fb89 - Fix that the worker mem report with alloc stats does not attempt
to print memory use of forwards and hints if they have been
  deleted already.
2024-08-01 17:15:07 +02:00
W.C.A. Wijngaards 9a6b6765cc - Fix dnstap test program, cleans up to have clean memory on exit,
for tap_data_free, does not delete NULL items. Also it does not try
  to free the tail, specifically in the free of the list since that
  picked up the next item in the list for its loop causing invalid
  free. Added internal unit test to unbound-dnstap-socket for that.
2024-08-01 16:12:04 +02:00
W.C.A. Wijngaards 03b511b1a2 - Fix for #1114: Fix that cache fill for forward-host names is
performed, so that with nonzero target-fetch-policy it fetches
  forwarder addresses and uses them from cache. Also updated that
  delegation point cache fill routines use CDflag for AAAA message
  lookups, so that its negative lookup stops a recursion since the
  cache uses the bit for disambiguation for dns64 but the recursion
  uses CDflag for the AAAA target lookups, so the check correctly
  stops a useless recursion by its cache lookup.
2024-07-31 11:42:44 +02:00
W.C.A. Wijngaards 6af28bed08 - Fix to document parameters of auth_zone_verify_zonemd_with_key. 2024-07-30 13:47:53 +02:00
W.C.A. Wijngaards f094f4ea3c - Add root key 38696 from 2024 for DNSSEC validation. It is added
to the default root keys in unbound-anchor. The content can be
  inspected with `unbound-anchor -l`.
2024-07-25 11:42:22 +02:00
Yorgos Thessalonikefs c717debace - For #935 and #1104, clarify RPZ order and semantics. 2024-07-24 01:54:02 +02:00
Yorgos Thessalonikefs 7d4d21764a - Cleanup ede.tdir test. 2024-07-23 20:22:25 +02:00
W.C.A. Wijngaards 83e6977f06 - Fix link of unbound-dnstap-socket without openssl. 2024-07-23 15:06:54 +02:00
W.C.A. Wijngaards 671e11552c - Fix link of dnstap without openssl. 2024-07-23 14:56:21 +02:00
W.C.A. Wijngaards c4541e634b - Fix uninitialized variable warning in create_tcp_accept_sock. 2024-07-23 10:42:36 +02:00
W.C.A. Wijngaards 30da725e67 - Fix to have empty definition when not supported for weak attribute. 2024-07-23 10:02:39 +02:00
W.C.A. Wijngaards 8de5ae3552 - Fix compile when the compiler does not support the noreturn
attribute.
2024-07-23 09:55:31 +02:00
W.C.A. Wijngaards 5bea29b01c - For #1110: Test for fallthrough attribute in configure and add
fallthrough attribute annotations.
2024-07-23 09:47:42 +02:00
Wouter WijngaardsandGitHub 89c9eafa44 Merge pull request #1110 from r-barnes/patch-1
Make fallthrough explicit for libworker.c
2024-07-23 09:44:28 +02:00
Yorgos Thessalonikefs 3512eaec48 - Fix #1106: ratelimit-below-domain logs the wrong FROM address. 2024-07-23 09:07:06 +02:00
Richard BarnesandGitHub f9bd35dcfa Make fallthrough explicit for libworker.c
The code currently doesn't compile with LLVM's `-Wimplicit-fallthrough` flag, but the attribute works for both GCC (>=7) and LLVM.
2024-07-22 16:37:38 -07:00
W.C.A. Wijngaards 3af4e44646 - Fix dnstap wakeup, a running wakeup timer is left to expire and not
increased, a timer is started when the dtio thread is sleeping,
  the timer set disabled when the dtio thread goes to sleep, and
  after sleep the thread checks to see if there are messages to log
  immediately.
2024-07-19 16:16:02 +02:00
W.C.A. Wijngaards c3dd6a2dbd - Add dnstap-sample-rate that logs only 1/N messages, for high volume
server environments. Thanks Dan Luther.
2024-07-19 10:04:40 +02:00
W.C.A. Wijngaards 8fca3e7c5b - For #1103: Fix to drop mesh state reference for the http2 stream
associated with the reply, not the currently active stream. And
  it does not remove it twice on a mesh_send_reply call. The reply
  h2_stream is NULL when not in use, for more initialisation.
2024-07-16 14:23:10 +02:00
W.C.A. Wijngaards 8947c2c764 - For #1103: fix to also drop mesh state reference when the discard
limit is reached, when there is an error making a new recursion
  state and when the connection is dropped with is_drop.
2024-07-15 14:51:20 +02:00
W.C.A. Wijngaards b1e3319a11 Merge branch 'master' of github.com:NLnetLabs/unbound 2024-07-12 16:41:58 +02:00
W.C.A. Wijngaards d52f501d90 - For #1103: fix to also drop mesh state reference when a h2 reply is
dropped.
2024-07-12 16:41:46 +02:00
Yorgos Thessalonikefs 7083d58c6b - For #1102: clearer text for using interface-* options for the
loopback interface.
2024-07-12 16:29:44 +02:00
W.C.A. Wijngaards 3adb9c8f92 - Fix #1103: unbound 1.20.0 segmentation fault with nghttp2. 2024-07-12 16:11:29 +02:00
Yorgos Thessalonikefs 51425b2388 - Add RPZ tag tests in acl_interface.tdir. 2024-07-12 15:38:12 +02:00
W.C.A. Wijngaards d43760a8cd - For #773: In contrib/unbound.service.in set unbound to start after
network-online.target. Also for contrib/unbound_portable.service.in.
2024-07-10 14:05:43 +02:00
Yorgos Thessalonikefs ea3e327006 - Update list of known EDE codes. 2024-07-09 15:58:30 +02:00
W.C.A. Wijngaards be09350eca - Fix shadowed error string variable in validator dnskey handling. 2024-07-08 16:50:16 +02:00
W.C.A. Wijngaards 169acfc546 - Fixup algo_needs_reason string buffer length. 2024-07-08 15:38:27 +02:00
W.C.A. Wijngaards bed7cc2a90 - Fix that validation reason failure that uses string print uses
separate buffer that is passed, from the scratch validation buffer.
2024-07-08 15:29:20 +02:00
Yorgos Thessalonikefs 02f4446833 - Don't check for message TTL changes if the RRsets remain the same. 2024-07-05 19:58:19 +02:00
W.C.A. Wijngaards c8a2289542 - Fix for #1099: Fix to check for deleted RRset when the contents
is updated and fetched after it is stored, and also check for a
  changed RRset.
2024-07-05 17:54:46 +02:00
W.C.A. Wijngaards b53d90053e - Fix #1099: Unbound core dump on SIGSEGV. 2024-07-05 17:18:01 +02:00
W.C.A. Wijngaards 978b0696d3 - Fix neater printout. 2024-07-05 14:11:26 +02:00
W.C.A. Wijngaards ec5f86b4eb - Fix for neater printout for error for missing DS response. 2024-07-05 08:49:52 +02:00
W.C.A. Wijngaards ec2f45c6fd - Fix to print details about the failure to lookup a DNSKEY record
when validation fails due to the missing DNSKEY. Also for key prime
  and DS lookups.
2024-07-04 14:51:18 +02:00
W.C.A. Wijngaards 6b319c97ee - Fix compile warnings in fptr_wlist.c. 2024-07-03 16:42:52 +02:00
W.C.A. Wijngaards 6eb3992c9e - Fix to remove unneeded linebreak in fptr_wlist.c. 2024-07-03 15:51:22 +02:00
W.C.A. Wijngaards 94a94fd8c8 - Fix to use modstack_init in zonemd unit test. 2024-07-03 15:49:13 +02:00
W.C.A. Wijngaards 36f9d1a2a9 - Add unit test skip files and bison and flex output to gitignore. 2024-07-03 14:59:39 +02:00
W.C.A. Wijngaards d3a2264272 Changelog entry for #144 and #1098
- Fix #144: Port ipset to BSD pf tables.
2024-07-03 14:53:42 +02:00
Wouter WijngaardsandGitHub 92b6c2a7b9 Merge pull request #1098 from NLnetLabs/ipset-pf-support
Ipset pf support
2024-07-03 14:49:16 +02:00
W.C.A. Wijngaards a335e601e4 ipset-pf-support, move startup and destartup to the front of the module
func block functions, modstack call deinit function names, and detect
module change when no startup functions are needed.
2024-07-03 13:53:44 +02:00
a19009df1d Apply suggestions from code review
Co-authored-by: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
2024-07-03 13:08:51 +02:00
Yorgos Thessalonikefs 96f8a94c19 - Fix for repeated use of a DNAME record: first overallocate and then
move the exact size of the init value to avoid false positive heap
  overflow reads from address sanitizers.
2024-07-03 10:08:44 +02:00
W.C.A. Wijngaards 2fe4e2ec3e - Fix compile warning in worker pthread id printout. 2024-07-02 09:44:58 +02:00
W.C.A. Wijngaards e54928a628 - Fix unused variable warning in do_cache_remove. 2024-07-02 09:33:22 +02:00
W.C.A. Wijngaards 538434186e - Fix to remove unused include from the readzone test program. 2024-07-02 09:31:34 +02:00
W.C.A. Wijngaards 65e7253d19 ipset-pf-support, simplification of code. 2024-07-02 09:08:27 +02:00
W.C.A. Wijngaards 03ac902296 - ipset-pf-support, fix to skip unit test if no pf dev. 2024-07-01 17:11:20 +02:00
W.C.A. Wijngaards 97ad1df343 ipset-pf-support, fix to log error on failure to open pf. 2024-07-01 17:06:11 +02:00
W.C.A. Wijngaards 2279cde8f7 ipset-pf-support, fix to remove unused include, free at end, adjust
qname for comparison.
2024-07-01 17:02:49 +02:00
W.C.A. Wijngaards ff653a7ef8 Call module init init again, and new function startup and destartup.
NULL can be used if the function is not used. Open shared ports during
reload. Deinit is called during reload.
2024-07-01 16:10:07 +02:00
W.C.A. Wijngaards fd11cd9182 ipset-pf-support, fix compilation, close of pf socket. 2024-07-01 14:54:45 +02:00
W.C.A. Wijngaards 3953f827fb Merge branch 'master' of https://github.com/madroach/unbound into ipset-pf-support 2024-07-01 14:36:33 +02:00
W.C.A. Wijngaards 7fbc061846 - Fix ip-ratelimit-cookie setting, it was not applied. 2024-06-27 14:51:58 +02:00
Yorgos Thessalonikefs 70f73a33b3 - Explicitly set the RD bit for the mesh query flags when prefetching.
These queries have no waiting client but they need to be treated as
  recursive.
2024-06-26 15:51:58 +02:00
Yorgos Thessalonikefs b67fbb69e7 - Fix pkg-config availability check in dnstap/dnstap.m4 and
systemd.m4.
- autoconf.
2024-06-21 14:34:12 +02:00
Yorgos Thessalonikefs 902c79608c - Fix #1092: Ubuntu 22.04 Jammy fails to compile unbound 1.20.0; by
adding helpful text for the Python interpreter version and allowing
  the default pkg-config unavailability error message to be shown.
- autoconf.
2024-06-19 15:27:50 +02:00
W.C.A. Wijngaards 08050dc939 - Fix #1091: Build fails with OpenSSL >= 3.0 built with
OPENSSL_NO_DEPRECATED.
2024-06-17 12:28:45 +02:00
W.C.A. Wijngaards 9603924bb4 - Add unit test for validation of repeated use of a DNAME record. 2024-06-07 11:56:19 +02:00
W.C.A. Wijngaards 4c2da2b979 - Fix validation for repeated use of a DNAME record. 2024-06-06 15:28:21 +02:00
W.C.A. Wijngaards 1974732d19 - Fix typos for 'the the' in text. 2024-06-06 09:35:57 +02:00
W.C.A. Wijngaards 3cad5818a1 - Fix memory leak in setup of dsa sig. 2024-06-06 09:30:09 +02:00
Yorgos Thessalonikefs ad12109191 - Merge #1080: AddressSanitizer detection in tdir tests and memory leak
fixes.
2024-06-04 17:34:58 +02:00
Yorgos Thessalonikefs f611220eb8 - Skip unbound-dnstap-socket unit test when not compiled with
--enable-debug.
2024-06-04 16:59:58 +02:00
Yorgos Thessalonikefs ac609fcbfc - Fix memory leak on exit for unbound-dnstap-socket; creates false negatives
during testing.
2024-05-31 12:11:17 +02:00
Yorgos Thessalonikefs 486985fbdf - Fix memory leak when reload_keep_cache is used and num-threads changes. 2024-05-31 12:09:35 +02:00
Yorgos Thessalonikefs caab100207 - Enable AddressSanitizer error detection in tdir tests. 2024-05-31 12:08:43 +02:00
Christopher Zimmermann 1d23e0c920 Merge remote-tracking branch 'upstream/master' 2021-02-03 13:19:19 +01:00
Christopher Zimmermann ad51795314 Don't try to run daemon_privileged on reload. 2020-05-10 22:30:25 +02:00
Christopher Zimmermann 7d76e84953 Port ipset to BSD pf tables 2020-05-10 22:30:25 +02:00
Christopher Zimmermann c96e4ca121 allow privileged initialisation of modules 2020-05-10 22:30:25 +02:00
197 changed files with 19547 additions and 871 deletions
+54
View File
@@ -161,6 +161,33 @@ jobs:
test_windows: "yes"
config: "no"
make: "no"
- name: FreeBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "freebsd"
cross_platform_arch: "x86-64"
cross_platform_version: "14.1"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: OpenBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "openbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "7.5"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: NetBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "netbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "10.0"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
steps:
- uses: actions/checkout@v4
@@ -331,6 +358,33 @@ jobs:
echo "::group::make install"
make install
echo "::endgroup::"
- name: cross-platform-action on ${{ matrix.cross_platform_os }} ${{ matrix.cross_platform_version }}
if: ${{ matrix.with_cross_platform_action == 'yes' }}
uses: cross-platform-actions/action@v0.25.0
env:
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
with:
environment_variables: CROSS_PLATFORM_OS
operating_system: ${{ matrix.cross_platform_os }}
architecture: ${{ matrix.cross_platform_arch }}
version: ${{ matrix.cross_platform_version }}
shell: bash
memory: 4G
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
echo "::group::configure"
./configure ${{ matrix.cross_platform_config }}
echo "::endgroup::"
echo "::group::make"
make
echo "::endgroup::"
echo "::group::make test"
make test
echo "::endgroup::"
- name: install libevent
if: ${{ matrix.install_libevent == 'yes' }}
run: sudo apt-get install libevent-dev
+5
View File
@@ -10,6 +10,9 @@
/config.status
/dnstap/dnstap_config.h
/dnscrypt/dnscrypt_config.h
/util/configlexer.c
/util/configparser.c
/util/configparser.h
/clubsyms.def
/doc/example.conf
/doc/libunbound.3
@@ -33,6 +36,7 @@
/asynclook
/delayer
/dohclient
/doqclient
/lock-verify
/memstats
/perf
@@ -55,6 +59,7 @@
/pythonmod/unboundmodule.py
/testdata/result.*
/testdata/.done-*
/testdata/.skip-*
/testdata/.perfstats.txt
/doc/html
/doc/xml
+17 -7
View File
@@ -179,11 +179,11 @@ testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
testcode/unitecs.c testcode/unitauth.c testcode/unitzonemd.c \
testcode/unittcpreuse.c
testcode/unittcpreuse.c testcode/unitdoq.c
UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \
unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \
readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo unitzonemd.lo \
unittcpreuse.lo
unittcpreuse.lo unitdoq.lo
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
$(COMPAT_OBJ)
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
@@ -242,6 +242,10 @@ DOHCLIENT_SRC=testcode/dohclient.c
DOHCLIENT_OBJ=dohclient.lo
DOHCLIENT_OBJ_LINK=$(DOHCLIENT_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
DOQCLIENT_SRC=testcode/doqclient.c
DOQCLIENT_OBJ=doqclient.lo
DOQCLIENT_OBJ_LINK=$(DOQCLIENT_OBJ) $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
PERF_SRC=testcode/perf.c
PERF_OBJ=perf.lo
PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
@@ -288,7 +292,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) \
$(DOHCLIENT_SRC) $(READZONE_SRC)
$(DOHCLIENT_SRC) $(DOQCLIENT_SRC) $(READZONE_SRC)
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
@@ -297,7 +301,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) \
$(DOHCLIENT_OBJ) $(READZONE_OBJ)
$(DOHCLIENT_OBJ) $(DOQCLIENT_OBJ) $(READZONE_OBJ)
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
@@ -334,7 +338,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h
TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
$(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) \
$(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) doqclient$(EXEEXT) \
testbound$(EXEEXT) unittest$(EXEEXT) readzone$(EXEEXT)
tests: all $(TEST_BIN)
@@ -416,6 +420,9 @@ streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
doqclient$(EXEEXT): $(DOQCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
perf$(EXEEXT): $(PERF_OBJ_LINK)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
@@ -439,7 +446,8 @@ unbound-control-setup: smallapp/unbound-control-setup.sh
dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
$(srcdir)/util/locks.h
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
@@ -702,6 +710,8 @@ depend:
# build rules
ipset.lo ipset.o: $(srcdir)/ipset/ipset.c
doqclient.lo doqclient.o: $(srcdir)/testcode/doqclient.c
unitdoq.lo unitdoq.o: $(srcdir)/testcode/unitdoq.c
# Dependencies
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
@@ -1297,7 +1307,7 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/wire2str.h
$(srcdir)/sldns/wire2str.h $(srcdir)/util/edns.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+1 -1
View File
@@ -9,7 +9,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
if test -z "$PYTHON"; then
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
AC_MSG_ERROR([Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version.])
PYTHON_VERSION=""
fi
+4 -3
View File
@@ -621,6 +621,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
}
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
@@ -828,8 +831,6 @@ cachedb_handle_query(struct module_qstate* qstate,
/* 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.
* TODO: this needs revisit. The expired data stored from cachedb has
* 0 TTL which is picked up by iterator later when looking in the cache.
*/
if(qstate->env->cfg->serve_expired && msg_expired) {
qstate->return_msg = NULL;
@@ -983,7 +984,7 @@ cachedb_get_mem(struct module_env* env, int id)
*/
static struct module_func_block cachedb_block = {
"cachedb",
&cachedb_init, &cachedb_deinit, &cachedb_operate,
NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
};
+23 -6
View File
@@ -58,7 +58,8 @@ struct redis_moddata {
int server_port; /* server's TCP port */
const char* server_path; /* server's unix path, or "", NULL if unused */
const char* server_password; /* server's AUTH password, or "", NULL if unused */
struct timeval timeout; /* timeout for connection setup and commands */
struct timeval command_timeout; /* timeout for commands */
struct timeval connect_timeout; /* timeout for connect */
int logical_db; /* the redis logical database to use */
};
@@ -88,10 +89,10 @@ redis_connect(const struct redis_moddata* moddata)
if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->timeout);
moddata->connect_timeout);
} else {
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout);
moddata->server_port, moddata->connect_timeout);
}
if(!ctx || ctx->err) {
const char *errstr = "out of memory";
@@ -100,7 +101,7 @@ redis_connect(const struct redis_moddata* moddata)
log_err("failed to connect to redis server: %s", errstr);
goto fail;
}
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) {
log_err("failed to set redis timeout");
goto fail;
}
@@ -159,8 +160,24 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
moddata->server_port = env->cfg->redis_server_port;
moddata->server_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
moddata->command_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->command_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
moddata->connect_timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_timeout % 1000) * 1000;
if(env->cfg->redis_command_timeout != 0) {
moddata->command_timeout.tv_sec =
env->cfg->redis_command_timeout / 1000;
moddata->command_timeout.tv_usec =
(env->cfg->redis_command_timeout % 1000) * 1000;
}
if(env->cfg->redis_connect_timeout != 0) {
moddata->connect_timeout.tv_sec =
env->cfg->redis_connect_timeout / 1000;
moddata->connect_timeout.tv_usec =
(env->cfg->redis_connect_timeout % 1000) * 1000;
}
moddata->logical_db = env->cfg->redis_logical_db;
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(moddata);
+109
View File
@@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* apply the fallthrough attribute. */
#undef ATTR_FALLTHROUGH
/* apply the noreturn attribute to a function that exits the program */
#undef ATTR_NORETURN
@@ -57,6 +60,9 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Whether the C compiler accepts the "fallthrough" attribute */
#undef HAVE_ATTR_FALLTHROUGH
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
@@ -123,6 +129,14 @@
and to 0 if you don't. */
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_conn_server_new', and to
0 if you don't. */
#undef HAVE_DECL_NGTCP2_CONN_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_crypto_encrypt_cb', and
to 0 if you don't. */
#undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#undef HAVE_DECL_NID_ED25519
@@ -406,12 +420,74 @@
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H
/* Define this to use nghttp2 client. */
#undef HAVE_NGHTTP2
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
#undef HAVE_NGHTTP2_NGHTTP2_H
/* Define this to use ngtcp2. */
#undef HAVE_NGTCP2
/* Define to 1 if you have the `ngtcp2_ccerr_default' function. */
#undef HAVE_NGTCP2_CCERR_DEFAULT
/* Define to 1 if you have the `ngtcp2_conn_encode_0rtt_transport_params'
function. */
#undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
/* Define to 1 if you have the `ngtcp2_conn_get_max_local_streams_uni'
function. */
#undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
/* Define to 1 if you have the `ngtcp2_conn_get_num_scid' function. */
#undef HAVE_NGTCP2_CONN_GET_NUM_SCID
/* Define to 1 if you have the `ngtcp2_conn_in_closing_period' function. */
#undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
/* Define to 1 if you have the `ngtcp2_conn_in_draining_period' function. */
#undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
/* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */
#undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4
/* Define to 1 if you have the `ngtcp2_conn_tls_early_data_rejected' function.
*/
#undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
/* Define to 1 if you have the `ngtcp2_crypto_encrypt_cb' function. */
#undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_client_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_server_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_H
/* Use libnss for crypto */
#undef HAVE_NSS
@@ -566,6 +642,9 @@
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
#undef HAVE_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
#undef HAVE_SSL_GET0_ALPN_SELECTED
@@ -575,6 +654,9 @@
/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
#undef HAVE_SSL_GET1_PEER_CERTIFICATE
/* Define to 1 if you have the `SSL_is_quic' function. */
#undef HAVE_SSL_IS_QUIC
/* Define to 1 if you have the `SSL_set1_host' function. */
#undef HAVE_SSL_SET1_HOST
@@ -617,6 +699,23 @@
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */
#undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
/* Define to 1 if `max_tx_udp_payload_size' is a member of `struct
ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN
/* Define to 1 if `original_dcid_present' is a member of `struct
ngtcp2_transport_params'. */
#undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
/* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */
#undef HAVE_STRUCT_NGTCP2_VERSION_CID
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
@@ -1484,6 +1583,10 @@ struct sockaddr_storage;
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
#ifdef HAVE_REALLOCARRAY
# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__)
#endif
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
@@ -1496,6 +1599,10 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size,
const char* file, int line, const char* func);
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
const char* func);
#elif defined(UNBOUND_ALLOC_LITE)
# include "util/alloc.h"
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
@@ -1506,6 +1613,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for DNS over QUIC traffic. */
#define UNBOUND_DNS_OVER_QUIC_PORT 853
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953
Vendored
+588 -58
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for unbound 1.20.1.
# Generated by GNU Autoconf 2.71 for unbound 1.22.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@@ -622,8 +622,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.20.1'
PACKAGE_STRING='unbound 1.20.1'
PACKAGE_VERSION='1.22.0'
PACKAGE_STRING='unbound 1.22.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@@ -921,6 +921,7 @@ with_libevent
with_libexpat
with_libhiredis
with_libnghttp2
with_libngtcp2
enable_static_exe
enable_fully_static
enable_lock_checks
@@ -1508,7 +1509,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.20.1 to adapt to many kinds of systems.
\`configure' configures unbound 1.22.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1574,7 +1575,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.20.1:";;
short | recursive ) echo "Configuration of unbound 1.22.0:";;
esac
cat <<\_ACEOF
@@ -1596,7 +1597,8 @@ Optional Features:
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-rpath disable hardcoded rpath (default=enabled)
--disable-largefile omit support for large files
--enable-systemd compile with systemd support
--enable-systemd compile with systemd support (requires libsystemd,
pkg-config)
--enable-alloc-checks enable to memory allocation statistics, for debug
purposes
--enable-alloc-lite enable for lightweight alloc assertions, for debug
@@ -1708,6 +1710,7 @@ Optional Packages:
--with-libexpat=path specify explicit path for libexpat.
--with-libhiredis=path specify explicit path for libhiredis.
--with-libnghttp2=path specify explicit path for libnghttp2.
--with-libngtcp2=path specify explicit path for libngtcp2, for QUIC.
--with-dnstap-socket-path=pathname
set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
@@ -1821,7 +1824,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.20.1
unbound configure 1.22.0
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2478,7 +2481,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.20.1, which was
It was created by unbound $as_me 1.22.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3240,13 +3243,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=20
UNBOUND_VERSION_MINOR=22
UNBOUND_VERSION_MICRO=1
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=28
LIBUNBOUND_REVISION=30
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -3341,7 +3344,9 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.20.1 had 9:28:1
# 1.21.0 had 9:28:1
# 1.21.1 had 9:29:1
# 1.22.0 had 9:30:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -6975,6 +6980,10 @@ printf "%s\n" "#define HAVE_ATTR_WEAK 1" >>confdefs.h
printf "%s\n" "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h
else
printf "%s\n" "#define ATTR_WEAK /**/" >>confdefs.h
fi
@@ -7022,6 +7031,79 @@ printf "%s\n" "#define HAVE_ATTR_NORETURN 1" >>confdefs.h
printf "%s\n" "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h
else
printf "%s\n" "#define ATTR_NORETURN /**/" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute" >&5
printf %s "checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute... " >&6; }
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test ${ac_cv_c_fallthrough_attribute+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_cv_c_fallthrough_attribute=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
void f(int x) {
int y = 0;
switch(x) {
case 1:
y = 1;
__attribute__((fallthrough));
/* fallthrough */
case 2:
y++;
break;
case 3:
y = 3;
break;
}
printf("%d", y);
}
int
main (void)
{
f(1);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_c_fallthrough_attribute="yes"
else $as_nop
ac_cv_c_fallthrough_attribute="no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
CFLAGS="$BAKCFLAGS"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_fallthrough_attribute" >&5
printf "%s\n" "$ac_cv_c_fallthrough_attribute" >&6; }
if test $ac_cv_c_fallthrough_attribute = yes; then
printf "%s\n" "#define HAVE_ATTR_FALLTHROUGH 1" >>confdefs.h
printf "%s\n" "#define ATTR_FALLTHROUGH __attribute__((fallthrough));" >>confdefs.h
else
printf "%s\n" "#define ATTR_FALLTHROUGH /**/" >>confdefs.h
fi
@@ -17624,7 +17706,8 @@ have_systemd=no
if test "x$enable_systemd" != xno
then :
if test -n "$PKG_CONFIG"; then
have_systemd=no
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
@@ -17684,11 +17767,31 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$SYSTEMD_PKG_ERRORS" >&5
have_systemd=no
as_fn_error $? "Package requirements (libsystemd) were not met:
$SYSTEMD_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
and SYSTEMD_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
have_systemd=no
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
and SYSTEMD_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
See \`config.log' for more details" "$LINENO" 5; }
else
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
@@ -17699,6 +17802,7 @@ fi
if test "x$have_systemd" != "xyes"
then :
have_systemd_daemon=no
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
@@ -17758,11 +17862,31 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
have_systemd_daemon=no
as_fn_error $? "Package requirements (libsystemd-daemon) were not met:
$SYSTEMD_DAEMON_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details." "$LINENO" 5
elif test $pkg_failed = untried; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
have_systemd_daemon=no
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
See \`config.log' for more details" "$LINENO" 5; }
else
SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
@@ -17789,7 +17913,9 @@ printf "%s\n" "#define HAVE_SYSTEMD 1" >>confdefs.h
*) :
;;
esac
else
as_fn_error $? "systemd enabled but need pkg-config to configure for it" "$LINENO" 5
fi
fi
if test "x$have_systemd" = xyes; then
@@ -19185,7 +19311,7 @@ fi
if test -z "$PYTHON"; then
as_fn_error $? "Cannot find python$PYTHON_VERSION in your system path" "$LINENO" 5
as_fn_error $? "Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version." "$LINENO" 5
PYTHON_VERSION=""
fi
@@ -20656,6 +20782,12 @@ then :
printf "%s\n" "#define HAVE_BIO_SET_CALLBACK_EX 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_func_SSL_CTX_set_tmp_ecdh"
if test "x$ac_cv_func_SSL_CTX_set_tmp_ecdh" = xyes
then :
printf "%s\n" "#define HAVE_SSL_CTX_SET_TMP_ECDH 1" >>confdefs.h
fi
# these check_funcs need -lssl
@@ -21190,7 +21322,25 @@ case "$enable_ecdsa" in
;;
*)
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
ac_fn_c_check_func "$LINENO" "EVP_PKEY_fromdata" "ac_cv_func_EVP_PKEY_fromdata"
if test "x$ac_cv_func_EVP_PKEY_fromdata" = xyes
then :
# with EVP_PKEY_fromdata, check if EC is not disabled
ac_fn_check_decl "$LINENO" "OPENSSL_NO_EC" "ac_cv_have_decl_OPENSSL_NO_EC" "$ac_includes_default
#include <openssl/evp.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_OPENSSL_NO_EC" = xyes
then :
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
fi
else $as_nop
# without EVP_PKEY_fromdata, older openssl, check for support
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
if test "x$ac_cv_func_ECDSA_sign" = xyes
then :
@@ -21198,12 +21348,15 @@ else $as_nop
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
fi
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
if test "x$ac_cv_func_SHA384_Init" = xyes
then :
else $as_nop
as_fn_error $? "OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
fi
fi
ac_fn_check_decl "$LINENO" "NID_X9_62_prime256v1" "ac_cv_have_decl_NID_X9_62_prime256v1" "$ac_includes_default
@@ -22054,6 +22207,353 @@ printf "%s\n" "#define HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW $ac_have_decl" >>con
fi
# ngtcp2
# Check whether --with-libngtcp2 was given.
if test ${with_libngtcp2+y}
then :
withval=$with_libngtcp2;
else $as_nop
withval="no"
fi
found_libngtcp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2" >&5
printf %s "checking for libngtcp2... " >&6; }
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/ngtcp2/ngtcp2.h"; then
found_libngtcp2="yes"
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
printf "%s\n" "found in $dir" >&6; }
printf "%s\n" "#define HAVE_NGTCP2 1" >>confdefs.h
LIBS="$LIBS -lngtcp2"
break;
fi
done
if test x_$found_libngtcp2 != x_yes; then
as_fn_error $? "Could not find libngtcp2, ngtcp2.h" "$LINENO" 5
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2.h" "ac_cv_header_ngtcp2_ngtcp2_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_openssl.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_openssl_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_openssl_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_quictls.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_quictls_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_quictls_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H 1" >>confdefs.h
fi
ac_fn_check_decl "$LINENO" "ngtcp2_conn_server_new" "ac_cv_have_decl_ngtcp2_conn_server_new" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_ngtcp2_conn_server_new" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_NGTCP2_CONN_SERVER_NEW $ac_have_decl" >>confdefs.h
ac_fn_check_decl "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_have_decl_ngtcp2_crypto_encrypt_cb" "$ac_includes_default
#include <ngtcp2/ngtcp2_crypto.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_ngtcp2_crypto_encrypt_cb" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB $ac_have_decl" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl" >&5
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl... " >&6; }
if test ${ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_save_LIBS=$LIBS
LIBS="-lngtcp2_crypto_openssl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char ngtcp2_crypto_encrypt_cb ();
int
main (void)
{
return ngtcp2_crypto_encrypt_cb ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb=yes
else $as_nop
ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" >&5
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" >&6; }
if test "x$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" = xyes
then :
LIBS="$LIBS -lngtcp2_crypto_openssl"
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls" >&5
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls... " >&6; }
if test ${ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_save_LIBS=$LIBS
LIBS="-lngtcp2_crypto_quictls $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char ngtcp2_crypto_encrypt_cb ();
int
main (void)
{
return ngtcp2_crypto_encrypt_cb ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb=yes
else $as_nop
ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" >&5
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" >&6; }
if test "x$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" = xyes
then :
LIBS="$LIBS -lngtcp2_crypto_quictls"
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_func_ngtcp2_crypto_encrypt_cb"
if test "x$ac_cv_func_ngtcp2_crypto_encrypt_cb" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_ENCRYPT_CB 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_ccerr_default" "ac_cv_func_ngtcp2_ccerr_default"
if test "x$ac_cv_func_ngtcp2_ccerr_default" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CCERR_DEFAULT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_in_closing_period" "ac_cv_func_ngtcp2_conn_in_closing_period"
if test "x$ac_cv_func_ngtcp2_conn_in_closing_period" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_in_draining_period" "ac_cv_func_ngtcp2_conn_in_draining_period"
if test "x$ac_cv_func_ngtcp2_conn_in_draining_period" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_get_max_local_streams_uni" "ac_cv_func_ngtcp2_conn_get_max_local_streams_uni"
if test "x$ac_cv_func_ngtcp2_conn_get_max_local_streams_uni" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_from_ossl_encryption_level" "ac_cv_func_ngtcp2_crypto_quictls_from_ossl_encryption_level"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_from_ossl_encryption_level" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_configure_server_context" "ac_cv_func_ngtcp2_crypto_quictls_configure_server_context"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_configure_server_context" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_configure_client_context" "ac_cv_func_ngtcp2_crypto_quictls_configure_client_context"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_configure_client_context" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_get_num_scid" "ac_cv_func_ngtcp2_conn_get_num_scid"
if test "x$ac_cv_func_ngtcp2_conn_get_num_scid" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_GET_NUM_SCID 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_tls_early_data_rejected" "ac_cv_func_ngtcp2_conn_tls_early_data_rejected"
if test "x$ac_cv_func_ngtcp2_conn_tls_early_data_rejected" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_encode_0rtt_transport_params" "ac_cv_func_ngtcp2_conn_encode_0rtt_transport_params"
if test "x$ac_cv_func_ngtcp2_conn_encode_0rtt_transport_params" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS 1" >>confdefs.h
fi
for ac_func in SSL_is_quic
do :
ac_fn_c_check_func "$LINENO" "SSL_is_quic" "ac_cv_func_SSL_is_quic"
if test "x$ac_cv_func_SSL_is_quic" = xyes
then :
printf "%s\n" "#define HAVE_SSL_IS_QUIC 1" >>confdefs.h
else $as_nop
as_fn_error $? "No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2." "$LINENO" 5
fi
done
ac_fn_c_check_type "$LINENO" "struct ngtcp2_version_cid" "ac_cv_type_struct_ngtcp2_version_cid" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_type_struct_ngtcp2_version_cid" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_VERSION_CID 1" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "ngtcp2_encryption_level" "ac_cv_type_ngtcp2_encryption_level" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_type_ngtcp2_encryption_level" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_ENCRYPTION_LEVEL 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_pkt_hd" "tokenlen" "ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "tokenlen" "ac_cv_member_struct_ngtcp2_settings_tokenlen" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_settings_tokenlen" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "max_tx_udp_payload_size" "ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_transport_params" "original_dcid_present" "ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ngtcp2_conn_shutdown_stream has 4 arguments" >&5
printf %s "checking whether ngtcp2_conn_shutdown_stream has 4 arguments... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <ngtcp2/ngtcp2.h>
int
main (void)
{
(void)ngtcp2_conn_shutdown_stream(NULL, 0, 0, 0);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
# set static linking for uninstalled libraries if requested
staticexe=""
@@ -23637,10 +24137,12 @@ if test x_$enable_lock_checks = x_yes; then
UBSYMS="-export-symbols clubsyms.def"
cp ${srcdir}/libunbound/ubsyms.def clubsyms.def
echo lock_protect >> clubsyms.def
echo lock_protect_place >> clubsyms.def
echo lock_unprotect >> clubsyms.def
echo lock_get_mem >> clubsyms.def
echo checklock_start >> clubsyms.def
echo checklock_stop >> clubsyms.def
echo checklock_set_output_name >> clubsyms.def
echo checklock_lock >> clubsyms.def
echo checklock_unlock >> clubsyms.def
echo checklock_init >> clubsyms.def
@@ -23733,7 +24235,7 @@ then :
else $as_nop
if test -n "$PKG_CONFIG"; then
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PROTOBUFC" >&5
@@ -23794,36 +24296,36 @@ fi
echo "$PROTOBUFC_PKG_ERRORS" >&5
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
fi
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
fi
fi
elif test $pkg_failed = untried; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
fi
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
fi
fi
else
@@ -23832,11 +24334,21 @@ else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
LIBS="$LIBS $PROTOBUFC_LIBS"
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
LIBS="$LIBS $PROTOBUFC_LIBS"
fi
else
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
fi
fi
fi
@@ -24235,7 +24747,21 @@ printf "%s\n" "#define USE_IPSET 1" >>confdefs.h
IPSET_OBJ="ipset.lo"
# mnl
# BSD's pf
for ac_header in net/pfvar.h
do :
ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "
#include <netinet/in.h>
#include <net/if.h>
"
if test "x$ac_cv_header_net_pfvar_h" = xyes
then :
printf "%s\n" "#define HAVE_NET_PFVAR_H 1" >>confdefs.h
else $as_nop
# mnl
# Check whether --with-libmnl was given.
if test ${with_libmnl+y}
@@ -24245,13 +24771,13 @@ else $as_nop
withval="yes"
fi
found_libmnl="no"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
found_libmnl="no"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
printf %s "checking for libmnl... " >&6; }
if test x_$withval = x_ -o x_$withval = x_yes; then
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
fi
for dir in $withval ; do
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
found_libmnl="yes"
extralibmnl=""
@@ -24269,10 +24795,14 @@ printf "%s\n" "found in $dir" >&6; }
LIBS="$LIBS -lmnl"
break;
fi
done
if test x_$found_libmnl != x_yes; then
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
fi
done
if test x_$found_libmnl != x_yes; then
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
fi
fi
done
;;
no|*)
# nothing
@@ -24467,7 +24997,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.20.1
version=1.22.0
date=`date +'%b %e, %Y'`
@@ -24979,7 +25509,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.20.1, which was
This file was extended by unbound $as_me 1.22.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25047,7 +25577,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
unbound config.status 1.20.1
unbound config.status 1.22.0
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+150 -18
View File
@@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[20])
m4_define([VERSION_MICRO],[1])
m4_define([VERSION_MINOR],[22])
m4_define([VERSION_MICRO],[0])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=28
LIBUNBOUND_REVISION=30
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -113,7 +113,9 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.20.1 had 9:28:1
# 1.21.0 had 9:28:1
# 1.21.1 had 9:29:1
# 1.22.0 had 9:30:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -339,6 +341,8 @@ AC_MSG_RESULT($ac_cv_c_weak_attribute)
if test $ac_cv_c_weak_attribute = yes; then
AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
else
AC_DEFINE(ATTR_WEAK,[], [apply the weak attribute to a symbol])
fi
])dnl End of CHECK_WEAK_ATTRIBUTE
@@ -360,11 +364,54 @@ AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
if test $ac_cv_c_noreturn_attribute = yes; then
AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
else
AC_DEFINE(ATTR_NORETURN,[], [apply the noreturn attribute to a function that exits the program])
fi
])dnl End of CHECK_NORETURN_ATTRIBUTE
CHECK_NORETURN_ATTRIBUTE
AC_DEFUN([CHECK_FALLTHROUGH_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "fallthrough" attribute)
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_CACHE_VAL(ac_cv_c_fallthrough_attribute,
[ac_cv_c_fallthrough_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
void f(int x) {
int y = 0;
switch(x) {
case 1:
y = 1;
__attribute__((fallthrough));
/* fallthrough */
case 2:
y++;
break;
case 3:
y = 3;
break;
}
printf("%d", y);
}
]], [[
f(1);
]])],[ac_cv_c_fallthrough_attribute="yes"],[ac_cv_c_fallthrough_attribute="no"])
])
CFLAGS="$BAKCFLAGS"
AC_MSG_RESULT($ac_cv_c_fallthrough_attribute)
if test $ac_cv_c_fallthrough_attribute = yes; then
AC_DEFINE(HAVE_ATTR_FALLTHROUGH, 1, [Whether the C compiler accepts the "fallthrough" attribute])
AC_DEFINE(ATTR_FALLTHROUGH, [__attribute__((fallthrough));], [apply the fallthrough attribute.])
else
AC_DEFINE(ATTR_FALLTHROUGH,[], [apply the fallthrough attribute.])
fi
])dnl End of CHECK_FALLTHROUGH_ATTRIBUTE
CHECK_FALLTHROUGH_ATTRIBUTE
if test "$srcdir" != "."; then
CPPFLAGS="$CPPFLAGS -I$srcdir"
fi
@@ -944,7 +991,7 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
@@ -1181,8 +1228,17 @@ case "$enable_ecdsa" in
;;
*)
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
AC_CHECK_FUNC(EVP_PKEY_fromdata, [
# with EVP_PKEY_fromdata, check if EC is not disabled
AC_CHECK_DECL([OPENSSL_NO_EC], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])
], [], [AC_INCLUDES_DEFAULT
#include <openssl/evp.h>
])
], [
# without EVP_PKEY_fromdata, older openssl, check for support
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
])
AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
#include <openssl/evp.h>
])
@@ -1523,6 +1579,64 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
])
fi
# ngtcp2
AC_ARG_WITH(libngtcp2, AS_HELP_STRING([--with-libngtcp2=path],[specify explicit path for libngtcp2, for QUIC.]),
[ ],[ withval="no" ])
found_libngtcp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libngtcp2)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/ngtcp2/ngtcp2.h"; then
found_libngtcp2="yes"
dnl assume /usr is in default path.
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
AC_MSG_RESULT(found in $dir)
AC_DEFINE([HAVE_NGTCP2], [1], [Define this to use ngtcp2.])
LIBS="$LIBS -lngtcp2"
break;
fi
done
if test x_$found_libngtcp2 != x_yes; then
AC_MSG_ERROR([Could not find libngtcp2, ngtcp2.h])
fi
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([ngtcp2_conn_server_new], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_CHECK_DECLS([ngtcp2_crypto_encrypt_cb], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2_crypto.h>
])
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ])
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])])
AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_CHECK_MEMBERS([struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen, struct ngtcp2_settings.max_tx_udp_payload_size, struct ngtcp2_transport_params.original_dcid_present],,,[AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_MSG_CHECKING([whether ngtcp2_conn_shutdown_stream has 4 arguments])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
],[
(void)ngtcp2_conn_shutdown_stream(NULL, 0, 0, 0);
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4, 1, [Define if ngtcp2_conn_shutdown_stream has 4 arguments.])
],[
AC_MSG_RESULT(no)
])
fi
# set static linking for uninstalled libraries if requested
AC_SUBST(staticexe)
staticexe=""
@@ -1838,10 +1952,12 @@ if test x_$enable_lock_checks = x_yes; then
UBSYMS="-export-symbols clubsyms.def"
cp ${srcdir}/libunbound/ubsyms.def clubsyms.def
echo lock_protect >> clubsyms.def
echo lock_protect_place >> clubsyms.def
echo lock_unprotect >> clubsyms.def
echo lock_get_mem >> clubsyms.def
echo checklock_start >> clubsyms.def
echo checklock_stop >> clubsyms.def
echo checklock_set_output_name >> clubsyms.def
echo checklock_lock >> clubsyms.def
echo checklock_unlock >> clubsyms.def
echo checklock_init >> clubsyms.def
@@ -1922,15 +2038,17 @@ case "$enable_ipset" in
IPSET_OBJ="ipset.lo"
AC_SUBST(IPSET_OBJ)
# mnl
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
# BSD's pf
AC_CHECK_HEADERS([net/pfvar.h], [], [
# mnl
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
[ ],[ withval="yes" ])
found_libmnl="no"
AC_MSG_CHECKING(for libmnl)
if test x_$withval = x_ -o x_$withval = x_yes; then
found_libmnl="no"
AC_MSG_CHECKING(for libmnl)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
fi
for dir in $withval ; do
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
found_libmnl="yes"
dnl assume /usr is in default path.
@@ -1948,10 +2066,14 @@ case "$enable_ipset" in
LIBS="$LIBS -lmnl"
break;
fi
done
if test x_$found_libmnl != x_yes; then
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
fi
done
if test x_$found_libmnl != x_yes; then
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
fi
], [
#include <netinet/in.h>
#include <net/if.h>
])
;;
no|*)
# nothing
@@ -2269,6 +2391,10 @@ struct sockaddr_storage;
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
#ifdef HAVE_REALLOCARRAY
# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__)
#endif
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
@@ -2281,6 +2407,10 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size,
const char* file, int line, const char* func);
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
const char* func);
#elif defined(UNBOUND_ALLOC_LITE)
# include "util/alloc.h"
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
@@ -2291,6 +2421,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for DNS over QUIC traffic. */
#define UNBOUND_DNS_OVER_QUIC_PORT 853
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953
+1 -1
View File
@@ -236,7 +236,7 @@ index 54006940..768fe202 100644
+ /* see if the failure did get (parent-lame) info */
+ if(!cache_fill_missing(super->env,
+ super_iq->qchase.qclass, super->region,
+ super_iq->dp))
+ super_iq->dp, 0))
+ log_err("ASN-AAAA-filter: out of memory adding missing");
+ dpns->resolved = 1; /* mark as failed */
+ }
+2 -2
View File
@@ -42,8 +42,8 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network.target
Before=network-online.target nss-lookup.target
After=network-online.target
Before=nss-lookup.target
[Install]
WantedBy=multi-user.target
+2 -2
View File
@@ -14,8 +14,8 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network.target
Before=network-online.target nss-lookup.target
After=network-online.target
Before=nss-lookup.target
Wants=nss-lookup.target
[Install]
+49 -8
View File
@@ -344,7 +344,7 @@ static int setup_acl_for_ports(struct acl_list* list,
return 1;
}
int
int
daemon_open_shared_ports(struct daemon* daemon)
{
log_assert(daemon);
@@ -444,6 +444,19 @@ daemon_open_shared_ports(struct daemon* daemon)
return 1;
}
int
daemon_privileged(struct daemon* daemon)
{
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
fatal_exit("failed to startup modules");
}
return 1;
}
/**
* Setup modules. setup module stack.
* @param daemon: the daemon
@@ -453,11 +466,15 @@ static void daemon_setup_modules(struct daemon* daemon)
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
daemon->env->need_to_validate = 0; /* set by module init below */
if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
fatal_exit("failed to setup modules");
if(daemon->mods_inited) {
modstack_call_deinit(&daemon->mods, daemon->env);
}
daemon->env->need_to_validate = 0; /* set by module init below */
if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
fatal_exit("failed to init modules");
}
daemon->mods_inited = 1;
log_edns_known_options(VERB_ALGO, daemon->env);
}
@@ -503,7 +520,10 @@ daemon_clear_allocs(struct daemon* daemon)
{
int i;
for(i=0; i<daemon->num; i++) {
/* daemon->num may be different during reloads (after configuration
* read). Use old_num which has the correct value used to setup the
* worker_allocs */
for(i=0; i<daemon->old_num; i++) {
alloc_clear(daemon->worker_allocs[i]);
free(daemon->worker_allocs[i]);
}
@@ -537,6 +557,12 @@ daemon_create_workers(struct daemon* daemon)
fatal_exit("out of memory during daemon init");
numport = daemon_get_shufport(daemon, shufport);
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");
#endif
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
if(daemon->reuseport && (int)daemon->num < (int)daemon->num_ports) {
@@ -715,6 +741,14 @@ daemon_fork(struct daemon* daemon)
"dnscrypt support");
#endif
}
if(daemon->cfg->cookie_secret_file &&
daemon->cfg->cookie_secret_file[0]) {
if(!(daemon->cookie_secrets = cookie_secrets_create()))
fatal_exit("Could not create cookie_secrets: out of memory");
if(!cookie_secrets_apply_cfg(daemon->cookie_secrets,
daemon->cfg->cookie_secret_file))
fatal_exit("Could not setup cookie_secrets");
}
/* create global local_zones */
if(!(daemon->local_zones = local_zones_create()))
fatal_exit("Could not create local zones: out of memory");
@@ -858,7 +892,7 @@ daemon_cleanup(struct daemon* daemon)
daemon->views = NULL;
if(daemon->env->auth_zones)
auth_zones_cleanup(daemon->env->auth_zones);
/* key cache is cleared by module desetup during next daemon_fork() */
/* key cache is cleared by module deinit during next daemon_fork() */
daemon_remote_clear(daemon->rc);
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
@@ -878,6 +912,10 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv);
daemon->dnscenv = NULL;
#endif
#ifdef HAVE_NGTCP2
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
#endif
daemon->cfg = NULL;
}
@@ -888,7 +926,9 @@ daemon_delete(struct daemon* daemon)
size_t i;
if(!daemon)
return;
modstack_desetup(&daemon->mods, daemon->env);
modstack_call_deinit(&daemon->mods, daemon->env);
modstack_call_destartup(&daemon->mods, daemon->env);
modstack_free(&daemon->mods);
daemon_remote_delete(daemon->rc);
for(i = 0; i < daemon->num_ports; i++)
listening_ports_free(daemon->ports[i]);
@@ -907,6 +947,7 @@ daemon_delete(struct daemon* daemon)
acl_list_delete(daemon->acl);
acl_list_delete(daemon->acl_interface);
tcl_list_delete(daemon->tcl);
cookie_secrets_delete(daemon->cookie_secrets);
listen_desetup_locks();
free(daemon->chroot);
free(daemon->pidfile);
+17
View File
@@ -58,6 +58,8 @@ struct ub_randstate;
struct daemon_remote;
struct respip_set;
struct shm_main_info;
struct doq_table;
struct cookie_secrets;
#include "dnstap/dnstap_config.h"
#ifdef USE_DNSTAP
@@ -115,6 +117,8 @@ struct daemon {
struct module_env* env;
/** stack of module callbacks */
struct module_stack mods;
/** The module stack has been inited */
int mods_inited;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** access control, which interfaces are allowed to connect */
@@ -144,8 +148,12 @@ struct daemon {
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
/** the doq connection table */
struct doq_table* doq_table;
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
/** the EDNS cookie secrets from the cookie-secret-file */
struct cookie_secrets* cookie_secrets;
};
/**
@@ -162,6 +170,15 @@ struct daemon* daemon_init(void);
*/
int daemon_open_shared_ports(struct daemon* daemon);
/**
* Do daemon setup that needs privileges
* like opening privileged ports or opening device files.
* The cfg member pointer must have been set for the daemon.
* @param daemon: the daemon.
* @return: false on error.
*/
int daemon_privileged(struct daemon* daemon);
/**
* Fork workers and start service.
* When the routine exits, it is no longer forked.
+229 -1
View File
@@ -88,6 +88,7 @@
#include "sldns/wire2str.h"
#include "sldns/sbuffer.h"
#include "util/timeval_func.h"
#include "util/edns.h"
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
@@ -301,7 +302,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* open fd */
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
cfg->ip_transparent, 0, 0, cfg->ip_freebind,
cfg->use_systemd, cfg->ip_dscp);
cfg->use_systemd, cfg->ip_dscp, "unbound-control");
freeaddrinfo(res);
}
@@ -865,6 +866,10 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
if(!print_longnum(ssl, "mem.http.response_buffer"SQ,
(size_t)s->svr.mem_http2_response_buffer))
return 0;
#ifdef HAVE_NGTCP2
if(!print_longnum(ssl, "mem.quic"SQ, (size_t)s->svr.mem_quic))
return 0;
#endif /* HAVE_NGTCP2 */
return 1;
}
@@ -995,6 +1000,10 @@ print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero)
(unsigned long)s->svr.qipv6)) return 0;
if(!ssl_printf(ssl, "num.query.https"SQ"%lu\n",
(unsigned long)s->svr.qhttps)) return 0;
#ifdef HAVE_NGTCP2
if(!ssl_printf(ssl, "num.query.quic"SQ"%lu\n",
(unsigned long)s->svr.qquic)) return 0;
#endif /* HAVE_NGTCP2 */
/* flags */
if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n",
(unsigned long)s->svr.qbit_QR)) return 0;
@@ -1682,6 +1691,8 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
#ifdef USE_CACHEDB
if(remcachedb && worker->env.cachedb_enabled)
cachedb_msg_remove_qinfo(&worker->env, &k);
#else
(void)remcachedb;
#endif
}
@@ -1950,6 +1961,8 @@ bogus_del_msg(struct lruhash_entry* e, void* arg)
struct reply_info* d = (struct reply_info*)e->data;
if(d->security == sec_status_bogus) {
d->ttl = inf->expired;
d->prefetch_ttl = inf->expired;
d->serve_expired_ttl = inf->expired;
inf->num_msgs++;
#ifdef USE_CACHEDB
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
@@ -2032,6 +2045,8 @@ negative_del_msg(struct lruhash_entry* e, void* arg)
* or NOERROR rcode with ANCOUNT==0: a NODATA answer */
if(FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) {
d->ttl = inf->expired;
d->prefetch_ttl = inf->expired;
d->serve_expired_ttl = inf->expired;
inf->num_msgs++;
#ifdef USE_CACHEDB
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
@@ -3193,6 +3208,210 @@ do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
do_rpz_enable_disable(ssl, worker, arg, 0);
}
/** Write the cookie secrets to file, returns `0` on failure.
* Caller has to hold the lock. */
static int
cookie_secret_file_dump(RES* ssl, struct worker* worker) {
char const* secret_file = worker->env.cfg->cookie_secret_file;
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
FILE* f;
size_t i;
if(secret_file == NULL || secret_file[0]==0) {
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
return 0;
}
log_assert( secret_file != NULL );
/* open write only and truncate */
if((f = fopen(secret_file, "w")) == NULL ) {
(void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
secret_file, strerror(errno));
return 0;
}
if(cookie_secrets == NULL) {
/* nothing to write */
fclose(f);
return 1;
}
for(i = 0; i < cookie_secrets->cookie_count; i++) {
struct cookie_secret const* cs = &cookie_secrets->
cookie_secrets[i];
ssize_t const len = hex_ntop(cs->cookie_secret,
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
sizeof(secret_hex));
(void)len; /* silence unused variable warning with -DNDEBUG */
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
fprintf(f, "%s\n", secret_hex);
}
explicit_bzero(secret_hex, sizeof(secret_hex));
fclose(f);
return 1;
}
/** Activate cookie secret */
static void
do_activate_cookie_secret(RES* ssl, struct worker* worker) {
char const* secret_file = worker->env.cfg->cookie_secret_file;
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
if(secret_file == NULL || secret_file[0] == 0) {
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
return;
}
if(cookie_secrets == NULL) {
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
return;
}
lock_basic_lock(&cookie_secrets->lock);
if(cookie_secrets->cookie_count <= 1 ) {
lock_basic_unlock(&cookie_secrets->lock);
(void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
return;
}
/* Only the worker 0 writes to file, the others update state. */
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
lock_basic_unlock(&cookie_secrets->lock);
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
secret_file);
return;
}
activate_cookie_secret(cookie_secrets);
if(worker->thread_num == 0)
(void)cookie_secret_file_dump(ssl, worker);
lock_basic_unlock(&cookie_secrets->lock);
send_ok(ssl);
}
/** Drop cookie secret */
static void
do_drop_cookie_secret(RES* ssl, struct worker* worker) {
char const* secret_file = worker->env.cfg->cookie_secret_file;
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
if(secret_file == NULL || secret_file[0] == 0) {
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
return;
}
if(cookie_secrets == NULL) {
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
return;
}
lock_basic_lock(&cookie_secrets->lock);
if(cookie_secrets->cookie_count <= 1 ) {
lock_basic_unlock(&cookie_secrets->lock);
(void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
return;
}
/* Only the worker 0 writes to file, the others update state. */
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
lock_basic_unlock(&cookie_secrets->lock);
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
secret_file);
return;
}
drop_cookie_secret(cookie_secrets);
if(worker->thread_num == 0)
(void)cookie_secret_file_dump(ssl, worker);
lock_basic_unlock(&cookie_secrets->lock);
send_ok(ssl);
}
/** Add cookie secret */
static void
do_add_cookie_secret(RES* ssl, struct worker* worker, char* arg) {
uint8_t secret[UNBOUND_COOKIE_SECRET_SIZE];
char const* secret_file = worker->env.cfg->cookie_secret_file;
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
if(secret_file == NULL || secret_file[0] == 0) {
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
return;
}
if(cookie_secrets == NULL) {
worker->daemon->cookie_secrets = cookie_secrets_create();
if(!worker->daemon->cookie_secrets) {
(void)ssl_printf(ssl, "error: out of memory");
return;
}
cookie_secrets = worker->daemon->cookie_secrets;
}
lock_basic_lock(&cookie_secrets->lock);
if(*arg == '\0') {
lock_basic_unlock(&cookie_secrets->lock);
(void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
return;
}
if(strlen(arg) != 32) {
lock_basic_unlock(&cookie_secrets->lock);
explicit_bzero(arg, strlen(arg));
(void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
return;
}
if(hex_pton(arg, secret, UNBOUND_COOKIE_SECRET_SIZE) !=
UNBOUND_COOKIE_SECRET_SIZE ) {
lock_basic_unlock(&cookie_secrets->lock);
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
explicit_bzero(arg, strlen(arg));
(void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
return;
}
/* Only the worker 0 writes to file, the others update state. */
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
lock_basic_unlock(&cookie_secrets->lock);
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
explicit_bzero(arg, strlen(arg));
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
secret_file);
return;
}
add_cookie_secret(cookie_secrets, secret, UNBOUND_COOKIE_SECRET_SIZE);
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
if(worker->thread_num == 0)
(void)cookie_secret_file_dump(ssl, worker);
lock_basic_unlock(&cookie_secrets->lock);
explicit_bzero(arg, strlen(arg));
send_ok(ssl);
}
/** Print cookie secrets */
static void
do_print_cookie_secrets(RES* ssl, struct worker* worker) {
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
int i;
if(!cookie_secrets)
return; /* Output is empty. */
lock_basic_lock(&cookie_secrets->lock);
for(i = 0; (size_t)i < cookie_secrets->cookie_count; i++) {
struct cookie_secret const* cs = &cookie_secrets->
cookie_secrets[i];
ssize_t const len = hex_ntop(cs->cookie_secret,
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
sizeof(secret_hex));
(void)len; /* silence unused variable warning with -DNDEBUG */
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
if (i == 0)
(void)ssl_printf(ssl, "active : %s\n", secret_hex);
else if (cookie_secrets->cookie_count == 2)
(void)ssl_printf(ssl, "staging: %s\n", secret_hex);
else
(void)ssl_printf(ssl, "staging[%d]: %s\n", i,
secret_hex);
}
lock_basic_unlock(&cookie_secrets->lock);
explicit_bzero(secret_hex, sizeof(secret_hex));
}
/** check for name with end-of-string, space or tab after it */
static int
cmdcmp(char* p, const char* cmd, size_t len)
@@ -3325,6 +3544,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
} else if(cmdcmp(p, "view_local_datas", 16)) {
do_view_datas_add(rc, ssl, worker, skipwhite(p+16));
return;
} else if(cmdcmp(p, "print_cookie_secrets", 20)) {
do_print_cookie_secrets(ssl, worker);
return;
}
#ifdef THREADS_DISABLED
@@ -3389,6 +3611,12 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
do_rpz_enable(ssl, worker, skipwhite(p+10));
} else if(cmdcmp(p, "rpz_disable", 11)) {
do_rpz_disable(ssl, worker, skipwhite(p+11));
} else if(cmdcmp(p, "add_cookie_secret", 17)) {
do_add_cookie_secret(ssl, worker, skipwhite(p+17));
} else if(cmdcmp(p, "drop_cookie_secret", 18)) {
do_drop_cookie_secret(ssl, worker);
} else if(cmdcmp(p, "activate_cookie_secret", 22)) {
do_activate_cookie_secret(ssl, worker);
} else {
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
}
+21 -2
View File
@@ -346,6 +346,12 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
(long long)http2_get_query_buffer_size();
s->svr.mem_http2_response_buffer =
(long long)http2_get_response_buffer_size();
#ifdef HAVE_NGTCP2
s->svr.mem_quic = (long long)doq_table_quic_size_get(
worker->daemon->doq_table);
#else
s->svr.mem_quic = 0;
#endif /* HAVE_NGTCP2 */
/* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset);
@@ -391,6 +397,13 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
else worker_send_cmd(who, worker_cmd_stats_noreset);
verbose(VERB_ALGO, "wait for stats reply");
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
unsigned long pthid = 0;
if(verbosity >= VERB_OPS)
memcpy(&pthid, &who->thr_id, sizeof(unsigned long));
# endif
#endif
verbose(VERB_OPS, "no response from thread %d"
#ifdef HAVE_GETTID
" LWP %u"
@@ -407,7 +420,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
#endif
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
, (unsigned long)*((unsigned long*)&who->thr_id)
, pthid
# endif
#endif
);
@@ -467,6 +480,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qhttps += a->svr.qhttps;
total->svr.qquic += a->svr.qquic;
total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA;
@@ -526,7 +540,8 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
else stats->qclass_big++;
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
if(c->type != comm_udp) {
stats->qtcp++;
if(c->type != comm_doq)
stats->qtcp++;
if(c->ssl != NULL) {
stats->qtls++;
#ifdef HAVE_SSL
@@ -535,6 +550,10 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
#endif
if(c->type == comm_http)
stats->qhttps++;
#ifdef HAVE_NGTCP2
else if(c->type == comm_doq)
stats->qquic++;
#endif
}
}
if(repinfo && addr_is_ip6(&repinfo->remote_addr, repinfo->remote_addrlen))
+4
View File
@@ -473,7 +473,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#endif
#ifdef HAVE_GETPWNAM
struct passwd *pwd = NULL;
#endif
if(!daemon_privileged(daemon))
fatal_exit("could not do privileged setup");
#ifdef HAVE_GETPWNAM
if(cfg->username && cfg->username[0]) {
if((pwd = getpwnam(cfg->username)) == NULL)
fatal_exit("user '%s' does not exist.", cfg->username);
+33 -16
View File
@@ -160,9 +160,11 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
+ sizeof(worker->rndstate)
+ regional_get_mem(worker->scratchpad)
+ sizeof(*worker->env.scratch_buffer)
+ sldns_buffer_capacity(worker->env.scratch_buffer)
+ forwards_get_mem(worker->env.fwds)
+ hints_get_mem(worker->env.hints);
+ sldns_buffer_capacity(worker->env.scratch_buffer);
if(worker->daemon->env->fwds)
log_info("forwards=%u", (unsigned)forwards_get_mem(worker->env.fwds));
if(worker->daemon->env->hints)
log_info("hints=%u", (unsigned)hints_get_mem(worker->env.hints));
if(worker->thread_num == 0)
me += acl_list_get_mem(worker->daemon->acl);
if(cur_serv) {
@@ -659,22 +661,18 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(rep->ttl < timenow) {
/* Check if we need to serve expired now */
if(worker->env.cfg->serve_expired &&
!worker->env.cfg->serve_expired_client_timeout
/* if serve-expired-client-timeout is set, serve
* an expired record without attempting recursion
* if the serve_expired_norec_ttl is set for the record
* as we know that recursion is currently failing. */
(!worker->env.cfg->serve_expired_client_timeout ||
timenow < rep->serve_expired_norec_ttl)
#ifdef USE_CACHEDB
&& !(worker->env.cachedb_enabled &&
worker->env.cfg->cachedb_check_when_serve_expired)
#endif
) {
if(worker->env.cfg->serve_expired_ttl &&
rep->serve_expired_ttl < timenow)
return 0;
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_YXDOMAIN)
if(!reply_info_can_answer_expired(rep, timenow))
return 0;
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
return 0;
@@ -1571,7 +1569,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if((ret=parse_edns_from_query_pkt(
c->buffer, &edns, worker->env.cfg, c, repinfo,
(worker->env.now ? *worker->env.now : time(NULL)),
worker->scratchpad)) != 0) {
worker->scratchpad,
worker->daemon->cookie_secrets)) != 0) {
struct edns_data reply_edns;
verbose(VERB_ALGO, "worker parse edns: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
@@ -2175,7 +2174,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
cfg->harden_large_queries, cfg->http_max_streams,
cfg->http_endpoint, cfg->http_notls_downstream,
worker->daemon->tcl, worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker);
dtenv, worker->daemon->doq_table, worker->env.rnd,
cfg->ssl_service_key, cfg->ssl_service_pem, cfg,
worker_handle_request, worker);
if(!worker->front) {
log_err("could not create listening sockets");
worker_delete(worker);
@@ -2509,3 +2510,19 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
+6 -4
View File
@@ -657,7 +657,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
qstate->return_msg->rep &&
!dns_cache_store(
qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, 0, 0, NULL,
0, qstate->prefetch_leeway, 0, NULL,
qstate->query_flags, qstate->qstarttime))
log_err("out of memory");
@@ -701,6 +701,7 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
iq->state = DNS64_NEW_QUERY;
iq->started_no_cache_store = qstate->no_cache_store;
qstate->no_cache_store = 1;
ATTR_FALLTHROUGH
/* fallthrough */
case module_event_pass:
qstate->ext_state[id] = handle_event_pass(qstate, id);
@@ -846,6 +847,7 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
*/
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
rep->serve_expired_norec_ttl,
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
rep->rrset_count, rep->security, LDNS_EDE_NONE);
if(!cp)
@@ -1006,7 +1008,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
/* Store the generated response in cache. */
if ( (!super_dq || !super_dq->started_no_cache_store) &&
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
0, 0, 0, NULL, super->query_flags, qstate->qstarttime))
0, super->prefetch_leeway, 0, NULL, super->query_flags, qstate->qstarttime))
log_err("out of memory");
}
@@ -1044,8 +1046,8 @@ dns64_get_mem(struct module_env* env, int id)
*/
static struct module_func_block dns64_block = {
"dns64",
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
&dns64_clear, &dns64_get_mem
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
&dns64_inform_super, &dns64_clear, &dns64_get_mem
};
/**
+45
View File
@@ -86,6 +86,31 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
return 1;
}
/** See if the message is sent due to dnstap sample rate */
static int
dt_sample_rate_limited(struct dt_env* env)
{
lock_basic_lock(&env->sample_lock);
/* Sampling is every [n] packets. Where n==1, every packet is sent */
if(env->sample_rate > 1) {
int submit = 0;
/* if sampling is engaged... */
if (env->sample_rate_count > env->sample_rate) {
/* once the count passes the limit */
/* submit the message */
submit = 1;
/* and reset the count */
env->sample_rate_count = 0;
}
/* increment count regardless */
env->sample_rate_count++;
lock_basic_unlock(&env->sample_lock);
return !submit;
}
lock_basic_unlock(&env->sample_lock);
return 0;
}
static void
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
{
@@ -146,6 +171,7 @@ dt_create(struct config_file* cfg)
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
if (!env)
return NULL;
lock_basic_init(&env->sample_lock);
env->dtio = dt_io_thread_create();
if(!env->dtio) {
@@ -241,6 +267,12 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
{
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
}
lock_basic_lock(&env->sample_lock);
if((env->sample_rate = (unsigned int)cfg->dnstap_sample_rate))
{
verbose(VERB_OPS, "dnstap SAMPLE_RATE enabled and set to \"%d\"", (int)env->sample_rate);
}
lock_basic_unlock(&env->sample_lock);
}
int
@@ -273,6 +305,7 @@ dt_delete(struct dt_env *env)
if (!env)
return;
dt_io_thread_delete(env->dtio);
lock_basic_destroy(&env->sample_lock);
free(env->identity);
free(env->version);
free(env);
@@ -409,6 +442,9 @@ dt_msg_send_client_query(struct dt_env *env,
struct dt_msg dm;
struct timeval qtime;
if(dt_sample_rate_limited(env))
return;
if(tstamp)
memcpy(&qtime, tstamp, sizeof(qtime));
else gettimeofday(&qtime, NULL);
@@ -447,6 +483,9 @@ dt_msg_send_client_response(struct dt_env *env,
struct dt_msg dm;
struct timeval rtime;
if(dt_sample_rate_limited(env))
return;
gettimeofday(&rtime, NULL);
/* type */
@@ -484,6 +523,9 @@ dt_msg_send_outside_query(struct dt_env *env,
struct timeval qtime;
uint16_t qflags;
if(dt_sample_rate_limited(env))
return;
gettimeofday(&qtime, NULL);
qflags = sldns_buffer_read_u16_at(qmsg, 2);
@@ -537,6 +579,9 @@ dt_msg_send_outside_response(struct dt_env *env,
struct dt_msg dm;
uint16_t qflags;
if(dt_sample_rate_limited(env))
return;
(void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
memcpy(&qflags, qbuf, sizeof(qflags));
qflags = ntohs(qflags);
+8
View File
@@ -39,6 +39,7 @@
#ifdef USE_DNSTAP
#include "util/locks.h"
struct config_file;
struct sldns_buffer;
struct dt_msg_queue;
@@ -75,6 +76,13 @@ struct dt_env {
unsigned log_forwarder_query_messages : 1;
/** whether to log Message/FORWARDER_RESPONSE */
unsigned log_forwarder_response_messages : 1;
/** lock on sample count */
lock_basic_type sample_lock;
/** rate limit value from config, samples 1/N messages */
unsigned int sample_rate;
/** rate limit counter */
unsigned int sample_rate_count;
};
/**
+28 -31
View File
@@ -34,41 +34,38 @@ AC_DEFUN([dt_DNSTAP],
LDFLAGS="$LDFLAGS -L$withval/lib"
],
[
ifdef([PKG_CHECK_MODULES],
[
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
[
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
LIBS="$LIBS $PROTOBUFC_LIBS"
],
[
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
if test -n "$PKG_CONFIG"; then
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
[
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
LIBS="$LIBS $PROTOBUFC_LIBS"
],
[
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
fi
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
fi
]
)
],
[
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
]
)
else
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
]
)
fi
fi
]
)
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
+45 -8
View File
@@ -176,10 +176,7 @@ void
mq_wakeup_cb(void* arg)
{
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
/* even if the dtio is already active, because perhaps much
* traffic suddenly, we leave the timer running to save on
* managing it, the once a second timer is less work then
* starting and stopping the timer frequently */
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
mq->dtio->wakeup_timer_enabled = 0;
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
@@ -210,6 +207,8 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
if(mq->dtio->wakeup_timer_enabled) {
if(wakeupnow) {
tv.tv_sec = 0;
tv.tv_usec = 0;
comm_timer_set(mq->wakeup_timer, &tv);
}
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
@@ -221,8 +220,14 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
if(!wakeupnow) {
tv.tv_sec = 1;
tv.tv_usec = 0;
/* If it is already set, keep it running. */
if(!comm_timer_is_set(mq->wakeup_timer))
comm_timer_set(mq->wakeup_timer, &tv);
} else {
tv.tv_sec = 0;
tv.tv_usec = 0;
comm_timer_set(mq->wakeup_timer, &tv);
}
comm_timer_set(mq->wakeup_timer, &tv);
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
}
@@ -260,8 +265,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* acquire lock */
lock_basic_lock(&mq->lock);
/* if list was empty, start timer for (eventual) wakeup */
if(mq->first == NULL)
/* if list was empty, start timer for (eventual) wakeup,
* or if dtio is not writing now an eventual wakeup is needed. */
if(mq->first == NULL || !mq->dtio->event_added_is_write)
wakeupstarttimer = 1;
/* if list contains more than wakeupnum elements, wakeup now,
* or if list is (going to be) almost full */
@@ -1259,6 +1265,13 @@ static void dtio_sleep(struct dt_io_thread* dtio)
/* unregister the event polling for write, because there is
* nothing to be written */
(void)dtio_add_output_event_read(dtio);
/* Set wakeuptimer enabled off; so that the next worker thread that
* wants to log starts a timer if needed, since the writer thread
* has gone to sleep. */
lock_basic_lock(&dtio->wakeup_timer_lock);
dtio->wakeup_timer_enabled = 0;
lock_basic_unlock(&dtio->wakeup_timer_lock);
}
#ifdef HAVE_SSL
@@ -1322,7 +1335,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) {
/* verification */
if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) {
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
X509* x = SSL_get1_peer_certificate(dtio->ssl);
#else
X509* x = SSL_get_peer_certificate(dtio->ssl);
#endif
if(!x) {
verbose(VERB_ALGO, "dnstap io, %s, SSL "
"connection failed no certificate",
@@ -1347,7 +1364,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
#endif
X509_free(x);
} else {
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
X509* x = SSL_get1_peer_certificate(dtio->ssl);
#else
X509* x = SSL_get_peer_certificate(dtio->ssl);
#endif
if(x) {
log_cert(VERB_ALGO, "dnstap io, peer "
"certificate", x);
@@ -1489,8 +1510,10 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
#endif
if((bits&UB_EV_READ || dtio->ssl_brief_write)) {
#ifdef HAVE_SSL
if(dtio->ssl_brief_write)
(void)dtio_disable_brief_write(dtio);
#endif
if(dtio->ready_frame_sent && !dtio->accept_frame_received) {
if(dtio_read_accept_frame(dtio) <= 0)
return;
@@ -1513,8 +1536,22 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
/* no messages on the first iteration,
* the queues are all empty */
dtio_sleep(dtio);
/* After putting to sleep, see if
* a message is in a message queue,
* if so, resume service. Stops a
* race condition where a thread could
* have one message but the dtio
* also just went to sleep. With the
* message queued between the
* dtio_find_msg and dtio_sleep
* calls. */
if(dtio_find_msg(dtio)) {
if(!dtio_add_output_event_write(dtio))
return;
}
}
return; /* nothing to do */
if(!dtio->cur_msg)
return; /* nothing to do */
}
}
+269 -40
View File
@@ -75,17 +75,18 @@
static void usage(char* argv[])
{
printf("usage: %s [options]\n", argv[0]);
printf(" Listen to dnstap messages\n");
printf(" Listen to dnstap messages\n");
printf("stdout has dnstap log, stderr has verbose server log\n");
printf("-u <socketpath> listen to unix socket with this file name\n");
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
printf("-x <server.key> server key file for TLS service\n");
printf("-y <server.pem> server cert file for TLS service\n");
printf("-z <verify.pem> cert file to verify client connections\n");
printf("-l long format for DNS printout\n");
printf("-v more verbose log output\n");
printf("-h this help text\n");
printf("-u <socketpath> listen to unix socket with this file name\n");
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
printf("-x <server.key> server key file for TLS service\n");
printf("-y <server.pem> server cert file for TLS service\n");
printf("-z <verify.pem> cert file to verify client connections\n");
printf("-l long format for DNS printout\n");
printf("-v more verbose log output\n");
printf("-c internal unit test and exit\n");
printf("-h this help text\n");
exit(1);
}
@@ -102,6 +103,14 @@ struct main_tap_data {
struct tap_socket_list* acceptlist;
};
/* list of data */
struct tap_data_list {
/** next in list */
struct tap_data_list* next;
/** the data */
struct tap_data* d;
};
/** tap callback variables */
struct tap_data {
/** the fd */
@@ -128,6 +137,10 @@ struct tap_data {
uint8_t* frame;
/** length of this frame */
size_t len;
/** back pointer to the tap_data_list entry;
* used to NULL the forward pointer to this data
* when this data is freed. */
struct tap_data_list* data_list;
};
/** list of sockets */
@@ -156,8 +169,89 @@ struct tap_socket {
char* ip;
/** for a TLS socket, the tls context */
SSL_CTX* sslctx;
/** dumb way to deal with memory leaks:
* tap_data was only freed on errors and not during exit leading to
* false positives when testing for memory leaks. */
struct tap_data_list* data_list;
};
/** try to delete tail entries from the list if all of them have no data */
static void tap_data_list_try_to_free_tail(struct tap_data_list* list)
{
struct tap_data_list* current = list;
log_assert(!list->d);
if(!list->next) /* we are the last, we can't remove ourselves */
return;
list = list->next;
while(list) {
if(list->d) /* a tail entry still has data; return */
return;
list = list->next;
}
/* keep the next */
list = current->next;
/* the tail will be removed; but not ourselves */
current->next = NULL;
while(list) {
current = list;
list = list->next;
free(current);
}
}
/** delete the tap structure */
static void tap_data_free(struct tap_data* data, int free_tail)
{
if(!data)
return;
if(data->ev) {
ub_event_del(data->ev);
ub_event_free(data->ev);
}
#ifdef HAVE_SSL
SSL_free(data->ssl);
#endif
sock_close(data->fd);
free(data->id);
free(data->frame);
if(data->data_list) {
data->data_list->d = NULL;
if(free_tail)
tap_data_list_try_to_free_tail(data->data_list);
}
free(data);
}
/** insert tap_data in the tap_data_list */
static int tap_data_list_insert(struct tap_data_list** liststart,
struct tap_data* d)
{
struct tap_data_list* entry = (struct tap_data_list*)
malloc(sizeof(*entry));
if(!entry)
return 0;
entry->next = *liststart;
entry->d = d;
d->data_list = entry;
*liststart = entry;
return 1;
}
/** delete the tap_data_list and free any remaining tap_data */
static void tap_data_list_delete(struct tap_data_list* list)
{
struct tap_data_list* e = list, *next;
while(e) {
next = e->next;
if(e->d) {
tap_data_free(e->d, 0);
e->d = NULL;
}
free(e);
e = next;
}
}
/** del the tap event */
static void tap_socket_delev(struct tap_socket* s)
{
@@ -173,7 +267,7 @@ static void tap_socket_close(struct tap_socket* s)
{
if(!s) return;
if(s->fd == -1) return;
close(s->fd);
sock_close(s->fd);
s->fd = -1;
}
@@ -184,6 +278,7 @@ static void tap_socket_delete(struct tap_socket* s)
#ifdef HAVE_SSL
SSL_CTX_free(s->sslctx);
#endif
tap_data_list_delete(s->data_list);
ub_event_free(s->ev);
free(s->socketpath);
free(s->ip);
@@ -728,27 +823,12 @@ static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len)
return receive_bytes(data, data->fd, buf, len);
}
/** delete the tap structure */
static void tap_data_free(struct tap_data* data)
{
ub_event_del(data->ev);
ub_event_free(data->ev);
#ifdef HAVE_SSL
SSL_free(data->ssl);
#endif
close(data->fd);
free(data->id);
free(data->frame);
free(data);
}
/** reply with ACCEPT control frame to bidirectional client,
* returns 0 on error */
static int reply_with_accept(struct tap_data* data)
{
#ifdef USE_DNSTAP
/* len includes the escape and framelength */
int r;
size_t len = 0;
void* acceptframe = fstrm_create_control_frame_accept(
DNSTAP_CONTENT_TYPE, &len);
@@ -759,6 +839,8 @@ static int reply_with_accept(struct tap_data* data)
fd_set_block(data->fd);
if(data->ssl) {
#ifdef HAVE_SSL
int r;
if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
@@ -769,6 +851,7 @@ static int reply_with_accept(struct tap_data* data)
free(acceptframe);
return 0;
}
#endif
} else {
if(send(data->fd, acceptframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
@@ -804,6 +887,7 @@ static int reply_with_finish(struct tap_data* data)
fd_set_block(data->fd);
if(data->ssl) {
#ifdef HAVE_SSL
int r;
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
int r2;
@@ -815,6 +899,7 @@ static int reply_with_finish(struct tap_data* data)
free(finishframe);
return 0;
}
#endif
} else {
if(send(data->fd, finishframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
@@ -842,7 +927,11 @@ static int tap_check_peer(struct tap_data* data)
if((SSL_get_verify_mode(data->ssl)&SSL_VERIFY_PEER)) {
/* verification */
if(SSL_get_verify_result(data->ssl) == X509_V_OK) {
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
X509* x = SSL_get1_peer_certificate(data->ssl);
#else
X509* x = SSL_get_peer_certificate(data->ssl);
#endif
if(!x) {
if(verbosity) log_info("SSL connection %s"
" failed no certificate", data->id);
@@ -864,7 +953,11 @@ static int tap_check_peer(struct tap_data* data)
#endif
X509_free(x);
} else {
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
X509* x = SSL_get1_peer_certificate(data->ssl);
#else
X509* x = SSL_get_peer_certificate(data->ssl);
#endif
if(x) {
if(verbosity)
log_cert(VERB_ALGO, "peer certificate", x);
@@ -906,7 +999,7 @@ static int tap_handshake(struct tap_data* data)
return 0;
} else if(r == 0) {
/* closed */
tap_data_free(data);
tap_data_free(data, 1);
return 0;
} else if(want == SSL_ERROR_SYSCALL) {
/* SYSCALL and errno==0 means closed uncleanly */
@@ -924,7 +1017,7 @@ static int tap_handshake(struct tap_data* data)
if(!silent)
log_err("SSL_handshake syscall: %s",
strerror(errno));
tap_data_free(data);
tap_data_free(data, 1);
return 0;
} else {
unsigned long err = ERR_get_error();
@@ -934,7 +1027,7 @@ static int tap_handshake(struct tap_data* data)
verbose(VERB_OPS, "ssl handshake failed "
"from %s", data->id);
}
tap_data_free(data);
tap_data_free(data, 1);
return 0;
}
}
@@ -942,7 +1035,7 @@ static int tap_handshake(struct tap_data* data)
data->ssl_handshake_done = 1;
if(!tap_check_peer(data)) {
/* closed */
tap_data_free(data);
tap_data_free(data, 1);
return 0;
}
return 1;
@@ -968,7 +1061,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
if(verbosity>=4) log_info("s recv %d", (int)ret);
if(ret == 0) {
/* closed or error */
tap_data_free(data);
tap_data_free(data, 1);
return;
} else if(ret == -1) {
/* continue later */
@@ -990,7 +1083,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
data->frame = calloc(1, data->len);
if(!data->frame) {
log_err("out of memory");
tap_data_free(data);
tap_data_free(data, 1);
return;
}
}
@@ -1003,7 +1096,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
if(verbosity>=4) log_info("f recv %d", (int)r);
if(r == 0) {
/* closed or error */
tap_data_free(data);
tap_data_free(data, 1);
return;
} else if(r == -1) {
/* continue later */
@@ -1028,13 +1121,13 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
data->is_bidirectional = 1;
if(verbosity) log_info("bidirectional stream");
if(!reply_with_accept(data)) {
tap_data_free(data);
tap_data_free(data, 1);
return;
}
} else if(data->len >= 4 && sldns_read_uint32(data->frame) ==
FSTRM_CONTROL_FRAME_STOP && data->is_bidirectional) {
if(!reply_with_finish(data)) {
tap_data_free(data);
tap_data_free(data, 1);
return;
}
}
@@ -1046,7 +1139,6 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
data->len = 0;
data->len_done = 0;
data->data_done = 0;
}
/** callback for main listening file descriptor */
@@ -1059,7 +1151,9 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
char* id = NULL;
struct sockaddr_storage addr;
socklen_t addrlen = (socklen_t)sizeof(addr);
int s = accept(fd, (struct sockaddr*)&addr, &addrlen);
int s;
memset(&addr, 0, sizeof(addr));
s = accept(fd, (struct sockaddr*)&addr, &addrlen);
if(s == -1) {
#ifndef USE_WINSOCK
/* EINTR is signal interrupt. others are closed connection. */
@@ -1129,6 +1223,8 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
&dtio_tap_callback, data);
if(!data->ev) fatal_exit("could not ub_event_new");
if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add");
if(!tap_data_list_insert(&tap_sock->data_list, data))
fatal_exit("could not tap_data_list_insert");
}
/** setup local accept sockets */
@@ -1243,6 +1339,114 @@ setup_and_run(struct config_strlist_head* local_list,
free(maindata);
}
/* internal unit tests */
static int internal_unittest()
{
/* unit test tap_data_list_try_to_free_tail() */
#define unit_tap_datas_max 5
struct tap_data* datas[unit_tap_datas_max];
struct tap_data_list* list;
struct tap_socket* socket = calloc(1, sizeof(*socket));
size_t i = 0;
log_assert(socket);
log_assert(unit_tap_datas_max>2); /* needed for the test */
for(i=0; i<unit_tap_datas_max; i++) {
datas[i] = calloc(1, sizeof(struct tap_data));
log_assert(datas[i]);
log_assert(tap_data_list_insert(&socket->data_list, datas[i]));
}
/* sanity base check */
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==unit_tap_datas_max);
/* Free the last data, tail cannot be erased */
list = socket->data_list;
while(list->next) list = list->next;
free(list->d);
list->d = NULL;
tap_data_list_try_to_free_tail(list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==unit_tap_datas_max);
/* Free the third to last data, tail cannot be erased */
list = socket->data_list;
for(i=0; i<unit_tap_datas_max-3; i++) list = list->next;
free(list->d);
list->d = NULL;
tap_data_list_try_to_free_tail(list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==unit_tap_datas_max);
/* Free the second to last data, try to remove tail from the third
* again, tail (last 2) should be removed */
list = socket->data_list;
for(i=0; i<unit_tap_datas_max-2; i++) list = list->next;
free(list->d);
list->d = NULL;
list = socket->data_list;
while(list->d) list = list->next;
tap_data_list_try_to_free_tail(list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==unit_tap_datas_max-2);
/* Free all the remaining data, try to remove tail from the start,
* only the start should remain */
list = socket->data_list;
while(list) {
free(list->d);
list->d = NULL;
list = list->next;
}
tap_data_list_try_to_free_tail(socket->data_list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==1);
/* clean up */
tap_data_list_delete(socket->data_list);
free(socket);
/* Start again. Add two elements */
socket = calloc(1, sizeof(*socket));
log_assert(socket);
for(i=0; i<2; i++) {
datas[i] = calloc(1, sizeof(struct tap_data));
log_assert(datas[i]);
log_assert(tap_data_list_insert(&socket->data_list, datas[i]));
}
/* sanity base check */
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==2);
/* Free the last data, tail cannot be erased */
list = socket->data_list;
while(list->next) list = list->next;
free(list->d);
list->d = NULL;
tap_data_list_try_to_free_tail(list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==2);
/* clean up */
tap_data_list_delete(socket->data_list);
free(socket);
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();
#endif
return 0;
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
@@ -1293,7 +1497,7 @@ int main(int argc, char** argv)
#endif
/* command line options */
while( (c=getopt(argc, argv, "hls:t:u:vx:y:z:")) != -1) {
while( (c=getopt(argc, argv, "hcls:t:u:vx:y:z:")) != -1) {
switch(c) {
case 'u':
if(!cfg_strlist_append(&local_list,
@@ -1329,14 +1533,20 @@ int main(int argc, char** argv)
case 'v':
verbosity++;
break;
case 'c':
#ifndef UNBOUND_DEBUG
fatal_exit("-c option needs compilation with "
"--enable-debug");
#endif
return internal_unittest();
case 'h':
case '?':
default:
usage(argv);
}
}
argc -= optind;
argv += optind;
/* argc -= optind; not using further arguments */
/* argv += optind; not using further arguments */
if(usessl) {
#ifdef HAVE_SSL
@@ -1365,6 +1575,9 @@ int main(int argc, char** argv)
config_delstrlist(tcp_list.first);
config_delstrlist(tls_list.first);
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();
@@ -1572,3 +1785,19 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
+334
View File
@@ -1,3 +1,337 @@
16 October 2024: Yorgos
- Fix for dnsoverquic and dnstap to use the correct dnstap
environment.
16 October 2024: Wouter
- Fix for dnstap with dnscrypt and dnstap without dnsoverquic.
14 October 2024: Wouter
- Fix to display warning if quic-port is set but dnsoverquic is not
enabled when compiled.
- Fix dnsoverquic to extend the number of streams when one is closed.
11 October 2024: Wouter
- Fix to disable detection of quic configured ports when quic is
not compiled in.
- Fix harden-unverified-glue for AAAA cache_fill_missing lookups.
- Fix contrib/aaaa-filter-iterator.patch for change in call
signature for cache_fill_missing.
10 October 2024: Wouter
- Fix cookie_file test sporadic fails for time change during
the test.
- Fix add reallocarray to alloc stats unit test, and disable
override of strdup in unbound-host, and the result of config
get option is freed properly.
9 October 2024: Wouter
- Merge #871: DNS over QUIC. This adds `quic-port: 853` and
`quic-size: 8m` that enable dnsoverquic, and the counters
`num.query.quic` and `mem.quic` in the statistics output.
The feature needs to be enabled by compiling with libngtcp2,
with `--with-libngtcp2=path` and libngtcp2 needs openssl+quic,
pass that with `--with-ssl=path` to compile unbound as well.
- Fix to limit NSEC TTL for messages from cachedb. Fix to limit the
prefetch ttl for messages after a CNAME with short TTL.
- Fix for dnstap compile of doqclient with doq disabled.
8 October 2024: Wouter
- Fix #1149: unbound-control-setup hangs sometimes depending on
the openssl version.
- Fix #1128: Cannot override tcp-upstream and tls-upstream with
forward-tcp-upstream and forward-tls-upstream.
3 October 2024: Yorgos
- Fix CVE-2024-8508, unbounded name compression could lead to denial
of service.
- This fix was part of 1.21.1, a security point release on 1.21.0.
The code repository continues with this fix and the version number
1.22.0.
30 September 2024: Wouter
- Fix negative cache NSEC3 parameter compares for zero length NSEC3
salt.
- Fix unbound dnstap socket test program analyzer warnings about
unused variable assignments and variable initialization.
25 September 2024: Wouter
- Fix #1144: [FR] log timestamps in ISO8601 format with timezone.
This adds the option `log-time-iso: yes` that logs in ISO8601
format.
24 September 2024: Yorgos
- Attempt to further fix doh_downstream_buffer_size.tdir flakiness.
- More clear text for prefetch and minimal-responses in the
unbound.conf man page.
- Merge #1143: Fix cache update when serve expired is used. Expired
records are favored over resolution and validation failures when
serve-expired is used.
23 September 2024: Wouter
- Fix dns64 with prefetch that the prefetch is stored in cache.
23 September 2024: Yorgos
- Fix doxygen warnings by commenting out CLANG_ASSISTED_PARSING,
CLANG_ADD_INC_PATHS, CLANG_OPTIONS and CLANG_DATABASE_PATH; they were
already disabled.
17 September 2024: Wouter
- Add redis-command-timeout: 20 and redis-connect-timeout: 200,
that can set the timeout separately for commands and the
connection set up to the redis server. If they are not
specified, the redis-timeout value is used.
16 September 2024: Wouter
- Merge #1140: Fix spelling mistake in comments.
11 September 2024: Yorgos
- Fix and add comments in testdata/val_negcache_ttl.rpl.
10 September 2024: Wouter
- Fix to limit NSEC and NSEC3 TTL when aggressive nsec is
enabled (RFC9077).
- Add unit test for ttl limit for aggressive nsec.
6 September 2024: Yorgos
- Fix alloc-size and calloc-transposed-args compiler warnings.
- Fix comment to not trigger doxygen unknown command.
5 September 2024: Wouter
- Fix config file read for dnstap-sample-rate.
2 September 2024: Wouter
- Merge #1135: Add new IANA trust anchor.
30 August 2024: Wouter
- Merge #1132: b.root renumbering.
- Fix for #1132, adjusted unit test for change in the test file.
- Fix for #1132, comment about adjusted copy of reference check.
29 August 2024: Wouter
- Unit test for auth zone transfer TLS, and TLS failure.
- Fix to print port number in logs for auth zone transfer activities.
28 August 2024: Wouter
- Fix that when rpz is applied the message does not get picked up by
the validator. That stops validation failures for the message.
- Fix that stub-zone and forward-zone clauses do not exhaust memory
for long content.
27 August 2024: Wouter
- Fix #1130: Loads of logs: "validation failure: key for validation
<domain>. is marked as invalid because of a previous" for
non-DNSSEC signed zone.
23 August 2024: Wouter
- Merge patch to fix for glue that is outside of zone, with
`harden-unverified-glue`, from Karthik Umashankar (Microsoft).
Enabling this option protects the Unbound resolver against bad
glue, that is unverified out of zone glue, by resolving them.
It uses the records as last resort if there is no other working
glue.
- Fix #1127: error: "memory exhausted" when defining more than 9994
local-zones.
- Fix documentation for cache_fill_missing function.
21 August 2024: Wouter
- Add cross platform freebsd, openbsd and netbsd to github ci.
- Fix for char signedness warnings on NetBSD.
20 August 2024: Wouter
- Add iter-scrub-ns, iter-scrub-cname and max-global-quota
configuration options.
19 August 2024: Wouter
- Fix #1126: unbound-control-setup hangs while testing for openssl
presence starting from version 1.21.0.
9 August 2024: Wouter
- Fix spelling for the cache-min-negative-ttl entry in the
example.conf.
- Tag for release 1.21.0, the repository continues with 1.21.1
in development.
8 August 2024: Wouter
- Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco
Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich.
- Fix CacheFlush issues with limit on NS RRs. Thanks to Yehuda Afek,
Anat Bremler-Barr, Shoham Danino and Yuval Shavitt (Tel-Aviv
University and Reichman University).
- Set version number to 1.21.0 for release. This has tag 1.21.0rc1.
- Fix that for windows the module startup is called and sets up
the module-config.
2 August 2024: Wouter
- Fix that alloc stats has strdup checks, it stops debuggers from
complaining about mismatch at free time.
- Fix testbound for alloc stats strdup in util/alloc.c.
- Merge #1090: Cookie secret file. Adds
`cookie-secret-file: "unbound_cookiesecrets.txt"` option to store
cookie secrets for EDNS COOKIE secret rollover. The remote control
add_cookie_secret, activate_cookie_secret and drop_cookie_secret
commands can be used for rollover, the command print_cookie_secrets
shows the values in use.
- Fix that alloc stats for forwards and hints are printed, and when
alloc stats is enabled, the unit test for unbound control waits for
reloads to complete.
1 August 2024: Wouter
- Fix dnstap test program, cleans up to have clean memory on exit,
for tap_data_free, does not delete NULL items. Also it does not try
to free the tail, specifically in the free of the list since that
picked up the next item in the list for its loop causing invalid
free. Added internal unit test to unbound-dnstap-socket for that.
- Fix that the worker mem report with alloc stats does not attempt
to print memory use of forwards and hints if they have been
deleted already.
31 July 2024: Wouter
- Fix for #1114: Fix that cache fill for forward-host names is
performed, so that with nonzero target-fetch-policy it fetches
forwarder addresses and uses them from cache. Also updated that
delegation point cache fill routines use CDflag for AAAA message
lookups, so that its negative lookup stops a recursion since the
cache uses the bit for disambiguation for dns64 but the recursion
uses CDflag for the AAAA target lookups, so the check correctly
stops a useless recursion by its cache lookup.
30 July 2024: Wouter
- Fix to document parameters of auth_zone_verify_zonemd_with_key.
25 July 2024: Wouter
- Add root key 38696 from 2024 for DNSSEC validation. It is added
to the default root keys in unbound-anchor. The content can be
inspected with `unbound-anchor -l`.
23 July 2024: Yorgos
- Fix #1106: ratelimit-below-domain logs the wrong FROM address.
- Cleanup ede.tdir test.
- For #935 and #1104, clarify RPZ order and semantics.
23 July 2024: Wouter
- Merge #1110: Make fallthrough explicit for libworker.c.
- For #1110: Test for fallthrough attribute in configure and add
fallthrough attribute annotations.
- Fix compile when the compiler does not support the noreturn
attribute.
- Fix to have empty definition when not supported for weak attribute.
- Fix uninitialized variable warning in create_tcp_accept_sock.
- Fix link of dnstap without openssl.
- Fix link of unbound-dnstap-socket without openssl.
19 July 2024: Wouter
- Add dnstap-sample-rate that logs only 1/N messages, for high volume
server environments. Thanks Dan Luther.
- Fix dnstap wakeup, a running wakeup timer is left to expire and not
increased, a timer is started when the dtio thread is sleeping,
the timer set disabled when the dtio thread goes to sleep, and
after sleep the thread checks to see if there are messages to log
immediately.
16 July 2024: Wouter
- For #1103: Fix to drop mesh state reference for the http2 stream
associated with the reply, not the currently active stream. And
it does not remove it twice on a mesh_send_reply call. The reply
h2_stream is NULL when not in use, for more initialisation.
15 July 2024: Wouter
- For #1103: fix to also drop mesh state reference when the discard
limit is reached, when there is an error making a new recursion
state and when the connection is dropped with is_drop.
12 July 2024: Yorgos
- Add RPZ tag tests in acl_interface.tdir.
- For #1102: clearer text for using interface-* options for the
loopback interface.
12 July 2024: Wouter
- Fix #1103: unbound 1.20.0 segmentation fault with nghttp2.
- For #1103: fix to also drop mesh state reference when a h2 reply is
dropped.
10 July 2024: Wouter
- For #773: In contrib/unbound.service.in set unbound to start after
network-online.target. Also for contrib/unbound_portable.service.in.
9 July 2024: Yorgos
- Update list of known EDE codes.
8 July 2024: Wouter
- Fix that validation reason failure that uses string print uses
separate buffer that is passed, from the scratch validation buffer.
- Fixup algo_needs_reason string buffer length.
- Fix shadowed error string variable in validator dnskey handling.
5 July 2024: Yorgos
- Don't check for message TTL changes if the RRsets remain the same.
5 July 2024: Wouter
- Fix for neater printout for error for missing DS response.
- Fix neater printout.
- Fix #1099: Unbound core dump on SIGSEGV.
- Fix for #1099: Fix to check for deleted RRset when the contents
is updated and fetched after it is stored, and also check for a
changed RRset.
4 July 2024: Wouter
- Fix to print details about the failure to lookup a DNSKEY record
when validation fails due to the missing DNSKEY. Also for key prime
and DS lookups.
3 July 2024: Yorgos
- Fix for repeated use of a DNAME record: first overallocate and then
move the exact size of the init value to avoid false positive heap
overflow reads from address sanitizers.
3 July 2024: Wouter
- Fix #144: Port ipset to BSD pf tables.
- Add unit test skip files and bison and flex output to gitignore.
- Fix to use modstack_init in zonemd unit test.
- Fix to remove unneeded linebreak in fptr_wlist.c.
- Fix compile warnings in fptr_wlist.c.
2 July 2024: Wouter
- Fix to remove unused include from the readzone test program.
- Fix unused variable warning in do_cache_remove.
- Fix compile warning in worker pthread id printout.
17 June 2024: Wouter
- Fix ip-ratelimit-cookie setting, it was not applied.
26 June 2024: Yorgos
- Explicitly set the RD bit for the mesh query flags when prefetching.
These queries have no waiting client but they need to be treated as
recursive.
21 June 2024: Yorgos
- Fix pkg-config availability check in dnstap/dnstap.m4 and
systemd.m4.
19 June 2024: Yorgos
- Fix #1092: Ubuntu 22.04 Jammy fails to compile unbound 1.20.0; by
adding helpful text for the Python interpreter version and allowing
the default pkg-config unavailability error message to be shown.
17 June 2024: Wouter
- Fix #1091: Build fails with OpenSSL >= 3.0 built with
OPENSSL_NO_DEPRECATED.
7 June 2024: Wouter
- Add unit test for validation of repeated use of a DNAME record.
6 June 2024: Wouter
- Fix memory leak in setup of dsa sig.
- Fix typos for 'the the' in text.
- Fix validation for repeated use of a DNAME record.
4 June 2024: Yorgos
- Merge #1080: AddressSanitizer detection in tdir tests and memory leak
fixes.
- Fix memory leak when reload_keep_cache is used and num-threads
changes.
- Fix memory leak on exit for unbound-dnstap-socket; creates false
negatives during testing.
3 June 2024: Wouter
- Fix to squelch connection reset by peer errors from log. And fix
that the tcp read errors are labeled as initial for the first calls.
+34 -2
View File
@@ -187,6 +187,15 @@ server:
# query upon encountering a CNAME record.
# max-query-restarts: 11
# Limit on number of NS records in NS RRset for incoming packets.
# iter-scrub-ns: 20
# Limit on number of CNAME, DNAME records for incoming packets.
# iter-scrub-cname: 11
# Limit on upstream queries for an incoming query and its recursion.
# max-global-quota: 128
# msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376
@@ -228,7 +237,7 @@ server:
# the time to live (TTL) value lower bound, in seconds. Default 0.
# For negative responses in the cache. If disabled, default,
# cache-min-tll applies if configured.
# cache-min-ttl applies if configured.
# cache-min-negative-ttl: 0
# the time to live (TTL) value for cached roundtrip times, lameness and
@@ -452,6 +461,10 @@ server:
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
# log-time-ascii: no
# log timestamp in ISO8601 format if also log-time-ascii is enabled.
# (y-m-dTh:m:s.msec[+-]tzhours:tzminutes)
# log-time-iso: no
# print one line with time, IP, name, type, class for every query.
# log-queries: no
@@ -524,6 +537,9 @@ server:
# Harden against out of zone rrsets, to avoid spoofing attempts.
# harden-glue: yes
# Harden against unverified (outside-zone, including sibling zone) glue rrsets
# harden-unverified-glue: no
# Harden against receiving dnssec-stripped data. If you turn it
# off, failing to validate dnskey data for a trustanchor will
# trigger insecure mode for that zone (like without a trustanchor).
@@ -904,6 +920,7 @@ server:
# tls-service-pem: "path/to/publiccertfile.pem"
# tls-port: 853
# https-port: 443
# quic-port: 853
# 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"
@@ -968,6 +985,9 @@ server:
# Disable TLS for DNS-over-HTTP downstream service.
# http-notls-downstream: no
# Maximum number of bytes used for QUIC buffers.
# quic-size: 8m
# The interfaces that use these listed port numbers will support and
# expect PROXYv2. For UDP and TCP/TLS interfaces.
# proxy-protocol-port: portno for each of the port numbers.
@@ -1044,6 +1064,11 @@ server:
# example value "000102030405060708090a0b0c0d0e0f".
# cookie-secret: <128 bit random hex string>
# File with cookie secrets, the 'cookie-secret:' option is ignored
# and the file can be managed to have staging and active secrets
# with remote control commands. Disabled with "". Default is "".
# cookie-secret-file: "/usr/local/etc/unbound_cookiesecrets.txt"
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
# ede: no
@@ -1284,6 +1309,10 @@ remote-control:
# # redis-server-password: ""
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# # timeout (in ms) for commands, if 0, uses redis-timeout.
# redis-command-timeout: 0
# # timeout (in ms) for connection set up, if 0, uses redis-timeout.
# redis-connect-timeout: 0
# # set timeout on redis records based on DNS response TTL
# redis-expire-records: no
# # redis logical database to use, 0 is the default database.
@@ -1329,6 +1358,8 @@ remote-control:
# dnstap-identity: ""
# # if "" it uses the package version.
# dnstap-version: ""
# # log only 1/N messages, if 0 it is disabled. default 0.
# dnstap-sample-rate: 0
# dnstap-log-resolver-query-messages: no
# dnstap-log-resolver-response-messages: no
# dnstap-log-client-query-messages: no
@@ -1337,7 +1368,8 @@ remote-control:
# dnstap-log-forwarder-response-messages: no
# Response Policy Zones
# RPZ policies. Applied in order of configuration. QNAME, Response IP
# RPZ policies. Applied in order of configuration. Any match from an earlier
# RPZ zone will terminate the RPZ lookup. QNAME, Response IP
# Address, nsdname, nsip and clientip triggers are supported. Supported
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
# and drop. Policies can be loaded from a file, or using zone
+43
View File
@@ -350,6 +350,41 @@ Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_re
.TP
.B view_local_datas \fIview\fR
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
.TP
.B add_cookie_secret <secret>
Add or replace a cookie secret persistently. <secret> needs to be an 128 bit
hex string.
.IP
Cookie secrets can be either \fIactive\fR or \fIstaging\fR. \fIActive\fR cookie
secrets are used to create DNS Cookies, but verification of a DNS Cookie
succeeds with any of the \fIactive\fR or \fIstaging\fR cookie secrets. The
state of the current cookie secrets can be printed with the
\fBprint_cookie_secrets\fR command.
.IP
When there are no cookie secrets configured yet, the <secret> is added as
\fIactive\fR. If there is already an \fIactive\fR cookie secret, the <secret>
is added as \fIstaging\fR or replacing an existing \fIstaging\fR secret.
.IP
To "roll" a cookie secret used in an anycast set. The new secret has to be
added as staging secret to \fBall\fR nodes in the anycast set. When \fBall\fR
nodes can verify DNS Cookies with the new secret, the new secret can be
activated with the \fBactivate_cookie_secret\fR command. After \fBall\fR nodes
have the new secret \fIactive\fR for at least one hour, the previous secret can
be dropped with the \fBdrop_cookie_secret\fR command.
.IP
Persistence is accomplished by writing to a file which if configured with the
\fBcookie\-secret\-file\fR option in the server section of the config file.
This is disabled by default, "".
.TP
.B drop_cookie_secret
Drop the \fIstaging\fR cookie secret.
.TP
.B activate_cookie_secret
Make the current \fIstaging\fR cookie secret \fIactive\fR, and the current
\fIactive\fR cookie secret \fIstaging\fR.
.TP
.B print_cookie_secrets
Show the current configured cookie secrets with their status.
.SH "EXIT CODE"
The unbound\-control program exits with status code 1 on error, 0 on success.
.SH "SET UP"
@@ -571,6 +606,10 @@ queries waiting for request stream completion.
Memory in bytes used by the HTTP/2 response buffers. Containing DNS responses
waiting to be written back to the clients.
.TP
.I mem.quic
Memory in bytes used by QUIC. Containing connection information, stream
information, queries read and responses written back to the clients.
.TP
.I histogram.<sec>.<usec>.to.<sec>.<usec>
Shows a histogram, summed over all threads. Every element counts the
recursive queries whose reply time fit between the lower and upper bound.
@@ -619,6 +658,10 @@ Number of queries that were made using HTTPS towards the Unbound server.
These are also counted in num.query.tcp and num.query.tls, because HTTPS
uses TLS and TCP.
.TP
.I num.query.quic
Number of queries that were made using QUIC towards the Unbound server.
These are also counted in num.query.tls, because TLS is used for these queries.
.TP
.I num.query.ipv6
Number of queries that were made using IPv6 towards the Unbound server.
.TP
+102 -22
View File
@@ -566,6 +566,9 @@ tls\-system\-cert to load CA certs, otherwise the connections cannot be
authenticated. This option enables TLS for all of them, but if you do not set
this you can configure TLS specifically for some forward zones with
forward\-tls\-upstream. And also with stub\-tls\-upstream.
If the tls\-upstream option is enabled, it is for all the forwards and stubs,
where the forward\-tls\-upstream and stub\-tls\-upstream options are ignored,
as if they had been set to yes.
.TP
.B ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
@@ -716,6 +719,18 @@ PROXYv2 is supported for UDP and TCP/TLS listening interfaces.
There is no support for PROXYv2 on a DoH or DNSCrypt listening interface.
Can list multiple, each on a new statement.
.TP
.B quic\-port: \fI<number>
The port number on which to provide DNS-over-QUIC service, default 853, 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.
.TP
.B quic\-size: \fI<size in bytes>
Maximum number of bytes for all QUIC buffers and data combined. Default is 8
megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
megabytes or gigabytes (1024*1024 bytes in a megabyte). New connections receive
connection refused when the limit is exceeded. New streams are reset when the
limit is exceeded.
.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
Default is no.
@@ -788,7 +803,8 @@ transports, regardless of the presence of an DNS Cookie and regardless of the
UDP queries without a DNS Cookie receive REFUSED responses with the TC flag set,
that may trigger fall back to TCP for those clients.
.IP
By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd.
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
interface) is implicitly \fIallow\fRed, the rest is \fIrefuse\fRd.
The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS
protocol is not designed to handle dropped packets due to policy, and
dropping may result in (possibly excessive) retried queries.
@@ -824,8 +840,12 @@ Similar to \fBaccess\-control:\fR but for interfaces.
.IP
The action is the same as the ones defined under \fBaccess\-control:\fR.
Interfaces are \fIrefuse\fRd by default.
By default only localhost (the IP netblock, not the loopback interface) is
\fIallow\fRed through the default \fBaccess\-control:\fR behavior.
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
interface) is implicitly \fIallow\fRed through the default
\fBaccess\-control:\fR behavior.
This also means that any attempt to use the \fBinterface-*:\fR options for the
loopback interface will not work as they will be overridden by the implicit
default "\fBaccess\-control:\fR 127.0.0.0/8 allow" option.
.IP
Note that the interface needs to be already specified with \fBinterface:\fR
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
@@ -931,6 +951,10 @@ Sets logfile lines to use a timestamp in UTC ascii. Default is no, which
prints the seconds since 1970 in brackets. No effect if using syslog, in
that case syslog formats the timestamp printed into the log files.
.TP
.B log\-time\-iso:\fR <yes or no>
Log time in ISO8601 format, if \fBlog\-time\-ascii:\fR yes is also set.
Default is no.
.TP
.B log\-queries: \fI<yes or no>
Prints one line per query to the log, with the log timestamp and IP address,
name, type and class. Default is no. Note that it takes time to print these
@@ -1043,6 +1067,11 @@ payload is very large.
.B harden\-glue: \fI<yes or no>
Will trust glue only if it is within the servers authority. Default is yes.
.TP
.B harden\-unverified\-glue: \fI<yes or no>
Will trust only in-zone glue. Will try to resolve all out of zone
(\fI<unverfied>) glue. Will fallback to the original glue if unable to resolve.
Default is no.
.TP
.B harden\-dnssec\-stripped: \fI<yes or no>
Require DNSSEC data for trust\-anchored zones, if such data is absent,
the zone becomes bogus. If turned off, and no DNSSEC data is received
@@ -1166,10 +1195,11 @@ IP6 ::1 and IP4 127.0.0.1/8. If no, then localhost can be used to send
queries to. Default is yes.
.TP
.B prefetch: \fI<yes or no>
If yes, message cache elements are prefetched before they expire to
keep the cache up to date. Default is no. Turning it on gives about
10 percent more traffic and load on the machine, but popular items do
not expire from the cache.
If yes, cache hits on message cache elements that are on their last 10 percent
of their TTL value trigger a prefetch to keep the cache up to date.
Default is no.
Turning it on gives about 10 percent more traffic and load on the machine, but
popular items do not expire from the cache.
.TP
.B prefetch\-key: \fI<yes or no>
If yes, fetch the DNSKEYs earlier in the validation process, when a DS
@@ -1189,12 +1219,13 @@ from the query ID, for speed and thread safety). Default is yes.
.B minimal-responses: \fI<yes or no>
If yes, Unbound does not insert authority/additional sections into response
messages when those sections are not required. This reduces response
size significantly, and may avoid TCP fallback for some responses.
This may cause a slight speedup. The default is yes, even though the DNS
size significantly, and may avoid TCP fallback for some responses which may
cause a slight speedup. The default is yes, even though the DNS
protocol RFCs mandate these sections, and the additional content could
be of use and save roundtrips for clients. Because they are not used,
and the saved roundtrips are easier saved with prefetch, whilst this is
faster.
save roundtrips for clients that use the additional content.
However these sections are hardly used by clients.
Enabling prefetch can benefit clients that need the additional content
by trying to keep that content fresh in the cache.
.TP
.B disable-dnssec-lame-check: \fI<yes or no>
If true, disables the DNSSEC lameness check in the iterator. This check
@@ -1952,6 +1983,23 @@ Changing this value needs caution as it can allow long CNAME chains to be
accepted, where Unbound needs to verify (resolve) each link individually.
Default is 11.
.TP 5
.B iter\-scrub\-ns: \fI<number>
Limit on the number of NS records allowed in an rrset of type NS, from the
iterator scrubber. This protects the internals of the resolver from overly
large NS sets. Default is 20.
.TP 5
.B iter\-scrub\-cname: \fI<number>
Limit on the number of CNAME, DNAME records in an answer, from the iterator
scrubber. This protects the internals of the resolver from overly long
indirection chains. Clips off the remainder of the reply packet at that point.
Default is 11.
.TP 5
.B max\-global\-quota: \fI<number>
Limit on the number of upstream queries sent out for an incoming query and
its subqueries from recursion. It is not reset during the resolution. When
it is exceeded the query is failed and the lookup process stops.
Default is 128.
.TP 5
.B fast\-server\-permil: \fI<number>
Specify how many times out of 1000 to pick from the set of fastest servers.
0 turns the feature off. A value of 900 would pick from the fastest
@@ -1978,6 +2026,20 @@ Useful to explicitly set for servers in an anycast deployment that need to
share the secret in order to verify each other's Server Cookies.
An example hex string would be "000102030405060708090a0b0c0d0e0f".
Default is a 128 bits random secret generated at startup time.
This option is ignored if a \fBcookie\-secret\-file\fR is
present. In that case the secrets from that file are used in DNS Cookie
calculations.
.TP 5
.B cookie\-secret\-file: \fI<filename>
File from which the secrets are read used in DNS Cookie calculations. When this
file exists, the secrets in this file are used and the secret specified by the
\fBcookie-secret\fR option is ignored.
Enable it by setting a filename, like "/usr/local/etc/unbound_cookiesecrets.txt".
The content of this file must be manipulated with the \fBadd_cookie_secret\fR,
\fBdrop_cookie_secret\fR and \fBactivate_cookie_secret\fR commands to the
\fIunbound\-control\fR(8) tool. Please see that manpage on how to perform a
safe cookie secret rollover.
Default is "" (disabled).
.TP 5
.B edns\-client\-string: \fI<IP netblock> <string>
Include an EDNS0 option containing configured ascii string in queries with
@@ -2769,6 +2831,14 @@ if the Redis server does not have the requested data, and will try to
re-establish a new connection later.
This option defaults to 100 milliseconds.
.TP
.B redis-command-timeout: \fI<msec>\fR
The timeout to use for redis commands, in milliseconds. If 0, it uses the
redis\-timeout value. The default is 0.
.TP
.B redis-connect-timeout: \fI<msec>\fR
The timeout to use for redis connection set up, in milliseconds. If 0, it
uses the redis\-timeout value. The default is 0.
.TP
.B redis-expire-records: \fI<yes or no>
If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
records so that Redis can evict keys that have expired automatically. If
@@ -2847,6 +2917,13 @@ Default is "".
The version to send with messages, if "" the package version is used.
Default is "".
.TP
.B dnstap-sample-rate: \fI<number>
The sample rate for log of messages, it logs only 1/N messages. With 0 it
is disabled. Default is 0. This is useful in a high volume environment,
where log functionality would otherwise not be reliable. For example 10
would spend only 1/10th time on logging, and 100 would only spend a
hundredth of the time on logging.
.TP
.B dnstap-log-resolver-query-messages: \fI<yes or no>
Enable to log resolver query messages. Default is no.
These are messages from Unbound to upstream servers.
@@ -2871,9 +2948,11 @@ Enable to log forwarder response messages. Default is no.
.SS Response Policy Zone Options
.LP
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
with a different name. RPZ clauses are applied in order of configuration. The
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
\fBname:\fR. 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. Note that a
PASSTHRU action is still considered a match.
The \fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
\fBmodule-config: "respip validator iterator"\fR.
.P
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
@@ -2881,12 +2960,13 @@ Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
and drop. RPZ QNAME triggers are applied after \fBlocal\-zones\fR and
before \fBauth\-zones\fR.
.P
The rpz zone is formatted with a SOA start record as usual. The items in
the zone are entries, that specify what to act on (the trigger) and what to
do (the action). The trigger to act on is recorded in the name, the action
to do is recorded as the resource record. The names all end in the zone
name, so you could type the trigger names without a trailing dot in the
zonefile.
The RPZ zone is a regular DNS zone formatted with a SOA start record as usual.
The items in the zone are entries, that specify what to act on (the trigger)
and what to do (the action).
The trigger to act on is recorded in the name, the action to do is recorded as
the resource record.
The names all end in the zone name, so you could type the trigger names without
a trailing dot in the zonefile.
.P
An example RPZ record, that answers example.com with NXDOMAIN
.nf
@@ -2986,7 +3066,7 @@ externally blocked. Default is no.
If enabled the zone is authoritatively answered for and queries for the RPZ
zone information are answered to downstream clients. This is useful for
monitoring scripts, that can then access the SOA information to check if
the rpz information is up to date. Default is no.
the RPZ information is up to date. Default is no.
.TP
.B tags: \fI<list of tags>
Limit the policies from this RPZ clause to clients with a matching tag. Tags
+4 -4
View File
@@ -1226,7 +1226,7 @@ VERBATIM_HEADERS = NO
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
#CLANG_ASSISTED_PARSING = NO
# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
# tag is set to YES then doxygen will add the directory of each input to the
@@ -1234,7 +1234,7 @@ CLANG_ASSISTED_PARSING = NO
# The default value is: YES.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_ADD_INC_PATHS = YES
#CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
@@ -1242,7 +1242,7 @@ CLANG_ADD_INC_PATHS = YES
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
#CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
@@ -1255,7 +1255,7 @@ CLANG_OPTIONS =
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
CLANG_DATABASE_PATH =
#CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
+2 -2
View File
@@ -297,8 +297,8 @@ inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type
*/
static struct module_func_block dynlibmod_block = {
"dynlib",
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
&dynlibmod_clear, &dynlibmod_get_mem
NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate,
&dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem
};
struct module_func_block* dynlibmod_get_funcblock(void)
+2 -1
View File
@@ -995,7 +995,8 @@ subnetmod_get_mem(struct module_env *env, int id)
* The module function block
*/
static struct module_func_block subnetmod_block = {
"subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
"subnetcache",
NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
};
+1 -1
View File
@@ -615,7 +615,7 @@ ipsecmod_get_mem(struct module_env* env, int id)
*/
static struct module_func_block ipsecmod_block = {
"ipsecmod",
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
};
+162 -47
View File
@@ -17,9 +17,19 @@
#include "sldns/wire2str.h"
#include "sldns/parseutil.h"
#ifdef HAVE_NET_PFVAR_H
#include <fcntl.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/pfvar.h>
typedef intptr_t filter_dev;
#else
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/ipset/ip_set.h>
typedef struct mnl_socket * filter_dev;
#endif
#define BUFF_LEN 256
@@ -41,24 +51,95 @@ static int error_response(struct module_qstate* qstate, int id, int rcode) {
return 0;
}
static struct mnl_socket * open_mnl_socket() {
struct mnl_socket *mnl;
#ifdef HAVE_NET_PFVAR_H
static void * open_filter() {
filter_dev dev;
mnl = mnl_socket_open(NETLINK_NETFILTER);
if (!mnl) {
dev = open("/dev/pf", O_RDWR);
if (dev == -1) {
log_err("open(\"/dev/pf\") failed: %s", strerror(errno));
return NULL;
}
else
return (void *)dev;
}
#else
static void * open_filter() {
filter_dev dev;
dev = mnl_socket_open(NETLINK_NETFILTER);
if (!dev) {
log_err("ipset: could not open netfilter.");
return NULL;
}
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
mnl_socket_close(mnl);
if (mnl_socket_bind(dev, 0, MNL_SOCKET_AUTOPID) < 0) {
mnl_socket_close(dev);
log_err("ipset: could not bind netfilter.");
return NULL;
}
return mnl;
return (void *)dev;
}
#endif
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
#ifdef HAVE_NET_PFVAR_H
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
struct pfioc_table io;
struct pfr_addr addr;
const char *p;
int i;
bzero(&io, sizeof(io));
bzero(&addr, sizeof(addr));
p = strrchr(setname, '/');
if (p) {
i = p - setname;
if (i >= PATH_MAX) {
errno = ENAMETOOLONG;
return -1;
}
memcpy(io.pfrio_table.pfrt_anchor, setname, i);
if (i < PATH_MAX)
io.pfrio_table.pfrt_anchor[i] = '\0';
p++;
}
else
p = setname;
if (strlen(p) >= PF_TABLE_NAME_SIZE) {
errno = ENAMETOOLONG;
return -1;
}
strlcpy(io.pfrio_table.pfrt_name, p, PF_TABLE_NAME_SIZE);
io.pfrio_buffer = &addr;
io.pfrio_size = 1;
io.pfrio_esize = sizeof(addr);
switch (af) {
case AF_INET:
addr.pfra_ip4addr = *(struct in_addr *)ipaddr;
addr.pfra_net = 32;
break;
case AF_INET6:
addr.pfra_ip6addr = *(struct in6_addr *)ipaddr;
addr.pfra_net = 128;
break;
default:
errno = EAFNOSUPPORT;
return -1;
}
addr.pfra_af = af;
if (ioctl(dev, DIOCRADDADDRS, &io) == -1) {
log_err("ioctl failed: %s", strerror(errno));
return -1;
}
return 0;
}
#else
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
struct nlattr *nested[2];
@@ -91,14 +172,15 @@ static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void
mnl_attr_nest_end(nlh, nested[1]);
mnl_attr_nest_end(nlh, nested[0]);
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
if (mnl_socket_sendto(dev, nlh, nlh->nlmsg_len) < 0) {
return -1;
}
return 0;
}
#endif
static void
ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
ipset_add_rrset_data(struct ipset_env *ie,
struct packed_rrset_data *d, const char* setname, int af,
const char* dname)
{
@@ -123,12 +205,16 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
snprintf(ip, sizeof(ip), "(inet_ntop_error)");
verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
}
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
ret = add_to_ipset((filter_dev)ie->dev, setname, rr_data + 2, af);
if (ret < 0) {
log_err("ipset: could not add %s into %s", dname, setname);
mnl_socket_close(mnl);
ie->mnl = NULL;
#if HAVE_NET_PFVAR_H
/* don't close as we might not be able to open again due to dropped privs */
#else
mnl_socket_close((filter_dev)ie->dev);
ie->dev = NULL;
#endif
break;
}
}
@@ -137,8 +223,8 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
static int
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
const char *qname, const int qlen, const char *setname, int af)
struct ub_packed_rrset_key *rrset, const char *qname, int qlen,
const char *setname, int af)
{
static char dname[BUFF_LEN];
const char *ds, *qs;
@@ -152,11 +238,20 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
log_err("bad domain name");
return -1;
}
if (dname[dlen - 1] == '.') {
dlen--;
}
if (qname[qlen - 1] == '.') {
qlen--;
}
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
ds = NULL;
qs = NULL;
plen = strlen(p->str);
if (p->str[plen - 1] == '.') {
plen--;
}
if (dlen == plen || (dlen > plen && dname[dlen - plen - 1] == '.' )) {
ds = dname + (dlen - plen);
@@ -167,8 +262,7 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
if ((ds && strncasecmp(p->str, ds, plen) == 0)
|| (qs && strncasecmp(p->str, qs, plen) == 0)) {
d = (struct packed_rrset_data*)rrset->entry.data;
ipset_add_rrset_data(ie, mnl, d, setname,
af, dname);
ipset_add_rrset_data(ie, d, setname, af, dname);
break;
}
}
@@ -178,7 +272,6 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
struct query_info qinfo, struct ipset_env *ie)
{
struct mnl_socket *mnl;
size_t i;
const char *setname;
struct ub_packed_rrset_key *rrset;
@@ -186,15 +279,17 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
static char qname[BUFF_LEN];
int qlen;
mnl = (struct mnl_socket *)ie->mnl;
if (!mnl) {
#ifdef HAVE_NET_PFVAR_H
#else
if (!ie->dev) {
/* retry to create mnl socket */
mnl = open_mnl_socket();
if (!mnl) {
ie->dev = open_filter();
if (!ie->dev) {
log_warn("ipset open_filter failed");
return -1;
}
ie->mnl = mnl;
}
#endif
qlen = sldns_wire2str_dname_buf(qinfo.qname, qinfo.qname_len,
qname, BUFF_LEN);
@@ -217,8 +312,8 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
}
if (setname) {
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
qname, qlen, setname, af) == -1)
if(ipset_check_zones_for_rrset(env, ie, rrset, qname,
qlen, setname, af) == -1)
return -1;
}
}
@@ -226,7 +321,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
return 0;
}
int ipset_init(struct module_env* env, int id) {
int ipset_startup(struct module_env* env, int id) {
struct ipset_env *ipset_env;
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
@@ -237,7 +332,43 @@ int ipset_init(struct module_env* env, int id) {
env->modinfo[id] = (void *)ipset_env;
ipset_env->mnl = NULL;
#ifdef HAVE_NET_PFVAR_H
ipset_env->dev = open_filter();
if (!ipset_env->dev) {
log_err("ipset open_filter failed");
return 0;
}
#else
ipset_env->dev = NULL;
#endif
return 1;
}
void ipset_destartup(struct module_env* env, int id) {
filter_dev dev;
struct ipset_env *ipset_env;
if (!env || !env->modinfo[id]) {
return;
}
ipset_env = (struct ipset_env*)env->modinfo[id];
dev = (filter_dev)ipset_env->dev;
if (dev) {
#if HAVE_NET_PFVAR_H
close(dev);
#else
mnl_socket_close(dev);
#endif
ipset_env->dev = NULL;
}
free(ipset_env);
env->modinfo[id] = NULL;
}
int ipset_init(struct module_env* env, int id) {
struct ipset_env *ipset_env = env->modinfo[id];
ipset_env->name_v4 = env->cfg->ipset_name_v4;
ipset_env->name_v6 = env->cfg->ipset_name_v6;
@@ -253,24 +384,8 @@ int ipset_init(struct module_env* env, int id) {
return 1;
}
void ipset_deinit(struct module_env *env, int id) {
struct mnl_socket *mnl;
struct ipset_env *ipset_env;
if (!env || !env->modinfo[id]) {
return;
}
ipset_env = (struct ipset_env *)env->modinfo[id];
mnl = (struct mnl_socket *)ipset_env->mnl;
if (mnl) {
mnl_socket_close(mnl);
ipset_env->mnl = NULL;
}
free(ipset_env);
env->modinfo[id] = NULL;
void ipset_deinit(struct module_env *ATTR_UNUSED(env), int ATTR_UNUSED(id)) {
/* nothing */
}
static int ipset_new(struct module_qstate* qstate, int id) {
@@ -376,8 +491,8 @@ size_t ipset_get_mem(struct module_env *env, int id) {
*/
static struct module_func_block ipset_block = {
"ipset",
&ipset_init, &ipset_deinit, &ipset_operate,
&ipset_inform_super, &ipset_clear, &ipset_get_mem
&ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit,
&ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem
};
struct module_func_block * ipset_get_funcblock(void) {
+5 -1
View File
@@ -37,7 +37,7 @@ extern "C" {
#endif
struct ipset_env {
void* mnl;
void* dev;
int v4_enabled;
int v6_enabled;
@@ -50,6 +50,10 @@ struct ipset_qstate {
int dummy;
};
/** Startup the ipset module */
int ipset_startup(struct module_env* env, int id);
/** Destartup the ipset module */
void ipset_destartup(struct module_env* env, int id);
/** Init the ipset module */
int ipset_init(struct module_env* env, int id);
/** Deinit the ipset module */
+113
View File
@@ -367,6 +367,47 @@ type_allowed_in_additional_section(uint16_t tp)
return 0;
}
/** Shorten RRset */
static void
shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
{
/* The too large NS RRset is shortened. This is so that too large
* content does not overwhelm the cache. It may make the rrset
* bogus if it was signed, and then the domain is not resolved any
* more, that is okay, the NS RRset was too large. During a referral
* it can be shortened and then the first part of the list could
* be used to resolve. The scrub continues to disallow glue for the
* removed nameserver RRs and removes that too. Because the glue
* is not marked as okay, since the RRs have been removed here. */
int i;
struct rr_parse* rr = rrset->rr_first, *prev = NULL;
if(!rr)
return;
for(i=0; i<count; i++) {
prev = rr;
rr = rr->next;
if(!rr)
return; /* The RRset is already short. */
}
if(verbosity >= VERB_QUERY
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
dname_pkt_copy(pkt, buf, rrset->dname);
log_nametypeclass(VERB_QUERY, "normalize: shorten RRset:", buf,
rrset->type, ntohs(rrset->rrset_class));
}
/* remove further rrs */
rrset->rr_last = prev;
rrset->rr_count = count;
while(rr) {
rrset->size -= rr->size;
rr = rr->next;
}
if(rrset->rr_last)
rrset->rr_last->next = NULL;
else rrset->rr_first = NULL;
}
/**
* This routine normalizes a response. This includes removing "irrelevant"
* records from the answer and additional sections and (re)synthesizing
@@ -387,6 +428,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
struct rrset_parse* rrset, *prev, *nsset=NULL;
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
@@ -401,6 +443,16 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
prev = NULL;
rrset = msg->rrset_first;
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
if(cname_length > env->cfg->iter_scrub_cname) {
/* Too many CNAMEs, or DNAMEs, from the authority
* server, scrub down the length to something
* shorter. This deletes everything after the limit
* is reached. The iterator is going to look up
* the content one by one anyway. */
remove_rrset("normalize: removing because too many cnames:",
pkt, msg, prev, &rrset);
continue;
}
if(rrset->type == LDNS_RR_TYPE_DNAME &&
pkt_strict_sub(pkt, sname, rrset->dname)) {
/* check if next rrset is correct CNAME. else,
@@ -420,6 +472,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"too long");
return 0;
}
cname_length++;
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
/* check next cname */
@@ -460,6 +513,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
if(rrset->type == LDNS_RR_TYPE_CNAME) {
struct rrset_parse* nx = rrset->rrset_all_next;
uint8_t* oldsname = sname;
cname_length++;
/* see if the next one is a DNAME, if so, swap them */
if(nx && nx->section == LDNS_SECTION_ANSWER &&
nx->type == LDNS_RR_TYPE_DNAME &&
@@ -507,6 +561,10 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
LDNS_SECTION_ANSWER &&
dname_pkt_compare(pkt, oldsname,
rrset->dname) == 0) {
if(rrset->type == LDNS_RR_TYPE_NS &&
rrset->rr_count > env->cfg->iter_scrub_ns) {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
prev = rrset;
rrset = rrset->rrset_all_next;
}
@@ -522,6 +580,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
if(rrset->type == LDNS_RR_TYPE_NS &&
rrset->rr_count > env->cfg->iter_scrub_ns) {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
/* Mark the additional names from relevant rrset as OK. */
/* only for RRsets that match the query name, other ones
* will be removed by sanitize, so no additional for them */
@@ -578,6 +641,25 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(rrset->rr_count > env->cfg->iter_scrub_ns) {
/* If this is not a referral, and the NS RRset
* is signed, then remove it entirely, so
* that when it becomes bogus it does not
* make the message that is otherwise fine
* into a bogus message. */
if(!(msg->an_rrsets == 0 &&
FLAGS_GET_RCODE(msg->flags) ==
LDNS_RCODE_NOERROR &&
!soa_in_auth(msg) &&
!(msg->flags & BIT_AA)) &&
rrset->rrsig_count != 0) {
remove_rrset("normalize: removing too large NS "
"RRset:", pkt, msg, prev, &rrset);
continue;
} else {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
}
}
/* if this is type DS and we query for type DS we just got
* a referral answer for our type DS query, fix packet */
@@ -789,6 +871,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
{
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
uint8_t* ns_rrset_dname = NULL;
int added_rrlen_ede = 0;
struct rrset_parse* rrset, *prev;
prev = NULL;
@@ -894,6 +977,16 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
}
if(rrset->type == LDNS_RR_TYPE_NS &&
(rrset->section == LDNS_SECTION_AUTHORITY ||
rrset->section == LDNS_SECTION_ANSWER)) {
/* If the type is NS, and we're in the
* answer or authority section, then
* store the dname so we can check
* against the glue records
* further down */
ns_rrset_dname = rrset->dname;
}
if(del_addi && rrset->section == LDNS_SECTION_ADDITIONAL) {
remove_rrset("sanitize: removing potential "
"poison reference RRset:", pkt, msg, prev, &rrset);
@@ -906,6 +999,26 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(env->cfg->harden_unverified_glue && ns_rrset_dname &&
rrset->section == LDNS_SECTION_ADDITIONAL &&
(rrset->type == LDNS_RR_TYPE_A || rrset->type == LDNS_RR_TYPE_AAAA) &&
!pkt_strict_sub(pkt, rrset->dname, ns_rrset_dname)) {
/* We're in the additional section, looking
* at an A/AAAA rrset, have a previous
* delegation point and we notice that
* the glue records are NOT for strict
* subdomains of the delegation. So set a
* flag, recompute the hash for the rrset
* and write the A/AAAA record to cache.
* It'll be retrieved if we can't separately
* resolve the glue */
rrset->flags = PACKED_RRSET_UNVERIFIED_GLUE;
rrset->hash = pkt_hash_rrset(pkt, rrset->dname, rrset->type, rrset->rrset_class, rrset->flags);
store_rrset(pkt, msg, env, rrset);
remove_rrset("sanitize: storing potential "
"unverified glue reference RRset:", pkt, msg, prev, &rrset);
continue;
}
prev = rrset;
rrset = rrset->rrset_all_next;
}
+42
View File
@@ -1564,3 +1564,45 @@ void iterator_set_ip46_support(struct module_stack* mods,
if(outnet->num_ip6 == 0)
ie->supports_ipv6 = 0;
}
void
limit_nsec_ttl(struct dns_msg* msg)
{
/* Limit NSEC and NSEC3 TTL in response, RFC9077 */
size_t i;
int found = 0;
time_t soa_ttl = 0;
/* Limit the NSEC and NSEC3 TTL values to the SOA TTL and SOA minimum
* TTL. That has already been applied to the SOA record ttl. */
for(i=0; i<msg->rep->rrset_count; i++) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA) {
struct packed_rrset_data* soadata = (struct packed_rrset_data*)s->entry.data;
found = 1;
soa_ttl = soadata->ttl;
break;
}
}
if(!found)
return;
for(i=0; i<msg->rep->rrset_count; i++) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC ||
ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) {
struct packed_rrset_data* data = (struct packed_rrset_data*)s->entry.data;
/* Limit the negative TTL. */
if(data->ttl > soa_ttl) {
if(verbosity >= VERB_ALGO) {
char buf[256];
snprintf(buf, sizeof(buf),
"limiting TTL %d of %s record to the SOA TTL of %d for",
(int)data->ttl, ((ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC)?"NSEC":"NSEC3"), (int)soa_ttl);
log_nametypeclass(VERB_ALGO, buf,
s->rk.dname, ntohs(s->rk.type),
ntohs(s->rk.rrset_class));
}
data->ttl = soa_ttl;
}
}
}
}
+7
View File
@@ -428,4 +428,11 @@ int iter_stub_fwd_no_cache(struct module_qstate *qstate,
void iterator_set_ip46_support(struct module_stack* mods,
struct module_env* env, struct outside_network* outnet);
/**
* Limit NSEC and NSEC3 TTL in response, RFC9077
* @param msg: dns message, the SOA record ttl is used to restrict ttls
* of NSEC and NSEC3 RRsets. If no SOA record, nothing happens.
*/
void limit_nsec_ttl(struct dns_msg* msg);
#endif /* ITERATOR_ITER_UTILS_H */
+67 -16
View File
@@ -70,6 +70,8 @@
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
/* number of packets */
int MAX_GLOBAL_QUOTA = 128;
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
/* in msec */
@@ -252,7 +254,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
} else {
/* see if the failure did get (parent-lame) info */
if(!cache_fill_missing(super->env, super_iq->qchase.qclass,
super->region, super_iq->dp))
super->region, super_iq->dp, 0))
log_err("out of memory adding missing");
}
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
@@ -320,16 +322,21 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
qstate->query_flags, 0,
qstate->env->cfg->serve_expired_ttl_reset)) != NULL) {
qstate->env->cfg->serve_expired)) != NULL) {
struct reply_info* rep = (struct reply_info*)msg->entry.data;
if(qstate->env->cfg->serve_expired &&
qstate->env->cfg->serve_expired_ttl_reset && rep &&
*qstate->env->now + qstate->env->cfg->serve_expired_ttl
> rep->serve_expired_ttl) {
verbose(VERB_ALGO, "reset serve-expired-ttl for "
if(qstate->env->cfg->serve_expired && rep) {
if(qstate->env->cfg->serve_expired_ttl_reset &&
*qstate->env->now + qstate->env->cfg->serve_expired_ttl
> rep->serve_expired_ttl) {
verbose(VERB_ALGO, "reset serve-expired-ttl for "
"response in cache");
rep->serve_expired_ttl = *qstate->env->now +
qstate->env->cfg->serve_expired_ttl;
}
verbose(VERB_ALGO, "set serve-expired-norec-ttl for "
"response in cache");
rep->serve_expired_ttl = *qstate->env->now +
qstate->env->cfg->serve_expired_ttl;
rep->serve_expired_norec_ttl = NORR_TTL +
*qstate->env->now;
}
if(rep && (FLAGS_GET_RCODE(rep->flags) ==
LDNS_RCODE_NOERROR ||
@@ -407,8 +414,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
num_an = 0;
for(p = iq->an_prepend_list; p; p = p->next) {
sets[num_an++] = p->rrset;
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
}
}
memcpy(sets+num_an, msg->rep->rrsets, msg->rep->an_numrrsets *
sizeof(struct ub_packed_rrset_key*));
@@ -421,8 +431,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
msg->rep->ns_numrrsets, p->rrset))
continue;
sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
}
}
memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns,
msg->rep->rrsets + msg->rep->an_numrrsets,
@@ -760,6 +773,14 @@ target_count_increase_nx(struct iter_qstate* iq, int num)
iq->target_count[TARGET_COUNT_NX] += num;
}
static void
target_count_increase_global_quota(struct iter_qstate* iq, int num)
{
target_count_create(iq);
if(iq->target_count)
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
}
/**
* Generate a subrequest.
* Generate a local request event. Local events are tied to this module, and
@@ -1560,6 +1581,11 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
errinf(qstate, "malloc failure for forward zone");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, 0)) {
errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if((qstate->query_flags&BIT_RD)==0) {
/* If the server accepts RD=0 queries and forwards
* with RD=1, then if the server is listed as an NS
@@ -2137,6 +2163,15 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(qstate->env->cfg->harden_unverified_glue) {
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, PACKED_RRSET_UNVERIFIED_GLUE))
log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try unverified glue from cache");
return next_state(iq, QUERYTARGETS_STATE);
}
}
if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
struct delegpt* dp;
int nolock = 0;
@@ -2179,7 +2214,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* see if that makes new names available */
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp))
qstate->region, iq->dp, 0))
log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try parent-side-name, w. glue from cache");
@@ -3008,6 +3043,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
target_count_increase_global_quota(iq, 1);
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
> MAX_GLOBAL_QUOTA) {
char s[LDNS_MAX_DOMAINLEN+1];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"global quota on number of upstream queries %d", s,
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Do not check ratelimit for forwarding queries or if we already got a
* pass. */
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
@@ -3400,7 +3446,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
old_dp->name, old_dp->namelen);
}
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp)) {
qstate->region, iq->dp, 0)) {
errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -3969,6 +4015,8 @@ processClassResponse(struct module_qstate* qstate, int id,
to->rep->prefetch_ttl = from->rep->prefetch_ttl;
if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
if(from->rep->serve_expired_norec_ttl < to->rep->serve_expired_norec_ttl)
to->rep->serve_expired_norec_ttl = from->rep->serve_expired_norec_ttl;
}
/* are we done? */
foriq->num_current_queries --;
@@ -4331,7 +4379,10 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(verbosity >= VERB_ALGO)
log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
iq->response->rep);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(iq->response);
}
if(event == module_event_capsfail || iq->caps_fallback) {
if(qstate->env->cfg->qname_minimisation &&
iq->minimisation_state != DONOT_MINIMISE_STATE) {
@@ -4489,8 +4540,8 @@ iter_get_mem(struct module_env* env, int id)
*/
static struct module_func_block iter_block = {
"iterator",
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super,
&iter_clear, &iter_get_mem
NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
&iter_inform_super, &iter_clear, &iter_get_mem
};
struct module_func_block*
+6
View File
@@ -55,6 +55,9 @@ struct rbtree_type;
/** max number of targets spawned for a query and its subqueries */
#define MAX_TARGET_COUNT 64
/** max number of upstream queries for a query and its subqueries, it is
* never reset. */
extern int MAX_GLOBAL_QUOTA;
/** max number of target lookups per qstate, per delegation point */
#define MAX_DP_TARGET_COUNT 16
/** max number of nxdomains allowed for target lookups for a query and
@@ -248,6 +251,9 @@ enum target_count_variables {
TARGET_COUNT_QUERIES,
/** Number of nxdomain responses encountered. */
TARGET_COUNT_NX,
/** Global quota on number of queries to upstream servers per
* client request, that is never reset. */
TARGET_COUNT_GLOBAL_QUOTA,
/** This should stay last here, it is used for the allocation */
TARGET_COUNT_MAX,
+4 -2
View File
@@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
ctx->pipe_pid = getpid();
cfg_apply_local_port_policy(cfg, 65536);
config_apply(cfg);
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
listen_setup_locks();
log_edns_known_options(VERB_ALGO, ctx->env);
@@ -393,7 +395,7 @@ context_serialize_cancel(struct ctx_query* q, uint32_t* len)
/* format of cancel:
* o uint32 cmd
* o uint32 async-id */
uint8_t* p = (uint8_t*)reallocarray(NULL, sizeof(uint32_t), 2);
uint8_t* p = (uint8_t*)reallocarray(NULL, 2, sizeof(uint32_t));
if(!p) return NULL;
*len = 2*sizeof(uint32_t);
sldns_write_uint32(p, UB_LIBCMD_CANCEL);
+9 -3
View File
@@ -188,7 +188,9 @@ ub_ctx_create(void)
int e = errno;
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
modstack_call_deinit(&ctx->mods, ctx->env);
modstack_call_destartup(&ctx->mods, ctx->env);
modstack_free(&ctx->mods);
listen_desetup_locks();
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
@@ -202,7 +204,9 @@ ub_ctx_create(void)
tube_delete(ctx->qq_pipe);
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
modstack_call_deinit(&ctx->mods, ctx->env);
modstack_call_destartup(&ctx->mods, ctx->env);
modstack_free(&ctx->mods);
listen_desetup_locks();
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
@@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
}
libworker_delete_event(ctx->event_worker);
modstack_desetup(&ctx->mods, ctx->env);
modstack_call_deinit(&ctx->mods, ctx->env);
modstack_call_destartup(&ctx->mods, ctx->env);
modstack_free(&ctx->mods);
a = ctx->alloc_list;
while(a) {
na = a->super;
+17
View File
@@ -292,6 +292,7 @@ libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len)
log_err("unknown command for bg worker %d",
(int)context_serial_getcmd(msg, len));
/* and fall through to quit */
ATTR_FALLTHROUGH
/* fallthrough */
case UB_LIBCMD_QUIT:
free(msg);
@@ -1057,3 +1058,19 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
@@ -30,6 +30,7 @@ def dnssecParse(domain, rrType=RR_TYPE_A):
resolver = ub_ctx()
resolver.add_ta(". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5")
resolver.add_ta(". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D")
resolver.add_ta(". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16")
dnssecParse("nic.cz")
dnssecParse("nonexistent-domain-blablabla.cz")
+4
View File
@@ -845,6 +845,10 @@ struct ub_server_stats {
long long qtls_resume;
/** RPZ action stats */
long long rpz_action[UB_STATS_RPZ_ACTION_NUM];
/** number of bytes in QUIC buffers */
long long mem_quic;
/** number of queries over (DNS over) QUIC */
long long qquic;
};
/**
+1 -1
View File
@@ -53,7 +53,7 @@ Generate a distribution tar file for unbound.
(which will then be unbound-<version>rc<number>)
-u git_url Retrieve the source from the specified repository url.
Detected from the working copy if not specified.
-b git_branch Retrieve the the specified branch or tag.
-b git_branch Retrieve the specified branch or tag.
Detected from the working copy if not specified.
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
+4
View File
@@ -176,6 +176,10 @@ config_file
Harden against spoofed glue (out of zone data).
.. attribute:: harden_unverified_glue
Harden against unverified glue.
.. attribute:: harden_dnssec_stripped
Harden against receiving no DNSSEC data for trust anchor.
+1
View File
@@ -1009,6 +1009,7 @@ struct config_file {
int harden_short_bufsize;
int harden_large_queries;
int harden_glue;
int harden_unverified_glue;
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
+2 -2
View File
@@ -777,8 +777,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id)
*/
static struct module_func_block pythonmod_block = {
"python",
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
&pythonmod_clear, &pythonmod_get_mem
NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate,
&pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem
};
struct module_func_block* pythonmod_get_funcblock(void)
+2 -2
View File
@@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
*/
static struct module_func_block respip_block = {
"respip",
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
&respip_clear, &respip_get_mem
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
&respip_inform_super, &respip_clear, &respip_get_mem
};
struct module_func_block*
+63 -24
View File
@@ -3684,6 +3684,29 @@ auth_zone_parse_notify_serial(sldns_buffer* pkt, uint32_t *serial)
return 1;
}
/** print addr to str, and if not 53, append "@port_number", for logs. */
static void addr_port_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
char* buf, size_t len)
{
uint16_t port = 0;
if(addr_is_ip6(addr, addrlen)) {
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
port = ntohs((uint16_t)sa->sin6_port);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
port = ntohs((uint16_t)sa->sin_port);
}
if(port == UNBOUND_DNS_PORT) {
/* If it is port 53, print it plainly. */
addr_to_str(addr, addrlen, buf, len);
} else {
char a[256];
a[0]=0;
addr_to_str(addr, addrlen, a, sizeof(a));
snprintf(buf, len, "%s@%d", a, (int)port);
}
}
/** see if addr appears in the list */
static int
addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
@@ -5516,7 +5539,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
if(!xfr->task_transfer->cp) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create http cp "
"connection for %s to %s", zname, as);
return 0;
@@ -5525,7 +5548,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
if(verbosity >= VERB_ALGO) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as);
}
/* Create or refresh the list of allow_notify addrs */
@@ -5548,7 +5571,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
if(!xfr->task_transfer->cp) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create tcp cp connection for "
"xfr %s to %s", zname, as);
return 0;
@@ -5557,7 +5580,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
if(verbosity >= VERB_ALGO) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
}
@@ -5660,7 +5683,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
}
if(verbosity >= VERB_ALGO) {
char s[64];
addr_to_str(&a->addr, a->addrlen, s, sizeof(s));
addr_port_to_str(&a->addr, a->addrlen, s, sizeof(s));
verbose(VERB_ALGO, "auth host %s lookup %s",
m->host, s);
}
@@ -6406,7 +6429,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
if(!xfr->task_probe->cp) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create udp cp for "
"probe %s to %s", zname, as);
return 0;
@@ -6426,7 +6449,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
(struct sockaddr*)&addr, addrlen, 0)) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to send soa probe for %s to %s",
zname, as);
return 0;
@@ -6434,7 +6457,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
if(verbosity >= VERB_ALGO) {
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_to_str(&addr, addrlen, as, sizeof(as));
addr_port_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
as);
}
@@ -7778,7 +7801,8 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
struct module_env* env, struct module_stack* mods,
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg)
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg,
char* reasonbuf, size_t reasonlen)
{
struct ub_packed_rrset_key pk;
enum sec_status sec;
@@ -7808,7 +7832,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
"zonemd: verify %s RRset with DNSKEY", typestr);
}
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
LDNS_SECTION_ANSWER, NULL, &verified);
LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen);
if(sec == sec_status_secure) {
return 1;
}
@@ -7851,7 +7875,8 @@ static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
static int zonemd_check_dnssec_absence(struct auth_zone* z,
struct module_env* env, struct module_stack* mods,
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
char** reason, char** why_bogus, uint8_t* sigalg)
char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf,
size_t reasonlen)
{
struct auth_rrset* nsec = NULL;
if(!apex) {
@@ -7863,7 +7888,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
struct ub_packed_rrset_key pk;
/* dnssec verify the NSEC */
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
nsec, why_bogus, sigalg)) {
nsec, why_bogus, sigalg, reasonbuf, reasonlen)) {
*reason = "DNSSEC verify failed for NSEC RRset";
return 0;
}
@@ -7906,7 +7931,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
}
/* dnssec verify the NSEC3 */
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
nsec3, why_bogus, sigalg)) {
nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) {
*reason = "DNSSEC verify failed for NSEC3 RRset";
return 0;
}
@@ -7928,7 +7953,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
struct module_env* env, struct module_stack* mods,
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
uint8_t* sigalg)
uint8_t* sigalg, char* reasonbuf, size_t reasonlen)
{
struct auth_rrset* soa;
if(!apex) {
@@ -7941,12 +7966,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
return 0;
}
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
why_bogus, sigalg)) {
why_bogus, sigalg, reasonbuf, reasonlen)) {
*reason = "DNSSEC verify failed for SOA RRset";
return 0;
}
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
zonemd_rrset, why_bogus, sigalg)) {
zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) {
*reason = "DNSSEC verify failed for ZONEMD RRset";
return 0;
}
@@ -8014,6 +8039,7 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
int is_insecure, char** result, uint8_t* sigalg)
{
char reasonbuf[256];
char* reason = NULL, *why_bogus = NULL;
struct auth_data* apex = NULL;
struct auth_rrset* zonemd_rrset = NULL;
@@ -8042,7 +8068,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
} else if(!zonemd_rrset && dnskey && !is_insecure) {
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
&reason, &why_bogus, sigalg)) {
&reason, &why_bogus, sigalg, reasonbuf,
sizeof(reasonbuf))) {
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
return;
}
@@ -8050,7 +8077,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
} else if(zonemd_rrset && dnskey && !is_insecure) {
/* check DNSSEC verify of SOA and ZONEMD */
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
zonemd_rrset, &reason, &why_bogus, sigalg)) {
zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf,
sizeof(reasonbuf))) {
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
return;
}
@@ -8107,6 +8135,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
* @param why_bogus: if the routine fails, returns the failure reason.
* @param keystorage: where to store the ub_packed_rrset_key that is created
* on success. A pointer to it is returned on success.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return the dnskey RRset, reference to zone data and keystorage, or
* NULL on failure.
*/
@@ -8114,7 +8144,8 @@ static struct ub_packed_rrset_key*
zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
struct module_stack* mods, struct trust_anchor* anchor,
int* is_insecure, char** why_bogus,
struct ub_packed_rrset_key* keystorage)
struct ub_packed_rrset_key* keystorage, char* reasonbuf,
size_t reasonlen)
{
struct auth_data* apex;
struct auth_rrset* dnskey_rrset;
@@ -8150,7 +8181,8 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
auth_zone_log(z->name, VERB_QUERY,
"zonemd: verify DNSKEY RRset with trust anchor");
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf,
reasonlen);
regional_free_all(env->scratch);
if(sec == sec_status_secure) {
/* success */
@@ -8173,7 +8205,8 @@ static struct ub_packed_rrset_key*
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
struct module_env* env, struct module_stack* mods,
struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus,
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg)
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg,
char* reasonbuf, size_t reasonlen)
{
struct auth_data* apex;
struct auth_rrset* dnskey_rrset;
@@ -8209,7 +8242,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
keystorage->rk.rrset_class = htons(z->dclass);
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
why_bogus, NULL, NULL);
why_bogus, NULL, NULL, reasonbuf, reasonlen);
regional_free_all(env->scratch);
if(sec == sec_status_secure) {
/* success */
@@ -8235,6 +8268,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
{
struct auth_zone* z = (struct auth_zone*)arg;
struct module_env* env;
char reasonbuf[256];
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
int is_insecure = 0, downprot;
@@ -8346,7 +8380,8 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
if(!reason && !is_insecure && !dnskey && ds) {
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
&keystorage, downprot?sigalg:NULL);
&keystorage, downprot?sigalg:NULL, reasonbuf,
sizeof(reasonbuf));
if(!dnskey && !is_insecure && !reason)
reason = "DNSKEY verify with DS failed";
}
@@ -8354,6 +8389,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
if(reason) {
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
lock_rw_unlock(&z->lock);
regional_free_all(env->scratch);
return;
}
@@ -8438,6 +8474,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
struct module_stack* mods, char** result, int offline, int only_online)
{
char reasonbuf[256];
char* reason = NULL, *why_bogus = NULL;
struct trust_anchor* anchor = NULL;
struct ub_packed_rrset_key* dnskey = NULL;
@@ -8472,7 +8509,8 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
}
/* equal to trustanchor, no need for online lookups */
dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
&is_insecure, &why_bogus, &keystorage);
&is_insecure, &why_bogus, &keystorage, reasonbuf,
sizeof(reasonbuf));
lock_basic_unlock(&anchor->lock);
if(!dnskey && !reason && !is_insecure) {
reason = "verify DNSKEY RRset with trust anchor failed";
@@ -8498,6 +8536,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
if(reason) {
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
regional_free_all(env->scratch);
return;
}
+67 -25
View File
@@ -88,7 +88,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
/* update ref if it was in the cache */
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
env->alloc, ((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?qstarttime:now + leeway))) {
LDNS_RR_TYPE_NS && !pside)?qstarttime:now) + leeway)) {
case 0: /* ref unchanged, item inserted */
break;
case 2: /* ref updated, cache is superior */
@@ -96,7 +96,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
struct ub_packed_rrset_key* ck;
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
/* if deleted rrset, do not copy it */
if(rep->ref[i].key->id == 0)
if(rep->ref[i].key->id == 0 ||
rep->ref[i].id != rep->ref[i].key->id)
ck = NULL;
else ck = packed_rrset_copy_region(
rep->ref[i].key, region, now);
@@ -109,14 +110,22 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
/* no break: also copy key item */
/* the line below is matched by gcc regex and silences
* the fallthrough warning */
ATTR_FALLTHROUGH
/* fallthrough */
case 1: /* ref updated, item inserted */
rep->rrsets[i] = rep->ref[i].key;
/* ref was updated; make sure the message ttl is
* updated to the minimum of the current rrsets. */
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
/* if deleted, skip ttl update. */
if(rep->ref[i].key->id != 0 &&
rep->ref[i].id == rep->ref[i].key->id) {
ttl = ((struct packed_rrset_data*)
rep->rrsets[i]->entry.data)->ttl;
if(ttl < min_ttl) min_ttl = ttl;
}
lock_rw_unlock(&rep->ref[i].key->entry.lock);
}
/* if ref was updated make sure the message ttl is updated to
* the minimum of the current rrsets. */
ttl = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)->ttl;
if(ttl < min_ttl) min_ttl = ttl;
}
if(min_ttl < rep->ttl) {
rep->ttl = min_ttl;
@@ -153,7 +162,7 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
size_t i;
/* store RRsets */
for(i=0; i<rep->rrset_count; i++) {
for(i=0; i<rep->rrset_count; i++) {
rep->ref[i].key = rep->rrsets[i];
rep->ref[i].id = rep->rrsets[i]->id;
}
@@ -188,6 +197,7 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
reply_info_sortref(rep);
if(!(e = query_info_entrysetup(qinfo, rep, hash))) {
log_err("store_msg: malloc failed");
reply_info_delete(rep, NULL);
return;
}
slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc);
@@ -337,6 +347,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
/* Because recursion for lookup uses BIT_CD, check
* for that so it stops the recursion lookup, if a
* negative answer is cached. Because the cache uses
* the CD flag for type AAAA. */
if(!neg)
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@@ -349,7 +366,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
/** find and add A and AAAA records for missing nameservers in delegpt */
int
cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp)
struct regional* region, struct delegpt* dp, uint32_t flags)
{
struct delegpt_ns* ns;
struct msgreply_entry* neg;
@@ -360,7 +377,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
continue;
ns->cache_lookup_count++;
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
ns->namelen, LDNS_RR_TYPE_A, qclass, flags, now, 0);
if(akey) {
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
NULL)) {
@@ -381,7 +398,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
}
}
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, flags, now, 0);
if(akey) {
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
NULL)) {
@@ -396,6 +413,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
/* Because recursion for lookup uses BIT_CD, check
* for that so it stops the recursion lookup, if a
* negative answer is cached. Because the cache uses
* the CD flag for type AAAA. */
if(!neg)
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@@ -584,22 +608,8 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
time_t now_control = now;
if(now > r->ttl) {
/* Check if we are allowed to serve expired */
if(allow_expired) {
if(env->cfg->serve_expired_ttl &&
r->serve_expired_ttl < now) {
return NULL;
}
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
} else {
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;
@@ -618,6 +628,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
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;
@@ -701,6 +712,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ttl = d->ttl - now;
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 = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -740,6 +752,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ttl = d->ttl - now;
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 = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -1047,6 +1060,35 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct regional* region, uint32_t flags, time_t qstarttime)
{
struct reply_info* rep = NULL;
if(SERVE_EXPIRED) {
/* We are serving expired records. Before caching, check if a
* useful expired record exists. */
struct msgreply_entry* e = msg_cache_lookup(env,
msgqinf->qname, msgqinf->qname_len, msgqinf->qtype,
msgqinf->qclass, flags, 0, 0);
if(e) {
struct reply_info* cached = e->entry.data;
if(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.
* In that case don't cache it and let a
* subsequent module handle the caching. For
* example, the iterator should not replace an
* expired secure answer with a fresh unchecked
* one and let the validator manage caching. */
&& cached->security != sec_status_bogus
&& (env->need_to_validate &&
msgrep->security == sec_status_unchecked)) {
verbose(VERB_ALGO, "a validated expired entry "
"could be overwritten, skip caching "
"the new message at this stage");
lock_rw_unlock(&e->entry.lock);
return 1;
}
lock_rw_unlock(&e->entry.lock);
}
}
/* alloc, malloc properly (not in region, like msg is) */
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
+2 -1
View File
@@ -202,10 +202,11 @@ struct dns_msg* dns_cache_lookup(struct module_env* env,
* @param qclass: which class to look in.
* @param region: where to store new dp info.
* @param dp: delegation point to fill missing entries.
* @param flags: rrset flags, or 0.
* @return false on alloc failure.
*/
int cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp);
struct regional* region, struct delegpt* dp, uint32_t flags);
/**
* Utility, create new, unpacked data structure for cache response.
+2
View File
@@ -357,6 +357,7 @@ infra_create(struct config_file* cfg)
return NULL;
}
infra_ip_ratelimit = cfg->ip_ratelimit;
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
@@ -408,6 +409,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit;
infra_ip_ratelimit = cfg->ip_ratelimit;
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
sizeof(struct infra_data)+INFRA_BYTES_NAME);
/* divide cachesize by slabs and multiply by slabs, because if the
+1 -1
View File
@@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
struct config_file* cfg);
/**
* Plain find infra data function (used by the the other functions)
* Plain find infra data function (used by the other functions)
* @param infra: infrastructure cache.
* @param addr: host address.
* @param addrlen: length of addr.
+5 -5
View File
@@ -128,8 +128,8 @@ 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, current data is better */
if( newd->ttl < timenow && cached->ttl >= timenow)
/* o if new data is expired, cached data is better */
if( newd->ttl < timenow && timenow <= cached->ttl)
return 0;
/* o store if rrset has been validated
* everything better than bogus data
@@ -140,9 +140,9 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if( cached->security == sec_status_bogus &&
newd->security != sec_status_bogus && !equal)
return 1;
/* o if current RRset is more trustworthy - insert it */
/* o if new RRset is more trustworthy - insert it */
if( newd->trust > cached->trust ) {
/* if the cached rrset is bogus, and this one equal,
/* if the cached rrset is bogus, and new is equal,
* do not update the TTL - let it expire. */
if(equal && cached->ttl >= timenow &&
cached->security == sec_status_bogus)
@@ -155,7 +155,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal ) {
/* if this is type NS, do not 'stick' to owner that changes
* the NS RRset, but use the old TTL for the new data, and
* the NS RRset, but use the cached TTL for the new data, and
* update to fetch the latest data. ttl is not expired, because
* that check was before this one. */
if(ns) {
+2501 -35
View File
File diff suppressed because it is too large Load Diff
+401 -4
View File
@@ -43,10 +43,16 @@
#define LISTEN_DNSPORT_H
#include "util/netevent.h"
#include "util/rbtree.h"
#include "util/locks.h"
#include "daemon/acl_list.h"
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#endif
struct listen_list;
struct config_file;
struct addrinfo;
@@ -100,7 +106,9 @@ enum listen_type {
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
listen_type_udpancil_dnscrypt,
/** HTTP(2) over TLS over TCP */
listen_type_http
listen_type_http,
/** DNS over QUIC */
listen_type_doq
};
/*
@@ -188,6 +196,11 @@ int resolve_interface_names(char** ifs, int num_ifs,
* @param tcp_conn_limit: TCP connection limit info.
* @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled.
* @param doq_table: the doq connection table, with shared information.
* @param rnd: random state.
* @param ssl_service_key: the SSL service key file.
* @param ssl_service_pem: the SSL service pem file.
* @param cfg: config file struct.
* @param cb: callback function when a request arrives. It is passed
* the packet and user argument. Return true to send a reply.
* @param cb_arg: user data argument for callback function.
@@ -198,8 +211,10 @@ listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
int harden_large_queries, uint32_t http_max_streams,
char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit,
void* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
void *cb_arg);
void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table,
struct ub_randstate* rnd, const char* ssl_service_key,
const char* ssl_service_pem, struct config_file* cfg,
comm_point_callback_type* cb, void *cb_arg);
/**
* delete the listening structure
@@ -278,11 +293,12 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use.
* @param additional: additional log information for the socket type.
* @return: the socket. -1 on error.
*/
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int nodelay, int freebind,
int use_systemd, int dscp);
int use_systemd, int dscp, const char* additional);
/**
* Create and bind local listening socket
@@ -452,6 +468,377 @@ int http2_submit_dns_response(struct http2_session* h2_session);
int http2_submit_dns_response(void* v);
#endif /* HAVE_NGHTTP2 */
#ifdef HAVE_NGTCP2
struct doq_conid;
struct doq_server_socket;
/**
* DoQ shared connection table. This is the connections for the host.
* And some config parameter values for connections. The host has to
* respond on that ip,port for those connections, so they are shared
* between threads.
*/
struct doq_table {
/** the lock on the tree and config elements. insert and deletion,
* also lookup in the tree needs to hold the lock. */
lock_rw_type lock;
/** rbtree of doq_conn, the connections to different destination
* addresses, and can be found by dcid. */
struct rbtree_type* conn_tree;
/** lock for the conid tree, needed for the conid tree and also
* the conid elements */
lock_rw_type conid_lock;
/** rbtree of doq_conid, connections can be found by their
* connection ids. Lookup by connection id, finds doq_conn. */
struct rbtree_type* conid_tree;
/** the server scid length */
int sv_scidlen;
/** the static secret for the server */
uint8_t* static_secret;
/** length of the static secret */
size_t static_secret_len;
/** the idle timeout in nanoseconds */
uint64_t idle_timeout;
/** the list of write interested connections, hold the doq_table.lock
* to change them */
struct doq_conn* write_list_first, *write_list_last;
/** rbtree of doq_timer. */
struct rbtree_type* timer_tree;
/** lock on the current_size counter. */
lock_basic_type size_lock;
/** current use, in bytes, of QUIC buffers.
* The doq_conn ngtcp2_conn structure, SSL structure and conid structs
* are not counted. */
size_t current_size;
};
/** create doq table */
struct doq_table* doq_table_create(struct config_file* cfg,
struct ub_randstate* rnd);
/** delete doq table */
void doq_table_delete(struct doq_table* table);
/**
* Timer information for doq timer.
*/
struct doq_timer {
/** The rbnode in the tree sorted by timeout value. Key this struct. */
struct rbnode_type node;
/** The timeout value. Absolute time value. */
struct timeval time;
/** If the timer is in the time tree, with the node. */
int timer_in_tree;
/** If there are more timers with the exact same timeout value,
* they form a set of timers. The rbnode timer has a link to the list
* with the other timers in the set. The rbnode timer is not a
* member of the list with the other timers. The other timers are not
* linked into the tree. */
struct doq_timer* setlist_first, *setlist_last;
/** If the timer is on the setlist. */
int timer_in_list;
/** If in the setlist, the next and prev element. */
struct doq_timer* setlist_next, *setlist_prev;
/** The connection that is timeouted. */
struct doq_conn* conn;
/** The worker that is waiting for the timeout event.
* Set for the rbnode tree linked element. If a worker is waiting
* for the event. If NULL, no worker is waiting for this timeout. */
struct doq_server_socket* worker_doq_socket;
};
/**
* Key information that makes a doq_conn node in the tree lookup.
*/
struct doq_conn_key {
/** the remote endpoint and local endpoint and ifindex */
struct doq_pkt_addr paddr;
/** the doq connection dcid */
uint8_t* dcid;
/** length of dcid */
size_t dcidlen;
};
/**
* DoQ connection, for DNS over QUIC. One connection to a remote endpoint
* with a number of streams in it. Every stream is like a tcp stream with
* a uint16_t length, query read, and a uint16_t length and answer written.
*/
struct doq_conn {
/** rbtree node, key is addresses and dcid */
struct rbnode_type node;
/** lock on the connection */
lock_basic_type lock;
/** the key information, with dcid and address endpoint */
struct doq_conn_key key;
/** the doq server socket for inside callbacks */
struct doq_server_socket* doq_socket;
/** the doq table this connection is part of */
struct doq_table* table;
/** if the connection is about to be deleted. */
uint8_t is_deleted;
/** the version, the client chosen version of QUIC */
uint32_t version;
/** the ngtcp2 connection, a server connection */
struct ngtcp2_conn* conn;
/** the connection ids that are associated with this doq_conn.
* There can be a number, that can change. They are linked here,
* so that upon removal, the list of actually associated conid
* elements can be removed as well. */
struct doq_conid* conid_list;
/** the ngtcp2 last error for the connection */
#ifdef HAVE_NGTCP2_CCERR_DEFAULT
struct ngtcp2_ccerr ccerr;
#else
struct ngtcp2_connection_close_error last_error;
#endif
/** the recent tls alert error code */
uint8_t tls_alert;
/** the ssl context, SSL* */
void* ssl;
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
/** the connection reference for ngtcp2_conn and userdata in ssl */
struct ngtcp2_crypto_conn_ref conn_ref;
#endif
/** closure packet, if any */
uint8_t* close_pkt;
/** length of closure packet. */
size_t close_pkt_len;
/** closure ecn */
uint32_t close_ecn;
/** the streams for this connection, of type doq_stream */
struct rbtree_type stream_tree;
/** the streams that want write, they have something to write.
* The list is ordered, the last have to wait for the first to
* get their data written. */
struct doq_stream* stream_write_first, *stream_write_last;
/** the conn has write interest if true, no write interest if false. */
uint8_t write_interest;
/** if the conn is on the connection write list */
uint8_t on_write_list;
/** the connection write list prev and next, if on the write list */
struct doq_conn* write_prev, *write_next;
/** The timer for the connection. If unused, it is not in the tree
* and not in the list. It is alloced here, so that it is prealloced.
* It has to be set after every read and write on the connection, so
* this improves performance, but also the allocation does not fail. */
struct doq_timer timer;
};
/**
* Connection ID and the doq_conn that is that connection. A connection
* has an original dcid, and then more connection ids associated.
*/
struct doq_conid {
/** rbtree node, key is the connection id. */
struct rbnode_type node;
/** the next and prev in the list of conids for the doq_conn */
struct doq_conid* next, *prev;
/** key to the doq_conn that is the connection */
struct doq_conn_key key;
/** the connection id, byte string */
uint8_t* cid;
/** the length of cid */
size_t cidlen;
};
/**
* DoQ stream, for DNS over QUIC.
*/
struct doq_stream {
/** the rbtree node for the stream, key is the stream_id */
rbnode_type node;
/** the stream id */
int64_t stream_id;
/** if the stream is closed */
uint8_t is_closed;
/** if the query is complete */
uint8_t is_query_complete;
/** the number of bytes read on the stream, up to querylen+2. */
size_t nread;
/** the length of the input query bytes */
size_t inlen;
/** the input bytes */
uint8_t* in;
/** does the stream have an answer to send */
uint8_t is_answer_available;
/** the answer bytes sent, up to outlen+2. */
size_t nwrite;
/** the length of the output answer bytes */
size_t outlen;
/** the output length in network wireformat */
uint16_t outlen_wire;
/** the output packet bytes */
uint8_t* out;
/** if the stream is on the write list */
uint8_t on_write_list;
/** the prev and next on the write list, if on the list */
struct doq_stream* write_prev, *write_next;
};
/** doq application error code that is sent when a stream is closed */
#define DOQ_APP_ERROR_CODE 1
/**
* Create the doq connection.
* @param c: the comm point for the listening doq socket.
* @param paddr: with remote and local address and ifindex for the
* connection destination. This is where packets are sent.
* @param dcid: the dcid, Destination Connection ID.
* @param dcidlen: length of dcid.
* @param version: client chosen version.
* @return new doq connection or NULL on allocation failure.
*/
struct doq_conn* doq_conn_create(struct comm_point* c,
struct doq_pkt_addr* paddr, const uint8_t* dcid, size_t dcidlen,
uint32_t version);
/**
* Delete the doq connection structure.
* @param conn: to delete.
* @param table: with memory size.
*/
void doq_conn_delete(struct doq_conn* conn, struct doq_table* table);
/** compare function of doq_conn */
int doq_conn_cmp(const void* key1, const void* key2);
/** compare function of doq_conid */
int doq_conid_cmp(const void* key1, const void* key2);
/** compare function of doq_timer */
int doq_timer_cmp(const void* key1, const void* key2);
/** compare function of doq_stream */
int doq_stream_cmp(const void* key1, const void* key2);
/** setup the doq_socket server tls context */
int doq_socket_setup_ctx(struct doq_server_socket* doq_socket);
/** setup the doq connection callbacks, and settings. */
int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen);
/** fill a buffer with random data */
void doq_fill_rand(struct ub_randstate* rnd, uint8_t* buf, size_t len);
/** delete a doq_conid */
void doq_conid_delete(struct doq_conid* conid);
/** add a connection id to the doq_conn.
* caller must hold doq_table.conid_lock. */
int doq_conn_associate_conid(struct doq_conn* conn, uint8_t* data,
size_t datalen);
/** remove a connection id from the doq_conn.
* caller must hold doq_table.conid_lock. */
void doq_conn_dissociate_conid(struct doq_conn* conn, const uint8_t* data,
size_t datalen);
/** initial setup to link current connection ids to the doq_conn */
int doq_conn_setup_conids(struct doq_conn* conn);
/** remove the connection ids from the doq_conn.
* caller must hold doq_table.conid_lock. */
void doq_conn_clear_conids(struct doq_conn* conn);
/** find a conid in the doq_conn connection.
* caller must hold table.conid_lock. */
struct doq_conid* doq_conid_find(struct doq_table* doq_table,
const uint8_t* data, size_t datalen);
/** receive a packet for a connection */
int doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr,
struct doq_conn* conn, struct ngtcp2_pkt_info* pi, int* err_retry,
int* err_drop);
/** send packets for a connection */
int doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
int* err_drop);
/** send the close packet for the connection, perhaps again. */
int doq_conn_send_close(struct comm_point* c, struct doq_conn* conn);
/** delete doq stream */
void doq_stream_delete(struct doq_stream* stream);
/** doq read a connection key from repinfo. It is not malloced, but points
* into the repinfo for the dcid. */
void doq_conn_key_from_repinfo(struct doq_conn_key* key,
struct comm_reply* repinfo);
/** doq find a stream in the connection */
struct doq_stream* doq_stream_find(struct doq_conn* conn, int64_t stream_id);
/** doq shutdown the stream. */
int doq_stream_close(struct doq_conn* conn, struct doq_stream* stream,
int send_shutdown);
/** send reply for a connection */
int doq_stream_send_reply(struct doq_conn* conn, struct doq_stream* stream,
struct sldns_buffer* buf);
/** the connection has write interest, wants to write packets */
void doq_conn_write_enable(struct doq_conn* conn);
/** the connection has no write interest, does not want to write packets */
void doq_conn_write_disable(struct doq_conn* conn);
/** set the connection on or off the write list, depending on write interest */
void doq_conn_set_write_list(struct doq_table* table, struct doq_conn* conn);
/** doq remove the connection from the write list */
void doq_conn_write_list_remove(struct doq_table* table,
struct doq_conn* conn);
/** doq get the first conn from the write list, if any, popped from list.
* Locks the conn that is returned. */
struct doq_conn* doq_table_pop_first(struct doq_table* table);
/**
* doq check if the timer for the conn needs to be changed.
* @param conn: connection, caller must hold lock on it.
* @param tv: time value, absolute time, returned.
* @return true if timer needs to be set to tv, false if no change is needed
* to the timer. The timer is already set to the right time in that case.
*/
int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv);
/** doq remove timer from tree */
void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer);
/** doq remove timer from list */
void doq_timer_list_remove(struct doq_table* table, struct doq_timer* timer);
/** doq unset the timer if it was set. */
void doq_timer_unset(struct doq_table* table, struct doq_timer* timer);
/** doq set the timer and add it. */
void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
struct doq_server_socket* worker_doq_socket, struct timeval* tv);
/** doq find a timeout in the timer tree */
struct doq_timer* doq_timer_find_time(struct doq_table* table,
struct timeval* tv);
/** doq handle timeout for a connection. Pass conn locked. Returns false for
* deletion. */
int doq_conn_handle_timeout(struct doq_conn* conn);
/** doq add size to the current quic buffer counter */
void doq_table_quic_size_add(struct doq_table* table, size_t add);
/** doq subtract size from the current quic buffer counter */
void doq_table_quic_size_subtract(struct doq_table* table, size_t subtract);
/** doq check if mem is available for quic. */
int doq_table_quic_size_available(struct doq_table* table,
struct config_file* cfg, size_t mem);
/** doq get the quic size value */
size_t doq_table_quic_size_get(struct doq_table* table);
#endif /* HAVE_NGTCP2 */
char* set_ip_dscp(int socket, int addrfamily, int ds);
/** for debug and profiling purposes only
@@ -459,4 +846,14 @@ char* set_ip_dscp(int socket, int addrfamily, int ds);
*/
void verbose_print_unbound_socket(struct unbound_socket* ub_sock);
/** event callback for testcode/doqclient */
void doq_client_event_cb(int fd, short event, void* arg);
/** timer event callback for testcode/doqclient */
void doq_client_timer_cb(int fd, short event, void* arg);
#ifdef HAVE_NGTCP2
/** get a timestamp in nanoseconds */
ngtcp2_tstamp doq_get_timestamp_nanosec(void);
#endif
#endif /* LISTEN_DNSPORT_H */
+41 -13
View File
@@ -311,7 +311,7 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
struct dns_msg*
mesh_serve_expired_lookup(struct module_qstate* qstate,
struct query_info* lookup_qinfo)
struct query_info* lookup_qinfo, int* is_expired)
{
hashvalue_type h;
struct lruhash_entry* e;
@@ -321,6 +321,7 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
time_t timenow = *qstate->env->now;
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
*is_expired = 0;
/* Lookup cache */
h = query_info_hash(lookup_qinfo, qstate->query_flags);
e = slabhash_lookup(qstate->env->msg_cache, h, lookup_qinfo, 0);
@@ -328,6 +329,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;
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
qstate->env->cfg->serve_expired, qstate->env->scratch);
if(!msg)
@@ -413,6 +415,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
int timeout = mesh->env->cfg->serve_expired?
mesh->env->cfg->serve_expired_client_timeout:0;
struct sldns_buffer* r_buffer = rep->c->buffer;
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
if(rep->c->tcp_req_info) {
r_buffer = rep->c->tcp_req_info->spool_buffer;
}
@@ -425,7 +428,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
return;
}
if(!unique)
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
/* does this create a new reply state? */
if(!s || s->list_select == mesh_no_list) {
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
@@ -453,7 +456,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
struct rbnode_type* n;
#endif
s = mesh_state_create(mesh->env, qinfo, cinfo,
qflags&(BIT_RD|BIT_CD), 0, 0);
mesh_flags, 0, 0);
if(!s) {
log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
@@ -565,6 +568,8 @@ servfail_mem:
edns->opt_list_inplace_cb_out = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
comm_point_send_reply(rep);
if(added)
mesh_state_delete(&s->s);
@@ -583,8 +588,9 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
int was_detached = 0;
int was_noreply = 0;
int added = 0;
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
if(!unique)
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
/* there are no limits on the number of callbacks */
@@ -594,7 +600,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
struct rbnode_type* n;
#endif
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
mesh_flags, 0, 0);
if(!s) {
return 0;
}
@@ -673,8 +679,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
int rpz_passthru)
{
/* Explicitly set the BIT_RD regardless of the client's flags. This is
* for a prefetch query (no client attached) but it needs to be treated
* as a recursion query. */
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
qflags&(BIT_RD|BIT_CD), 0, 0);
mesh_flags, 0, 0);
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
#endif
@@ -694,8 +704,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
return;
}
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
if(!s) {
log_err("prefetch mesh_state_create: out of memory");
return;
@@ -756,14 +765,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
#endif
/* Explicitly set the BIT_RD regardless of the client's flags. This is
* for a prefetch query (no client attached) but it needs to be treated
* as a recursion query. */
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
if(!mesh_make_new_space(mesh, NULL)) {
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
mesh->stats_dropped ++;
return;
}
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
if(!s) {
log_err("prefetch_subnet mesh_state_create: out of memory");
return;
@@ -966,6 +978,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
for(; rep; rep=rep->next) {
infra_wait_limit_dec(mesh->env->infra_cache,
&rep->query_reply, mesh->env->cfg);
if(rep->query_reply.c->use_h2)
http2_stream_remove_mesh_state(rep->h2_stream);
comm_point_drop_reply(&rep->query_reply);
log_assert(mesh->num_reply_addrs > 0);
mesh->num_reply_addrs--;
@@ -1522,6 +1536,8 @@ void mesh_query_done(struct mesh_state* mstate)
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->stats_dropped++;
@@ -1554,6 +1570,9 @@ void mesh_query_done(struct mesh_state* mstate)
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;
} else {
@@ -1568,6 +1587,8 @@ void mesh_query_done(struct mesh_state* mstate)
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
r_buffer = NULL;
}
/* mesh_send_reply removed mesh state from
* http2_stream. */
prev = r;
prev_buffer = r_buffer;
}
@@ -1720,6 +1741,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
return 0;
if(rep->c->use_h2)
r->h2_stream = rep->c->h2_stream;
else r->h2_stream = NULL;
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
* and can be different for different original queries (even if the
@@ -2156,6 +2178,7 @@ mesh_serve_expired_callback(void* arg)
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
int i = 0;
int is_expired;
if(!qstate->serve_expired_data) return;
verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
comm_timer_delete(qstate->serve_expired_data->timer);
@@ -2173,7 +2196,7 @@ mesh_serve_expired_callback(void* arg)
fptr_ok(fptr_whitelist_serve_expired_lookup(
qstate->serve_expired_data->get_cached_answer));
msg = (*qstate->serve_expired_data->get_cached_answer)(qstate,
lookup_qinfo);
lookup_qinfo, &is_expired);
if(!msg)
return;
/* Reset these in case we pass a second time from here. */
@@ -2243,6 +2266,8 @@ mesh_serve_expired_callback(void* arg)
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->stats_dropped++;
@@ -2263,8 +2288,10 @@ mesh_serve_expired_callback(void* arg)
/* Add EDE Stale Answer (RCF8914). Ignore global ede as this is
* warning instead of an error */
if (r->edns.edns_present && qstate->env->cfg->ede_serve_expired &&
qstate->env->cfg->ede) {
if(r->edns.edns_present &&
qstate->env->cfg->ede_serve_expired &&
qstate->env->cfg->ede &&
is_expired) {
edns_opt_list_append_ede(&r->edns.opt_list_out,
mstate->s.region, LDNS_EDE_STALE_ANSWER, NULL);
}
@@ -2276,6 +2303,7 @@ mesh_serve_expired_callback(void* arg)
r, r_buffer, prev, prev_buffer);
if(r->query_reply.c->tcp_req_info)
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
/* mesh_send_reply removed mesh state from http2_stream. */
infra_wait_limit_dec(mstate->s.env->infra_cache,
&r->query_reply, mstate->s.env->cfg);
prev = r;
+2 -1
View File
@@ -673,11 +673,12 @@ void mesh_serve_expired_callback(void* arg);
* the same behavior as when replying from cache.
* @param qstate: the module qstate.
* @param lookup_qinfo: the query info to look for in the cache.
* @param is_expired: set if the cached answer is expired.
* @return dns_msg if a cached answer was found, otherwise NULL.
*/
struct dns_msg*
mesh_serve_expired_lookup(struct module_qstate* qstate,
struct query_info* lookup_qinfo);
struct query_info* lookup_qinfo, int* is_expired);
/**
* See if the mesh has space for more queries. You can allocate queries
+69 -9
View File
@@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
stack->mod = NULL;
}
void
modstack_free(struct module_stack* stack)
{
if(!stack)
return;
stack->num = 0;
free(stack->mod);
stack->mod = NULL;
}
int
modstack_config(struct module_stack* stack, const char* module_conf)
{
@@ -222,18 +232,59 @@ module_func_block* module_factory(const char** str)
return NULL;
}
int
modstack_setup(struct module_stack* stack, const char* module_conf,
int
modstack_call_startup(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
int i;
if(stack->num != 0)
modstack_desetup(stack, env);
fatal_exit("unexpected already initialised modules");
/* fixed setup of the modules */
if(!modstack_config(stack, module_conf)) {
return 0;
}
for(i=0; i<stack->num; i++) {
if(stack->mod[i]->startup == NULL)
continue;
verbose(VERB_OPS, "startup module %d: %s",
i, stack->mod[i]->name);
fptr_ok(fptr_whitelist_mod_startup(stack->mod[i]->startup));
if(!(*stack->mod[i]->startup)(env, i)) {
log_err("module startup for module %s failed",
stack->mod[i]->name);
return 0;
}
}
return 1;
}
int
modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
while(*module_conf && isspace((unsigned char)*module_conf))
module_conf++;
if(strncmp(stack->mod[i]->name, module_conf,
strlen(stack->mod[i]->name))) {
if(stack->mod[i]->startup || stack->mod[i]->destartup) {
log_err("changed module ordering during reload not supported, for module that needs startup");
return 0;
} else {
changed = 1;
}
}
module_conf += strlen(stack->mod[i]->name);
}
if(changed) {
modstack_free(stack);
if(!modstack_config(stack, module_conf)) {
return 0;
}
}
for(i=0; i<stack->num; i++) {
verbose(VERB_OPS, "init module %d: %s",
i, stack->mod[i]->name);
@@ -247,20 +298,29 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
return 1;
}
void
modstack_desetup(struct module_stack* stack, struct module_env* env)
void
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
{
int i;
for(i=0; i<stack->num; i++) {
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
(*stack->mod[i]->deinit)(env, i);
}
stack->num = 0;
free(stack->mod);
stack->mod = NULL;
}
int
void
modstack_call_destartup(struct module_stack* stack, struct module_env* env)
{
int i;
for(i=0; i<stack->num; i++) {
if(stack->mod[i]->destartup == NULL)
continue;
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
(*stack->mod[i]->destartup)(env, i);
}
}
int
modstack_find(struct module_stack* stack, const char* name)
{
int i;
+31 -7
View File
@@ -60,6 +60,23 @@ struct module_stack {
*/
void modstack_init(struct module_stack* stack);
/**
* Free the stack of modules
* @param stack: stack that frees up memory.
*/
void modstack_free(struct module_stack* stack);
/**
* Initialises modules and assignes ids. Calls module_startup().
* @param stack: Expected empty, filled according to module_conf
* @param module_conf: string what modules to initialize
* @param env: module environment which is inited by the modules.
* environment should have a superalloc, cfg,
* @return on false a module init failed.
*/
int modstack_call_startup(struct module_stack* stack, const char* module_conf,
struct module_env* env);
/**
* Read config file module settings and set up the modfunc block
* @param stack: the stack of modules (empty before call).
@@ -83,24 +100,31 @@ struct module_func_block* module_factory(const char** str);
const char** module_list_avail(void);
/**
* Setup modules. Assigns ids and calls module_init.
* @param stack: if not empty beforehand, it will be desetup()ed.
* It is then modstack_configged().
* @param module_conf: string what modules to insert.
* Init modules. Calls module_init().
* @param stack: It is modstack_setupped().
* @param module_conf: module ordering to check against the ordering in stack.
* fails on changed ordering.
* @param env: module environment which is inited by the modules.
* environment should have a superalloc, cfg,
* env.need_to_validate is set by the modules.
* @return on false a module init failed.
*/
int modstack_setup(struct module_stack* stack, const char* module_conf,
int modstack_call_init(struct module_stack* stack, const char* module_conf,
struct module_env* env);
/**
* Desetup the modules, deinit, delete.
* Deinit the modules.
* @param stack: made empty.
* @param env: module env for module deinit() calls.
*/
void modstack_desetup(struct module_stack* stack, struct module_env* env);
void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
/**
* Destartup the modules, close, delete.
* @param stack: made empty.
* @param env: module env for module destartup() calls.
*/
void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
/**
* Find index of module by name.
+4 -1
View File
@@ -3466,7 +3466,10 @@ outnet_serviced_query(struct outside_network* outnet,
timenow = *env->now;
if(!infra_ratelimit_inc(env->infra_cache, zone,
zonelen, timenow, env->cfg->ratelimit_backoff,
&qstate->qinfo, qstate->reply)) {
&qstate->qinfo,
qstate->mesh_info->reply_list
?&qstate->mesh_info->reply_list->query_reply
:NULL)) {
/* Can we pass through with slip factor? */
if(env->cfg->ratelimit_factor == 0 ||
ub_random_max(env->rnd,
+37 -6
View File
@@ -242,10 +242,14 @@ rpz_action_to_localzone_type(enum rpz_action a)
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
case RPZ_DROP_ACTION: return local_zone_always_deny;
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
case RPZ_LOCAL_DATA_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
case RPZ_INVALID_ACTION: /* fallthrough */
case RPZ_INVALID_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
default: return local_zone_invalid;
}
}
@@ -258,10 +262,14 @@ rpz_action_to_respip_action(enum rpz_action a)
case RPZ_NODATA_ACTION: return respip_always_nodata;
case RPZ_DROP_ACTION: return respip_always_deny;
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
case RPZ_LOCAL_DATA_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
case RPZ_INVALID_ACTION: /* fallthrough */
case RPZ_INVALID_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
default: return respip_invalid;
}
}
@@ -276,7 +284,9 @@ localzone_type_to_rpz_action(enum localzone_type lzt)
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
case local_zone_invalid: /* fallthrough */
case local_zone_invalid:
ATTR_FALLTHROUGH
/* fallthrough */
default: return RPZ_INVALID_ACTION;
}
}
@@ -291,7 +301,9 @@ respip_action_to_rpz_action(enum respip_action a)
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
case respip_invalid: /* fallthrough */
case respip_invalid:
ATTR_FALLTHROUGH
/* fallthrough */
default: return RPZ_INVALID_ACTION;
}
}
@@ -1957,6 +1969,7 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
0, /* an */
0, /* ns */
0, /* ar */
@@ -1987,6 +2000,7 @@ rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
0, /* an */
0, /* ns */
0, /* ar */
@@ -2019,6 +2033,7 @@ rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qs
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
1, /* an */
0, /* ns */
0, /* ar */
@@ -2164,6 +2179,7 @@ rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
1, /* an */
0, /* ns */
0, /* ar */
@@ -2276,15 +2292,18 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) {
verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data");
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
goto done;
}
switch(action) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2294,11 +2313,13 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
@@ -2306,6 +2327,7 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
ms->rpz_applied = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
@@ -2340,9 +2362,11 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
switch(action) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2352,11 +2376,13 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
@@ -2364,6 +2390,7 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
ms->rpz_applied = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'",
@@ -2567,9 +2594,11 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
switch(localzone_type_to_rpz_action(lzt)) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2579,11 +2608,13 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
+3 -3
View File
@@ -106,7 +106,7 @@ ssize_t sldns_bget_token(struct sldns_buffer *b, char *token, const char *delim,
* \param[in] k_del keyword delimiter
* \param[out] data the data found
* \param[in] d_del the data delimiter
* \param[in] data_limit maximum size the the data buffer
* \param[in] data_limit maximum size the data buffer
* \return the number of character read
*/
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
@@ -119,7 +119,7 @@ ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del,
* \param[in] k_del keyword delimiter
* \param[out] data the data found
* \param[in] d_del the data delimiter
* \param[in] data_limit maximum size the the data buffer
* \param[in] data_limit maximum size the data buffer
* \param[in] line_nr pointer to an integer containing the current line number (for
debugging purposes)
* \return the number of character read
@@ -134,7 +134,7 @@ ssize_t sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_de
* \param[in] k_del keyword delimiter
* \param[out] data the data found
* \param[in] d_del the data delimiter
* \param[in] data_limit maximum size the the data buffer
* \param[in] data_limit maximum size the data buffer
* \return the number of character read
*/
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
+9
View File
@@ -436,11 +436,13 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
/* ........ ........ ....4444 4....... ........ */
c = src[3] >> 7 ;
ATTR_FALLTHROUGH
/* fallthrough */
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
/* ........ .......3 3333.... ........ ........ */
c = src[2] >> 4 ;
ATTR_FALLTHROUGH
/* fallthrough */
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
@@ -449,6 +451,7 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
/* .....111 11...... ........ ........ ........ */
c = src[1] >> 6 ;
ATTR_FALLTHROUGH
/* fallthrough */
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
@@ -460,11 +463,14 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
switch (src_sz) {
case 1: dst[2] = '=';
dst[3] = '=';
ATTR_FALLTHROUGH
/* fallthrough */
case 2: dst[4] = '=';
ATTR_FALLTHROUGH
/* fallthrough */
case 3: dst[5] = '=';
dst[6] = '=';
ATTR_FALLTHROUGH
/* fallthrough */
case 4: dst[7] = '=';
}
@@ -577,17 +583,20 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
/* ........ ........ ........ .55555.. ........ */
/* ........ ........ ....4444 4....... ........ */
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
ATTR_FALLTHROUGH
/* fallthrough */
case 5: /* ........ ........ ....4444 4....... ........ */
/* ........ .......3 3333.... ........ ........ */
dst[2] = buf[3] << 4 | buf[4] >> 1;
ATTR_FALLTHROUGH
/* fallthrough */
case 4: /* ........ .......3 3333.... ........ ........ */
/* ........ ..22222. ........ ........ ........ */
/* .....111 11...... ........ ........ ........ */
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
ATTR_FALLTHROUGH
/* fallthrough */
case 2: /* .....111 11...... ........ ........ ........ */
+5
View File
@@ -470,6 +470,11 @@ enum sldns_enum_ede_code
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
LDNS_EDE_NETWORK_ERROR = 23,
LDNS_EDE_INVALID_DATA = 24,
LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
LDNS_EDE_TOO_EARLY = 26,
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
LDNS_EDE_BADPROXYPOLICY = 28,
LDNS_EDE_SYNTHESIZED = 29
};
typedef enum sldns_enum_ede_code sldns_ede_code;
+6
View File
@@ -228,6 +228,11 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
{ LDNS_EDE_INVALID_DATA, "Invalid Data" },
{ LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" },
{ LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" },
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
{ 0, NULL}
};
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
@@ -1236,6 +1241,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
break;
case SVCB_KEY_DOHPATH:
ATTR_FALLTHROUGH
/* fallthrough */
default:
r = sldns_str_print(s, slen, "=\"");
+8 -2
View File
@@ -151,7 +151,7 @@
#define HTTPS_PORT 443
#ifdef USE_WINSOCK
/* sneakily reuse the the wsa_strerror function, on windows */
/* sneakily reuse the wsa_strerror function, on windows */
char* wsa_strerror(int err);
#endif
@@ -183,7 +183,9 @@ static const char DS_TRUST_ANCHOR[] =
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
* because the makedist script greps on the source here */
/* anchor 20326 is from 2017 */
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"
/* anchor 38696 is from 2024 */
". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16\n";
/** verbosity for this application */
static int verb = 0;
@@ -805,7 +807,11 @@ TLS_initiate(SSL_CTX* sslctx, int fd, const char* urlname, int use_sni)
}
/* wants to be called again */
}
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
x = SSL_get1_peer_certificate(ssl);
#else
x = SSL_get_peer_certificate(ssl);
#endif
if(!x) {
if(verb) printf("Server presented no peer certificate\n");
SSL_free(ssl);
+6 -3
View File
@@ -140,10 +140,13 @@ check_mod(struct config_file* cfg, struct module_func_block* fb)
fatal_exit("out of memory");
if(!edns_known_options_init(&env))
fatal_exit("out of memory");
if(!(*fb->init)(&env, 0)) {
fatal_exit("bad config for %s module", fb->name);
}
if(fb->startup && !(*fb->startup)(&env, 0))
fatal_exit("bad config during startup for %s module", fb->name);
if(!(*fb->init)(&env, 0))
fatal_exit("bad config during init for %s module", fb->name);
(*fb->deinit)(&env, 0);
if(fb->destartup)
(*fb->destartup)(&env, 0);
sldns_buffer_free(env.scratch_buffer);
regional_destroy(env.scratch);
edns_known_options_delete(&env);
+1 -1
View File
@@ -104,7 +104,7 @@ while getopts 'd:hr' arg; do
done
shift $((OPTIND - 1))
if ! openssl >/dev/null 2>&1; then
if ! openssl version </dev/null >/dev/null 2>&1; then
echo "$0 requires openssl to be installed for keys/certificates generation." >&2
exit 1
fi
+14
View File
@@ -186,6 +186,10 @@ usage(void)
printf(" rpz_enable zone Enable the RPZ zone if it had previously\n");
printf(" been disabled\n");
printf(" rpz_disable zone Disable the RPZ zone\n");
printf(" add_cookie_secret <secret> add (or replace) a new cookie secret <secret>\n");
printf(" drop_cookie_secret drop a staging cookie secret\n");
printf(" activate_cookie_secret make a staging cookie secret active\n");
printf(" print_cookie_secrets show all cookie secrets with their status\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
@@ -289,6 +293,9 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
PR_LL("mem.streamwait", s->svr.mem_stream_wait);
PR_LL("mem.http.query_buffer", s->svr.mem_http2_query_buffer);
PR_LL("mem.http.response_buffer", s->svr.mem_http2_response_buffer);
#ifdef HAVE_NGTCP2
PR_LL("mem.quic", s->svr.mem_quic);
#endif
}
/** print histogram */
@@ -355,6 +362,9 @@ static void print_extended(struct ub_stats_info* s, int inhibit_zero)
PR_UL("num.query.tls_resume", s->svr.qtls_resume);
PR_UL("num.query.ipv6", s->svr.qipv6);
PR_UL("num.query.https", s->svr.qhttps);
#ifdef HAVE_NGTCP2
PR_UL("num.query.quic", s->svr.qquic);
#endif
/* flags */
PR_UL("num.query.flags.QR", s->svr.qbit_QR);
@@ -759,7 +769,11 @@ setup_ssl(SSL_CTX* ctx, int fd)
/* check authenticity of server */
if(SSL_get_verify_result(ssl) != X509_V_OK)
ssl_err("SSL verification failed");
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
x = SSL_get1_peer_certificate(ssl);
#else
x = SSL_get_peer_certificate(ssl);
#endif
if(!x)
ssl_err("Server presented no peer certificate");
X509_free(x);
+6
View File
@@ -50,6 +50,8 @@
#undef calloc
#undef free
#undef realloc
#undef reallocarray
#undef strdup
#endif
#ifdef UNBOUND_ALLOC_LITE
#undef malloc
@@ -492,7 +494,11 @@ int main(int argc, char* argv[])
if(strcmp(use_syslog, "yes") == 0) /* disable use-syslog */
check_ub_res(ub_ctx_set_option(ctx,
"use-syslog:", "no"));
#ifdef UNBOUND_ALLOC_STATS
unbound_stat_free_log(use_syslog, __FILE__, __LINE__, __func__);
#else
free(use_syslog);
#endif
}
argc -= optind;
argv += optind;
+16
View File
@@ -255,3 +255,19 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
+8 -6
View File
@@ -2,17 +2,19 @@
# Copyright 2015, Sami Kerola, CloudFlare.
# BSD licensed.
AC_ARG_ENABLE([systemd],
[AS_HELP_STRING([--enable-systemd], [compile with systemd support])],
[AS_HELP_STRING([--enable-systemd], [compile with systemd support (requires libsystemd, pkg-config)])],
[], [enable_systemd=no])
have_systemd=no
AS_IF([test "x$enable_systemd" != xno], [
ifdef([PKG_CHECK_MODULES], [
if test -n "$PKG_CONFIG"; then
dnl systemd v209 or newer
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [have_systemd=no])
have_systemd=no
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [])
dnl old systemd library
AS_IF([test "x$have_systemd" != "xyes"], [
have_systemd_daemon=no
PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
[have_systemd_daemon=yes], [have_systemd_daemon=no])
[have_systemd_daemon=yes], [])
AS_IF([test "x$have_systemd_daemon" = "xyes"],
[have_systemd=yes])
])
@@ -24,8 +26,8 @@ AS_IF([test "x$enable_systemd" != xno], [
LIBS="$LIBS $SYSTEMD_LIBS"
]
)
], [
else
AC_MSG_ERROR([systemd enabled but need pkg-config to configure for it])
])
fi
])
AM_CONDITIONAL([USE_SYSTEMD], [test "x$have_systemd" = xyes])
+18 -2
View File
@@ -68,6 +68,8 @@ static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS];
int check_locking_order = 1;
/** the pid of this runset, reasonably unique. */
static pid_t check_lock_pid;
/** the name of the output file */
static const char* output_name = "ublocktrace";
/**
* Should checklocks print a trace of the lock and unlock calls.
* It uses fprintf for that because the log function uses a lock and that
@@ -142,7 +144,8 @@ acquire_locklock(struct checked_lock* lock,
/** add protected region */
void
lock_protect(void *p, void* area, size_t size)
lock_protect_place(void* p, void* area, size_t size, const char* def_func,
const char* def_file, int def_line, const char* def_area)
{
struct checked_lock* lock = *(struct checked_lock**)p;
struct protected_area* e = (struct protected_area*)malloc(
@@ -151,6 +154,10 @@ lock_protect(void *p, void* area, size_t size)
fatal_exit("lock_protect: out of memory");
e->region = area;
e->size = size;
e->def_func = def_func;
e->def_file = def_file;
e->def_line = def_line;
e->def_area = def_area;
e->hold = malloc(size);
if(!e->hold)
fatal_exit("lock_protect: out of memory");
@@ -203,6 +210,9 @@ prot_check(struct checked_lock* lock,
if(memcmp(p->hold, p->region, p->size) != 0) {
log_hex("memory prev", p->hold, p->size);
log_hex("memory here", p->region, p->size);
log_err("lock_protect on %s %s:%d %s failed",
p->def_func, p->def_file, p->def_line,
p->def_area);
lock_error(lock, func, file, line,
"protected area modified");
}
@@ -675,13 +685,19 @@ checklock_unlock(enum check_lock_type type, struct checked_lock* lock,
}
}
void
checklock_set_output_name(const char* name)
{
output_name = name;
}
/** open order info debug file, thr->num must be valid */
static void
open_lockorder(struct thr_check* thr)
{
char buf[24];
time_t t;
snprintf(buf, sizeof(buf), "ublocktrace.%d", thr->num);
snprintf(buf, sizeof(buf), "%s.%d", output_name, thr->num);
thr->order_info = fopen(buf, "w");
if(!thr->order_info)
fatal_exit("could not open %s: %s", buf, strerror(errno));
+23 -1
View File
@@ -90,6 +90,14 @@ struct protected_area {
void* hold;
/** next protected area in list */
struct protected_area* next;
/** the place where the lock_protect is made, at init. */
const char* def_func;
/** the file where the lock_protect is made */
const char* def_file;
/** the line number where the lock_protect is made */
int def_line;
/** the text string for the area that is protected, at init call. */
const char* def_area;
};
/**
@@ -181,12 +189,19 @@ struct checked_lock {
* It demangles the lock itself (struct checked_lock**).
* @param area: ptr to mem.
* @param size: length of area.
* @param def_func: function where the lock_protect() line is.
* @param def_file: file where the lock_protect() line is.
* @param def_line: line where the lock_protect() line is.
* @param def_area: area string
* You can call it multiple times with the same lock to give several areas.
* Call it when you are done initializing the area, since it will be copied
* at this time and protected right away against unauthorised changes until
* the next lock() call is done.
*/
void lock_protect(void* lock, void* area, size_t size);
void lock_protect_place(void* lock, void* area, size_t size,
const char* def_func, const char* def_file, int def_line,
const char* def_area);
#define lock_protect(lock, area, size) lock_protect_place(lock, area, size, __func__, __FILE__, __LINE__, #area)
/**
* Remove protected area from lock.
@@ -203,6 +218,13 @@ void lock_unprotect(void* lock, void* area);
*/
size_t lock_get_mem(void* lock);
/**
* Set the output name, prefix, of the lock check output file(s).
* Call it before the checklock_start or thread creation. Pass a fixed string.
* @param name: string to use for output data file names.
*/
void checklock_set_output_name(const char* name);
/**
* Initialise checklock. Sets up internal debug structures.
*/
+2701
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -939,6 +939,11 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
int ATTR_UNUSED(http_notls),
struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
struct doq_table* ATTR_UNUSED(table),
struct ub_randstate* ATTR_UNUSED(rnd),
const char* ATTR_UNUSED(ssl_service_key),
const char* ATTR_UNUSED(ssl_service_pem),
struct config_file* ATTR_UNUSED(cfg),
comm_point_callback_type* cb, void *cb_arg)
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
@@ -1655,6 +1660,12 @@ void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
timeval_add(&t->tv, &t->runtime->now_tv);
}
int comm_timer_is_set(struct comm_timer* timer)
{
struct fake_timer* t = (struct fake_timer*)timer;
return t->enabled;
}
void comm_timer_delete(struct comm_timer* timer)
{
struct fake_timer* t = (struct fake_timer*)timer;
@@ -1978,4 +1989,8 @@ void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
{
}
void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream))
{
}
/*********** End of Dummy routines ***********/
+11
View File
@@ -127,6 +127,7 @@ dir=$name.$$
result=result.$name
done=.done-$name
skip=.skip-$name
asan_text="SUMMARY: AddressSanitizer"
success="no"
if test -x "`which bash`"; then
shell="bash"
@@ -200,6 +201,16 @@ if test -f $name.post -a ! -f ../$skip; then
echo "Warning: $name.post did not exit successfully"
fi
fi
# Check if there were any AddressSanitizer errors
# if compiled with -fsanitize=address
if grep "$asan_text" $result >/dev/null 2>&1; then
if test -f ../$done; then
rm ../$done
fi
echo "$name: FAILED (AddressSanitizer)" >> $result
echo "$name: FAILED (AddressSanitizer)"
success="no"
fi
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
mv $result ..
+3 -3
View File
@@ -220,7 +220,7 @@ perfsetup(struct perfinfo* info)
#endif
signal(SIGTERM, perf_sigh) == SIG_ERR)
fatal_exit("could not bind to signal");
info->io = (struct perfio*)calloc(sizeof(struct perfio), info->io_num);
info->io = (struct perfio*)calloc(info->io_num, sizeof(struct perfio));
if(!info->io) fatal_exit("out of memory");
#ifndef S_SPLINT_S
FD_ZERO(&info->rset);
@@ -501,8 +501,8 @@ qlist_grow_capacity(struct perfinfo* info)
{
size_t newcap = (size_t)((info->qlist_capacity==0)?16:
info->qlist_capacity*2);
uint8_t** d = (uint8_t**)calloc(sizeof(uint8_t*), newcap);
size_t* l = (size_t*)calloc(sizeof(size_t), newcap);
uint8_t** d = (uint8_t**)calloc(newcap, sizeof(uint8_t*));
size_t* l = (size_t*)calloc(newcap, sizeof(size_t));
if(!d || !l) fatal_exit("out of memory");
if(info->qlist_data && info->qlist_capacity)
memcpy(d, info->qlist_data, sizeof(uint8_t*)*
+1 -1
View File
@@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert)
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
if (!SSL_CTX_set_ecdh_auto(ctx,1))
if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
#elif defined(USE_ECDSA)
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
if(1) {
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
if (!ecdh) {
-1
View File
@@ -45,7 +45,6 @@
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"
+4
View File
@@ -471,7 +471,11 @@ send_em(const char* svr, const char* pp2_client, int udp, int usessl,
}
}
if(1) {
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
X509* x = SSL_get1_peer_certificate(ssl);
#else
X509* x = SSL_get_peer_certificate(ssl);
#endif
if(!x) printf("SSL: no peer certificate\n");
else {
X509_print_fp(stdout, x);
+50 -18
View File
@@ -72,23 +72,6 @@ int daemon_main(int argc, char* argv[]);
/** config files (removed at exit) */
static struct config_strlist* cfgfiles = NULL;
#ifdef UNBOUND_ALLOC_STATS
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
char* unbound_stat_strdup_log(char* s, const char* file, int line,
const char* func);
char* unbound_stat_strdup_log(char* s, const char* file, int line,
const char* func) {
char* result;
size_t len;
if(!s) return NULL;
len = strlen(s);
log_info("%s:%d %s strdup(%u)", file, line, func, (unsigned)len+1);
result = unbound_stat_malloc(len+1);
memmove(result, s, len+1);
return result;
}
#endif /* UNBOUND_ALLOC_STATS */
/** give commandline usage for testbound. */
static void
testbound_usage(void)
@@ -519,7 +502,7 @@ struct listen_port* daemon_remote_open_ports(struct config_file*
struct daemon_remote* daemon_remote_create(struct config_file* ATTR_UNUSED(cfg))
{
return (struct daemon_remote*)calloc(1,1);
return (struct daemon_remote*)calloc(1, sizeof(struct daemon_remote));
}
void daemon_remote_delete(struct daemon_remote* rc)
@@ -617,3 +600,52 @@ void listen_desetup_locks(void)
{
/* nothing */
}
#ifdef HAVE_NGTCP2
void comm_point_doq_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
void* ATTR_UNUSED(arg))
{
/* nothing */
}
int doq_conn_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
{
return 0;
}
int doq_conid_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
{
return 0;
}
int doq_timer_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
{
return 0;
}
int doq_stream_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
{
return 0;
}
struct doq_table* doq_table_create(struct config_file* ATTR_UNUSED(cfg),
struct ub_randstate* ATTR_UNUSED(rnd))
{
return calloc(1, sizeof(struct doq_table));
}
void doq_table_delete(struct doq_table* table)
{
free(table);
}
void doq_timer_cb(void* ATTR_UNUSED(arg))
{
/* nothing */
}
size_t doq_table_quic_size_get(struct doq_table* ATTR_UNUSED(table))
{
return 0;
}
#endif
+84
View File
@@ -0,0 +1,84 @@
/*
* testcode/unitdoq.c - unit test for doq routines.
*
* Copyright (c) 2022, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file
* Calls doq related unit tests. Exits with code 1 on a failure.
*/
#include "config.h"
#ifdef HAVE_NGTCP2
#include "util/netevent.h"
#include "services/listen_dnsport.h"
#include "testcode/unitmain.h"
/** check the size of a connection for doq */
static void
doq_size_conn_check()
{
/* Printout the size of one doq connection, in memory usage.
* A connection with a couple cids, of type doq_conid, and
* it has one stream, and that has a query and an answer. */
size_t answer_size = 233; /* size of www.nlnetlabs.nl minimal answer
with dnssec and one A record. The unsigned answer is 176 with
additional data, 61 bytes minimal response one A record. */
size_t query_size = 45; /* size of query for www.nlnetlabs.nl, with
an EDNS record with DO flag. */
size_t conn_size = sizeof(struct doq_conn);
size_t conid_size = sizeof(struct doq_conid);
size_t stream_size = sizeof(struct doq_stream);
conn_size += 16; /* DCID len in the conn key */
conn_size += 0; /* the size of the ngtcp2_conn */
conn_size += 0; /* the size of the SSL record */
conn_size += 0; /* size of the close pkt,
but we do not count it here. Only if the conn gets closed. */
conid_size += 16; /* the dcid of the conn key */
conid_size += 16; /* the cid */
stream_size += query_size; /* size of in buffer */
stream_size += answer_size; /* size of out buffer */
printf("doq connection size %u bytes\n", (unsigned)(conn_size +
conid_size*3 + stream_size));
}
void doq_test(void)
{
unit_show_feature("doq");
doq_size_conn_check();
}
#endif /* HAVE_NGTCP2 */
+5 -2
View File
@@ -1117,7 +1117,7 @@ static void edns_ede_encode_encodedecode(struct query_info* qinfo,
sldns_buffer_skip(pkt, 2 + 2);
/* decode */
unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0,
region) == 0);
region, NULL) == 0);
}
static void edns_ede_encode_check(struct edns_data* edns, int* found_ede,
@@ -1232,7 +1232,7 @@ static void edns_ede_answer_encode_test(void)
unit_assert(region);
rep = construct_reply_info_base(region,
LDNS_RCODE_NOERROR | BIT_QR, 1,
3600, 3600, 3600,
3600, 3600, 3600, 0,
0, 0, 0, 0,
sec_status_unchecked, LDNS_EDE_NONE);
unit_assert(rep);
@@ -1432,6 +1432,9 @@ main(int argc, char* argv[])
#ifdef CLIENT_SUBNET
ecs_test();
#endif /* CLIENT_SUBNET */
#ifdef HAVE_NGTCP2
doq_test();
#endif /* HAVE_NGTCP2 */
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
+2
View File
@@ -84,5 +84,7 @@ void authzone_test(void);
void zonemd_test(void);
/** unit test for tcp_reuse functions */
void tcpreuse_test(void);
/** unit test for doq functions */
void doq_test(void);
#endif /* TESTCODE_UNITMAIN_H */
+4 -2
View File
@@ -178,6 +178,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
struct query_info* qinfo)
{
enum sec_status sec;
char reasonbuf[256];
char* reason = NULL;
uint8_t sigalg[ALGO_NEEDS_MAX+1];
int verified = 0;
@@ -188,8 +189,9 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
}
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
/* ok to give null as qstate here, won't be used for answer section. */
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
LDNS_SECTION_ANSWER, NULL, &verified);
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
NULL, LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf,
sizeof(reasonbuf));
if(vsig) {
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
reason?reason:"");
+11 -7
View File
@@ -108,7 +108,7 @@ static void zonemd_generate_test(const char* zname, char* zfile,
digestdup = strdup(digest);
unit_assert(digestdup);
for(i=0; i<strlen(digestdup); i++) {
digestdup[i] = toupper(digestdup[i]);
digestdup[i] = toupper((unsigned char)digestdup[i]);
}
if(verbosity >= VERB_ALGO) {
char zname[255+1];
@@ -165,9 +165,10 @@ static void zonemd_generate_tests(void)
1, 1, "1291b78ddf7669b1a39d014d87626b709b55774c5d7d58fadc556439889a10eaf6f11d615900a4f996bd46279514e473");
/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
* from section A.5 */
* from section A.5.
* Adjusted with renumbered B.root. */
zonemd_generate_test("root-servers.net", SRCDIRSTR "/testdata/zonemd.example_a5.zone",
1, 1, "f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a978a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79");
1, 1, "5a9521d88984ee123d9626191e2a327a43a16fd4339dd4ecc13d8672d5bae527d066d33645e35778677800005247d199");
}
/** test the zonemd check routine */
@@ -256,7 +257,6 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
struct auth_zone* z;
/* setup test harness */
memset(&mods, 0, sizeof(mods));
memset(&env, 0, sizeof(env));
env.scratch = regional_create();
if(!env.scratch)
@@ -288,8 +288,10 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
if(!env.auth_zones)
fatal_exit("out of memory");
modstack_init(&mods);
if(!modstack_setup(&mods, env.cfg->module_conf, &env))
fatal_exit("could not modstack_setup");
if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
fatal_exit("could not modstack_startup");
if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
fatal_exit("could not modstack_call_init");
env.mesh = mesh_create(&mods, &env);
if(!env.mesh)
fatal_exit("out of memory");
@@ -327,7 +329,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
/* desetup test harness */
mesh_delete(env.mesh);
modstack_desetup(&mods, &env);
modstack_call_deinit(&mods, &env);
modstack_call_destartup(&mods, &env);
modstack_free(&mods);
auth_zones_delete(env.auth_zones);
anchors_delete(env.anchors);
config_delete(env.cfg);
+55 -43
View File
@@ -7,57 +7,69 @@
. ../common.sh
PRE="../.."
get_make
(cd $PRE ; $MAKE unittest; $MAKE lock-verify)
(cd $PRE ; $MAKE unittest; $MAKE lock-verify; $MAKE unbound-dnstap-socket)
if test -f $PRE/unbound_do_valgrind_in_test; then
do_valgrind=yes
DO_VALGRIND=yes
else
do_valgrind=no
DO_VALGRIND=no
fi
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
if test $do_valgrind = "yes"; then
echo "valgrind yes"
echo
tmpout=/tmp/tmpout.$$
if (cd $PRE; valgrind $VALGRIND_FLAGS ./unittest >$tmpout 2>&1); then
echo "unit test worked."
# Run a unit test; it exits on failure
# $1: the command to start the unit test
run_unittest () {
unit_cmd=$1
echo "> testing $unit_cmd"
if test $DO_VALGRIND = "yes"; then
echo "valgrind yes"
echo
tmpout=/tmp/tmpout.$$
if (cd $PRE; valgrind $VALGRIND_FLAGS ./$unit_cmd >$tmpout 2>&1); then
echo "unit test worked."
else
echo "unit test failed."
exit 1
fi
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
: # clean
else
cat $tmpout
echo "Memory leaked in unit test"
grep "in use at exit" $tmpout
exit 1
fi
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
: # clean
else
cat $tmpout
echo "Errors in unit test"
grep "ERROR SUMMARY" $tmpout
exit 1
fi
rm -f $tmpout
else
echo "unit test failed."
exit 1
# without valgrind
if (cd $PRE; ./$unit_cmd); then
echo "unit test worked."
else
echo "unit test failed."
exit 1
fi
fi
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
: # clean
else
cat $tmpout
echo "Memory leaked in unittest"
grep "in use at exit" $tmpout
exit 1
fi
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
: # clean
else
cat $tmpout
echo "Errors in unittest"
grep "ERROR SUMMARY" $tmpout
exit 1
fi
rm -f $tmpout
else
# without valgrind
if (cd $PRE; ./unittest); then
echo "unit test worked."
else
echo "unit test failed."
exit 1
fi
fi
if test -f $PRE/ublocktrace.0; then
if (cd $PRE; ./lock-verify ublocktrace.*); then
echo "lock-verify test worked."
else
echo "lock-verify test failed."
exit 1
if test -f $PRE/ublocktrace.0; then
if (cd $PRE; ./lock-verify ublocktrace.*); then
echo "lock-verify test worked."
else
echo "lock-verify test failed."
exit 1
fi
fi
}
run_unittest "unittest"
if grep "define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
run_unittest "unbound-dnstap-socket -c"
fi
exit 0
+50 -16
View File
@@ -73,12 +73,53 @@ control_command () {
$PRE/unbound-control $@ > outfile
}
# Reload the server and check the reload has finished processing
# when a lot of debug is enabled, a lot of log needs to be printed.
control_reload () {
prelines=`wc -l unbound.log | awk '{print $1;}'`
cmd="$1"
if test -z "$cmd"; then cmd="reload"; fi
control_command -c ub.conf $cmd
expect_exit_value 0
# see if the reload has completed.
lines1=`wc -l unbound.log | awk '{print $1;}'`
count=0
lines2=`wc -l unbound.log | awk '{print $1;}'`
# See if the log finishes up without sleeping too long.
while test "$lines1" -ne "$lines2"; do
lines1=`wc -l unbound.log | awk '{print $1;}'`
# There is no sleep here. The add and compare are a
# brief wait.
count=`expr "$count" + 1`
if test "$count" -gt 30; then
break;
fi
lines2=`wc -l unbound.log | awk '{print $1;}'`
done
if test "$lines1" -ne "$lines2"; then
count=0
while test "$lines1" -ne "$lines2"; do
tail -1 unbound.log
lines1=`wc -l unbound.log | awk '{print $1;}'`
sleep 1
count=`expr "$count" + 1`
if test "$count" -gt 30; then
echo "reload is taking too long"
exit 1
fi
lines2=`wc -l unbound.log | awk '{print $1;}'`
done
if test "$count" -ne "0"; then
echo "reload done with $count sec"
fi
fi
}
# Reload the server for a clean state
clean_reload () {
echo "> Reloading the server for a clean state"
cp main.conf ub.conf
control_command -c ub.conf reload
expect_exit_value 0
control_reload
}
# Reload the server for a clean state and populate the cache
@@ -175,8 +216,7 @@ expect_exit_value 1
# local-data element in the server.
teststep "reload the server"
echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf
control_command -c ub.conf reload
expect_exit_value 0
control_reload
query afterreload.
expect_answer "5.6.7.8"
@@ -336,16 +376,14 @@ fi
clean_reload_and_fill_cache
teststep "reload and check cache - should be empty"
control_command -c ub.conf reload
expect_exit_value 0
control_reload
query www.example.com +nordflag
fail_answer "10.20.30.40"
clean_reload_and_fill_cache
teststep "reload_keep_cache and check cache - should not be empty"
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
control_reload reload_keep_cache
query www.example.com +nordflag
expect_answer "10.20.30.40"
@@ -353,8 +391,7 @@ clean_reload_and_fill_cache
teststep "change msg-cache-size and reload_keep_cache - should be empty"
echo "server: msg-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
control_reload reload_keep_cache
query www.example.com +nordflag
fail_answer "10.20.30.40"
@@ -362,8 +399,7 @@ clean_reload_and_fill_cache
teststep "change rrset-cache-size and reload_keep_cache - should be empty"
echo "server: rrset-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
control_reload reload_keep_cache
query www.example.com +nordflag
fail_answer "10.20.30.40"
@@ -375,8 +411,7 @@ clean_reload_and_fill_cache
teststep "change num-threads and reload_keep_cache - should be empty"
echo "server: num-threads: 2" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
control_reload reload_keep_cache
query www.example.com +nordflag
fail_answer "10.20.30.40"
@@ -384,8 +419,7 @@ clean_reload_and_fill_cache
teststep "change minimal-responses and reload_keep_cache - should not be empty"
echo "server: minimal-responses: no" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
control_reload reload_keep_cache
query www.example.com +nordflag
expect_answer "10.20.30.40"
+45 -1
View File
@@ -5,9 +5,10 @@ server:
pidfile: "unbound.pid"
chroot: ""
username: ""
module-config: "respip validator iterator" # respip for the RPZ part
do-not-query-localhost: no
use-caps-for-id: no
define-tag: "one two refuse"
define-tag: "one two refuse rpz-one rpz-two rpz-nx"
# Interface configuration for IPv4
interface: @IPV4_ADDR@@@PORT_ALLOW@
@@ -16,6 +17,9 @@ server:
interface: @IPV4_ADDR@@@PORT_TAG_1@
interface: @IPV4_ADDR@@@PORT_TAG_2@
interface: @IPV4_ADDR@@@PORT_TAG_3@
interface: @IPV4_ADDR@@@PORT_RPZ_1@
interface: @IPV4_ADDR@@@PORT_RPZ_2@
interface: @IPV4_ADDR@@@PORT_RPZ_NX@
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
@@ -26,6 +30,9 @@ server:
interface-action: @IPV4_ADDR@@@PORT_TAG_1@ allow
interface-action: @IPV4_ADDR@@@PORT_TAG_2@ allow
interface-action: @IPV4_ADDR@@@PORT_TAG_3@ allow
interface-action: @IPV4_ADDR@@@PORT_RPZ_1@ allow
interface-action: @IPV4_ADDR@@@PORT_RPZ_2@ allow
interface-action: @IPV4_ADDR@@@PORT_RPZ_NX@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_INT@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_EXT@ allow
interface-action: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ allow
@@ -33,6 +40,9 @@ server:
interface-tag: @IPV4_ADDR@@@PORT_TAG_1@ "one"
interface-tag: @IPV4_ADDR@@@PORT_TAG_2@ "two"
interface-tag: @IPV4_ADDR@@@PORT_TAG_3@ "refuse"
interface-tag: @IPV4_ADDR@@@PORT_RPZ_1@ "rpz-one"
interface-tag: @IPV4_ADDR@@@PORT_RPZ_2@ "rpz-two"
interface-tag: @IPV4_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_1@ one redirect
interface-tag-data: @IPV4_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_2@ two redirect
@@ -50,6 +60,9 @@ server:
interface: @IPV6_ADDR@@@PORT_TAG_1@
interface: @IPV6_ADDR@@@PORT_TAG_2@
interface: @IPV6_ADDR@@@PORT_TAG_3@
interface: @IPV6_ADDR@@@PORT_RPZ_1@
interface: @IPV6_ADDR@@@PORT_RPZ_2@
interface: @IPV6_ADDR@@@PORT_RPZ_NX@
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
@@ -60,6 +73,9 @@ server:
interface-action: @IPV6_ADDR@@@PORT_TAG_1@ allow
interface-action: @IPV6_ADDR@@@PORT_TAG_2@ allow
interface-action: @IPV6_ADDR@@@PORT_TAG_3@ allow
interface-action: @IPV6_ADDR@@@PORT_RPZ_1@ allow
interface-action: @IPV6_ADDR@@@PORT_RPZ_2@ allow
interface-action: @IPV6_ADDR@@@PORT_RPZ_NX@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_INT@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_EXT@ allow
interface-action: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ allow
@@ -67,6 +83,9 @@ server:
interface-tag: @IPV6_ADDR@@@PORT_TAG_1@ "one"
interface-tag: @IPV6_ADDR@@@PORT_TAG_2@ "two"
interface-tag: @IPV6_ADDR@@@PORT_TAG_3@ "refuse"
interface-tag: @IPV6_ADDR@@@PORT_RPZ_1@ "rpz-one"
interface-tag: @IPV6_ADDR@@@PORT_RPZ_2@ "rpz-two"
interface-tag: @IPV6_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_1@ one redirect
interface-tag-data: @IPV6_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_2@ two redirect
@@ -84,6 +103,9 @@ server:
interface: @INTERFACE@@@PORT_TAG_1@
interface: @INTERFACE@@@PORT_TAG_2@
interface: @INTERFACE@@@PORT_TAG_3@
interface: @INTERFACE@@@PORT_RPZ_1@
interface: @INTERFACE@@@PORT_RPZ_2@
interface: @INTERFACE@@@PORT_RPZ_NX@
interface: @INTERFACE@@@PORT_VIEW_INT@
interface: @INTERFACE@@@PORT_VIEW_EXT@
interface: @INTERFACE@@@PORT_VIEW_INTEXT@
@@ -94,6 +116,9 @@ server:
interface-action: @INTERFACE@@@PORT_TAG_1@ allow
interface-action: @INTERFACE@@@PORT_TAG_2@ allow
interface-action: @INTERFACE@@@PORT_TAG_3@ allow
interface-action: @INTERFACE@@@PORT_RPZ_1@ allow
interface-action: @INTERFACE@@@PORT_RPZ_2@ allow
interface-action: @INTERFACE@@@PORT_RPZ_NX@ allow
interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
@@ -101,6 +126,9 @@ server:
interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
interface-tag: @INTERFACE@@@PORT_RPZ_1@ "rpz-one"
interface-tag: @INTERFACE@@@PORT_RPZ_2@ "rpz-two"
interface-tag: @INTERFACE@@@PORT_RPZ_NX@ "rpz-nx"
interface-tag-action: @INTERFACE@@@PORT_TAG_1@ one redirect
interface-tag-data: @INTERFACE@@@PORT_TAG_1@ one "A 1.1.1.1"
interface-tag-action: @INTERFACE@@@PORT_TAG_2@ two redirect
@@ -130,6 +158,22 @@ view:
name: "intext"
view-first: yes
# RPZ configuration
rpz:
name: "rpz-one"
zonefile: "rpz-one.zone"
tags: "rpz-one"
rpz:
name: "rpz-two"
zonefile: "rpz-two.zone"
tags: "rpz-two"
rpz:
name: "rpz-nx"
zonefile: "rpz-nx.zone"
tags: "rpz-nx"
# Stubs configuration
forward-zone:
name: "."
+12 -3
View File
@@ -7,7 +7,7 @@ if test ! -x "`which unshare 2>&1`"; then
skip_test "no unshare (from util-linux package) available, skip test"
fi
get_random_port 11
get_random_port 14
PORT_ALLOW=$RND_PORT
PORT_DENY=$(($RND_PORT + 1))
@@ -18,8 +18,11 @@ PORT_TAG_3=$(($RND_PORT + 5))
PORT_VIEW_INT=$(($RND_PORT + 6))
PORT_VIEW_EXT=$(($RND_PORT + 7))
PORT_VIEW_INTEXT=$(($RND_PORT + 8))
FORWARD_PORT=$(($RND_PORT + 9))
STUB_PORT=$(($RND_PORT + 10))
PORT_RPZ_1=$(($RND_PORT + 9))
PORT_RPZ_2=$(($RND_PORT + 10))
PORT_RPZ_NX=$(($RND_PORT + 11))
FORWARD_PORT=$(($RND_PORT + 12))
STUB_PORT=$(($RND_PORT + 13))
IPV4_ADDR=192.168.1.1
IPV6_ADDR=2001:db8::1
@@ -41,6 +44,9 @@ sed \
-e 's/@PORT_VIEW_INT\@/'$PORT_VIEW_INT'/' \
-e 's/@PORT_VIEW_EXT\@/'$PORT_VIEW_EXT'/' \
-e 's/@PORT_VIEW_INTEXT\@/'$PORT_VIEW_INTEXT'/' \
-e 's/@PORT_RPZ_1\@/'$PORT_RPZ_1'/' \
-e 's/@PORT_RPZ_2\@/'$PORT_RPZ_2'/' \
-e 's/@PORT_RPZ_NX\@/'$PORT_RPZ_NX'/' \
-e 's/@FORWARD_PORT\@/'$FORWARD_PORT'/' \
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
@@ -63,6 +69,9 @@ echo "PORT_TAG_3=$PORT_TAG_3" >> .tpkg.var.test
echo "PORT_VIEW_INT=$PORT_VIEW_INT" >> .tpkg.var.test
echo "PORT_VIEW_EXT=$PORT_VIEW_EXT" >> .tpkg.var.test
echo "PORT_VIEW_INTEXT=$PORT_VIEW_INTEXT" >> .tpkg.var.test
echo "PORT_RPZ_1=$PORT_RPZ_1" >> .tpkg.var.test
echo "PORT_RPZ_2=$PORT_RPZ_2" >> .tpkg.var.test
echo "PORT_RPZ_NX=$PORT_RPZ_NX" >> .tpkg.var.test
echo "FORWARD_PORT=$FORWARD_PORT" >> .tpkg.var.test
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
echo "IPV4_ADDR=$IPV4_ADDR" >> .tpkg.var.test
+48
View File
@@ -78,6 +78,16 @@ expect_refused () {
fi
}
expect_nx_answer () {
echo "> check answer for NXDOMAIN"
if grep "NXDOMAIN" outfile; then
echo "OK"
else
echo "Not OK"
end 1
fi
}
expect_external_answer () {
echo "> check external answer"
if grep "1.2.3.4" outfile; then
@@ -118,6 +128,26 @@ expect_tag_two_answer () {
fi
}
expect_rpz_one_answer () {
echo "> check tag 'one' answer"
if grep "11.11.11.11" outfile; then
echo "OK"
else
echo "Not OK"
end 1
fi
}
expect_rpz_two_answer () {
echo "> check tag 'two' answer"
if grep "22.22.22.22" outfile; then
echo "OK"
else
echo "Not OK"
end 1
fi
}
# do the test
for i in 4 6; do
@@ -142,6 +172,15 @@ for i in 4 6; do
query $i $PORT_TAG_3 "local"
expect_refused
query $i $PORT_RPZ_1 "local"
expect_rpz_one_answer
query $i $PORT_RPZ_2 "local"
expect_rpz_two_answer
query $i $PORT_RPZ_NX "local"
expect_nx_answer
query $i $PORT_VIEW_INT "www.internal"
expect_internal_answer
@@ -183,6 +222,15 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
query_addr $addr $PORT_TAG_3 "local"
expect_refused
query_addr $addr $PORT_RPZ_1 "local"
expect_rpz_one_answer
query_addr $addr $PORT_RPZ_2 "local"
expect_rpz_two_answer
query_addr $addr $PORT_RPZ_NX "local"
expect_nx_answer
query_addr $addr $PORT_VIEW_INT "www.internal"
expect_internal_answer
+3
View File
@@ -0,0 +1,3 @@
$ORIGIN rpz-nx.
@ IN SOA no.no no.no 1 2 3 4 5
local IN CNAME .
+3
View File
@@ -0,0 +1,3 @@
$ORIGIN rpz-one.
@ IN SOA no.no no.no 1 2 3 4 5
local IN A 11.11.11.11
+3
View File
@@ -0,0 +1,3 @@
$ORIGIN rpz-two.
@ IN SOA no.no no.no 1 2 3 4 5
local IN A 22.22.22.22
+16
View File
@@ -0,0 +1,16 @@
BaseName: auth_tls
Version: 1.0
Description: Perform AXFR over tls for authority zone
CreationDate: Thu 29 Aug 09:35:40 CEST 2024
Maintainer: dr. W.C.A. Wijngaards
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: auth_tls.pre
Post: auth_tls.post
Test: auth_tls.test
AuxFiles:
Passed:
Failure:
+21
View File
@@ -0,0 +1,21 @@
server:
logfile: "/dev/stderr"
xfrdfile: xfrd.state
username: ""
chroot: ""
zonesdir: ""
pidfile: "nsd.pid"
zonelistfile: "zone.list"
verbosity: 5
port: @NSD_PORT@
interface: 127.0.0.1@@NSD_PORT@
tls-port: @NSD_PORT@
tls-service-key: "nsd_server.key"
tls-service-pem: "nsd_server.pem"
zone:
name: "example.com"
zonefile: "example.com.zone"
provide-xfr: 0.0.0.0/0 NOKEY
provide-xfr: ::0/0 NOKEY
+14
View File
@@ -0,0 +1,14 @@
# #-- auth_tls.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $NSD_PID
kill_pid $UNBOUND_PID
echo "nsd.log"
cat nsd.log
echo "unbound.log"
cat unbound.log

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