Compare 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
W.C.A. Wijngaards 86fe9cbce5 - 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.
2024-06-03 12:14:51 +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
W.C.A. Wijngaards 4b30e88eec - Fix for #1079: fix RPZ taglist in iterator callback that no client
info is like no taglist intersection.
2024-05-30 12:44:26 +02:00
W.C.A. Wijngaards b6c7ea563f - Fix #1079: tags from tagged rpz zones are no longer honored after
upgrade from 1.19.3 to 1.20.0.
2024-05-30 12:11:30 +02:00
W.C.A. Wijngaards 910d7cf446 Changelog note for #1078.
- Merge #1078: Only check old pid if no username.
2024-05-29 14:45:01 +02:00
Wouter WijngaardsandGitHub cd485f2036 Merge pull request #1078 from vopatek/master
Only check old pid if no username
2024-05-29 14:44:31 +02:00
Martin Vopatek 8ff1baf585 Only check old pid if no username
Do as the comment says and only check old pid if there is no username
configured.
2024-05-29 14:16:18 +02:00
Yorgos Thessalonikefs 5fc4673901 - Update patch to remove 'command' shell builtin and update error
text.
2024-05-27 17:17:48 +02:00
Michael TokarevandYorgos Thessalonikefs faf3d358dc unbound-control-setup: check openssl
Before doing anything, check if openssl binary (which we will use)
is available, and print a useful error message if it is not found.
2024-05-27 16:35:34 +02:00
Yorgos Thessalonikefs f5a2160ba3 - Fix unused variable warning on compilation with no thread support. 2024-05-27 14:56:52 +02:00
W.C.A. Wijngaards 0c0c36f015 - Fix spelling of tcp-idle-timeout docs, from Michael Tokarev. 2024-05-27 14:36:35 +02:00
W.C.A. Wijngaards 47956de897 - Fix to enable that SERVFAIL is cached, for a short period, for more
cases. In the cases where limits are exceeded.
2024-05-27 13:53:16 +02:00
Yorgos Thessalonikefs b30c869a59 Changelog entry for #1059:
- Fix #1059: Intermittent DNS blocking failure with local-zone and
  always_nxdomain. Addition of local_zones dynamically via
  unbound-control was not finding the zone's parent correctly.
2024-05-24 15:24:52 +02:00
Yorgos ThessalonikefsandGitHub 6f030e9672 Proper parent identification for dynamically entered local zones (#1076)
- Fix #1059: Intermittent DNS blocking failure with local-zone and
  always_nxdomain. Addition of local_zones dynamically via
  unbound-control was not finding the zone's parent correctly.
2024-05-24 15:21:40 +02:00
W.C.A. Wijngaards 7107d3c9e7 - Fix #1064: Unbound 1.20 Cachedb broken?
Add unit test for validation status commit.
2024-05-24 09:06:48 +02:00
W.C.A. Wijngaards fbdc06ebc4 - Fix for #1064: Fix that cachedb expired messages are considered
insecure, and thus can be served to clients when dnssec is enabled.
2024-05-21 17:06:18 +02:00
W.C.A. Wijngaards d149e755fd - Fix for parse end of forward-zone, stub-zone and view. 2024-05-21 12:04:57 +02:00
W.C.A. Wijngaards 86ee8ccd12 - Fix to print a parse error when config is read with no name for
a forward-zone, stub-zone or view.
2024-05-21 11:54:18 +02:00
W.C.A. Wijngaards 8d6a1ba811 Changelog note for #1073.
- Merge #1073: fix null pointer dereference issue in function
  ub_ctx_set_fwd.
2024-05-21 11:52:47 +02:00
Wouter WijngaardsandGitHub 9ccb8d5f20 Merge pull request #1073 from xiaoxiaoafeifei/master
fix null pointer dereference issue in function ub_ctx_set_fwd
2024-05-21 11:51:52 +02:00
zhailiangliang 8e43e2574c fix null pointer dereference issue in function ub_ctx_set_fwd of file libunbound/libunbound.c 2024-05-21 08:40:35 +00:00
Yorgos Thessalonikefs 2e70506763 Changelog entry for #1069:
- Merge #1069: Fix unbound-control stdin commands for multi-process
  Unbounds.
2024-05-17 10:31:20 +02:00
7f184c8ca8 Fix unbound-control stdin commands for multi-process Unbounds (#1069)
- Fix unbound-control commands that read stdin in multi-process
  operation (local_zones_remove, local_zones, local_datas_remove,
  local_datas, view_local_datas_remove, view_local_datas). They will
  be properly distributed to all processes. dump_cache and load_cache
  are no longer supported in multi-process operation.

 - Remove testdata/remote-threaded.tdir. testdata/09-unbound-control.tdir
  now checks both single and multi process/thread operation.

---------

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2024-05-17 10:25:24 +02:00
W.C.A. Wijngaards da2b307aa3 - Fix #1071: [FR] Clear both in-memory and cachedb module cache with
`unbound-control flush*` commands.
2024-05-16 16:56:58 +02:00
Yorgos Thessalonikefs 739a88ceed Changelog entry for #1070:
- Merge #1070: Fix rtt assignement for low values of
  infra-cache-max-rtt.
2024-05-16 13:43:24 +02:00
Yorgos ThessalonikefsandGitHub 3ff5c7a74d Fix rtt assignement for low values of infra-cache-max-rtt (#1070)
* Fix rtt assignement for still useful servers when a low value for
  infra-cache-max-rtt is configured.
2024-05-16 13:42:32 +02:00
Yorgos Thessalonikefs 1048c4a28c - Add missing common functions to tdir tests. 2024-05-15 11:20:36 +02:00
W.C.A. Wijngaards 7de009f99a - Fix when the mesh jostle is exceeded that nameserver targets are
marked as resolved, so that the lookup is not stuck on the
  requestlist.
2024-05-10 09:50:35 +02:00
W.C.A. Wijngaards 95669855fb - Fix to squelch udp connect errors in the log at low verbosity about
invalid argument for IPv6 link local addresses.
2024-05-08 16:40:41 +02:00
W.C.A. Wijngaards 56e7cade28 The code repository continues with version 1.20.1. 2024-05-08 11:10:53 +02:00
W.C.A. Wijngaards c085a53268 - Fix for #1062: declaration before statement, avoid print of null,
and redundant check for array size.
And changelog note for merge of #1062.
2024-05-07 14:05:21 +02:00
Wouter WijngaardsandGitHub 49569b81aa Merge pull request #1062 from xiaoxiaoafeifei/master
Fix potential overflow bug while parsing port in function cfg_mark_ports
2024-05-07 14:02:21 +02:00
zhailiangliang 4497e8a154 Fix potential overflow bug while parsing port in function cfg_mark_ports 2024-05-07 11:35:52 +00:00
W.C.A. Wijngaards b9525c5fd4 - Set version number to 1.20.0 for release. 2024-05-01 10:15:12 +02:00
W.C.A. Wijngaards c3206f4568 - Fix for the DNSBomb vulnerability CVE-2024-33655. Thanks to Xiang Li
from the Network and Information Security Lab of Tsinghua University
  for reporting it.
2024-05-01 10:10:58 +02:00
W.C.A. Wijngaards 9abed3fc83 - Fix doxygen comment for errinf_to_str_bogus. 2024-04-29 13:42:26 +02:00
Yorgos Thessalonikefs 63a6b7b255 - Cleanup unnecessary strdup calls for EDE strings. 2024-04-29 10:15:19 +02:00
W.C.A. Wijngaards 15dc8e8a3f - Man page entry for unbound-checkconf -q. 2024-04-26 14:54:25 +02:00
Yorgos Thessalonikefs cd4a017e96 - Fix #876: [FR] can unbound-checkconf be silenced when configuration
is valid?
2024-04-26 14:50:39 +02:00
W.C.A. Wijngaards 82c0207fa6 - Add unit tests for cachedb and subnet cache expired data. 2024-04-26 13:33:26 +02:00
W.C.A. Wijngaards 7c5e765b3b - Fix cachedb with serve-expired-client-timeout disabled. The edns
subnet module deletes global cache and cachedb cache when it
  stores a result, and serve-expired is enabled, so that the global
  reply, that is older than the ecs reply, does not return after
  the ecs reply expires.
2024-04-26 13:32:15 +02:00
W.C.A. Wijngaards f456d97a34 - Fix doc unit test for out of directory build. 2024-04-25 17:06:06 +02:00
W.C.A. Wijngaards 8b490b1540 - Fix to disable fragmentation on systems with IP_DONTFRAG,
with a nonzero value for the socket option argument.
2024-04-25 12:53:05 +02:00
W.C.A. Wijngaards b3951e5885 Changelog note for #1041 and #1038.
- Merge #1041: Stub and Forward unshare. This has one structure
  for them and fixes #1038: fatal error: Could not initialize
  thread / error: reading root hints.
2024-04-25 11:12:27 +02:00
Wouter WijngaardsandGitHub ced9762b14 Merge pull request #1041 from NLnetLabs/stubfwd-unshare
Stub and Forward unshare
2024-04-25 11:11:00 +02:00
9b9bba9f02 Update locking management for iter_fwd and iter_hints methods. (#1054)
fast reload, move most of the locking management to iter_fwd and
iter_hints methods. The caller still has the ability to handle its
own locking, if desired, for atomic operations on sets of different
structs.

Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2024-04-25 11:05:58 +02:00
W.C.A. Wijngaards 07859a9ef3 - Fix configure flto check error, by finding grep for it. 2024-04-25 10:53:35 +02:00
W.C.A. Wijngaards cb74467acb - Fix ci workflow for macos for moved install locations. 2024-04-24 16:31:44 +02:00
Yorgos Thessalonikefs 62dad42152 - Merge #1053: Remove child delegations from cache when grandchild
delegations are returned from parent.
2024-04-23 14:24:07 +02:00
Yorgos Thessalonikefs 3ec74d1e3a - When a granchild delegation is returned, remove any cached child delegations
up to parent to not cause delegation invalidation because of an
  expired child delegation that would never be updated. Most likely to
  happen without qname-minimisation. Reported by Roland van Rijswijk-Deij.
2024-04-22 15:46:06 +02:00
W.C.A. Wijngaards 52aff65e35 - Fix edns subnet to sort rrset references when storing messages
in the cache. This fixes a race condition in the rrset locks.
2024-04-22 13:44:42 +02:00
W.C.A. Wijngaards 5994fb3db5 - Add checklock feature verbose_locking to trace locks and unlocks. 2024-04-22 13:42:35 +02:00
Yorgos Thessalonikefs 0dbcb45d28 Changelog entry for #1049:
- Merge #1049 from Petr Menšík: Py_NoSiteFlag is not needed since
  Python 3.8
2024-04-15 14:49:14 +02:00
Yorgos ThessalonikefsandGitHub d71f257215 Merge pull request #1049 from InfrastructureServices/python3.12-Py_NoSiteFlag-warning
Py_NoSiteFlag is not needed since Python 3.8
2024-04-15 14:47:45 +02:00
Petr Mensik b11d234f77 Py_NoSiteFlag is not needed since Python 3.8
Python since 3.12 prints warning about Py_NoSiteFlag is deprecated. It
seems that variable is not needed since Python 3.8, since it sets in
such cases directly config.site_import variable few moments later.
Move using deprecated variable to versions before that flag in config
could be used only.

This should fix warning like:

pythonmod/pythonmod.c: In function 'pythonmod_init':
pythonmod/pythonmod.c:359:7: warning: 'Py_NoSiteFlag' is deprecated [-Wdeprecated-declarations]
  359 |       Py_NoSiteFlag = 1;
      |       ^~~~~~~~~~~~~
In file included from /usr/include/python3.12/Python.h:48,
                 from pythonmod/pythonmod.c:54:
/usr/include/python3.12/cpython/pydebug.h:14:37: note: declared here
   14 | Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag;
      |                                     ^~~~~~~~~~~~~

https://docs.python.org/3/c-api/init.html#c.Py_NoSiteFlag
2024-04-15 13:52:41 +02:00
W.C.A. Wijngaards 0d4c5aa421 - Fix configure, autoconf for #1048. 2024-04-15 12:17:56 +02:00
W.C.A. Wijngaards 9e60f93b84 Changelog note for #1048.
- Fix #1048: Update ax_pkg_swig.m4 and ax_pthread.m4.
2024-04-15 12:15:54 +02:00
Wouter WijngaardsandGitHub 9d63e8f093 Merge pull request #1048 from InfrastructureServices/configure-m4-refresh
Update ax_pkg_swig.m4 and ax_pthread.m4
2024-04-15 12:15:26 +02:00
Petr Mensik 4c40253df7 Update ax_pkg_swig.m4 and ax_pthread.m4
Use vanilla m4 files with known source. Prepared for possible removal at
build time if the system already has autoconf-archive source present.
Switch to AX_PKG_SWIG macro for versioned or unversioned swig detection.
2024-04-15 11:54:46 +02:00
W.C.A. Wijngaards 491b56d051 - Fixup cachedb to not refetch when serve-expired-client-timeout is
used.
2024-04-12 14:22:18 +02:00
W.C.A. Wijngaards 4d530920e0 - Fixup unit test for cachedb server expired client timeout with
a check if response if from upstream or from cachedb.
2024-04-12 11:51:00 +02:00
W.C.A. Wijngaards 08fb9a9209 - Fix cachedb for serve-expired with serve-expired-client-timeout. 2024-04-12 11:26:53 +02:00
W.C.A. Wijngaards 04ff2672b5 - Fix to not reply serve expired unless enabled for cachedb. 2024-04-10 17:06:01 +02:00
W.C.A. Wijngaards d47849a26e - Fix cachedb for serve-expired with serve-expired-reply-ttl. 2024-04-10 17:01:57 +02:00
W.C.A. Wijngaards 63ee97d0fd - Fix makefile dependencies for fake_event.c. 2024-04-10 14:04:39 +02:00
W.C.A. Wijngaards bd74a32b79 - Extended test for cachedb serve expired. 2024-04-10 13:08:23 +02:00
W.C.A. Wijngaards b990be88ef - Add test for cachedb serve expired. 2024-04-10 12:36:21 +02:00
W.C.A. Wijngaards cccf5e73c0 - Fixup compile without cachedb. 2024-04-10 11:33:52 +02:00
W.C.A. Wijngaards f3f85e5a11 - Fixup compile without cachedb. 2024-04-10 11:29:10 +02:00
W.C.A. Wijngaards d55511f1dd - Fixup compile without cachedb. 2024-04-10 11:27:08 +02:00
W.C.A. Wijngaards d98c7b9ae3 - Implement cachedb-check-when-serve-expired: yes option, default
is enabled. When serve expired is enabled with cachedb, it first
  checks cachedb before serving the expired response.
2024-04-10 11:21:28 +02:00
Yorgos Thessalonikefs a30221c5bb - Merge #1043 from xiaoxiaoafeifei: Add loongarch support; updates
config.guess(2024-01-01) and config.sub(2024-01-01), verified
  with upstream.
2024-04-09 17:00:59 +02:00
zhailiangliang 411e843fc4 Add loongarch support:
1. update config.guess(2024-01-01) and config.sub(2024-01-01)
  2. add loongarch to little endian support
2024-04-09 11:15:14 +08:00
Yorgos Thessalonikefs 8575d5b35c - Fix #595: unbound-anchor cannot deal with full disk; it will now
first write out to a temp file before replacing the original one,
  like Unbound already does for auto-trust-anchor-file.
2024-04-08 14:15:03 +02:00
W.C.A. Wijngaards ba16e41160 - Fix comment syntax for view function views_find_view. 2024-04-05 16:11:29 +02:00
Yorgos Thessalonikefs 708d5229ae - Merge #1027: Introduce 'cache-min-negative-ttl' option. 2024-04-05 11:44:37 +02:00
Yorgos Thessalonikefs fb4a7d65d7 - Fix #369: dnstap showing extra responses; for client responses
right from the cache when replying with expired data or
  prefetching.
2024-04-03 15:18:13 +02:00
W.C.A. Wijngaards d7353e6e99 - fast-reload, helpful comments for hints lookup function return value. 2024-04-03 13:55:57 +02:00
W.C.A. Wijngaards 48113cfaba - fast-reload, unshared stub hints, making the structure locked, with an rwlock. 2024-04-03 13:55:57 +02:00
W.C.A. Wijngaards c0b5754ef7 - fast-reload, for nonthreaded, the unbound-control commands forward,
forward_add and forward_delete should be distributed to other processes,
  but when threaded, they should not be distributed to other threads because
  the structure is not thread specific any more.
2024-04-03 13:55:57 +02:00
W.C.A. Wijngaards f2fb498c69 - fast-reload, unshare forwards, making the structure locked, with an rwlock. 2024-04-03 13:55:54 +02:00
Yorgos Thessalonikefs 91e8e0e511 - Fix #1035: Potential Bug while parsing port from the "stub-host"
string; also affected forward-zones and remote-control host
  directives.
2024-04-03 13:37:57 +02:00
W.C.A. Wijngaards dfff8d23cf - For #1040: adjust error text and disallow negative ports in other
parts of cfg_mark_ports.
2024-04-03 10:16:18 +02:00
W.C.A. Wijngaards 103d9a68fa Changelog note for #1040
- Fix #1040: fix heap-buffer-overflow issue in function cfg_mark_ports
  of file util/config_file.c.
2024-04-03 10:03:04 +02:00
Wouter WijngaardsandGitHub a814fe8c5f Merge pull request #1040 from xiaoxiaoafeifei/master
fix heap-buffer-overflow issue in function cfg_mark_ports of file util/config_file.c
2024-04-03 10:02:45 +02:00
zhailiangliang 193401e754 fix heap-buffer-overflow issue in function cfg_mark_ports of file util/config_file.c 2024-04-03 15:40:58 +08:00
W.C.A. Wijngaards e1aeabde44 - Fix for crypto related failures to have a better error string. 2024-03-28 09:58:57 +01:00
W.C.A. Wijngaards 6d1e61173b - Fix #1034: DoT forward-zone via unbound-control. 2024-03-28 09:58:03 +01:00
W.C.A. Wijngaards 6f82b5be4a - Fix that the server does not chown the pidfile. 2024-03-27 14:52:25 +01:00
W.C.A. Wijngaards 192f1b0e2b - Fix that when the server truncates the pidfile, it does not follow
symbolic links.
2024-03-27 14:07:54 +01:00
W.C.A. Wijngaards 238a796e38 - Fix to add unit test for lruhash space that exercises the routines. 2024-03-27 13:33:46 +01:00
W.C.A. Wijngaards fe393ac355 - Fix comment in lruhash space function. 2024-03-27 12:30:00 +01:00
W.C.A. Wijngaards 3ea078baf6 - Fix for #1032, add safeguard to make table space positive. 2024-03-27 11:49:20 +01:00
W.C.A. Wijngaards eb3e1ae24f - Fix #1032: The size of subnet_msg_cache calculation mistake cause
memory usage increased beyond expectations.
2024-03-27 11:45:34 +01:00
W.C.A. Wijngaards c2b20c585e - Fix name of unit test for subnet cache response. 2024-03-27 11:43:55 +01:00
Yorgos Thessalonikefs 07561964fc - For #831: Format text, use exclamation icon and explicit label
names.
2024-03-25 22:02:08 +01:00
Yorgos Thessalonikefs ce8c1ce5b0 Changelog entry for #831
- Merge #831 from Pierre4012: Improve Windows NSIS installer
  script (setup.nsi).
2024-03-25 16:46:25 +01:00
Pierre4012andGitHub ef60dcac31 Improve Windows NSIS installer script (setup.nsi) (#831)
* Improve Windows NSIS installer script (setup.nsi)

Two improvements of installer script :
- avoid error message when Unbound is running,
- add "DisplayVersion" in registry thus Windows package manager (Winget) can handle Unbound.

* Update setup.nsi ask user to stop unbound service + DisplayVersion in Windows registry
2024-03-25 16:43:49 +01:00
W.C.A. Wijngaards 73bd5a19aa - Fix localdata and rpz localdata to match CNAME only if no direct
type match is available.
2024-03-19 10:21:10 +01:00
W.C.A. Wijngaards fef974ca5c - Fix rpz so that rpz CNAME can apply after rpz CNAME. And fix that
clientip and nsip can give a CNAME.
2024-03-19 09:32:53 +01:00
W.C.A. Wijngaards 8dbf46913b - Fix rpz for qtype CNAME after nameserver trigger. 2024-03-18 14:36:29 +01:00
W.C.A. Wijngaards e46b188fe8 - Add rpz unit test for nsip action override. 2024-03-18 14:11:43 +01:00
W.C.A. Wijngaards e6b1f9a4c3 - Fix rpz that copies the cname override completely to the temp
region, so there are no references to the rpz region.
2024-03-18 13:52:59 +01:00
W.C.A. Wijngaards 39cfc8c1c0 - Fix rpz, it follows iterator CNAMEs for nsip and nsdname and sets
the reply query_info values, that is better for debug logging.
2024-03-18 12:45:00 +01:00
W.C.A. Wijngaards 79e25e192c - Fix that rpz CNAME content is limited to the max number of cnames. 2024-03-18 11:25:29 +01:00
Yorgos Thessalonikefs 792089f523 Merge branch 'features/makedist-persist-windir' 2024-03-15 17:22:00 +01:00
Yorgos Thessalonikefs 34636caa2d - For windows build, persist the openssl and expat directories for
repeated builds while debugging.
2024-03-15 16:59:46 +01:00
W.C.A. Wijngaards 2993437eaa - Fix that addrinfo is not kept around but copied and freed, so that
log-destaddr uses a copy of the information, much like NSD does.
2024-03-15 13:39:49 +01:00
W.C.A. Wijngaards 0bcc8c0211 - The code repository continues with version 1.19.4. 2024-03-14 10:33:13 +01:00
W.C.A. Wijngaards 4b54d8e15e - Fix rpz for cname override action after nsdname and nsip triggers. 2024-03-13 17:14:14 +01:00
W.C.A. Wijngaards afe52595a9 - Fix to unify codepath for local alias for rpz cname action override. 2024-03-13 16:12:48 +01:00
W.C.A. Wijngaards 4f417262e3 - Fix rpz that the rpz override is taken in case of clientip triggers.
Fix that the clientip passthru action is logged. Fix that the
  clientip localdata action is logged. Fix rpz override action cname
  for the clientip trigger.
2024-03-13 16:04:58 +01:00
W.C.A. Wijngaards 1db3b38104 - Fix #1029: rpz trigger clientip and action rpz-passthru not working
as expected.
2024-03-13 13:45:04 +01:00
Yorgos Thessalonikefs bc47f50926 Changelog entry for #1028:
- Merge #1028: Clearer documentation for tcp-idle-timeout and
  edns-tcp-keepalive-timeout.
2024-03-12 14:52:57 +01:00
Yorgos ThessalonikefsandGitHub e36b5a099c Clearer documentation for tcp-idle-timeout and edns-tcp-keepalive-timeout (#1028)
* - Clearer documentation for tcp-idle-timeout and
  edns-tcp-keepalive-timeout.

* - Address review comment.
2024-03-12 14:52:00 +01:00
Yorgos Thessalonikefs 025881d0e9 - Introduce 'cache-min-negative-ttl' option to bound the minimum TTL for
negative answers overriding 'cache-min-ttl'.
2024-03-12 11:24:59 +01:00
W.C.A. Wijngaards 320d0a5f1b - Fix #1021 Inconsistent Behavior with Changing rpz-cname-override
and doing a unbound-control reload.
2024-03-11 16:31:58 +01:00
W.C.A. Wijngaards d382210fce Update doc/Changelog to note the fixes included in 1.19.3rc2. 2024-03-11 12:30:24 +01:00
W.C.A. Wijngaards 7b62767e16 - Fix unbound-control-setup.cmd to have CA v3 basicConstraints,
like unbound-control-setup.sh has.
2024-03-08 17:18:05 +01:00
W.C.A. Wijngaards 6568841bb0 - Fix doc test so it ignores but outputs unsupported doxygen options. 2024-03-08 16:43:24 +01:00
W.C.A. Wijngaards e361f6b284 - Fix qname minimisation for reply with a DNAME for qtype CNAME that
answers it.
2024-03-08 16:33:17 +01:00
Yorgos Thessalonikefs 53766917ef - Update doc/unbound.doxygen with 'doxygen -u'. Fixes option
deprecation warnings and updates with newer defaults.
2024-03-08 16:13:36 +01:00
W.C.A. Wijngaards 2a255076f5 - Fix validator classification of qtype DNAME for positive and
redirection answers, and fix validator signature routine for dealing
  with the synthesized CNAME for a DNAME without previously
  encountering it and also for when the qtype is DNAME.
2024-03-08 14:10:06 +01:00
W.C.A. Wijngaards fb080e7853 - Remove unused portion from iter_dname_ttl unit test. 2024-03-08 09:51:37 +01:00
W.C.A. Wijngaards 0818841038 - Fix TTL of synthesized CNAME when a DNAME is used from cache. 2024-03-08 09:47:59 +01:00
W.C.A. Wijngaards 939baebfe7 - Fix unbound-control-setup.cmd to use 3072 bits so that certificates
are long enough for newer OpenSSL versions.
2024-03-08 09:07:36 +01:00
W.C.A. Wijngaards 326ba26522 - Version set to 1.19.3 for release. After 1.19.2 point release with
security fix for CVE-2024-1931, Denial of service when trimming
  EDE text on positive replies. The code repo includes the fix and
  is for version 1.19.3.
2024-03-07 11:06:42 +01:00
W.C.A. Wijngaards ec0b510f1c - Fix for #1022: Fix ede prohibited in access control refused answers. 2024-03-05 13:39:29 +01:00
W.C.A. Wijngaards be626f7c53 - Fix edns subnet replies for scope zero answers to not get stored
in the global cache, and in cachedb, when the upstream replies
  without an EDNS record.
2024-03-04 13:20:13 +01:00
W.C.A. Wijngaards 3096e4930e - Move github workflows to use checkoutv4. 2024-02-28 11:44:52 +01:00
Yorgos Thessalonikefs 33bdf44a04 - Document the suspend argument for process_ds_response(). 2024-02-23 14:34:33 +01:00
W.C.A. Wijngaards ccbe31c21f - Fix trim of EDE text from large udp responses from spinning cpu. 2024-02-22 16:22:31 +01:00
Yorgos Thessalonikefs c6746499c1 Changelog entry for #1010:
- Merge #1010: Mention REFUSED has the TC bit set with unmatched
  allow_cookie acl in the manpage. It also fixes the code to match the
  documentation about clients with a valid cookie that bypass the
  ratelimit regardless of the allow_cookie acl.
2024-02-20 15:33:18 +01:00
Willem TooropandGitHub e1229e375f Mention REFUSED has the TC bit set with unmatched allow_cookie acl in the manpage (#1010)
* Mention REFUSED with TC with unmatched allow_cookie acl in manpage

Also moved the part about bypassing ip-ratelimit to the ip-ratelimit
description as it will be bypassed with a valid DNS-Cookie regardless of the
allow_cookie acl.

* Apply suggestions from code review

* Update doc/unbound.conf.5.in

* DNS-Cookies should bypass ip-ratelimit setting
2024-02-20 15:29:34 +01:00
W.C.A. Wijngaards be27499d39 - These fixes are part of the 1.19.1 release, that is a security
point release on 1.19.0, the code repository continues with these
  fixes, with version number 1.19.2.
2024-02-13 14:03:30 +01:00
W.C.A. Wijngaards 56a2b564ef Merge commit '92f2a1ca690a44880f4c4fa70a4b5a4b029aaf1c' 2024-02-13 13:58:09 +01:00
W.C.A. Wijngaards 9a00877af9 Merge commit '882903f2fa800c4cb6f5e225b728e2887bb7b9ae' 2024-02-13 13:57:56 +01:00
W.C.A. Wijngaards 92f2a1ca69 - Fix CVE-2023-50868, NSEC3 closest encloser proof can exhaust CPU. 2024-02-13 13:02:43 +01:00
W.C.A. Wijngaards 882903f2fa - Fix CVE-2023-50387, DNSSEC verification complexity can be exploited to
exhaust CPU resources and stall DNS resolvers.
2024-02-13 13:02:08 +01:00
W.C.A. Wijngaards 54d86dd73b - Fix documentation for access-control in the unbound.conf man page. 2024-02-08 14:36:18 +01:00
Yorgos Thessalonikefs b496714caa - autoconf. 2024-02-07 10:51:16 +01:00
Yorgos Thessalonikefs 3f5175584b - For #1006: fix logic error introduced by previous fix. 2024-02-07 10:49:28 +01:00
Yorgos Thessalonikefs 11fff226f3 - autoheader, autoconf. 2024-02-07 10:42:39 +01:00
Yorgos Thessalonikefs 93490a0fc1 - Fix #1006: Can't find protobuf-c package since #999. 2024-02-07 10:38:52 +01:00
W.C.A. Wijngaards 0585c3e5fd Autoconf and changelog note for #999
- Merge #999: Search for protobuf-c with pkg-config.
2024-01-30 16:24:41 +01:00
Wouter WijngaardsandGitHub 0b74f2a007 Merge pull request #999 from NickCao/master
Search for protobuf-c with pkg-config
2024-01-30 16:23:43 +01:00
Nick Cao 59d98b9ef6 Search for protobuf-c with pkg-config 2024-01-26 17:52:24 -05:00
Yorgos Thessalonikefs 3522451600 - Update message TTL when using cached RRSETs. It could result in
non-expired messages with expired RRSETs (non-usable messages by
  Unbound).
2024-01-23 10:10:37 +01:00
Yorgos Thessalonikefs fe03bacd6c - Update error printout for duplicate trust anchors to include the
trust anchor name (relates to #920).
2024-01-22 15:54:36 +01:00
W.C.A. Wijngaards 1f46d5945b - Fix for #997: Print details for SSL certificate failure. 2024-01-22 09:40:36 +01:00
W.C.A. Wijngaards 585d73bf7c For analysis workflow, clean up the script to use OpenSSL Configure
without change.
2024-01-17 16:23:18 +01:00
W.C.A. Wijngaards 9e84cebfdb - workflow for analysis, cleanup of windows compile with msys2 perl. 2024-01-17 16:20:22 +01:00
W.C.A. Wijngaards d1a2bd67da - Fix warning for windres on resource files due to redefinition. 2024-01-17 16:19:56 +01:00
W.C.A. Wijngaards 7708429d35 For workflow, set perl interpreter for build. 2024-01-17 15:08:56 +01:00
W.C.A. Wijngaards 6045911d95 - Fix for workflow 2024-01-17 14:58:44 +01:00
W.C.A. Wijngaards 1b212aa073 For workflow, look for pacman. 2024-01-17 14:56:10 +01:00
W.C.A. Wijngaards 4d48166835 For workflow, use msys2 perl. 2024-01-17 14:53:23 +01:00
W.C.A. Wijngaards 437bac370a In workflow, use strawberry perl to run configure script. 2024-01-17 14:40:57 +01:00
W.C.A. Wijngaards 546062d3a3 For workflow, change path separator. 2024-01-17 14:36:35 +01:00
W.C.A. Wijngaards 576b93c99f For windows runner, look at perl contents. 2024-01-17 14:30:48 +01:00
W.C.A. Wijngaards 180275c4e0 Fix to install with cpanmin a missing perl module for the windows workflow. 2024-01-17 14:07:57 +01:00
W.C.A. Wijngaards 379e4b68f5 Fix for workflow to install perl module. 2024-01-17 14:03:30 +01:00
W.C.A. Wijngaards 74b4d81992 - Update workflow for ports to use newer openssl on windows compile. 2024-01-17 13:45:59 +01:00
W.C.A. Wijngaards fea8f0d5fd Changelog note for #993
- Merge #993: Update b.root-servers.net also in example config file.
2024-01-16 16:44:15 +01:00
Wouter WijngaardsandGitHub 0e5dab5eaf Merge pull request #993 from InfrastructureServices/b.root-servers.net-conf
Update b.root-servers.net also in example config file
2024-01-16 16:44:02 +01:00
W.C.A. Wijngaards c550bc154f - Fix to link with libssp for libcrypto and getaddrinfo check for
only header. Also update crosscompile to remove ssp for 32bit.
2024-01-16 16:40:14 +01:00
Petr Mensik 40fcb91206 Update b.root-servers.net also in example config file
Addition to commit a8739bad76, which
updated only address specified in code. But addresses provided in
example configuration were not updated, I think they should be updated
too.
2024-01-16 16:14:13 +01:00
W.C.A. Wijngaards c8554ff48c - Fix to link with -lcrypt32 for OpenSSL 3.2.0 on Windows. 2024-01-15 16:44:27 +01:00
W.C.A. Wijngaards 3d95cef08c Changelog note for #988.
- Merge #988: Fix NLnetLabs#981: dump_cache truncates large records.
2024-01-09 08:41:52 +01:00
Wouter WijngaardsandGitHub 9cd724cf5e Merge pull request #988 from dyunwei/master
Fix NLnetLabs#981: dump_cache truncates large records.
2024-01-09 08:41:30 +01:00
dyunwei eb7eb5ce68 Fix NLnetLabs#981: dump_cache truncates large records. 2024-01-09 14:17:31 +08:00
W.C.A. Wijngaards 418eeb642c - Fix unit test for #987 change in udp1xxx retry packet send. 2024-01-05 14:11:55 +01:00
W.C.A. Wijngaards 8ac56d004d Changelog note for #987
- Merge #987: skip edns frag retry if advertised udp payload size is
  not smaller.
2024-01-05 13:47:30 +01:00
Wouter WijngaardsandGitHub 52a76583c5 Merge pull request #987 from borisVanhoof/skip_edns_frag_retry
skip edns frag retry if advertised udp payload size is not smaller
2024-01-05 13:47:15 +01:00
sahnalys12 b1d02cc94f skip edns frag retry if advertised udp payload size is not smaller
If serviced query is in UDP_EDNS_FRAG mode, and EDNS_ADVERTISED_SIZE
is 1232 (the default) or more, then the retry will have the same edns
udp payload size with the same result.
2024-01-05 12:16:23 +01:00
W.C.A. Wijngaards b9b488b6d3 - Remove unneeded newlines and improve indentation in remote control
code.
2024-01-04 17:06:15 +01:00
W.C.A. Wijngaards 9a2d0238a8 - Fix #983: Sha1 runtime insecure change was incomplete. 2024-01-03 13:33:43 +01:00
W.C.A. Wijngaards 5cc21690eb Changelog note for #985.
- Merge #985: Add DoH and DoT to dnstap message.
2024-01-03 10:37:44 +01:00
Wouter WijngaardsandGitHub f80f65d58c Merge pull request #985 from k-akashi/dnstap_dot_doh
Add DoH and DoT to dnstap message
2024-01-03 10:36:38 +01:00
W.C.A. Wijngaards df284fbe65 Changelog note for #979 and #980.
- Merge #980: DoH: reject non-h2 early. To fix #979: Improve errors
  for non-HTTP/2 DoH clients.
2024-01-03 10:04:06 +01:00
Wouter WijngaardsandGitHub b632ebf129 Merge pull request #980 from jsha/reject-non-h2
DoH: reject non-h2 early
2024-01-03 09:59:15 +01:00
k-akashi 4b9cd8e81d Add DoH and DoT to dnstap message 2023-12-27 07:26:21 +09:00
Yorgos Thessalonikefs 6c82f4ae9b - Update example.conf with cookie options. 2023-12-22 11:42:20 +01:00
Jacob Hoffman-Andrews 87644fa46b DoH: reject non-h2 early
Previously, non-h2 connections would be accepted, and then error out
with a verbose message "http2: session_recv from ____ failed,
error: Received bad client magic byte string". Instead, we can detect
absence of h2 support at connection time and reject with a clearer
verbose message.
2023-12-13 16:58:44 -08:00
W.C.A. Wijngaards 22dc376392 Fixup doc/Changelog. 2023-12-08 17:17:23 +01:00
W.C.A. Wijngaards 4ef1fb5a24 - Fix root_zonemd unit test, it checks that the root ZONEMD verifies,
now that the root has a valid ZONEMD.
2023-12-08 17:15:35 +01:00
Yorgos Thessalonikefs be6fd80a1c - Merge PR #973: Use the origin (DNAME) TTL for synthesized CNAMEs as per RFC 6672. 2023-12-08 09:23:26 +01:00
W.C.A. Wijngaards c48a467b8e Changelog note for #975
- Merge #975: Fixed some syntax errors in rpl files.
2023-12-07 12:11:03 +01:00
Wouter WijngaardsandGitHub 557edbb84a Merge pull request #975 from NLnetLabs/testdata-syntax
Fixed some syntax errors in rpl files.
2023-12-07 12:10:40 +01:00
Philip Homburg 0cfc6e6d95 Fixed some syntax errors in rpl files. 2023-12-07 11:38:01 +01:00
W.C.A. Wijngaards 2978106991 - Fix #974: doc: default number of outgoing ports without libevent. 2023-12-07 09:41:03 +01:00
Yorgos Thessalonikefs 8517f49745 - Use the origin (DNAME) TTL for syntesized CNAMEs as per RFC 6672. 2023-12-06 23:40:01 +01:00
W.C.A. Wijngaards 6c76b4e2f8 - Fix tests to use new common.sh functions, wait_logfile and
kill_from_pidfile.
2023-12-06 16:32:06 +01:00
W.C.A. Wijngaards c91bd60051 - Update test script file common.sh. 2023-12-06 16:14:24 +01:00
W.C.A. Wijngaards a8739bad76 - Updated IPv4 and IPv6 address for b.root-servers.net in root hints. 2023-12-06 13:25:58 +01:00
W.C.A. Wijngaards 2b97442f2e - iana portlist update. 2023-12-06 13:22:35 +01:00
W.C.A. Wijngaards 5997355e22 - Fix to sync the tests script file common.sh. 2023-12-06 11:58:14 +01:00
W.C.A. Wijngaards d8bd9845cc - Fix dnstap that assertion failed on logging other than UDP and TCP
traffic. It lists it as TCP traffic.
2023-12-05 13:14:08 +01:00
W.C.A. Wijngaards 3d1bc143af - Fix #969: [FR] distinguish Do53, DoT and DoH in the logs. 2023-12-05 10:05:51 +01:00
W.C.A. Wijngaards 72a25f825c Changelog note for #971
- Merge #971: fix 'WARNING: Message has 41 extra bytes at end'.
2023-12-05 09:09:42 +01:00
Wouter WijngaardsandGitHub c4e0354876 Merge pull request #971 from dukeartem/master
fix 'WARNING: Message has 41 extra bytes at end'
2023-12-05 09:09:23 +01:00
ArtemandGitHub 389e820878 fix 'WARNING: Message has 41 extra bytes at end' 2023-12-05 09:43:15 +03:00
Yorgos Thessalonikefs a2f0186427 - Merge #968: Replace the obsolescent fgrep with grep -F in tests. 2023-11-27 16:47:13 +01:00
W.C.A. Wijngaards 58d670a258 - Fix #964: config.h.in~ backup file in release tar balls. 2023-11-27 16:04:33 +01:00
Yorgos Thessalonikefs ca88669435 - Replace the obsolescent fgrep with grep -F in tests. 2023-11-24 15:51:17 +01:00
Yorgos Thessalonikefs 15a9b0f2be - Use 127.0.0.1 explicitly in tests to avoid delays and errors on newer
systems.
2023-11-24 15:34:25 +01:00
W.C.A. Wijngaards 197bf15402 - Fix unit test parse of origin syntax. 2023-11-09 15:26:46 +01:00
W.C.A. Wijngaards 0bae242cbf - The repository continues with 1.19.1. 2023-11-08 10:59:25 +01:00
W.C.A. Wijngaards 3352b1090e - Set version number to 1.19.0.
- Tag for 1.19.0rc1 release.
2023-11-02 08:40:20 +01:00
W.C.A. Wijngaards c4d17dd231 - Fix compilation without openssl, remove unused function warning. 2023-11-01 17:09:37 +01:00
W.C.A. Wijngaards 5f78f67e39 - Fix SSL compile failure for other missing definitions in
log_crypto_err_io_code_arg.
2023-11-01 14:20:52 +01:00
W.C.A. Wijngaards b1d99bb6b6 - Fix SSL compile failure for definition in log_crypto_err_io_code_arg. 2023-11-01 14:14:02 +01:00
George Thessalonikefs 8914e9fd03 - Mention flex and bison in README.md when building from repository
source.
2023-11-01 13:57:06 +01:00
George Thessalonikefs 8d1d728d88 - Fix #941: dnscrypt doesn't work after upgrade to 1.18 with
suggestion by dukeartem to also fix the udp_ancil with dnscrypt.
2023-10-31 22:41:06 +01:00
George Thessalonikefs 59c14c747a Changelog entry for #930
- Merge #930 from Stuart Henderson: add void to
  log_ident_revert_to_default declaration.
2023-10-30 12:18:01 +01:00
Yorgos ThessalonikefsandGitHub ccdf29a5f8 Merge pull request #930 from sthen/patch-1
add void to log_ident_revert_to_default declaration
2023-10-30 11:53:39 +01:00
W.C.A. Wijngaards a7e079ea16 - autoconf. 2023-10-30 10:44:23 +01:00
George Thessalonikefs a97bed9d22 - Clearer configure text for missing protobuf-c development libraries. 2023-10-24 16:34:12 +02:00
W.C.A. Wijngaards 0ce68e97a7 Changelog entry for #951.
- Merge #951: Cachedb no store. The cachedb-no-store: yes option is
  used to stop cachedb from writing messages to the backend storage.
  It reads messages when data is available from the backend. The
  default is no.
2023-10-20 17:01:13 +02:00
Wouter WijngaardsandGitHub 3f66230874 Merge pull request #951 from NLnetLabs/cachedb-no-store
Cachedb no store
2023-10-20 17:00:13 +02:00
W.C.A. Wijngaards 35d0a8a843 - Fix to print detailed errors when an SSL IO routine fails via
SSL_get_error.
2023-10-19 11:17:32 +02:00
George Thessalonikefs 44c3d4d2dc - Changelog entry for:
Merge #955 from buevsan: fix ipset wrong behavior.
- Update testdata/ipset.tdir test for ipset fix.
2023-10-18 15:11:38 +02:00
Yorgos ThessalonikefsandGitHub 167772fbca Merge pull request #955 from buevsan/fix-ipset
fix ipset wrong behavior
2023-10-18 15:08:08 +02:00
George Thessalonikefs 2f0b11673a - Update the dns64_lookup.rpl test for the DNS64 fallback patch. 2023-10-18 12:59:54 +02:00
George Thessalonikefs c5aa6a2286 - Changelog entry for DNS64 patches from Daniel Gröber. 2023-10-18 12:16:35 +02:00
George Thessalonikefs d5522c3480 Fixes for dns64 fallback to plain AAAA when no A records:
- Cleanup if condition.
- Rename variable for readability.
2023-10-18 12:03:40 +02:00
Daniel Gröber via Unbound-usersandGeorge Thessalonikefs c1e5e6781e dns64: Fall back to plain AAAA query with synthall but no A records
Networks which only have tunneled IPv6 access but still want to go
IPv6-only internally can use unbound's DNS64 module together with the
dns64-synthall or dns64-ignore-aaaa options to direct most traffic (any
dualstack domain) to their NAT64.

There is only one problem with this setup, currently domains with only AAAA
records will fail to resolve.

To allow for this use-case arrange for the A sub-query to make the AAAA
super query advance along the module stack when no records are returned.

Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
2023-10-18 12:03:40 +02:00
George Thessalonikefs dd086e5bfd Fixes for dns64 readability refactoring:
- Move declarations to the top for C90 compliance.
- Save cycles by not calling (yet) unneeded functions.
- Possible use of uninitialised value.
- Consistent formatting.
2023-10-18 12:03:40 +02:00
Daniel Gröber via Unbound-usersandGeorge Thessalonikefs 213bb7c6ed dns64: Fix misleading indentation
Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
2023-10-18 12:03:40 +02:00
Daniel Gröber via Unbound-usersandGeorge Thessalonikefs 0c88f98a3b dns64: Refactor handle_event checks for readability
No functional change intended.

Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
2023-10-18 12:03:40 +02:00
Alexander V. Buev 23ae0a9838 fix ipset wrong behavior
Issue description:

    If local zone directive is assigned as following:

      "local-zone domain.com ipset"

    then any answers for query with names such as
    "anytext1domain.com" or "example2domain.com"
    will be added to ipset.

  This commit fixes this issue.
2023-10-17 18:35:42 +03:00
W.C.A. Wijngaards 0f78bea4a3 - Fix #954: Inconsistent RPZ handling for A record returned along with
CNAME.
2023-10-17 16:47:04 +02:00
George Thessalonikefs 4b627bd29e - Update pymod tests for the new Python script variable. 2023-10-16 16:32:09 +02:00
George Thessalonikefs e4510c76e5 - For multi Python module setups, clean previously parsed module
functions in __main__'s dictionary, if any, so that only current
  module functions are registered.
2023-10-16 16:03:11 +02:00
George Thessalonikefs 122dd6c11e - Expose the configured listening and outgoing interfaces, if any, as
a list of strings in the Python 'config_file' class instead of the
  current Swig object proxy; fixes #79.
2023-10-16 15:53:47 +02:00
George Thessalonikefs 63a5280f8f - Expose the script filename in the Python module environment 'mod_env'
instead of the config_file structure which includes the linked list
  of scripts in a multi Python module setup; fixes #79.
2023-10-16 15:47:18 +02:00
George Thessalonikefs 07149f576a - Better fix for infinite loop when reading multiple lines of input on
a broken remote control socket, by treating a zero byte line the
  same as transmission end. Addesses #947 and #948.
2023-10-13 14:58:16 +02:00
dbd2a43ab1 Apply suggestions from code review
Co-authored-by: Yorgos Thessalonikefs <george@nlnetlabs.nl>
2023-10-13 13:46:52 +02:00
W.C.A. Wijngaards 4a211a9117 - cachedb-no-store, example conf and man page documentation. 2023-10-13 11:37:18 +02:00
W.C.A. Wijngaards 18ebe165ba Merge branch 'master' into cachedb-no-store 2023-10-12 14:51:12 +02:00
W.C.A. Wijngaards 908e1cb11a Changelog note for #944.
- Merge #944: Disable EDNS DO.
  Disable the EDNS DO flag in upstream requests. This can be helpful
  for devices that cannot handle DNSSEC information. But it should not
  be enabled otherwise, because that would stop DNSSEC validation. The
  DNSSEC validation would not work for Unbound itself, and also not
  for downstream users. Default is no. The option
  is disable-edns-do: no
2023-10-12 14:05:31 +02:00
Wouter WijngaardsandGitHub 5c6c57ed89 Merge pull request #944 from NLnetLabs/disable-edns-do
Disable EDNS DO
2023-10-12 14:04:29 +02:00
W.C.A. Wijngaards 47094fd83f Merge branch 'master' into cachedb-no-store 2023-10-11 13:51:34 +02:00
W.C.A. Wijngaards 67153f897e - Fix for #949: Fix pythonmod/ubmodule-tst.py for Python 3.x. 2023-10-11 13:47:28 +02:00
W.C.A. Wijngaards f2528dc3ac - Fix that cachedb does not warn when serve-expired is disabled about
use of serve-expired-reply-ttl and serve-expired-client-timeout.
2023-10-11 13:29:56 +02:00
W.C.A. Wijngaards 935bc162e1 - cachedb-no-store, unit test cachedb_no_store.tdir. 2023-10-11 12:01:55 +02:00
W.C.A. Wijngaards d5954aff08 - Fix #949: "could not create control compt". 2023-10-11 11:59:26 +02:00
George Thessalonikefs e98b89651e - Fix #850: [FR] Ability to use specific database in Redis, with new
redis-logical-db configuration option.
2023-10-11 11:44:55 +02:00
George Thessalonikefs 516f90abdb - Fix infinite loop when reading multiple lines of input on a broken
remote control socket. Addesses #947 and #948.
2023-10-10 15:17:48 +02:00
W.C.A. Wijngaards c09320c651 - Fix that printout of EDNS options shows the EDNS cookie option by
name.
2023-10-09 12:36:54 +02:00
W.C.A. Wijngaards 6d0812b567 - Fix edns subnet so that queries with a source prefix of zero cause
the recursor send no edns subnet option to the upstream.
2023-10-09 12:21:22 +02:00
b05154218c Update doc/unbound.conf.5.in
Co-authored-by: Yorgos Thessalonikefs <george@nlnetlabs.nl>
2023-10-06 16:40:34 +02:00
c8ae3de610 Update validator/validator.c
Co-authored-by: Yorgos Thessalonikefs <george@nlnetlabs.nl>
2023-10-06 16:39:33 +02:00
W.C.A. Wijngaards ae96aa0a6d - cachedb-no-store, implement cachedb-no-store: yes configuration option. 2023-10-06 13:22:10 +02:00
W.C.A. Wijngaards 1e85749e6e Merge branch 'master' into disable-edns-do 2023-10-05 15:57:41 +02:00
W.C.A. Wijngaards b624ed5050 - disable-edns-do, validator init prints warning when disable-edns-do is
turned on, but there are trust anchors, and then turns off disable-edns-do.
2023-10-05 14:33:22 +02:00
W.C.A. Wijngaards b865aca03a - Fix #946: Forwarder returns servfail on upstream response noerror no
data.
2023-10-04 18:16:22 +02:00
W.C.A. Wijngaards 2e7714e80c - disable-edns-do, unbound-checkconf warns about disable-edns-do and DNSSEC
validation that is enabled, and suggests to turn one off.
2023-10-04 15:28:52 +02:00
W.C.A. Wijngaards 39df4f0923 - disable-edns-do, queriers receive no EDNS in response if the
disable-edns-do option is enabled and they set the DO flag. And unit test
  for that.
2023-10-04 13:54:05 +02:00
W.C.A. Wijngaards eff3e01ec3 Merge branch 'master' into disable-edns-do 2023-10-04 13:34:47 +02:00
George Thessalonikefs 13d4504dfc - Merge #881: Generalise the proxy protocol code. 2023-10-03 14:51:50 +02:00
George Thessalonikefs 9342bf685e - Fix misplaced comment. 2023-10-02 16:13:23 +02:00
George Thessalonikefs f804c087e4 proxy-protocol, review comments:
- more generic switch statement for address families;
- comment the protocol values as such in their definitions;
- less hardcoded values for address family and protocol combinations.
2023-09-29 17:31:52 +02:00
W.C.A. Wijngaards 0102360e92 root-zonemd-test, add test for ZONEMD usage from the root zone,
currently with the unsupported algorithm.
2023-09-29 16:03:08 +02:00
W.C.A. Wijngaards ca481322d4 Merge branch 'master' into disable-edns-do 2023-09-28 16:49:01 +02:00
W.C.A. Wijngaards 654a7eab62 - Fix #942: 1.18.0 libunbound DNS regression when built without
OpenSSL.
2023-09-22 13:15:35 +02:00
W.C.A. Wijngaards 4e5b0b7eec - disable-edns-do, unit test checks lookup without EDNS DO flag. 2023-09-22 11:39:39 +02:00
W.C.A. Wijngaards 9aaafddf04 - disable-edns-do, the option turns of the EDNS DO flag when a message is
sent from the iterator.
2023-09-20 13:28:06 +02:00
W.C.A. Wijngaards 9cd282e001 Merge branch 'master' into disable-edns-do 2023-09-20 13:18:26 +02:00
W.C.A. Wijngaards bd5dc855af - Fix rpz tcp-only action with rpz triggers nsdname and nsip. 2023-09-18 09:55:39 +02:00
W.C.A. Wijngaards 31218166fc - Fix to remove two c99 notations. 2023-09-15 13:30:30 +02:00
W.C.A. Wijngaards 6bdecdbc5a Changelog note and autoconf for #936
- Merge #936: Check for c99 with autoconf versions prior to 2.70.
2023-09-15 13:24:20 +02:00
Wouter WijngaardsandGitHub 45e6e71652 Merge pull request #936 from fobser/c99
Check for c99 with autoconf versions prior to 2.70
2023-09-15 13:23:28 +02:00
Florian Obser 3abb32c3ba Check for c99 with autoconf versions prior to 2.70 2023-09-15 13:00:17 +02:00
W.C.A. Wijngaards 6e65343895 - Fix authority zone answers for obscured DNAMEs and delegations. 2023-09-14 11:37:49 +02:00
W.C.A. Wijngaards d1977c679b - disable-edns-do, doc and add option disable-edns-do: no. 2023-09-13 13:11:53 +02:00
W.C.A. Wijngaards 0ee44ef384 - Fix send of udp retries when ENOBUFS is returned. It stops looping
and also waits for the condition to go away. Reported by Florian
  Obser.
2023-09-08 13:35:42 +02:00
Philip Homburg 1c8f0e0fc5 Avoid calling comm_point_udp_ancil_callback from comm_point_create_udp 2023-09-07 16:35:22 +02:00
Philip Homburg 17a557dfd5 Fix #928 (1.18 doesn't start on macOS/SunOS) 2023-09-07 16:35:22 +02:00
W.C.A. Wijngaards 8c751d48a2 - Fix to print EDE text in readable form in output logs. 2023-09-07 15:28:01 +02:00
W.C.A. Wijngaards 5b8a7340bb - Fix to set ede match in unit test for rr length removal.
Changelog note.
2023-09-07 14:59:13 +02:00
W.C.A. Wijngaards 33784e612a - Fix to set ede match in unit test for rr length removal. 2023-09-07 14:58:51 +02:00
W.C.A. Wijngaards fdd5f8ff83 - Fix to add EDE text when RRs have been removed due to length. 2023-09-07 14:44:48 +02:00
W.C.A. Wijngaards 63616a5fce - Fix to move msgparse_rrset_remove_rr code to util/msgparse.c. 2023-09-07 11:29:53 +02:00
W.C.A. Wijngaards dfc00271d1 - Fix to scrub resource records of type A and AAAA that have an
inappropriate size. They are removed from responses.
2023-09-07 11:08:04 +02:00
W.C.A. Wijngaards 1143050ea6 Changelog note for #931
- Merge #931: Prevent warnings from -Wmissing-prototypes.
2023-09-06 09:49:35 +02:00
Wouter WijngaardsandGitHub 5ab4a9330a Merge pull request #931 from fobser/missing-prototypes
Prevent warnings from -Wmissing-prototypes.
2023-09-06 09:49:23 +02:00
Florian Obser 2cd7c719ef Prevent warnings from -Wmissing-prototypes. 2023-09-05 17:35:30 +02:00
Stuart HendersonandGitHub ed00129866 add void to log_ident_revert_to_default declaration
Avoid warning from LLVM 16:

util_log.c:190:33: warning: a function declaration without a prototype is deprecated in all versions of C             
[-Wstrict-prototypes]                                                                                                 
void log_ident_revert_to_default()                                                                                    
                                ^                                                                                     
                                 void
2023-09-05 14:28:06 +00:00
W.C.A. Wijngaards 10843805ac - Fix #927: unbound 1.18.0 make test error. Fix make test without SHA1. 2023-08-31 13:54:03 +02:00
W.C.A. Wijngaards f0e15272b2 - Fix autoconf 2.69 warnings in configure. 2023-08-31 09:19:24 +02:00
W.C.A. Wijngaards d4c4537b33 - Fix for WKS call to getservbyname that creates allocation on exit
in unit test by testing numbers first and testing from the services
  list later.
2023-08-30 14:31:24 +02:00
W.C.A. Wijngaards ba1183bb6e Tag 1.18.0rc1 became the 1.18.0 release on
30 aug 2023, with the fix from 25 aug, fix compile on NetBSD
included. The repository continues with version 1.18.1.
2023-08-30 11:03:42 +02:00
W.C.A. Wijngaards 85ee5284f5 - Fix for version generation race condition that ignored changes. 2023-08-28 13:25:04 +02:00
W.C.A. Wijngaards 3795e37410 - Fix compile error on NetBSD in util/netevent.h. 2023-08-25 08:43:27 +02:00
W.C.A. Wijngaards d396d8dae3 - Tag for 1.18.0rc1 release. 2023-08-23 10:49:45 +02:00
W.C.A. Wijngaards 8da117b086 - Set version number to 1.18.0. 2023-08-22 14:32:51 +02:00
W.C.A. Wijngaards 6e43145382 - Fix unit test for unbound-control to work when threads are disabled,
and fix cache dump check.
2023-08-21 16:58:10 +02:00
W.C.A. Wijngaards be53e37b15 - Fix #923: processQueryResponse() THROWAWAY should be mindful of
fail_reply.
2023-08-21 14:32:13 +02:00
W.C.A. Wijngaards 3160d6ac08 - Fix for #925: unbound.service: Main process exited, code=killed,
status=11/SEGV. Fixes cachedb configuration handling.
2023-08-21 11:28:49 +02:00
W.C.A. Wijngaards d1f388ec93 - Fix windows ci workflow to install bison and flex. 2023-08-21 10:43:02 +02:00
W.C.A. Wijngaards 5bd07f8e88 Further debug for windows ci workflow. 2023-08-21 10:20:23 +02:00
W.C.A. Wijngaards 3ea6f730ac - Debug Windows ci workflow. 2023-08-21 10:16:00 +02:00
W.C.A. Wijngaards 083770cb39 - Fix stat_values test to work with dig that enables DNS cookies. 2023-08-18 13:39:27 +02:00
W.C.A. Wijngaards 8756ad63dd - Fix uninitialized memory passed in padding bytes of cmsg to sendmsg. 2023-08-18 13:18:46 +02:00
W.C.A. Wijngaards c4566aa5d3 Changelog for commit.
- Fix for iter_dec_attempts that could cause a hang, part of
  capsforid and qname minimisation, depending on the settings.
2023-08-18 13:10:51 +02:00
W.C.A. Wijngaards 2791ccbe02 - Fix for iter_dec_attempts that could cause a hang, part of
capsforid and qname minimisation, depending on the settings.
2023-08-18 09:11:06 +02:00
W.C.A. Wijngaards 5f423906de - Fix ip_ratelimit test to work with dig that enables DNS cookies. 2023-08-17 15:43:14 +02:00
W.C.A. Wijngaards 4844fa3481 - Fix regional_alloc_init for potential unaligned source of the copy. 2023-08-17 15:22:54 +02:00
W.C.A. Wijngaards 0f5fecd516 Changelog note for #762.
- Merge PR #762: Downstream DNS Server Cookies a la RFC7873 and
  RFC9018. Create server cookies for clients that send client cookies.
  This needs to be explicitly turned on in the config file with:
  `answer-cookie: yes`. A `cookie-secret:` can be configured for
  anycast setups. Without one, a random cookie secret is generated.
  The acl option `allow_cookie` allows queries with either a valid
  cookie or over a stateful transport. The statistics output has
  `queries_cookie_valid` and `queries_cookie_client` and
  `queries_cookie_invalid` information. The `ip\-ratelimit\-cookie:`
  value determines a rate limit for queries with cookies, if desired.
2023-08-17 15:18:46 +02:00
Wouter WijngaardsandGitHub a1c82ac5fd Merge pull request #762 from NLnetLabs/features/downstream-cookies
Downstream DNS Server Cookies a la RFC7873 and RFC9018
2023-08-17 15:14:11 +02:00
W.C.A. Wijngaards 1c85901cc4 - Fix out of bounds read in parse_edns_options_from_query, it would read
8 bytes after a client option of length 8, and then ignore them to
  recreate a 24 byte response. The fixup does not read out of bounds,
  and puts zeroes in the buffer at that point, that then are ignored.
2023-08-16 16:58:49 +02:00
W.C.A. Wijngaards b1c707e551 - Fix possibly unaligned memory access. 2023-08-16 14:57:38 +02:00
W.C.A. Wijngaards 2b1028bdad - Fix possibly unaligned memory access. 2023-08-16 10:06:06 +02:00
George Thessalonikefs bab5ad623c - For #762: Introduce stat counters for downstream DNS Cookies per
thread and total: num.queries_cookie_valid, num.queries_cookie_client,
  num.queries.cookie_invalid.
2023-08-08 15:19:56 +02:00
George Thessalonikefs 49e4258102 - For #762: Interaction between DNS Cookies and source IP ratelimiting
by allowing Cookies to bypass the ratelimit, but still allowing
  ratelimit to valid DNS Cookie clients via the new
  ip-ratelimit-cookie option.
2023-08-08 10:14:03 +02:00
George Thessalonikefs 81e219827e - For #762: Silence maybe-uninitialized compiler warning. 2023-08-07 11:20:48 +02:00
George Thessalonikefs 02ac374640 - For #762: Remove re-introduced files from merge (configlexer.c, configparser.c, configparser.h). 2023-08-07 11:12:49 +02:00
George Thessalonikefs 025d810b45 - For #762: annotate case statement fallthrough for gcc. 2023-08-07 11:04:23 +02:00
George Thessalonikefs 4ccb613396 Merge branch 'master' into features/downstream-cookies 2023-08-05 20:37:48 +02:00
George Thessalonikefs 9025be814a - For #762: remove uneeded include. 2023-08-05 20:18:56 +02:00
George Thessalonikefs fbc0256825 - For #762: Cleaner manpage text and uniform use of the term DNS
Cookies.
2023-08-05 20:00:37 +02:00
George Thessalonikefs 8580a74b37 - For #762: Introduce rpl testing for DNS Cookies. 2023-08-05 19:50:57 +02:00
George Thessalonikefs b6e2f4dbf8 - For #762: Formatting. 2023-08-04 19:03:23 +02:00
George Thessalonikefs 702f485587 - For #762: relocate EDNS cookie code to util/edns and introduce unit
tests.
2023-08-04 14:26:08 +02:00
George Thessalonikefs 6e47c1e05b - For #762: remove relocated code. 2023-08-02 15:51:05 +02:00
George Thessalonikefs d4145772b5 - Move a cache reply callback in worker.c closer to the cache reply
generation.
2023-08-02 12:33:52 +02:00
George Thessalonikefs 00a08beee9 - For #762: Ignore util/siphash.c for the 01-doc test. 2023-08-01 17:40:49 +02:00
George Thessalonikefs 5b55a46550 - For #762: relocate RFC 1982 serial number arithmetic functions to their own
file in util/rfc_1982.[ch].
2023-08-01 17:26:14 +02:00
George Thessalonikefs 2cc9563cf8 - Fix to use the now cached EDE, if any, for CD_bit queries. 2023-08-01 15:23:25 +02:00
George Thessalonikefs 8aec671860 - More braces and formatting for Fix for EDNS EDE size calculation to
avoid future bugs.
2023-08-01 15:15:33 +02:00
W.C.A. Wijngaards 990b12bc8e - Fix for EDNS EDE size calculation. 2023-08-01 15:08:50 +02:00
George Thessalonikefs 11f12bc981 - Merge #911 from natalie-reece: Exclude EDE before other EDNS options when
there isn't enough space.
- For #911: Try to trim EXTRA-TEXT (and LDNS_EDE_OTHER options
  altogether) before giving up on attaching EDE options.
2023-08-01 10:01:18 +02:00
George Thessalonikefs 08e11284fb - For #911: Try to trim EXTRA-TEXT (and LDNS_EDE_OTHER options
altogether) before giving up on attaching EDE options.
2023-08-01 09:55:28 +02:00
W.C.A. Wijngaards f531011e85 - iana portlist update. 2023-07-31 10:24:43 +02:00
George Thessalonikefs d18813be30 - Merge #790 from Tom Carpay: Add support for EDE caching in cachedb
and subnetcache.
2023-07-31 10:18:10 +02:00
5f76e201f0 - For #790: Update formatting in cachedb/cachedb.c
Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2023-07-31 10:13:01 +02:00
George Thessalonikefs dcd0191d7e Merge branch 'master' of https://github.com/natalie-reece/unbound into natalie-reece-master 2023-07-31 09:57:21 +02:00
George Thessalonikefs 8936f3496e - For #790: clean testcase. 2023-07-31 09:41:57 +02:00
George Thessalonikefs f97927a47e Merge branch 'master' into features/ede-caching-cachedb 2023-07-30 14:17:52 +02:00
George Thessalonikefs 6819c1e444 - Merge #759 from Tom Carpay: Add EDE (RFC8914) caching. 2023-07-30 11:48:04 +02:00
George Thessalonikefs 6487d6febe - For #759: fix doc string. 2023-07-30 11:43:06 +02:00
George Thessalonikefs 373904f865 - Fix unused variable compile warning for kernel timestamps in
netevent.c
2023-07-28 20:17:07 +02:00
George Thessalonikefs 0912015fb9 - Review for #790: Fix memory leak. 2023-07-28 17:21:15 +02:00
George Thessalonikefs c15cfb4bd9 - Review for #790: Address Wouter's comments. 2023-07-28 16:55:51 +02:00
George Thessalonikefs 66c95e8081 - Review for #790: replace tdir tests with simpler rpl tests. 2023-07-28 16:54:05 +02:00
George Thessalonikefs 843fc69927 Address review comments for #759:
- Clear error text when an expected signature is missing.
2023-07-28 14:05:25 +02:00
George Thessalonikefs 50ea4a1072 Address review comments for #759:
- Decrease allocations for "" EDE strings when loading the cachedump.
- Check for existence of EDE code before attaching.
2023-07-28 12:56:13 +02:00
George Thessalonikefs 1e47eea6e3 - Merge #889 from borisVanhoof: Free memory in error case + remove
unused function.
2023-07-21 21:13:43 +02:00
George Thessalonikefs 6289238cd6 - For #889: Account for num_detached_states before possible
mesh_state_delete when erroring out.
2023-07-21 21:05:38 +02:00
George Thessalonikefs 97fdd0e2eb - For #889: use netcat-openbsd instead of netcat-traditional. 2023-07-21 21:04:40 +02:00
George Thessalonikefs 201da1f50a Merge branch 'free_memory_in_error_case' of https://github.com/borisVanhoof/unbound into borisVanhoof-free_memory_in_error_case 2023-07-21 17:04:33 +02:00
George Thessalonikefs 51c189394d - Cleaner failure code for callback functions in interface.i. 2023-07-21 16:53:36 +02:00
George Thessalonikefs 2e257fff2a - Merge #390 from Frank Riley: Add missing callbacks to the python
module.
2023-07-21 16:50:57 +02:00
George Thessalonikefs 4776f749be Merge branch 'python_add_missing_callbacks' of https://github.com/fhriley/unbound into fhriley-python_add_missing_callbacks 2023-07-21 15:19:12 +02:00
George Thessalonikefs 04053d39a0 - Merge #118 from mibere: Changed verbosity level for Redis init &
deinit.
2023-07-21 15:01:48 +02:00
mibereandGeorge Thessalonikefs ef9f7f113f Log established connection to Redis 2023-07-21 14:41:26 +02:00
mibereandGeorge Thessalonikefs 2d33bba3c0 Changed verbosity level for Redis init & deinit
Redis init & deinit are basic (operational) information
2023-07-21 14:39:34 +02:00
George Thessalonikefs 36b38cea74 - Merge #857 from eaglegai: fix potential memory leaks when errors
happen.
2023-07-21 14:04:38 +02:00
George Thessalonikefs 40f446a499 - For #857: fix mixed declarations and code. 2023-07-21 14:02:01 +02:00
George Thessalonikefs e839771ddf Merge branch 'master' of https://github.com/eaglegai/unbound into eaglegai-master 2023-07-21 12:43:47 +02:00
George Thessalonikefs ae2c2be1a5 Merge branch 'master' of github.com:NLnetLabs/unbound 2023-07-20 12:56:31 +02:00
George Thessalonikefs bf37487dca - Merge #901 from Sergei Trofimovich: config: improve handling of
unknown modules.
2023-07-20 12:56:20 +02:00
W.C.A. Wijngaards 8d45c1592b - For #909: Fix RR class comparison. 2023-07-20 12:16:24 +02:00
George Thessalonikefs 862fa0d514 Merge branch 'module-error' of https://github.com/trofi/unbound into trofi-module-error 2023-07-20 12:08:27 +02:00
George Thessalonikefs 27c028cf27 - Merge #909 from headshog: Numeric truncation when parsing TYPEXX and
CLASSXX representation.
- For #909: Fix return values.
2023-07-20 11:57:17 +02:00
George Thessalonikefs 5b7faca7db For #909: Numeric truncation when parsing TYPEXX and CLASSXX representation
- Fix return values.
- Formatting nits.
2023-07-20 11:42:05 +02:00
George Thessalonikefs d29bc712b1 Merge branch 'fix-numtrunc' of https://github.com/headshog/unbound into headshog-fix-numtrunc 2023-07-20 11:07:19 +02:00
headshog 0b131d5a31 parse sldns_get_rr_class_by_name and sldns_get_rr_type_by_name return value 0 2023-07-19 18:09:03 +03:00
George Thessalonikefs 90b434c260 - For #759: add support for cached EDEs to cachedump 2023-07-19 17:06:10 +02:00
George Thessalonikefs 846b158304 - Remove redundant checks when attaching EDE to a SERVFAIL answer. 2023-07-19 15:26:08 +02:00
George Thessalonikefs 95604a90e8 Review for #759:
- Keep EDE information for keys close to key creation.
- Fix inconsistencies between reply and cached EDEs.
- Incorporate EDE caching checks in EDE tests.
- Fix some EDE cases where missing DNSKEY was wrongly reported.
2023-07-19 15:20:44 +02:00
George Thessalonikefs f5a2a58ce3 Review for #759:
- Fix SEGFAULT in load_cache control command.
- Change reason_bogus_str to an explicit NULL-terminated string.
- Fix potential memory leak when discarding a message for referrals and
  0 TTL answers.
- Fix reason_bogus initialization in localzone answers.
- reply_info creation in validator is always regional.
2023-07-17 17:26:31 +02:00
headshog 78c284e05d fix numtrunc in str2wire.c 2023-07-17 12:58:52 +03:00
George Thessalonikefs 299f55b0d1 - More clear description of the different auth-zone behaviors on the
man page.
2023-07-14 15:28:42 +02:00
George Thessalonikefs 52f0387cac - Merge #880 from chipitsine: services/authzone.c: remove redundant
check.
2023-07-13 11:52:14 +02:00
George Thessalonikefs 606e5a0a5f Merge branch 'cleanup_cppcheck' of https://github.com/chipitsine/unbound into chipitsine-cleanup_cppcheck 2023-07-13 11:49:41 +02:00
George Thessalonikefs 15b8d8b96a Merge branch 'master' into features/ede-caching 2023-07-13 11:25:59 +02:00
Natalie Reece 67e52ea9c5 Exclude EDE before other EDNS options when there isn't enough space 2023-07-11 17:01:26 -06:00
George Thessalonikefs 7240ecbeb0 - Merge #664 from tilan7763: Add prefetch support for subnet cache
entries.
- For #664: Easier code flow for subnetcache prefetching.
- For #664: Add testcase.
- For #664: Rename subnet_prefetch tests to subnet_global_prefetch to
  differentiate from the new subnet prefetch support.
2023-07-11 14:31:49 +02:00
George Thessalonikefs a952ac17be Merge branch 'tilan7663-subnet_cache_prefetch' into subnet_cache_prefetch 2023-07-07 16:50:58 +02:00
George Thessalonikefs 40e47bf767 - For #664: easier code flow for subnetcache prefetching.
- For #664: add testcase.
2023-07-06 22:22:21 +02:00
George Thessalonikefs 0afe58a06e - Skip the 00-lint test. splint is not maintained; it either does not
work or produces false positives. Static analysis is handled in the
  clang test.
2023-07-03 15:38:16 +02:00
George Thessalonikefs 2069271384 - Merge #802: add validation EDEs to queries where the CD bit is set.
- For #802: Cleanup comments and add RCODE check for CD bit test case.
2023-07-03 14:48:39 +02:00
George Thessalonikefs 014db3fb03 - For #802: Cleanup comments and add RCODE check for CD bit test case. 2023-07-03 14:40:01 +02:00
W.C.A. Wijngaards 5aa47fb1fa - Fix dereference of NULL variable warning in mesh_do_callback. 2023-07-03 13:50:39 +02:00
George Thessalonikefs 1962991937 - Merge #739: Add SVCB dohpath support.
- Code cleanup for sldns_str2wire_svcparam_key_lookup.
2023-07-03 11:02:05 +02:00
George Thessalonikefs 5be7f1ef8a - Code cleanup for sldns_str2wire_svcparam_key_lookup. 2023-07-03 10:51:34 +02:00
W.C.A. Wijngaards 48a6ff14a4 - Fix #906: warning: ‘Py_SetProgramName’ is deprecated. 2023-07-03 10:23:37 +02:00
George Thessalonikefs ade710a9fd - For #739: minor cleanup for testcases. 2023-07-03 10:10:16 +02:00
George Thessalonikefs 31d38d2cfe Merge branch 'master' into features/dohpath-for-unbound 2023-06-30 11:50:23 +02:00
George Thessalonikefs 380e3de140 - Merge #827 from rcmcdonald91: Eliminate unnecessary Python reloading
which causes memory leaks.
2023-06-29 13:02:27 +02:00
George Thessalonikefs fc8bf269e9 - More fixes for reference counting for python module and clean up
failure code.
2023-06-29 12:26:49 +02:00
W.C.A. Wijngaards 7696074fa9 - Fix python modules with multiple scripts, by incrementing reference
counts.
2023-06-29 10:16:37 +02:00
George Thessalonikefs bea61fc37c - Remove warning about unknown cast-function-type warning pragma. 2023-06-27 16:44:29 +02:00
George Thessalonikefs 41dac805f5 - Merge #892: Add cachedb hit stat. Introduces 'num.query.cachedb' as
a new statistical counter.
2023-06-27 12:46:26 +02:00
W.C.A. Wijngaards 2207a55107 Add changelog and contrib/README mention for #903
- Merge #903: contrib: add yocto compatible init script.
2023-06-22 15:41:17 +02:00
Wouter WijngaardsandGitHub 196f8a68f6 Merge pull request #903 from beni-sandu/master
contrib: add yocto compatible init script
2023-06-22 15:37:07 +02:00
Beniamin Sandu 0d13b4ec4c contrib: add yocto compatible init script
Signed-off-by: Beniamin Sandu <beniaminsandu@gmail.com>
2023-06-22 14:18:45 +03:00
George Thessalonikefs f1537e2041 - For #762: please doxygen. 2023-06-22 12:21:27 +02:00
George Thessalonikefs 47cf44cc70 - For #762: relocate edns_opt_list_append_keepalive. 2023-06-22 12:11:28 +02:00
George Thessalonikefs 1cd75cccfc - For #762: More generic integration for siphash.c 2023-06-22 11:45:08 +02:00
Sergei Trofimovich d10a889a68 config: improve handling of unknown modules
The change fixes module print when specified module is unknown. On
example config:

    server:
      module-config: "respip valdator iterator"

Before the change printed error looked like:

    error: Unknown value in module-config, module: ''. This module is
    not present (not compiled in), See the list of linked modules with
    unbound -V

After the change module is printed as expected:

    error: Unknown value in module-config, module: 'valdator'. This
    module is not present (not compiled in), See the list of linked
    modules with unbound -V

Module truncation happens because parse error does not guarantee that
leading whitespace is removed by `module_factory()` call.

The change always removes leading whitespace (if present).
2023-06-19 18:20:22 +01:00
Philip Homburg 64476280ed Changelog for #887 and #516 2023-06-15 11:09:08 +02:00
Philip Homburg b1bcde3137 Merge branch 'freebsd-aslr-issue' 2023-06-15 11:06:29 +02:00
George Thessalonikefs b02f9befcd - For #762: fix compiler C90 warning. 2023-06-14 16:41:01 +02:00
George Thessalonikefs 0f1ea7e490 - Properly handle all return values of worker_check_request during
early EDE code.
- Do not check the incoming request more than once.
2023-06-14 11:40:59 +02:00
W.C.A. Wijngaards f9317d65b3 - Fix for uncertain unit test for doh buffer size events. 2023-06-12 12:39:00 +02:00
W.C.A. Wijngaards 2cf0359ffe Changelog note for #895
- Fix #895: python + sysconfig gives ANOTHER path comparing to
  distutils.
2023-06-12 10:39:44 +02:00
W.C.A. Wijngaards 35885e5a70 - Merge #896: Fix: #895: pythonmodule: add all site-packages
directories to sys.path.
2023-06-12 10:30:50 +02:00
Wouter WijngaardsandGitHub 0585b1d75a Merge pull request #896 from socketpair/bugfix
Fix: #895: pythonmodule: add all site-packages directories to sys.path
2023-06-12 10:30:05 +02:00
Коренберг Марк a25fc52818 Fix: #895: pythonmodule: add all site-packages directories to sys.path 2023-06-11 10:39:13 +03:00
Philip Homburg 52581f8644 Fix for issue #887 (Timeouts to forward servers on BSD based system with ASLR)
and proabbly #516 (Stream reuse does not work on Windows)
2023-06-09 13:59:31 +02:00
9412b9c2ca Review comment for daemon/stats.c
Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2023-06-02 12:39:23 +02:00
65230bd117 Review comment for testdata/stat_values.tdir/stat_values.test
Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2023-05-31 17:09:16 +02:00
George Thessalonikefs db5cf5851d - More efficient mesh accounting per client. 2023-05-30 23:34:31 +02:00
George Thessalonikefs 3c3fd7a795 - More predictable testing for cachedb. 2023-05-30 23:33:48 +02:00
George Thessalonikefs 4f52be4db9 - Introduce num.query.cachedb to track cache hits for the external cache. 2023-05-30 17:49:50 +02:00
W.C.A. Wijngaards 512236d705 - Fix unbound-dnstap-socket time fraction conversion for printout. 2023-05-25 16:27:19 +02:00
W.C.A. Wijngaards d57986724e - Fix unbound-dnstap-socket printout when no query is present. 2023-05-25 14:30:25 +02:00
Boris VANHOOF 4e39d3dfe1 could not find package netcat for docker container 2023-05-23 10:11:07 +02:00
Boris VANHOOF a21bc23139 free memory in error case 2023-05-23 09:23:03 +02:00
Boris VANHOOF 62d54d8091 remove unused function 2023-05-23 09:22:35 +02:00
Boris VANHOOF 17559c737b typo in comments 2023-05-23 09:21:58 +02:00
W.C.A. Wijngaards 59fd48c226 - Fix to remove unused variables from RPZ clientip data structure. 2023-05-19 16:36:31 +02:00
W.C.A. Wijngaards da78c42f88 - Fix RPZ removal of client-ip, nsip, nsdname triggers from IXFR. 2023-05-19 14:38:41 +02:00
W.C.A. Wijngaards a07ccbae9a - Fix to print debug log for ancillary data with correct IP address. 2023-05-16 09:21:21 +02:00
W.C.A. Wijngaards 2a2598dbf2 - Fix #888: [FR] Use kernel timestamps for dnstap. 2023-05-16 08:50:38 +02:00
W.C.A. Wijngaards 1fb78afc29 - Fix warning in windows compile, in set_recvtimestamp. 2023-05-11 09:32:59 +02:00
W.C.A. Wijngaards b2cba7b707 - Fix doxygen in addr_to_nat64 header definition. 2023-05-04 15:53:05 +02:00
W.C.A. Wijngaards 8dd09e31d2 - Fix to remove unused whitespace from acx_nlnetlabs.m4 and config.h. 2023-05-04 11:17:06 +02:00
W.C.A. Wijngaards 806c3d7330 - Fix #885: Error: util/configlexer.c: No such file or directory,
adds error messages explaining to install flex and bison.
2023-05-04 11:12:11 +02:00
W.C.A. Wijngaards cac1d13fda - Fix proxy-protocol to read header in multiple reads and check buffer size. 2023-05-02 14:54:51 +02:00
W.C.A. Wijngaards 80153decd1 - Fix proxy-protocol buffer checks when writing and read from buffer. 2023-05-02 14:36:29 +02:00
George Thessalonikefs 2695eb9d1a Changelog entry for #722:
- Merge #722 from David 'eqvinox' Lamparter: NAT64 support.
- For #722: minor fixes, formatting, refactoring.
2023-05-01 18:32:40 +02:00
George Thessalonikefs 20184483df Merge branch 'eqvinox-nat64' 2023-05-01 18:24:05 +02:00
George Thessalonikefs adb4aeb609 - For #722: Minor fixes, formatting and refactoring. 2023-05-01 18:23:13 +02:00
W.C.A. Wijngaards 70c2b587fc - Fix RPZ IP responses with trigger rpz-drop on cache entries, that
they are dropped.
2023-05-01 09:26:17 +02:00
Philip Homburg a50ddd7ab9 Changelog for #860 2023-04-26 17:15:59 +02:00
Philip Homburg 4a04ba813a Merge branch '0ttl' 2023-04-26 17:14:15 +02:00
Philip Homburg 1aa2c318e7 Remove msg_del_for_0ttl, call msg_cache_remove directly 2023-04-26 17:11:29 +02:00
George Thessalonikefs e1ec3cf893 Merge branch 'nat64' of https://github.com/eqvinox/unbound into eqvinox-nat64 2023-04-26 15:14:39 +02:00
W.C.A. Wijngaards 8058dc9127 - Fix for #882: document variable to stop doxygen warning. 2023-04-26 14:07:33 +02:00
W.C.A. Wijngaards 144f29638c - Fix for #882: small changes, date updated in Copyright for
util/timeval_func.c and util/timeval_func.h. Man page entries and
  example entry.
2023-04-26 13:49:33 +02:00
Wouter WijngaardsandGitHub 7081b0340f Merge pull request #882 from vvfedorenko/features/dropqueuedpackets
Features/dropqueuedpackets
2023-04-26 13:25:32 +02:00
Vadim Fedorenko 263096d1f6 stats: add query max wait time metric
Add new statistic value to know the size of the queue in microseconds.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-26 03:27:25 -07:00
Vadim Fedorenko e577ab105e stats: add counter for timed out queries
Add counter `num_queries_timed_out` meaning queries that were sitting in the
socket queue and waiting to being processed too long. There is no reason
to process such queries, so let's drop it in the very beginning of the
pipeline.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-26 03:27:25 -07:00
Vadim Fedorenko 04540f82e5 config: add sock_queue_timeout configuration
Add sock_queue_timeout config option to have queue timeout configurable.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-26 03:27:19 -07:00
Vadim Fedorenko 2e6ddd6032 netevent: parse and store rcv timestamp from sock
Add special field in comm_point to store the software receive timestamp
for every particular UDP packet. Aux data parser is updated to read
values and the whole callback is switched to use recvmsg form.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-26 03:26:51 -07:00
Vadim Fedorenko a197aac2f6 timeval_func: move all timeval manipulation to separate file
There are several definitions of the same functions manipulating timeval
structures. Let's move them to separate file and arrange the code
preperly.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-26 03:23:41 -07:00
W.C.A. Wijngaards 15a2add0f8 streamtcp, implement NOTIFY[=N] that sends a notify packet. 2023-04-26 11:57:10 +02:00
Vadim Fedorenko 648ad4db6f Linting change.
Remove config parser/lexer code as it's rebuilded every time but can
break adding new config options.
Also clean up the code base to avoid mixing actual code changes and lint
issues.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
2023-04-25 17:05:00 -07:00
W.C.A. Wijngaards 4bcc0a0a7a streamtcp, implement IXFR=N queries, add documentation for proxy option. 2023-04-25 16:44:58 +02:00
W.C.A. Wijngaards 542f717bf9 - adjust generic proxy-protocol header for IPv6 support with ifdef. 2023-04-25 08:16:19 +02:00
George Thessalonikefs b5cc8b6c59 - Generalise the proxy protocol code 2023-04-24 16:15:56 +02:00
Ilya ShipitsinandGitHub cba1350886 services/authzone.c: remove redundant check
found by cppcheck

services\authzone.c:7513:12: style: Condition 'rrlist[i]' is always true [knownConditionTrueFalse]
2023-04-24 11:45:41 +02:00
W.C.A. Wijngaards fe46bc47d7 - Fix for #878: Invalid IP address in unbound.conf causes Segmentation
Fault on OpenBSD.
2023-04-19 09:56:31 +02:00
W.C.A. Wijngaards e11d206a82 Changelog entry for #875 and #874.
- Merge #875: change obsolete txt URL in unbound-anchor.c to point
  to RFC 7958, and Fix #874.
2023-04-14 11:19:25 +02:00
Wouter WijngaardsandGitHub 8de8c8f6f7 Merge pull request #875 from dyunwei/master
Changelog entry for #874
2023-04-14 11:17:43 +02:00
yunweiandGitHub 4954df5859 Changelog entry for #874
unbound-anchor is compliant with RFC 7958, and the XML format remains unchanged between the old draft and RFC 7958.  Update the comments to improve clarity.
2023-04-14 16:45:11 +08:00
W.C.A. Wijngaards a3ef9dd53b - Show build status for branch=master. 2023-04-13 11:29:53 +02:00
W.C.A. Wijngaards d6c33e1757 - Fix build badge, from failing travis link to github ci action link. 2023-04-13 11:22:11 +02:00
W.C.A. Wijngaards 7033234a48 - Fix for #870: Add test case for the qname minimisation and CNAME. 2023-04-06 10:04:04 +02:00
W.C.A. Wijngaards c7618a9b80 - Fix #870: NXDOMAIN instead of NOERROR rcode when asked for existing
CNAME record.
2023-04-04 10:06:16 +02:00
Philip Homburg 312035f58a Changelog for issue #676 2023-03-24 14:54:14 +01:00
Philip Homburg 7e6a7f310d Fix issue #676: Unencrypted query is sent when forward-tls-upstream: yes is
used without tls-cert-bundle

Model the behavior of unbound in unbound-host: always create a SSL context
2023-03-24 14:51:37 +01:00
Philip Homburg 1ac9b7548b Small fixes from Wouter's review 2023-03-23 15:15:54 +01:00
Philip Homburg eb7eff4fc7 Extra consistency check to make sure that when TLS is requested, either we
set up a TLS connection or we return an error.
2023-03-23 15:00:10 +01:00
Philip Homburg 072be3300f Tests for serve-expired in combination with new 0 TTL data. 2023-03-22 15:23:47 +01:00
Philip Homburg 9d7b1d3127 Fix issue #860: Bad interaction with 0 TTL records and serve-expired 2023-03-22 15:23:47 +01:00
Philip Homburg e850ca67f1 Changelog for issue #851 2023-03-21 13:54:27 +01:00
Philip Homburg 2a100ee9ee Fix issue #851: reserved identifier violation 2023-03-21 13:51:51 +01:00
W.C.A. Wijngaards 8f83c0a2cb - iana portlist update. 2023-03-20 14:55:55 +01:00
George Thessalonikefs d7e7761141 - Fix #812, fix #846, by using the SSL_OP_IGNORE_UNEXPECTED_EOF option
to ignore the unexpected eof while reading in openssl >= 3.
2023-03-17 14:39:37 +01:00
W.C.A. Wijngaards a97d7175a6 - Fix ssl.h include brackets, instead of quotes. 2023-03-16 15:40:43 +01:00
W.C.A. Wijngaards 4f25d75d4b - Fix unbound-dnstap-socket test program to reply the finish frame
over a TLS connection correctly.
2023-03-14 16:57:37 +01:00
eaglegai 184248eb0e fix memory leak in unbound-streamtcp when open_svr failed
==1927474== Memcheck, a memory error detector
==1927474== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1927474== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==1927474== Command: unbound-streamtcp -f localhost
==1927474==
fatal: bad server specs 'localhost'
==1927474==
==1927474== HEAP SUMMARY:
==1927474==     in use at exit: 131,186 bytes in 4 blocks
==1927474==   total heap usage: 5 allocs, 1 frees, 132,210 bytes allocated
==1927474==
==1927474== 40 bytes in 1 blocks are still reachable in loss record 1 of 4
==1927474==    at 0x483F751: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1927474==    by 0x1E0573: sldns_buffer_new (sbuffer.c:21)
==1927474==    by 0x11ECED: send_em (streamtcp.c:374)
==1927474==    by 0x11E6C1: main (streamtcp.c:585)
==1927474==
==1927474== 40 bytes in 1 blocks are still reachable in loss record 2 of 4
==1927474==    at 0x483F751: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1927474==    by 0x1E0573: sldns_buffer_new (sbuffer.c:21)
==1927474==    by 0x11ECFA: send_em (streamtcp.c:375)
==1927474==    by 0x11E6C1: main (streamtcp.c:585)
==1927474==
==1927474== 65,553 bytes in 1 blocks are still reachable in loss record 3 of 4
==1927474==    at 0x483F751: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1927474==    by 0x1E0583: sldns_buffer_new (sbuffer.c:27)
==1927474==    by 0x11ECED: send_em (streamtcp.c:374)
==1927474==    by 0x11E6C1: main (streamtcp.c:585)
==1927474==
==1927474== 65,553 bytes in 1 blocks are still reachable in loss record 4 of 4
==1927474==    at 0x483F751: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==1927474==    by 0x1E0583: sldns_buffer_new (sbuffer.c:27)
==1927474==    by 0x11ECFA: send_em (streamtcp.c:375)
==1927474==    by 0x11E6C1: main (streamtcp.c:585)
==1927474==
==1927474== LEAK SUMMARY:
==1927474==    definitely lost: 0 bytes in 0 blocks
==1927474==    indirectly lost: 0 bytes in 0 blocks
==1927474==      possibly lost: 0 bytes in 0 blocks
==1927474==    still reachable: 131,186 bytes in 4 blocks
==1927474==         suppressed: 0 bytes in 0 blocks
==1927474==
==1927474== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Signed-off-by: eaglegai <eaglegai@163.com>
2023-03-07 21:49:54 +08:00
eaglegai 319119943f fix potential memory leak in unbound-host when errors happen
==3709953== HEAP SUMMARY:
==3709953==     in use at exit: 276,541 bytes in 23 blocks
==3709953==   total heap usage: 29 allocs, 6 frees, 280,682 bytes allocated
==3709953==
==3709953== 1 bytes in 1 blocks are still reachable in loss record 1 of 23
==3709953==    at 0x4866EC0: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-arm64-linux.so)
==3709953==    by 0x48E2BC3: ub_initstate (random.c:85)
==3709953==    by 0x489B067: ub_ctx_create_nopipe (libunbound.c:114)
==3709953==    by 0x489B31F: ub_ctx_create (libunbound.c:180)
==3709953==    by 0x10E203: main (unbound-host.c:433)
==3709953==
......
==3709953== 8,192 bytes in 1 blocks are still reachable in loss record 22 of 23
==3709953==    at 0x4866EC0: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-arm64-linux.so)
==3709953==    by 0x48E427B: regional_create_custom (regional.c:94)
==3709953==    by 0x48DEA03: edns_strings_create (edns.c:57)
==3709953==    by 0x489B0F3: ub_ctx_create_nopipe (libunbound.c:157)
==3709953==    by 0x489B31F: ub_ctx_create (libunbound.c:180)
==3709953==    by 0x10E203: main (unbound-host.c:433)
==3709953==
==3709953== 262,144 bytes in 1 blocks are still reachable in loss record 23 of 23
==3709953==    at 0x486933C: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-arm64-linux.so)
==3709953==    by 0x48C826F: config_create (config_file.c:179)
==3709953==    by 0x48C85AF: config_create_forlib (config_file.c:383)
==3709953==    by 0x489B0BB: ub_ctx_create_nopipe (libunbound.c:130)
==3709953==    by 0x489B31F: ub_ctx_create (libunbound.c:180)
==3709953==    by 0x10E203: main (unbound-host.c:433)
==3709953==
==3709953== LEAK SUMMARY:
==3709953==    definitely lost: 0 bytes in 0 blocks
==3709953==    indirectly lost: 0 bytes in 0 blocks
==3709953==      possibly lost: 0 bytes in 0 blocks
==3709953==    still reachable: 276,541 bytes in 23 blocks
==3709953==         suppressed: 0 bytes in 0 blocks
==3709953==
==3709953== For lists of detected and suppressed errors, rerun with: -s
==3709953== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Signed-off-by: eaglegai <eaglegai@163.com>
2023-03-06 22:04:06 +08:00
Christian McDonald 60304f972e #827 review response 2023-02-24 09:31:19 -05:00
W.C.A. Wijngaards d97c174f50 - Fix for #852: Completion of error handling. 2023-02-23 13:38:29 +01:00
Philip Homburg ed07c5424d Changelog entry for issue #825 2023-02-21 09:29:39 +01:00
Philip Homburg fb187d1a60 Merge branch 'master' into ecs-serve-expired-bug 2023-02-21 09:28:13 +01:00
Philip Homburg 71e0ddc94a Improved comment 2023-02-21 09:27:03 +01:00
Philip Homburg b89d0d1cce Test cache update from serve-expired and client-subnet-always-forward 2023-02-21 09:21:43 +01:00
Philip Homburg d1f5ded1d9 ifdef CLIENT_SUBNET 2023-02-21 09:21:24 +01:00
Philip Homburg fb06364014 Fix issue #825: interaction between ECS and serve-expired. 2023-02-21 09:20:28 +01:00
George Thessalonikefs 02a77f0567 Changelog entry for
- Clean up iterator/iterator.c::error_response_cache() and allow for
  better interaction with serve-expired, prefetch and cached error
  responses.
2023-02-10 16:54:44 +01:00
George Thessalonikefs eb81761b13 - Clean up iterator/iterator.c::error_response_cache() and allow for
better interaction with serve-expired, prefetch and cached error
  responses.
2023-02-10 16:51:07 +01:00
George Thessalonikefs 96c70d91ca - Add testcase for refreshing expired error responses. 2023-02-09 12:44:01 +01:00
W.C.A. Wijngaards 488811157e - Fix to git ignore the library symbol file that configure can create. 2023-02-09 12:08:27 +01:00
W.C.A. Wijngaards e225e4bcab - Fix consistency of unit test without roundrobin answers for the
cnametooptout unit test.
2023-02-09 11:46:33 +01:00
George Thessalonikefs 1c1c5d72d3 Changelog entry for
- Allow TTL refresh of expired error responses.
2023-02-09 10:52:56 +01:00
George Thessalonikefs 87a8c80fcb - Allow TTL refresh of expired error responses. 2023-02-09 10:47:46 +01:00
W.C.A. Wijngaards a8977df4d9 - Fix unit tests for spurious empty messages. 2023-02-09 10:38:55 +01:00
W.C.A. Wijngaards 4953daa016 - Fix to ignore entirely empty responses, and try at another authority.
This turns completely empty responses, a type of noerror/nodata into
  a servfail, but they do not conform to RFC2308, and the retry can
  fetch improved content.
2023-02-09 09:56:40 +01:00
W.C.A. Wijngaards 5ab5b3b43a - Fix #841: Unbound won't build with aaaa-filter-iterator.patch. 2023-02-08 11:36:52 +01:00
Christian McDonald 0bf55e6063 set modinfo to null last 2023-02-01 15:17:59 -05:00
George Thessalonikefs 24e6d1e18e - Add duration variable for speed_local.test. 2023-01-30 11:33:58 +01:00
R. Christian McDonaldandGitHub 45142868ec Fix copyright date 2023-01-28 14:02:51 -05:00
W.C.A. Wijngaards 8b9382998d Regenerate configure for the fix acx_nlnetlabs.m4 for -Wstrict-prototypes. 2023-01-26 10:59:16 +01:00
W.C.A. Wijngaards c482999898 - Fix acx_nlnetlabs.m4 for -Wstrict-prototypes. 2023-01-26 10:54:38 +01:00
George Thessalonikefs 6bf677e7de Fix #833: [FR] Ability to set the Redis password. 2023-01-23 11:45:07 +01:00
W.C.A. Wijngaards d666e9bd13 - Fix #835: [FR] Ability to use Redis unix sockets. 2023-01-23 10:10:23 +01:00
W.C.A. Wijngaards 77f15428c9 - Add #835: [FR] Ability to use Redis unix sockets. 2023-01-23 10:09:28 +01:00
W.C.A. Wijngaards 111e66ae64 Changelog note for #819, generate configparser.c and comment syntax change.
- Merge #819: Added new static zone type block_a to suppress all A
  queries for specific zones.
2023-01-20 16:19:20 +01:00
Wouter WijngaardsandGitHub 6a4a9435d1 Merge pull request #819 from pavel-odintsov/pavel/suppress_a
Added new static zone type block_a to suppress all A queries for specific zones
2023-01-20 16:18:05 +01:00
R. Christian McDonaldandGitHub 55a28d6946 cleanup callbacks that might have been registered by Python script 2023-01-19 16:30:47 -05:00
R. Christian McDonaldandGitHub ddecffd918 Merge branch 'NLnetLabs:master' into rcm-python-reloading 2023-01-19 16:28:12 -05:00
W.C.A. Wijngaards 6afdc336ba - Fix test for new default. 2023-01-19 16:06:30 +01:00
W.C.A. Wijngaards c9233f8429 - Set default for harden-unknown-additional to no. So that it does
not hamper future protocol developments.
2023-01-19 15:45:10 +01:00
W.C.A. Wijngaards 8df1e58209 - Add harden-unknown-additional option. Default on and it removes
unknown records from the authority section and additional section.
  Thanks to Xiang Li, from NISL Lab, Tsinghua University.
2023-01-19 14:59:18 +01:00
W.C.A. Wijngaards d69f875261 - Set max-udp-size default to 1232. This is the same default value as
the default value for edns-buffer-size. It restricts client edns
  buffer size choices, and makes unbound behave similar to other DNS
  resolvers. The new choice, down from 4096 means it is harder to get
  large responses from Unbound. Thanks to Xiang Li, from NISL Lab,
  Tsinghua University.
2023-01-19 14:16:17 +01:00
W.C.A. Wijngaards b12ab31ae3 - Fix not following cleared RD flags potentially enables amplification
DDoS attacks, reported by Xiang Li and Wei Xu from NISL Lab,
  Tsinghua University. The fix stops query loops, by refusing to send
  RD=0 queries to a forwarder, they still get answered from cache.
2023-01-18 13:18:47 +01:00
Christian McDonald cfd3bcb21e eliminate unnecessary Python reloading which causes memory leaks 2023-01-13 16:39:28 -05:00
W.C.A. Wijngaards 90d42148de - Improve documentation for #826, describe the large collisions amount. 2023-01-13 11:22:47 +01:00
W.C.A. Wijngaards 469133e8df Changelog note and documentation for #826
- Merge #826: Аdd a metric about the maximum number of collisions in
  lrushah.
2023-01-13 11:01:46 +01:00
Wouter WijngaardsandGitHub 785c938106 Merge pull request #826 from sakateka/lruhash_max_collisions
Аdd a metric about the maximum number of collisions in lrushah
2023-01-13 10:57:44 +01:00
Sergey Kacheev 52a4ccee18 add a metric about the maximum number of collisions in lrushah 2023-01-13 13:33:38 +07:00
W.C.A. Wijngaards aa621f1c04 Code repository continues with version 1.17.2. 2023-01-12 10:21:28 +01:00
W.C.A. Wijngaards 0fed35a4b7 - Fix python version detection in configure. 2023-01-09 15:10:00 +01:00
W.C.A. Wijngaards 4517dcd439 - Fix python module install path detection. 2023-01-09 15:03:38 +01:00
W.C.A. Wijngaards c5c4f6d40b Changelog note for 1.17.1rc2 fix.
- Fix wildcard in hyperlocal zone service degradation, reported
  by Sergey Kacheev. This fix is included in 1.17.1rc2.
2023-01-06 13:23:02 +01:00
W.C.A. Wijngaards 0419b06ca4 Merge branch 'branch-1.17.1' 2023-01-06 13:22:06 +01:00
W.C.A. Wijngaards 90831af981 - Fix wildcard in hyperlocal zone service degradation, reported
by Sergey Kacheev.
2023-01-06 13:21:39 +01:00
W.C.A. Wijngaards ba6325f24f - Fix #823: Response change to NODATA for some ANY queries since
1.12, tested on 1.16.1.
2023-01-06 09:16:59 +01:00
W.C.A. Wijngaards 2025946247 Changelog note for tag for 1.17.1rc1.
- Tag for 1.17.1 release.
2023-01-05 11:06:07 +01:00
Alex BandandGitHub e92bd614c0 Add Mastodon link 2023-01-04 16:21:43 +01:00
Alex BandandGitHub f93fdb5e09 Add Mastodon 2023-01-04 15:57:45 +01:00
Pavel Odintsov d5b9a790fe Added new static zone type block_a to suppress all A queries for specific zones 2023-01-03 19:17:51 +00:00
W.C.A. Wijngaards 70260273a4 - Update github workflows to use checkout v3. 2023-01-02 13:30:03 +01:00
W.C.A. Wijngaards 1224cd9d25 - Fix windows compile for libunbound subprocess reap comm point closes. 2023-01-02 13:06:39 +01:00
George Thessalonikefs 0682d4371e - Merge #569 from JINMEI Tatuya: add keep-cache option to
'unbound-control reload' to keep caches.
2022-12-14 16:40:00 +01:00
George Thessalonikefs 7716d26d46 - Use an explicit 'reload_keep_cache' command and introduce test cases
for #569.
2022-12-14 16:33:28 +01:00
George Thessalonikefs 857d6ce3a1 Merge branch 'reuse-caches-on-reload' of https://github.com/jinmeiib/unbound-1 into jinmeiib-reuse-caches-on-reload 2022-12-13 16:42:38 +01:00
George Thessalonikefs af2ef61c49 - Merge #461 from Christian Allred: Add max-query-restarts option. 2022-12-13 15:54:51 +01:00
George Thessalonikefs df411b3f28 - Updates for #461 (Add max-query-restarts option). 2022-12-13 15:29:22 +01:00
George Thessalonikefs 71db243b0d Merge branch 'restart_conf' of https://github.com/cgallred/unbound into cgallred-restart_conf 2022-12-13 14:35:01 +01:00
George Thessalonikefs 67cf625608 Merge branch 'master' of github.com:NLnetLabs/unbound 2022-12-13 13:59:42 +01:00
George Thessalonikefs c61b2121b5 - Expose 'max-sent-count' as a configuration option; the
default value retains Unbound's behavior.
2022-12-13 13:57:07 +01:00
George Thessalonikefs 859d0f2dfe - Expose 'statistics-inhibit-zero' as a configuration option; the
default value retains Unbound's behavior.
2022-12-13 10:47:37 +01:00
W.C.A. Wijngaards 1a2e6aabac - Fix to wrap Makefile scripts directory in quotes for uninstall. 2022-12-13 09:03:52 +01:00
W.C.A. Wijngaards 726aa5b0f5 Changelog note for #808
- Merge #808: Wrap Makefile script's directory variables in quotes.
2022-12-13 08:53:44 +01:00
Wouter WijngaardsandGitHub 5204c14e6d Merge pull request #808 from sneurlax/fix/windows
Wrap Makefile script's directory variables in quotes
2022-12-13 08:53:07 +01:00
sneurlax 2daaebf3aa wrap directory variables in quotes
see https://github.com/NLnetLabs/unbound/issues/807
2022-12-12 19:27:19 -06:00
TCY16 dd3984eae9 add validation EDEs to CD bit queries 2022-12-05 11:41:17 +01:00
W.C.A. Wijngaards 6b8642b662 Fix date. 2022-12-01 13:05:02 +01:00
W.C.A. Wijngaards 5c041c0ba9 - Fix #773: When used with systemd-networkd, unbound does not start
until systemd-networkd-wait-online.service times out.
2022-12-01 13:04:05 +01:00
George Thessalonikefs d7a9def160 - Clear documentation for interactivity between the subnet module and
the serve-expired and prefetch configuration options.
2022-11-30 14:45:36 +01:00
George Thessalonikefs ef8111ece7 Merge branch 'master' of github.com:NLnetLabs/unbound 2022-11-30 14:34:00 +01:00
George Thessalonikefs 90f6cb1158 - Add SVCB and HTTPS to the types removed by 'unbound-control flush'. 2022-11-30 14:33:16 +01:00
W.C.A. Wijngaards effbf99281 - Fix #782: Segmentation fault in stats.c:404. 2022-11-30 10:18:27 +01:00
Philip Homburg 81861aee05 Changelog entry for #720 2022-11-29 16:20:52 +01:00
W.C.A. Wijngaards 6f7da59b77 - Fix for the ignore of tcp events for closed comm points, preserve
the use after free protection features.
2022-11-28 10:04:52 +01:00
TCY16 a96c64d966 add subnetcache test and rename/improve cachedb test 2022-11-24 16:14:37 +01:00
TCY16 79d39e7f4d Add subnetcache support 2022-11-24 16:14:12 +01:00
Philip-NLnetLabsandGitHub b86a97019f Merge pull request #720 from jonathangray/winsock_uaf
fix use after free when WSACreateEvent() fails
2022-11-23 14:08:01 +01:00
George Thessalonikefs 896f7a8306 - Ignore expired error responses. 2022-11-22 17:44:55 +01:00
tcarpayandGitHub a7ac109e4e Remove erroneous filepath in test 2022-11-22 12:11:55 +01:00
TCY16 79108f4c3d add ede cachedb test 2022-11-21 15:26:49 +01:00
TCY16 6dcba49ff1 add cachedb support 2022-11-21 13:23:00 +01:00
TCY16 8b4a8493d0 Merge branch 'master' of github.com:NLnetLabs/unbound into features/ede-caching 2022-11-21 11:34:36 +01:00
TCY16 b65ff768bc remove superfluous variables 2022-11-18 11:30:11 +01:00
W.C.A. Wijngaards f72116883b - Fix #779: [doc] Missing documention in ub_resolve_event() for
callback parameter was_ratelimited.
2022-11-11 11:28:15 +01:00
George Thessalonikefs 4e305e644b - Complementary fix for distutils.sysconfig deprecation in Python 3.10
to commit 62c5039ab9.
2022-11-09 11:41:28 +01:00
W.C.A. Wijngaards 89d9b25090 - iana portlist update. 2022-11-08 15:24:24 +01:00
W.C.A. Wijngaards dda1d9544c - Fix #775: libunbound: subprocess reap causes parent process reap
to hang.
2022-11-08 15:04:05 +01:00
W.C.A. Wijngaards 52a9e6268e - Fix to make sure to not read again after a tcp comm point is closed. 2022-11-08 13:23:44 +01:00
W.C.A. Wijngaards 8367b24bc5 - Fix to ignore tcp events for closed comm points. 2022-11-08 12:02:48 +01:00
Willem Toorop 8df26b132b Merge branch 'master' into devel/merge-master-into-downstream-cookies 2022-11-07 17:09:20 +00:00
David Lamparter 64fb06f892 NAT64 support
This implements #721.  Includes documentation and some very basic tests.
Please refer to doc for further detail.
2022-11-07 11:37:50 +00:00
TCY16 5bf4c505db remove value check 2022-10-28 17:40:18 +02:00
TCY16 5158876bfd Merge branch 'master' of github.com:NLnetLabs/unbound into features/dohpath-for-unbounid 2022-10-28 11:14:59 +02:00
George Thessalonikefs f531faf163 Changelog entry for #767
- Merge #767 from jonathangray: consistently use IPv4/IPv6 in
    unbound.conf.5.
2022-10-21 15:49:56 +02:00
Yorgos ThessalonikefsandGitHub c0c9acccfd Merge pull request #767 from jonathangray/man
consistently use IPv4/IPv6 in unbound.conf.5
2022-10-21 15:46:45 +02:00
W.C.A. Wijngaards 17e5dd6131 - Fix that cachedb does not store failures in the external cache. 2022-10-21 10:11:47 +02:00
George Thessalonikefs e9107907e5 - Clarify the use of MAX_SENT_COUNT in the iterator code. 2022-10-18 12:29:07 +02:00
W.C.A. Wijngaards ba8642aeb7 - testcode/dohclient sets log identity to its name. 2022-10-17 16:00:43 +02:00
W.C.A. Wijngaards 5ffa4d7232 - In unit test, print python script name list correctly. 2022-10-14 16:49:57 +02:00
W.C.A. Wijngaards 2571d00535 Changelog note for #768
- Merge #768 from fobser: Arithmetic on a pointer to void is a GNU
  extension.
2022-10-14 16:22:17 +02:00
Wouter WijngaardsandGitHub f9a563d495 Merge pull request #768 from fobser/void_math
Arithmetic on a pointer to void is a GNU extension.
2022-10-14 16:21:14 +02:00
Florian Obser 08dcae0dab Arithmetic on a pointer to void is a GNU extension. 2022-10-14 13:56:32 +02:00
W.C.A. Wijngaards 5ac1bc13cb - Tag for 1.17.0 release. The code repository continues with 1.17.1. 2022-10-13 09:34:44 +02:00
W.C.A. Wijngaards f5e1ef650d Merge branch 'branch-1.17.0' 2022-10-13 09:32:22 +02:00
George Thessalonikefs d25e0cd9b0 - Fix PROXYv2 header read for TCP connections when no proxied addresses
are provided.
2022-10-11 17:39:30 +02:00
Jonathan Gray 4f27799456 consistently use IPv4/IPv6 2022-10-10 19:14:58 +11:00
W.C.A. Wijngaards 97d1cff315 Changelog note for tag for 1.17.0rc1 release. 2022-10-07 13:29:33 +02:00
George Thessalonikefs a4631a3ecf - Fix unit test to properly test the reuse_write_wait_pop function. 2022-10-07 11:29:46 +02:00
George Thessalonikefs 2569b12b9c - Fix to stop possible loops in the tcp reuse code (write_wait list
and tcp_wait list). Based on analysis and patch from Prad Seniappan
  and Karthik Umashankar.
2022-10-07 11:25:36 +02:00
W.C.A. Wijngaards bf1cce6f9b - Fix proxy length debug output printout typecasts. 2022-10-06 15:53:21 +02:00
W.C.A. Wijngaards b043bc5eb4 - Fix to stop responses with TC flag from resulting in partial
responses. It retries to fetch the data elsewhere, or fails the
  query and in depth fix removes the TC flag from the cached item.
2022-10-06 10:01:09 +02:00
George Thessalonikefs d122617dd4 - Fix checkconf test for dnscrypt and proxy port. 2022-10-05 22:03:01 +02:00
W.C.A. Wijngaards 6b8181acb7 - Fix dnscrypt compile for proxy protocol code changes. 2022-10-05 14:09:12 +02:00
George Thessalonikefs f609a45354 - Make ede.tdir test more predictable by using static data. 2022-10-05 02:44:50 +02:00
George Thessalonikefs 60db1111c0 - Use DEBUG_TDIR from environment in mini_tdir.sh for debugging.
- Fix string comparison in mini_tdir.sh.
2022-10-05 01:13:29 +02:00
George Thessalonikefs 40b2b3a6f3 Changelog entry for #764
- Merge #764: Leniency for target discovery when under load (for
  NRDelegation changes).
2022-10-04 22:24:18 +02:00
Yorgos ThessalonikefsandGitHub f1d263a318 Leniency for target discovery when under load (for NRDelegation changes) (#764)
* - Introduce leniency for target discovery when under load.

* - Allow for easier testing (to be reverted).

* - Happy compiler.

* - Precheck access to target_fetch_policy.

* - Do not mark a nameserver as resolved when one of A/AAAA is negative.

* - Update fetch_glue.rpl test for (possible) outstanding queries.

* - Update fetch_glue_cname.rpl test for possible outstanding queries.

* - Better fix for fetch_glue_cname.rpl.

* - Fix iter_emptydp_for_glue.rpl to match the referral.

* - Disabled the nxns tests for now (to be reverted).

* - Update iter_recurse.rpl for possible outstanding queries.

* Revert "- Disabled the nxns tests for now (to be reverted)."

This reverts commit 34a9c13a90.

* Revert "- Allow for easier testing (to be reverted)."

This reverts commit b6dfe35e1d.
2022-10-04 22:21:08 +02:00
W.C.A. Wijngaards f0614a57f8 - Fix to clean up after the acl_interface unit test. 2022-10-04 16:59:10 +02:00
W.C.A. Wijngaards bf7a2884fb - Fix static analysis report to remove dead code from the
rpz_callback_from_iterator_module function.
2022-10-04 09:08:11 +02:00
W.C.A. Wijngaards c0eaadfc42 - Fix to close errno block in comm_point_tcp_handle_read outside of
ifdef.
2022-10-03 16:21:39 +02:00
George Thessalonikefs 22e43aa631 Changelog entry for #760
- Merge #760: PROXYv2 downstream support. (New proxy-protocol-port
  configuration option).
2022-10-03 15:34:22 +02:00
Yorgos ThessalonikefsandGitHub c4e51a4cfe PROXYv2 downstream support (#760) 2022-10-03 15:29:47 +02:00
W.C.A. Wijngaards 7d96a7e3fe - Fix windows compile, the identifier interface is defined in headers. 2022-10-03 15:03:50 +02:00
W.C.A. Wijngaards 9842fbf760 - Fix test tdir skip report printout. 2022-10-03 10:26:30 +02:00
W.C.A. Wijngaards a102fb1df8 - Fix to remove erroneous TC flag from TCP upstream. 2022-10-03 09:53:41 +02:00
Willem Toorop bd2c202674 The generated lexer and parser sources for configuring cookies 2022-09-28 10:34:06 +02:00
Willem Toorop 75f3fbdd65 Downstream DNS Cookies a la RFC7873 and RFC9018
Create server cookies for clients that send client cookies.
Needs to be turned on in the config file with:

	answer-cookie: yes

A cookie-secret can be configured for anycast setups.
Also adds an access control list that will allow queries with
either a valid cookie or over a stateful transport.
2022-09-28 10:28:19 +02:00
Willem Toorop 71f23ef354 extended_error_encode() for extended errors 2022-09-28 09:57:56 +02:00
George Thessalonikefs 5b98816751 - Better output for skipped tdir tests. 2022-09-26 15:51:28 +02:00
TCY16 0b176750bd add @wcawijngaards' review comments 2022-09-26 12:14:17 +02:00
TCY16 f0989fc754 differentiate between malloc and regional_alloc 2022-09-26 11:49:49 +02:00
TCY16 c9f90def0a swap malloc for regional_alloc and add free 2022-09-26 11:18:58 +02:00
TCY16 57c4f28f20 add happy-flow test 2022-09-21 16:21:48 +02:00
TCY16 d731fa2e21 use correct edns_list attach function 2022-09-21 16:19:38 +02:00
W.C.A. Wijngaards e93c75a5d4 - Fix doxygen warning in respip.h. 2022-09-21 15:23:04 +02:00
W.C.A. Wijngaards 8e18f11965 - This patch was released in 1.16.3, the code repository continues
with the previous features and fixes for 1.17.0.
2022-09-21 12:16:13 +02:00
W.C.A. Wijngaards e3871ca907 Merge branch 'branch-1.16.3' 2022-09-21 12:11:26 +02:00
TCY16 dcfcde2ec8 add cached EDE strings 2022-09-21 11:21:33 +02:00
Philip-NLnetLabsandGitHub f68e252345 Merge pull request #757 from NLnetLabs/philip-issue-749
Philip issue 749
2022-09-20 15:07:14 +02:00
Philip Homburg 1e5158045f Merge branch 'ryndia-issue-749' into philip-issue-749 2022-09-20 14:48:57 +02:00
George Thessalonikefs 99e12ae4b5 - Remove unused testcode/mini_tpkg.sh file. 2022-09-20 14:47:24 +02:00
Philip Homburg 5f3b460586 Align with version 1.58 on cvsweb.openbsd.org 2022-09-20 14:47:19 +02:00
George Thessalonikefs 9b1647ebae - Convert tdir tests to use the new skip_test functionality. 2022-09-20 14:45:20 +02:00
George Thessalonikefs 307805b64f Changelog entry for #753:
- Merge #753: ACL per interface. (New interface-* configuration
  options).
2022-09-20 11:36:01 +02:00
Yorgos ThessalonikefsandGitHub f02d6bddd1 Merge pull request #753 from NLnetLabs/acl_interface
ACL per interface
2022-09-16 16:45:59 +02:00
eb02170338 Apply suggestions from code review
Co-authored-by: Wouter Wijngaards <wcawijngaards@users.noreply.github.com>
2022-09-16 14:43:23 +02:00
George Thessalonikefs d301bfe4a2 - ACL per interface: refactor, complete testing and a bugfix for
interface names.
2022-09-11 20:57:41 +02:00
George Thessalonikefs fc123303ac - Add functionality to skip tdir tests from the .pre file;
- Initial tests for interface-* options.
2022-09-11 20:21:32 +02:00
George Thessalonikefs aec33b3d63 Documentation for interface-* options. 2022-09-11 20:21:32 +02:00
George Thessalonikefs 7e9fd2114b Cleared error messages for interface-* options. 2022-09-11 20:21:32 +02:00
George Thessalonikefs c30bdff939 Initial commit for interface based ACL. 2022-09-11 20:21:32 +02:00
ryndiaandGitHub cfc656294e Update arc4random.c 2022-09-07 20:16:20 +04:00
W.C.A. Wijngaards 007db2c327 - Fix to check pthread_t size after pthread has been detected. 2022-09-02 10:21:00 +02:00
W.C.A. Wijngaards 5bbaf78c3f - Remove include that was there for debug purposes. 2022-09-02 10:11:23 +02:00
W.C.A. Wijngaards 57230d7f22 - Fix to log a verbose message at operational notice level if a
thread is not responding, to stats requests. It is logged with
  thread identifiers.
2022-09-01 15:14:20 +02:00
TCY16 5f309d0018 Add caching EDEs 2022-09-01 14:10:14 +02:00
W.C.A. Wijngaards d66e1cccf8 - Fix to set out of file descriptor warning to operational verbosity. 2022-09-01 14:01:56 +02:00
W.C.A. Wijngaards 2450b4653a - Slow down log frequency of write wait failures. 2022-09-01 14:00:29 +02:00
W.C.A. Wijngaards eb3378396f - Fix to update config tests to fix checking if nonblocking sockets
work on OpenBSD.
2022-09-01 09:16:05 +02:00
W.C.A. Wijngaards 1f5cc25974 - Fix for wait for udp send to stop when packet is successfully sent. 2022-08-31 16:45:15 +02:00
W.C.A. Wijngaards ec5812a748 - Fix to wait for blocked write on UDP sockets, with a timeout if it
takes too long the packet is dropped.
2022-08-31 11:54:11 +02:00
W.C.A. Wijngaards 10a5a5880a - Patch from Vadim Fedorenko that adds MSG_DONTWAIT to receive
operations, so that instruction reordering does not cause mistakenly
  blocking socket operations.
2022-08-31 10:11:25 +02:00
W.C.A. Wijngaards 2fa1c17cd9 - Fix to avoid process wide fcntl calls mixed with nonblocking
operations after a blocked write.
2022-08-31 10:09:39 +02:00
TCY16 b642c5fe1f add better URI template checking 2022-08-25 14:06:13 +02:00
TCY16 f3fa363443 implement @gthess' review comments; fix check on compulsory text and add tests 2022-08-24 12:38:08 +02:00
W.C.A. Wijngaards e6f878ee71 - Fix #741: systemd socket activation fails on IPv6. 2022-08-22 09:12:08 +02:00
TCY16 8d939691a3 implement @wcawijngaards' review comment 2022-08-19 14:48:47 +02:00
TCY16 b465e0cfc0 add testcase and fix comment 2022-08-15 16:12:22 +02:00
TCY16 73b3b32062 fix styling nits 2022-08-15 14:41:06 +02:00
TCY16 6e31d1f5be add dohpath parsing 2022-08-15 14:36:35 +02:00
TCY16 14fe4669e7 fix testcase comment 2022-08-12 14:09:00 +02:00
W.C.A. Wijngaards dc6c04b243 - Fix to log accept error ENFILE and EMFILE errno, but slowly, once
per 10 seconds. Also log accept failures when no slow down is used.
2022-08-12 09:54:29 +02:00
W.C.A. Wijngaards ef57f8bd51 - Fix #734 [FR] enable unbound-checkconf to detect more (basic)
errors.
2022-08-05 14:41:05 +02:00
W.C.A. Wijngaards fbe8e3b0b2 - Fix ratelimit inconsistency, for ip-ratelimits the value is the
amount allowed, like for ratelimits.
2022-08-04 11:33:37 +02:00
W.C.A. Wijngaards 1c164ab442 Changelog note for #730
- Merge #730 from luisdallos: Fix startup failure on Windows 8.1 due
  to unsupported IPV6_USER_MTU socket option being set.
2022-08-02 16:12:31 +02:00
Wouter WijngaardsandGitHub e738ec31ca Merge pull request #730 from luisdallos/win81-unsup-sockopt-fix
Fix startup failure on Windows 8.1 due to unsupported IPV6_USER_MTU socket option being set
2022-08-02 16:12:16 +02:00
W.C.A. Wijngaards 07b073ddb3 - Fix unittest for edns subnet change. 2022-08-02 14:43:57 +02:00
W.C.A. Wijngaards 0f08cc6d55 - Fix edns subnet so that scope 0 answers only match sourcemask 0
queries for answers from cache if from a query with sourcemask 0.
2022-08-02 14:13:55 +02:00
Luis Dallos 7d3c6f1c43 Fix startup failure on Windows 8.1 due to unsupported IPV6_USER_MTU socket option being set
Newer mingw-w64 (starting from 8.0.1) introduces support for `IPV6_USER_MTU` socket
option [1], which is not supported on Windows 8.1 and older [2]. As there is no way
to avoid this socket option from being picked at compile time when targeting older
versions of Windows, check for `setsockopt(..., IPV6_USER_MTU, ...)` failures at
runtime in order to avoid startup failure on those versions of Windows where the
`IPV6_USER_MTU` socket option is unsupported.

[1]: mirror/mingw-w64@e30bff4
[2]: `WSAGetLastError()` returns `WSAENOPROTOOPT` (`Bad protocol option`) error code
2022-08-01 23:03:24 -04:00
W.C.A. Wijngaards cd22fdc28d - Fix #728: alloc_reg_obtain() core dump. Stop double
alloc_reg_release when serviced_create fails.
2022-08-01 16:45:41 +02:00
W.C.A. Wijngaards 5ae48f85c0 - The code repo continues with 1.16.3. 2022-08-01 15:17:10 +02:00
JINMEI Tatuya fccb2eb2e8 prevent memory leak in case cache isn't reused 2022-07-22 14:33:21 -07:00
Jonathan Gray 1464b166a4 fix use after free when WSACreateEvent() fails 2022-07-22 18:23:59 +10:00
George Thessalonikefs 91c298c901 Merge branch 'subnet_cache_prefetch' of https://github.com/tilan7663/unbound into tilan7663-subnet_cache_prefetch 2022-05-17 16:16:09 +03:00
Tian Lan 8afbc0944f Add prefetch support for subnet cache entries
- Entries in the subnet cache should now be prefetched.

- Rename testdata subnet_*.crpl to subnet_*.rpl so they are visible to
  make test

Signed-off-by: Tian Lan <tian.lan@twosigma.com>
2022-04-29 11:46:05 -04:00
Christian Allred d19e12ab5d Merge branch 'master' of https://github.com/NLnetLabs/unbound into restart_conf 2022-04-18 12:16:40 -07:00
JINMEI Tatuya 5b2eda28e3 add keep-cache option to unbound-control reload to keep caches 2021-11-11 10:47:08 -08:00
Christian Allred 766244bd81 Document max-query-restarts option 2021-04-05 18:59:09 -07:00
Christian Allred 07c0d04a14 Use max-query-restarts in iterative resolver 2021-04-05 16:25:43 -07:00
Christian Allred 0e3068559c Add max-query-restarts to grammar and lexer 2021-04-05 16:24:49 -07:00
Christian Allred 41fa45c99e Add max-query-restarts config parameter 2021-04-05 15:41:53 -07:00
Christopher Zimmermann 1d23e0c920 Merge remote-tracking branch 'upstream/master' 2021-02-03 13:19:19 +01:00
Frank Riley 28b45e1d87 Add missing callbacks to the python module 2021-01-01 10:19:32 -07: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
673 changed files with 64081 additions and 29113 deletions
+74 -15
View File
@@ -32,12 +32,12 @@ jobs:
- name: OS X
os: macos-latest
install_expat: "yes"
config: "--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl --with-libexpat=/usr/local/opt/expat"
config: "--enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat"
make_test: "yes"
- name: Clang on OS X
os: macos-latest
install_expat: "yes"
config: "CC=clang --enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl --with-libexpat=/usr/local/opt/expat --disable-static"
config: "CC=clang --enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat --disable-static"
make_test: "yes"
clang_analysis: "yes"
- name: ubsan (gcc undefined behaviour sanitizer)
@@ -161,9 +161,36 @@ 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@v2
- uses: actions/checkout@v4
with:
submodules: false
- name: test_windows
@@ -175,21 +202,26 @@ jobs:
cd ..
export prepath=`pwd`
echo prepath=${prepath}
#echo "curl cpanm"
#curl -L -k -s -S -o cpanm https://cpanmin.us/
#echo "perl cpanm Pod::Usage"
#perl cpanm Pod::Usage
echo "choco install winflexbison3"
choco install winflexbison3
echo 'LEX="win_flex"'
export LEX="win_flex"
echo 'YACC="win_bison -y"'
export YACC="win_bison -y"
mkdir openssl
echo "curl openssl"
curl -L -k -s -S -o openssl-1.1.1j.tar.gz https://www.openssl.org/source/openssl-1.1.1j.tar.gz
tar xzf openssl-1.1.1j.tar.gz
cd openssl-1.1.1j
curl -L -k -s -S -o openssl-3.2.0.tar.gz https://www.openssl.org/source/openssl-3.2.0.tar.gz
tar xzf openssl-3.2.0.tar.gz
cd openssl-3.2.0
# remove pod::Usage because we do not need -help or -man output
# from the Configure script
echo "Fixup ./Configure by removing use Pod::Usage require"
sed -e 's/use Pod::Usage//' < Configure > Configure.fix
echo "./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix=\""$prepath/openssl\"""
./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl"
# from the Configure script, this fixes it for openssl 1.1.1
#echo "Fixup ./Configure by removing use Pod::Usage require"
#sed -e 's/use Pod::Usage//' < Configure > Configure.fix
# ./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl"
# pacman is used to install for msys2, with
# C:/msys64/usr/bin/pacman -S perl
echo "C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix=\""$prepath/openssl"\" PERL=\"C:/msys64/usr/bin/perl\""
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
# make the libs only, build faster
echo "make build_libs"
#make
@@ -326,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
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: configure
run: ./configure --enable-debug
- name: make
+6
View File
@@ -10,6 +10,10 @@
/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
/doc/unbound-anchor.8
@@ -32,6 +36,7 @@
/asynclook
/delayer
/dohclient
/doqclient
/lock-verify
/memstats
/perf
@@ -54,6 +59,7 @@
/pythonmod/unboundmodule.py
/testdata/result.*
/testdata/.done-*
/testdata/.skip-*
/testdata/.perfstats.txt
/doc/html
/doc/xml
+57 -38
View File
@@ -122,15 +122,15 @@ iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
services/localzone.c services/mesh.c services/modstack.c services/view.c \
services/rpz.c \
services/rpz.c util/rfc_1982.c \
services/outbound_list.c services/outside_network.c util/alloc.c \
util/config_file.c util/configlexer.c util/configparser.c \
util/shm_side/shm_main.c services/authzone.c \
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
util/rtt.c util/siphash.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
util/timehist.c util/tube.c \
util/timehist.c util/tube.c util/proxy_protocol.c util/timeval_func.c \
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
validator/autotrust.c validator/val_anchor.c validator/validator.c \
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
@@ -145,14 +145,14 @@ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
fptr_wlist.lo siphash.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
autotrust.lo val_anchor.lo rpz.lo \
autotrust.lo val_anchor.lo rpz.lo rfc_1982.lo proxy_protocol.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo timeval_func.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -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 \
@@ -198,7 +198,7 @@ CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
$(COMPAT_OBJ) @WIN_CHECKCONF_OBJ_LINK@
CONTROL_SRC=smallapp/unbound-control.c
CONTROL_OBJ=unbound-control.lo
CONTROL_OBJ=unbound-control.lo
CONTROL_OBJ_LINK=$(CONTROL_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) \
$(SLDNS_OBJ) $(COMPAT_OBJ) @WIN_CONTROL_OBJ_LINK@
HOST_SRC=smallapp/unbound-host.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
@@ -455,6 +463,7 @@ unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnsta
dynlibmod.lo dynlibdmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h
redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h
timeval_func.lo timeval_func.o: $(srcdir)/util/timeval_func.c $(srcdir)/util/timeval_func.h
# dnscrypt
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@@ -498,6 +507,7 @@ util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
echo "#include \"util/configyyrename.h\"" >> $@ ;\
$(LEX) -t $(srcdir)/util/configlexer.lex >> $@ ;\
fi
@if test ! -f $@; then echo "No $@ : need flex and bison to compile from source repository"; exit 1; fi
util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
@-if test ! -d util; then $(INSTALL) -d util; fi
@@ -516,7 +526,7 @@ distclean: clean
rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1
rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service
rm -f $(TEST_BIN)
rm -f Makefile
rm -f Makefile
maintainer-clean: distclean
rm -f util/configlexer.c util/configparser.c util/configparser.h
@@ -616,7 +626,7 @@ install-all: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL) $(UNBOUND_EVENT_INSTA
$(INSTALL) -c -m 644 doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5
$(INSTALL) -c -m 644 doc/unbound-host.1 $(DESTDIR)$(mandir)/man1
$(INSTALL) -c -m 755 unbound-control-setup $(DESTDIR)$(sbindir)/unbound-control-setup
if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 doc/example.conf $(DESTDIR)$(configfile); fi
if test ! -e "$(DESTDIR)$(configfile)"; then $(INSTALL) -d `dirname "$(DESTDIR)$(configfile)"`; $(INSTALL) -c -m 644 doc/example.conf "$(DESTDIR)$(configfile)"; fi
pythonmod-uninstall:
rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
@@ -645,11 +655,11 @@ uninstall: $(PYTHONMOD_UNINSTALL) $(PYUNBOUND_UNINSTALL) $(UNBOUND_EVENT_UNINSTA
rm -f -- $(DESTDIR)$(includedir)/unbound.h
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la
@echo
@echo "You still need to remove "`dirname $(DESTDIR)$(configfile)`" , $(DESTDIR)$(configfile) by hand"
@echo "You still need to remove "`dirname "$(DESTDIR)$(configfile)"`" , $(DESTDIR)$(configfile) by hand"
iana_update:
curl -o port-numbers.tmp https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml --compressed
if file port-numbers.tmp | grep 'gzip' >/dev/null; then zcat port-numbers.tmp; else cat port-numbers.tmp; fi | awk '/<record>/ {p=0;} /<protocol>udp/ {p=1;} /<protocol>[^u]/ {p=0;} /Decomissioned|Decommissioned|Removed|De-registered|unassigned|Unassigned|Reserved/ {u=1;} /<number>/ { if(u==1) {u=0;} else { if(p==1) { match($$0,/[0-9]+/); print substr($$0, RSTART, RLENGTH) ","}}}' | sort -nu > util/iana_ports.inc
if file port-numbers.tmp | grep 'gzip' >/dev/null; then zcat port-numbers.tmp; else cat port-numbers.tmp; fi | awk '/<record>/ {p=0;} /<protocol>udp/ {p=1;} /<protocol>[^u]/ {p=0;} /Decomissioned|Decommissioned|Removed|De-registered|unassigned|Unassigned|Reserved/ {u=1;} /<number>/ { if(u==1) {u=0;} else { if(p==1) { match($$0,/[0-9]+/); print substr($$0, RSTART, RLENGTH) ","}}}' | sort -nu > util/iana_ports.inc
rm -f port-numbers.tmp
# dependency generation
@@ -700,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 \
@@ -736,7 +748,7 @@ msgencode.lo msgencode.o: $(srcdir)/util/data/msgencode.c config.h $(srcdir)/uti
msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
@@ -791,7 +803,7 @@ iter_priv.lo iter_priv.o: $(srcdir)/iterator/iter_priv.c config.h $(srcdir)/iter
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h
iter_resptype.lo iter_resptype.o: $(srcdir)/iterator/iter_resptype.c config.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iterator.h $(srcdir)/util/log.h \
$(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h
@@ -877,7 +889,7 @@ rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdi
outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h \
@@ -915,7 +927,8 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/rrdef.h
shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
@@ -928,7 +941,7 @@ shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/ut
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/tube.h
$(srcdir)/util/tube.h $(srcdir)/util/timeval_func.h
authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
@@ -983,7 +996,9 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/timeval_func.h
proxy_protocol.lo proxy_protocol.o: $(srcdir)/util/proxy_protocol.c config.h \
$(srcdir)/util/proxy_protocol.h $(srcdir)/sldns/sbuffer.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@@ -1004,6 +1019,8 @@ rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/itera
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
siphash.lo siphash.o: $(srcdir)/util/siphash.c
rfc_1982.lo rfc_1982.o: $(srcdir)/util/rfc_1982.c
edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/regional.h \
@@ -1184,7 +1201,7 @@ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/r
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/random.h $(srcdir)/respip/respip.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/outside_network.h
$(srcdir)/services/outside_network.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
$(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
@@ -1271,7 +1288,8 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
$(srcdir)/util/edns.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
$(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
$(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.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 $(srcdir)/util/netevent.h \
@@ -1289,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 \
@@ -1319,7 +1337,7 @@ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.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/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/timeval_func.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
@@ -1341,21 +1359,21 @@ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/test
$(srcdir)/daemon/remote.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 \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/daemon/daemon.h \
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/util/alloc.h $(srcdir)/util/timeval_func.h $(srcdir)/services/modstack.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
$(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h $(srcdir)/daemon/worker.h
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/random.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/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/timeval_func.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
@@ -1407,7 +1425,7 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
$(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h $(srcdir)/util/timeval_func.h \
$(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@@ -1415,13 +1433,13 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
$(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/edns.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h $(srcdir)/util/timeval_func.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/remote.h
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/daemon/remote.h $(srcdir)/util/storage/slabhash.h $(srcdir)/daemon/daemon.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
@@ -1477,7 +1495,8 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h
$(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/util/edns.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@@ -1489,7 +1508,8 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
$(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@@ -1503,8 +1523,7 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/li
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/sldns/str2wire.h
$(srcdir)/util/data/msgencode.h $(srcdir)/sldns/str2wire.h
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
@@ -1512,7 +1531,7 @@ asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libu
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/net_help.h $(srcdir)/util/proxy_protocol.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+6 -3
View File
@@ -1,9 +1,10 @@
# Unbound
[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound)
[![Github Build Status](https://github.com/NLnetLabs/unbound/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/NLnetLabs/unbound/actions)
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/109262826617293067?domain=https%3A%2F%2Ffosstodon.org&style=social)](https://fosstodon.org/@nlnetlabs)
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
fast and lean and incorporates modern features based on open standards. If you
@@ -16,7 +17,9 @@ You can learn more about Unbound by reading our
## Compiling
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
installed. Unbound can be compiled and installed using:
installed.
If building from the repository source you also need flex and bison installed.
Unbound can be compiled and installed using:
```
./configure && make && make install
@@ -26,7 +29,7 @@ You can use libevent if you want. libevent is useful when using many (10000)
outgoing ports. By default max 256 ports are opened at the same time and the
builtin alternative is equally capable and a little faster.
Use the `--with-libevent=dir` configure option to compile Unbound with libevent
Use the `--with-libevent` configure option to compile Unbound with libevent
support.
## Unbound configuration
+110 -49
View File
@@ -2,7 +2,13 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 43
# Version 48
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
# and check for getaddrinfo with only header.
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
# 2023-05-04 fix to remove unused whitespace.
# 2023-01-26 fix -Wstrict-prototypes.
# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD.
# 2021-08-17 fix sed script in ssldir split handling.
# 2021-08-17 fix for openssl to detect split version, with ssldir_include
# and ssldir_lib output directories.
@@ -186,7 +192,7 @@ dnl cache=`echo $1 | sed 'y%.=/+- %___p__%'`
AC_CACHE_VAL(cv_prog_cc_flag_needed_$cache,
[
echo '$2' > conftest.c
echo 'void f(){}' >>conftest.c
echo 'void f(void){}' >>conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then
eval "cv_prog_cc_flag_needed_$cache=no"
else
@@ -232,7 +238,7 @@ dnl DEPFLAG: set to flag that generates dependencies.
AC_DEFUN([ACX_DEPFLAG],
[
AC_MSG_CHECKING([$CC dependency flag])
echo 'void f(){}' >conftest.c
echo 'void f(void){}' >conftest.c
if test "`$CC -MM conftest.c 2>&1`" = "conftest.o: conftest.c"; then
DEPFLAG="-MM"
else
@@ -271,7 +277,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAUL
#include <getopt.h>
#endif
int test() {
int test(void) {
int a;
char **opts = NULL;
struct timeval tv;
@@ -308,7 +314,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAUL
#include <getopt.h>
#endif
int test() {
int test(void) {
int a;
char **opts = NULL;
struct timeval tv;
@@ -334,7 +340,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG,
[
#include <stdbool.h>
#include <ctype.h>
int test() {
int test(void) {
int a = 0;
return a;
}
@@ -344,7 +350,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE,
[
#include <ctype.h>
int test() {
int test(void) {
int a;
a = isascii(32);
return a;
@@ -355,7 +361,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE,
[
#include <netinet/in.h>
int test() {
int test(void) {
struct in6_pktinfo inf;
int a = (int)sizeof(inf);
return a;
@@ -369,7 +375,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE -D_FRSRESGID,
[
#include <unistd.h>
int test() {
int test(void) {
int a = setresgid(0,0,0);
a = setresuid(0,0,0);
return a;
@@ -384,7 +390,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_POSIX_C_SOURCE=200112,
#endif
#include <netdb.h>
int test() {
int test(void) {
int a = 0;
char *t;
time_t time = 0;
@@ -412,7 +418,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D__EXTENSIONS__,
#include <getopt.h>
#endif
int test() {
int test(void) {
int a;
char **opts = NULL;
struct timeval tv;
@@ -474,7 +480,7 @@ fi
dnl Setup ATTR_FORMAT config.h parts.
dnl make sure you call ACX_CHECK_FORMAT_ATTRIBUTE also.
AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
[
[
#ifdef HAVE_ATTR_FORMAT
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
@@ -704,7 +710,7 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir_lib"
ACX_RUNTIME_PATH_ADD([$ssldir_lib])
fi
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
@@ -729,40 +735,73 @@ AC_DEFUN([ACX_SSL_CHECKS], [
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
])
])
])
])
])
])
])
fi
@@ -776,7 +815,7 @@ AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT])
dnl Check for SSL, where SSL is mandatory
dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found
dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
dnl Checks main header files of SSL.
dnl
AC_DEFUN([ACX_WITH_SSL],
@@ -833,7 +872,7 @@ dnl try to see if an additional _LARGEFILE_SOURCE 1 is needed to get fseeko
ACX_CHECK_COMPILER_FLAG_NEEDED(-D_LARGEFILE_SOURCE=1,
[
#include <stdio.h>
int test() {
int test(void) {
int a = fseeko(stdin, 0, 0);
return a;
}
@@ -858,7 +897,7 @@ char* (*f) () = getaddrinfo;
#ifdef __cplusplus
}
#endif
int main() {
int main(void) {
;
return 0;
}
@@ -869,7 +908,7 @@ dnl see if on windows
if test "$ac_cv_header_windows_h" = "yes"; then
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
USE_WINSOCK="1"
if echo $LIBS | grep 'lws2_32' >/dev/null; then
if echo "$LIBS" | grep 'lws2_32' >/dev/null; then
:
else
LIBS="$LIBS -lws2_32"
@@ -877,6 +916,24 @@ if test "$ac_cv_header_windows_h" = "yes"; then
fi
],
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
dnl perhaps getaddrinfo needs only the include
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
],
[
(void)getaddrinfo(NULL, NULL, NULL, NULL);
]
)],
[
ac_cv_func_getaddrinfo="yes"
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
USE_WINSOCK="1"
],
ORIGLIBS="$LIBS"
LIBS="$LIBS -lws2_32"
AC_LINK_IFELSE(
@@ -901,6 +958,7 @@ ac_cv_func_getaddrinfo="no"
LIBS="$ORIGLIBS"
])
)
)
AC_MSG_RESULT($ac_cv_func_getaddrinfo)
if test $ac_cv_func_getaddrinfo = yes; then
@@ -922,7 +980,7 @@ cache=`echo $1 | sed 'y%.=/+-%___p_%'`
AC_CACHE_VAL(cv_cc_deprecated_$cache,
[
echo '$3' >conftest.c
echo 'void f(){ $2 }' >>conftest.c
echo 'void f(void){ $2 }' >>conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
eval "cv_cc_deprecated_$cache=no"
else
@@ -963,6 +1021,9 @@ AC_LANG_SOURCE([[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -1313,7 +1374,7 @@ AC_DEFUN([AHX_CONFIG_W32_FD_SET_T],
#ifdef HAVE_WINSOCK2_H
#define FD_SET_T (u_int)
#else
#define FD_SET_T
#define FD_SET_T
#endif
])
@@ -1351,7 +1412,7 @@ dnl $3: define value, 1
AC_DEFUN([AHX_CONFIG_FLAG_OMITTED],
[#if defined($1) && !defined($2)
#define $2 $3
[#]endif ])
[#]endif])
dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags
dnl $1: the -DNAME or -DNAME=value string.
+46 -17
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
@@ -17,33 +17,62 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
PYTHON_VERSION=`$PYTHON -c "import sys; \
print(sys.version.split()[[0]])"`
fi
# calculate the version number components.
[
v="$PYTHON_VERSION"
PYTHON_VERSION_MAJOR=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_MAJOR"; then PYTHON_VERSION_MAJOR="0"; fi
v=`echo $v | sed -e 's/^[0-9]*$//' -e 's/[0-9]*[^0-9]//'`
PYTHON_VERSION_MINOR=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_MINOR"; then PYTHON_VERSION_MINOR="0"; fi
v=`echo $v | sed -e 's/^[0-9]*$//' -e 's/[0-9]*[^0-9]//'`
PYTHON_VERSION_PATCH=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_PATCH"; then PYTHON_VERSION_PATCH="0"; fi
]
# Check if you have sysconfig
AC_MSG_CHECKING([for the sysconfig Python module])
if ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`; then
# For some systems, sysconfig exists, but has the wrong paths,
# on Debian 10, for python 2.7 and 3.7. So, we check the version,
# and for older versions try distutils.sysconfig first. For newer
# versions>=3.10, where distutils.sysconfig is deprecated, use
# sysconfig first and then attempt the other one.
py_distutils_first="no"
if test $PYTHON_VERSION_MAJOR -lt 3; then
py_distutils_first="yes"
fi
if test $PYTHON_VERSION_MAJOR -eq 3 -a $PYTHON_VERSION_MINOR -lt 10; then
py_distutils_first="yes"
fi
# Check if you have the first module
if test "$py_distutils_first" = "yes"; then m="distutils"; else m="sysconfig"; fi
sysconfig_module=""
AC_MSG_CHECKING([for the $m Python module])
if ac_modulecheck_result1=`$PYTHON -c "import $m" 2>&1`; then
AC_MSG_RESULT([yes])
sysconfig_module="sysconfig"
# if yes, use sysconfig, because distutils is deprecated.
sysconfig_module="$m"
else
AC_MSG_RESULT([no])
# if no, try to use distutils
fi
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
# if not found, try the other one.
if test -z "$sysconfig_module"; then
if test "$py_distutils_first" = "yes"; then m2="sysconfig"; else m2="distutils"; fi
AC_MSG_CHECKING([for the $m2 Python module])
if ac_modulecheck_result2=`$PYTHON -c "import $m2" 2>&1`; then
AC_MSG_RESULT([yes])
sysconfig_module="$m2"
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
AC_MSG_ERROR([cannot import Python module "$m", or "$m2".
Please check your Python installation. The errors are:
$m
$ac_modulecheck_result1
$m2
$ac_modulecheck_result2])
PYTHON_VERSION=""
fi
sysconfig_module="distutils.sysconfig"
fi
if test "$sysconfig_module" = "distutils"; then sysconfig_module="distutils.sysconfig"; fi
#
# Check for Python include path
+58 -52
View File
@@ -1,39 +1,43 @@
# ===========================================================================
# http://autoconf-archive.cryp.to/ac_pkg_swig.html
# https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
# ===========================================================================
#
# SYNOPSIS
#
# AC_PROG_SWIG([major.minor.micro])
# AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found])
#
# DESCRIPTION
#
# This macro searches for a SWIG installation on your system. If found you
# should call SWIG via $(SWIG). You can use the optional first argument to
# check if the version of the available SWIG is greater than or equal to
# the value of the argument. It should have the format: N[.N[.N]] (N is a
# number between 0 and 999. Only the first N is mandatory.)
# This macro searches for a SWIG installation on your system. If found,
# then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is
# found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd.
#
# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
# the swig package is this version number or higher.
# You can use the optional first argument to check if the version of the
# available SWIG is greater than or equal to the value of the argument. It
# should have the format: N[.N[.N]] (N is a number between 0 and 999. Only
# the first N is mandatory.) If the version argument is given (e.g.
# 1.3.17), AX_PKG_SWIG checks that the swig package is this version number
# or higher.
#
# As usual, action-if-found is executed if SWIG is found, otherwise
# action-if-not-found is executed.
#
# In configure.in, use as:
#
# AC_PROG_SWIG(1.3.17)
# SWIG_ENABLE_CXX
# SWIG_MULTI_MODULE_SUPPORT
# SWIG_PYTHON
# AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ])
# AX_SWIG_ENABLE_CXX
# AX_SWIG_MULTI_MODULE_SUPPORT
# AX_SWIG_PYTHON
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
# LICENSE
#
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
# Copyright (c) 2008 Alan W. Irwin
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
# Copyright (c) 2008 Andrew Collier
# Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
# Copyright (c) 2018 Reini Urban <rurban@cpan.org>
# Copyright (c) 2021 Vincent Danjean <Vincent.Danjean@ens-lyon.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -46,7 +50,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -57,17 +61,21 @@
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Macro Archive. When you make and
# distribute a modified version of the Autoconf Macro, you may extend this
# special exception to the GPL to apply to your modified version as well.
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
AC_DEFUN([AC_PROG_SWIG],[
AC_PATH_PROG([SWIG],[swig])
#serial 15
AC_DEFUN([AX_PKG_SWIG],[
# Find path to the "swig" executable.
AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0])
if test -z "$SWIG" ; then
AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
elif test -n "$1" ; then
AC_MSG_CHECKING([for SWIG version])
m4_ifval([$3],[$3],[:])
elif test -z "$1" ; then
m4_ifval([$2],[$2],[:])
else
AC_MSG_CHECKING([SWIG version])
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
AC_MSG_RESULT([$swig_version])
if test -n "$swig_version" ; then
@@ -77,12 +85,12 @@ AC_DEFUN([AC_PROG_SWIG],[
if test -z "$required_major" ; then
[required_major=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_minor" ; then
[required_minor=0]
fi
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_patch" ; then
[required_patch=0]
@@ -103,30 +111,28 @@ AC_DEFUN([AC_PROG_SWIG],[
if test -z "$available_patch" ; then
[available_patch=0]
fi
[badversion=0]
if test $available_major -lt $required_major ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -lt $required_minor ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -eq $required_minor \
-a $available_patch -lt $required_patch ; then
[badversion=1]
fi
if test $badversion -eq 1 ; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
# Convert the version tuple into a single number for easier comparison.
# Using base 100 should be safe since SWIG internally uses BCD values
# to encode its version number.
required_swig_vernum=`expr $required_major \* 10000 \
\+ $required_minor \* 100 \+ $required_patch`
available_swig_vernum=`expr $available_major \* 10000 \
\+ $available_minor \* 100 \+ $available_patch`
if test $available_swig_vernum -lt $required_swig_vernum; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.])
SWIG=''
m4_ifval([$3],[$3],[])
else
AC_MSG_NOTICE([SWIG executable is '$SWIG'])
SWIG_LIB=`$SWIG -swiglib`
AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
AC_MSG_CHECKING([for SWIG library])
SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '`
AC_MSG_RESULT([$SWIG_LIB])
m4_ifval([$2],[$2],[])
fi
else
AC_MSG_WARN([cannot determine SWIG version])
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
SWIG=''
m4_ifval([$3],[$3],[])
fi
fi
AC_SUBST([SWIG_LIB])
+317 -127
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
@@ -14,24 +14,28 @@
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
# needed for multi-threaded programs (defaults to the value of CC
# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
# special cc_r/CC_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# but also to link with them as well. For example, you might link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# If you are only building threaded programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
# CXX="$PTHREAD_CXX"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
@@ -55,6 +59,7 @@
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -67,7 +72,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -82,35 +87,41 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 21
#serial 31
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_SED])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# requires special compiler flags (e.g. on Tru64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CC="$CC"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test x"$ax_pthread_ok" = xno; then
if test "x$ax_pthread_ok" = "xno"; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CC="$ax_pthread_save_CC"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
fi
# We must check for the threads library under a number of different
@@ -118,12 +129,14 @@ fi
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
# Create a list of thread flags to try. Items with a "," contain both
# C compiler flags (before ",") and linker flags (after ","). Other items
# starting with a "-" are C compiler flags, and remaining items are
# library names, except for "none" which indicates that we try without
# any flags at all, and "pthread-config" which is a program returning
# the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
@@ -132,82 +145,163 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
# (Note: HP C rejects this with "bad form for `-t' option")
# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# doesn't hurt to check since this sometimes defines pthreads and
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
# is present but should not be used directly; and before -mthreads,
# because the compiler interprets this as "-mt" + "-hreads")
# -mthreads: Mingw32/gcc, Lynx/gcc
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case ${host_os} in
case $host_os in
freebsd*)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
;;
hpux*)
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
# multi-threading and also sets -lpthread."
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
;;
openedition*)
# IBM z/OS requires a feature-test macro to be defined in order to
# enable POSIX threads at all, so give the user a hint if this is
# not set. (We don't define these ourselves, as they can affect
# other portions of the system API in unpredictable ways.)
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
[
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
AX_PTHREAD_ZOS_MISSING
# endif
],
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
;;
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
# tests will erroneously succeed. (N.B.: The stubs are missing
# pthread_cleanup_push, or rather a function called by this macro,
# so we could check for that, but who knows whether they'll stub
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
;;
esac
# Clang doesn't consider unrecognized options an error unless we specify
# -Werror. We throw in some extra Clang-specific options to ensure that
# this doesn't happen for GCC, which also accepts -Werror.
# Are we compiling with Clang?
AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
save_CFLAGS="$CFLAGS"
ax_pthread_extra_flags="-Werror"
CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
[AC_MSG_RESULT([yes])],
[ax_pthread_extra_flags=
AC_MSG_RESULT([no])])
CFLAGS="$save_CFLAGS"
AC_CACHE_CHECK([whether $CC is Clang],
[ax_cv_PTHREAD_CLANG],
[ax_cv_PTHREAD_CLANG=no
# Note that Autoconf sets GCC=yes for Clang as well as GCC
if test "x$GCC" = "xyes"; then
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
# if defined(__clang__) && defined(__llvm__)
AX_PTHREAD_CC_IS_CLANG
# endif
],
[ax_cv_PTHREAD_CLANG=yes])
fi
])
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
# Note that for GCC and Clang -pthread generally implies -lpthread,
# except when -nostdlib is passed.
# This is problematic using libtool to build C++ shared libraries with pthread:
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
# To solve this, first try -pthread together with -lpthread for GCC
AS_IF([test "x$GCC" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
AS_IF([test "x$ax_pthread_clang" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread"])
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
# correctly enabled
case $host_os in
darwin* | hpux* | linux* | osf* | solaris*)
ax_pthread_check_macro="_REENTRANT"
;;
aix*)
ax_pthread_check_macro="_THREAD_SAFE"
;;
*)
ax_pthread_check_macro="--"
;;
esac
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
if test "x$ax_pthread_ok" = "xno"; then
for ax_pthread_try_flag in $ax_pthread_flags; do
case $ax_pthread_try_flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
*,*)
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
PTHREAD_CFLAGS="$ax_pthread_try_flag"
;;
pthread-config)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
if test x"$ax_pthread_config" = xno; then continue; fi
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
PTHREAD_LIBS="-l$ax_pthread_try_flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -218,8 +312,18 @@ for flag in $ax_pthread_flags; do
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { *((int*)a) = 0; }
# if $ax_pthread_check_cond
# error "$ax_pthread_check_macro must be defined"
# endif
static void *some_global = NULL;
static void routine(void *a)
{
/* To avoid any unused-parameter or
unused-but-set-parameter warning. */
some_global = a;
}
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
@@ -227,101 +331,187 @@ for flag in $ax_pthread_flags; do
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = xyes; then
break;
fi
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
if test "x$ax_pthread_clang" = "xyes"; then
# Clang takes -pthread; it has never supported any other flag
# (Note 1: This will need to be revisited if a system that Clang
# supports has POSIX threads in a separate library. This tends not
# to be the way of modern systems, but it's conceivable.)
# (Note 2: On some systems, notably Darwin, -pthread is not needed
# to get POSIX threads support; the API is always present and
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
# during compilation"). They expect -pthread to be passed in only
# when source code is being compiled.
#
# Problem is, this is at odds with the way Automake and most other
# C build frameworks function, which is that the same flags used in
# compilation (CFLAGS) are also used in linking. Many systems
# supported by AX_PTHREAD require exactly this for POSIX threads
# support, and in fact it is often not straightforward to specify a
# flag that is used only in the compilation phase and not in
# linking. Such a scenario is extremely rare in practice.
#
# Even though use of the -pthread flag in linking would only print
# a warning, this can be a nuisance for well-run software projects
# that build with -Werror. So if the active version of Clang has
# this misfeature, we search for an option to squash it.
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
# Create an alternate version of $ac_link that compiles and
# links in two steps (.c -> .o, .o -> exe) instead of one
# (.c -> exe), because the warning occurs only in the second
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
ac_link="$ax_pthread_save_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[ac_link="$ax_pthread_2step_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[break])
])
done
ac_link="$ax_pthread_save_ac_link"
CFLAGS="$ax_pthread_save_CFLAGS"
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
])
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
no | unknown) ;;
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
esac
fi # $ax_pthread_clang = yes
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
if test "x$ax_pthread_ok" = "xyes"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT([$attr_name])
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_CACHE_CHECK([for joinable pthread attribute],
[ax_cv_PTHREAD_JOINABLE_ATTR],
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $ax_pthread_attr; return attr /* ; */])],
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
[])
done
])
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
[$ax_cv_PTHREAD_JOINABLE_ATTR],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
ax_pthread_joinable_attr_defined=yes
])
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case ${host_os} in
aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
osf* | hpux*) flag="-D_REENTRANT";;
solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
# TODO: What about Clang on Solaris?
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT([$flag])
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([whether more special flags are required for pthreads],
[ax_cv_PTHREAD_SPECIAL_FLAGS],
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
case $host_os in
solaris*)
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
;;
esac
])
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
test "x$ax_pthread_special_flags_added" != "xyes"],
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
ax_pthread_special_flags_added=yes])
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;
return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
ax_pthread_prio_inherit_defined=yes
])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
# More AIX lossage: compile with *_r variant
if test "x$GCC" != xyes; then
if test "x$GCC" != "xyes"; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[
AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
],
[
AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
]
)
])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
AC_SUBST([PTHREAD_CXX])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
if test "x$ax_pthread_ok" = "xyes"; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
+212 -44
View File
@@ -50,6 +50,8 @@
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "services/cache/dns.h"
#include "services/mesh.h"
#include "services/modstack.h"
#include "validator/val_neg.h"
#include "validator/val_secalgo.h"
#include "iterator/iter_utils.h"
@@ -102,7 +104,6 @@ static int
testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
{
struct testframe_moddata* d;
(void)env;
verbose(VERB_ALGO, "testframe_init");
d = (struct testframe_moddata*)calloc(1,
sizeof(struct testframe_moddata));
@@ -111,6 +112,15 @@ testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("out of memory");
return 0;
}
/* Register an EDNS option (65534) to bypass the worker cache lookup
* for testing */
if(!edns_register_option(LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST,
1 /* bypass cache */,
0 /* no aggregation */, env)) {
log_err("testframe_init, could not register test opcode");
free(d);
return 0;
}
lock_basic_init(&d->lock);
lock_protect(&d->lock, d, sizeof(*d));
return 1;
@@ -218,6 +228,8 @@ static int
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
{
const char* backend_str = cfg->cachedb_backend;
if(!backend_str || *backend_str==0)
return 1;
cachedb_env->backend = cachedb_find_backend(backend_str);
if(!cachedb_env->backend) {
log_err("cachedb: cannot find backend name '%s'", backend_str);
@@ -228,7 +240,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
return 1;
}
int
int
cachedb_init(struct module_env* env, int id)
{
struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
@@ -255,31 +267,19 @@ cachedb_init(struct module_env* env, int id)
return 0;
}
cachedb_env->enabled = 1;
if(env->cfg->serve_expired_reply_ttl)
log_warn(
"cachedb: serve-expired-reply-ttl is set but not working for data "
"originating from the external cache; 0 TLL is used for those.");
if(env->cfg->serve_expired_client_timeout)
log_warn(
"cachedb: serve-expired-client-timeout is set but not working for "
"data originating from the external cache; expired data are used "
"in the reply without first trying to refresh the data.");
return 1;
}
void
void
cachedb_deinit(struct module_env* env, int id)
{
struct cachedb_env* cachedb_env;
if(!env || !env->modinfo[id])
return;
cachedb_env = (struct cachedb_env*)env->modinfo[id];
/* free contents */
/* TODO */
if(cachedb_env->enabled) {
(*cachedb_env->backend->deinit)(env, cachedb_env);
}
free(cachedb_env);
env->modinfo[id] = NULL;
}
@@ -322,30 +322,30 @@ error_response(struct module_qstate* qstate, int id, int rcode)
/**
* Hash the query name, type, class and dbacess-secret into lookup buffer.
* @param qstate: query state with query info
* and env->cfg with secret.
* @param qinfo: query info
* @param env: with env->cfg with secret.
* @param buf: returned buffer with hash to lookup
* @param len: length of the buffer.
*/
static void
calc_hash(struct module_qstate* qstate, char* buf, size_t len)
calc_hash(struct query_info* qinfo, struct module_env* env, char* buf,
size_t len)
{
uint8_t clear[1024];
size_t clen = 0;
uint8_t hash[CACHEDB_HASHSIZE/8];
const char* hex = "0123456789ABCDEF";
const char* secret = qstate->env->cfg->cachedb_secret;
const char* secret = env->cfg->cachedb_secret;
size_t i;
/* copy the hash info into the clear buffer */
if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
memmove(clear+clen, qstate->qinfo.qname,
qstate->qinfo.qname_len);
clen += qstate->qinfo.qname_len;
if(clen + qinfo->qname_len < sizeof(clear)) {
memmove(clear+clen, qinfo->qname, qinfo->qname_len);
clen += qinfo->qname_len;
}
if(clen + 4 < sizeof(clear)) {
uint16_t t = htons(qstate->qinfo.qtype);
uint16_t c = htons(qstate->qinfo.qclass);
uint16_t t = htons(qinfo->qtype);
uint16_t c = htons(qinfo->qclass);
memmove(clear+clen, &t, 2);
memmove(clear+clen+2, &c, 2);
clen += 4;
@@ -390,6 +390,15 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
if(!qstate->return_msg || !qstate->return_msg->rep)
return 0;
/* do not store failures like SERVFAIL in the cachedb, this avoids
* overwriting expired, valid, content with broken content. */
if(FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
/* We don't store the reply if its TTL is 0 unless serve-expired is
* enabled. Such a reply won't be reusable and simply be a waste for
* the backend. It's also compatible with the default behavior of
@@ -397,6 +406,14 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
if(qstate->return_msg->rep->ttl == 0 &&
!qstate->env->cfg->serve_expired)
return 0;
/* The EDE is added to the out-list so it is encoded in the cached message */
if (qstate->env->cfg->ede && qstate->return_msg->rep->reason_bogus != LDNS_EDE_NONE) {
edns_opt_list_append_ede(&edns.opt_list_out, qstate->env->scratch,
qstate->return_msg->rep->reason_bogus,
qstate->return_msg->rep->reason_bogus_str);
}
if(verbosity >= VERB_ALGO)
log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
qstate->return_msg->rep);
@@ -487,12 +504,42 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
}
}
/* Set the TTL of the given RRset to fixed value. */
static void
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
{
size_t i;
size_t total = data->count + data->rrsig_count;
data->ttl = ttl;
for(i=0; i<total; i++) {
data->rr_ttl[i] = ttl;
}
data->ttl_add = 0;
}
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
static void
set_msg_ttl(struct dns_msg* msg, time_t ttl)
{
size_t i;
msg->rep->ttl = ttl;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, ttl);
}
}
/** convert dns message in buffer to return_msg */
static int
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
int* msg_expired)
{
struct msg_parse* prs;
struct edns_data edns;
struct edns_option* ede;
uint64_t timestamp, expiry;
time_t adjust;
size_t lim = sldns_buffer_limit(buf);
@@ -530,6 +577,24 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
if(!qstate->return_msg)
return 0;
/* We find the EDE in the in-list after parsing */
if(qstate->env->cfg->ede &&
(ede = edns_opt_list_find(edns.opt_list_in, LDNS_EDNS_EDE))) {
if(ede->opt_len >= 2) {
qstate->return_msg->rep->reason_bogus =
sldns_read_uint16(ede->opt_data);
}
/* allocate space and store the error string and it's size */
if(ede->opt_len > 2) {
size_t ede_len = ede->opt_len - 2;
qstate->return_msg->rep->reason_bogus_str = regional_alloc(
qstate->region, sizeof(char) * (ede_len+1));
memcpy(qstate->return_msg->rep->reason_bogus_str,
ede->opt_data+2, ede_len);
qstate->return_msg->rep->reason_bogus_str[ede_len] = 0;
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;
/* see how much of the TTL expired, and remove it */
@@ -540,15 +605,25 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
adjust = *qstate->env->now - (time_t)timestamp;
if(qstate->return_msg->rep->ttl < adjust) {
verbose(VERB_ALGO, "cachedb msg expired");
*msg_expired = 1;
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
if(qstate->env->cfg->serve_expired)
adjust = -1;
else
if(!qstate->env->cfg->serve_expired ||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */
else
adjust = -1;
}
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
@@ -556,6 +631,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
* 'now' should be redundant given how these values were calculated,
* but we check it just in case as does good_expiry_and_qinfo(). */
if(qstate->env->cfg->serve_expired &&
!qstate->env->cfg->serve_expired_client_timeout &&
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
qstate->need_refetch = 1;
}
@@ -568,10 +644,11 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
* return true if lookup was successful.
*/
static int
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie)
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
int* msg_expired)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(qstate, key, sizeof(key));
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
/* call backend to fetch data for key into scratch buffer */
if( !(*ie->backend->lookup)(qstate->env, ie, key,
@@ -585,7 +662,7 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie)
}
/* parse dns message into return_msg */
if( !parse_data(qstate, qstate->env->scratch_buffer) ) {
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired) ) {
return 0;
}
return 1;
@@ -598,7 +675,7 @@ static void
cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(qstate, key, sizeof(key));
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
/* prepare data in scratch buffer */
if(!prep_data(qstate, qstate->env->scratch_buffer))
@@ -615,13 +692,18 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
* See if unbound's internal cache can answer the query
*/
static int
cachedb_intcache_lookup(struct module_qstate* qstate)
cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
{
uint8_t dpname_storage[LDNS_MAX_DOMAINLEN+1];
uint8_t* dpname=NULL;
size_t dpnamelen=0;
struct dns_msg* msg;
/* for testframe bypass this lookup */
if(cde->backend == &testframe_backend) {
return 0;
}
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo,
&dpname, &dpnamelen))
&dpname, &dpnamelen, dpname_storage, sizeof(dpname_storage)))
return 0; /* no cache for these queries */
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,
@@ -652,17 +734,43 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
* Store query into the internal cache of unbound.
*/
static void
cachedb_intcache_store(struct module_qstate* qstate)
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
{
uint32_t store_flags = qstate->query_flags;
int serve_expired = qstate->env->cfg->serve_expired;
if(qstate->env->cfg->serve_expired)
store_flags |= DNSCACHE_STORE_ZEROTTL;
if(!qstate->return_msg)
return;
if(serve_expired && msg_expired) {
/* Set TTLs to a value such that value + *env->now is
* going to be now-3 seconds. Making it expired
* in the cache. */
set_msg_ttl(qstate->return_msg, (time_t)-3);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
qstate->return_msg->rep->security = sec_status_insecure;
}
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
qstate->region, store_flags, qstate->qstarttime);
if(serve_expired && msg_expired) {
if(qstate->env->cfg->serve_expired_client_timeout) {
/* No expired response from the query state, the
* query resolution needs to continue and it can
* pick up the expired result after the timer out
* of cache. */
return;
}
/* set TTLs to zero again */
adjust_msg_ttl(qstate->return_msg, -1);
/* Send serve expired responses based on the cachedb
* returned message, that was just stored in the cache.
* It can then continue to work on this query. */
mesh_respond_serve_expired(qstate->mesh_info);
}
}
/**
@@ -678,6 +786,8 @@ cachedb_handle_query(struct module_qstate* qstate,
struct cachedb_qstate* ATTR_UNUSED(iq),
struct cachedb_env* ie, int id)
{
int msg_expired = 0;
qstate->is_cachedb_answer = 0;
/* check if we are enabled, and skip if so */
if(!ie->enabled) {
/* pass request to next module */
@@ -694,7 +804,7 @@ cachedb_handle_query(struct module_qstate* qstate,
/* lookup inside unbound's internal cache.
* This does not look for expired entries. */
if(cachedb_intcache_lookup(qstate)) {
if(cachedb_intcache_lookup(qstate, ie)) {
if(verbosity >= VERB_ALGO) {
if(qstate->return_msg->rep)
log_dns_msg("cachedb internal cache lookup",
@@ -711,31 +821,46 @@ cachedb_handle_query(struct module_qstate* qstate,
}
/* ask backend cache to see if we have data */
if(cachedb_extcache_lookup(qstate, ie)) {
if(cachedb_extcache_lookup(qstate, ie, &msg_expired)) {
if(verbosity >= VERB_ALGO)
log_dns_msg(ie->backend->name,
&qstate->return_msg->qinfo,
qstate->return_msg->rep);
/* store this result in internal cache */
cachedb_intcache_store(qstate);
cachedb_intcache_store(qstate, msg_expired);
/* 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.
* Document that ext cachedb does not work properly with
* serve_stale_reply_ttl yet. */
*/
if(qstate->env->cfg->serve_expired && msg_expired) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_wait_module;
/* The expired reply is sent with
* mesh_respond_serve_expired, and so
* the need_refetch is not used. */
qstate->need_refetch = 0;
return;
}
if(qstate->need_refetch && qstate->serve_expired_data &&
qstate->serve_expired_data->timer) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_wait_module;
return;
}
qstate->is_cachedb_answer = 1;
/* we are done with the query */
qstate->ext_state[id] = module_finished;
return;
}
if(qstate->serve_expired_data &&
qstate->env->cfg->cachedb_check_when_serve_expired &&
!qstate->env->cfg->serve_expired_client_timeout) {
/* Reply with expired data if any to client, because cachedb
* also has no useful, current data */
mesh_respond_serve_expired(qstate->mesh_info);
}
/* no cache fetches */
/* pass request to next module */
qstate->ext_state[id] = module_wait_module;
@@ -753,12 +878,18 @@ static void
cachedb_handle_response(struct module_qstate* qstate,
struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
{
qstate->is_cachedb_answer = 0;
/* check if we are not enabled or instructed to not cache, and skip */
if(!ie->enabled || qstate->no_cache_store) {
/* we are done with the query */
qstate->ext_state[id] = module_finished;
return;
}
if(qstate->env->cfg->cachedb_no_store) {
/* do not store the item in the external cache */
qstate->ext_state[id] = module_finished;
return;
}
/* store the item into the backend cache */
cachedb_extcache_store(qstate, ie);
@@ -853,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
};
@@ -862,4 +993,41 @@ cachedb_get_funcblock(void)
{
return &cachedb_block;
}
int
cachedb_is_enabled(struct module_stack* mods, struct module_env* env)
{
struct cachedb_env* ie;
int id = modstack_find(mods, "cachedb");
if(id == -1)
return 0;
ie = (struct cachedb_env*)env->modinfo[id];
if(ie && ie->enabled)
return 1;
return 0;
}
void cachedb_msg_remove(struct module_qstate* qstate)
{
cachedb_msg_remove_qinfo(qstate->env, &qstate->qinfo);
}
void cachedb_msg_remove_qinfo(struct module_env* env, struct query_info* qinfo)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
int id = modstack_find(env->modstack, "cachedb");
struct cachedb_env* ie = (struct cachedb_env*)env->modinfo[id];
log_query_info(VERB_ALGO, "cachedb msg remove", qinfo);
calc_hash(qinfo, env, key, sizeof(key));
sldns_buffer_clear(env->scratch_buffer);
sldns_buffer_write_u32(env->scratch_buffer, 0);
sldns_buffer_flip(env->scratch_buffer);
/* call backend */
(*ie->backend->store)(env, ie, key,
sldns_buffer_begin(env->scratch_buffer),
sldns_buffer_limit(env->scratch_buffer),
0);
}
#endif /* USE_CACHEDB */
+24
View File
@@ -41,6 +41,7 @@
*/
#include "util/module.h"
struct cachedb_backend;
struct module_stack;
/**
* The global variable environment contents for the cachedb
@@ -110,3 +111,26 @@ size_t cachedb_get_mem(struct module_env* env, int id);
*/
struct module_func_block* cachedb_get_funcblock(void);
/**
* See if the cachedb is enabled.
* @param mods: module stack. It finds the cachedb module environment.
* @param env: module environment.
* @return true if exists and enabled.
*/
int cachedb_is_enabled(struct module_stack* mods, struct module_env* env);
/**
* Remove a message from the global cache. Because edns subnet has a more
* specific entry, and if not removed when everything expires, the global
* entry is used, instead of a fresh lookup of the edns subnet entry.
* @param qstate: query state.
*/
void cachedb_msg_remove(struct module_qstate* qstate);
/**
* Remove message from the cachedb cache, by query info.
* @param env: module environment to look up cachedb state.
* @param qinfo: the message to remove.
*/
void cachedb_msg_remove_qinfo(struct module_env* env,
struct query_info* qinfo);
+92 -29
View File
@@ -56,19 +56,44 @@ struct redis_moddata {
int numctxs; /* number of ctx entries */
const char* server_host; /* server's IP address or host name */
int server_port; /* server's TCP port */
struct timeval timeout; /* timeout for connection setup and commands */
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 command_timeout; /* timeout for commands */
struct timeval connect_timeout; /* timeout for connect */
int logical_db; /* the redis logical database to use */
};
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t);
static void
moddata_clean(struct redis_moddata** moddata) {
if(!moddata || !*moddata)
return;
if((*moddata)->ctxs) {
int i;
for(i = 0; i < (*moddata)->numctxs; i++) {
if((*moddata)->ctxs[i])
redisFree((*moddata)->ctxs[i]);
}
free((*moddata)->ctxs);
}
free(*moddata);
*moddata = NULL;
}
static redisContext*
redis_connect(const struct redis_moddata* moddata)
{
redisContext* ctx;
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout);
if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->connect_timeout);
} else {
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->connect_timeout);
}
if(!ctx || ctx->err) {
const char *errstr = "out of memory";
if(ctx)
@@ -76,13 +101,35 @@ 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;
}
if(moddata->server_password && moddata->server_password[0]!=0) {
redisReply* rep;
rep = redisCommand(ctx, "AUTH %s", moddata->server_password);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to authenticate with password");
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
if(moddata->logical_db > 0) {
redisReply* rep;
rep = redisCommand(ctx, "SELECT %d", moddata->logical_db);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to set logical database (%d)",
moddata->logical_db);
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
verbose(VERB_OPS, "Connection to Redis established");
return ctx;
fail:
fail:
if(ctx)
redisFree(ctx);
return NULL;
@@ -94,28 +141,52 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
int i;
struct redis_moddata* moddata = NULL;
verbose(VERB_ALGO, "redis_init");
verbose(VERB_OPS, "Redis initialization");
moddata = calloc(1, sizeof(struct redis_moddata));
if(!moddata) {
log_err("out of memory");
return 0;
goto fail;
}
moddata->numctxs = env->cfg->num_threads;
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
if(!moddata->ctxs) {
log_err("out of memory");
free(moddata);
return 0;
goto fail;
}
/* note: server_host is a shallow reference to configured string.
* we don't have to free it in this module. */
moddata->server_host = env->cfg->redis_server_host;
moddata->server_port = env->cfg->redis_server_port;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
for(i = 0; i < moddata->numctxs; i++)
moddata->ctxs[i] = redis_connect(moddata);
moddata->server_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password;
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);
if(!ctx) {
log_err("redis_init: failed to init redis");
goto fail;
}
moddata->ctxs[i] = ctx;
}
cachedb_env->backend_data = moddata;
if(env->cfg->redis_expire_records) {
redisReply* rep = NULL;
@@ -128,7 +199,7 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
return 0;
goto fail;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
@@ -140,11 +211,14 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
return 0;
goto fail;
}
}
return 1;
fail:
moddata_clean(&moddata);
return 0;
}
static void
@@ -154,19 +228,8 @@ redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
cachedb_env->backend_data;
(void)env;
verbose(VERB_ALGO, "redis_deinit");
if(!moddata)
return;
if(moddata->ctxs) {
int i;
for(i = 0; i < moddata->numctxs; i++) {
if(moddata->ctxs[i])
redisFree(moddata->ctxs[i]);
}
free(moddata->ctxs);
}
free(moddata);
verbose(VERB_OPS, "Redis deinitialization");
moddata_clean(&moddata);
}
/*
+7 -1
View File
@@ -57,6 +57,8 @@
#define BLOCKSZ 64
#define RSBUFSZ (16*BLOCKSZ)
#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
static struct {
size_t rs_have; /* valid bytes at end of rs_buf */
@@ -179,6 +181,7 @@ static void
_rs_stir(void)
{
u_char rnd[KEYSZ + IVSZ];
uint32_t rekey_fuzz = 0;
if (getentropy(rnd, sizeof rnd) == -1) {
if(errno != ENOSYS ||
@@ -201,7 +204,10 @@ _rs_stir(void)
rs->rs_have = 0;
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
rs->rs_count = 1600000;
/* rekey interval should not be predictable */
chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
(uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
}
static inline void
+1 -1
View File
@@ -47,7 +47,7 @@
#define SHA512_Update SHA512Update
#define SHA512_Final SHA512Final
#else
#include "openssl/sha.h"
#include <openssl/sha.h>
#endif
#include <sys/vfs.h>
+704 -559
View File
File diff suppressed because it is too large Load Diff
+220 -34
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
@@ -298,6 +312,9 @@
/* Define to 1 if you have the `getrlimit' function. */
#undef HAVE_GETRLIMIT
/* Define to 1 if you have the `gettid' function. */
#undef HAVE_GETTID
/* Define to 1 if you have the `glob' function. */
#undef HAVE_GLOB
@@ -361,6 +378,9 @@
/* Define if we have LibreSSL */
#undef HAVE_LIBRESSL
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
@@ -373,8 +393,8 @@
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MINIX_CONFIG_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
@@ -400,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
@@ -457,6 +539,12 @@
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
#undef HAVE_OSSL_PARAM_BLD_NEW
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
@@ -554,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
@@ -563,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
@@ -575,6 +669,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -602,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
@@ -677,6 +791,9 @@
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
@@ -800,19 +917,27 @@
/* Shared data */
#undef SHARE_DIR
/* The size of `pthread_t', as computed by sizeof. */
#undef SIZEOF_PTHREAD_T
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `time_t', as computed by sizeof. */
#undef SIZEOF_TIME_T
/* The size of `unsigned long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG
/* define if (v)snprintf does not return length needed, (but length used) */
#undef SNPRINTF_RET_BROKEN
/* Define to 1 if libsodium supports sodium_set_misuse_handler */
#undef SODIUM_MISUSE_HANDLER
/* Define to 1 if you have the ANSI C header files. */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* use default strptime. */
@@ -908,21 +1033,87 @@
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# undef _DARWIN_C_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
/* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# undef _HPUX_ALT_XOPEN_SOCKET_API
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
# undef _MINIX
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# undef _NETBSD_SOURCE
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# undef _OPENBSD_SOURCE
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
# undef _POSIX_SOURCE
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
# undef _POSIX_1_SOURCE
#endif
/* Enable POSIX-compatible threading on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# undef __STDC_WANT_IEC_60559_BFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# undef __STDC_WANT_LIB_EXT2__
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# undef __STDC_WANT_MATH_SPEC_FUNCS__
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
/* Enable X/Open extensions. Define to 500 only if necessary
to make mbstate_t available. */
#ifndef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
#endif
@@ -948,11 +1139,6 @@
`char[]'. */
#undef YYTEXT_POINTER
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
@@ -962,19 +1148,9 @@
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Enable for compile on Minix */
#undef _NETBSD_SOURCE
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* defined to use gcc ansi snprintf and sscanf that understands %lld when
compiled for windows. */
#undef __USE_MINGW_ANSI_STDIO
@@ -1015,7 +1191,7 @@
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `int' if <sys/types.h> does not define. */
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t
/* Define to 'int' if not defined */
@@ -1053,39 +1229,39 @@
#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
#define _BSD_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE)
#define _DEFAULT_SOURCE 1
#endif
#endif
#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
#define __EXTENSIONS__ 1
#endif
#endif
#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112
#endif
#endif
#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE 600
#endif
#endif
#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
#define _XOPEN_SOURCE_EXTENDED 1
#endif
#endif
#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
#define _ALL_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
#define _LARGEFILE_SOURCE 1
#endif
#endif
@@ -1169,7 +1345,7 @@
#endif
#ifdef HAVE_ATTR_FORMAT
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
@@ -1279,7 +1455,7 @@ void* reallocarray(void *ptr, size_t nmemb, size_t size);
#ifdef HAVE_WINSOCK2_H
#define FD_SET_T (u_int)
#else
#define FD_SET_T
#define FD_SET_T
#endif
@@ -1407,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);
@@ -1419,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 */
@@ -1429,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
+503 -325
View File
File diff suppressed because it is too large Load Diff
Vendored
+8074 -5095
View File
File diff suppressed because it is too large Load Diff
+248 -68
View File
@@ -4,21 +4,21 @@ AC_PREREQ([2.56])
sinclude(acx_nlnetlabs.m4)
sinclude(ax_pthread.m4)
sinclude(acx_python.m4)
sinclude(ac_pkg_swig.m4)
sinclude(ax_pkg_swig.m4)
sinclude(dnstap/dnstap.m4)
sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[16])
m4_define([VERSION_MICRO],[3])
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=19
LIBUNBOUND_REVISION=30
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -105,6 +105,17 @@ LIBUNBOUND_AGE=1
# 1.16.1 had 9:17:1
# 1.16.2 had 9:18:1
# 1.16.3 had 9:19:1
# 1.17.0 had 9:20:1
# 1.17.1 had 9:21:1
# 1.18.0 had 9:22:1
# 1.19.0 had 9:23:1
# 1.19.1 had 9:24:1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27: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
@@ -154,7 +165,7 @@ esac
# are we on MinGW?
if uname -s 2>&1 | grep MINGW >/dev/null; then on_mingw="yes"
else
else
if echo $host | grep mingw >/dev/null; then on_mingw="yes"
else on_mingw="no"; fi
fi
@@ -183,9 +194,9 @@ ub_conf_dir=`AS_DIRNAME(["$ub_conf_file"])`
AC_SUBST(ub_conf_dir)
# Determine run, chroot directory and pidfile locations
AC_ARG_WITH(run-dir,
AS_HELP_STRING([--with-run-dir=path],[set default directory to chdir to (by default dir part of cfg file)]),
UNBOUND_RUN_DIR="$withval",
AC_ARG_WITH(run-dir,
AS_HELP_STRING([--with-run-dir=path],[set default directory to chdir to (by default dir part of cfg file)]),
UNBOUND_RUN_DIR="$withval",
if test $on_mingw = no; then
UNBOUND_RUN_DIR=`dirname "$ub_conf_file"`
else
@@ -196,9 +207,9 @@ AC_SUBST(UNBOUND_RUN_DIR)
ACX_ESCAPE_BACKSLASH($UNBOUND_RUN_DIR, hdr_run)
AC_DEFINE_UNQUOTED(RUN_DIR, ["$hdr_run"], [Directory to chdir to])
AC_ARG_WITH(chroot-dir,
AS_HELP_STRING([--with-chroot-dir=path],[set default directory to chroot to (by default same as run-dir)]),
UNBOUND_CHROOT_DIR="$withval",
AC_ARG_WITH(chroot-dir,
AS_HELP_STRING([--with-chroot-dir=path],[set default directory to chroot to (by default same as run-dir)]),
UNBOUND_CHROOT_DIR="$withval",
if test $on_mingw = no; then
UNBOUND_CHROOT_DIR="$UNBOUND_RUN_DIR"
else
@@ -216,9 +227,9 @@ AC_ARG_WITH(share-dir,
AC_SUBST(UNBOUND_SHARE_DIR)
AC_DEFINE_UNQUOTED(SHARE_DIR, ["$UNBOUND_SHARE_DIR"], [Shared data])
AC_ARG_WITH(pidfile,
AS_HELP_STRING([--with-pidfile=filename],[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
UNBOUND_PIDFILE="$withval",
AC_ARG_WITH(pidfile,
AS_HELP_STRING([--with-pidfile=filename],[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
UNBOUND_PIDFILE="$withval",
if test $on_mingw = no; then
UNBOUND_PIDFILE="$UNBOUND_RUN_DIR/unbound.pid"
else
@@ -229,9 +240,9 @@ AC_SUBST(UNBOUND_PIDFILE)
ACX_ESCAPE_BACKSLASH($UNBOUND_PIDFILE, hdr_pid)
AC_DEFINE_UNQUOTED(PIDFILE, ["$hdr_pid"], [default pidfile location])
AC_ARG_WITH(rootkey-file,
AS_HELP_STRING([--with-rootkey-file=filename],[set default pathname to root key file (default run-dir/root.key). This file is read and written.]),
UNBOUND_ROOTKEY_FILE="$withval",
AC_ARG_WITH(rootkey-file,
AS_HELP_STRING([--with-rootkey-file=filename],[set default pathname to root key file (default run-dir/root.key). This file is read and written.]),
UNBOUND_ROOTKEY_FILE="$withval",
if test $on_mingw = no; then
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
else
@@ -242,9 +253,9 @@ AC_SUBST(UNBOUND_ROOTKEY_FILE)
ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTKEY_FILE, hdr_rkey)
AC_DEFINE_UNQUOTED(ROOT_ANCHOR_FILE, ["$hdr_rkey"], [default rootkey location])
AC_ARG_WITH(rootcert-file,
AS_HELP_STRING([--with-rootcert-file=filename],[set default pathname to root update certificate file (default run-dir/icannbundle.pem). This file need not exist if you are content with the builtin.]),
UNBOUND_ROOTCERT_FILE="$withval",
AC_ARG_WITH(rootcert-file,
AS_HELP_STRING([--with-rootcert-file=filename],[set default pathname to root update certificate file (default run-dir/icannbundle.pem). This file need not exist if you are content with the builtin.]),
UNBOUND_ROOTCERT_FILE="$withval",
if test $on_mingw = no; then
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
else
@@ -255,9 +266,9 @@ AC_SUBST(UNBOUND_ROOTCERT_FILE)
ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTCERT_FILE, hdr_rpem)
AC_DEFINE_UNQUOTED(ROOT_CERT_FILE, ["$hdr_rpem"], [default rootcert location])
AC_ARG_WITH(username,
AS_HELP_STRING([--with-username=user],[set default user that unbound changes to (default user is unbound)]),
UNBOUND_USERNAME="$withval",
AC_ARG_WITH(username,
AS_HELP_STRING([--with-username=user],[set default user that unbound changes to (default user is unbound)]),
UNBOUND_USERNAME="$withval",
UNBOUND_USERNAME="unbound")
AC_SUBST(UNBOUND_USERNAME)
AC_DEFINE_UNQUOTED(UB_USERNAME, ["$UNBOUND_USERNAME"], [default username])
@@ -266,6 +277,9 @@ AC_DEFINE(WINVER, 0x0502, [the version of the windows API enabled])
ACX_RSRC_VERSION(wnvs)
AC_DEFINE_UNQUOTED(RSRC_PACKAGE_VERSION, [$wnvs], [version number for resource files])
# Check for 'grep -e' program, here, since ACX_CHECK_FLTO needs that.
AC_PROG_GREP
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_LANG([C])
@@ -276,14 +290,14 @@ ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"])
ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
default_cflags=yes
fi
AC_PROG_CC
m4_version_prereq([2.70], [AC_PROG_CC], [AC_PROG_CC_STDC])
ACX_DEPFLAG
ACX_DETERMINE_EXT_FLAGS_UNBOUND
# debug mode flags warnings
AC_ARG_ENABLE(checking, AS_HELP_STRING([--enable-checking],[Enable warnings, asserts, makefile-dependencies]))
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[same as enable-checking]))
if test "$enable_debug" = "yes"; then debug_enabled="$enable_debug";
if test "$enable_debug" = "yes"; then debug_enabled="$enable_debug";
else debug_enabled="$enable_checking"; fi
AC_SUBST(debug_enabled)
case "$debug_enabled" in
@@ -327,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
@@ -348,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
@@ -386,18 +445,28 @@ fi
if test "$LEX" != "" -a "$LEX" != ":"; then
ACX_YYLEX_OPTION
fi
if test "$LEX" = "" -o "$LEX" = ":"; then
if test ! -f util/configlexer.c; then
AC_MSG_ERROR([no lex and no util/configlexer.c: need flex and bison to compile from source repository.])
fi
fi
AC_PROG_YACC
if test "$YACC" = "" -o "$YACC" = ":"; then
if test ! -f util/configparser.c; then
AC_MSG_ERROR([no yacc and no util/configparser.c: need flex and bison to compile from source repository.])
fi
fi
AC_CHECK_PROG(doxygen, doxygen, doxygen)
AC_CHECK_TOOL(STRIP, strip)
ACX_LIBTOOL_C_ONLY
# pkg-config is only needed for these options, do not require it otherwise
if test "$enable_systemd" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
if test "$enable_systemd" = "yes" -o "$enable_dnstap" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
PKG_PROG_PKG_CONFIG
fi
# Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT])
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
AC_CHECK_HEADERS([net/if.h],,, [
@@ -451,6 +520,9 @@ AC_CHECK_HEADERS([netioapi.h],,, [AC_INCLUDES_DEFAULT
#endif
])
# Check for Linux timestamping headers
AC_CHECK_HEADERS([linux/net_tstamp.h],,, [AC_INCLUDES_DEFAULT])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
AC_CHECK_TYPE(int8_t, signed char)
@@ -509,7 +581,8 @@ res = strptime("2010-07-15T00:00:00+00:00", "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:
if (!res) return 2;
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
if (!res) return 1; return 0; }
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"],
[eval "ac_cv_c_strptime_works=maybe"])
else
eval "ac_cv_c_strptime_works=maybe"
fi
@@ -546,11 +619,11 @@ sinclude(systemd.m4)
# Include systemd.m4 - end
# set memory allocation checking if requested
AC_ARG_ENABLE(alloc-checks, AS_HELP_STRING([--enable-alloc-checks],[ enable to memory allocation statistics, for debug purposes ]),
AC_ARG_ENABLE(alloc-checks, AS_HELP_STRING([--enable-alloc-checks],[ enable to memory allocation statistics, for debug purposes ]),
, )
AC_ARG_ENABLE(alloc-lite, AS_HELP_STRING([--enable-alloc-lite],[ enable for lightweight alloc assertions, for debug purposes ]),
AC_ARG_ENABLE(alloc-lite, AS_HELP_STRING([--enable-alloc-lite],[ enable for lightweight alloc assertions, for debug purposes ]),
, )
AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ enable nonregional allocs, slow but exposes regional allocations to other memory purifiers, for debug purposes ]),
, )
if test x_$enable_alloc_nonregional = x_yes; then
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
@@ -583,7 +656,7 @@ if test "$on_mingw" = "yes"; then
])],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_WINDOWS_THREADS, 1, [Using Windows threads])
,
,
AC_MSG_RESULT(no)
)
@@ -594,7 +667,7 @@ else
# check this first, so that the pthread lib does not get linked in via
# libssl or libpython, and thus distorts the tests, and we end up using
# the non-threadsafe C libraries.
AC_ARG_WITH(pthreads, AS_HELP_STRING([--with-pthreads],[use pthreads library, or --without-pthreads to disable threading support.]),
AC_ARG_WITH(pthreads, AS_HELP_STRING([--with-pthreads],[use pthreads library, or --without-pthreads to disable threading support.]),
[ ],[ withval="yes" ])
ub_have_pthreads=no
if test x_$withval != x_no; then
@@ -607,6 +680,8 @@ if test x_$withval != x_no; then
CC="$PTHREAD_CC"
ub_have_pthreads=yes
AC_CHECK_TYPES([pthread_spinlock_t, pthread_rwlock_t],,,[#include <pthread.h>])
AC_CHECK_SIZEOF([unsigned long])
AC_CHECK_SIZEOF(pthread_t)
if echo "$CFLAGS" | $GREP -e "-pthread" >/dev/null; then
AC_MSG_CHECKING([if -pthread unused during linking])
@@ -619,7 +694,7 @@ int main(void) {return 0;}
# first compile
echo "$CC $CFLAGS -c conftest.c -o conftest.o" >&AS_MESSAGE_LOG_FD
$CC $CFLAGS -c conftest.c -o conftest.o 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
if test $? = 0; then
if test $? = 0; then
# then link
echo "$CC $CFLAGS -Werror $LDFLAGS $LIBS -o conftest contest.o" >&AS_MESSAGE_LOG_FD
$CC $CFLAGS -Werror $LDFLAGS $LIBS -o conftest conftest.o 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
@@ -640,7 +715,7 @@ int main(void) {return 0;}
])
fi
# check solaris thread library
# check solaris thread library
AC_ARG_WITH(solaris-threads, AS_HELP_STRING([--with-solaris-threads],[use solaris native thread library.]), [ ],[ withval="no" ])
ub_have_sol_threads=no
if test x_$withval != x_no; then
@@ -654,8 +729,8 @@ if test x_$withval != x_no; then
ACX_CHECK_COMPILER_FLAG(mt, [CFLAGS="$CFLAGS -mt"],
[CFLAGS="$CFLAGS -D_REENTRANT"])
ub_have_sol_threads=yes
] , [
AC_MSG_ERROR([no solaris threads found.])
] , [
AC_MSG_ERROR([no solaris threads found.])
])
fi
fi
@@ -730,7 +805,14 @@ if test x_$ub_test_python != x_no; then
ac_save_LIBS="$LIBS" dnl otherwise AC_PYTHON_DEVEL thrashes $LIBS
AC_PYTHON_DEVEL
if test ! -z "$PYTHON_VERSION"; then
if test `$PYTHON -c "print('$PYTHON_VERSION' >= '2.4.0')"` = "False"; then
badversion="no"
if test "$PYTHON_VERSION_MAJOR" -lt 2; then
badversion="yes"
fi
if test "$PYTHON_VERSION_MAJOR" -eq 2 -a "$PYTHON_VERSION_MINOR" -lt 4; then
badversion="yes"
fi
if test "$badversion" = "yes"; then
AC_MSG_ERROR([Python version >= 2.4.0 is required])
fi
@@ -765,9 +847,9 @@ if test x_$ub_test_python != x_no; then
ub_have_swig=no
AC_ARG_ENABLE(swig-version-check, AS_HELP_STRING([--disable-swig-version-check],[Disable swig version check to build python modules with older swig even though that is unreliable]))
if test "$enable_swig_version_check" = "yes"; then
AC_PROG_SWIG(2.0.1)
AX_PKG_SWIG(2.0.1)
else
AC_PROG_SWIG
AX_PKG_SWIG
fi
AC_MSG_CHECKING(SWIG)
if test ! -x "$SWIG"; then
@@ -909,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"
@@ -1081,7 +1163,7 @@ int load_gost_id(void)
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
}
int main(void) {
int main(void) {
EVP_MD_CTX* ctx;
const EVP_MD* md;
unsigned char digest[64]; /* its a 256-bit digest, so uses 32 bytes */
@@ -1112,7 +1194,8 @@ int main(void) {
return 6;
return 0;
}
]])] , [eval "ac_cv_c_gost_works=yes"], [eval "ac_cv_c_gost_works=no"])
]])] , [eval "ac_cv_c_gost_works=yes"], [eval "ac_cv_c_gost_works=no"],
[eval "ac_cv_c_gost_works=maybe"])
CFLAGS="$BAKCFLAGS"
else
eval "ac_cv_c_gost_works=maybe"
@@ -1145,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>
])
@@ -1487,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=""
@@ -1497,13 +1647,17 @@ if test x_$enable_static_exe = x_yes; then
if test "$on_mingw" = yes; then
staticexe="-all-static"
# for static compile, include gdi32 and zlib here.
if echo $LIBS | grep 'lgdi32' >/dev/null; then
if echo "$LIBS" | grep 'lgdi32' >/dev/null; then
:
else
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
LIBS="$LIBS -l:libssp.a"
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
fi
fi
fi
@@ -1520,12 +1674,16 @@ if test x_$enable_fully_static = x_yes; then
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
LIBS="$LIBS -l:libssp.a"
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
:
else
LIBS="$LIBS -l:libssp.a"
fi
fi
fi
# set lock checking if requested
AC_ARG_ENABLE(lock_checks, AS_HELP_STRING([--enable-lock-checks],[ enable to check lock and unlock calls, for debug purposes ]),
AC_ARG_ENABLE(lock_checks, AS_HELP_STRING([--enable-lock-checks],[ enable to check lock and unlock calls, for debug purposes ]),
, )
if test x_$enable_lock_checks = x_yes; then
AC_DEFINE(ENABLE_LOCK_CHECKS, 1, [Define if you want to use debug lock checking (slow).])
@@ -1540,7 +1698,11 @@ if test "$USE_WINSOCK" = 1; then
#include <windows.h>
])
AC_CHECK_TOOL(WINDRES, windres)
LIBS="$LIBS -liphlpapi -lcrypt32"
if echo "$LIBS" | grep crypt32 >/dev/null; then
LIBS="$LIBS -liphlpapi"
else
LIBS="$LIBS -liphlpapi -lcrypt32"
fi
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
AC_SUBST(WINAPPS)
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
@@ -1644,7 +1806,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
AC_MSG_RESULT(no))
AC_SEARCH_LIBS([setusercontext], [util])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@@ -1689,7 +1851,7 @@ int main(void) { return !(snprintf(NULL, 0, "test") == 4); }
AC_MSG_RESULT(no)
AC_DEFINE([SNPRINTF_RET_BROKEN], [], [define if (v)snprintf does not return length needed, (but length used)])
AC_LIBOBJ(snprintf)
])
], [AC_MSG_RESULT(maybe)])
fi
fi
AC_REPLACE_FUNCS(strlcat)
@@ -1790,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
@@ -1874,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.
@@ -1900,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
@@ -1919,7 +2089,7 @@ case "$enable_explicit_port_randomisation" in
esac
if echo "$host" | $GREP -i -e linux >/dev/null; then
AC_ARG_ENABLE(linux-ip-local-port-range, AC_HELP_STRING([--enable-linux-ip-local-port-range], [Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports.]))
AC_ARG_ENABLE(linux-ip-local-port-range, AS_HELP_STRING([--enable-linux-ip-local-port-range], [Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports.]))
case "$enable_linux_ip_local_port_range" in
yes)
AC_DEFINE([USE_LINUX_IP_LOCAL_PORT_RANGE], [1], [Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and does not affect unbound resolving daemon itself. This may severely limit the number of available outgoing ports and thus decrease randomness. Define this only when the target system restricts (e.g. some of SELinux enabled distributions) the use of non-ephemeral ports.])
@@ -1976,11 +2146,11 @@ AC_ARG_WITH(libunbound-only, AS_HELP_STRING([--with-libunbound-only],[do not bui
fi
])
if test $ALLTARGET = "alltargets"; then
if test $USE_NSS = "yes"; then
AC_MSG_ERROR([--with-nss can only be used in combination with --with-libunbound-only.])
if test $USE_NSS = "yes"; then
AC_MSG_ERROR([--with-nss can only be used in combination with --with-libunbound-only.])
fi
if test $USE_NETTLE = "yes"; then
AC_MSG_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
AC_MSG_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
fi
fi
@@ -1991,7 +2161,7 @@ ACX_STRIP_EXT_FLAGS
if test -n "$LATE_LDFLAGS"; then
LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
fi
# remove start spaces
# remove start spaces
LDFLAGS=`echo "$LDFLAGS"|sed -e 's/^ *//'`
LIBS=`echo "$LIBS"|sed -e 's/^ *//'`
@@ -2221,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);
@@ -2233,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 */
@@ -2243,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 -3
View File
@@ -1,10 +1,8 @@
FROM gcc:latest
WORKDIR /usr/src/unbound
RUN apt-get update
# install semantic parser & lexical analyzer
RUN apt-get install -y bison flex
# install packages used in tests
RUN apt-get install -y ldnsutils dnsutils xxd splint doxygen netcat
RUN apt-get update && apt-get install -y bison flex ldnsutils dnsutils xxd splint doxygen netcat-openbsd
# accept short rsa keys, which are used in tests
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
+3
View File
@@ -55,3 +55,6 @@ distribution but may be helpful.
contributed by Andreas Schulze.
* metrics.awk: awk script that can convert unbound-control stats to
Prometheus metrics format output.
* unbound.init_yocto: An init script to start and stop the server. Put it
in /etc/init.d/unbound to use it. It is for the Yocto Project, in
embedded systems, contributed by beni-sandu.
+3 -3
View File
@@ -105,9 +105,9 @@ index 2482a1f4..bd5ba243 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -177,6 +177,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
+ iter_env->aaaa_filter = cfg->aaaa_filter;
return 1;
}
@@ -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 */
+ }
+9
View File
@@ -22,4 +22,13 @@ pidfile=${unbound_pidfile:-"/usr/local/etc/unbound/unbound.pid"}
command_args=${unbound_flags:-"-c /usr/local/etc/unbound/unbound.conf"}
extra_commands="reload"
if test "$1" = "stop" ; then
run_rc_command "$1"
ret=$?
if test $ret -eq 0; then
rm -f "$pidfile"
fi
exit $ret
fi
run_rc_command "$1"
+1
View File
@@ -75,6 +75,7 @@ stop() {
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
umount ${rootdir}/dev/log >/dev/null 2>&1
fi;
+1
View File
@@ -58,6 +58,7 @@ stop() {
killproc -p $pidfile unbound
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound
do
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then
+140
View File
@@ -0,0 +1,140 @@
#!/bin/sh
#
# unbound This shell script takes care of starting and stopping
# unbound (DNS server).
#
# chkconfig: - 14 86
# description: unbound is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
### BEGIN INIT INFO
# Provides: $named unbound
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Should-Start: $syslog
# Should-Stop: $syslog
# Short-Description: unbound recursive Domain Name Server.
# Description: unbound is a Domain Name Server (DNS)
# that is used to resolve host names to IP addresses.
### END INIT INFO
# Source function library.
. /etc/init.d/functions
exec="/usr/sbin/unbound"
prog="unbound"
config="/etc/unbound/unbound.conf"
pidfile="/var/unbound/unbound.pid"
rootdir="/var/unbound"
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
start() {
[ -x $exec ] || exit 5
[ -f $config ] || exit 6
echo -n $"Starting $prog: "
# setup root jail
if [ -s /etc/localtime ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
cp -fp /etc/localtime ${rootdir}/etc/localtime
fi;
fi;
if [ -s /etc/resolv.conf ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
fi;
fi;
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
fi;
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
fi;
# if not running, start it up here
daemonize $exec
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc $prog"
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
umount ${rootdir}/dev/log >/dev/null 2>&1
fi;
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
umount ${rootdir}/dev/random >/dev/null 2>&1
fi;
return $retval
}
restart() {
stop
start
}
reload() {
kill -HUP `cat $pidfile`
}
force_reload() {
restart
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}
rh_status_q() {
rh_status -p $pidfile >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
-1
View File
@@ -44,7 +44,6 @@ Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Before=nss-lookup.target
Wants=network-online.target 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]
+389 -88
View File
@@ -46,9 +46,10 @@
#include "util/config_file.h"
#include "util/net_help.h"
#include "services/localzone.h"
#include "services/listen_dnsport.h"
#include "sldns/str2wire.h"
struct acl_list*
struct acl_list*
acl_list_create(void)
{
struct acl_list* acl = (struct acl_list*)calloc(1,
@@ -63,10 +64,10 @@ acl_list_create(void)
return acl;
}
void
void
acl_list_delete(struct acl_list* acl)
{
if(!acl)
if(!acl)
return;
regional_destroy(acl->region);
free(acl);
@@ -74,8 +75,8 @@ acl_list_delete(struct acl_list* acl)
/** insert new address into acl_list structure */
static struct acl_addr*
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
int complain_duplicates)
{
struct acl_addr* node = regional_alloc_zero(acl->region,
@@ -90,6 +91,33 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
return node;
}
/** parse str to acl_access enum */
static int
parse_acl_access(const char* str, enum acl_access* control)
{
if(strcmp(str, "allow") == 0)
*control = acl_allow;
else if(strcmp(str, "deny") == 0)
*control = acl_deny;
else if(strcmp(str, "refuse") == 0)
*control = acl_refuse;
else if(strcmp(str, "deny_non_local") == 0)
*control = acl_deny_non_local;
else if(strcmp(str, "refuse_non_local") == 0)
*control = acl_refuse_non_local;
else if(strcmp(str, "allow_snoop") == 0)
*control = acl_allow_snoop;
else if(strcmp(str, "allow_setrd") == 0)
*control = acl_allow_setrd;
else if (strcmp(str, "allow_cookie") == 0)
*control = acl_allow_cookie;
else {
log_err("access control type %s unknown", str);
return 0;
}
return 1;
}
/** apply acl_list string */
static int
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
@@ -99,29 +127,14 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
int net;
socklen_t addrlen;
enum acl_access control;
if(strcmp(s2, "allow") == 0)
control = acl_allow;
else if(strcmp(s2, "deny") == 0)
control = acl_deny;
else if(strcmp(s2, "refuse") == 0)
control = acl_refuse;
else if(strcmp(s2, "deny_non_local") == 0)
control = acl_deny_non_local;
else if(strcmp(s2, "refuse_non_local") == 0)
control = acl_refuse_non_local;
else if(strcmp(s2, "allow_snoop") == 0)
control = acl_allow_snoop;
else if(strcmp(s2, "allow_setrd") == 0)
control = acl_allow_setrd;
else {
log_err("access control type %s unknown", str);
if(!parse_acl_access(s2, &control)) {
return 0;
}
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse access control: %s %s", str, s2);
return 0;
}
if(!acl_list_insert(acl, &addr, addrlen, net, control,
if(!acl_list_insert(acl, &addr, addrlen, net, control,
complain_duplicates)) {
log_err("out of memory");
return 0;
@@ -131,19 +144,27 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
/** find or create node (NULL on parse or error) */
static struct acl_addr*
acl_find_or_create(struct acl_list* acl, const char* str)
acl_find_or_create_str2addr(struct acl_list* acl, const char* str,
int is_interface, int port)
{
struct acl_addr* node;
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse netblock: %s", str);
return NULL;
int net = (str_is_ip6(str)?128:32);
if(is_interface) {
if(!extstrtoaddr(str, &addr, &addrlen, port)) {
log_err("cannot parse interface: %s", str);
return NULL;
}
} else {
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse netblock: %s", str);
return NULL;
}
}
/* find or create node */
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
addrlen, net))) {
addrlen, net)) && !is_interface) {
/* create node, type 'allow' since otherwise tags are
* pointless, can override with specific access-control: cfg */
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
@@ -155,14 +176,65 @@ acl_find_or_create(struct acl_list* acl, const char* str)
return node;
}
/** find or create node (NULL on error) */
static struct acl_addr*
acl_find_or_create(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access control)
{
struct acl_addr* node;
int net = (addr_is_ip6(addr, addrlen)?128:32);
/* find or create node */
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, addr,
addrlen, net))) {
/* create node;
* can override with specific access-control: cfg */
if(!(node=(struct acl_addr*)acl_list_insert(acl, addr,
addrlen, net, control, 1))) {
log_err("out of memory");
return NULL;
}
}
return node;
}
/** apply acl_interface string */
static int
acl_interface_str_cfg(struct acl_list* acl_interface, const char* iface,
const char* s2, int port)
{
struct acl_addr* node;
enum acl_access control;
if(!parse_acl_access(s2, &control)) {
return 0;
}
if(!(node=acl_find_or_create_str2addr(acl_interface, iface, 1, port))) {
log_err("cannot update ACL on non-configured interface: %s %d",
iface, port);
return 0;
}
node->control = control;
return 1;
}
struct acl_addr*
acl_interface_insert(struct acl_list* acl_interface,
struct sockaddr_storage* addr, socklen_t addrlen,
enum acl_access control)
{
return acl_find_or_create(acl_interface, addr, addrlen, control);
}
/** apply acl_tag string */
static int
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
size_t bitmaplen)
size_t bitmaplen, int is_interface, int port)
{
struct acl_addr* node;
if(!(node=acl_find_or_create(acl, str)))
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
}
node->taglen = bitmaplen;
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
if(!node->taglist) {
@@ -175,11 +247,14 @@ acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
/** apply acl_view string */
static int
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
struct views* vs)
struct views* vs, int is_interface, int port)
{
struct acl_addr* node;
if(!(node=acl_find_or_create(acl, str)))
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
}
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
if(!node->view) {
log_err("no view with name: %s", str2);
@@ -192,13 +267,17 @@ acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
/** apply acl_tag_action string */
static int
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
const char* str, const char* tag, const char* action)
const char* str, const char* tag, const char* action,
int is_interface, int port)
{
struct acl_addr* node;
int tagid;
enum localzone_type t;
if(!(node=acl_find_or_create(acl, str)))
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
}
/* allocate array if not yet */
if(!node->tag_actions) {
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
@@ -281,13 +360,17 @@ check_data(const char* data, const struct config_strlist* head)
/** apply acl_tag_data string */
static int
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
const char* str, const char* tag, const char* data)
const char* str, const char* tag, const char* data,
int is_interface, int port)
{
struct acl_addr* node;
int tagid;
char* dupdata;
if(!(node=acl_find_or_create(acl, str)))
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
return 0;
}
/* allocate array if not yet */
if(!node->tag_datas) {
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
@@ -329,11 +412,11 @@ acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
}
/** read acl_list config */
static int
read_acl_list(struct acl_list* acl, struct config_file* cfg)
static int
read_acl_list(struct acl_list* acl, struct config_str2list* acls)
{
struct config_str2list* p;
for(p = cfg->acls; p; p = p->next) {
for(p = acls; p; p = p->next) {
log_assert(p->str && p->str2);
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
return 0;
@@ -341,15 +424,38 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
return 1;
}
/** read acl tags config */
static int
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
/** read acl view config */
static int
read_acl_view(struct acl_list* acl, struct config_str2list** acl_view,
struct views* v)
{
struct config_strbytelist* np, *p = cfg->acl_tags;
cfg->acl_tags = NULL;
struct config_str2list* np, *p = *acl_view;
*acl_view = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
if(!acl_list_view_cfg(acl, p->str, p->str2, v, 0, 0)) {
config_deldblstrlist(p);
return 0;
}
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tags config */
static int
read_acl_tags(struct acl_list* acl, struct config_strbytelist** acl_tags)
{
struct config_strbytelist* np, *p = *acl_tags;
*acl_tags = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len, 0, 0)) {
config_del_strbytelist(p);
return 0;
}
@@ -363,38 +469,18 @@ read_acl_tags(struct acl_list* acl, struct config_file* cfg)
return 1;
}
/** read acl view config */
static int
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
{
struct config_str2list* np, *p = cfg->acl_view;
cfg->acl_view = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
return 0;
}
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tag actions config */
static int
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
static int
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg,
struct config_str3list** acl_tag_actions)
{
struct config_str3list* p, *np;
p = cfg->acl_tag_actions;
cfg->acl_tag_actions = NULL;
p = *acl_tag_actions;
*acl_tag_actions = NULL;
while(p) {
log_assert(p->str && p->str2 && p->str3);
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
p->str3)) {
p->str3, 0, 0)) {
config_deltrplstrlist(p);
return 0;
}
@@ -410,15 +496,17 @@ read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
}
/** read acl tag datas config */
static int
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
static int
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg,
struct config_str3list** acl_tag_datas)
{
struct config_str3list* p, *np;
p = cfg->acl_tag_datas;
cfg->acl_tag_datas = NULL;
p = *acl_tag_datas;
*acl_tag_datas = NULL;
while(p) {
log_assert(p->str && p->str2 && p->str3);
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3,
0, 0)) {
config_deltrplstrlist(p);
return 0;
}
@@ -433,30 +521,27 @@ read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
return 1;
}
int
int
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v)
{
regional_free_all(acl->region);
addr_tree_init(&acl->tree);
if(!read_acl_list(acl, cfg))
if(!read_acl_list(acl, cfg->acls))
return 0;
if(!read_acl_view(acl, cfg, v))
if(!read_acl_view(acl, &cfg->acl_view, v))
return 0;
if(!read_acl_tags(acl, cfg))
if(!read_acl_tags(acl, &cfg->acl_tags))
return 0;
if(!read_acl_tag_actions(acl, cfg))
if(!read_acl_tag_actions(acl, cfg, &cfg->acl_tag_actions))
return 0;
if(!read_acl_tag_datas(acl, cfg))
if(!read_acl_tag_datas(acl, cfg, &cfg->acl_tag_datas))
return 0;
/* insert defaults, with '0' to ignore them if they are duplicates */
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
return 0;
/* the 'refuse' defaults for /0 are now done per interface instead */
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
return 0;
if(cfg->do_ip6) {
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
return 0;
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
@@ -466,7 +551,223 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
return 1;
}
enum acl_access
int
acl_interface_compare(const void* k1, const void* k2)
{
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
/* We don't care about comparing node->net. All addresses in the
* acl_interface tree have either 32 (ipv4) or 128 (ipv6). */
}
void
acl_interface_init(struct acl_list* acl_interface)
{
regional_free_all(acl_interface->region);
/* We want comparison in the tree to include only address and port.
* We don't care about comparing node->net. All addresses in the
* acl_interface->tree should have either 32 (ipv4) or 128 (ipv6).
* Initialise with the appropriate compare function but keep treating
* it as an addr_tree. */
addr_tree_addrport_init(&acl_interface->tree);
}
static int
read_acl_interface_action(struct acl_list* acl_interface,
struct config_str2list* acls, int port)
{
struct config_str2list* p;
for(p = acls; p; p = p->next) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif))
return 0;
for(i = 0; i<num_resif; i++) {
if(!acl_interface_str_cfg(acl_interface, resif[i], p->str2, port)){
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
}
return 1;
}
/** read acl view config for interface */
static int
read_acl_interface_view(struct acl_list* acl_interface,
struct config_str2list** acl_view,
struct views* v, int port)
{
struct config_str2list* np, *p = *acl_view;
*acl_view = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deldblstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_view_cfg(acl_interface, resif[i], p->str2,
v, 1, port)) {
config_del_strarray(resif, num_resif);
config_deldblstrlist(p);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tags config for interface */
static int
read_acl_interface_tags(struct acl_list* acl_interface,
struct config_strbytelist** acl_tags, int port)
{
struct config_strbytelist* np, *p = *acl_tags;
*acl_tags = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_del_strbytelist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tags_cfg(acl_interface, resif[i], p->str2,
p->str2len, 1, port)) {
config_del_strbytelist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tag actions config for interface*/
static int
read_acl_interface_tag_actions(struct acl_list* acl_interface,
struct config_file* cfg,
struct config_str3list** acl_tag_actions, int port)
{
struct config_str3list* p, *np;
p = *acl_tag_actions;
*acl_tag_actions = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2 && p->str3);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deltrplstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tag_action_cfg(acl_interface, cfg,
resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p->str3);
free(p);
p = np;
}
return 1;
}
/** read acl tag datas config for interface */
static int
read_acl_interface_tag_datas(struct acl_list* acl_interface,
struct config_file* cfg,
struct config_str3list** acl_tag_datas, int port)
{
struct config_str3list* p, *np;
p = *acl_tag_datas;
*acl_tag_datas = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2 && p->str3);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deltrplstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tag_data_cfg(acl_interface, cfg,
resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p->str3);
free(p);
p = np;
}
return 1;
}
int
acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
struct views* v)
{
if(!read_acl_interface_action(acl_interface, cfg->interface_actions,
cfg->port))
return 0;
if(!read_acl_interface_view(acl_interface, &cfg->interface_view, v,
cfg->port))
return 0;
if(!read_acl_interface_tags(acl_interface, &cfg->interface_tags,
cfg->port))
return 0;
if(!read_acl_interface_tag_actions(acl_interface, cfg,
&cfg->interface_tag_actions, cfg->port))
return 0;
if(!read_acl_interface_tag_datas(acl_interface, cfg,
&cfg->interface_tag_datas, cfg->port))
return 0;
addr_tree_init_parents(&acl_interface->tree);
return 1;
}
enum acl_access
acl_get_control(struct acl_addr* acl)
{
if(acl) return acl->control;
@@ -481,7 +782,7 @@ acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
addr, addrlen);
}
size_t
size_t
acl_list_get_mem(struct acl_list* acl)
{
if(!acl) return 0;
+42 -5
View File
@@ -36,7 +36,7 @@
/**
* \file
*
* This file keeps track of the list of clients that are allowed to
* This file keeps track of the list of clients that are allowed to
* access the server.
*/
@@ -64,8 +64,12 @@ enum acl_access {
acl_allow,
/** allow full access for all queries, recursion and cache snooping */
acl_allow_snoop,
/** allow full access for recursion queries and set RD flag regardless of request */
acl_allow_setrd
/** allow full access for recursion queries and set RD flag regardless
* of request */
acl_allow_setrd,
/** allow full access for recursion (+RD) queries if valid cookie
* present or stateful transport */
acl_allow_cookie
};
/**
@@ -74,7 +78,7 @@ enum acl_access {
struct acl_list {
/** regional for allocation */
struct regional* region;
/**
/**
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
@@ -108,7 +112,7 @@ struct acl_addr {
};
/**
* Create acl structure
* Create acl structure
* @return new structure or NULL on error.
*/
struct acl_list* acl_list_create(void);
@@ -119,6 +123,20 @@ struct acl_list* acl_list_create(void);
*/
void acl_list_delete(struct acl_list* acl);
/**
* Insert interface in the acl_list. This should happen when the listening
* interface is setup.
* @param acl_interface: acl_list to insert to.
* @param addr: interface IP.
* @param addrlen: length of the interface IP.
* @param control: acl_access.
* @return new structure or NULL on error.
*/
struct acl_addr*
acl_interface_insert(struct acl_list* acl_interface,
struct sockaddr_storage* addr, socklen_t addrlen,
enum acl_access control);
/**
* Process access control config.
* @param acl: where to store.
@@ -129,6 +147,25 @@ void acl_list_delete(struct acl_list* acl);
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v);
/** compare ACL interface "addr_tree" nodes (+port) */
int acl_interface_compare(const void* k1, const void* k2);
/**
* Initialise (also clean) the acl_interface struct.
* @param acl_interface: where to store.
*/
void acl_interface_init(struct acl_list* acl_interface);
/**
* Process interface control config.
* @param acl_interface: where to store.
* @param cfg: config options.
* @param v: views structure
* @return 0 on error.
*/
int acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
struct views* v);
/**
* Lookup access control status for acl structure.
* @param acl: structure for acl storage.
+41 -19
View File
@@ -166,8 +166,7 @@ dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
/** dump message entry */
static int
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
time_t now)
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
{
size_t i;
char* nm, *tp, *cl;
@@ -192,13 +191,15 @@ dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
}
/* meta line */
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u\n",
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets)) {
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"")) {
free(nm);
free(tp);
free(cl);
@@ -387,7 +388,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
struct rrset_ref ref;
uint8_t* p;
ak = alloc_special_obtain(&worker->alloc);
ak = alloc_special_obtain(worker->alloc);
if(!ak) {
log_warn("error out of memory");
return 0;
@@ -398,7 +399,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
if(!ak->rk.dname) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, &worker->alloc);
ub_packed_rrset_parsedelete(ak, worker->alloc);
return 0;
}
s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) +
@@ -408,7 +409,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ad = (struct packed_rrset_data*)malloc(s);
if(!ad) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, &worker->alloc);
ub_packed_rrset_parsedelete(ak, worker->alloc);
return 0;
}
p = (uint8_t*)ad;
@@ -431,7 +432,8 @@ move_into_cache(struct ub_packed_rrset_key* k,
ref.key = ak;
ref.id = ak->id;
(void)rrset_cache_update(worker->env.rrset_cache, &ref,
&worker->alloc, *worker->env.now);
worker->alloc, *worker->env.now);
return 1;
}
@@ -632,6 +634,9 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
long long ttl;
size_t i;
int go_on = 1;
int ede;
int consumed = 0;
char* ede_str = NULL;
regional_free_all(region);
@@ -646,11 +651,16 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
}
/* read remainder of line */
if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u", &flags, &qdcount, &ttl,
&security, &an, &ns, &ar) != 7) {
/* note the last space before any possible EDE text */
if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u %d %n", &flags, &qdcount, &ttl,
&security, &an, &ns, &ar, &ede, &consumed) != 8) {
log_warn("error cannot parse numbers: %s", s);
return 0;
}
/* there may be EDE text after the numbers */
if(consumed > 0 && (size_t)consumed < strlen(s))
ede_str = s + consumed;
memset(&rep, 0, sizeof(rep));
rep.flags = (uint16_t)flags;
rep.qdcount = (uint16_t)qdcount;
rep.ttl = (time_t)ttl;
@@ -665,6 +675,8 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
rep.ns_numrrsets = (size_t)ns;
rep.ar_numrrsets = (size_t)ar;
rep.rrset_count = (size_t)an+(size_t)ns+(size_t)ar;
rep.reason_bogus = (sldns_ede_code)ede;
rep.reason_bogus_str = ede_str?(char*)regional_strdup(region, ede_str):NULL;
rep.rrsets = (struct ub_packed_rrset_key**)regional_alloc_zero(
region, sizeof(struct ub_packed_rrset_key*)*rep.rrset_count);
@@ -827,6 +839,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
char b[260];
struct query_info qinfo;
struct iter_hints_stub* stub;
int nolock = 0;
regional_free_all(region);
qinfo.qname = nm;
qinfo.qname_len = nmlen;
@@ -838,13 +851,16 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
if(!ssl_printf(ssl, "The following name servers are used for lookup "
"of %s\n", b))
return 0;
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass);
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass, nolock);
if(dp) {
if(!ssl_printf(ssl, "forwarding request:\n"))
if(!ssl_printf(ssl, "forwarding request:\n")) {
lock_rw_unlock(&worker->env.fwds->lock);
return 0;
}
print_dp_main(ssl, dp, NULL);
print_dp_details(ssl, worker, dp);
lock_rw_unlock(&worker->env.fwds->lock);
return 1;
}
@@ -859,7 +875,8 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
/* go up? */
if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
(worker->env.cfg->do_ip4 && worker->back->num_ip4 != 0),
(worker->env.cfg->do_ip6 && worker->back->num_ip6 != 0))) {
(worker->env.cfg->do_ip6 && worker->back->num_ip6 != 0),
worker->env.cfg->do_nat64)) {
print_dp_main(ssl, dp, msg);
print_dp_details(ssl, worker, dp);
if(!ssl_printf(ssl, "cache delegation was "
@@ -879,21 +896,26 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
return 0;
continue;
}
}
}
stub = hints_lookup_stub(worker->env.hints, nm, qinfo.qclass,
dp);
dp, nolock);
if(stub) {
if(stub->noprime) {
if(!ssl_printf(ssl, "The noprime stub servers "
"are used:\n"))
"are used:\n")) {
lock_rw_unlock(&worker->env.hints->lock);
return 0;
}
} else {
if(!ssl_printf(ssl, "The stub is primed "
"with servers:\n"))
"with servers:\n")) {
lock_rw_unlock(&worker->env.hints->lock);
return 0;
}
}
print_dp_main(ssl, stub->dp, NULL);
print_dp_details(ssl, worker, stub->dp);
lock_rw_unlock(&worker->env.hints->lock);
} else {
print_dp_main(ssl, dp, msg);
print_dp_details(ssl, worker, dp);
+213 -12
View File
@@ -91,11 +91,19 @@
#include "util/net_help.h"
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include <signal.h>
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
/** How many quit requests happened. */
static int sig_record_quit = 0;
@@ -257,6 +265,7 @@ daemon_init(void)
free(daemon);
return NULL;
}
daemon->env->modstack = &daemon->mods;
/* init edns_known_options */
if(!edns_known_options_init(daemon->env)) {
free(daemon->env);
@@ -271,8 +280,17 @@ daemon_init(void)
free(daemon);
return NULL;
}
daemon->acl_interface = acl_list_create();
if(!daemon->acl_interface) {
acl_list_delete(daemon->acl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
daemon->tcl = tcl_list_create();
if(!daemon->tcl) {
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
edns_known_options_delete(daemon->env);
free(daemon->env);
@@ -284,6 +302,7 @@ daemon_init(void)
log_err("gettimeofday: %s", strerror(errno));
daemon->time_last_stat = daemon->time_boot;
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
@@ -293,6 +312,7 @@ daemon_init(void)
}
if(!(daemon->env->edns_strings = edns_strings_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl_interface);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
@@ -303,7 +323,28 @@ daemon_init(void)
return daemon;
}
int
static int setup_acl_for_ports(struct acl_list* list,
struct listen_port* port_list)
{
struct acl_addr* acl_node;
for(; port_list; port_list=port_list->next) {
if(!port_list->socket) {
/* This is mainly for testbound where port_list is
* empty. */
continue;
}
if(!(acl_node = acl_interface_insert(list,
(struct sockaddr_storage*)port_list->socket->addr,
port_list->socket->addrlen,
acl_refuse))) {
return 0;
}
port_list->socket->acl = acl_node;
}
return 1;
}
int
daemon_open_shared_ports(struct daemon* daemon)
{
log_assert(daemon);
@@ -320,6 +361,8 @@ daemon_open_shared_ports(struct daemon* daemon)
free(daemon->ports);
daemon->ports = NULL;
}
/* clean acl_interface */
acl_interface_init(daemon->acl_interface);
if(!resolve_interface_names(daemon->cfg->ifs,
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
return 0;
@@ -329,7 +372,8 @@ daemon_open_shared_ports(struct daemon* daemon)
daemon->reuseport = 1;
#endif
/* try to use reuseport */
p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
p0 = listening_ports_open(daemon->cfg, resif, num_resif,
&daemon->reuseport);
if(!p0) {
listening_ports_free(p0);
config_del_strarray(resif, num_resif);
@@ -350,6 +394,12 @@ daemon_open_shared_ports(struct daemon* daemon)
return 0;
}
daemon->ports[0] = p0;
if(!setup_acl_for_ports(daemon->acl_interface,
daemon->ports[0])) {
listening_ports_free(p0);
config_del_strarray(resif, num_resif);
return 0;
}
if(daemon->reuseport) {
/* continue to use reuseport */
for(i=1; i<daemon->num_ports; i++) {
@@ -365,6 +415,15 @@ daemon_open_shared_ports(struct daemon* daemon)
config_del_strarray(resif, num_resif);
return 0;
}
if(!setup_acl_for_ports(daemon->acl_interface,
daemon->ports[i])) {
for(i=0; i<daemon->num_ports; i++)
listening_ports_free(daemon->ports[i]);
free(daemon->ports);
daemon->ports = NULL;
config_del_strarray(resif, num_resif);
return 0;
}
}
}
config_del_strarray(resif, num_resif);
@@ -385,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
@@ -394,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);
}
@@ -433,6 +509,30 @@ static int daemon_get_shufport(struct daemon* daemon, int* shufport)
return avail;
}
/**
* Clear and delete per-worker alloc caches, and free memory maintained in
* superalloc.
* The rrset and message caches must be empty at the time of call.
* @param daemon: the daemon that maintains the alloc caches to be cleared.
*/
static void
daemon_clear_allocs(struct daemon* daemon)
{
int 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]);
}
free(daemon->worker_allocs);
daemon->worker_allocs = NULL;
alloc_clear_special(&daemon->superalloc);
}
/**
* Allocate empty worker structures. With backptr and thread-number,
* from 0..numthread initialised. Used as user arguments to new threads.
@@ -457,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) {
@@ -485,6 +591,21 @@ daemon_create_workers(struct daemon* daemon)
/* the above is not ports/numthr, due to rounding */
fatal_exit("could not create worker");
}
/* create per-worker alloc caches if not reusing existing ones. */
if(!daemon->worker_allocs) {
daemon->worker_allocs = (struct alloc_cache**)calloc(
(size_t)daemon->num, sizeof(struct alloc_cache*));
if(!daemon->worker_allocs)
fatal_exit("could not allocate worker allocs");
for(i=0; i<daemon->num; i++) {
struct alloc_cache* alloc = calloc(1,
sizeof(struct alloc_cache));
if (!alloc)
fatal_exit("could not allocate worker alloc");
alloc_init(alloc, &daemon->superalloc, i);
daemon->worker_allocs[i] = alloc;
}
}
free(shufport);
}
@@ -604,6 +725,9 @@ daemon_fork(struct daemon* daemon)
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
fatal_exit("Could not setup access control list");
if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
daemon->views))
fatal_exit("Could not setup interface control list");
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
if(daemon->cfg->dnscrypt) {
@@ -617,11 +741,25 @@ 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");
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
fatal_exit("Could not set up local zones");
if(!(daemon->env->fwds = forwards_create()) ||
!forwards_apply_cfg(daemon->env->fwds, daemon->cfg))
fatal_exit("Could not set forward zones");
if(!(daemon->env->hints = hints_create()) ||
!hints_apply_cfg(daemon->env->hints, daemon->cfg))
fatal_exit("Could not set root or stub hints");
/* process raw response-ip configuration data */
if(!(daemon->respip_set = respip_set_create()))
@@ -646,6 +784,10 @@ daemon_fork(struct daemon* daemon)
if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
fatal_exit("Could not set up EDNS strings");
#ifdef USE_CACHEDB
daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
daemon->env);
#endif
/* response-ip-xxx options don't work as expected without the respip
* module. To avoid run-time operational surprise we reject such
* configuration. */
@@ -713,6 +855,7 @@ daemon_fork(struct daemon* daemon)
/* Shutdown SHM */
shm_main_shutdown(daemon);
daemon->reuse_cache = daemon->workers[0]->reuse_cache;
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
}
@@ -727,9 +870,20 @@ daemon_cleanup(struct daemon* daemon)
log_thread_set(NULL);
/* clean up caches because
* a) RRset IDs will be recycled after a reload, causing collisions
* b) validation config can change, thus rrset, msg, keycache clear */
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
* b) validation config can change, thus rrset, msg, keycache clear
*
* If we are trying to keep the cache as long as possible, we should
* defer the cleanup until we know whether the new configuration allows
* the reuse. (If we're exiting, cleanup should be done here). */
if(!daemon->reuse_cache || daemon->need_to_exit) {
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
}
daemon->old_num = daemon->num; /* save the current num */
forwards_delete(daemon->env->fwds);
daemon->env->fwds = NULL;
hints_delete(daemon->env->hints);
daemon->env->hints = NULL;
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
respip_set_delete(daemon->respip_set);
@@ -738,14 +892,19 @@ 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]);
free(daemon->workers);
daemon->workers = NULL;
/* Unless we're trying to keep the cache, worker alloc_caches should be
* cleared and freed here. We do this after deleting workers to
* guarantee that the alloc caches are valid throughout the lifetime
* of workers. */
if(!daemon->reuse_cache || daemon->need_to_exit)
daemon_clear_allocs(daemon);
daemon->num = 0;
alloc_clear_special(&daemon->superalloc);
#ifdef USE_DNSTAP
dt_delete(daemon->dtenv);
daemon->dtenv = NULL;
@@ -753,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;
}
@@ -763,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]);
@@ -780,7 +945,9 @@ daemon_delete(struct daemon* daemon)
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
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);
@@ -841,8 +1008,42 @@ daemon_delete(struct daemon* daemon)
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
{
int new_num = cfg->num_threads?cfg->num_threads:1;
daemon->cfg = cfg;
config_apply(cfg);
/* If this is a reload and we deferred the decision on whether to
* reuse the alloc, RRset, and message caches, then check to see if
* it's safe to keep the caches:
* - changing the number of threads is obviously incompatible with
* keeping the per-thread alloc caches. It also means we have to
* clear RRset and message caches. (note that 'new_num' may be
* adjusted in daemon_create_workers, but for our purpose we can
* simply compare it with 'old_num'; if they are equal here,
* 'new_num' won't be adjusted to a different value than 'old_num').
* - changing RRset cache size effectively clears any remaining cache
* entries. We could keep their keys in alloc caches, but it would
* be more consistent with the sense of the change to clear allocs
* and free memory. To do so we also have to clear message cache.
* - only changing message cache size does not necessarily affect
* RRset or alloc cache. But almost all new subsequent queries will
* require recursive resolution anyway, so it doesn't help much to
* just keep RRset and alloc caches. For simplicity we clear/free
* the other two, too. */
if(daemon->worker_allocs &&
(new_num != daemon->old_num ||
!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs) ||
!slabhash_is_size(&daemon->env->rrset_cache->table,
cfg->rrset_cache_size, cfg->rrset_cache_slabs)))
{
log_warn("cannot reuse caches due to critical config change");
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
daemon_clear_allocs(daemon);
}
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {
slabhash_delete(daemon->env->msg_cache);
+25
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
@@ -99,8 +101,12 @@ struct daemon {
void* listen_sslctx, *connect_sslctx;
/** num threads allocated */
int num;
/** num threads allocated in the previous config or 0 at first */
int old_num;
/** the worker entries */
struct worker** workers;
/** per-worker allocation cache */
struct alloc_cache **worker_allocs;
/** do we need to exit unbound (or is it only a reload?) */
int need_to_exit;
/** master random table ; used for port div between threads on reload*/
@@ -111,8 +117,12 @@ 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 */
struct acl_list* acl_interface;
/** TCP connection limit, limit connections from client IPs */
struct tcl_list* tcl;
/** local authority zones */
@@ -138,6 +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;
};
/**
@@ -154,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.
+695 -274
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -46,7 +46,7 @@
#ifndef DAEMON_REMOTE_H
#define DAEMON_REMOTE_H
#ifdef HAVE_OPENSSL_SSL_H
#include "openssl/ssl.h"
#include <openssl/ssl.h>
#endif
struct config_file;
struct listen_list;
+87 -14
View File
@@ -4,22 +4,22 @@
* Copyright (c) 2007, 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
@@ -70,6 +70,9 @@
#include <openssl/ssl.h>
#endif
/** How long to wait for threads to transmit statistics, in msec. */
#define STATS_THREAD_WAIT 60000
/** add timers and the values do not overflow or become negative */
static void
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
@@ -113,8 +116,8 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
log_info("server stats for thread %d: %u queries, "
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
"ip ratelimiting",
threadnum, (unsigned)stats->num_queries,
(unsigned)(stats->num_queries -
threadnum, (unsigned)stats->num_queries,
(unsigned)(stats->num_queries -
stats->num_queries_missed_cache),
(unsigned)stats->num_queries_missed_cache,
(unsigned)stats->num_queries_prefetch,
@@ -276,7 +279,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
timehist_export(worker->env.mesh->histogram, s->svr.hist,
timehist_export(worker->env.mesh->histogram, s->svr.hist,
NUM_BUCKETS_HIST);
/* values from outside network */
s->svr.unwanted_replies = (long long)worker->back->unwanted_replies;
@@ -290,8 +293,10 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.queries_ratelimited = (long long)get_queries_ratelimit(worker, reset);
/* get cache sizes */
s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache);
s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table);
get_slabhash_stats(worker->env.msg_cache,
&s->svr.msg_cache_count, &s->svr.msg_cache_max_collisions);
get_slabhash_stats(&worker->env.rrset_cache->table,
&s->svr.rrset_cache_count, &s->svr.rrset_cache_max_collisions);
s->svr.infra_cache_count = (long long)count_slabhash_entries(worker->env.infra_cache->hosts);
if(worker->env.key_cache)
s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab);
@@ -341,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);
@@ -351,6 +362,11 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.num_query_subnet = 0;
s->svr.num_query_subnet_cache = 0;
#endif
#ifdef USE_CACHEDB
s->svr.num_query_cachedb = (long long)worker->env.mesh->ans_cachedb;
#else
s->svr.num_query_cachedb = 0;
#endif
/* get tcp accept usage */
s->svr.tcp_accept_usage = 0;
@@ -380,6 +396,35 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
worker_send_cmd(who, worker_cmd_stats);
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"
#endif
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
" pthread 0x%lx"
# endif
#endif
,
who->thread_num
#ifdef HAVE_GETTID
, (unsigned)who->thread_tid
#endif
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
, pthid
# endif
#endif
);
}
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
fatal_exit("failed to read stats over cmd channel");
if(len != (uint32_t)sizeof(*s))
@@ -394,7 +439,7 @@ void server_stats_reply(struct worker* worker, int reset)
struct ub_stats_info s;
server_stats_compile(worker, &s, reset);
verbose(VERB_ALGO, "write stats replymsg");
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
(uint8_t*)&s, sizeof(s), 0))
fatal_exit("could not write stat values over cmd channel");
}
@@ -403,8 +448,14 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
{
total->svr.num_queries += a->svr.num_queries;
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
total->svr.num_queries_cookie_valid += a->svr.num_queries_cookie_valid;
total->svr.num_queries_cookie_client += a->svr.num_queries_cookie_client;
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
total->svr.num_queries_timed_out += a->svr.num_queries_timed_out;
if (total->svr.max_query_time_us < a->svr.max_query_time_us)
total->svr.max_query_time_us = a->svr.max_query_time_us;
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
total->svr.ans_expired += a->svr.ans_expired;
#ifdef USE_DNSCRYPT
@@ -429,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;
@@ -446,6 +498,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.unwanted_replies += a->svr.unwanted_replies;
total->svr.unwanted_queries += a->svr.unwanted_queries;
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
#ifdef USE_CACHEDB
total->svr.num_query_cachedb += a->svr.num_query_cachedb;
#endif
for(i=0; i<UB_STATS_QTYPE_NUM; i++)
total->svr.qtype[i] += a->svr.qtype[i];
for(i=0; i<UB_STATS_QCLASS_NUM; i++)
@@ -485,18 +540,23 @@ 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
if(SSL_session_reused(c->ssl))
if(SSL_session_reused(c->ssl))
stats->qtls_resume++;
#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->addr, repinfo->addrlen))
if(repinfo && addr_is_ip6(&repinfo->remote_addr, repinfo->remote_addrlen))
stats->qipv6++;
if( (flags&BIT_QR) )
stats->qbit_QR++;
@@ -530,3 +590,16 @@ void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf)
stats->ans_rcode_nodata ++;
}
}
void server_stats_downstream_cookie(struct ub_server_stats* stats,
struct edns_data* edns)
{
if(!(edns->edns_present && edns->cookie_present)) return;
if(edns->cookie_valid) {
stats->num_queries_cookie_valid++;
} else if(edns->cookie_client) {
stats->num_queries_cookie_client++;
} else {
stats->num_queries_cookie_invalid++;
}
}
+7
View File
@@ -126,4 +126,11 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
*/
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
/**
* Add DNS Cookie stats for this query
* @param stats: the stats
* @param edns: edns record
*/
void server_stats_downstream_cookie(struct ub_server_stats* stats,
struct edns_data* edns);
#endif /* DAEMON_STATS_H */
+23 -20
View File
@@ -366,9 +366,8 @@ readpid (const char* file)
/** write pid to file.
* @param pidfile: file name of pid file.
* @param pid: pid to write to file.
* @return false on failure
*/
static int
static void
writepid (const char* pidfile, pid_t pid)
{
int fd;
@@ -383,7 +382,7 @@ writepid (const char* pidfile, pid_t pid)
, 0644)) == -1) {
log_err("cannot open pidfile %s: %s",
pidfile, strerror(errno));
return 0;
return;
}
while(count < strlen(pidbuf)) {
ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
@@ -393,17 +392,16 @@ writepid (const char* pidfile, pid_t pid)
log_err("cannot write to pidfile %s: %s",
pidfile, strerror(errno));
close(fd);
return 0;
return;
} else if(r == 0) {
log_err("cannot write any bytes to pidfile %s: "
"write returns 0 bytes written", pidfile);
close(fd);
return 0;
return;
}
count += r;
}
close(fd);
return 1;
}
/**
@@ -475,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);
@@ -545,7 +547,15 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
cfg, 1);
if(!daemon->pidfile)
fatal_exit("pidfile alloc: out of memory");
checkoldpid(daemon->pidfile, pidinchroot);
/* Check old pid if there is no username configured.
* With a username, the assumption is that the privilege
* drop makes a pidfile not removed when the server stopped
* last time. The server does not chown the pidfile for it,
* because that creates privilege escape problems, with the
* pidfile writable by unprivileged users, but used by
* privileged users. */
if(!(cfg->username && cfg->username[0]))
checkoldpid(daemon->pidfile, pidinchroot);
}
#endif
@@ -557,18 +567,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
/* write new pidfile (while still root, so can be outside chroot) */
#ifdef HAVE_KILL
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
if(writepid(daemon->pidfile, getpid())) {
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
pidinchroot) {
# ifdef HAVE_CHOWN
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
(unsigned)cfg_uid, (unsigned)cfg_gid,
daemon->pidfile, strerror(errno));
}
# endif /* HAVE_CHOWN */
}
}
writepid(daemon->pidfile, getpid());
}
#else
(void)daemon;
@@ -746,7 +745,11 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
if(daemon->pidfile) {
int fd;
/* truncate pidfile */
fd = open(daemon->pidfile, O_WRONLY | O_TRUNC, 0644);
fd = open(daemon->pidfile, O_WRONLY | O_TRUNC
#ifdef O_NOFOLLOW
| O_NOFOLLOW
#endif
, 0644);
if(fd != -1)
close(fd);
/* delete pidfile */
+441 -235
View File
File diff suppressed because it is too large Load Diff
+7 -1
View File
@@ -86,6 +86,10 @@ struct worker {
struct daemon* daemon;
/** thread id */
ub_thread_type thr_id;
#ifdef HAVE_GETTID
/** thread tid, the LWP id. */
pid_t thread_tid;
#endif
/** pipe, for commands for this worker */
struct tube* cmd;
/** the event base this worker works with */
@@ -114,7 +118,7 @@ struct worker {
/** do we need to restart or quit (on signal) */
int need_to_exit;
/** allocation cache for this thread */
struct alloc_cache alloc;
struct alloc_cache *alloc;
/** per thread statistics */
struct ub_server_stats stats;
/** thread scratch regional */
@@ -127,6 +131,8 @@ struct worker {
/** dnstap environment, changed for this thread */
struct dt_env dtenv;
#endif
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
};
/**
+63 -46
View File
@@ -59,7 +59,7 @@
******************************************************************************/
/**
* This is the default DNS64 prefix that is used whent he dns64 module is listed
* This is the default DNS64 prefix that is used when the dns64 module is listed
* in module-config but when the dns64-prefix variable is not present.
*/
static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
@@ -573,28 +573,29 @@ static enum module_ext_state
handle_event_pass(struct module_qstate* qstate, int id)
{
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
if (iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
&& qstate->qinfo.qname_len == 74
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
/* Handle PTR queries for IPv6 addresses. */
return handle_ipv6_ptr(qstate, id);
int synth_all_cfg = qstate->env->cfg->dns64_synthall;
int synth_qname = 0;
if (qstate->env->cfg->dns64_synthall &&
iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
return generate_type_A_query(qstate, id);
if(iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
&& qstate->qinfo.qname_len == 74
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa")) {
/* Handle PTR queries for IPv6 addresses. */
return handle_ipv6_ptr(qstate, id);
}
if(dns64_always_synth_for_qname(qstate, id) &&
iq && iq->state == DNS64_NEW_QUERY
&& !(qstate->query_flags & BIT_CD)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
if(iq && iq->state == DNS64_NEW_QUERY &&
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
(synth_all_cfg ||
(synth_qname=(dns64_always_synth_for_qname(qstate, id)
&& !(qstate->query_flags & BIT_CD))))) {
if(synth_qname)
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
return generate_type_A_query(qstate, id);
}
/* We are finished when our sub-query is finished. */
if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
if(iq && iq->state == DNS64_SUBQUERY_FINISHED)
return module_finished;
/* Otherwise, pass request to next module. */
@@ -627,32 +628,37 @@ handle_event_moddone(struct module_qstate* qstate, int id)
* synthesize in (sec 5.1.2 of RFC6147).
* - A successful AAAA query with an answer.
*/
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
&& !(qstate->query_flags & BIT_CD)
&& !(qstate->return_msg &&
qstate->return_msg->rep &&
reply_find_answer_rrset(&qstate->qinfo,
qstate->return_msg->rep)))
/* not internal, type AAAA, not CD, and no answer RRset,
* So, this is a AAAA noerror/nodata answer */
return generate_type_A_query(qstate, id);
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
&& !(qstate->query_flags & BIT_CD)
&& dns64_always_synth_for_qname(qstate, id)) {
/* if it is not internal, AAAA, not CD and listed domain,
* generate from A record and ignore AAAA */
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
/* When an AAAA query completes check if we want to perform DNS64
* synthesis. We skip queries with DNSSEC enabled (!CD) and
* ones generated by us to retrive the A/PTR record to use for
* synth. */
int could_synth =
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
(!iq || iq->state != DNS64_INTERNAL_QUERY) &&
!(qstate->query_flags & BIT_CD);
int has_data = /* whether query returned non-empty rrset */
qstate->return_msg &&
qstate->return_msg->rep &&
reply_find_answer_rrset(&qstate->qinfo, qstate->return_msg->rep);
int synth_qname = 0;
if(could_synth &&
(!has_data ||
(synth_qname=dns64_always_synth_for_qname(qstate, id)))) {
if(synth_qname)
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
return generate_type_A_query(qstate, id);
}
/* Store the response in cache. */
if ( (!iq || !iq->started_no_cache_store) &&
qstate->return_msg && qstate->return_msg->rep &&
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, 0, 0, NULL, qstate->query_flags, qstate->qstarttime))
if( (!iq || !iq->started_no_cache_store) &&
qstate->return_msg &&
qstate->return_msg->rep &&
!dns_cache_store(
qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, qstate->prefetch_leeway, 0, NULL,
qstate->query_flags, qstate->qstarttime))
log_err("out of memory");
/* do nothing */
@@ -695,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);
@@ -840,8 +847,9 @@ 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);
rep->rrset_count, rep->security, LDNS_EDE_NONE);
if(!cp)
return;
@@ -969,10 +977,19 @@ dns64_inform_super(struct module_qstate* qstate, int id,
}
super_dq->state = DNS64_SUBQUERY_FINISHED;
/* If there is no successful answer, we're done. */
if (qstate->return_rcode != LDNS_RCODE_NOERROR
|| !qstate->return_msg
|| !qstate->return_msg->rep) {
/* If there is no successful answer, we're done.
* Guarantee that we have at least a NOERROR reply further on. */
if(qstate->return_rcode != LDNS_RCODE_NOERROR
|| !qstate->return_msg
|| !qstate->return_msg->rep) {
return;
}
/* When no A record is found for synthesis fall back to AAAA again. */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A &&
!reply_find_answer_rrset(&qstate->qinfo,
qstate->return_msg->rep)) {
super_dq->state = DNS64_INTERNAL_QUERY;
return;
}
@@ -991,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");
}
@@ -1029,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
};
/**
+73 -11
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);
@@ -305,6 +338,7 @@ dt_msg_fill_net(struct dt_msg *dm,
struct sockaddr_storage *qs,
struct sockaddr_storage *rs,
enum comm_point_type cptype,
void *cpssl,
ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
uint32_t *qport, protobuf_c_boolean *has_qport,
ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
@@ -371,13 +405,26 @@ dt_msg_fill_net(struct dt_msg *dm,
*has_rport = 1;
}
log_assert(cptype == comm_udp || cptype == comm_tcp);
if (cptype == comm_udp) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
dm->m.has_socket_protocol = 1;
} else if (cptype == comm_tcp) {
if (cpssl == NULL) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
dm->m.has_socket_protocol = 1;
} else {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT;
dm->m.has_socket_protocol = 1;
}
} else if (cptype == comm_http) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH;
dm->m.has_socket_protocol = 1;
} else {
/* other socket protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
dm->m.has_socket_protocol = 1;
}
@@ -388,12 +435,19 @@ dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
sldns_buffer *qmsg)
void *cpssl,
sldns_buffer *qmsg,
struct timeval* tstamp)
{
struct dt_msg dm;
struct timeval qtime;
gettimeofday(&qtime, NULL);
if(dt_sample_rate_limited(env))
return;
if(tstamp)
memcpy(&qtime, tstamp, sizeof(qtime));
else gettimeofday(&qtime, NULL);
/* type */
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_QUERY);
@@ -407,8 +461,7 @@ dt_msg_send_client_query(struct dt_env *env,
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, rsock, cptype,
dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
@@ -424,11 +477,15 @@ dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
sldns_buffer *rmsg)
{
struct dt_msg dm;
struct timeval rtime;
if(dt_sample_rate_limited(env))
return;
gettimeofday(&rtime, NULL);
/* type */
@@ -443,8 +500,7 @@ dt_msg_send_client_response(struct dt_env *env,
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, rsock, cptype,
dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
@@ -459,6 +515,7 @@ dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
sldns_buffer *qmsg)
{
@@ -466,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);
@@ -494,8 +554,7 @@ dt_msg_send_outside_query(struct dt_env *env,
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, qsock, cptype,
dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
@@ -510,6 +569,7 @@ dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
@@ -519,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);
@@ -553,8 +616,7 @@ dt_msg_send_outside_response(struct dt_env *env,
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, qsock, cptype,
dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
+15 -1
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;
};
/**
@@ -126,13 +134,16 @@ dt_delete(struct dt_env *env);
* @param rsock: local (service) address/port.
* @param cptype: comm_udp or comm_tcp.
* @param qmsg: query message.
* @param tstamp: timestamp or NULL if none provided.
*/
void
dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
struct sldns_buffer *qmsg);
void *cpssl,
struct sldns_buffer *qmsg,
struct timeval* tstamp);
/**
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
@@ -147,6 +158,7 @@ dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
struct sldns_buffer *rmsg);
/**
@@ -166,6 +178,7 @@ dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
struct sldns_buffer *qmsg);
@@ -190,6 +203,7 @@ dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
+66 -38
View File
@@ -5,45 +5,73 @@
# Check for required dnstap libraries and add dnstap configure args.
AC_DEFUN([dt_DNSTAP],
[
AC_ARG_ENABLE([dnstap],
AS_HELP_STRING([--enable-dnstap],
[Enable dnstap support (requires protobuf-c)]),
[opt_dnstap=$enableval], [opt_dnstap=no])
AC_ARG_ENABLE([dnstap],
AS_HELP_STRING([--enable-dnstap],
[Enable dnstap support (requires protobuf-c)]),
[opt_dnstap=$enableval],
[opt_dnstap=no])
AC_ARG_WITH([dnstap-socket-path],
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
[set default dnstap socket path]),
[opt_dnstap_socket_path=$withval], [opt_dnstap_socket_path="$1"])
AC_ARG_WITH([dnstap-socket-path],
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
[set default dnstap socket path]),
[opt_dnstap_socket_path=$withval],
[opt_dnstap_socket_path="$1"])
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi
AC_ARG_WITH([protobuf-c],
AS_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]),
[
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I$withval/include/google"
else
CFLAGS="$CFLAGS -I$withval/include"
fi
LDFLAGS="$LDFLAGS -L$withval/lib"
],
[
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
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
fi
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], [],
AC_MSG_ERROR([The protobuf-c library was not found. Please install the development libraries for protobuf-c!]))
$2
else
$3
fi
AC_ARG_WITH([protobuf-c], AS_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I$withval/include/google"
else
CFLAGS="$CFLAGS -I$withval/include"
fi
LDFLAGS="$LDFLAGS -L$withval/lib"
], [
# 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
])
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
$2
else
$3
fi
])
+75 -7
View File
@@ -13,8 +13,8 @@
// with this file. If not, see:
//
// <http://creativecommons.org/publicdomain/zero/1.0/>.
syntax = "proto2";
syntax = "proto2";
package dnstap;
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
@@ -56,11 +56,60 @@ enum SocketFamily {
INET6 = 2; // IPv6 (RFC 2460)
}
// SocketProtocol: the transport protocol of a socket. This specifies how to
// interpret "transport port" fields.
// SocketProtocol: the protocol used to transport a DNS message.
enum SocketProtocol {
UDP = 1; // User Datagram Protocol (RFC 768)
TCP = 2; // Transmission Control Protocol (RFC 793)
UDP = 1; // DNS over UDP transport (RFC 1035 section 4.2.1)
TCP = 2; // DNS over TCP transport (RFC 1035 section 4.2.2)
DOT = 3; // DNS over TLS (RFC 7858)
DOH = 4; // DNS over HTTPS (RFC 8484)
DNSCryptUDP = 5; // DNSCrypt over UDP (https://dnscrypt.info/protocol)
DNSCryptTCP = 6; // DNSCrypt over TCP (https://dnscrypt.info/protocol)
DOQ = 7; // DNS over QUIC (RFC 9250)
}
// Policy: information about any name server operator policy
// applied to the processing of a DNS message.
message Policy {
// Match: what aspect of the message or message exchange
// triggered the application of the Policy.
enum Match {
QNAME = 1; // Name in question section of query
CLIENT_IP = 2; // Client IP address
RESPONSE_IP = 3; // Address in A/AAAA RRSet
NS_NAME = 4; // Authoritative name server, by name
NS_IP = 5; // Authoritative name server, by IP address
}
// The Action taken to implement the Policy.
enum Action {
NXDOMAIN = 1; // Respond with NXDOMAIN
NODATA = 2; // Respond with empty answer section
PASS = 3; // Do not alter the response (passthrough)
DROP = 4; // Do not respond.
TRUNCATE = 5; // Truncate UDP response, forcing TCP retry
LOCAL_DATA = 6; // Respond with local data from policy
}
// type: the type of policy applied, e.g. "RPZ" for a
// policy from a Response Policy Zone.
optional string type = 1;
// rule: the rule matched by the message.
//
// In a RPZ context, this is the owner name of the rule in
// the Reponse Policy Zone in wire format.
optional bytes rule = 2;
// action: the policy action taken in response to the
// rule match.
optional Action action = 3;
// match: the feature of the message exchange which matched the rule.
optional Match match = 4;
// The matched value. Format depends on the matched feature .
optional bytes value = 5;
}
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
@@ -158,6 +207,24 @@ message Message {
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
// stub resolver, from the perspective of the stub resolver.
STUB_RESPONSE = 10;
// TOOL_QUERY is a DNS query message sent from a DNS software tool to a
// DNS server, from the perspective of the tool.
TOOL_QUERY = 11;
// TOOL_RESPONSE is a DNS response message received by a DNS software
// tool from a DNS server, from the perspective of the tool.
TOOL_RESPONSE = 12;
// UPDATE_QUERY is a Dynamic DNS Update request (RFC 2136) received
// by an authoritative name server, from the perspective of the
// authoritative name server.
UPDATE_QUERY = 13;
// UPDATE_RESPONSE is a Dynamic DNS Update response (RFC 2136) sent
// from an authoritative name server, from the perspective of the
// authoritative name server.
UPDATE_RESPONSE = 14;
}
// One of the Type values described above.
@@ -215,6 +282,9 @@ message Message {
// The responder's original wire-format DNS response message, verbatim.
optional bytes response_message = 14;
// Operator policy applied to the processing of this message, if any.
optional Policy policy = 15;
}
// All fields except for 'type' in the Message schema are optional.
@@ -236,7 +306,6 @@ message Message {
// RESOLVER_QUERY:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_message
// query_time_sec, query_time_nsec
// query_zone
@@ -244,7 +313,6 @@ message Message {
// RESOLVER_RESPONSE:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_time_sec, query_time_nsec
// query_zone
// response_address, response_port
+51 -14
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 */
@@ -788,7 +794,7 @@ static int dtio_write_ssl(struct dt_io_thread* dtio, uint8_t* buf,
}
return -1;
}
log_crypto_err("dnstap io, could not SSL_write");
log_crypto_err_io("dnstap io, could not SSL_write", want);
return -1;
}
return r;
@@ -954,7 +960,7 @@ static int dtio_write_more(struct dt_io_thread* dtio)
* -1: continue, >0: number of bytes read into buffer */
static ssize_t receive_bytes(struct dt_io_thread* dtio, void* buf, size_t len) {
ssize_t r;
r = recv(dtio->fd, (void*)buf, len, 0);
r = recv(dtio->fd, (void*)buf, len, MSG_DONTWAIT);
if(r == -1) {
char* to = dtio->socket_path;
if(!to) to = dtio->ip_str;
@@ -1029,7 +1035,7 @@ static int ssl_read_bytes(struct dt_io_thread* dtio, void* buf, size_t len)
"other side");
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
@@ -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);
@@ -1431,8 +1452,8 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio,
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
log_crypto_err_code("dnstap io, ssl handshake failed",
err);
log_crypto_err_io_code("dnstap io, ssl handshake failed",
want, err);
verbose(VERB_OPS, "dnstap io, ssl handshake failed "
"from %s", dtio->ip_str);
}
@@ -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 */
}
}
@@ -1960,7 +1997,7 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio)
memset(&addr, 0, sizeof(addr));
addrlen = (socklen_t)sizeof(addr);
if(!extstrtoaddr(dtio->ip_str, &addr, &addrlen)) {
if(!extstrtoaddr(dtio->ip_str, &addr, &addrlen, UNBOUND_DNS_PORT)) {
log_err("could not parse IP '%s'", dtio->ip_str);
return 0;
}
+303 -57
View File
@@ -61,6 +61,7 @@
#include "services/listen_dnsport.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "sldns/pkthdr.h"
#ifdef USE_DNSTAP
#include <protobuf-c/protobuf-c.h>
#include "dnstap/dnstap.pb-c.h"
@@ -74,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);
}
@@ -101,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 */
@@ -127,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 */
@@ -155,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)
{
@@ -172,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;
}
@@ -183,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);
@@ -272,7 +368,7 @@ static int make_tcp_accept(char* ip)
memset(&addr, 0, sizeof(addr));
len = (socklen_t)sizeof(addr);
if(!extstrtoaddr(ip, &addr, &len)) {
if(!extstrtoaddr(ip, &addr, &len, UNBOUND_DNS_PORT)) {
log_err("could not parse IP '%s'", ip);
return -1;
}
@@ -448,6 +544,7 @@ static char* q_of_msg(ProtobufCBinaryData message)
char buf[300];
/* header, name, type, class minimum to get the query tuple */
if(message.len < 12 + 1 + 4 + 4) return NULL;
if(LDNS_QDCOUNT(message.data) < 1) return NULL;
if(sldns_wire2str_rrquestion_buf(message.data+12, message.len-12,
buf, sizeof(buf)) != 0) {
/* remove trailing newline, tabs to spaces */
@@ -502,7 +599,7 @@ static char* tv_to_str(protobuf_c_boolean has_time_sec, uint64_t time_sec,
time_t time_t_sec;
memset(&tv, 0, sizeof(tv));
if(has_time_sec) tv.tv_sec = time_sec;
if(has_time_nsec) tv.tv_usec = time_nsec;
if(has_time_nsec) tv.tv_usec = time_nsec/1000;
buf[0]=0;
time_t_sec = tv.tv_sec;
@@ -617,7 +714,7 @@ static void log_data_frame(uint8_t* pkt, size_t len)
static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
size_t len)
{
ssize_t ret = recv(fd, buf, len, 0);
ssize_t ret = recv(fd, buf, len, MSG_DONTWAIT);
if(ret == 0) {
/* closed */
if(verbosity) log_info("dnstap client stream closed from %s",
@@ -706,7 +803,7 @@ static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len)
(data->id?data->id:""));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
if(verbosity) log_info("dnstap client stream closed from %s",
(data->id?data->id:""));
return 0;
@@ -726,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);
@@ -757,15 +839,19 @@ 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) {
if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
log_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(acceptframe);
return 0;
}
#endif
} else {
if(send(data->fd, acceptframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
@@ -789,7 +875,7 @@ static int reply_with_accept(struct tap_data* data)
/** reply with FINISH control frame to bidirectional client,
* returns 0 on error */
static int reply_with_finish(int fd)
static int reply_with_finish(struct tap_data* data)
{
#ifdef USE_DNSTAP
size_t len = 0;
@@ -799,21 +885,37 @@ static int reply_with_finish(int fd)
return 0;
}
fd_set_block(fd);
if(send(fd, finishframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
fd_set_nonblock(fd);
free(finishframe);
return 0;
fd_set_block(data->fd);
if(data->ssl) {
#ifdef HAVE_SSL
int r;
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(finishframe);
return 0;
}
#endif
} else {
if(send(data->fd, finishframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
fd_set_nonblock(data->fd);
free(finishframe);
return 0;
}
}
if(verbosity) log_info("sent control frame(finish)");
fd_set_nonblock(fd);
fd_set_nonblock(data->fd);
free(finishframe);
return 1;
#else
log_err("no dnstap compiled, no reply");
(void)fd;
(void)data;
return 0;
#endif
}
@@ -825,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);
@@ -847,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);
@@ -889,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 */
@@ -907,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();
@@ -917,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;
}
}
@@ -925,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;
@@ -933,7 +1043,7 @@ static int tap_handshake(struct tap_data* data)
#endif /* HAVE_SSL */
/** callback for dnstap listener */
void dtio_tap_callback(int fd, short ATTR_UNUSED(bits), void* arg)
void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
{
struct tap_data* data = (struct tap_data*)arg;
if(verbosity>=3) log_info("tap callback");
@@ -951,7 +1061,7 @@ void dtio_tap_callback(int 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 */
@@ -973,7 +1083,7 @@ void dtio_tap_callback(int 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;
}
}
@@ -986,7 +1096,7 @@ void dtio_tap_callback(int 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 */
@@ -1011,13 +1121,13 @@ void dtio_tap_callback(int 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(fd)) {
tap_data_free(data);
if(!reply_with_finish(data)) {
tap_data_free(data, 1);
return;
}
}
@@ -1029,7 +1139,6 @@ void dtio_tap_callback(int fd, short ATTR_UNUSED(bits), void* arg)
data->len = 0;
data->len_done = 0;
data->data_done = 0;
}
/** callback for main listening file descriptor */
@@ -1042,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. */
@@ -1112,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 */
@@ -1226,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. */
@@ -1276,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,
@@ -1312,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
@@ -1348,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();
@@ -1555,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
+1398 -1
View File
File diff suppressed because it is too large Load Diff
+4 -5
View File
@@ -19,11 +19,10 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
* Make and install: ./configure; make; make install
* --with-libevent=/path/to/libevent
Can be set to either the system install or the build directory.
--with-libevent=no (default) gives a builtin alternative
implementation. libevent is useful when having many (thousands)
of outgoing ports. This improves randomization and spoof
resistance. For the default of 16 ports the builtin alternative
works well and is a little faster.
--with-libevent=no gives a builtin alternative implementation.
Libevent is enabled by default, it is useful when having many
(thousands) of outgoing ports. This improves randomization and spoof
resistance. It also allows a higher number of outgoing queries.
* --with-libexpat=/path/to/libexpat
Can be set to the install directory of libexpat.
* --without-pthreads
+20
View File
@@ -28,3 +28,23 @@ prefix. For example:
;; ANSWER SECTION:
jazz-v4.viagenie.ca. 86400 IN AAAA 64:ff9b::ce7b:1f02
NAT64 support was added by David Lamparter in 2022; license(s) of the
surrounding code apply. Note that NAT64 is closely related but functionally
orthogonal to DNS64; it allows Unbound to send outgoing queries to IPv4-only
servers over IPv6 through the configured NAT64 prefix. This allows running
an Unbound instance on an IPv6-only host without breaking every single domain
that only has IPv4 servers. Whether that Unbound instance also does DNS64 is
an independent choice.
To enable NAT64 in Unbound, add to unbound.conf's "server" section:
do-nat64: yes
The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the
standard 64:FF9B::/96 prefix. You can reconfigure it with:
nat64-prefix: 64:FF9B::/96
To test NAT64 operation, pick a domain that only has IPv4 reachability for its
nameservers and try resolving any names in that domain.
+192 -12
View File
@@ -17,7 +17,7 @@ server:
# whitespace is not necessary, but looks cleaner.
# verbosity number, 0 is least verbose. 1 is default.
verbosity: 1
# verbosity: 1
# print statistics to the log (for every thread) every N seconds.
# Set to "" or 0 to disable. Default is disabled.
@@ -35,9 +35,14 @@ server:
# statistics-cumulative: no
# enable extended statistics (query types, answer codes, status)
# printed from unbound-control. default off, because of speed.
# printed from unbound-control. Default off, because of speed.
# extended-statistics: no
# Inhibits selected extended statistics (qtype, qclass, qopcode, rcode,
# rpz-actions) from printing if their value is 0.
# Default on.
# statistics-inhibit-zero: yes
# number of threads to create. 1 disables threading.
# num-threads: 1
@@ -50,6 +55,7 @@ server:
# interface: 192.0.2.154
# interface: 192.0.2.154@5003
# interface: 2001:DB8::5
# interface: eth0@5003
# enable this feature to copy the source address of queries to reply.
# Socket options are not supported on all platforms. experimental.
@@ -137,8 +143,8 @@ server:
# edns-buffer-size: 1232
# Maximum UDP response size (not applied to TCP response).
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
# max-udp-size: 4096
# Suggested values are 512 to 4096. Default is 1232. 65536 disables it.
# max-udp-size: 1232
# max memory to use for stream(tcp and tls) waiting result buffers.
# stream-wait-size: 4m
@@ -172,10 +178,43 @@ server:
# a throwaway response (also timeouts) is received.
# outbound-msg-retry: 5
# Hard limit on the number of outgoing queries Unbound will make while
# resolving a name, making sure large NS sets do not loop.
# It resets on query restarts (e.g., CNAME) and referrals.
# max-sent-count: 32
# Hard limit on the number of times Unbound is allowed to restart a
# 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
# msec before recursion replies are dropped. The work item continues.
# discard-timeout: 1900
# Max number of replies waiting for recursion per IP address.
# wait-limit: 1000
# Max replies waiting for recursion for IP address with cookie.
# wait-limit-cookie: 10000
# Apart from the default, the wait limit can be set for a netblock.
# wait-limit-netblock: 192.0.2.0/24 50000
# Apart from the default, the wait limit with cookie can be adjusted.
# wait-limit-cookie-netblock: 192.0.2.0/24 50000
# the amount of memory to use for the RRset cache.
# plain value in bytes or you can append k, m or G. default is "4Mb".
# rrset-cache-size: 4m
@@ -196,6 +235,11 @@ server:
# the time to live (TTL) value cap for negative responses in the cache
# cache-max-negative-ttl: 3600
# the time to live (TTL) value lower bound, in seconds. Default 0.
# For negative responses in the cache. If disabled, default,
# cache-min-ttl applies if configured.
# cache-min-negative-ttl: 0
# the time to live (TTL) value for cached roundtrip times, lameness and
# EDNS version information for hosts. In seconds.
# infra-host-ttl: 900
@@ -217,7 +261,8 @@ server:
# the maximum number of hosts that are cached (roundtrip, EDNS, lame).
# infra-cache-numhosts: 10000
# define a number of tags here, use with local-zone, access-control.
# define a number of tags here, use with local-zone, access-control,
# interface-*.
# repeat the define-tag statement to add additional tags.
# define-tag: "tag1 tag2 tag3"
@@ -227,6 +272,18 @@ server:
# Enable IPv6, "yes" or "no".
# do-ip6: yes
# If running unbound on an IPv6-only host, domains that only have
# IPv4 servers would become unresolveable. If NAT64 is available in
# the network, unbound can use NAT64 to reach these servers with
# the following option. This is NOT needed for enabling DNS64 on a
# system that has IPv4 connectivity.
# Consider also enabling prefer-ip6 to prefer native IPv6 connections
# to nameservers.
# do-nat64: no
# NAT64 prefix. Defaults to using dns64-prefix value.
# nat64-prefix: 64:ff9b::0/96
# Enable UDP, "yes" or "no".
# do-udp: yes
@@ -255,9 +312,14 @@ server:
# Enable EDNS TCP keepalive option.
# edns-tcp-keepalive: no
# Timeout for EDNS TCP keepalive, in msec.
# Timeout for EDNS TCP keepalive, in msec. Overrides tcp-idle-timeout
# if edns-tcp-keepalive is set.
# edns-tcp-keepalive-timeout: 120000
# UDP queries that have waited in the socket buffer for a long time
# can be dropped. Default is 0, disabled. In seconds, such as 3.
# sock-queue-timeout: 0
# Use systemd socket activation for UDP, TCP, and control sockets.
# use-systemd: no
@@ -271,11 +333,10 @@ server:
# Choose deny (drop message), refuse (polite error reply),
# allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
# allow_snoop (recursive and nonrecursive ok)
# allow_cookie (allow UDP with valid cookie or stateful transport)
# deny_non_local (drop queries unless can be answered from local-data)
# refuse_non_local (like deny_non_local but polite error reply).
# access-control: 0.0.0.0/0 refuse
# access-control: 127.0.0.0/8 allow
# access-control: ::0/0 refuse
# access-control: ::1 allow
# access-control: ::ffff:127.0.0.1 allow
@@ -284,7 +345,7 @@ server:
# are tagged with one of these tags.
# access-control-tag: 192.0.2.0/24 "tag2 tag3"
# set action for particular tag for given access control element
# set action for particular tag for given access control element.
# if you have multiple tag values, the tag used to lookup the action
# is the first tag match between access-control-tag and local-zone-tag
# where "first" comes from the order of the define-tag values.
@@ -296,6 +357,58 @@ server:
# Set view for access control element
# access-control-view: 192.0.2.0/24 viewname
# Similar to 'access-control:' but for interfaces.
# Control which listening interfaces are allowed to accept (recursive)
# queries for this server.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the action.
# The actions are the same as 'access-control:' above.
# By default all the interfaces configured are refused.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-action: 192.0.2.153 allow
# interface-action: 192.0.2.154 allow
# interface-action: 192.0.2.154@5003 allow
# interface-action: 2001:DB8::5 allow
# interface-action: eth0@5003 allow
# Similar to 'access-control-tag:' but for interfaces.
# Tag interfaces with a list of tags (in "" with spaces between).
# Interfaces using these tags use localzones that are tagged with one
# of these tags.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the list of tags.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag: eth0@5003 "tag2 tag3"
# Similar to 'access-control-tag-action:' but for interfaces.
# Set action for particular tag for a given interface element.
# If you have multiple tag values, the tag used to lookup the action
# is the first tag match between interface-tag and local-zone-tag
# where "first" comes from the order of the define-tag values.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the tag and action.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag-action: eth0@5003 tag3 refuse
# Similar to 'access-control-tag-data:' but for interfaces.
# Set redirect data for a particular tag for an interface element.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the tag and the redirect data.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag-data: eth0@5003 tag2 "A 127.0.0.1"
# Similar to 'access-control-view:' but for interfaces.
# Set view for an interface element.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the view name.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-view: eth0@5003 viewname
# if given, a chroot(2) is done to the given directory.
# i.e. you can chroot to the working directory, for example,
# for extra security, but make sure all files are in that directory.
@@ -348,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
@@ -359,6 +476,9 @@ server:
# filtering log-queries and log-replies from the log.
# log-tag-queryreply: no
# log with destination address, port and type for log-replies.
# log-destaddr: no
# log the local-zone actions, like local-zone type inform is enabled
# also for the other local zone types.
# log-local-actions: no
@@ -417,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).
@@ -437,6 +560,10 @@ server:
# to validate the zone.
# harden-algo-downgrade: no
# Harden against unknown records in the authority section and the
# additional section.
# harden-unknown-additional: no
# Sent minimum amount of information to upstream servers to enhance
# privacy. Only sent minimum required labels of the QNAME and set QTYPE
# to A when possible.
@@ -597,6 +724,11 @@ server:
# that set CD but cannot validate themselves.
# ignore-cd-flag: no
# Disable the DO flag in outgoing requests. It is helpful for upstream
# devices that cannot handle DNSSEC information. But do not enable it
# otherwise, because it would stop DNSSEC validation.
# disable-edns-do: no
# Serve expired responses from cache, with serve-expired-reply-ttl in
# the response, and then attempt to fetch the data afresh.
# serve-expired: no
@@ -744,6 +876,8 @@ server:
# o always_transparent, always_refuse, always_nxdomain, always_nodata,
# always_deny resolve in that way but ignore local data for
# that name
# o block_a resolves all records normally but returns
# NODATA for A queries and ignores local data for that name
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
# o noview breaks out of that view towards global local-zones.
#
@@ -786,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"
@@ -850,6 +985,13 @@ 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.
# DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96
@@ -886,6 +1028,13 @@ server:
# if 0(default) it is disabled, otherwise states qps allowed per ip address
# ip-ratelimit: 0
# global query ratelimit for all ip addresses with a valid DNS Cookie.
# feature is experimental.
# if 0(default) it is disabled, otherwise states qps allowed per ip address
# useful in combination with 'allow_cookie'.
# If used, suggested to be higher than ip-ratelimit, tenfold.
# ip-ratelimit-cookie: 0
# ip ratelimits are tracked in a cache, size in bytes of cache (or k,m).
# ip-ratelimit-size: 4m
# ip ratelimit cache slabs, reduces lock contention if equal to cpucount.
@@ -907,6 +1056,19 @@ server:
# the number of servers that will be used in the fast server selection.
# fast-server-num: 3
# reply to requests containing DNS Cookies as specified in RFC 7873 and RFC 9018.
# answer-cookie: no
# secret for DNS Cookie generation.
# useful for anycast deployments.
# 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
@@ -1053,7 +1215,7 @@ remote-control:
# sources of notifies.
# auth-zone:
# name: "."
# primary: 199.9.14.201 # b.root-servers.net
# primary: 170.247.170.2 # b.root-servers.net
# primary: 192.33.4.12 # c.root-servers.net
# primary: 199.7.91.13 # d.root-servers.net
# primary: 192.5.5.241 # f.root-servers.net
@@ -1061,7 +1223,7 @@ remote-control:
# primary: 193.0.14.129 # k.root-servers.net
# primary: 192.0.47.132 # xfr.cjr.dns.icann.org
# primary: 192.0.32.132 # xfr.lax.dns.icann.org
# primary: 2001:500:200::b # b.root-servers.net
# primary: 2801:1b8:10::b # b.root-servers.net
# primary: 2001:500:2::c # c.root-servers.net
# primary: 2001:500:2d::d # d.root-servers.net
# primary: 2001:500:2f::f # f.root-servers.net
@@ -1129,6 +1291,11 @@ remote-control:
# backend: "testframe"
# # secret seed string to calculate hashed keys
# secret-seed: "default"
# # if the backend should be read from, but not written to.
# cachedb-no-store: no
# # if the cachedb should be checked before a serve-expired response is
# # given, when serve-expired is enabled.
# cachedb-check-when-serve-expired: yes
#
# # For "redis" backend:
# # (to enable, use --with-libhiredis to configure before compiling)
@@ -1136,10 +1303,20 @@ remote-control:
# redis-server-host: 127.0.0.1
# # redis server's TCP port
# redis-server-port: 6379
# # if the server uses a unix socket, set its path, or "" when not used.
# # redis-server-path: "/var/lib/redis/redis-server.sock"
# # if the server uses an AUTH password, specify here, or "" when not used.
# # 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.
# redis-logical-db: 0
# IPSet
# Add specify domain into set via ipset.
@@ -1181,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
@@ -1189,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
+4
View File
@@ -14,6 +14,7 @@ unbound\-checkconf
.B unbound\-checkconf
.RB [ \-h ]
.RB [ \-f ]
.RB [ \-q ]
.RB [ \-o
.IR option ]
.RI [ cfgfile ]
@@ -37,6 +38,9 @@ Print full pathname, with chroot applied to it. Use with the \-o option.
If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed.
.TP
.B \-q
Make the operation quiet, suppress output on success.
.TP
.I cfgfile
The config file to read with settings for Unbound. It is checked.
If omitted, the config file at the default location is checked.
+126 -16
View File
@@ -54,6 +54,12 @@ Stop the server. The server daemon exits.
.B reload
Reload the server. This flushes the cache and reads the config file fresh.
.TP
.B reload_keep_cache
Reload the server but try to keep the RRset and message cache if
(re)configuration allows for it.
That means the caches sizes and the number of threads must not change between
reloads.
.TP
.B verbosity \fInumber
Change verbosity value for logging. Same values as \fBverbosity\fR keyword in
\fIunbound.conf\fR(5). This new setting lasts until the server is issued
@@ -115,31 +121,38 @@ Remove local data RRs read from stdin of unbound\-control. Input is one name per
line. For bulk removals.
.TP
.B dump_cache
The contents of the cache is printed in a text format to stdout. You can
redirect it to a file to store the cache in a file.
The content of the cache is printed in a text format to stdout.
You can redirect it to a file to store the cache in a file.
Not supported in remote Unbounds in multi-process operation.
.TP
.B load_cache
The contents of the cache is loaded from stdin. Uses the same format as
dump_cache uses. Loading the cache with old, or wrong data can result
in old or wrong data returned to clients. Loading data into the cache
in this way is supported in order to aid with debugging.
The content of the cache is loaded from stdin.
Uses the same format as dump_cache uses.
Loading the cache with old, or wrong data can result in old or wrong data
returned to clients.
Loading data into the cache in this way is supported in order to aid with
debugging.
Not supported in remote Unbounds in multi-process operation.
.TP
.B lookup \fIname
Print to stdout the name servers that would be used to look up the
name specified.
.TP
.B flush \fIname
.B flush \fR[\fI+c\fR] \fIname
Remove the name from the cache. Removes the types
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV and NAPTR.
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV, NAPTR, SVCB and HTTPS.
Because that is fast to do. Other record types can be removed using
.B flush_type
or
.B flush_zone\fR.
.IP
The '+c' option removes the items also from the cachedb cache. If
cachedb is in use.
.TP
.B flush_type \fIname\fR \fItype
.B flush_type \fR[\fI+c\fR] \fIname\fR \fItype
Remove the name, type information from the cache.
.TP
.B flush_zone \fIname
.B flush_zone \fR[\fI+c\fR] \fIname
Remove all information at or below the name from the cache.
The rrsets and key entries are removed so that new lookups will be performed.
This needs to walk and inspect the entire cache, and is a slow operation.
@@ -147,10 +160,10 @@ The entries are set to expired in the implementation of this command (so,
with serve\-expired enabled, it'll serve that information but schedule a
prefetch for new information).
.TP
.B flush_bogus
.B flush_bogus \fR[\fI+c\fR]
Remove all bogus data from the cache.
.TP
.B flush_negative
.B flush_negative \fR[\fI+c\fR]
Remove all negative data from the cache. This is nxdomain answers,
nodata answers and servfail answers. Also removes bad key entries
(which could be due to failed lookups) from the dnssec key cache, and
@@ -233,22 +246,24 @@ still be bogus, use \fBflush_zone\fR to remove it), does not affect the config f
.B insecure_remove \fIzone
Removes domain\-insecure for the given zone.
.TP
.B forward_add \fR[\fI+i\fR] \fIzone addr ...
.B forward_add \fR[\fI+it\fR] \fIzone addr ...
Add a new forward zone to running Unbound. With +i option also adds a
\fIdomain\-insecure\fR for the zone (so it can resolve insecurely if you have
a DNSSEC root trust anchor configured for other names).
The addr can be IP4, IP6 or nameserver names, like \fIforward-zone\fR config
in unbound.conf.
The +t option sets it to use tls upstream, like \fIforward\-tls\-upstream\fR: yes.
.TP
.B forward_remove \fR[\fI+i\fR] \fIzone
Remove a forward zone from running Unbound. The +i also removes a
\fIdomain\-insecure\fR for the zone.
.TP
.B stub_add \fR[\fI+ip\fR] \fIzone addr ...
.B stub_add \fR[\fI+ipt\fR] \fIzone addr ...
Add a new stub zone to running Unbound. With +i option also adds a
\fIdomain\-insecure\fR for the zone. With +p the stub zone is set to prime,
without it it is set to notprime. The addr can be IP4, IP6 or nameserver
names, like the \fIstub-zone\fR config in unbound.conf.
The +t option sets it to use tls upstream, like \fIstub\-tls\-upstream\fR: yes.
.TP
.B stub_remove \fR[\fI+i\fR] \fIzone
Remove a stub zone from running Unbound. The +i also removes a
@@ -335,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"
@@ -363,6 +413,15 @@ number of queries received by thread
.I threadX.num.queries_ip_ratelimited
number of queries rate limited by thread
.TP
.I threadX.num.queries_cookie_valid
number of queries with a valid DNS Cookie by thread
.TP
.I threadX.num.queries_cookie_client
number of queries with a client part only DNS Cookie by thread
.TP
.I threadX.num.queries_cookie_invalid
number of queries with an invalid DNS Cookie by thread
.TP
.I threadX.num.cachehits
number of queries that were successfully answered using a cache lookup
.TP
@@ -392,6 +451,14 @@ as a cache response was sent.
.I threadX.num.expired
number of replies that served an expired cache entry.
.TP
.I threadX.num.queries_timed_out
number of queries that are dropped because they waited in the UDP socket buffer
for too long.
.TP
.I threadX.query.queue_time_us.max
The maximum wait time for packets in the socket buffer, in microseconds. This
is only reported when sock-queue-timeout is enabled.
.TP
.I threadX.num.recursivereplies
The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries.
.TP
@@ -432,6 +499,18 @@ buffers are full.
.I total.num.queries
summed over threads.
.TP
.I total.num.queries_ip_ratelimited
summed over threads.
.TP
.I total.num.queries_cookie_valid
summed over threads.
.TP
.I total.num.queries_cookie_client
summed over threads.
.TP
.I total.num.queries_cookie_invalid
summed over threads.
.TP
.I total.num.cachehits
summed over threads.
.TP
@@ -456,6 +535,12 @@ summed over threads.
.I total.num.expired
summed over threads.
.TP
.I total.num.queries_timed_out
summed over threads.
.TP
.I total.query.queue_time_us.max
the maximum of the thread values.
.TP
.I total.num.recursivereplies
summed over threads.
.TP
@@ -521,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.
@@ -569,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
@@ -591,7 +684,7 @@ ratelimiting.
.TP
.I num.query.dnscrypt.shared_secret.cachemiss
The number of dnscrypt queries that did not find a shared secret in the cache.
The can be use to compute the shared secret hitrate.
This can be used to compute the shared secret hitrate.
.TP
.I num.query.dnscrypt.replay
The number of dnscrypt queries that found a nonce hit in the nonce cache and
@@ -647,6 +740,18 @@ timing and protocol support information.
The number of items in the key cache. These are DNSSEC keys, one item
per delegation point, and their validation status.
.TP
.I msg.cache.max_collisions
The maximum number of hash table collisions in the msg cache. This is the
number of hashes that are identical when a new element is inserted in the
hash table. If the value is very large, like hundreds, something is wrong
with the performance of the hash table, hash values are incorrect or malicious.
.TP
.I rrset.cache.max_collisions
The maximum number of hash table collisions in the rrset cache. This is the
number of hashes that are identical when a new element is inserted in the
hash table. If the value is very large, like hundreds, something is wrong
with the performance of the hash table, hash values are incorrect or malicious.
.TP
.I dnscrypt_shared_secret.cache.count
The number of items in the shared secret cache. These are precomputed shared
secrets for a given client public key/server secret key pair. Shared secrets
@@ -686,7 +791,12 @@ Number of queries that got an answer that contained EDNS client subnet data.
.I num.query.subnet_cache
Number of queries answered from the edns client subnet cache. These are
counted as cachemiss by the main counters, but hit the client subnet
specific cache, after getting processed by the edns client subnet module.
specific cache after getting processed by the edns client subnet module.
.TP
.I num.query.cachedb
Number of queries answered from the external cache of cachedb.
These are counted as cachemiss by the main counters, but hit the cachedb
external cache after getting processed by the cachedb module.
.TP
.I num.rpz.action.<rpz_action>
Number of queries answered using configured RPZ policy, per RPZ action type.
+409 -63
View File
@@ -112,13 +112,21 @@ If enabled, extended statistics are printed from \fIunbound\-control\fR(8).
Default is off, because keeping track of more statistics takes time. The
counters are listed in \fIunbound\-control\fR(8).
.TP
.B statistics\-inhibit\-zero: \fI<yes or no>
If enabled, selected extended statistics with a value of 0 are inhibited from
printing with \fIunbound\-control\fR(8).
These are query types, query classes, query opcodes, answer rcodes
(except NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMPL, REFUSED) and
RPZ actions.
Default is on.
.TP
.B num\-threads: \fI<number>
The number of threads to create to serve clients. Use 1 for no threading.
.TP
.B port: \fI<port number>
The port number, default 53, on which the server responds to queries.
.TP
.B interface: \fI<ip address[@port]>
.B interface: \fI<ip address or interface name [@port]>
Interface to use to connect to the network. This interface is listened to
for queries from clients, and answers to clients are given from it.
Can be given multiple times to work on several interfaces. If none are
@@ -129,7 +137,7 @@ A port number can be specified with @port (without spaces between
interface and port number), if not specified the default port (from
\fBport\fR) is used.
.TP
.B ip\-address: \fI<ip address[@port]>
.B ip\-address: \fI<ip address or interface name [@port]>
Same as interface: (for ease of compatibility with nsd.conf).
.TP
.B interface\-automatic: \fI<yes or no>
@@ -225,7 +233,8 @@ number).
.B max\-udp\-size: \fI<number>
Maximum UDP response size (not applied to TCP response). 65536 disables the
udp response size maximum, and uses the choice from the client, always.
Suggested values are 512 to 4096. Default is 4096.
Suggested values are 512 to 4096. Default is 1232. The default value is the
same as the default for edns\-buffer\-size.
.TP
.B stream\-wait\-size: \fI<number>
Number of bytes size maximum to use for waiting stream buffers. Default is
@@ -293,6 +302,36 @@ Increase this if you are behind a slow satellite link, to eg. 1128.
That would then avoid re\-querying every initial query because it times out.
Default is 376 msec.
.TP
.B discard\-timeout: \fI<msec>
The wait time in msec where recursion requests are dropped. This is
to stop a large number of replies from accumulating. They receive
no reply, the work item continues to recurse. It is nice to be a bit
larger than serve\-expired\-client\-timeout if that is enabled.
A value of 1900 msec is suggested. The value 0 disables it.
Default 1900 msec.
.TP
.B wait\-limit: \fI<number>
The number of replies that can wait for recursion, for an IP address.
This makes a ratelimit per IP address of waiting replies for recursion.
It stops very large amounts of queries waiting to be returned to one
destination. The value 0 disables wait limits. Default is 1000.
.TP
.B wait\-limit\-cookie: \fI<number>
The number of replies that can wait for recursion, for an IP address
that sent the query with a valid DNS cookie. Since the cookie validates
the client address, the limit can be higher. Default is 10000.
.TP
.B wait\-limit\-netblock: \fI<netblock> <number>
The wait limit for the netblock. If not given the wait\-limit value is
used. The most specific netblock is used to determine the limit. Useful for
overriding the default for a specific, group or individual, server.
The value -1 disables wait limits for the netblock.
.TP
.B wait\-limit\-cookie\-netblock: \fI<netblock> <number>
The wait limit for the netblock, when the query has a DNS cookie.
If not given, the wait\-limit\-cookie value is used.
The value -1 disables wait limits for the netblock.
.TP
.B so\-rcvbuf: \fI<number>
If not 0, then set the SO_RCVBUF socket option to get more buffer
space on UDP port 53 incoming queries. So that short spikes on busy
@@ -349,7 +388,7 @@ ip\-transparent option is also available.
The value of the Differentiated Services Codepoint (DSCP) in the
differentiated services field (DS) of the outgoing IP packet headers.
The field replaces the outdated IPv4 Type-Of-Service field and the
IPV6 traffic class field.
IPv6 traffic class field.
.TP
.B rrset\-cache\-size: \fI<number>
Number of bytes size of the RRset cache. Default is 4 megabytes.
@@ -379,6 +418,15 @@ Time to live maximum for negative responses, these have a SOA in the
authority section that is limited in time. Default is 3600.
This applies to nxdomain and nodata answers.
.TP
.B cache\-min\-negative\-ttl: \fI<seconds>
Time to live minimum for negative responses, these have a SOA in the
authority section that is limited in time.
Default is 0 (disabled).
If this is disabled and \fBcache-min-ttl\fR is configured, it will take effect
instead.
In that case you can set this to 1 to honor the upstream TTL.
This applies to nxdomain and nodata answers.
.TP
.B infra\-host\-ttl: \fI<seconds>
Time to live for entries in the host cache. The host cache contains
roundtrip timing, lameness and EDNS support information. Default is 900.
@@ -416,7 +464,7 @@ Enable or disable whether ip4 queries are answered or issued. Default is yes.
Enable or disable whether ip6 queries are answered or issued. Default is yes.
If disabled, queries are not answered on IPv6, and queries are not sent on
IPv6 to the internet nameservers. With this option you can disable the
ipv6 transport for sending DNS traffic, it does not impact the contents of
IPv6 transport for sending DNS traffic, it does not impact the contents of
the DNS traffic, which may have ip4 and ip6 addresses in it.
.TP
.B prefer\-ip4: \fI<yes or no>
@@ -463,6 +511,8 @@ configured value if the number of free buffers falls below 35% of the
total number configured, and finally to 0 if the number of free buffers
falls below 20% of the total number configured. A minimum timeout of
200 milliseconds is observed regardless of the option value used.
It will be overridden by \fBedns\-tcp\-keepalive\-timeout\fR if
\fBedns\-tcp\-keepalive\fR is enabled.
.TP
.B tcp-reuse-timeout: \fI<msec>\fR
The period Unbound will keep TCP persistent connections open to
@@ -481,20 +531,19 @@ This option defaults to 3000 milliseconds.
Enable or disable EDNS TCP Keepalive. Default is no.
.TP
.B edns-tcp-keepalive-timeout: \fI<msec>\fR
The period Unbound will wait for a query on a TCP connection when
EDNS TCP Keepalive is active. If this timeout expires Unbound closes
the connection. If the client supports the EDNS TCP Keepalive option,
Overrides \fBtcp\-idle\-timeout\fR when \fBedns\-tcp\-keepalive\fR is enabled.
If the client supports the EDNS TCP Keepalive option,
Unbound sends the timeout value to the client to encourage it to
close the connection before the server times out.
This option defaults to 120000 milliseconds.
When the number of free incoming TCP buffers falls below 50% of
the total number configured, the advertised timeout is progressively
reduced to 1% of the configured value, then to 0.2% of the configured
value if the number of free buffers falls below 35% of the total number
configured, and finally to 0 if the number of free buffers falls below
20% of the total number configured.
A minimum actual timeout of 200 milliseconds is observed regardless of the
advertised timeout.
.TP
.B sock\-queue\-timeout: \fI<sec>\fR
UDP queries that have waited in the socket buffer for a long time can be
dropped. Default is 0, disabled. The time is set in seconds, 3 could be a
good value to ignore old queries that likely the client does not need a reply
for any more. This could happen if the host has not been able to service
the queries for a while, i.e. Unbound is not running, and then is enabled
again. It uses timestamp socket options.
.TP
.B tcp\-upstream: \fI<yes or no>
Enable or disable whether the upstream queries use TCP only for transport.
@@ -517,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
@@ -656,6 +708,29 @@ Ignored if the option is not available. Default is yes.
Disable use of TLS for the downstream DNS-over-HTTP connections. Useful for
local back end servers. Default is no.
.TP
.B proxy\-protocol\-port: \fI<portnr>
List port numbers as proxy\-protocol\-port, and when interfaces are defined,
eg. with the @port suffix, as this port number, they support and expect PROXYv2.
In this case the proxy address will only be used for the network communication
and initial ACL (check if the proxy itself is denied/refused by configuration).
The proxied address (if any) will then be used as the true client address and
will be used where applicable for logging, ACL, DNSTAP, RPZ and IP ratelimiting.
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.
@@ -671,19 +746,25 @@ When at the limit, further connections are accepted but closed immediately.
This option is experimental at this time.
.TP
.B access\-control: \fI<IP netblock> <action>
Specify treatment of incoming queries from their originating IP address.
Queries can be allowed to have access to this server that gives DNS
answers, or refused, with other actions possible. The IP address range
can be specified as a netblock, it is possible to give the statement
several times in order to specify the treatment of different netblocks.
.IP
The netblock is given as an IP4 or IP6 address with /size appended for a
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
\fIrefuse_non_local\fR.
The most specific netblock match is used, if none match \fIdeny\fR is used.
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIallow_cookie\fR,
\fIdeny_non_local\fR or \fIrefuse_non_local\fR.
The most specific netblock match is used, if none match \fIrefuse\fR is used.
The order of the access\-control statements therefore does not matter.
.IP
The action \fIdeny\fR stops queries from hosts from that netblock.
The \fIdeny\fR action stops queries from hosts from that netblock.
.IP
The action \fIrefuse\fR stops queries too, but sends a DNS rcode REFUSED
The \fIrefuse\fR action stops queries too, but sends a DNS rcode REFUSED
error message back.
.IP
The action \fIallow\fR gives access to clients from that netblock.
The \fIallow\fR action gives access to clients from that netblock.
It gives only access for recursion clients (which is
what almost all clients need). Nonrecursive queries are refused.
.IP
@@ -703,14 +784,27 @@ may be useful if another DNS server must forward requests for specific
zones to a resolver DNS server, but only supports stub domains and
sends queries to the resolver DNS server with the RD bit cleared.
.IP
The action \fIallow_snoop\fR gives nonrecursive access too. This give
The \fIallow_snoop\fR action gives nonrecursive access too. This give
both recursive and non recursive access. The name \fIallow_snoop\fR refers
to cache snooping, a technique to use nonrecursive queries to examine
the cache contents (for malicious acts). However, nonrecursive queries can
also be a valuable debugging tool (when you want to examine the cache
contents). In that case use \fIallow_snoop\fR for your administration host.
.IP
By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd.
The \fIallow_cookie\fR action allows access only to UDP queries that contain a
valid DNS Cookie as specified in RFC 7873 and RFC 9018, when the
\fBanswer\-cookie\fR option is enabled.
UDP queries containing only a DNS Client Cookie and no Server Cookie, or an
invalid DNS Cookie, will receive a BADCOOKIE response including a newly
generated DNS Cookie, allowing clients to retry with that DNS Cookie.
The \fIallow_cookie\fR action will also accept requests over stateful
transports, regardless of the presence of an DNS Cookie and regardless of the
\fBanswer\-cookie\fR setting.
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 (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.
@@ -741,6 +835,50 @@ Set redirect data for particular tag for given access control element.
.B access\-control\-view: \fI<IP netblock> <view name>
Set view for given access control element.
.TP
.B interface\-action: \fI<ip address or interface name [@port]> <action>
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 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
settings for targeted clients.
.TP
.B interface\-tag: \fI<ip address or interface name [@port]> <"list of tags">
Similar to \fBaccess\-control-tag:\fR but for interfaces.
.IP
Note that the interface needs to be already specified with \fBinterface:\fR
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
settings for targeted clients.
.TP
.B interface\-tag\-action: \fI<ip address or interface name [@port]> <tag> <action>
Similar to \fBaccess\-control-tag-action:\fR but for interfaces.
.IP
Note that the interface needs to be already specified with \fBinterface:\fR
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
settings for targeted clients.
.TP
.B interface\-tag\-data: \fI<ip address or interface name [@port]> <tag> <"resource record string">
Similar to \fBaccess\-control-tag-data:\fR but for interfaces.
.IP
Note that the interface needs to be already specified with \fBinterface:\fR
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
settings for targeted clients.
.TP
.B interface\-view: \fI<ip address or interface name [@port]> <view name>
Similar to \fBaccess\-control-view:\fR but for interfaces.
.IP
Note that the interface needs to be already specified with \fBinterface:\fR
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
settings for targeted clients.
.TP
.B chroot: \fI<directory>
If chroot is enabled, you should pass the configfile (from the
commandline) as a full path from the original root. After the
@@ -813,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
@@ -831,6 +973,11 @@ Prints the word 'query' and 'reply' with log\-queries and log\-replies.
This makes filtering logs easier. The default is off (for backwards
compatibility).
.TP
.B log\-destaddr: \fI<yes or no>
Prints the destination address, port and type in the log\-replies output.
This disambiguates what type of traffic, eg. udp or tcp, and to what local
port the traffic was sent to.
.TP
.B log\-local\-actions: \fI<yes or no>
Print log lines to inform about local zone actions. These lines are like the
local\-zone type inform prints out, but they are also printed for the other
@@ -920,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
@@ -960,6 +1112,12 @@ validate the zone. Default is no. Zone signers must produce zones
that allow this feature to work, but sometimes they do not, and turning
this option off avoids that validation failure.
.TP
.B harden\-unknown\-additional: \fI<yes or no>
Harden against unknown records in the authority section and additional
section. Default is no. If no, such records are copied from the upstream
and presented to the client together with the answer. If yes, it could
hamper future protocol developments that want to add records.
.TP
.B use\-caps\-for\-id: \fI<yes or no>
Use 0x20\-encoded random bits in the query to foil spoof attempts.
This perturbs the lowercase and uppercase of query names sent to
@@ -1037,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
@@ -1060,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
@@ -1214,6 +1374,20 @@ servers that set the CD flag but cannot validate DNSSEC themselves are
the clients, and then Unbound provides them with DNSSEC protection.
The default value is "no".
.TP
.B disable\-edns\-do: \fI<yes or no>
Disable the EDNS DO flag in upstream requests.
It breaks DNSSEC validation for Unbound's clients.
This results in the upstream name servers to not include DNSSEC records in
their replies and could be helpful for devices that cannot handle DNSSEC
information.
When the option is enabled, clients that set the DO flag receive no EDNS
record in the response to indicate the lack of support to them.
If this option is enabled but Unbound is already configured for DNSSEC
validation (i.e., the validator module is enabled; default) this option is
implicitly turned off with a warning as to not break DNSSEC validation in
Unbound.
Default is no.
.TP
.B serve\-expired: \fI<yes or no>
If enabled, Unbound attempts to serve old responses from cache with a
TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the
@@ -1332,10 +1506,10 @@ address space are not validated. This is usually required whenever
Configure a local zone. The type determines the answer to give if
there is no match from local\-data. The types are deny, refuse, static,
transparent, redirect, nodefault, typetransparent, inform, inform_deny,
inform_redirect, always_transparent, always_refuse, always_nxdomain, always_null, noview,
and are explained below. After that the default settings are listed. Use
local\-data: to enter data into the local zone. Answers for local zones
are authoritative DNS answers. By default the zones are class IN.
inform_redirect, always_transparent, block_a, always_refuse, always_nxdomain,
always_null, noview, and are explained below. After that the default settings
are listed. Use local\-data: to enter data into the local zone. Answers for
local zones are authoritative DNS answers. By default the zones are class IN.
.IP
If you need more complicated authoritative data, with referrals, wildcards,
CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for
@@ -1410,6 +1584,12 @@ Ie. answer queries with fixed data and also log the machines that ask.
\h'5'\fIalways_transparent\fR
Like transparent, but ignores local data and resolves normally.
.TP 10
\h'5'\fIblock_a\fR
Like transparent, but ignores local data and resolves normally all query
types excluding A. For A queries it unconditionally returns NODATA.
Useful in cases when there is a need to explicitly force all apps to use
IPv6 protocol and avoid any queries to IPv4.
.TP 10
\h'5'\fIalways_refuse\fR
Like refuse, but ignores local data and refuses the query.
.TP 10
@@ -1620,7 +1800,7 @@ This specifies the action data for \fIresponse-ip\fR with action being
to redirect as specified by "\fIresource record string\fR". "Resource
record string" is similar to that of \fIaccess-control-tag-action\fR,
but it must be of either AAAA, A or CNAME types.
If the IP-netblock is an IPv6/IPV4 prefix, the record
If the IP-netblock is an IPv6/IPv4 prefix, the record
must be AAAA/A respectively, unless it is a CNAME (which can be used
for both versions of IP netblocks). If it is CNAME there must not be
more than one \fIresponse-ip-data\fR for the same IP-netblock.
@@ -1726,11 +1906,30 @@ A value of 0 will disable ratelimiting for domain names that end in this name.
.TP 5
.B ip\-ratelimit: \fI<number or 0>
Enable global ratelimiting of queries accepted per IP address.
If 0, the default, it is disabled. This option is experimental at this time.
This option is experimental at this time.
The ratelimit is in queries per second that are allowed. More queries are
completely dropped and will not receive a reply, SERVFAIL or otherwise.
IP ratelimiting happens before looking in the cache. This may be useful for
mitigating amplification attacks.
Clients with a valid DNS Cookie will bypass the ratelimit.
If a ratelimit for such clients is still needed, \fBip\-ratelimit\-cookie\fR
can be used instead.
Default is 0 (disabled).
.TP 5
.B ip\-ratelimit\-cookie: \fI<number or 0>
Enable global ratelimiting of queries accepted per IP address with a valid DNS
Cookie.
This option is experimental at this time.
The ratelimit is in queries per second that are allowed.
More queries are completely dropped and will not receive a reply, SERVFAIL or
otherwise.
IP ratelimiting happens before looking in the cache.
This option could be useful in combination with \fIallow_cookie\fR in an
attempt to mitigate other amplification attacks than UDP reflections (e.g.,
attacks targeting Unbound itself) which are already handled with DNS Cookies.
If used, the value is suggested to be higher than \fBip\-ratelimit\fR e.g.,
tenfold.
Default is 0 (disabled).
.TP 5
.B ip\-ratelimit\-size: \fI<memory size>
Give the size of the data structure in which the current ongoing rates are
@@ -1769,6 +1968,38 @@ If a forward/stub zone is used, this is the number of retries per nameserver in
the zone.
Default is 5.
.TP 5
.B max\-sent\-count: \fI<number>
Hard limit on the number of outgoing queries Unbound will make while resolving
a name, making sure large NS sets do not loop.
Results in SERVFAIL when reached.
It resets on query restarts (e.g., CNAME) and referrals.
Default is 32.
.TP 5
.B max\-query\-restarts: \fI<number>
Hard limit on the number of times Unbound is allowed to restart a query upon
encountering a CNAME record.
Results in SERVFAIL when reached.
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
@@ -1784,6 +2015,32 @@ Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5
.B answer\-cookie: \fI<yes or no>
If enabled, Unbound will answer to requests containing DNS Cookies as
specified in RFC 7873 and RFC 9018.
Default is no.
.TP 5
.B cookie\-secret: \fI<128 bit hex string>
Server's secret for DNS Cookie generation.
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
destination address matching the configured IP netblock. This configuration
@@ -1802,7 +2059,7 @@ errors. Default is "no".
When the \fBval-log-level\fR option is also set to \fB2\fR, responses with
Extended DNS Errors concerning DNSSEC failures that are not served from cache,
will also contain a descriptive text message about the reason for the failure.
.TP
.TP 5
.B ede\-serve\-expired: \fI<yes or no>
If enabled, Unbound will attach an Extended DNS Error (RFC8914) Code 3 - Stale
Answer as EDNS0 option to the expired response. Note that this will not attach
@@ -1823,9 +2080,11 @@ section for options. To setup the correct self\-signed certificates use the
The option is used to enable remote control, default is "no".
If turned off, the server does not listen for control commands.
.TP 5
.B control\-interface: \fI<ip address or path>
.B control\-interface: \fI<ip address or interface name or path>
Give IPv4 or IPv6 addresses or local socket path to listen on for
control commands.
If an interface name is used instead of an ip address, the list of ip addresses
on that interface are used.
By default localhost (127.0.0.1 and ::1) is listened to.
Use 0.0.0.0 and ::0 to listen to all interfaces.
If you change this and permissions have been dropped, you must restart
@@ -2015,13 +2274,32 @@ useful when you want immediate changes to be visible.
Authority zones are configured with \fBauth\-zone:\fR, and each one must
have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone clauses, each with a different name, pertaining to that part of the namespace.
The authority zone with the name closest to the name looked up is used.
Authority zones are processed after \fBlocal\-zones\fR and before
cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner
make Unbound respond like an authority server. Authority zones are also
processed after cache, just before going to the network to fetch
information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used
in this manner provide a local copy of an authority server that speeds up
lookups of that data.
Authority zones can be processed on two distinct, non-exclusive, configurable
stages.
.LP
With \fBfor\-downstream:\fR \fIyes\fR (default), authority zones are processed
after \fBlocal\-zones\fR and before cache.
When used in this manner, Unbound responds like an authority server with no
further processing other than returning an answer from the zone contents.
A notable example, in this case, is CNAME records which are returned verbatim
to downstream clients without further resolution.
.LP
With \fBfor\-upstream:\fR \fIyes\fR (default), authority zones are processed
after the cache lookup, just before going to the network to fetch
information for recursion.
When used in this manner they provide a local copy of an authority server
that speeds up lookups for that data during resolving.
.LP
If both options are enabled (default), client queries for an authority zone are
answered authoritatively from Unbound, while internal queries that require data
from the authority zone consult the local zone data instead of going to the
network.
.LP
An interesting configuration is \fBfor\-downstream:\fR \fIno\fR,
\fBfor\-upstream:\fR \fIyes\fR that allows for hyperlocal behavior where both
client and internal queries consult the local zone data while resolving.
In this case, the aforementioned CNAME example will result in a thoroughly
resolved answer.
.LP
Authority zones can be read from zonefile. And can be kept updated via
AXFR and IXFR. After update the zonefile is rewritten. The update mechanism
@@ -2215,6 +2493,21 @@ List domain for which the AAAA records are ignored and the A record is
used by dns64 processing instead. Can be entered multiple times, list a
new domain for which it applies, one per line. Applies also to names
underneath the name given.
.SS "NAT64 Operation"
.LP
NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4-only
servers. It is controlled by two options in the \fBserver:\fR section:
.TP
.B do\-nat64: \fI<yes or no>\fR
Use NAT64 to reach IPv4-only servers.
Consider also enabling \fBprefer\-ip6\fR to prefer native IPv6 connections to
nameservers.
Default no.
.TP
.B nat64\-prefix: \fI<IPv6 prefix>\fR
Use a specific NAT64 prefix to reach IPv4-only servers. Defaults to using
the prefix configured in \fBdns64\-prefix\fR, which in turn defaults to
64:ff9b::/96. The prefix length must be one of /32, /40, /48, /56, /64 or /96.
.SS "DNSCrypt Options"
.LP
The
@@ -2305,6 +2598,9 @@ The maximum size of the ECS cache is controlled by 'msg-cache-size' in the
configuration file. On top of that, for each query only 100 different subnets
are allowed to be stored for each address family. Exceeding that number, older
entries will be purged from cache.
.LP
This module does not interact with the \fBserve\-expired*\fR and
\fBprefetch:\fR options.
.TP
.B send\-client\-subnet: \fI<IP address>\fR
Send client source address to this authority. Append /num to indicate a
@@ -2436,11 +2732,7 @@ If Unbound cannot even find an answer in the backend, it resolves the
query as usual, and stores the answer in the backend.
.P
This module interacts with the \fBserve\-expired\-*\fR options and will reply
with expired data if Unbound is configured for that. Currently the use
of \fBserve\-expired\-client\-timeout:\fR and
\fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from
the external cache as these will result in a reply with 0 TTL without trying to
update the data first, ignoring the configured values.
with expired data if Unbound is configured for that.
.P
If Unbound was built with
\fB\-\-with\-libhiredis\fR
@@ -2491,6 +2783,21 @@ operationally.
If the backend database is shared by multiple Unbound instances,
all instances must use the same secret seed.
This option defaults to "default".
.TP
.B cachedb-no-store: \fI<yes or no>\fR
If the backend should be read from, but not written to. This makes this
instance not store dns messages in the backend. But if data is available it
is retrieved. The default is no.
.TP
.B cachedb-check-when-serve-expired: \fI<yes or no>\fR
If enabled, the cachedb is checked before an expired response is returned.
When \fBserve\-expired\fR is enabled, without \fBserve\-expired\-client\-timeout\fR, it then
does not immediately respond with an expired response from cache, but instead
first checks the cachedb for valid contents, and if so returns it. If the
cachedb also has no valid contents, the serve expired response is sent.
If also \fBserve\-expired\-client\-timeout\fR is enabled, the expired response
is delayed until the timeout expires. Unless the lookup succeeds within the
timeout. The default is yes.
.P
The following
.B cachedb
@@ -2507,6 +2814,16 @@ This option defaults to "127.0.0.1".
The TCP port number of the Redis server.
This option defaults to 6379.
.TP
.B redis-server-path: \fI<unix socket path>\fR
The unix socket path to connect to the redis server. Off by default, and it
can be set to "" to turn this off. Unix sockets may have better throughput
than the IP address option.
.TP
.B redis-server-password: \fI"<password>"\fR
The Redis AUTH password to use for the redis server.
Only relevant if Redis is configured for client password authorisation.
Off by default, and it can be set to "" to turn this off.
.TP
.B redis-timeout: \fI<msec>\fR
The period until when Unbound waits for a response from the Redis sever.
If this timeout expires Unbound closes the connection, treats it as
@@ -2514,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
@@ -2521,6 +2846,17 @@ Unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
this option is internally reverted to "no". Redis SETEX support is required
for this option (Redis >= 2.0.0).
This option defaults to no.
.TP
.B redis-logical-db: \fI<logical database index>
The logical database in Redis to use.
These are databases in the same Redis instance sharing the same configuration
and persisted in the same RDB/AOF file.
If unsure about using this option, Redis documentation
(https://redis.io/commands/select/) suggests not to use a single Redis instance
for multiple unrelated applications.
The default database in Redis is 0 while other logical databases need to be
explicitly SELECT'ed upon connecting.
This option defaults to 0.
.SS DNSTAP Logging Options
DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fR, is enabled
in the \fBdnstap:\fR section.
@@ -2581,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.
@@ -2605,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.
@@ -2615,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
@@ -2720,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
+2007 -886
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -75,6 +75,7 @@ int dynlibmod_init(struct module_env* env, int id) {
struct config_strlist* cfg_item = env->cfg->dynlib_file;
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
__DYNMOD dynamic_library;
int i;
if (!de)
{
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
@@ -84,7 +85,7 @@ int dynlibmod_init(struct module_env* env, int id) {
env->modinfo[id] = (void*) de;
de->fname = NULL;
for(int i = dynlib_mod_idx;
for(i = dynlib_mod_idx;
i != 0 && cfg_item != NULL;
i--, cfg_item = cfg_item->next) {}
@@ -296,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)
+7 -2
View File
@@ -97,6 +97,7 @@ node_create(struct addrtree *tree, void *elem, addrlen_t scope,
tree->node_count++;
node->scope = scope;
node->ttl = ttl;
node->only_match_scope_zero = 0;
node->edge[0] = NULL;
node->edge[1] = NULL;
node->parent_edge = NULL;
@@ -155,6 +156,7 @@ clean_node(struct addrtree *tree, struct addrnode *node)
if (!node->elem) return;
tree->size_bytes -= tree->sizefunc(node->elem);
tree->delfunc(tree->env, node->elem);
node->only_match_scope_zero = 0;
node->elem = NULL;
}
@@ -358,7 +360,7 @@ issub(const addrkey_t *s1, addrlen_t l1,
void
addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
time_t now)
time_t now, int only_match_scope_zero)
{
struct addrnode *newnode, *node;
struct addredge *edge;
@@ -381,6 +383,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
/* update this node's scope and data */
clean_node(tree, node);
node->ttl = ttl;
node->only_match_scope_zero = only_match_scope_zero;
node->elem = elem;
node->scope = scope;
tree->size_bytes += tree->sizefunc(elem);
@@ -447,6 +450,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
newnode->elem = elem;
newnode->scope = scope;
newnode->ttl = ttl;
newnode->only_match_scope_zero = only_match_scope_zero;
}
tree->size_bytes += node_size(tree, newnode);
@@ -483,7 +487,8 @@ addrtree_find(struct addrtree *tree, const addrkey_t *addr,
/* Current node more specific then question. */
log_assert(depth <= sourcemask);
/* does this node have data? if yes, see if we have a match */
if (node->elem && node->ttl >= now) {
if (node->elem && node->ttl >= now &&
!(sourcemask != 0 && node->only_match_scope_zero)) {
/* saved at wrong depth */;
log_assert(node->scope >= depth);
if (depth == node->scope ||
+6 -1
View File
@@ -95,6 +95,10 @@ struct addrnode {
time_t ttl;
/** Number of significant bits in address. */
addrlen_t scope;
/** Only use the element for queries for subnet/0. Set if the query
* for /0 was answered with scope 0. For query /x answer scope 0,
* they can match anything and this is false. */
int only_match_scope_zero;
/** A node can have 0-2 edges, set to NULL for unused */
struct addredge *edge[2];
/** edge between this node and parent */
@@ -157,11 +161,12 @@ void addrtree_delete(struct addrtree *tree);
* @param scope: Number of significant bits in addr.
* @param elem: data to store in the tree.
* @param ttl: elem is valid up to this time, seconds.
* @param only_match_scope_zero: set for when query /0 has scope /0 answer.
* @param now: Current time in seconds.
*/
void addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
time_t now);
time_t now, int only_match_scope_zero);
/**
* Find a node containing an element in the tree.
+136 -16
View File
@@ -55,7 +55,11 @@
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "iterator/iter_utils.h"
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
/** externally called */
void
@@ -151,10 +155,11 @@ int ecs_whitelist_check(struct query_info* qinfo,
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
qstate->no_cache_store = 0;
}
sq->subnet_sent_no_subnet = 0;
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
qstate->env->cfg->client_subnet_always_forward) ||
ecs_is_whitelisted(sn_env->whitelist,
@@ -165,6 +170,14 @@ int ecs_whitelist_check(struct query_info* qinfo,
* set. */
if(!edns_opt_list_find(qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode)) {
/* if the client is not wanting an EDNS subnet option,
* omit it and store that we omitted it but actually
* are doing EDNS subnet to the server. */
if(sq->ecs_server_out.subnet_source_mask == 0) {
sq->subnet_sent_no_subnet = 1;
sq->subnet_sent = 0;
return 1;
}
subnet_ecs_opt_list_append(&sq->ecs_server_out,
&qstate->edns_opts_back_out, qstate, region);
}
@@ -203,6 +216,17 @@ subnetmod_init(struct module_env *env, int id)
}
alloc_init(&sn_env->alloc, NULL, 0);
env->modinfo[id] = (void*)sn_env;
/* Warn that serve-expired and prefetch do not work with the subnet
* module cache. */
if(env->cfg->serve_expired)
log_warn(
"subnetcache: serve-expired is set but not working "
"for data originating from the subnet module cache.");
if(env->cfg->prefetch)
log_warn(
"subnetcache: prefetch is set but not working "
"for data originating from the subnet module cache.");
/* Copy msg_cache settings */
sn_env->subnet_msg_cache = slabhash_create(env->cfg->msg_cache_slabs,
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
@@ -289,9 +313,18 @@ delfunc(void *envptr, void *elemptr) {
static size_t
sizefunc(void *elemptr) {
struct reply_info *elem = (struct reply_info *)elemptr;
return sizeof (struct reply_info) - sizeof (struct rrset_ref)
size_t s = sizeof (struct reply_info) - sizeof (struct rrset_ref)
+ elem->rrset_count * sizeof (struct rrset_ref)
+ elem->rrset_count * sizeof (struct ub_packed_rrset_key *);
size_t i;
for (i = 0; i < elem->rrset_count; i++) {
struct ub_packed_rrset_key *key = elem->rrsets[i];
struct packed_rrset_data *data = key->entry.data;
s += ub_rrset_sizefunc(key, data);
}
if(elem->reason_bogus_str)
s += strlen(elem->reason_bogus_str)+1;
return s;
}
/**
@@ -331,6 +364,7 @@ update_cache(struct module_qstate *qstate, int id)
struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
struct ecs_data *edns = &sq->ecs_client_in;
size_t i;
int only_match_scope_zero, diff_size;
/* We already calculated hash upon lookup (lookup_and_reply) if we were
* allowed to look in the ECS cache */
@@ -339,7 +373,7 @@ update_cache(struct module_qstate *qstate, int id)
((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash :
query_info_hash(&qstate->qinfo, qstate->query_flags);
/* Step 1, general qinfo lookup */
struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
struct lruhash_entry* lru_entry = slabhash_lookup(subnet_msg_cache, h,
&qstate->qinfo, 1);
int need_to_insert = (lru_entry == NULL);
if (!lru_entry) {
@@ -383,29 +417,38 @@ update_cache(struct module_qstate *qstate, int id)
log_err("subnetcache: cache insertion failed");
return;
}
/* store RRsets */
for(i=0; i<rep->rrset_count; i++) {
rep->ref[i].key = rep->rrsets[i];
rep->ref[i].id = rep->rrsets[i]->id;
}
reply_info_set_ttls(rep, *qstate->env->now);
reply_info_sortref(rep);
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
if(edns->subnet_source_mask == 0 && edns->subnet_scope_mask == 0)
only_match_scope_zero = 1;
else only_match_scope_zero = 0;
diff_size = (int)tree->size_bytes;
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
edns->subnet_source_mask, sq->max_scope, rep,
rep->ttl, *qstate->env->now);
rep->ttl, *qstate->env->now, only_match_scope_zero);
diff_size = (int)tree->size_bytes - diff_size;
lock_rw_unlock(&lru_entry->lock);
if (need_to_insert) {
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
NULL);
} else {
slabhash_update_space_used(subnet_msg_cache, h, NULL,
diff_size);
}
}
/** Lookup in cache and reply true iff reply is sent. */
static int
lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq, int prefetch)
{
struct lruhash_entry *e;
struct module_env *env = qstate->env;
@@ -457,6 +500,10 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
INET6_SIZE);
sq->ecs_client_out.subnet_validdata = 1;
}
if (prefetch && *qstate->env->now >= ((struct reply_info *)node->elem)->prefetch_ttl) {
qstate->need_refetch = 1;
}
return 1;
}
@@ -493,18 +540,18 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
* module_finished */
return module_finished;
}
/* We have not asked for subnet data */
if (!sq->subnet_sent) {
if (!sq->subnet_sent && !sq->subnet_sent_no_subnet) {
if (s_in->subnet_validdata)
verbose(VERB_QUERY, "subnetcache: received spurious data");
if (sq->subnet_downstream) /* Copy back to client */
cp_edns_bad_response(c_out, c_in);
return module_finished;
}
/* subnet sent but nothing came back */
if (!s_in->subnet_validdata) {
if (!s_in->subnet_validdata && !sq->subnet_sent_no_subnet) {
/* The authority indicated no support for edns subnet. As a
* consequence the answer ended up in the regular cache. It
* is still useful to put it in the edns subnet cache for
@@ -519,11 +566,23 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
cp_edns_bad_response(c_out, c_in);
return module_finished;
}
/* Purposefully there was no sent subnet, and there is consequently
* no subnet in the answer. If there was, use the subnet in the answer
* anyway. But if there is not, treat it as a prefix 0 answer. */
if(sq->subnet_sent_no_subnet && !s_in->subnet_validdata) {
/* Fill in 0.0.0.0/0 scope 0, or ::0/0 scope 0, for caching. */
s_in->subnet_addr_fam = s_out->subnet_addr_fam;
s_in->subnet_source_mask = 0;
s_in->subnet_scope_mask = 0;
memset(s_in->subnet_addr, 0, INET6_SIZE);
s_in->subnet_validdata = 1;
}
/* Being here means we have asked for and got a subnet specific
* answer. Also, the answer from the authority is not yet cached
* anywhere. */
/* can we accept response? */
if(s_out->subnet_addr_fam != s_in->subnet_addr_fam ||
s_out->subnet_source_mask != s_in->subnet_source_mask ||
@@ -536,6 +595,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
sq->subnet_sent_no_subnet = 0;
return module_restart_next;
}
@@ -545,7 +605,21 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
}
sne->num_msg_nocache++;
lock_rw_unlock(&sne->biglock);
/* If there is an expired answer in the global cache, remove that,
* because expired answers would otherwise resurface once the ecs data
* expires, giving once in a while global data responses for ecs
* domains, with serve expired enabled. */
if(qstate->env->cfg->serve_expired) {
msg_cache_remove(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, 0);
#ifdef USE_CACHEDB
if(qstate->env->cachedb_enabled)
cachedb_msg_remove(qstate);
#endif
}
if (sq->subnet_downstream) {
/* Client wants to see the answer, echo option back
* and adjust the scope. */
@@ -656,6 +730,7 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
sq->subnet_sent_no_subnet = 0;
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
} else if (!sq->track_max_scope &&
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR &&
@@ -674,6 +749,24 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
return 1;
}
/** verbose print edns subnet option in pretty print */
static void
subnet_log_print(const char* s, struct edns_option* ecs_opt)
{
if(verbosity >= VERB_ALGO) {
char buf[256];
char* str = buf;
size_t str_len = sizeof(buf);
if(!ecs_opt) {
verbose(VERB_ALGO, "%s (null)", s);
return;
}
(void)sldns_wire2str_edns_subnet_print(&str, &str_len,
ecs_opt->opt_data, ecs_opt->opt_len);
verbose(VERB_ALGO, "%s %s", s, buf);
}
}
int
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
void* ATTR_UNUSED(cbargs))
@@ -688,6 +781,7 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
qstate->env->cfg->client_subnet_opcode)) &&
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
subnet_log_print("answer has edns subnet", ecs_opt);
/* Only skip global cache store if we sent an ECS option
* and received one back. Answers from non-whitelisted
* servers will end up in global cache. Answers for
@@ -698,6 +792,9 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
sq->ecs_server_in.subnet_scope_mask >
sq->max_scope))
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
} else if(sq->subnet_sent_no_subnet) {
/* The answer can be stored as scope 0, not in global cache. */
qstate->no_cache_store = 1;
}
return 1;
@@ -736,11 +833,17 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
qstate->ext_state[id] = module_finished;
return;
}
subnet_log_print("query has edns subnet", ecs_opt);
sq->subnet_downstream = 1;
}
else if(qstate->mesh_info->reply_list) {
subnet_option_from_ss(
&qstate->mesh_info->reply_list->query_reply.addr,
&qstate->mesh_info->reply_list->query_reply.client_addr,
&sq->ecs_client_in, qstate->env->cfg);
}
else if(qstate->client_addr.ss_family != AF_UNSPEC) {
subnet_option_from_ss(
&qstate->client_addr,
&sq->ecs_client_in, qstate->env->cfg);
}
@@ -766,7 +869,9 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
if(!sq->started_no_cache_lookup && !qstate->blacklist) {
lock_rw_wrlock(&sne->biglock);
if(lookup_and_reply(qstate, id, sq)) {
if(qstate->mesh_info->reply_list &&
lookup_and_reply(qstate, id, sq,
qstate->env->cfg->prefetch)) {
sne->num_msg_cache++;
lock_rw_unlock(&sne->biglock);
verbose(VERB_QUERY, "subnetcache: answered from cache");
@@ -775,6 +880,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
subnet_ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate,
qstate->region);
if(verbosity >= VERB_ALGO) {
subnet_log_print("reply has edns subnet",
edns_opt_list_find(
qstate->edns_opts_front_out,
qstate->env->cfg->
client_subnet_opcode));
}
return;
}
lock_rw_unlock(&sne->biglock);
@@ -823,6 +935,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
subnet_ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate,
qstate->region);
if(verbosity >= VERB_ALGO) {
subnet_log_print("reply has edns subnet",
edns_opt_list_find(
qstate->edns_opts_front_out,
qstate->env->cfg->
client_subnet_opcode));
}
}
qstate->no_cache_store = sq->started_no_cache_store;
qstate->no_cache_lookup = sq->started_no_cache_lookup;
@@ -876,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
};
+7
View File
@@ -85,6 +85,13 @@ struct subnet_qstate {
struct ecs_data ecs_server_out;
int subnet_downstream;
int subnet_sent;
/**
* If there was no subnet sent because the client used source prefix
* length 0 for omitting the information. Then the answer is cached
* like subnet was a /0 scope. Like the subnet_sent flag, but when
* the EDNS subnet option is omitted because the client asked.
*/
int subnet_sent_no_subnet;
/** keep track of longest received scope, set after receiving CNAME for
* incoming QNAME. */
int track_max_scope;
+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
};
+164 -49
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,23 +238,31 @@ 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) {
if (dlen == plen || (dlen > plen && dname[dlen - plen - 1] == '.' )) {
ds = dname + (dlen - plen);
}
if (qlen >= plen) {
if (qlen == plen || (qlen > plen && qname[qlen - plen - 1] == '.' )) {
qs = qname + (qlen - plen);
}
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 */
+39
View File
@@ -321,6 +321,45 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
}
}
int
delegpt_addr_on_result_list(struct delegpt* dp, struct delegpt_addr* find)
{
struct delegpt_addr* a = dp->result_list;
while(a) {
if(a == find)
return 1;
a = a->next_result;
}
return 0;
}
void
delegpt_usable_list_remove_addr(struct delegpt* dp, struct delegpt_addr* del)
{
struct delegpt_addr* usa = dp->usable_list, *prev = NULL;
while(usa) {
if(usa == del) {
/* snip off the usable list */
if(prev)
prev->next_usable = usa->next_usable;
else dp->usable_list = usa->next_usable;
return;
}
prev = usa;
usa = usa->next_usable;
}
}
void
delegpt_add_to_result_list(struct delegpt* dp, struct delegpt_addr* a)
{
if(delegpt_addr_on_result_list(dp, a))
return;
delegpt_usable_list_remove_addr(dp, a);
a->next_result = dp->result_list;
dp->result_list = a;
}
void
delegpt_add_unused_targets(struct delegpt* dp)
{
+25
View File
@@ -457,4 +457,29 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
/** get memory in use by dp */
size_t delegpt_get_mem(struct delegpt* dp);
/**
* See if the addr is on the result list.
* @param dp: delegation point.
* @param find: the pointer is searched for on the result list.
* @return 1 if found, 0 if not found.
*/
int delegpt_addr_on_result_list(struct delegpt* dp, struct delegpt_addr* find);
/**
* Remove the addr from the usable list.
* @param dp: the delegation point.
* @param del: the addr to remove from the list, the pointer is searched for.
*/
void delegpt_usable_list_remove_addr(struct delegpt* dp,
struct delegpt_addr* del);
/**
* Add the delegpt_addr back to the result list, if it is not already on
* the result list. Also removes it from the usable list.
* @param dp: delegation point.
* @param a: addr to add, nothing happens if it is already on the result list.
* It is removed from the usable list.
*/
void delegpt_add_to_result_list(struct delegpt* dp, struct delegpt_addr* a);
#endif /* ITERATOR_ITER_DELEGPT_H */
+93 -27
View File
@@ -71,6 +71,7 @@ forwards_create(void)
sizeof(struct iter_forwards));
if(!fwd)
return NULL;
lock_rw_init(&fwd->lock);
return fwd;
}
@@ -100,6 +101,7 @@ forwards_delete(struct iter_forwards* fwd)
{
if(!fwd)
return;
lock_rw_destroy(&fwd->lock);
fwd_del_tree(fwd);
free(fwd);
}
@@ -332,45 +334,64 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
int
forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
{
if(fwd->tree) {
lock_unprotect(&fwd->lock, fwd->tree);
}
fwd_del_tree(fwd);
fwd->tree = rbtree_create(fwd_cmp);
if(!fwd->tree)
return 0;
lock_protect(&fwd->lock, fwd->tree, sizeof(*fwd->tree));
lock_rw_wrlock(&fwd->lock);
/* read forward zones */
if(!read_forwards(fwd, cfg))
if(!read_forwards(fwd, cfg)) {
lock_rw_unlock(&fwd->lock);
return 0;
if(!make_stub_holes(fwd, cfg))
}
if(!make_stub_holes(fwd, cfg)) {
lock_rw_unlock(&fwd->lock);
return 0;
}
fwd_init_parents(fwd);
lock_rw_unlock(&fwd->lock);
return 1;
}
struct delegpt*
forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass,
int nolock)
{
rbnode_type* res = NULL;
struct iter_forward_zone* res;
struct iter_forward_zone key;
int has_dp;
key.node.key = &key;
key.dclass = qclass;
key.name = qname;
key.namelabs = dname_count_size_labels(qname, &key.namelen);
res = rbtree_search(fwd->tree, &key);
if(res) return ((struct iter_forward_zone*)res)->dp;
return NULL;
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&fwd->lock); }
res = (struct iter_forward_zone*)rbtree_search(fwd->tree, &key);
has_dp = res && res->dp;
if(!has_dp && !nolock) { lock_rw_unlock(&fwd->lock); }
return has_dp?res->dp:NULL;
}
struct delegpt*
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass,
int nolock)
{
/* lookup the forward zone in the tree */
rbnode_type* res = NULL;
struct iter_forward_zone *result;
struct iter_forward_zone key;
int has_dp;
key.node.key = &key;
key.dclass = qclass;
key.name = qname;
key.namelabs = dname_count_size_labels(qname, &key.namelen);
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&fwd->lock); }
if(rbtree_find_less_equal(fwd->tree, &key, &res)) {
/* exact */
result = (struct iter_forward_zone*)res;
@@ -378,8 +399,10 @@ forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
/* smaller element (or no element) */
int m;
result = (struct iter_forward_zone*)res;
if(!result || result->dclass != qclass)
if(!result || result->dclass != qclass) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return NULL;
}
/* count number of labels matched */
(void)dname_lab_cmp(result->name, result->namelabs, key.name,
key.namelabs, &m);
@@ -389,20 +412,22 @@ forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
result = result->parent;
}
}
if(result)
return result->dp;
return NULL;
has_dp = result && result->dp;
if(!has_dp && !nolock) { lock_rw_unlock(&fwd->lock); }
return has_dp?result->dp:NULL;
}
struct delegpt*
forwards_lookup_root(struct iter_forwards* fwd, uint16_t qclass)
forwards_lookup_root(struct iter_forwards* fwd, uint16_t qclass, int nolock)
{
uint8_t root = 0;
return forwards_lookup(fwd, &root, qclass);
return forwards_lookup(fwd, &root, qclass, nolock);
}
int
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
/* Finds next root item in forwards lookup tree.
* Caller needs to handle locking of the forwards structure. */
static int
next_root_locked(struct iter_forwards* fwd, uint16_t* dclass)
{
struct iter_forward_zone key;
rbnode_type* n;
@@ -419,7 +444,7 @@ forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
}
/* root not first item? search for higher items */
*dclass = p->dclass + 1;
return forwards_next_root(fwd, dclass);
return next_root_locked(fwd, dclass);
}
/* find class n in tree, we may get a direct hit, or if we don't
* this is the last item of the previous class so rbtree_next() takes
@@ -447,10 +472,21 @@ forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
}
/* not a root node, return next higher item */
*dclass = p->dclass+1;
return forwards_next_root(fwd, dclass);
return next_root_locked(fwd, dclass);
}
}
int
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass, int nolock)
{
int ret;
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&fwd->lock); }
ret = next_root_locked(fwd, dclass);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return ret;
}
size_t
forwards_get_mem(struct iter_forwards* fwd)
{
@@ -458,10 +494,12 @@ forwards_get_mem(struct iter_forwards* fwd)
size_t s;
if(!fwd)
return 0;
lock_rw_rdlock(&fwd->lock);
s = sizeof(*fwd) + sizeof(*fwd->tree);
RBTREE_FOR(p, struct iter_forward_zone*, fwd->tree) {
s += sizeof(*p) + p->namelen + delegpt_get_mem(p->dp);
}
lock_rw_unlock(&fwd->lock);
return s;
}
@@ -477,50 +515,78 @@ fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
}
int
forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp,
int nolock)
{
struct iter_forward_zone *z;
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&fwd->lock); }
if((z=fwd_zone_find(fwd, c, dp->name)) != NULL) {
(void)rbtree_delete(fwd->tree, &z->node);
fwd_zone_free(z);
}
if(!forwards_insert(fwd, c, dp))
if(!forwards_insert(fwd, c, dp)) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return 0;
}
fwd_init_parents(fwd);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return 1;
}
void
forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
int nolock)
{
struct iter_forward_zone *z;
if(!(z=fwd_zone_find(fwd, c, nm)))
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&fwd->lock); }
if(!(z=fwd_zone_find(fwd, c, nm))) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return; /* nothing to do */
}
(void)rbtree_delete(fwd->tree, &z->node);
fwd_zone_free(z);
fwd_init_parents(fwd);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
}
int
forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
int nolock)
{
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&fwd->lock); }
if(fwd_zone_find(fwd, c, nm) != NULL) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return 1; /* already a stub zone there */
}
if(!fwd_add_stub_hole(fwd, c, nm)) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return 0;
}
fwd_init_parents(fwd);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return 1;
}
void
forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
uint8_t* nm, int nolock)
{
struct iter_forward_zone *z;
if(!(z=fwd_zone_find(fwd, c, nm)))
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&fwd->lock); }
if(!(z=fwd_zone_find(fwd, c, nm))) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return; /* nothing to do */
if(z->dp != NULL)
}
if(z->dp != NULL) {
if(!nolock) { lock_rw_unlock(&fwd->lock); }
return; /* not a stub hole */
}
(void)rbtree_delete(fwd->tree, &z->node);
fwd_zone_free(z);
fwd_init_parents(fwd);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
}
+49 -11
View File
@@ -43,6 +43,7 @@
#ifndef ITERATOR_ITER_FWD_H
#define ITERATOR_ITER_FWD_H
#include "util/rbtree.h"
#include "util/locks.h"
struct config_file;
struct delegpt;
@@ -50,6 +51,11 @@ struct delegpt;
* Iterator forward zones structure
*/
struct iter_forwards {
/** lock on the forwards tree.
* When grabbing both this lock and the anchors.lock, this lock
* is grabbed first. When grabbing both this lock and the hints.lock
* this lock is grabbed first. */
lock_rw_type lock;
/**
* Zones are stored in this tree. Sort order is specially chosen.
* first sorted on qclass. Then on dname in nsec-like order, so that
@@ -106,47 +112,65 @@ int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
/**
* Find forward zone exactly by name
* The return value is contents of the forwards structure.
* Caller should lock and unlock a readlock on the forwards structure if nolock
* is set.
* Otherwise caller should unlock the readlock on the forwards structure if a
* value was returned.
* @param fwd: forward storage.
* @param qname: The qname of the query.
* @param qclass: The qclass of the query.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: A delegation point or null.
*/
struct delegpt* forwards_find(struct iter_forwards* fwd, uint8_t* qname,
uint16_t qclass);
uint16_t qclass, int nolock);
/**
* Find forward zone information
* For this qname/qclass find forward zone information, returns delegation
* point with server names and addresses, or NULL if no forwarding is needed.
* The return value is contents of the forwards structure.
* Caller should lock and unlock a readlock on the forwards structure if nolock
* is set.
* Otherwise caller should unlock the readlock on the forwards structure if a
* value was returned.
*
* @param fwd: forward storage.
* @param qname: The qname of the query.
* @param qclass: The qclass of the query.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: A delegation point if the query has to be forwarded to that list,
* otherwise null.
*/
struct delegpt* forwards_lookup(struct iter_forwards* fwd,
uint8_t* qname, uint16_t qclass);
struct delegpt* forwards_lookup(struct iter_forwards* fwd,
uint8_t* qname, uint16_t qclass, int nolock);
/**
* Same as forwards_lookup, but for the root only
* @param fwd: forward storage.
* @param qclass: The qclass of the query.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: A delegation point if root forward exists, otherwise null.
*/
struct delegpt* forwards_lookup_root(struct iter_forwards* fwd,
uint16_t qclass);
struct delegpt* forwards_lookup_root(struct iter_forwards* fwd,
uint16_t qclass, int nolock);
/**
* Find next root item in forwards lookup tree.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a readlock on the forwards structure.
* @param fwd: the forward storage
* @param qclass: class to look at next, or higher.
* @param nolock: Skip locking, locking is handled by the caller.
* @return false if none found, or if true stored in qclass.
*/
int forwards_next_root(struct iter_forwards* fwd, uint16_t* qclass);
int forwards_next_root(struct iter_forwards* fwd, uint16_t* qclass,
int nolock);
/**
* Get memory in use by forward storage
* Locks and unlocks the structure.
* @param fwd: forward storage.
* @return bytes in use
*/
@@ -158,42 +182,56 @@ int fwd_cmp(const void* k1, const void* k2);
/**
* Add zone to forward structure. For external use since it recalcs
* the tree parents.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the forwards structure.
* @param fwd: the forward data structure
* @param c: class of zone
* @param dp: delegation point with name and target nameservers for new
* forward zone. malloced.
* @param nolock: Skip locking, locking is handled by the caller.
* @return false on failure (out of memory);
*/
int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
struct delegpt* dp);
int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
struct delegpt* dp, int nolock);
/**
* Remove zone from forward structure. For external use since it
* recalcs the tree parents.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the forwards structure.
* @param fwd: the forward data structure
* @param c: class of zone
* @param nm: name of zone (in uncompressed wireformat).
* @param nolock: Skip locking, locking is handled by the caller.
*/
void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm);
void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c,
uint8_t* nm, int nolock);
/**
* Add stub hole (empty entry in forward table, that makes resolution skip
* a forward-zone because the stub zone should override the forward zone).
* Does not add one if not necessary.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the forwards structure.
* @param fwd: the forward data structure
* @param c: class of zone
* @param nm: name of zone (in uncompressed wireformat).
* @param nolock: Skip locking, locking is handled by the caller.
* @return false on failure (out of memory);
*/
int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm);
int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c,
uint8_t* nm, int nolock);
/**
* Remove stub hole, if one exists.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the forwards structure.
* @param fwd: the forward data structure
* @param c: class of zone
* @param nm: name of zone (in uncompressed wireformat).
* @param nolock: Skip locking, locking is handled by the caller.
*/
void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
uint8_t* nm);
uint8_t* nm, int nolock);
#endif /* ITERATOR_ITER_FWD_H */
+77 -27
View File
@@ -57,6 +57,8 @@ hints_create(void)
sizeof(struct iter_hints));
if(!hints)
return NULL;
lock_rw_init(&hints->lock);
lock_protect(&hints->lock, &hints->tree, sizeof(hints->tree));
return hints;
}
@@ -83,6 +85,7 @@ hints_delete(struct iter_hints* hints)
{
if(!hints)
return;
lock_rw_destroy(&hints->lock);
hints_del_tree(hints);
free(hints);
}
@@ -100,7 +103,7 @@ ah(struct delegpt* dp, const char* sv, const char* ip)
return 0;
}
if(!delegpt_add_ns_mlc(dp, dname, 0, NULL, UNBOUND_DNS_PORT) ||
!extstrtoaddr(ip, &addr, &addrlen) ||
!extstrtoaddr(ip, &addr, &addrlen, UNBOUND_DNS_PORT) ||
!delegpt_add_target_mlc(dp, dname, dname_len,
&addr, addrlen, 0, 0)) {
free(dname);
@@ -129,7 +132,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
dp->has_parent_side_NS = 1;
if(do_ip4) {
if(!ah(dp, "A.ROOT-SERVERS.NET.", "198.41.0.4")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "199.9.14.201")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "170.247.170.2")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "192.33.4.12")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "199.7.91.13")) goto failed;
if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) goto failed;
@@ -144,7 +147,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
}
if(do_ip6) {
if(!ah(dp, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:200::b")) goto failed;
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2801:1b8:10::b")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
@@ -438,47 +441,70 @@ read_root_hints_list(struct iter_hints* hints, struct config_file* cfg)
int
hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
{
int nolock = 1;
lock_rw_wrlock(&hints->lock);
hints_del_tree(hints);
name_tree_init(&hints->tree);
/* read root hints */
if(!read_root_hints_list(hints, cfg))
if(!read_root_hints_list(hints, cfg)) {
lock_rw_unlock(&hints->lock);
return 0;
}
/* read stub hints */
if(!read_stubs(hints, cfg))
if(!read_stubs(hints, cfg)) {
lock_rw_unlock(&hints->lock);
return 0;
}
/* use fallback compiletime root hints */
if(!hints_lookup_root(hints, LDNS_RR_CLASS_IN)) {
if(!hints_find_root(hints, LDNS_RR_CLASS_IN, nolock)) {
struct delegpt* dp = compile_time_root_prime(cfg->do_ip4,
cfg->do_ip6);
verbose(VERB_ALGO, "no config, using builtin root hints.");
if(!dp)
if(!dp) {
lock_rw_unlock(&hints->lock);
return 0;
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, 0))
}
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, 0)) {
lock_rw_unlock(&hints->lock);
return 0;
}
}
name_tree_init_parents(&hints->tree);
lock_rw_unlock(&hints->lock);
return 1;
}
struct delegpt*
hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
struct delegpt*
hints_find(struct iter_hints* hints, uint8_t* qname, uint16_t qclass,
int nolock)
{
struct iter_hints_stub *stub;
size_t len;
int has_dp;
int labs = dname_count_size_labels(qname, &len);
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&hints->lock); }
stub = (struct iter_hints_stub*)name_tree_find(&hints->tree,
qname, len, labs, qclass);
has_dp = stub && stub->dp;
if(!has_dp && !nolock) { lock_rw_unlock(&hints->lock); }
return has_dp?stub->dp:NULL;
}
struct delegpt*
hints_find_root(struct iter_hints* hints, uint16_t qclass, int nolock)
{
uint8_t rootlab = 0;
struct iter_hints_stub *stub;
stub = (struct iter_hints_stub*)name_tree_find(&hints->tree,
&rootlab, 1, 1, qclass);
if(!stub)
return NULL;
return stub->dp;
return hints_find(hints, &rootlab, qclass, nolock);
}
struct iter_hints_stub*
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
uint16_t qclass, struct delegpt* cache_dp)
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
uint16_t qclass, struct delegpt* cache_dp, int nolock)
{
size_t len;
int labs;
@@ -486,14 +512,20 @@ hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
/* first lookup the stub */
labs = dname_count_size_labels(qname, &len);
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&hints->lock); }
r = (struct iter_hints_stub*)name_tree_lookup(&hints->tree, qname,
len, labs, qclass);
if(!r) return NULL;
if(!r) {
if(!nolock) { lock_rw_unlock(&hints->lock); }
return NULL;
}
/* If there is no cache (root prime situation) */
if(cache_dp == NULL) {
if(r->dp->namelabs != 1)
return r; /* no cache dp, use any non-root stub */
if(!nolock) { lock_rw_unlock(&hints->lock); }
return NULL;
}
@@ -510,12 +542,18 @@ hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
if(dname_strict_subdomain(r->dp->name, r->dp->namelabs,
cache_dp->name, cache_dp->namelabs))
return r; /* need to prime this stub */
if(!nolock) { lock_rw_unlock(&hints->lock); }
return NULL;
}
int hints_next_root(struct iter_hints* hints, uint16_t* qclass)
int hints_next_root(struct iter_hints* hints, uint16_t* qclass, int nolock)
{
return name_tree_next_root(&hints->tree, qclass);
int ret;
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_rdlock(&hints->lock); }
ret = name_tree_next_root(&hints->tree, qclass);
if(!nolock) { lock_rw_unlock(&hints->lock); }
return ret;
}
size_t
@@ -524,40 +562,52 @@ hints_get_mem(struct iter_hints* hints)
size_t s;
struct iter_hints_stub* p;
if(!hints) return 0;
lock_rw_rdlock(&hints->lock);
s = sizeof(*hints);
RBTREE_FOR(p, struct iter_hints_stub*, &hints->tree) {
s += sizeof(*p) + delegpt_get_mem(p->dp);
}
lock_rw_unlock(&hints->lock);
return s;
}
int
hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
int noprime)
int noprime, int nolock)
{
struct iter_hints_stub *z;
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&hints->lock); }
if((z=(struct iter_hints_stub*)name_tree_find(&hints->tree,
dp->name, dp->namelen, dp->namelabs, c)) != NULL) {
(void)rbtree_delete(&hints->tree, &z->node);
hints_stub_free(z);
}
if(!hints_insert(hints, c, dp, noprime))
if(!hints_insert(hints, c, dp, noprime)) {
if(!nolock) { lock_rw_unlock(&hints->lock); }
return 0;
}
name_tree_init_parents(&hints->tree);
if(!nolock) { lock_rw_unlock(&hints->lock); }
return 1;
}
void
hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm)
hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm,
int nolock)
{
struct iter_hints_stub *z;
size_t len;
int labs = dname_count_size_labels(nm, &len);
/* lock_() calls are macros that could be nothing, surround in {} */
if(!nolock) { lock_rw_wrlock(&hints->lock); }
if(!(z=(struct iter_hints_stub*)name_tree_find(&hints->tree,
nm, len, labs, c)))
nm, len, labs, c))) {
if(!nolock) { lock_rw_unlock(&hints->lock); }
return; /* nothing to do */
}
(void)rbtree_delete(&hints->tree, &z->node);
hints_stub_free(z);
name_tree_init_parents(&hints->tree);
if(!nolock) { lock_rw_unlock(&hints->lock); }
}
+47 -7
View File
@@ -43,6 +43,7 @@
#ifndef ITERATOR_ITER_HINTS_H
#define ITERATOR_ITER_HINTS_H
#include "util/storage/dnstree.h"
#include "util/locks.h"
struct iter_env;
struct config_file;
struct delegpt;
@@ -51,6 +52,10 @@ struct delegpt;
* Iterator hints structure
*/
struct iter_hints {
/** lock on the forwards tree.
* When grabbing both this lock and the anchors.lock, this lock
* is grabbed first. */
lock_rw_type lock;
/**
* Hints are stored in this tree. Sort order is specially chosen.
* first sorted on qclass. Then on dname in nsec-like order, so that
@@ -95,42 +100,70 @@ void hints_delete(struct iter_hints* hints);
int hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg);
/**
* Find root hints for the given class.
* Find hints for the given class.
* The return value is contents of the hints structure.
* Caller should lock and unlock a readlock on the hints structure if nolock
* is set.
* Otherwise caller should unlock the readlock on the hints structure if a
* value was returned.
* @param hints: hint storage.
* @param qname: the qname that generated the delegation point.
* @param qclass: class for which root hints are requested. host order.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: NULL if no hints, or a ptr to stored hints.
*/
struct delegpt* hints_lookup_root(struct iter_hints* hints, uint16_t qclass);
struct delegpt* hints_find(struct iter_hints* hints, uint8_t* qname,
uint16_t qclass, int nolock);
/**
* Same as hints_lookup, but for the root only.
* @param hints: hint storage.
* @param qclass: class for which root hints are requested. host order.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: NULL if no hints, or a ptr to stored hints.
*/
struct delegpt* hints_find_root(struct iter_hints* hints,
uint16_t qclass, int nolock);
/**
* Find next root hints (to cycle through all root hints).
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a readlock on the hints structure.
* @param hints: hint storage
* @param qclass: class for which root hints are sought.
* 0 means give the first available root hints class.
* x means, give class x or a higher class if any.
* returns the found class in this variable.
* @param nolock: Skip locking, locking is handled by the caller.
* @return true if a root hint class is found.
* false if not root hint class is found (qclass may have been changed).
*/
int hints_next_root(struct iter_hints* hints, uint16_t* qclass);
int hints_next_root(struct iter_hints* hints, uint16_t* qclass, int nolock);
/**
* Given a qname/qclass combination, and the delegation point from the cache
* for this qname/qclass, determine if this combination indicates that a
* stub hint exists and must be primed.
* The return value is contents of the hints structure.
* Caller should lock and unlock a readlock on the hints structure if nolock
* is set.
* Otherwise caller should unlock the readlock on the hints structure if a
* value was returned.
*
* @param hints: hint storage.
* @param qname: The qname that generated the delegation point.
* @param qclass: The qclass that generated the delegation point.
* @param dp: The cache generated delegation point.
* @param nolock: Skip locking, locking is handled by the caller.
* @return: A priming delegation point if there is a stub hint that must
* be primed, otherwise null.
*/
struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
uint8_t* qname, uint16_t qclass, struct delegpt* dp);
struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
uint8_t* qname, uint16_t qclass, struct delegpt* dp, int nolock);
/**
* Get memory in use by hints
* Locks and unlocks the structure.
* @param hints: hint storage.
* @return bytes in use
*/
@@ -139,23 +172,30 @@ size_t hints_get_mem(struct iter_hints* hints);
/**
* Add stub to hints structure. For external use since it recalcs
* the tree parents.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the hints structure.
* @param hints: the hints data structure
* @param c: class of zone
* @param dp: delegation point with name and target nameservers for new
* hints stub. malloced.
* @param noprime: set noprime option to true or false on new hint stub.
* @param nolock: Skip locking, locking is handled by the caller.
* @return false on failure (out of memory);
*/
int hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
int noprime);
int noprime, int nolock);
/**
* Remove stub from hints structure. For external use since it
* recalcs the tree parents.
* Handles its own locking unless nolock is set. In that case the caller
* should lock and unlock a writelock on the hints structure.
* @param hints: the hints data structure
* @param c: class of stub zone
* @param nm: name of stub zone (in uncompressed wireformat).
* @param nolock: Skip locking, locking is handled by the caller.
*/
void hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm);
void hints_delete_stub(struct iter_hints* hints, uint16_t c,
uint8_t* nm, int nolock);
#endif /* ITERATOR_ITER_HINTS_H */
+2 -24
View File
@@ -207,28 +207,6 @@ size_t priv_get_mem(struct iter_priv* priv)
return sizeof(*priv) + regional_get_mem(priv->region);
}
/** remove RR from msgparse RRset, return true if rrset is entirely bad */
static int
remove_rr(const char* str, sldns_buffer* pkt, struct rrset_parse* rrset,
struct rr_parse* prev, struct rr_parse** rr, struct sockaddr_storage* addr, socklen_t addrlen)
{
if(verbosity >= VERB_QUERY && rrset->dname_len <= LDNS_MAX_DOMAINLEN && str) {
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
dname_pkt_copy(pkt, buf, rrset->dname);
log_name_addr(VERB_QUERY, str, buf, addr, addrlen);
}
if(prev)
prev->next = (*rr)->next;
else rrset->rr_first = (*rr)->next;
if(rrset->rr_last == *rr)
rrset->rr_last = prev;
rrset->rr_count --;
rrset->size -= (*rr)->size;
/* rr struct still exists, but is unlinked, so that in the for loop
* the rr->next works fine to continue. */
return rrset->rr_count == 0;
}
int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
struct rrset_parse* rrset)
{
@@ -261,7 +239,7 @@ int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
INET_SIZE);
memmove(&addr, &sa, len);
if(priv_lookup_addr(priv, &addr, len)) {
if(remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, &rr, &addr, len))
if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, len))
return 1;
continue;
}
@@ -284,7 +262,7 @@ int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
INET6_SIZE);
memmove(&addr, &sa, len);
if(priv_lookup_addr(priv, &addr, len)) {
if(remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, &rr, &addr, len))
if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, len))
return 1;
continue;
}
+24 -2
View File
@@ -42,6 +42,7 @@
#include "config.h"
#include "iterator/iter_resptype.h"
#include "iterator/iter_delegpt.h"
#include "iterator/iterator.h"
#include "services/cache/dns.h"
#include "util/net_help.h"
#include "util/data/dname.h"
@@ -105,7 +106,8 @@ response_type_from_cache(struct dns_msg* msg,
enum response_type
response_type_from_server(int rdset,
struct dns_msg* msg, struct query_info* request, struct delegpt* dp)
struct dns_msg* msg, struct query_info* request, struct delegpt* dp,
int* empty_nodata_found)
{
uint8_t* origzone = (uint8_t*)"\000"; /* the default */
struct ub_packed_rrset_key* s;
@@ -113,7 +115,11 @@ response_type_from_server(int rdset,
if(!msg || !request)
return RESPONSE_TYPE_THROWAWAY;
/* If the TC flag is set, the response is incomplete. Too large to
* fit even in TCP or so. Discard it, it cannot be retrieved here. */
if((msg->rep->flags & BIT_TC))
return RESPONSE_TYPE_THROWAWAY;
/* If the message is NXDOMAIN, then it answers the question. */
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
/* make sure its not recursive when we don't want it to */
@@ -280,6 +286,22 @@ response_type_from_server(int rdset,
/* If we've gotten this far, this is NOERROR/NODATA (which could
* be an entirely empty message) */
/* For entirely empty messages, try again, at first, then accept
* it it happens more. A regular noerror/nodata response has a soa
* negative ttl value in the authority section. This makes it try
* again at another authority. And decides between storing a 5 second
* empty message or a 5 second servfail response. */
if(msg->rep->an_numrrsets == 0 && msg->rep->ns_numrrsets == 0 &&
msg->rep->ar_numrrsets == 0) {
if(empty_nodata_found) {
/* detect as throwaway at first, but accept later. */
(*empty_nodata_found)++;
if(*empty_nodata_found < EMPTY_NODATA_RETRY_COUNT)
return RESPONSE_TYPE_THROWAWAY;
return RESPONSE_TYPE_ANSWER;
}
return RESPONSE_TYPE_ANSWER;
}
/* check if recursive answer; saying it has empty cache */
if( (msg->rep->flags&BIT_RA) && !(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_REC_LAME;
+3 -1
View File
@@ -119,9 +119,11 @@ enum response_type response_type_from_cache(struct dns_msg* msg,
* @param request: the request that generated the response.
* @param dp: The delegation point that was being queried
* when the response was returned.
* @param empty_nodata_found: flag to keep track of empty nodata detection.
* @return the response type (CNAME or ANSWER).
*/
enum response_type response_type_from_server(int rdset,
struct dns_msg* msg, struct query_info* request, struct delegpt* dp);
struct dns_msg* msg, struct query_info* request, struct delegpt* dp,
int* empty_nodata_found);
#endif /* ITERATOR_ITER_RESPTYPE_H */
+219 -7
View File
@@ -283,7 +283,8 @@ synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
sizeof(uint32_t)+sizeof(uint16_t)+aliaslen);
if(!cn->rr_first->ttl_data)
return NULL;
sldns_write_uint32(cn->rr_first->ttl_data, 0); /* TTL = 0 */
memmove(cn->rr_first->ttl_data, rrset->rr_first->ttl_data,
sizeof(uint32_t)); /* RFC6672: synth CNAME TTL == DNAME TTL */
sldns_write_uint16(cn->rr_first->ttl_data+4, aliaslen);
memmove(cn->rr_first->ttl_data+6, alias, aliaslen);
cn->rr_first->size = sizeof(uint16_t)+aliaslen;
@@ -346,6 +347,67 @@ soa_in_auth(struct msg_parse* msg)
return 0;
}
/** Check if type is allowed in the authority section */
static int
type_allowed_in_authority_section(uint16_t tp)
{
if(tp == LDNS_RR_TYPE_SOA || tp == LDNS_RR_TYPE_NS ||
tp == LDNS_RR_TYPE_DS || tp == LDNS_RR_TYPE_NSEC ||
tp == LDNS_RR_TYPE_NSEC3)
return 1;
return 0;
}
/** Check if type is allowed in the additional section */
static int
type_allowed_in_additional_section(uint16_t tp)
{
if(tp == LDNS_RR_TYPE_A || tp == LDNS_RR_TYPE_AAAA)
return 1;
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
@@ -355,15 +417,18 @@ soa_in_auth(struct msg_parse* msg)
* @param msg: msg to normalize.
* @param qinfo: original query.
* @param region: where to allocate synthesized CNAMEs.
* @param env: module env with config options.
* @return 0 on error.
*/
static int
scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, struct regional* region)
struct query_info* qinfo, struct regional* region,
struct module_env* env)
{
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)
@@ -378,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,
@@ -397,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 */
@@ -437,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 &&
@@ -484,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;
}
@@ -499,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 */
@@ -511,6 +597,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
/* Mark additional names from AUTHORITY */
while(rrset && rrset->section == LDNS_SECTION_AUTHORITY) {
/* protect internals of recursor by making sure to del these */
if(rrset->type==LDNS_RR_TYPE_DNAME ||
rrset->type==LDNS_RR_TYPE_CNAME ||
rrset->type==LDNS_RR_TYPE_A ||
@@ -519,6 +606,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* Allowed list of types in the authority section */
if(env->cfg->harden_unknown_additional &&
!type_allowed_in_authority_section(rrset->type)) {
remove_rrset("normalize: removing irrelevant "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* only one NS set allowed in authority section */
if(rrset->type==LDNS_RR_TYPE_NS) {
/* NS set must be pertinent to the query */
@@ -547,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 */
@@ -576,7 +689,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
* found in ANSWER and AUTHORITY. */
/* These records have not been marked OK previously */
while(rrset && rrset->section == LDNS_SECTION_ADDITIONAL) {
/* FIXME: what about other types? */
if(rrset->type==LDNS_RR_TYPE_A ||
rrset->type==LDNS_RR_TYPE_AAAA)
{
@@ -589,6 +701,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
}
/* protect internals of recursor by making sure to del these */
if(rrset->type==LDNS_RR_TYPE_DNAME ||
rrset->type==LDNS_RR_TYPE_CNAME ||
rrset->type==LDNS_RR_TYPE_NS) {
@@ -596,6 +709,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* Allowed list of types in the additional section */
if(env->cfg->harden_unknown_additional &&
!type_allowed_in_additional_section(rrset->type)) {
remove_rrset("normalize: removing irrelevant "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
prev = rrset;
rrset = rrset->rrset_all_next;
}
@@ -679,6 +799,56 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
return 0;
}
/** Remove individual RRs, if the length is wrong. Returns true if the RRset
* has been removed. */
static int
scrub_sanitize_rr_length(sldns_buffer* pkt, struct msg_parse* msg,
struct rrset_parse* prev, struct rrset_parse** rrset, int* added_ede,
struct module_qstate* qstate)
{
struct rr_parse* rr, *rr_prev = NULL;
for(rr = (*rrset)->rr_first; rr; rr = rr->next) {
/* Sanity check for length of records
* An A record should be 6 bytes only
* (2 bytes for length and 4 for IPv4 addr)*/
if((*rrset)->type == LDNS_RR_TYPE_A && rr->size != 6 ) {
if(!*added_ede) {
*added_ede = 1;
errinf_ede(qstate, "sanitize: records of inappropriate length have been removed.",
LDNS_EDE_OTHER);
}
if(msgparse_rrset_remove_rr("sanitize: removing type A RR of inappropriate length:",
pkt, *rrset, rr_prev, rr, NULL, 0)) {
remove_rrset("sanitize: removing type A RRset of inappropriate length:",
pkt, msg, prev, rrset);
return 1;
}
continue;
}
/* Sanity check for length of records
* An AAAA record should be 18 bytes only
* (2 bytes for length and 16 for IPv6 addr)*/
if((*rrset)->type == LDNS_RR_TYPE_AAAA && rr->size != 18 ) {
if(!*added_ede) {
*added_ede = 1;
errinf_ede(qstate, "sanitize: records of inappropriate length have been removed.",
LDNS_EDE_OTHER);
}
if(msgparse_rrset_remove_rr("sanitize: removing type AAAA RR of inappropriate length:",
pkt, *rrset, rr_prev, rr, NULL, 0)) {
remove_rrset("sanitize: removing type AAAA RRset of inappropriate length:",
pkt, msg, prev, rrset);
return 1;
}
continue;
}
rr_prev = rr;
}
return 0;
}
/**
* Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects
@@ -691,15 +861,18 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
* @param zonename: name of server zone.
* @param env: module environment with config and cache.
* @param ie: iterator environment with private address data.
* @param qstate: for setting errinf for EDE error messages.
* @return 0 on error.
*/
static int
scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie)
struct iter_env* ie, struct module_qstate* qstate)
{
int 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;
rrset = msg->rrset_first;
@@ -744,6 +917,14 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = msg->rrset_first;
while(rrset) {
/* Sanity check for length of records */
if(rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA) {
if(scrub_sanitize_rr_length(pkt, msg, prev, &rrset,
&added_rrlen_ede, qstate))
continue;
}
/* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA)) {
@@ -796,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);
@@ -808,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;
}
@@ -817,7 +1028,8 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
int
scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct regional* region,
struct module_env* env, struct iter_env* ie)
struct module_env* env, struct module_qstate* qstate,
struct iter_env* ie)
{
/* basic sanity checks */
log_nametypeclass(VERB_ALGO, "scrub for", zonename, LDNS_RR_TYPE_NS,
@@ -846,10 +1058,10 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
}
/* normalize the response, this cleans up the additional. */
if(!scrub_normalize(pkt, msg, qinfo, region))
if(!scrub_normalize(pkt, msg, qinfo, region, env))
return 0;
/* delete all out-of-zone information */
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie))
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate))
return 0;
return 1;
}
+4 -1
View File
@@ -48,6 +48,7 @@ struct query_info;
struct regional;
struct module_env;
struct iter_env;
struct module_qstate;
/**
* Cleanup the passed dns message.
@@ -59,11 +60,13 @@ struct iter_env;
* Used to determine out of bailiwick information.
* @param regional: where to allocate (new) parts of the message.
* @param env: module environment with config settings and cache.
* @param qstate: for setting errinf for EDE error messages.
* @param ie: iterator module environment data.
* @return: false if the message is total waste. true if scrubbed with success.
*/
int scrub_message(struct sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct regional* regional,
struct module_env* env, struct iter_env* ie);
struct module_env* env, struct module_qstate* qstate,
struct iter_env* ie);
#endif /* ITERATOR_ITER_SCRUB_H */
+136 -16
View File
@@ -71,6 +71,11 @@
/** time when nameserver glue is said to be 'recent' */
#define SUSPICION_RECENT_EXPIRY 86400
/** if NAT64 is enabled and no NAT64 prefix is configured, first fall back to
* DNS64 prefix. If that is not configured, fall back to this default value.
*/
static const char DEFAULT_NAT64_PREFIX[] = "64:ff9b::/96";
/** fillup fetch policy array */
static void
fetch_fill(struct iter_env* ie, const char* str)
@@ -142,6 +147,7 @@ caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
int
iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
{
const char *nat64_prefix;
int i;
/* target fetch policy */
if(!read_fetch_policy(iter_env, cfg->target_fetch_policy))
@@ -172,9 +178,35 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
}
nat64_prefix = cfg->nat64_prefix;
if(!nat64_prefix)
nat64_prefix = cfg->dns64_prefix;
if(!nat64_prefix)
nat64_prefix = DEFAULT_NAT64_PREFIX;
if(!netblockstrtoaddr(nat64_prefix, 0, &iter_env->nat64_prefix_addr,
&iter_env->nat64_prefix_addrlen,
&iter_env->nat64_prefix_net)) {
log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix);
return 0;
}
if(!addr_is_ip6(&iter_env->nat64_prefix_addr,
iter_env->nat64_prefix_addrlen)) {
log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix);
return 0;
}
if(!prefixnet_is_nat64(iter_env->nat64_prefix_net)) {
log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
nat64_prefix);
return 0;
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->use_nat64 = cfg->do_nat64;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
return 1;
}
@@ -238,7 +270,8 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip6 available */
}
if(!iter_env->supports_ipv4 && !addr_is_ip6(&a->addr, a->addrlen)) {
if(!iter_env->supports_ipv4 && !iter_env->use_nat64 &&
!addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip4 available */
}
/* check lameness - need zone , class info */
@@ -246,9 +279,10 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
name, namelen, qtype, &lame, &dnsseclame, &reclame,
&rtt, now)) {
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
verbose(VERB_ALGO, " rtt=%d%s%s%s%s", rtt,
verbose(VERB_ALGO, " rtt=%d%s%s%s%s%s", rtt,
lame?" LAME":"",
dnsseclame?" DNSSEC_LAME":"",
a->dnsseclame?" ADDR_DNSSEC_LAME":"",
reclame?" REC_LAME":"",
a->lame?" ADDR_LAME":"");
if(lame)
@@ -745,10 +779,15 @@ iter_mark_pside_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
int
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp, int supports_ipv4, int supports_ipv6)
struct delegpt* dp, int supports_ipv4, int supports_ipv6,
int use_nat64)
{
struct delegpt_ns* ns;
struct delegpt_addr* a;
if(supports_ipv6 && use_nat64)
supports_ipv4 = 1;
/* check:
* o RD qflag is on.
* o no addresses are provided.
@@ -1246,8 +1285,17 @@ iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
uint16_t* c)
{
uint16_t c1 = *c, c2 = *c;
int r1 = hints_next_root(hints, &c1);
int r2 = forwards_next_root(fwd, &c2);
int r1, r2;
int nolock = 1;
/* prelock both forwards and hints for atomic read. */
lock_rw_rdlock(&fwd->lock);
lock_rw_rdlock(&hints->lock);
r1 = hints_next_root(hints, &c1, nolock);
r2 = forwards_next_root(fwd, &c2, nolock);
lock_rw_unlock(&fwd->lock);
lock_rw_unlock(&hints->lock);
if(!r1 && !r2) /* got none, end of list */
return 0;
else if(!r1) /* got one, return that */
@@ -1308,8 +1356,7 @@ void iter_dec_attempts(struct delegpt* dp, int d, int outbound_msg_retry)
for(a=dp->target_list; a; a = a->next_target) {
if(a->attempts >= outbound_msg_retry) {
/* add back to result list */
a->next_result = dp->result_list;
dp->result_list = a;
delegpt_add_to_result_list(dp, a);
}
if(a->attempts > d)
a->attempts -= d;
@@ -1413,15 +1460,21 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp)
int
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
uint8_t** retdpname, size_t* retdpnamelen)
uint8_t** retdpname, size_t* retdpnamelen, uint8_t* dpname_storage,
size_t dpname_storage_len)
{
struct iter_hints_stub *stub;
struct delegpt *dp;
int nolock = 1;
/* Check for stub. */
/* Lock both forwards and hints for atomic read. */
lock_rw_rdlock(&qstate->env->fwds->lock);
lock_rw_rdlock(&qstate->env->hints->lock);
stub = hints_lookup_stub(qstate->env->hints, qinf->qname,
qinf->qclass, NULL);
dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass);
qinf->qclass, NULL, nolock);
dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass,
nolock);
/* see if forward or stub is more pertinent */
if(stub && stub->dp && dp) {
@@ -1435,7 +1488,9 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* check stub */
if (stub != NULL && stub->dp != NULL) {
if(stub->dp->no_cache) {
int stub_no_cache = stub->dp->no_cache;
lock_rw_unlock(&qstate->env->fwds->lock);
if(stub_no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
@@ -1443,15 +1498,27 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
}
if(retdpname) {
*retdpname = stub->dp->name;
if(stub->dp->namelen > dpname_storage_len) {
verbose(VERB_ALGO, "no cache stub dpname too long");
lock_rw_unlock(&qstate->env->hints->lock);
*retdpname = NULL;
*retdpnamelen = 0;
return stub_no_cache;
}
memmove(dpname_storage, stub->dp->name,
stub->dp->namelen);
*retdpname = dpname_storage;
*retdpnamelen = stub->dp->namelen;
}
return (stub->dp->no_cache);
lock_rw_unlock(&qstate->env->hints->lock);
return stub_no_cache;
}
/* Check for forward. */
if (dp) {
if(dp->no_cache) {
int dp_no_cache = dp->no_cache;
lock_rw_unlock(&qstate->env->hints->lock);
if(dp_no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
@@ -1459,11 +1526,22 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
}
if(retdpname) {
*retdpname = dp->name;
if(dp->namelen > dpname_storage_len) {
verbose(VERB_ALGO, "no cache dpname too long");
lock_rw_unlock(&qstate->env->fwds->lock);
*retdpname = NULL;
*retdpnamelen = 0;
return dp_no_cache;
}
memmove(dpname_storage, dp->name, dp->namelen);
*retdpname = dpname_storage;
*retdpnamelen = dp->namelen;
}
return (dp->no_cache);
lock_rw_unlock(&qstate->env->fwds->lock);
return dp_no_cache;
}
lock_rw_unlock(&qstate->env->fwds->lock);
lock_rw_unlock(&qstate->env->hints->lock);
if(retdpname) {
*retdpname = NULL;
*retdpnamelen = 0;
@@ -1486,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;
}
}
}
}
+17 -3
View File
@@ -189,10 +189,13 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
* if not, then the IPv4 addresses are useless.
* @param supports_ipv6: if we support ipv6 for lookups to the target.
* if not, then the IPv6 addresses are useless.
* @param use_nat64: if we support NAT64 for lookups to the target.
* if yes, IPv4 addresses are useful even if we don't support IPv4.
* @return true if dp is useless.
*/
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp, int supports_ipv4, int supports_ipv6);
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp, int supports_ipv4, int supports_ipv6,
int use_nat64);
/**
* See if qname has DNSSEC needs. This is true if there is a trust anchor above
@@ -404,10 +407,14 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
* Used for NXDOMAIN checks, above that it is an nxdomain from a
* different server and zone. You can pass NULL to not get it.
* @param retdpnamelen: returns the length of the dpname.
* @param dpname_storage: this is where the dpname buf is stored, if any.
* So that caller can manage the buffer.
* @param dpname_storage_len: size of dpname_storage buffer.
* @return true if no_cache is set in stub or fwd.
*/
int iter_stub_fwd_no_cache(struct module_qstate *qstate,
struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen);
struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen,
uint8_t* dpname_storage, size_t dpname_storage_len);
/**
* Set support for IP4 and IP6 depending on outgoing interfaces
@@ -421,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 */
+591 -228
View File
File diff suppressed because it is too large Load Diff
+41 -7
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
@@ -63,12 +66,8 @@ struct rbtree_type;
/** max number of nxdomains allowed for target lookups for a query and
* its subqueries when fallback has kicked in */
#define MAX_TARGET_NX_FALLBACK (MAX_TARGET_NX*2)
/** max number of query restarts. Determines max number of CNAME chain. */
#define MAX_RESTART_COUNT 11
/** max number of referrals. Makes sure resolver does not run away */
#define MAX_REFERRAL_COUNT 130
/** max number of queries-sent-out. Make sure large NS set does not loop */
#define MAX_SENT_COUNT 32
/** max number of queries for which to perform dnsseclameness detection,
* (rrsigs missing detection) after that, just pick up that response */
#define DNSSEC_LAME_DETECT_COUNT 4
@@ -105,9 +104,11 @@ extern int BLACKLIST_PENALTY;
* Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a
* fast server, this causes server exploration as a side benefit. msec. */
#define RTT_BAND 400
/** Number of retries for empty nodata packets before it is accepted. */
#define EMPTY_NODATA_RETRY_COUNT 2
/**
* Global state for the iterator.
* Global state for the iterator.
*/
struct iter_env {
/** A flag to indicate whether or not we have an IPv6 route */
@@ -116,6 +117,18 @@ struct iter_env {
/** A flag to indicate whether or not we have an IPv4 route */
int supports_ipv4;
/** A flag to locally apply NAT64 to make IPv4 addrs into IPv6 */
int use_nat64;
/** NAT64 prefix address, cf. dns64_env->prefix_addr */
struct sockaddr_storage nat64_prefix_addr;
/** sizeof(sockaddr_in6) */
socklen_t nat64_prefix_addrlen;
/** CIDR mask length of NAT64 prefix */
int nat64_prefix_net;
/** A set of inetaddrs that should never be queried. */
struct iter_donotq* donotq;
@@ -145,6 +158,12 @@ struct iter_env {
/** number of retries on outgoing queries */
int outbound_msg_retry;
/** number of queries_sent */
int max_sent_count;
/** max number of query restarts to limit length of CNAME chain */
int max_query_restarts;
};
/**
@@ -232,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,
@@ -324,7 +346,7 @@ struct iter_qstate {
/** the number of times this query has been restarted. */
int query_restart_count;
/** the number of times this query as followed a referral. */
/** the number of times this query has followed a referral. */
int referral_count;
/** number of queries fired off */
@@ -401,6 +423,11 @@ struct iter_qstate {
*/
int refetch_glue;
/**
* This flag detects that a completely empty nodata was received,
* already so that it is accepted later. */
int empty_nodata_found;
/** list of pending queries to authoritative servers. */
struct outbound_list outlist;
@@ -437,7 +464,14 @@ struct iter_qstate {
/** true if there have been parse failures of reply packets */
int parse_failures;
/** a failure printout address for last received answer */
struct comm_reply* fail_reply;
union {
struct in_addr in;
#ifdef AF_INET6
struct in6_addr in6;
#endif
} fail_addr;
/** which fail_addr, 0 is nothing, 4 or 6 */
int fail_addr_type;
};
/**
+13 -2
View File
@@ -53,6 +53,8 @@
#include "util/storage/slabhash.h"
#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
int
context_finalize(struct ub_ctx* ctx)
@@ -70,9 +72,12 @@ context_finalize(struct ub_ctx* ctx)
} else {
log_init(cfg->logfile, cfg->use_syslog, NULL);
}
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);
@@ -84,6 +89,12 @@ context_finalize(struct ub_ctx* ctx)
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
ctx->env, &ctx->mods))
return UB_INITFAIL;
if(!(ctx->env->fwds = forwards_create()) ||
!forwards_apply_cfg(ctx->env->fwds, cfg))
return UB_INITFAIL;
if(!(ctx->env->hints = hints_create()) ||
!hints_apply_cfg(ctx->env->hints, cfg))
return UB_INITFAIL;
if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
@@ -384,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);
+6
View File
@@ -89,6 +89,12 @@ struct ub_ctx {
pid_t bg_pid;
/** tid of bg worker thread */
ub_thread_type bg_tid;
/** pid when pipes are created. This was the process when the
* setup was called. Helps with clean up, so we can tell after a fork
* which side of the fork the delete is on. */
pid_t pipe_pid;
/** when threaded, the worker that exists in the created thread. */
struct libworker* thread_worker;
/** do threading (instead of forking) for async resolution */
int dothread;
+59 -8
View File
@@ -66,6 +66,8 @@
#include "services/authzone.h"
#include "services/listen_dnsport.h"
#include "sldns/sbuffer.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#ifdef HAVE_PTHREAD
#include <signal.h>
#endif
@@ -171,6 +173,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
ctx->env->worker = NULL;
ctx->env->need_to_validate = 0;
modstack_init(&ctx->mods);
ctx->env->modstack = &ctx->mods;
rbtree_init(&ctx->queries, &context_query_cmp);
return ctx;
}
@@ -185,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);
@@ -199,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);
@@ -305,11 +312,31 @@ ub_ctx_delete(struct ub_ctx* ctx)
int do_stop = 1;
if(!ctx) return;
/* if the delete is called but it has forked, and before the fork
* the context was finalized, then the bg worker is not stopped
* from here. There is one worker, but two contexts that refer to
* it and only one should clean up, the one with getpid == pipe_pid.*/
if(ctx->created_bg && ctx->pipe_pid != getpid()) {
do_stop = 0;
#ifndef USE_WINSOCK
/* Stop events from getting deregistered, if the backend is
* epoll, the epoll fd is the same as the other process.
* That process should deregister them. */
if(ctx->qq_pipe->listen_com)
ctx->qq_pipe->listen_com->event_added = 0;
if(ctx->qq_pipe->res_com)
ctx->qq_pipe->res_com->event_added = 0;
if(ctx->rr_pipe->listen_com)
ctx->rr_pipe->listen_com->event_added = 0;
if(ctx->rr_pipe->res_com)
ctx->rr_pipe->res_com->event_added = 0;
#endif
}
/* see if bg thread is created and if threads have been killed */
/* no locks, because those may be held by terminated threads */
/* for processes the read pipe is closed and we see that on read */
#ifdef HAVE_PTHREAD
if(ctx->created_bg && ctx->dothread) {
if(ctx->created_bg && ctx->dothread && do_stop) {
if(pthread_kill(ctx->bg_tid, 0) == ESRCH) {
/* thread has been killed */
do_stop = 0;
@@ -318,9 +345,28 @@ ub_ctx_delete(struct ub_ctx* ctx)
#endif /* HAVE_PTHREAD */
if(do_stop)
ub_stop_bg(ctx);
if(ctx->created_bg && ctx->pipe_pid != getpid() && ctx->thread_worker) {
/* This delete is happening from a different process. Delete
* the thread worker from this process memory space. The
* thread is not there to do so, so it is freed here. */
struct ub_event_base* evbase = comm_base_internal(
ctx->thread_worker->base);
libworker_delete_event(ctx->thread_worker);
ctx->thread_worker = NULL;
#ifdef USE_MINI_EVENT
ub_event_base_free(evbase);
#else
/* cannot event_base_free, because the epoll_fd cleanup
* in libevent could stop the original event_base in the
* other process from working. */
free(evbase);
#endif
}
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;
@@ -342,6 +388,8 @@ ub_ctx_delete(struct ub_ctx* ctx)
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_strings_delete(ctx->env->edns_strings);
forwards_delete(ctx->env->fwds);
hints_delete(ctx->env->hints);
auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}
@@ -939,7 +987,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
if(!addr) {
/* disable fwd mode - the root stub should be first. */
if(ctx->env->cfg->forwards &&
strcmp(ctx->env->cfg->forwards->name, ".") == 0) {
(ctx->env->cfg->forwards->name &&
strcmp(ctx->env->cfg->forwards->name, ".") == 0)) {
s = ctx->env->cfg->forwards;
ctx->env->cfg->forwards = s->next;
s->next = NULL;
@@ -951,7 +1000,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
lock_basic_unlock(&ctx->cfglock);
/* check syntax for addr */
if(!extstrtoaddr(addr, &storage, &stlen)) {
if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) {
errno=EINVAL;
return UB_SYNTAX;
}
@@ -959,7 +1008,8 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
/* it parses, add root stub in front of list */
lock_basic_lock(&ctx->cfglock);
if(!ctx->env->cfg->forwards ||
strcmp(ctx->env->cfg->forwards->name, ".") != 0) {
(ctx->env->cfg->forwards->name &&
strcmp(ctx->env->cfg->forwards->name, ".") != 0)) {
s = calloc(1, sizeof(*s));
if(!s) {
lock_basic_unlock(&ctx->cfglock);
@@ -977,6 +1027,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
ctx->env->cfg->forwards = s;
} else {
log_assert(ctx->env->cfg->forwards);
log_assert(ctx->env->cfg->forwards->name);
s = ctx->env->cfg->forwards;
}
dupl = strdup(addr);
@@ -1031,7 +1082,7 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
if(addr) {
struct sockaddr_storage storage;
socklen_t stlen;
if(!extstrtoaddr(addr, &storage, &stlen)) {
if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) {
errno=EINVAL;
return UB_SYNTAX;
}
+31 -24
View File
@@ -62,6 +62,7 @@
#include "util/random.h"
#include "util/config_file.h"
#include "util/netevent.h"
#include "util/proxy_protocol.h"
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/net_help.h"
@@ -69,8 +70,6 @@
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "util/tube.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#ifdef USE_DNSTAP
@@ -99,8 +98,6 @@ libworker_delete_env(struct libworker* w)
!w->is_bg || w->is_bg_thread);
sldns_buffer_free(w->env->scratch_buffer);
regional_destroy(w->env->scratch);
forwards_delete(w->env->fwds);
hints_delete(w->env->hints);
ub_randfree(w->env->rnd);
free(w->env);
}
@@ -158,30 +155,19 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
}
w->env->scratch = regional_create_custom(cfg->msg_buffer_size);
w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
w->env->fwds = forwards_create();
if(w->env->fwds && !forwards_apply_cfg(w->env->fwds, cfg)) {
forwards_delete(w->env->fwds);
w->env->fwds = NULL;
}
w->env->hints = hints_create();
if(w->env->hints && !hints_apply_cfg(w->env->hints, cfg)) {
hints_delete(w->env->hints);
w->env->hints = NULL;
}
if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) {
w->sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert);
if(!w->sslctx) {
/* to make the setup fail after unlock */
hints_delete(w->env->hints);
w->env->hints = NULL;
}
#ifdef HAVE_SSL
w->sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert);
if(!w->sslctx) {
/* to make the setup fail after unlock */
sldns_buffer_free(w->env->scratch_buffer);
w->env->scratch_buffer = NULL;
}
#endif
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
}
if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds ||
!w->env->hints) {
if(!w->env->scratch || !w->env->scratch_buffer) {
libworker_delete(w);
return NULL;
}
@@ -265,6 +251,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
w->env->kill_sub = &mesh_state_delete;
w->env->detect_cycle = &mesh_detect_cycle;
comm_base_timept(w->base, &w->env->now, &w->env->now_tv);
pp_init(&sldns_write_uint16, &sldns_write_uint32);
return w;
}
@@ -305,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);
@@ -395,6 +383,7 @@ int libworker_bg(struct ub_ctx* ctx)
w = libworker_setup(ctx, 1, NULL);
if(!w) return UB_NOMEM;
w->is_bg_thread = 1;
ctx->thread_worker = w;
#ifdef ENABLE_LOCK_CHECKS
w->thread_num = 1; /* for nicer DEBUG checklocks */
#endif
@@ -604,6 +593,8 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
edns->opt_list_out = NULL;
edns->opt_list_inplace_cb_out = NULL;
edns->padding_block_size = 0;
edns->cookie_present = 0;
edns->cookie_valid = 0;
if(sldns_buffer_capacity(w->back->udp_buff) < 65535)
edns->udp_size = (uint16_t)sldns_buffer_capacity(
w->back->udp_buff);
@@ -1067,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")
+6
View File
@@ -36,6 +36,9 @@
%begin %{
/* store state of warning output, restored at later pop */
#pragma GCC diagnostic push
/* ignore warnings for pragma below, where for older GCC it can produce a
warning if the cast-function-type warning is absent. */
#pragma GCC diagnostic ignored "-Wpragmas"
/* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
#pragma GCC diagnostic ignored "-Wcast-function-type"
%}
@@ -860,6 +863,9 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
%inline %{
//SWIG will see the ub_ctx as a class
struct ub_ctx {
/* Dummy member, so the struct is not empty, MSVC complains about
* that. */
int dummy;
};
%}
+5 -4
View File
@@ -52,8 +52,8 @@
* unbound was compiled with, otherwise it wouldn't work, the event and
* event_base structures would be different.
*/
#ifndef _UB_UNBOUND_EVENT_H
#define _UB_UNBOUND_EVENT_H
#ifndef UB_UNBOUND_EVENT_H
#define UB_UNBOUND_EVENT_H
#ifdef __cplusplus
extern "C" {
@@ -230,7 +230,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
* @param callback: this is called on completion of the resolution.
* It is called as:
* void callback(void* mydata, int rcode, void* packet, int packet_len,
* int sec, char* why_bogus)
* int sec, char* why_bogus, int was_ratelimited)
* with mydata: the same as passed here, you may pass NULL,
* with rcode: 0 on no error, nonzero for mostly SERVFAIL situations,
* this is a DNS rcode.
@@ -241,6 +241,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
* with packet_len: length in bytes of the packet buffer.
* with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure.
* with why_bogus: text string explaining why it is bogus (or NULL).
* with was_ratelimited: if the query was ratelimited.
* These point to buffers inside unbound; do not deallocate the packet or
* error string.
*
@@ -261,4 +262,4 @@ int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
}
#endif
#endif /* _UB_UNBOUND_H */
#endif /* UB_UNBOUND_EVENT_H */
+70 -50
View File
@@ -4,22 +4,22 @@
* Copyright (c) 2007, 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
@@ -36,7 +36,7 @@
/**
* \file
*
* This file contains functions to resolve DNS queries and
* This file contains functions to resolve DNS queries and
* validate the answers. Synchronously and asynchronously.
*
* Several ways to use this interface from an application wishing
@@ -65,7 +65,7 @@
* ... or process() calls my_callback() with results.
*
* ... if the application has nothing more to do, wait for answer
* ub_wait(ctx);
* ub_wait(ctx);
*
* Application threaded. Blocking.
* Blocking, same as above. The current thread does the work.
@@ -83,7 +83,7 @@
* CRYPTO_set_id_callback and CRYPTO_set_locking_callback.
*
* If no threading is compiled in, the above async example uses fork(2) to
* create a process to perform the work. The forked process exits when the
* create a process to perform the work. The forked process exits when the
* calling process exits, or ctx_delete() is called.
* Otherwise, for asynchronous with threading, a worker thread is created.
*
@@ -94,8 +94,8 @@
* The second calls another worker thread (or process) to perform the work.
* And no buffers need to be set up, but a context-switch happens.
*/
#ifndef _UB_UNBOUND_H
#define _UB_UNBOUND_H
#ifndef UB_UNBOUND_H
#define UB_UNBOUND_H
#ifdef __cplusplus
extern "C" {
@@ -128,10 +128,10 @@ struct ub_result {
/** the class asked for */
int qclass;
/**
* a list of network order DNS rdata items, terminated with a
/**
* a list of network order DNS rdata items, terminated with a
* NULL pointer, so that data[0] is the first result entry,
* data[1] the second, and the last entry is NULL.
* data[1] the second, and the last entry is NULL.
* If there was no data, data[0] is NULL.
*/
char** data;
@@ -139,8 +139,8 @@ struct ub_result {
/** the length in bytes of the data items, len[i] for data[i] */
int* len;
/**
* canonical name for the result (the final cname).
/**
* canonical name for the result (the final cname).
* zero terminated string.
* May be NULL if no canonical name exists.
*/
@@ -165,9 +165,9 @@ struct ub_result {
*/
int havedata;
/**
/**
* If there was no data, and the domain did not exist, this is true.
* If it is false, and there was no data, then the domain name
* If it is false, and there was no data, then the domain name
* is purported to exist, but the requested data type is not available.
*/
int nxdomain;
@@ -182,19 +182,19 @@ struct ub_result {
*/
int secure;
/**
* If the result was not secure (secure==0), and this result is due
/**
* If the result was not secure (secure==0), and this result is due
* to a security failure, bogus is true.
* This means the data has been actively tampered with, signatures
* failed, expected signatures were not present, timestamps on
* failed, expected signatures were not present, timestamps on
* signatures were out of date and so on.
*
* If !secure and !bogus, this can happen if the data is not secure
* because security is disabled for that domain name.
* If !secure and !bogus, this can happen if the data is not secure
* because security is disabled for that domain name.
* This means the data is from a domain where data is not signed.
*/
int bogus;
/**
* If the result is bogus this contains a string (zero terminated)
* that describes the failure. There may be other errors as well
@@ -222,7 +222,7 @@ struct ub_result {
* The readable function definition looks like:
* void my_callback(void* my_arg, int err, struct ub_result* result);
* It is called with
* void* my_arg: your pointer to a (struct of) data of your choice,
* void* my_arg: your pointer to a (struct of) data of your choice,
* or NULL.
* int err: if 0 all is OK, otherwise an error occurred and no results
* are forthcoming.
@@ -301,8 +301,8 @@ int ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val);
* This is a power-users interface that lets you specify all sorts
* of options.
* @param str: the string is malloced and returned here. NULL on error.
* The caller must free() the string. In cases with multiple
* entries (auto-trust-anchor-file), a newline delimited list is
* The caller must free() the string. In cases with multiple
* entries (auto-trust-anchor-file), a newline delimited list is
* returned in the string.
* @return 0 if OK else an error code (malloc failure, syntax error).
*/
@@ -321,10 +321,10 @@ int ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str);
int ub_ctx_config(struct ub_ctx* ctx, const char* fname);
/**
* Set machine to forward DNS queries to, the caching resolver to use.
* IP4 or IP6 address. Forwards all DNS requests to that machine, which
* is expected to run a recursive resolver. If the proxy is not
* DNSSEC-capable, validation may fail. Can be called several times, in
* Set machine to forward DNS queries to, the caching resolver to use.
* IP4 or IP6 address. Forwards all DNS requests to that machine, which
* is expected to run a recursive resolver. If the proxy is not
* DNSSEC-capable, validation may fail. Can be called several times, in
* that case the addresses are used as backup servers.
*
* To read the list of nameservers from /etc/resolv.conf (from DHCP or so),
@@ -389,7 +389,7 @@ int ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname);
/**
* Read list of hosts from the filename given.
* Usually "/etc/hosts".
* Usually "/etc/hosts".
* These addresses are not flagged as DNSSEC secure when queried for.
*
* @param ctx: context.
@@ -403,7 +403,7 @@ int ub_ctx_hosts(struct ub_ctx* ctx, const char* fname);
/**
* Add a trust anchor to the given context.
* The trust anchor is a string, on one line, that holds a valid DNSKEY or
* DS RR.
* DS RR.
* @param ctx: context.
* At this time it is only possible to add trusted keys before the
* first resolve is done.
@@ -465,7 +465,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out);
* Set debug verbosity for the context
* Output is directed to stderr.
* @param ctx: context.
* @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed,
* @param d: debug level, 0 is off, 1 is very minimal, 2 is detailed,
* and 3 is lots.
* @return 0 if OK, else error.
*/
@@ -474,10 +474,10 @@ int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
/**
* Set a context behaviour for asynchronous action.
* @param ctx: context.
* @param dothread: if true, enables threading and a call to resolve_async()
* @param dothread: if true, enables threading and a call to resolve_async()
* creates a thread to handle work in the background.
* If false, a process is forked to handle work in the background.
* Changes to this setting after async() calls have been made have
* Changes to this setting after async() calls have been made have
* no effect (delete and re-create the context to change).
* @return 0 if OK, else error.
*/
@@ -495,7 +495,7 @@ int ub_poll(struct ub_ctx* ctx);
/**
* Wait for a context to finish with results. Calls ub_process() after
* the wait for you. After the wait, there are no more outstanding
* the wait for you. After the wait, there are no more outstanding
* asynchronous queries.
* @param ctx: context.
* @return: 0 if OK, else error.
@@ -530,11 +530,11 @@ int ub_process(struct ub_ctx* ctx);
* @param rrtype: type of RR in host order, 1 is A (address).
* @param rrclass: class of RR in host order, 1 is IN (for internet).
* @param result: the result data is returned in a newly allocated result
* structure. May be NULL on return, return value is set to an error
* structure. May be NULL on return, return value is set to an error
* in that case (out of memory).
* @return 0 if OK, else error.
*/
int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, struct ub_result** result);
/**
@@ -561,11 +561,11 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
* If an error happens during processing, your callback will be called
* with error set to a nonzero value (and result==NULL).
* @param async_id: if you pass a non-NULL value, an identifier number is
* returned for the query as it is in progress. It can be used to
* returned for the query as it is in progress. It can be used to
* cancel the query.
* @return 0 if OK, else error.
*/
int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_callback_type callback, int* async_id);
/**
@@ -589,7 +589,7 @@ int ub_cancel(struct ub_ctx* ctx, int async_id);
*/
void ub_resolve_free(struct ub_result* result);
/**
/**
* Convert error value to a human readable string.
* @param err: error code from one of the libunbound functions.
* The error codes are from the type enum ub_ctx_err.
@@ -605,7 +605,7 @@ const char* ub_strerror(int err);
int ub_ctx_print_local_zones(struct ub_ctx* ctx);
/**
* Add a new zone with the zonetype to the local authority info of the
* Add a new zone with the zonetype to the local authority info of the
* library.
* @param ctx: context. Is finalized by the routine.
* @param zone_name: name of the zone in text, "example.com"
@@ -613,7 +613,7 @@ int ub_ctx_print_local_zones(struct ub_ctx* ctx);
* @param zone_type: type of the zone (like for unbound.conf) in text.
* @return 0 if OK, else error.
*/
int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
const char *zone_type);
/**
@@ -649,7 +649,7 @@ int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data);
*/
const char* ub_version(void);
/**
/**
* Some global statistics that are not in struct stats_info,
* this struct is shared on a shm segment (shm-key in unbound.conf)
*/
@@ -695,13 +695,22 @@ struct ub_server_stats {
long long num_queries;
/** number of queries that have been dropped/ratelimited by ip. */
long long num_queries_ip_ratelimited;
/** number of queries with a valid DNS Cookie. */
long long num_queries_cookie_valid;
/** number of queries with only the client part of the DNS Cookie. */
long long num_queries_cookie_client;
/** number of queries with invalid DNS Cookie. */
long long num_queries_cookie_invalid;
/** number of queries that had a cache-miss. */
long long num_queries_missed_cache;
/** number of prefetch queries - cachehits with prefetch */
long long num_queries_prefetch;
/** number of queries which are too late to process */
long long num_queries_timed_out;
/** the longest wait time in the queue */
long long max_query_time_us;
/**
* Sum of the querylistsize of the worker for
* Sum of the querylistsize of the worker for
* every query that missed cache. To calculate average.
*/
long long sum_query_list_size;
@@ -773,12 +782,12 @@ struct ub_server_stats {
long long tcp_accept_usage;
/** expired answers served from cache */
long long ans_expired;
/** histogram data exported to array
/** histogram data exported to array
* if the array is the same size, no data is lost, and
* if all histograms are same size (is so by default) then
* adding up works well. */
long long hist[UB_STATS_BUCKET_NUM];
/** number of message cache entries */
long long msg_cache_count;
/** number of rrset cache entries */
@@ -788,6 +797,11 @@ struct ub_server_stats {
/** number of key cache entries */
long long key_cache_count;
/** maximum number of collisions in the msg cache */
long long msg_cache_max_collisions;
/** maximum number of collisions in the rrset cache */
long long rrset_cache_max_collisions;
/** number of queries that used dnscrypt */
long long num_query_dnscrypt_crypted;
/** number of queries that queried dnscrypt certificates */
@@ -819,6 +833,8 @@ struct ub_server_stats {
/** number of queries answered from edns-subnet specific data, and
* the answer was from the edns-subnet cache. */
long long num_query_subnet_cache;
/** number of queries served from cachedb */
long long num_query_cachedb;
/** number of bytes in the stream wait buffers */
long long mem_stream_wait;
/** number of bytes in the HTTP2 query buffers */
@@ -829,9 +845,13 @@ 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;
};
/**
/**
* Statistics to send over the control pipe when asked
* This struct is made to be memcopied, sent in binary.
* shm mapped with (number+1) at num_threads+1, with first as total
@@ -860,4 +880,4 @@ struct ub_stats_info {
}
#endif
#endif /* _UB_UNBOUND_H */
#endif /* UB_UNBOUND_H */
+147 -45
View File
@@ -45,20 +45,24 @@ usage () {
Usage $0: [-h] [-s] [-u git_url] [-b git_branch] [-w ...args...]
Generate a distribution tar file for unbound.
-h This usage information.
-s Build a snapshot distribution file. The current date is
automatically appended to the current unbound version number.
-rc <nr> Build a release candidate, the given string will be added
to the version number
(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.
Detected from the working copy if not specified.
-h This usage information.
-s Build a snapshot distribution file. The current date is
automatically appended to the current unbound version number.
-rc <nr> Build a release candidate, the given string will be added
to the version number
(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 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.
-w32 32bit windows compile.
-w ... Build windows binary dist. last args passed to configure.
-wdir directory Build openssl and expat in a persistent directory for
windows dist. If builds are already in that directory
they are used right away. Useful when debuggin windows
builds.
-w32 32bit windows compile.
-w ... Build windows binary dist. last args passed to configure.
EOF
exit 1
}
@@ -143,6 +147,16 @@ create_temp_dir () {
cd $temp_dir
}
activate_windebug_dir () {
info "Activating persistent directory for windows build."
if test ! -d "$WINDIR"; then
mkdir -p "$WINDIR"
info "Created $WINDIR persistent directory."
fi
cd "$WINDIR"
WINDIR="`pwd`"
}
# pass filename as $1 arg.
# creates file.sha1 and file.sha256
storehash () {
@@ -187,7 +201,9 @@ DOWIN="no"
W64="yes"
WINSSL=""
WINEXPAT=""
MINJ=""
WINDIR=""
# Use environment if set otherwise null
MINJ="${MINJ:+$MINJ}"
# Parse the command line arguments.
while [ "$1" ]; do
@@ -214,6 +230,10 @@ while [ "$1" ]; do
WINEXPAT="$2"
shift
;;
"-wdir")
WINDIR="$2"
shift
;;
"-w32")
W64="no"
;;
@@ -253,8 +273,27 @@ if [ "$DOWIN" = "yes" ]; then
shared_cross_flag=""
check_git_repo
create_temp_dir
if test -n "$WINDIR"; then
activate_windebug_dir
else
create_temp_dir
fi
if test -n "$WINSSL" \
-a -n "$WINDIR" \
-a -d "$WINDIR" \
-a -d "${WINDIR}/sslinstall" \
-a -d "${WINDIR}/openssl_shared" \
-a -d "${WINDIR}/sslsharedinstall"; then
info "Found already compiled openssl at $WINDIR/sslinstall; using that."
WINSSL=""
# Variables needed later on.
sslinstall="${WINDIR}/sslinstall"
cross_flag="$cross_flag --with-ssl=$sslinstall"
sslsharedinstall="${WINDIR}/sslsharedinstall"
shared_cross_flag="$shared_cross_flag --with-ssl=$sslsharedinstall"
fi
# crosscompile openssl for windows.
if test -n "$WINSSL"; then
info "Cross compile $WINSSL"
@@ -267,10 +306,10 @@ if [ "$DOWIN" = "yes" ]; then
# cross-compilation and it is not used anyway
# before 1.0.1i need --cross-compile-prefix=i686-w64-mingw32-
if test "$mw64" = "mingw64"; then
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw64"
sslflags="no-asm no-tests -DOPENSSL_NO_CAPIENG mingw64"
sspdll="/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libssp-0.dll"
else
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw"
sslflags="no-asm no-tests -DOPENSSL_NO_CAPIENG mingw"
sspdll="/usr/i686-w64-mingw32/sys-root/mingw/bin/libssp-0.dll"
fi
if test -f "$sspdll"; then
@@ -282,9 +321,18 @@ if [ "$DOWIN" = "yes" ]; then
SSPLIB=""
fi
info "winssl: Configure no-shared $sslflags"
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" no-shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
if test "$W64" = "no"; then
# Disable stack-protector for 32-bit windows builds.
# mingw passes an LDFLAGS, so there is something
# passed in the LDFLAGS to stop -lssp passed in it.
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB __CNF_LDFLAGS="-fno-stack-protector" CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" no-shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
else
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" no-shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
fi
info "winssl: make"
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
# only install sw not docs, which take a long time.
@@ -297,9 +345,15 @@ if [ "$DOWIN" = "yes" ]; then
sslsharedinstall="`pwd`/sslsharedinstall"
cd openssl_shared
info "winssl: Configure shared $sslflags"
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslsharedinstall" shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
if test "$W64" = "no"; then
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB __CNF_LDFLAGS="-fno-stack-protector" CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslsharedinstall" shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
else
set -x # echo the configure command
__CNF_LDLIBS=$SSPLIB CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslsharedinstall" shared $sslflags || error_cleanup "OpenSSL Configure failed"
set +x
fi
info "winssl: make"
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
info "winssl: make install_sw"
@@ -308,6 +362,17 @@ if [ "$DOWIN" = "yes" ]; then
cd ..
fi
if test -n "$WINEXPAT" \
-a -n "$WINDIR" \
-a -d "$WINDIR" \
-a -d "${WINDIR}/wxpinstall"; then
info "Found already compiled expat at $WINDIR/wxpinstall; using that."
WINEXPAT=""
# Variables needed later on.
wxpinstall="${WINDIR}/wxpinstall"
cross_flag="$cross_flag --with-libexpat=$wxpinstall"
shared_cross_flag="$shared_cross_flag --with-libexpat=$wxpinstall"
fi
if test -n "$WINEXPAT"; then
info "Cross compile $WINEXPAT"
info "wxp: tar unpack"
@@ -315,7 +380,16 @@ if [ "$DOWIN" = "yes" ]; then
wxpinstall="`pwd`/wxpinstall"
cd expat-* || error_cleanup "no expat-X dir in tarball"
info "wxp: configure"
$configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" || error_cleanup "libexpat configure failed"
if test "$W64" = "no"; then
# Disable stack-protector for 32-bit windows builds.
set -x # echo the configure command
$configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" LDFLAGS="-fno-stack-protector" || error_cleanup "libexpat configure failed"
set +x
else
set -x # echo the configure command
$configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" || error_cleanup "libexpat configure failed"
set +x
fi
info "wxp: make"
make $MINJ || error_cleanup "libexpat crosscompile failed"
info "wxp: make install"
@@ -325,8 +399,12 @@ if [ "$DOWIN" = "yes" ]; then
cd ..
fi
info "GITREPO is $GITREPO"
info "GITBRANCH is $GITBRANCH"
if test -n "$WINDIR"; then
cd "$cwd"
create_temp_dir
fi
info "GITREPO is $GITREPO"
info "GITBRANCH is $GITBRANCH"
info "Exporting source from git."
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
@@ -358,13 +436,17 @@ if [ "$DOWIN" = "yes" ]; then
replace_version "configure.ac" "$version" "$version2"
version="$version2"
info "Rebuilding configure script (autoconf) snapshot."
autoconf || error_cleanup "Autoconf failed."
autoheader || error_cleanup "Autoheader failed."
autoconf -f || error_cleanup "Autoconf failed."
autoheader -f || error_cleanup "Autoheader failed."
rm -r autom4te* || echo "ignored"
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
fi
if test "`uname`" = "Linux"; then
(cd ..; cp -r unbound unbound_shared)
cd ..
cp -r unbound unbound_shared
unbound_shared="`pwd`/unbound_shared"
cd unbound
fi
# procedure for making unbound installer on mingw.
@@ -378,13 +460,15 @@ if [ "$DOWIN" = "yes" ]; then
fi
if test "$W64" = "no"; then
# Disable stack-protector for 32-bit windows builds.
echo "$configure"' --enable-debug --enable-static-exe --disable-flto --disable-gost '"$* $cross_flag" "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector'
$configure --enable-debug --enable-static-exe --disable-flto --disable-gost $* $cross_flag "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector'\
set -x
$configure --enable-debug --enable-static-exe --disable-flto --disable-gost $* $cross_flag "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector' LDFLAGS="-fno-stack-protector" \
|| error_cleanup "Could not configure"
set +x
else
echo "$configure"' --enable-debug --enable-static-exe --disable-flto --disable-gost '"$* $cross_flag"
set -x
$configure --enable-debug --enable-static-exe --disable-flto --disable-gost $* $cross_flag \
|| error_cleanup "Could not configure"
set +x
fi
info "Calling make"
make $MINJ || error_cleanup "Could not make"
@@ -392,16 +476,18 @@ if [ "$DOWIN" = "yes" ]; then
if test "`uname`" = "Linux"; then
info "Make DLL"
cd ../unbound_shared
cd $unbound_shared
if test "$W64" = "no"; then
# Disable stack-protector for 32-bit windows builds.
echo "$configure"' --enable-debug --disable-flto --disable-gost '"$* $shared_cross_flag" "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector'
$configure --enable-debug --disable-flto --disable-gost $* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector'\
set -x
$configure --enable-debug --disable-flto --disable-gost $* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag" CFLAGS='-O2 -g -fno-stack-protector' LDFLAGS="-fno-stack-protector" \
|| error_cleanup "Could not configure"
set +x
else
echo "$configure"' --enable-debug --disable-flto --disable-gost '"$* $shared_cross_flag"
$configure --enable-debug --disable-flto --disable-gost $* $shared_cross_flag \
set -x
$configure --enable-debug --disable-flto --disable-gost $* $shared_cross_flag \
|| error_cleanup "Could not configure"
set +x
fi
info "Calling make for DLL"
make $MINJ || error_cleanup "Could not make DLL"
@@ -430,17 +516,26 @@ if [ "$DOWIN" = "yes" ]; then
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd .
mkdir libunbound
# test to see if lib or lib64 (for openssl 3.0.0) needs to be used
if test -f ../../sslsharedinstall/lib/libcrypto.dll.a; then
cp ../../sslsharedinstall/lib/libcrypto.dll.a libunbound/.
if test -f $sslsharedinstall/lib/libcrypto.dll.a; then
cp $sslsharedinstall/lib/libcrypto.dll.a libunbound/.
else
cp ../../sslsharedinstall/lib64/libcrypto.dll.a libunbound/.
cp $sslsharedinstall/lib64/libcrypto.dll.a libunbound/.
fi
if test -f ../../sslsharedinstall/lib/libssl.dll.a; then
cp ../../sslsharedinstall/lib/libssl.dll.a libunbound/.
if test -f $sslsharedinstall/lib/libssl.dll.a; then
cp $sslsharedinstall/lib/libssl.dll.a libunbound/.
else
cp ../../sslsharedinstall/lib64/libssl.dll.a libunbound/.
cp $sslsharedinstall/lib64/libssl.dll.a libunbound/.
fi
cp ../../unbound_shared/unbound.h ../../unbound_shared/.libs/libunbound*.dll ../../unbound_shared/.libs/libunbound.dll.a ../../unbound_shared/.libs/libunbound.a ../../unbound_shared/.libs/libunbound*.def ../../sslsharedinstall/bin/libcrypto*.dll ../../sslsharedinstall/bin/libssl*.dll ../../wxpinstall/bin/libexpat*.dll ../../wxpinstall/lib/libexpat.dll.a libunbound/.
cp $unbound_shared/unbound.h \
$unbound_shared/.libs/libunbound*.dll \
$unbound_shared/.libs/libunbound.dll.a \
$unbound_shared/.libs/libunbound.a \
$unbound_shared/.libs/libunbound*.def \
$sslsharedinstall/bin/libcrypto*.dll \
$sslsharedinstall/bin/libssl*.dll \
$wxpinstall/bin/libexpat*.dll \
$wxpinstall/lib/libexpat.dll.a \
libunbound/.
if test -f "$sspdll"; then
cp "$sspdll" libunbound/.
fi
@@ -470,6 +565,11 @@ if [ "$DOWIN" = "yes" ]; then
storehash unbound-$version.zip
ls -lG unbound_setup_$version.exe
ls -lG unbound-$version.zip
echo "create signed versions with:"
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound_setup_$version.exe"
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.zip"
info "Done"
exit 0
fi
@@ -511,9 +611,10 @@ if [ `uname -s | grep -i -c darwin` -ne 0 ]; then
fi
info "Building configure script (autoreconf)."
autoreconf || error_cleanup "Autoconf failed."
autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
info "Building lexer and parser."
echo "#include \"config.h\"" > util/configlexer.c || error_cleanup "Failed to create configlexer"
@@ -556,8 +657,9 @@ fi
if [ "$RECONFIGURE" = "yes" ]; then
info "Rebuilding configure script (autoconf) snapshot."
autoreconf || error_cleanup "Autoconf failed."
autoreconf -f || error_cleanup "Autoconf failed."
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
fi
replace_all doc/README
+2 -2
View File
@@ -1,9 +1,9 @@
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
return True
def init_standard(id, env):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, env.cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, mod_env['script']))
return True
def deinit(id):
+2 -2
View File
@@ -50,7 +50,7 @@ Script file must contain four compulsory functions:
::
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
return True
@@ -69,7 +69,7 @@ Script file must contain four compulsory functions:
::
def init_standard(id, env):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, env.cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, mod_env['script']))
return True
+8 -3
View File
@@ -129,7 +129,7 @@ config_file
.. attribute:: ifs
Interface description strings (IP addresses).
List of interface description strings (IP addresses).
.. attribute:: num_out_ifs
@@ -138,7 +138,7 @@ config_file
.. attribute:: out_ifs
Outgoing interface description strings (IP addresses).
List of outgoing interface description strings (IP addresses).
.. attribute:: root_hints
@@ -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.
@@ -339,4 +343,5 @@ config_file
.. attribute:: python_script
Python script file.
Linked list of Python script files.
Deprecated; `mod_env['script']` should be used instead.
+5 -2
View File
@@ -6,8 +6,11 @@ Global variables
.. envvar:: mod_env
Module environment, contains data pointer for module-specific data.
See :class:`pythonmod_env`.
Module environment, it is the 'data' pointer for module-specific data
in :class:`pythonmod_env`.
It is initialized as a dictionary with the 'script' key pointing to the
module's python script.
It can be further populated during runtime for module-specific data.
Predefined constants
+1 -1
View File
@@ -80,7 +80,7 @@ def init_standard(id, env):
..note:: The previously accessible configuration options can now be found in
env.cfg.
"""
log_info("python: inited script {}".format(env.cfg.python_script))
log_info("python: inited script {}".format(mod_env['script']))
# Register EDNS option 65001 as a known EDNS option.
if not register_edns_option(env, 65001, bypass_cache_stage=True,
+44 -1
View File
@@ -34,6 +34,9 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
'''
import os
#Try:
# - dig @localhost nlnetlabs.nl +ednsopt=65002:
# This query *could* be answered from cache. If so, unbound will reply
@@ -242,6 +245,36 @@ def inplace_query_callback(qinfo, flags, qstate, addr, zone, region, **kwargs):
return True
def inplace_query_response_callback(qstate, response, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called after receiving a reply from a backend server.
:param qstate: module qstate. opt_lists are available here;
:param response: struct dns_msg. The reply received from the backend server;
:param **kwargs: Dictionary that may contain parameters added in a future
release.
"""
log_dns_msg(
"python: incoming reply from {}{}".format(qstate.reply.addr, os.linesep),
response.qinfo, response.rep
)
return True
def inplace_edns_back_parsed_call(qstate, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called after EDNS is parsed on a reply from a backend server..
:param qstate: module qstate. opt_lists are available here;
:param **kwargs: Dictionary that may contain parameters added in a future
release.
"""
log_info("python: edns parsed")
return True
def init_standard(id, env):
"""
New version of the init function.
@@ -254,7 +287,7 @@ def init_standard(id, env):
env.cfg.
"""
log_info("python: inited script {}".format(env.cfg.python_script))
log_info("python: inited script {}".format(mod_env['script']))
# Register the inplace_reply_callback function as an inplace callback
# function when answering a resolved query.
@@ -281,6 +314,16 @@ def init_standard(id, env):
if not register_inplace_cb_query(inplace_query_callback, env, id):
return False
# Register the inplace_edns_back_parsed_call function as an inplace callback
# for when a reply is received from a backend server.
if not register_inplace_cb_query_response(inplace_query_response_callback, env, id):
return False
# Register the inplace_edns_back_parsed_call function as an inplace callback
# for when EDNS is parsed on a reply from a backend server.
if not register_inplace_cb_edns_back_parsed_call(inplace_edns_back_parsed_call, env, id):
return False
return True
+1 -1
View File
@@ -87,7 +87,7 @@ def logDnsMsg(qstate):
print "-"*100
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
return True
def deinit(id):
+197 -44
View File
@@ -86,6 +86,20 @@
}
return list;
}
/* converts an array of strings (char**) to a List of strings */
PyObject* CharArrayAsStringList(char** array, int len) {
PyObject* list;
int i;
if(!array||len==0) return PyList_New(0);
list = PyList_New(len);
for (i=0; i < len; i++) {
PyList_SET_ITEM(list, i, PyString_FromString(array[i]));
}
return list;
}
%}
/* ************************************************************************************ *
@@ -609,9 +623,9 @@ struct mesh_reply {
struct comm_reply query_reply;
};
%rename(_addr) comm_reply::addr;
%rename(_addr) comm_reply::client_addr;
struct comm_reply {
struct sockaddr_storage addr;
struct sockaddr_storage client_addr;
};
%extend comm_reply {
@@ -952,6 +966,9 @@ struct config_str2list {
/* ************************************************************************************ *
Structure config_file
* ************************************************************************************ */
%ignore config_file::ifs;
%ignore config_file::out_ifs;
%ignore config_file::python_script;
struct config_file {
int verbosity;
int stat_interval;
@@ -992,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;
@@ -1035,6 +1053,25 @@ struct config_file {
struct config_strlist* python_script;
};
%inline %{
PyObject* _get_ifs_tuple(struct config_file* cfg) {
return CharArrayAsStringList(cfg->ifs, cfg->num_ifs);
}
PyObject* _get_ifs_out_tuple(struct config_file* cfg) {
return CharArrayAsStringList(cfg->out_ifs, cfg->num_out_ifs);
}
%}
%extend config_file {
%pythoncode %{
ifs = property(_unboundmodule._get_ifs_tuple)
out_ifs = property(_unboundmodule._get_ifs_out_tuple)
def _deprecated_python_script(self): return "cfg.python_script is deprecated, you can use `mod_env['script']` instead."
python_script = property(_deprecated_python_script)
%}
}
/* ************************************************************************************ *
ASN: Adding structures related to forwards_lookup and dns_cache_find_delegation
* ************************************************************************************ */
@@ -1378,9 +1415,9 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
struct regional* region, struct dns_msg** msg, uint32_t timenow,
int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp, int supports_ipv4, int supports_ipv6);
struct delegpt* dp, int supports_ipv4, int supports_ipv6, int use_nat64);
struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
uint8_t* qname, uint16_t qclass, struct delegpt* dp);
uint8_t* qname, uint16_t qclass, struct delegpt* dp, int nolock);
/* Custom function to perform logic similar to the one in daemon/cachedump.c */
struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t nmlen);
@@ -1397,6 +1434,7 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
struct query_info qinfo;
struct iter_hints_stub* stub;
uint32_t timenow = *qstate->env->now;
int nolock = 0;
regional_free_all(region);
qinfo.qname = (uint8_t*)nm;
@@ -1409,7 +1447,8 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
if(!dp)
return NULL;
if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6)) {
qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6,
qstate->env->cfg->do_nat64)) {
if (dname_is_root((uint8_t*)nm))
return NULL;
nm = (char*)dp->name;
@@ -1418,9 +1457,12 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
dname_str((uint8_t*)nm, b);
continue;
}
stub = hints_lookup_stub(qstate->env->hints, qinfo.qname, qinfo.qclass, dp);
stub = hints_lookup_stub(qstate->env->hints, qinfo.qname,
qinfo.qclass, dp, nolock);
if (stub) {
return stub->dp;
struct delegpt* stubdp = delegpt_copy(stub->dp, region);
lock_rw_unlock(&qstate->env->hints->lock);
return stubdp;
} else {
return dp;
}
@@ -1550,13 +1592,15 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
struct comm_reply* repinfo, struct regional* region,
struct timeval* start_time, int id, void* python_callback)
{
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
PyObject *py_rep, *py_repinfo, *py_region;
PyObject *func = NULL, *py_edns = NULL, *py_qstate = NULL;
PyObject *py_opt_list_out = NULL, *py_qinfo = NULL;
PyObject *py_rep = NULL, *py_repinfo = NULL, *py_region = NULL;
PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
int res = 0;
double py_start_time = ((double)start_time->tv_sec) + ((double)start_time->tv_usec) / 1.0e6;
PyGILState_STATE gstate = PyGILState_Ensure();
func = (PyObject *) python_callback;
py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
py_qstate = SWIG_NewPointerObj((void*) qstate,
@@ -1567,20 +1611,24 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0);
py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
if(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out
&& py_region && py_repinfo) {
py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
rcode, py_edns, py_opt_list_out, py_region);
py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
py_start_time);
if(py_args && py_kwargs) {
result = PyObject_Call(func, py_args, py_kwargs);
} else {
log_err("pythonmod: malloc failure in python_inplace_cb_reply_generic");
}
} else {
log_err("pythonmod: malloc failure in python_inplace_cb_reply_generic");
if(!(py_qinfo && py_qstate && py_rep && py_edns && py_opt_list_out
&& py_region && py_repinfo)) {
log_err("pythonmod: swig pointer failure in python_inplace_cb_reply_generic");
goto out;
}
py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
rcode, py_edns, py_opt_list_out, py_region);
py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
py_start_time);
if(!(py_args && py_kwargs)) {
log_err("pythonmod: BuildValue failure in python_inplace_cb_reply_generic");
goto out;
}
result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
out:
Py_XDECREF(py_edns);
Py_XDECREF(py_qstate);
Py_XDECREF(py_opt_list_out);
@@ -1590,9 +1638,6 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
Py_XDECREF(py_region);
Py_XDECREF(py_args);
Py_XDECREF(py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
Py_XDECREF(result);
PyGILState_Release(gstate);
return res;
@@ -1640,29 +1685,34 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
int res = 0;
PyObject *func = python_callback;
PyObject *py_args = NULL, *py_kwargs = NULL, *result = NULL;
PyObject *py_qinfo = NULL;
PyObject *py_qstate = NULL;
PyObject *py_addr = NULL;
PyObject *py_zone = NULL;
PyObject *py_region = NULL;
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
PyObject *py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
PyObject *py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
PyObject *py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
PyObject *py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
if(py_qinfo && py_qstate && py_addr && py_zone && py_region) {
py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
py_kwargs = Py_BuildValue("{}");
if(py_args && py_kwargs) {
result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
} else {
log_err("pythonmod: malloc failure in python_inplace_cb_query_generic");
}
} else {
log_err("pythonmod: malloc failure in python_inplace_cb_query_generic");
py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
if(!(py_qinfo && py_qstate && py_addr && py_zone && py_region)) {
log_err("pythonmod: swig pointer failure in python_inplace_cb_query_generic");
goto out;
}
py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
py_kwargs = Py_BuildValue("{}");
if(!(py_args && py_kwargs)) {
log_err("pythonmod: BuildValue failure in python_inplace_cb_query_generic");
goto out;
}
result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
out:
Py_XDECREF(py_qinfo);
Py_XDECREF(py_qstate);
Py_XDECREF(py_addr);
@@ -1686,6 +1736,105 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
if (ret) Py_INCREF(py_cb);
return ret;
}
int python_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* python_callback)
{
int res = 0;
PyObject *func = python_callback;
PyObject *py_qstate = NULL;
PyObject *py_response = NULL;
PyObject *py_args = NULL;
PyObject *py_kwargs = NULL;
PyObject *result = NULL;
PyGILState_STATE gstate = PyGILState_Ensure();
py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
py_response = SWIG_NewPointerObj((void*) response, SWIGTYPE_p_dns_msg, 0);
if(!(py_qstate && py_response)) {
log_err("pythonmod: swig pointer failure in python_inplace_cb_query_response");
goto out;
}
py_args = Py_BuildValue("(OO)", py_qstate, py_response);
py_kwargs = Py_BuildValue("{}");
if(!(py_args && py_kwargs)) {
log_err("pythonmod: BuildValue failure in python_inplace_cb_query_response");
goto out;
}
result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
out:
Py_XDECREF(py_qstate);
Py_XDECREF(py_response);
Py_XDECREF(py_args);
Py_XDECREF(py_kwargs);
Py_XDECREF(result);
PyGILState_Release(gstate);
return res;
}
static int register_inplace_cb_query_response(PyObject* py_cb,
struct module_env* env, int id)
{
int ret = inplace_cb_register(python_inplace_cb_query_response,
inplace_cb_query_response, (void*) py_cb, env, id);
if (ret) Py_INCREF(py_cb);
return ret;
}
int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate,
int id, void* python_callback)
{
int res = 0;
PyObject *func = python_callback;
PyObject *py_qstate = NULL;
PyObject *py_args = NULL;
PyObject *py_kwargs = NULL;
PyObject *result = NULL;
PyGILState_STATE gstate = PyGILState_Ensure();
py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
if(!py_qstate) {
log_err("pythonmod: swig pointer failure in python_inplace_cb_edns_back_parsed_call");
goto out;
}
py_args = Py_BuildValue("(O)", py_qstate);
py_kwargs = Py_BuildValue("{}");
if(!(py_args && py_kwargs)) {
log_err("pythonmod: BuildValue failure in python_inplace_cb_edns_back_parsed_call");
goto out;
}
result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
out:
Py_XDECREF(py_qstate);
Py_XDECREF(py_args);
Py_XDECREF(py_kwargs);
Py_XDECREF(result);
PyGILState_Release(gstate);
return res;
}
static int register_inplace_cb_edns_back_parsed_call(PyObject* py_cb,
struct module_env* env, int id)
{
int ret = inplace_cb_register(python_inplace_cb_edns_back_parsed_call,
inplace_cb_edns_back_parsed, (void*) py_cb, env, id);
if (ret) Py_INCREF(py_cb);
return ret;
}
%}
/* C declarations */
int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
@@ -1702,3 +1851,7 @@ static int register_inplace_cb_reply_servfail(PyObject* py_cb,
struct module_env* env, int id);
static int register_inplace_cb_query(PyObject *py_cb,
struct module_env* env, int id);
static int register_inplace_cb_query_response(PyObject *py_cb,
struct module_env* env, int id);
static int register_inplace_cb_edns_back_parsed_call(PyObject *py_cb,
struct module_env* env, int id);
+185 -44
View File
@@ -112,6 +112,34 @@ struct pythonmod_qstate {
PyObject* data;
};
/* The dict from __main__ could have remnants from a previous script
* invocation, in a multi python module setup. Usually this is fine since newer
* scripts will update their values. The obvious erroneous case is when mixing
* python scripts that make use of both 'init' and 'init_standard'. This
* results in 'init_standard' to persist on following scripts that don't use it
* (thus not replacing it). This is also problematic in case where a script
* does not define a required function but a previously loaded script did. The
* current solution is to make sure to clean offensive remnants that influence
* further parsing of the individual scripts.
*/
static void
clean_python_function_objects(PyObject* dict) {
const char* function_names[] = {
"init",
"init_standard",
"deinit",
"operate",
"inform_super"
};
size_t i;
for(i=0; i<sizeof(function_names)/sizeof(function_names[0]); i++) {
if(PyDict_GetItemString(dict, function_names[i]) != NULL) {
PyDict_DelItemString(dict, function_names[i]);
}
}
};
/* Generated */
#ifndef S_SPLINT_S
#include "pythonmod/interface.h"
@@ -252,13 +280,24 @@ cleanup:
Py_XDECREF(exc_tb);
}
/* we only want to unwind Python once at exit */
static void
pythonmod_atexit(void)
{
log_assert(py_mod_count == 0);
log_assert(mainthr != NULL);
PyEval_RestoreThread(mainthr);
Py_Finalize();
}
int pythonmod_init(struct module_env* env, int id)
{
int py_mod_idx = py_mod_count++;
/* Initialize module */
FILE* script_py = NULL;
PyObject* py_init_arg, *res;
PyObject* py_init_arg = NULL, *res = NULL, *fname = NULL;
PyGILState_STATE gil;
int init_standard = 1, i = 0;
#if PY_MAJOR_VERSION < 3
@@ -292,47 +331,98 @@ int pythonmod_init(struct module_env* env, int id)
/* Initialize Python libraries */
if (py_mod_count==1 && !Py_IsInitialized())
{
#if PY_VERSION_HEX >= 0x03080000
PyStatus status;
PyPreConfig preconfig;
PyConfig config;
#endif
#if PY_MAJOR_VERSION >= 3
wchar_t progname[8];
mbstowcs(progname, "unbound", 8);
#else
char *progname = "unbound";
#endif
#if PY_VERSION_HEX < 0x03080000
Py_SetProgramName(progname);
Py_NoSiteFlag = 1;
#else
/* Python must be preinitialized, before the PyImport_AppendInittab
* call. */
PyPreConfig_InitPythonConfig(&preconfig);
status = Py_PreInitialize(&preconfig);
if(PyStatus_Exception(status)) {
log_err("python exception in Py_PreInitialize: %s%s%s",
(status.func?status.func:""), (status.func?": ":""),
(status.err_msg?status.err_msg:""));
return 0;
}
#endif
#if PY_MAJOR_VERSION >= 3
PyImport_AppendInittab(SWIG_name, (void*)SWIG_init);
#endif
#if PY_VERSION_HEX < 0x03080000
Py_NoSiteFlag = 1;
Py_Initialize();
#else
PyConfig_InitPythonConfig(&config);
status = PyConfig_SetString(&config, &config.program_name, progname);
if(PyStatus_Exception(status)) {
log_err("python exception in PyConfig_SetString(.. program_name ..): %s%s%s",
(status.func?status.func:""), (status.func?": ":""),
(status.err_msg?status.err_msg:""));
PyConfig_Clear(&config);
return 0;
}
config.site_import = 0;
status = Py_InitializeFromConfig(&config);
if(PyStatus_Exception(status)) {
log_err("python exception in Py_InitializeFromConfig: %s%s%s",
(status.func?status.func:""), (status.func?": ":""),
(status.err_msg?status.err_msg:""));
PyConfig_Clear(&config);
return 0;
}
PyConfig_Clear(&config);
#endif
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION <= 6)
/* initthreads only for python 3.6 and older */
PyEval_InitThreads();
#endif
SWIG_init();
mainthr = PyEval_SaveThread();
/* register callback to unwind Python at exit */
atexit(pythonmod_atexit);
}
gil = PyGILState_Ensure();
if (py_mod_count==1) {
/* Initialize Python */
PyRun_SimpleString("import sys \n");
if(PyRun_SimpleString("import sys \n") < 0 ) {
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
goto python_init_fail;
}
PyRun_SimpleString("sys.path.append('.') \n");
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
if(env->cfg->directory && env->cfg->directory[0]) {
char wdir[1524];
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
env->cfg->directory);
PyRun_SimpleString(wdir);
}
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
PyRun_SimpleString("import distutils.sysconfig \n");
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
if(PyRun_SimpleString("import site\n") < 0) {
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
goto python_init_fail;
}
if(PyRun_SimpleString("sys.path.extend(site.getsitepackages())\n") < 0) {
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
goto python_init_fail;
}
if(PyRun_SimpleString("from unboundmodule import *\n") < 0)
{
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
}
@@ -348,18 +438,32 @@ int pythonmod_init(struct module_env* env, int id)
if (script_py == NULL)
{
log_err("pythonmod: can't open file %s for reading", pe->fname);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
/* Load file */
pe->module = PyImport_AddModule("__main__");
Py_XINCREF(pe->module);
pe->dict = PyModule_GetDict(pe->module);
pe->data = PyDict_New();
Py_XINCREF(pe->data);
PyModule_AddObject(pe->module, "mod_env", pe->data);
Py_XINCREF(pe->dict);
clean_python_function_objects(pe->dict);
/* TODO: deallocation of pe->... if an error occurs */
pe->data = PyDict_New();
/* add the script filename to the global "mod_env" for trivial access */
fname = PyString_FromString(pe->fname);
if(PyDict_SetItemString(pe->data, "script", fname) < 0) {
log_err("pythonmod: could not add item to dictionary");
Py_XDECREF(fname);
goto python_init_fail;
}
Py_XDECREF(fname);
Py_XINCREF(pe->data); /* reference will be stolen below */
if(PyModule_AddObject(pe->module, "mod_env", pe->data) < 0) {
log_err("pythonmod: could not add mod_env object");
Py_XDECREF(pe->data); /* 2 times, here and on python_init_fail; */
/* on failure the reference is not stolen */
goto python_init_fail;
}
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
@@ -390,18 +494,30 @@ int pythonmod_init(struct module_env* env, int id)
fstr = malloc(flen+1);
if(!fstr) {
log_err("malloc failure to print parse error");
PyGILState_Release(gil);
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
return 0;
#endif
goto python_init_fail;
}
fseek(script_py, 0, SEEK_SET);
if(fread(fstr, flen, 1, script_py) < 1) {
log_err("file read failed to print parse error: %s: %s",
pe->fname, strerror(errno));
PyGILState_Release(gil);
fclose(script_py);
free(fstr);
return 0;
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
goto python_init_fail;
}
fstr[flen] = 0;
/* we compile the string, but do not run it, to stop side-effects */
@@ -409,17 +525,26 @@ int pythonmod_init(struct module_env* env, int id)
* that we are expecting */
(void)Py_CompileString(fstr, pe->fname, Py_file_input);
#endif
log_py_err();
PyGILState_Release(gil);
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
/* no cleanup needed for python before 3.9 */
#else
/* cleanup for python 3.9 and newer */
free(fstr);
#endif
return 0;
goto python_init_fail;
}
/* close the file */
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
@@ -432,28 +557,28 @@ int pythonmod_init(struct module_env* env, int id)
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
{
log_err("pythonmod: function init is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
}
Py_XINCREF(pe->func_init);
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
{
log_err("pythonmod: function deinit is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
Py_XINCREF(pe->func_deinit);
if ((pe->func_operate = PyDict_GetItemString(pe->dict, "operate")) == NULL)
{
log_err("pythonmod: function operate is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
Py_XINCREF(pe->func_operate);
if ((pe->func_inform = PyDict_GetItemString(pe->dict, "inform_super")) == NULL)
{
log_err("pythonmod: function inform_super is missing in %s", pe->fname);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
Py_XINCREF(pe->func_inform);
if (init_standard)
{
@@ -469,21 +594,31 @@ int pythonmod_init(struct module_env* env, int id)
{
log_err("pythonmod: Exception occurred in function init");
log_py_err();
Py_XDECREF(res);
Py_XDECREF(py_init_arg);
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
Py_XDECREF(res);
Py_XDECREF(py_init_arg);
PyGILState_Release(gil);
return 1;
python_init_fail:
Py_XDECREF(pe->module);
Py_XDECREF(pe->dict);
Py_XDECREF(pe->data);
Py_XDECREF(pe->func_init);
Py_XDECREF(pe->func_deinit);
Py_XDECREF(pe->func_operate);
Py_XDECREF(pe->func_inform);
Py_XDECREF(res);
Py_XDECREF(py_init_arg);
PyGILState_Release(gil);
return 0;
}
void pythonmod_deinit(struct module_env* env, int id)
{
int cbtype;
struct pythonmod_env* pe = env->modinfo[id];
if(pe == NULL)
return;
@@ -503,18 +638,24 @@ void pythonmod_deinit(struct module_env* env, int id)
/* Free result if any */
Py_XDECREF(res);
/* Free shared data if any */
Py_XDECREF(pe->module);
Py_XDECREF(pe->dict);
Py_XDECREF(pe->data);
Py_XDECREF(pe->func_init);
Py_XDECREF(pe->func_deinit);
Py_XDECREF(pe->func_inform);
Py_XDECREF(pe->func_operate);
PyGILState_Release(gil);
if(--py_mod_count==0) {
PyEval_RestoreThread(mainthr);
Py_Finalize();
mainthr = NULL;
}
py_mod_count--;
}
pe->fname = NULL;
free(pe);
/* iterate over all possible callback types and clean up each in turn */
for (cbtype = 0; cbtype < inplace_cb_types_total; cbtype++)
inplace_cb_delete(env, cbtype, id);
/* Module is deallocated in Python */
env->modinfo[id] = NULL;
}
@@ -636,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)
+8
View File
@@ -82,4 +82,12 @@ int python_inplace_cb_query_generic(
uint8_t* zone, size_t zonelen, struct regional* region, int id,
void* python_callback);
/** Declared here for fptr_wlist access. The definition is in interface.i. */
int python_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* python_callback);
/** Declared here for fptr_wlist access. The definition is in interface.i. */
int python_inplace_cb_edns_back_parsed_call(struct module_qstate* qstate,
int id, void* python_callback);
#endif /* PYTHONMOD_H */
+4 -4
View File
@@ -172,14 +172,14 @@ int createResponse(struct module_qstate* qstate, sldns_buffer* pkt)
}
/* Convert reply->addr to string */
/* Convert reply->client_addr to string */
void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen)
{
int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
void* sinaddr = &((struct sockaddr_in*) &(reply->addr))->sin_addr;
int af = (int)((struct sockaddr_in*) &(reply->client_addr))->sin_family;
void* sinaddr = &((struct sockaddr_in*) &(reply->client_addr))->sin_addr;
if(af == AF_INET6)
sinaddr = &((struct sockaddr_in6*)&(reply->addr))->sin6_addr;
sinaddr = &((struct sockaddr_in6*)&(reply->client_addr))->sin6_addr;
dest[0] = 0;
if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0)
return;
+1 -1
View File
@@ -35,7 +35,7 @@
import os
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
return True
def deinit(id):
+21 -18
View File
@@ -33,7 +33,7 @@
POSSIBILITY OF SUCH DAMAGE.
'''
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
return True
def deinit(id):
@@ -55,12 +55,15 @@ def setTTL(qstate, ttl):
def dataHex(data, prefix=""):
res = ""
for i in range(0, (len(data)+15)/16):
for i in range(0, int((len(data)+15)/16)):
res += "%s0x%02X | " % (prefix, i*16)
d = map(lambda x:ord(x), data[i*16:i*16+17])
if type(data[0]) == type(1):
d = map(lambda x:int(x), data[i*16:i*16+17])
else:
d = map(lambda x:ord(x), data[i*16:i*16+17])
for ch in d:
res += "%02X " % ch
for i in range(0,17-len(d)):
for i in range(0,17-len(data[i*16:i*16+17])):
res += " "
res += "| "
for ch in d:
@@ -72,31 +75,31 @@ def dataHex(data, prefix=""):
return res
def printReturnMsg(qstate):
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl)
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str
print("Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl))
print(" qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str)
if (qstate.return_msg.rep):
print "RRSets:",qstate.return_msg.rep.rrset_count
print("RRSets:",qstate.return_msg.rep.rrset_count)
prevkey = None
for i in range(0,qstate.return_msg.rep.rrset_count):
r = qstate.return_msg.rep.rrsets[i]
rk = r.rk
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
print(i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags)
print("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
d = r.entry.data
print " RRDatas:",d.count+d.rrsig_count
print(" RRDatas:",d.count+d.rrsig_count)
for j in range(0,d.count+d.rrsig_count):
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:"
print dataHex(d.rr_data[j]," ")
print(" ",j,":","TTL=",d.rr_ttl[j],"RR data:")
print(dataHex(d.rr_data[j]," "))
def operate(id, event, qstate, qdata):
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
#print "pythonmod: per query data", qdata
#print("pythonmod: per query data", qdata)
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list,
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
print
print("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str)
print("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype)
print("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass)
print("")
# TEST:
# > dig @127.0.0.1 www.seznam.cz A
@@ -118,7 +121,7 @@ def operate(id, event, qstate, qdata):
invalidateQueryInCache(qstate, qstate.return_msg.qinfo)
if (qstate.return_msg.rep.authoritative):
print "X"*300
print("X"*300)
setTTL(qstate, 10) #do cache nastavime TTL na 10
if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):

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