Compare commits

...
Author SHA1 Message Date
W.C.A. Wijngaards 79fa94834e - 1.9.3rc2 release candidate tag. 2019-08-22 14:50:49 +02:00
W.C.A. Wijngaards e35d5f5a2d delete duplicate file. 2019-08-22 13:32:34 +02:00
W.C.A. Wijngaards 334e2b1e35 updated fastrpz.patch to apply cleanly. 2019-08-22 13:31:09 +02:00
W.C.A. Wijngaards 06847ff3be - Fix that pkg-config is setup before --enable-systemd needs it. 2019-08-22 12:22:25 +02:00
W.C.A. Wijngaards 80c2c69fa7 - Fix log_dns_msg to log irrespective of minimal responses config. 2019-08-21 17:41:29 +02:00
Ralph Dolmans 8b752e359e - Document limitation of pidfile removal outside of chroot directory. 2019-08-19 13:27:19 +02:00
W.C.A. Wijngaards d3b3d64ef3 - Remove warning about unknown cast-function-type warning pragma. 2019-08-16 12:52:58 +02:00
W.C.A. Wijngaards c602ba7319 - Fixup contrib/fastrpz.patch 2019-08-16 12:37:13 +02:00
W.C.A. Wijngaards bdb6c153e4 - Please doxygen's parser for "@" occurrence in doxygen comment. 2019-08-16 12:21:40 +02:00
W.C.A. Wijngaards d8a8730cac - Fix unittest valgrind false positive uninitialised value report,
where if gcc 9.1.1 uses -O2 (but not -O1) then valgrind 3.15.0
  issues an uninitialised value for the token buffer at the str2wire.c
  rrinternal_get_owner() strcmp with the '@' value.  Rewritten to use
  straight character comparisons removes the false positive.  Also
  valgrinds --expensive-definedness-checks=yes can stop this false
  positive.
2019-08-16 12:18:23 +02:00
W.C.A. Wijngaards 0532cdd357 - (for later release): -V prints if TCP fastopen is available. 2019-08-15 17:04:38 +02:00
W.C.A. Wijngaards e84b913585 - 1.9.3rc1 release candidate tag. 2019-08-15 15:49:15 +02:00
W.C.A. Wijngaards a5027f5f56 - Fix character buffer size in ub_ctx_hosts. 2019-08-15 15:11:04 +02:00
W.C.A. Wijngaards 06a58ca248 - escape commandline contents for -V. 2019-08-15 15:05:02 +02:00
W.C.A. Wijngaards 4700d79024 - avoid warning about upcast on 32bit systems for autotrust. 2019-08-15 14:25:46 +02:00
W.C.A. Wijngaards 9d9884c442 - Fix autotrust temp file uniqueness windows compile. 2019-08-15 14:02:14 +02:00
W.C.A. Wijngaards c1c75929fa - iana portlist updated. 2019-08-15 13:07:26 +02:00
W.C.A. Wijngaards 8cb3656b3e - Fix warning for unused variable for compilation without systemd. 2019-08-14 16:08:19 +02:00
George Thessalonikefs a90f173875 - Fix #59, when compiled with systemd support check that we can properly
communicate with systemd through the `NOTIFY_SOCKET`.
2019-08-14 15:51:28 +02:00
Wouter WijngaardsandGitHub b266db3920 Merge pull request #57 from NLnetLabs/show-build-options
Introduce `-V` option to print the version number and build options.
2019-08-14 12:47:42 +02:00
gthessandGitHub fd415d8833 Merge branch 'master' into show-build-options 2019-08-14 11:45:41 +02:00
W.C.A. Wijngaards b5a52f8c86 - Generate configlexer with newer flex. 2019-08-14 11:40:35 +02:00
W.C.A. Wijngaards 67271242bf autoconf for the '-V' option changes. 2019-08-14 11:34:27 +02:00
George Thessalonikefs 008813f0a2 - Introduce -V option to print the version number and build options.
Previously reported build options like linked libs and linked modules
  are now moved from `-h` to `-V` as well for consistency.
- PACKAGE_BUGREPORT now also includes link to GitHub issues.
2019-08-12 17:52:43 +02:00
W.C.A. Wijngaards fa506e3cda - Check repinfo in worker_handle_request, if null, drop it. 2019-08-01 16:57:36 +02:00
W.C.A. Wijngaards df0c844eed - Fix to timeval_add for remaining second in microseconds. 2019-08-01 16:48:41 +02:00
W.C.A. Wijngaards 199e6c586b - Fix to return after failed auth zone http chunk write.
- Fix to remove unused test for task_probe existance.
2019-08-01 16:40:52 +02:00
W.C.A. Wijngaards 21f740d313 - Fix #52 #53, fix for example fail program. 2019-08-01 09:34:44 +02:00
W.C.A. Wijngaards e860d39f54 - For #52 #53, second context does not close logfile override. 2019-08-01 09:15:33 +02:00
W.C.A. Wijngaards fe0b1da859 Fix comment. 2019-07-29 16:58:23 +02:00
W.C.A. Wijngaards 27811ffaa9 - Add hex print of trust anchor pointer to trust anchor file temp
name to make it unique, for libunbound created multiple contexts.
2019-07-29 16:51:40 +02:00
W.C.A. Wijngaards 7d5ab2f4de - Add verbose log message when auth zone file is written, at level 4. 2019-07-29 09:25:49 +02:00
W.C.A. Wijngaards 5f5c00203e - Fix question section mismatch in local zone redirect. 2019-07-23 14:01:59 +02:00
W.C.A. Wijngaards b4b0065554 Fixup space in error message. 2019-07-19 12:51:37 +02:00
W.C.A. Wijngaards c94e13220b - Fix #49: Set no renegotiation on the SSL context to stop client
session renegotiation.
2019-07-19 08:18:06 +02:00
W.C.A. Wijngaards 368386c011 - Fix #48: Unbound returns additional records on NODATA response,
if minimal-responses is enabled, also the additional for negative
  responses is removed.
2019-07-12 14:34:35 +02:00
Ralph Dolmans d5ebc63add - Fix in respip addrtree selection. Absence of addr_tree_init_parents() call
made it impossible to go up the tree when the matching netmask is too
   specific.
2019-07-09 14:58:36 +02:00
Ralph Dolmans d323e1bda8 - Fix for possible assertion failure when answering respip CNAME from cache. 2019-07-05 16:52:03 +02:00
W.C.A. Wijngaards 36819adcc2 Nicer spelling and layout. 2019-06-25 15:14:07 +02:00
W.C.A. Wijngaards da46ea24d5 - For #45, check that 127.0.0.1 and ::1 are not used in unbound.conf
when do-not-query-localhost is turned on, or at default on,
  unbound-checkconf prints a warning if it is found in forward-addr or
  stub-addr statements.
2019-06-25 14:50:49 +02:00
W.C.A. Wijngaards 1aa1facabc - Fix memleak in unit test, reported from the clang 8.0 static analyzer. 2019-06-24 10:53:27 +02:00
W.C.A. Wijngaards 78b2f1cc20 - Fix python dict reference and double free in config. 2019-06-18 17:25:08 +02:00
W.C.A. Wijngaards 164f302011 - Merge PR #6: Python module: support multiple instances
- Merge PR #5: Python module: define constant MODULE_RESTART_NEXT
- Merge PR #4: Python module: assign something useful to the
  per-query data store 'qdata'
Noted in Changelog.
2019-06-18 17:11:31 +02:00
W.C.A. Wijngaards cc39725cf3 Merge branch 'episource-dev/all-merged/master'.
Merge PR #6: Python module: support multiple instances
Merge PR #5: Python module: define constant MODULE_RESTART_NEXT
Merge PR #4: Python module: assign something useful to the per-query data store 'qdata'
2019-06-18 17:08:59 +02:00
W.C.A. Wijngaards 63b2628a18 Merge branch 'dev/all-merged/master' of git://github.com/episource/unbound into episource-dev/all-merged/master 2019-06-18 17:07:57 +02:00
W.C.A. Wijngaards 0f3eac4a0e - Added documentation to the ipset files (for doxygen output). 2019-06-18 16:25:11 +02:00
W.C.A. Wijngaards 72738471f1 - make depend 2019-06-18 15:59:10 +02:00
W.C.A. Wijngaards c1e75c0369 - Fix to make unbound-control with ipset, remove unused variable,
use unsigned type because of comparison, and assign null instead
  of compare with it.  Remade lex and yacc output.
2019-06-18 15:57:28 +02:00
W.C.A. Wijngaards b16c872a60 - PR #28: IPSet module, by Kevin Chou. Created a module to support
the ipset that could add the domain's ip to a list easily.
  Needs libmnl, and --enable-ipset and config it, doc/README.ipset.md.
- Fix to omit RRSIGs from addition to the ipset.
2019-06-18 15:38:37 +02:00
W.C.A. Wijngaards 364441e0f5 Merge branch 'k9982874-master',PR #28 IPset module. 2019-06-18 13:54:04 +02:00
W.C.A. Wijngaards ed95b07764 Merge branch 'master' of git://github.com/k9982874/unbound into k9982874-master 2019-06-18 13:52:52 +02:00
W.C.A. Wijngaards bf2307ca97 - Fix for #24: Fix abort due to scan of auth zone masters using old
address from previous scan.
2019-06-17 14:15:36 +02:00
W.C.A. Wijngaards 1ec96d8f07 - Fix #39: In libunbound, leftover logfile is close()d unpredictably. 2019-06-17 12:13:12 +02:00
W.C.A. Wijngaards 3499d3c647 - Master contains version 1.9.3 in development. 2019-06-17 11:42:19 +02:00
W.C.A. Wijngaards ee06aaaad9 - 1.9.2rc3 release candidate tag. 2019-06-14 08:38:37 +02:00
W.C.A. Wijngaards af6c5dea43 - Fix another spoolbuf storage code point, in prefetch. 2019-06-12 08:32:45 +02:00
W.C.A. Wijngaards b57771d42b - 1.9.2rc1 release candidate tag. 2019-06-11 12:46:44 +02:00
W.C.A. Wijngaards 6067ce6d2b - Fix that fixes the Fix that spoolbuf is not used to store tcp
pipelined response between mesh send and callback end, this fixes
  error cases that did not use the correct spoolbuf.
2019-06-11 12:15:43 +02:00
W.C.A. Wijngaards 081fd4fdae - 1.9.2rc1 release candidate tag. 2019-06-06 09:32:53 +02:00
W.C.A. Wijngaards 09a0e6ee30 - iana portlist updated. 2019-06-04 12:21:21 +02:00
W.C.A. Wijngaards a4f4d7b6ba - Fix to guard _OPENBSD_SOURCE from redefinition. 2019-05-29 13:28:03 +02:00
W.C.A. Wijngaards e2a2dcdfd5 - gitignore config.h.in~. 2019-05-28 11:12:41 +02:00
W.C.A. Wijngaards 14b11384a4 - Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD. 2019-05-28 11:12:05 +02:00
W.C.A. Wijngaards a03f0a388e - Fix double file close in tcp pipelined response code. 2019-05-27 11:23:41 +02:00
Wouter Wijngaards 0b77c9d676 - Fix that spoolbuf is not used to store tcp pipelined response
between mesh send and callback end.
2019-05-24 09:35:38 +02:00
W.C.A. Wijngaards 1c3ba0cef7 - Note that so-reuseport at extreme load is better turned off,
otherwise queries are not distributed evenly, on Linux 4.4.x.
2019-05-20 11:57:09 +02:00
Kevin Chou 19c2ece763 fix segmentation fault 2019-05-18 13:48:49 +08:00
W.C.A. Wijngaards 310396190b - Fix #31: swig 4.0 and python module. 2019-05-16 11:06:01 +02:00
W.C.A. Wijngaards a08fe8ca60 - Attempt to fix malformed tcp response. 2019-05-13 15:39:59 +02:00
W.C.A. Wijngaards a95f5fd5cb - Squelch log messages from tcp send about connection reset by peer.
They can be enabled with verbosity at higher values for diagnosing
  network connectivity issues.
2019-05-13 10:39:39 +02:00
W.C.A. Wijngaards a922a19d70 - Revert fix for oss-fuzz, error is in that build script that
unconditionally includes .o files detected by configure, also
  when the machine architecture uses different LIBOBJS files.
2019-05-09 17:07:01 +02:00
W.C.A. Wijngaards a8d0177b36 - Attempt to fix build failure in oss-fuzz
because of reallocarray.
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14648.
Does not omit compile flags from commandline.
2019-05-08 14:43:56 +02:00
W.C.A. Wijngaards 779b86fb22 - Fix doxygen output error on readme markdown vignettes. 2019-05-07 16:11:15 +02:00
W.C.A. Wijngaards e3453711e5 - Fix edns-subnet locks, in error cases the lock was not unlocked. 2019-05-07 16:10:22 +02:00
W.C.A. Wijngaards 73484d3b36 Fix spelling in code annotation of changes
in the public domain lookup3.c file.
2019-05-06 10:10:58 +02:00
W.C.A. Wijngaards f1c23891ab - Fix #30: AddressSanitizer finding in lookup3.c.
This sets the hash function to use a slower but better auditable code
that does not read beyond array boundaries.  This makes code better
security checkable, and is better for security.  It is fixed to be
slower, but not read outside of the array.
2019-05-06 09:44:01 +02:00
W.C.A. Wijngaards 9b7843f879 - Fix #29: Solaris 11.3 and missing symbols be64toh, htobe64. 2019-05-06 09:26:23 +02:00
Kevin Chou 5f4c9b0dfe rollback the code 2019-05-05 10:47:00 +08:00
Kevin Chou 3280e76527 bugfix 2019-05-04 17:39:27 +08:00
Kevin Chou 46099259be performance improvement 2019-05-04 12:52:18 +08:00
Kevin Chu 56af87e2f3 edit config parser to support ipset 2019-05-03 17:45:34 +08:00
W.C.A. Wijngaards bd5eeff364 - And gitignore unit test generated files, and generated doc files. 2019-05-02 16:14:03 +02:00
W.C.A. Wijngaards 2fea5663bd - Fix .gitignore, add pythonmod and dnstap generated files. 2019-05-02 16:01:56 +02:00
Kevin Chu 1a48bdebb5 Add support for ipset 2019-05-02 19:43:30 +08:00
W.C.A. Wijngaards f46c238552 - contrib/fastrpz.patch updated for code changes, and with git diff. 2019-05-02 11:17:41 +02:00
Ralph Dolmans 7e300939c0 Add repology batch to README.md 2019-05-01 18:03:16 +02:00
W.C.A. Wijngaards 409bc229ef Merge branch 'features/XoT' 2019-05-01 16:41:47 +02:00
W.C.A. Wijngaards ee0087d5c7 - PR #16: XoT support, AXFR over TLS
Turn it on with master: <ip>#<authname> in unbound.conf.  This uses TLS to
download the AXFR (or IXFR).
2019-05-01 16:41:09 +02:00
Willem Toorop d4f697f160 Merge branch 'master' into features/XoT 2019-05-01 16:24:52 +02:00
W.C.A. Wijngaards 6e4bab2629 fixup shell 2019-05-01 13:39:32 +02:00
W.C.A. Wijngaards 5c5ddbe859 - Nicer travis output for clang analysis. 2019-05-01 13:34:45 +02:00
gthessandGitHub ea506d0f68 Merge pull request #26 from NLnetLabs/github_readme
Added README.md file for Github use
2019-05-01 13:18:49 +02:00
W.C.A. Wijngaards 27e334e813 fixup to remove .git from makedist tarballs. 2019-05-01 12:47:53 +02:00
W.C.A. Wijngaards 8e48a5cf5f Merge branch 'makedist_from_git' 2019-05-01 12:28:29 +02:00
Ralph Dolmans 9bc81f31d8 Added README.md file for Github use 2019-05-01 12:28:24 +02:00
W.C.A. Wijngaards c6db87d81d - Update makedist for git. 2019-05-01 12:27:19 +02:00
W.C.A. Wijngaards f90e80d3bc update makedist for git 2019-05-01 12:14:41 +02:00
e60f92ea29 Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:41:56 +02:00
46b5e96c54 Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:41:45 +02:00
f5a197f96e Update services/outside_network.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:25:45 +02:00
196654efec Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:25:09 +02:00
a9c8d00d63 Update services/outside_network.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:25:04 +02:00
5e4cfcc665 Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:24:45 +02:00
193cb2fcc4 Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:23:23 +02:00
b57a2f15db Update services/authzone.c
Co-Authored-By: wtoorop <willem@nlnetlabs.nl>
2019-04-29 11:23:11 +02:00
wtooropandGitHub 8d2c08befd Merge pull request #4 from wcawijngaards/features/XoT
Fix test code for call change for XoT.
2019-04-29 10:58:49 +02:00
W.C.A. Wijngaards d9a9f73e82 Fix test code for call change for XoT. 2019-04-29 10:52:25 +02:00
wtooropandGitHub e19da1b619 Merge pull request #3 from wcawijngaards/features/XoT
Fixup fd pass.
2019-04-29 10:44:06 +02:00
W.C.A. Wijngaards 6ce60bcb61 Fixup fd pass. 2019-04-29 10:40:12 +02:00
Wouter WijngaardsandGitHub ff026a1f3c Merge branch 'master' into features/XoT 2019-04-29 10:32:27 +02:00
wtooropandGitHub a37730cee8 Merge pull request #2 from wcawijngaards/features/XoT
Review changes for the XoT branch
2019-04-29 10:27:15 +02:00
W.C.A. Wijngaards af11b54071 Review changes for the XoT branch
With doc, SSL setup function, and function parameter doc.
2019-04-29 10:25:19 +02:00
Wouter Wijngaards 2a78803049 - Fix wrong query name in local zone redirect answers with a CNAME,
the copy of the local alias is in unpacked form.


git-svn-id: file:///svn/unbound/trunk@5175 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-25 14:07:42 +00:00
Ralph Dolmans edf1ad369a - Scrub RRs from answer section when reusing NXDOMAIN message for subdomain
answers.
 - For harden-below-nxdomain: do not consider a name to be non-exitent when
   message contains a CNAME record.


git-svn-id: file:///svn/unbound/trunk@5174 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 15:09:15 +00:00
Wouter Wijngaards 52ea271a65 Remove lint, gives parse errors on system headers.
git-svn-id: file:///svn/unbound/trunk@5173 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 11:34:12 +00:00
Wouter Wijngaards ae54e9013b Add splint to run make lint.
git-svn-id: file:///svn/unbound/trunk@5172 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 11:29:31 +00:00
Wouter Wijngaards 8a3ae4d08a See if make lint works.
git-svn-id: file:///svn/unbound/trunk@5171 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 11:26:07 +00:00
Wouter Wijngaards 1cc54b080a Brackets to stop exiting from the build script.
git-svn-id: file:///svn/unbound/trunk@5170 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 10:41:24 +00:00
Wouter Wijngaards 63171a2522 Disable flto for correct warning report.
git-svn-id: file:///svn/unbound/trunk@5169 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 10:30:33 +00:00
Wouter Wijngaards 2e023a5699 Printout with exit code.
git-svn-id: file:///svn/unbound/trunk@5168 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 10:18:32 +00:00
Wouter Wijngaards 1c1fc36d76 Prinout analysis output (if any).
git-svn-id: file:///svn/unbound/trunk@5167 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 10:05:17 +00:00
Wouter Wijngaards 42d7db578a Fix run directory for clang analysis.
git-svn-id: file:///svn/unbound/trunk@5166 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 09:49:11 +00:00
Wouter Wijngaards d4a6380562 Run clang analysis from travis.
git-svn-id: file:///svn/unbound/trunk@5165 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 09:40:54 +00:00
Wouter Wijngaards 8133251662 Fix to libssl-dev
git-svn-id: file:///svn/unbound/trunk@5164 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 09:35:07 +00:00
Wouter Wijngaards 5a8d314ce3 fixup to libopenssl-dev.
git-svn-id: file:///svn/unbound/trunk@5163 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 09:32:58 +00:00
Wouter Wijngaards 99f36a4e1e - travis build file.
git-svn-id: file:///svn/unbound/trunk@5162 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-18 09:30:35 +00:00
Wouter Wijngaards 61a28c2ee5 - iana portlist updated.
git-svn-id: file:///svn/unbound/trunk@5161 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-16 13:21:22 +00:00
Wouter Wijngaards 2552a81b40 - Better braces in if statement in TCP fastopen code.
git-svn-id: file:///svn/unbound/trunk@5160 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-16 12:53:50 +00:00
Wouter Wijngaards ab6f1d0fc7 - Fix tls write event for read state change to re-call SSL_write and
not resume the TLS handshake.


git-svn-id: file:///svn/unbound/trunk@5159 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-15 11:52:21 +00:00
Wouter Wijngaards c8a56bfa8f - Squelch SSL read and write connection reset by peer and broken pipe
messages.  Verbosity 2 and higher enables them.


git-svn-id: file:///svn/unbound/trunk@5158 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-11 15:04:32 +00:00
George Thessalonikefs d1150541bb - Update python documentation for init_standard().
- Typos.


git-svn-id: file:///svn/unbound/trunk@5157 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-11 15:03:04 +00:00
Wouter Wijngaards ead84a5a64 Nicer.
git-svn-id: file:///svn/unbound/trunk@5156 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-11 13:51:08 +00:00
Wouter Wijngaards c6369e9ffa - Fix that auth zone fails over to next master for timeout in tcp.
git-svn-id: file:///svn/unbound/trunk@5155 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-11 13:41:53 +00:00
Wouter Wijngaards 474afc9016 - Fix that auth zone uses correct network type for sockets for
SOA serial probes.  This fixes that probes fail because earlier
  probe addresses are unreachable.


git-svn-id: file:///svn/unbound/trunk@5154 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-11 08:00:33 +00:00
Wouter Wijngaards bd3c02bd59 - Fix to wipe ssl ticket keys from memory with explicit_bzero,
if available.


git-svn-id: file:///svn/unbound/trunk@5153 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-08 14:42:08 +00:00
Wouter Wijngaards 32b1d900ff Add explanation to changelog.
git-svn-id: file:///svn/unbound/trunk@5152 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-08 14:36:00 +00:00
Wouter Wijngaards 4eac399dfd - Fix #17: Add python module example from Jan Janak, that is a
plugin for the Unbound DNS resolver to resolve DNS records in
  multicast DNS [RFC 6762] via Avahi.


git-svn-id: file:///svn/unbound/trunk@5151 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-08 14:34:58 +00:00
Wouter Wijngaards c26fc84945 - verbose information about auth zone lookup process, also lookup
start, timeout and fail.


git-svn-id: file:///svn/unbound/trunk@5150 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-08 12:42:09 +00:00
Wouter Wijngaards 2b47ca080e - Fix to use event_assign with libevent for thread-safety.
git-svn-id: file:///svn/unbound/trunk@5149 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-08 11:02:34 +00:00
Wouter Wijngaards 348cbab016 - Fix to reinit event structure for accepted TCP (and TLS) sockets.
git-svn-id: file:///svn/unbound/trunk@5148 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-05 14:11:28 +00:00
Wouter Wijngaards a777329b7f - Fix spelling error in log output for event method.
git-svn-id: file:///svn/unbound/trunk@5147 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-04 14:28:39 +00:00
Willem Toorop 92121f7878 Report XoT failure as XoT failure, not https 2019-04-03 12:41:14 +02:00
Wouter Wijngaards ce8167a3bb - Fix auth-zone NSEC3 response for wildcard nodata answers,
include the closest encloser in the answer.


git-svn-id: file:///svn/unbound/trunk@5146 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-03 06:36:40 +00:00
Wouter Wijngaards 937523285a - Move goto label in answer_from_cache to the end of the function
where it is more visible.


git-svn-id: file:///svn/unbound/trunk@5145 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-03 05:32:28 +00:00
Wouter Wijngaards 8a0de6b519 - Fix for auth zone nsec3 ent fix for wildcard nodata.
git-svn-id: file:///svn/unbound/trunk@5144 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-02 14:28:36 +00:00
Wouter Wijngaards e338143639 - Fix for out of bounds integers, thanks to OSTIF audit. It is in
allocation debug code.


git-svn-id: file:///svn/unbound/trunk@5143 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-02 12:28:20 +00:00
Wouter Wijngaards 59570b0413 - Fix auth-zone NSEC3 response for empty nonterminals with exact
match nsec3 records.


git-svn-id: file:///svn/unbound/trunk@5142 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-04-02 12:21:41 +00:00
Wouter Wijngaards 78adebf8ec - Fix crash if tls-servic-pem not filled in when necessary.
git-svn-id: file:///svn/unbound/trunk@5141 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-25 08:51:17 +00:00
Wouter Wijngaards b75c37252c - Fix that tls-session-ticket-keys: "" on its own in unbound.conf
disables the tls session ticker key calls into the OpenSSL API.


git-svn-id: file:///svn/unbound/trunk@5140 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-25 08:47:14 +00:00
Willem Toorop 48ad6477eb AXFR over TLS
Enable by specifying an auth name, like this:
```
auth-zone:
        name: nlnetlabs.nl
        master: 185.49.140.60#ns.nlnetlabs.nl
```
2019-03-24 10:43:57 +01:00
Wouter Wijngaards 296f28e8d0 - Fix #4240: Fix whitespace cleanup in example.conf.
git-svn-id: file:///svn/unbound/trunk@5139 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-21 12:14:20 +00:00
Wouter Wijngaards 83e2cade5b - add type CAA to libpyunbound (accessing libunbound from python).
git-svn-id: file:///svn/unbound/trunk@5138 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-19 12:14:52 +00:00
Wouter Wijngaards ce0628ee55 - Fix #4239: set NOTIMPL when deny-any is enabled, for RFC8482.
git-svn-id: file:///svn/unbound/trunk@5137 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-18 09:26:06 +00:00
Wouter Wijngaards bb5251da66 - Add log message, at verbosity 4, that says the query is encrypted
with TLS, if that is enabled for the query.


git-svn-id: file:///svn/unbound/trunk@5136 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-18 08:41:39 +00:00
Wouter Wijngaards bfd0c5ec85 1.9.1 on 12 March 2019. Trunk has 1.9.2 in development.
git-svn-id: file:///svn/unbound/trunk@5135 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-12 09:33:18 +00:00
Wouter Wijngaards 8092cd6331 - Fix for #4233: guard use of NDEBUG, so that it can be passed in
CFLAGS into configure.


git-svn-id: file:///svn/unbound/trunk@5133 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-07 08:34:00 +00:00
Wouter Wijngaards 7105ea9293 - Tag release 1.9.1rc1.
git-svn-id: file:///svn/unbound/trunk@5132 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-05 08:48:15 +00:00
Philipp Serr efb3697332 Merge branch 'dev/pythonmod-multi-instance/v1.9.0' into dev/all-merged/master 2019-03-02 14:35:19 +01:00
Philipp Serr 56a174bb0f Merge branch 'dev/pythonmod-data/v1.9.0' into dev/all-merged/master 2019-03-02 14:34:58 +01:00
Philipp Serr 9d2980de1a Merge branch 'dev/module_ext_state/v1.9.0' into dev/all-merged/master 2019-03-02 14:34:41 +01:00
Philipp Serr bfae29866b Document how to configure multiple python modules 2019-03-02 14:32:49 +01:00
Philipp Serr b248654aab Support multiple python module instances
This commit adds proper support for multiple instances of the python
module: When more than one instance is added to the module list, the
first instance loads the first script specified in the `python:`
configuration section. The second instance loads the second script,
and so on.

When there are more module instances in the module list than there are
scripts in the `python:` section, an error is raised during
initialization and unbound won't start. When more scripts than module
instances are provided, the surplus scripts are ignored.
2019-03-02 14:32:48 +01:00
Philipp Serr 7cc4ff05ad Initialize per-query qdata and per-module mod_env
The python module used to assign None to the per-query (qdata argument)
and per-module (mod_env variable) data stores. Hence, there was no
obvious way for python code to use these data stores.

This commit initializes both data stores with a dict instance.
2019-03-02 09:26:57 +01:00
Philipp Serr b4a9031cdb Add module_restart_next definition to swig file 2019-03-02 09:25:14 +01:00
Wouter Wijngaards 16cc196bf2 - output forwarder log in ssl_req_order test.
git-svn-id: file:///svn/unbound/trunk@5130 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-03-01 12:38:53 +00:00
Wouter Wijngaards c79a99a577 Fix to account for tabs as well.
git-svn-id: file:///svn/unbound/trunk@5129 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-28 12:06:04 +00:00
Wouter Wijngaards a82c0eeece - Print correct module that failed when module-config is wrong.
git-svn-id: file:///svn/unbound/trunk@5128 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-28 09:56:45 +00:00
Wouter Wijngaards a62c1135fe - Remove memory leak on pythonmod python2 script file init.
- Remove swig gcc8 python function cast warnings, they are ignored.


git-svn-id: file:///svn/unbound/trunk@5127 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-28 09:12:54 +00:00
Wouter Wijngaards ba0cad0bc3 Fixup for python 2
git-svn-id: file:///svn/unbound/trunk@5126 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-27 14:22:55 +00:00
Wouter Wijngaards 7c1f9699d8 - Fix for python module on Windows, fix fopen.
git-svn-id: file:///svn/unbound/trunk@5125 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-27 14:14:08 +00:00
Wouter Wijngaards 33a814683b - Fix #14: contrib/unbound.init: Fix wrong comparison judgment
before copying.


git-svn-id: file:///svn/unbound/trunk@5124 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-27 06:58:10 +00:00
Wouter Wijngaards beebe5ba0c - Fix #4229: Unbound man pages lack information, about access-control
order and local zone tags, and elements in views.


git-svn-id: file:///svn/unbound/trunk@5123 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-27 06:56:21 +00:00
Wouter Wijngaards 225534e5ab - Fix #4227: pair event del and add for libevent for tcp_req_info.
git-svn-id: file:///svn/unbound/trunk@5122 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-25 15:48:27 +00:00
Wouter Wijngaards 3599fd9c60 - In man page and example config explain that most modules have to
be listed at the start of module-config.


git-svn-id: file:///svn/unbound/trunk@5121 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-21 10:03:11 +00:00
Wouter Wijngaards 5b162ead92 - In example.conf explain where to put cachedb module in module-config.
git-svn-id: file:///svn/unbound/trunk@5120 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-21 09:48:38 +00:00
Wouter Wijngaards 62428e17f6 - Fix the error for unknown module in module-config is understandable,
and explains it was not compiled in and where to see the list.


git-svn-id: file:///svn/unbound/trunk@5119 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-21 09:40:25 +00:00
Wouter Wijngaards 079253670e - Fix pythonmod include and sockaddr_un ifdefs for compile on
Windows, and for libunbound.


git-svn-id: file:///svn/unbound/trunk@5118 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-20 15:19:58 +00:00
Wouter Wijngaards 91e863138b - Print query name and IP address when domain rate limit exceeded.
git-svn-id: file:///svn/unbound/trunk@5117 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-18 15:53:02 +00:00
Wouter Wijngaards d1e92a0ebd - Spaces instead of tabs in that log message.
git-svn-id: file:///svn/unbound/trunk@5116 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-18 12:32:42 +00:00
Wouter Wijngaards 3949bf2c82 - Print query name with ip_ratelimit exceeded log lines.
git-svn-id: file:///svn/unbound/trunk@5115 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-18 10:40:41 +00:00
Wouter Wijngaards a41375411e - Fix capsforid canonical sort qsort callback.
git-svn-id: file:///svn/unbound/trunk@5114 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-14 08:16:15 +00:00
Wouter Wijngaards 030832cf12 - make depend, with newer gcc, nicer layout.
git-svn-id: file:///svn/unbound/trunk@5113 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-11 10:02:45 +00:00
Wouter Wijngaards 49a36d98bb - Fix #13: Remove left-over requirements on OpenSSL >= 1.1.0 for
cert name matching, from man page.


git-svn-id: file:///svn/unbound/trunk@5112 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-11 09:59:47 +00:00
Wouter Wijngaards ddae2885bd Also fix this unit test for qname minimisation
asked queries that have to be added to the provided answer list.


git-svn-id: file:///svn/unbound/trunk@5111 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-11 09:56:57 +00:00
Wouter Wijngaards 19193fd534 - Fix recursion lame test for qname minimisation asked queries,
that were not present in the set of prepared answers.


git-svn-id: file:///svn/unbound/trunk@5110 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-11 09:49:13 +00:00
Wouter Wijngaards 4e249c96e8 - Note default for module-config in man page.
git-svn-id: file:///svn/unbound/trunk@5109 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-11 08:53:59 +00:00
Wouter Wijngaards cae8361dcd - Fix #4225: clients seem to erroneously receive no answer with
DNS-over-TLS and qname-minimisation.


git-svn-id: file:///svn/unbound/trunk@5108 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-08 15:05:24 +00:00
Wouter Wijngaards 429e130768 - Fix that qname minimisation does not skip a label when missing
nameserver targets need to be fetched.


git-svn-id: file:///svn/unbound/trunk@5107 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-08 13:30:51 +00:00
Wouter Wijngaards 20d57ec58b - Fix #4206: OpenSSL 1.0.2 hostname verification for FreeBSD 11.2.
git-svn-id: file:///svn/unbound/trunk@5106 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-07 08:34:28 +00:00
Wouter Wijngaards e43c3daec2 Trunk has 1.9.1 in development.
git-svn-id: file:///svn/unbound/trunk@5105 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-05 09:26:39 +00:00
Wouter Wijngaards 64c4e69b07 Release version numbers.
git-svn-id: file:///svn/unbound/trunk@5102 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-05 08:17:36 +00:00
Wouter Wijngaards a9e028564d Keep scratch region free on exit.
git-svn-id: file:///svn/unbound/trunk@5101 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-04 15:48:21 +00:00
Wouter Wijngaards 99994a26b0 - Perform canonical sort for 0x20 capsforid compare of replies,
this sorts rrsets in the authority and additional section before
  comparison, so that out of order rrsets do not cause failure.


git-svn-id: file:///svn/unbound/trunk@5100 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-04 15:22:08 +00:00
Wouter Wijngaards fe97f25b75 - Fix that log-replies prints the correct name for local-alias
names, for names that have a CNAME in local-data configuration.
  It logs the original query name, not the target of the CNAME.
- Add local-zone type inform_redirect, which logs like type inform,
  and redirects like type redirect.


git-svn-id: file:///svn/unbound/trunk@5099 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-02-04 09:51:27 +00:00
Wouter Wijngaards 281030d576 - Wipe TLS session key data from memory on exit.
git-svn-id: file:///svn/unbound/trunk@5098 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 15:25:27 +00:00
Wouter Wijngaards 8992e8c91f note ticker number.
git-svn-id: file:///svn/unbound/trunk@5097 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 12:35:33 +00:00
Wouter Wijngaards b34a6defc1 - Fix OpenSSL without ENGINE support compilation.
git-svn-id: file:///svn/unbound/trunk@5096 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 12:33:28 +00:00
Wouter Wijngaards 8cf5eae166 - Fix OpenSSL without ENGINE support compilation.
git-svn-id: file:///svn/unbound/trunk@5095 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 11:34:11 +00:00
Wouter Wijngaards df8f236b62 - For openssl 1.0.2 use the CRYPTO_THREADID locking callbacks,
still supports the set_id_callback previous API.  And for 1.1.0
  no locking callbacks are needed.


git-svn-id: file:///svn/unbound/trunk@5094 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 11:31:55 +00:00
Wouter Wijngaards 273ff1201b - fixed pkg-config operations, PKG_PROG_PKG_CONFIG moved out of
conditional section, fixes systemd builds, from Enrico Scholz.


git-svn-id: file:///svn/unbound/trunk@5093 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 10:21:54 +00:00
Wouter Wijngaards 91f585ed38 - improve documentation for forward-first.
git-svn-id: file:///svn/unbound/trunk@5092 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 09:37:06 +00:00
Wouter Wijngaards b9b226bdea - improve documentation for tls-service-key.
git-svn-id: file:///svn/unbound/trunk@5091 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 09:22:48 +00:00
Wouter Wijngaards 8fffdca2a6 - Set ub_ctx_set_tls call signature in ltrace config file for
libunbound in contrib/libunbound.so.conf.


git-svn-id: file:///svn/unbound/trunk@5090 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-31 09:16:15 +00:00
Ralph Dolmans 723845b350 - Fix case in which query timeout can result in marking delegation as
edns_lame_known.


git-svn-id: file:///svn/unbound/trunk@5089 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-30 13:44:19 +00:00
Wouter Wijngaards 31b677b35f - Fix locking for libunbound context setup with broken port config.
git-svn-id: file:///svn/unbound/trunk@5088 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-29 16:07:07 +00:00
Wouter Wijngaards c2e3baa81a - Fix #4224: auth_xfr_notify.rpl test broken due to typo
git-svn-id: file:///svn/unbound/trunk@5087 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-29 14:37:35 +00:00
Wouter Wijngaards 7273b35243 - Fix spelling of tls-ciphers in example.conf.in.
git-svn-id: file:///svn/unbound/trunk@5086 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-29 12:43:56 +00:00
Wouter Wijngaards dfe8e0dfa2 - set version to 1.9.0 for release.
git-svn-id: file:///svn/unbound/trunk@5084 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-29 08:07:50 +00:00
Wouter Wijngaards 7ad8ffccf5 - List example config for root zone copy locally hosted with auth-zone
as suggested from draft-ietf-dnsop-7706-bis-02.  But with updated
  B root address.



git-svn-id: file:///svn/unbound/trunk@5083 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-28 08:49:12 +00:00
Wouter Wijngaards 065c7c5dd8 - List d.root-servers.net as a host that allows AXFR in example.conf
config file, as suggested from draft-ietf-dnsop-7706-bis-02.


git-svn-id: file:///svn/unbound/trunk@5082 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-28 08:39:50 +00:00
Wouter Wijngaards 71744b8bb2 - Set build system for added call in the libunbound API.
git-svn-id: file:///svn/unbound/trunk@5081 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-28 08:26:10 +00:00
Wouter Wijngaards 3d2dfc4769 - ub_ctx_set_tls call for libunbound that enables DoT for the machines
set with ub_ctx_set_fwd.  Patch from Florian Obser.


git-svn-id: file:///svn/unbound/trunk@5080 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-28 08:22:08 +00:00
Wouter Wijngaards 5e4f0d65ce Fix year on recent commit messages.
git-svn-id: file:///svn/unbound/trunk@5079 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 16:19:37 +00:00
Wouter Wijngaards aae44940c7 - output of newer lex 2.6.1 and bison 3.0.5.
git-svn-id: file:///svn/unbound/trunk@5078 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 13:00:09 +00:00
Wouter Wijngaards 062c2cacfc - remove compile warnings from libnettle compile.
git-svn-id: file:///svn/unbound/trunk@5077 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 12:58:06 +00:00
Wouter Wijngaards ce65cdde71 - no lock when threads disabled in tcp request buffer count.
git-svn-id: file:///svn/unbound/trunk@5076 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 12:54:40 +00:00
Wouter Wijngaards b005fcd87b - updated contrib/fastrpz.patch to cleanly diff.
git-svn-id: file:///svn/unbound/trunk@5075 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 12:50:45 +00:00
Wouter Wijngaards f11d6653d6 - Fix that tcp for auth zone and outgoing does not remove and
then gets the ssl read again applied to the deleted commpoint.


git-svn-id: file:///svn/unbound/trunk@5074 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-25 12:46:15 +00:00
Wouter Wijngaards 20d5e35576 - Moved includes and make depend.
git-svn-id: file:///svn/unbound/trunk@5073 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 16:10:05 +00:00
Wouter Wijngaards 3028fa50a8 - Patch from Florian Obser fixes some compiler warnings:
include mini_event.h to have a prototype for mini_ev_cmp
  include edns.h to have a prototype for apply_edns_options
  sldns_wire2str_edns_keepalive_print is only called in the wire2str,
  module declare it static to get rid of compiler warning:
  no previous prototype for function
  infra_find_ip_ratedata() is only called in the infra module,
  declare it static to get rid of compiler warning:
  no previous prototype for function
  do not shadow local variable buf in authzone
  auth_chunks_delete and az_nsec3_findnode are only called in the
  authzone module, declare them static to get rid of compiler warning:
  no previous prototype for function...
  copy_rrset() is only called in the respip module, declare it
  static to get rid of compiler warning:
  no previous prototype for function 'copy_rrset'
  no need for another variable "r"; gets rid of compiler warning:
  declaration shadows a local variable in libunbound.c
  no need for another variable "ns"; gets rid of compiler warning:
  declaration shadows a local variable in iterator.c



git-svn-id: file:///svn/unbound/trunk@5072 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 16:05:00 +00:00
Wouter Wijngaards e584933b2b make fix nicer in perf testcode.
git-svn-id: file:///svn/unbound/trunk@5071 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 12:52:26 +00:00
Wouter Wijngaards d48abb9a84 clang analysis fixes, assert arc4random buffer in init,
no check for already checked delegation pointer in iterator,
in testcode check for NULL packet matches, in perf do not copy
from NULL start list when growing capacity.  Adjust host and file
only when present in test header read to please checker.  In
testcode for unknown macro operand give zero result. Initialise the
passed argv array in test code.  In test code add EDNS data
segment copy only when nonempty.


git-svn-id: file:///svn/unbound/trunk@5070 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 11:55:10 +00:00
Wouter Wijngaards 37361a1d10 - Fix unit test for python 3.7 new keyword 'async'.
git-svn-id: file:///svn/unbound/trunk@5069 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 09:37:57 +00:00
Wouter Wijngaards 299cc0c689 - Newer aclocal and libtoolize used for generating configure scripts,
aclocal 1.16.1 and libtoolize 2.4.6.


git-svn-id: file:///svn/unbound/trunk@5068 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-24 08:57:47 +00:00
Wouter Wijngaards 707e5a915b Neater spaces
git-svn-id: file:///svn/unbound/trunk@5067 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 14:18:24 +00:00
Wouter Wijngaards 649e265d6f - Fix for IXFR fallback to reset counter when IXFR does not timeout.
git-svn-id: file:///svn/unbound/trunk@5066 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 11:52:17 +00:00
Wouter Wijngaards 9d4ca81959 Fixup ssl unit test with example ticket files.
git-svn-id: file:///svn/unbound/trunk@5065 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 10:50:26 +00:00
Wouter Wijngaards 68a57554a6 For TLS session keys, keep config options in order read from file to keep the first one as the first one.
git-svn-id: file:///svn/unbound/trunk@5064 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 10:41:03 +00:00
Wouter Wijngaards cc9fb69911 fix lint and clang analysis errors
git-svn-id: file:///svn/unbound/trunk@5063 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 10:23:02 +00:00
Wouter Wijngaards d3f397c686 More fixes, statistic counter at end of struct for backwards compatibility, man page, free at exit, indent.
git-svn-id: file:///svn/unbound/trunk@5062 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 10:19:04 +00:00
Wouter Wijngaards ed8b859e31 make depend
git-svn-id: file:///svn/unbound/trunk@5061 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 09:44:08 +00:00
Wouter Wijngaards 011a7d8830 - Fixes for patch (includes, declarations, warnings).
git-svn-id: file:///svn/unbound/trunk@5060 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 09:43:47 +00:00
Wouter Wijngaards 510606dd1c - Patch for TLS session resumption from Manabu Sonoda,
enable with tls-session-ticket-keys in unbound.conf.


git-svn-id: file:///svn/unbound/trunk@5059 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 09:35:52 +00:00
Wouter Wijngaards 4e59c8344f - Fix configure to detect SSL_CTX_set_ciphersuites, for better
library compatibility when compiling.


git-svn-id: file:///svn/unbound/trunk@5058 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 08:57:49 +00:00
Wouter Wijngaards 4c8f334c15 another spelling fix.
git-svn-id: file:///svn/unbound/trunk@5057 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 08:48:52 +00:00
Wouter Wijngaards 2f52ecdd9c lex and yacc.
git-svn-id: file:///svn/unbound/trunk@5056 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 08:46:33 +00:00
Wouter Wijngaards 5d82b7c421 - Fixes for the patch, and man page entry.
git-svn-id: file:///svn/unbound/trunk@5055 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 08:45:16 +00:00
Wouter Wijngaards 8ae9f26bce - Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
options for unbound.conf.


git-svn-id: file:///svn/unbound/trunk@5054 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-23 08:37:00 +00:00
Wouter Wijngaards 55f560a3ca - Fix that auth zone after IXFR fallback tries the same master.
git-svn-id: file:///svn/unbound/trunk@5053 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 15:44:09 +00:00
Wouter Wijngaards 51caffb454 - Fix for #4219: secondaries not updated after serial change, unbound
falls back to AXFR after IXFR gives several timeout failures.


git-svn-id: file:///svn/unbound/trunk@5052 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 15:36:58 +00:00
Wouter Wijngaards ef1baf94f7 Fix lint and unit test.
git-svn-id: file:///svn/unbound/trunk@5051 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 13:35:33 +00:00
Wouter Wijngaards 8b18d1a0a4 - unbound-control stats has mem.streamwait that counts TCP and TLS
waiting result buffers.


git-svn-id: file:///svn/unbound/trunk@5050 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 13:20:06 +00:00
Wouter Wijngaards 4481b9584c Fix test failure.
git-svn-id: file:///svn/unbound/trunk@5049 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 10:29:01 +00:00
Wouter Wijngaards dec68aa9a9 - Doc for stream-wait-size and unit test.
git-svn-id: file:///svn/unbound/trunk@5048 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 08:52:23 +00:00
Wouter Wijngaards c10712a82b - Fix space calculation for tcp req buffer size.
git-svn-id: file:///svn/unbound/trunk@5047 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-22 08:27:49 +00:00
Wouter Wijngaards d81e2c654f - Add stream-wait-size: 4m config option to limit the maximum
memory used by waiting tcp and tls stream replies.  This avoids
  a denial of service where these replies use up all of the memory.


git-svn-id: file:///svn/unbound/trunk@5046 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 16:20:14 +00:00
Wouter Wijngaards f5dcd84d27 Fix reread of buffer data, better, also for TCP.
git-svn-id: file:///svn/unbound/trunk@5045 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 14:14:12 +00:00
Wouter Wijngaards 7c4911c577 No leaks found.
git-svn-id: file:///svn/unbound/trunk@5044 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 13:45:13 +00:00
Wouter Wijngaards be4583ac84 - Fix that multiple dns fragments can be carried in one TLS frame.
git-svn-id: file:///svn/unbound/trunk@5043 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 13:41:13 +00:00
Wouter Wijngaards 068374740c - Unit tests for ssl out of order processing.
git-svn-id: file:///svn/unbound/trunk@5042 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 13:26:21 +00:00
Wouter Wijngaards f7d63b0927 - Unit test for tcp request reorder and timeouts.
git-svn-id: file:///svn/unbound/trunk@5041 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 13:04:08 +00:00
Wouter Wijngaards 9087b18234 - Fix tcp idle timeout test, for difference in the tcp reply code.
git-svn-id: file:///svn/unbound/trunk@5040 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-21 09:36:01 +00:00
Wouter Wijngaards 19a3907657 - increase mesh max activation count for capsforid long fetches.
git-svn-id: file:///svn/unbound/trunk@5039 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-17 08:58:09 +00:00
Wouter Wijngaards 762920232a - For caps-for-id fallback, use the whitelist to avoid timeout
starting a fallback sequence for it.


git-svn-id: file:///svn/unbound/trunk@5038 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-17 08:50:25 +00:00
Ralph Dolmans f30fe71395 - Get ready for the DNS flag day: remove EDNS lame procedure, do not re-query
without EDNS after timeout.


git-svn-id: file:///svn/unbound/trunk@5037 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-16 10:23:13 +00:00
Wouter Wijngaards ec6f4bab46 comment fixes after review.
git-svn-id: file:///svn/unbound/trunk@5036 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-15 13:42:22 +00:00
Wouter Wijngaards 0d2efc3f3f - Review fixes in out of order processing.
git-svn-id: file:///svn/unbound/trunk@5035 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-15 10:27:00 +00:00
Wouter Wijngaards bb480068fa - In the out of order processing, reset byte count for (potential)
partial read.


git-svn-id: file:///svn/unbound/trunk@5034 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-15 09:24:00 +00:00
Wouter Wijngaards ae9fe1a10e - streamtcp option -a send queries consecutively and prints answers
as they arrive.
- Fix for out of order processing administration quit cleanup.
- unit test for tcp out of order processing.


git-svn-id: file:///svn/unbound/trunk@5033 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-14 15:52:50 +00:00
Wouter Wijngaards dd19026e91 - Initial commit for out-of-order processing for TCP and TLS.
git-svn-id: file:///svn/unbound/trunk@5032 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-11 14:12:27 +00:00
Wouter Wijngaards 42d2c04ae1 - Log query name for looping module errors.
git-svn-id: file:///svn/unbound/trunk@5031 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-09 13:57:14 +00:00
Wouter Wijngaards db2557826a - Fix NSEC3 record that is returned in wildcard replies from
auth-zone zones with NSEC3 and wildcards.


git-svn-id: file:///svn/unbound/trunk@5030 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-08 14:39:31 +00:00
Wouter Wijngaards 11d98df304 - Fix syntax in comment of local alias processing.
git-svn-id: file:///svn/unbound/trunk@5029 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-08 13:29:38 +00:00
Wouter Wijngaards ec84fd2ca6 - Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
the patch adds a program used for fuzzing.


git-svn-id: file:///svn/unbound/trunk@5028 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-07 15:01:24 +00:00
Wouter Wijngaards fe6eb5f665 - Document interaction between the tls-upstream option in the server
section and forward-tls-upstream option in the forward-zone sections.


git-svn-id: file:///svn/unbound/trunk@5027 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-07 10:52:08 +00:00
Wouter Wijngaards 90b00dfe57 - On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
and server tcp fastopen is enabled at compile time.


git-svn-id: file:///svn/unbound/trunk@5026 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-07 09:06:41 +00:00
Wouter Wijngaards 023411f975 - Fix for crash in dns64 module if response is null.
git-svn-id: file:///svn/unbound/trunk@5025 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-12 16:03:05 +00:00
Wouter Wijngaards a97bfa08ec trunk had 1.8.2, Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec.
Trunk then became 1.8.4 in development.


git-svn-id: file:///svn/unbound/trunk@5024 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-11 11:08:57 +00:00
Wouter Wijngaards 9c2a45c59e svn trunk 1.8.2, Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec.
Trunk then became 1.8.4 in development.


git-svn-id: file:///svn/unbound/trunk@5020 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-11 09:44:16 +00:00
Wouter Wijngaards 1b72e814e7 - Fixup openssl 1.0.2 compile
git-svn-id: file:///svn/unbound/trunk@5019 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 14:36:43 +00:00
Wouter Wijngaards 71b078611f - Fix #4206: support openssl 1.0.2 for TLS hostname verification,
alongside the 1.1.0 and later support that is already there.


git-svn-id: file:///svn/unbound/trunk@5018 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 14:27:24 +00:00
Wouter Wijngaards 1ef8cfcac5 - Fix for FreeBSD port make with dnscrypt and dnstap enabled.
git-svn-id: file:///svn/unbound/trunk@5017 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 13:14:57 +00:00
Wouter Wijngaards 6b8e316663 - Fix for FreeBSD port make with dnscrypt and dnstap enabled.
git-svn-id: file:///svn/unbound/trunk@5016 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 10:41:33 +00:00
Wouter Wijngaards 21d03697ca - ip-ratelimit-factor of 1 allows all traffic through, instead of the
previous blocking everything.


git-svn-id: file:///svn/unbound/trunk@5015 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 09:38:50 +00:00
Wouter Wijngaards 4c7f824e0a - Fix config parser memory leaks.
git-svn-id: file:///svn/unbound/trunk@5014 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-10 09:27:49 +00:00
Wouter Wijngaards 42244e1b4d - Fix dns64 allocation in wrong region for returned internal queries.
git-svn-id: file:///svn/unbound/trunk@5013 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-06 08:04:37 +00:00
Wouter Wijngaards 2981adac66 trunk has 1.8.3 in development.
git-svn-id: file:///svn/unbound/trunk@5012 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-04 09:30:03 +00:00
Wouter Wijngaards 91971db3d0 And document.
git-svn-id: file:///svn/unbound/trunk@5009 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 14:56:12 +00:00
Wouter Wijngaards b4e8ab4254 Fix test.
git-svn-id: file:///svn/unbound/trunk@5008 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 14:54:29 +00:00
Wouter Wijngaards 198a7ce74d - cache-max-ttl also defines upperbound of initial TTL in response.
git-svn-id: file:///svn/unbound/trunk@5007 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 14:50:47 +00:00
Wouter Wijngaards e103490376 Cleaner image.
git-svn-id: file:///svn/unbound/trunk@5006 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 11:24:51 +00:00
Wouter Wijngaards f3658c210c Fixup icon lines.
git-svn-id: file:///svn/unbound/trunk@5005 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 11:16:17 +00:00
Wouter Wijngaards 1ba3682d9b remove unnecessary files, they are in combined.ico.
git-svn-id: file:///svn/unbound/trunk@5004 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 10:39:35 +00:00
Wouter Wijngaards 39b7468bab Fixup icon more, for small icon display on Windows 10.
git-svn-id: file:///svn/unbound/trunk@5003 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 10:09:54 +00:00
Wouter Wijngaards a42e9aaaba more fixes, higher colormap.
git-svn-id: file:///svn/unbound/trunk@5002 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 09:06:05 +00:00
Wouter Wijngaards a9b7194485 - Fix icon, no ragged edges and nicer resolutions available, for eg.
Win 7 and Windows 10 display.


git-svn-id: file:///svn/unbound/trunk@5001 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-12-03 08:30:55 +00:00
Wouter Wijngaards 2ad55ba791 - log-tag-queryreply: yes in unbound.conf tags the log-queries and
log-replies in the log file for easier log filter maintenance.


git-svn-id: file:///svn/unbound/trunk@5000 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-30 09:45:37 +00:00
Wouter Wijngaards ac8dc59341 - Patch for typo in unbound.conf man page.
git-svn-id: file:///svn/unbound/trunk@4999 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-30 08:33:50 +00:00
Wouter Wijngaards c1c1cd97e7 - Remove clang analysis warnings.
git-svn-id: file:///svn/unbound/trunk@4998 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 14:39:26 +00:00
Wouter Wijngaards b23c373f4d - Refuse to start with no ports.
git-svn-id: file:///svn/unbound/trunk@4997 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 14:26:16 +00:00
Wouter Wijngaards e6da6c251c Fixup test.
git-svn-id: file:///svn/unbound/trunk@4996 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 13:09:46 +00:00
Wouter Wijngaards 81ded6124d - Fix that unbound-checkconf does not complains if the config file
is not placed inside the chroot.


git-svn-id: file:///svn/unbound/trunk@4995 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 12:55:13 +00:00
Wouter Wijngaards c417f733af - tag for 1.8.2rc1.
git-svn-id: file:///svn/unbound/trunk@4994 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 09:27:19 +00:00
Wouter Wijngaards 63dcbe3d75 - Fix chroot auth-zone fix to remove chroot prefix.
git-svn-id: file:///svn/unbound/trunk@4992 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 08:27:47 +00:00
Wouter Wijngaards fb342b73d3 - iana portlist updated.
git-svn-id: file:///svn/unbound/trunk@4991 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-29 08:27:22 +00:00
Wouter Wijngaards cccb5094a4 - Fix clang analysis for outside directory build test.
git-svn-id: file:///svn/unbound/trunk@4990 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-28 13:34:31 +00:00
Wouter Wijngaards 3330d5296c - Fix leak in chroot fix for auth-zone.
git-svn-id: file:///svn/unbound/trunk@4989 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-28 12:37:52 +00:00
Wouter Wijngaards f95f98b12a - Update contrib fastrpz patch for latest release.
git-svn-id: file:///svn/unbound/trunk@4988 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 15:47:52 +00:00
Wouter Wijngaards 7bb6358540 Better fix.
git-svn-id: file:///svn/unbound/trunk@4987 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 13:46:44 +00:00
Wouter Wijngaards ca33c52086 - Fix windows compile for new rrset roundrobin fix.
git-svn-id: file:///svn/unbound/trunk@4986 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 13:35:29 +00:00
Wouter Wijngaards aba3ba738f - Put new logos into windows installer.
git-svn-id: file:///svn/unbound/trunk@4985 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 13:24:40 +00:00
Wouter Wijngaards 60da4369a4 - stat count SERVFAIL downstream auth-zone queries for expired zones.
git-svn-id: file:///svn/unbound/trunk@4984 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 12:42:59 +00:00
Wouter Wijngaards b04e84ab9e - auth-zone give SERVFAIL when expired, fallback activates when
expired, and this is documented in the man page.


git-svn-id: file:///svn/unbound/trunk@4983 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 12:31:37 +00:00
Wouter Wijngaards d96de4c222 - New and better fix for Fix #4193: Fix that prefetch failure does
not overwrite valid cache entry with SERVFAIL.


git-svn-id: file:///svn/unbound/trunk@4982 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 10:56:45 +00:00
Wouter Wijngaards 0ff5c52657 - Fix #4208: 'stub-no-cache' and 'forward-no-cache' not work.
git-svn-id: file:///svn/unbound/trunk@4981 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 10:29:14 +00:00
Wouter Wijngaards f532367412 Review fix.
git-svn-id: file:///svn/unbound/trunk@4980 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 09:05:00 +00:00
Wouter Wijngaards 94996b8a29 - Fix DNS64 to not store intermediate results in cache, this avoids
other threads from picking up the wrong data.  The module restores
  the previous no_cache_store setting when the the module is finished.


git-svn-id: file:///svn/unbound/trunk@4979 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-27 08:43:38 +00:00
Wouter Wijngaards 59e6f149a7 - Fix that unbound-control can send file for view_local_datas.
git-svn-id: file:///svn/unbound/trunk@4978 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-26 13:55:36 +00:00
Wouter Wijngaards 470806b097 - Add unbound-control view_local_datas command, like local_datas.
git-svn-id: file:///svn/unbound/trunk@4977 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-26 13:37:23 +00:00
Wouter Wijngaards 8fcc82171a - Fix #4193: Fix that prefetch failure does not overwrite valid cache
entry with SERVFAIL.


git-svn-id: file:///svn/unbound/trunk@4976 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-26 10:25:50 +00:00
Wouter Wijngaards 4d5b32ee59 - Fix to not set GLOB_NOSORT so the unbound.conf include: files are
sorted and in a predictable order.


git-svn-id: file:///svn/unbound/trunk@4975 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-26 09:54:34 +00:00
Wouter Wijngaards 816aa50dfc - make depend.
git-svn-id: file:///svn/unbound/trunk@4974 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 15:57:15 +00:00
Wouter Wijngaards 068c52d8f5 - Fix that empty zonefile means the zonefile is not set and not used.
git-svn-id: file:///svn/unbound/trunk@4973 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 15:55:18 +00:00
Wouter Wijngaards 692caffe2c - auth zone zonefiles can be in a chroot, the chroot directory
components are removed before use.


git-svn-id: file:///svn/unbound/trunk@4972 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 15:51:09 +00:00
Wouter Wijngaards c97bb52d77 - Fix #4209: Crash in libunbound when called from getdns.
git-svn-id: file:///svn/unbound/trunk@4971 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 15:07:30 +00:00
Wouter Wijngaards 438634b718 nicer python error log errors.
git-svn-id: file:///svn/unbound/trunk@4970 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 13:47:37 +00:00
Wouter Wijngaards d21cb609a8 - review fixes for python module.
git-svn-id: file:///svn/unbound/trunk@4969 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 13:31:21 +00:00
Wouter Wijngaards 668c0627c0 Fix compare signed with unsigned in python interface for pythonmod
git-svn-id: file:///svn/unbound/trunk@4968 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 13:07:37 +00:00
Wouter Wijngaards de0b6da9f4 - ignore debug python module for test in doxygen output.
git-svn-id: file:///svn/unbound/trunk@4967 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 13:05:26 +00:00
Wouter Wijngaards 5853f90076 - With ./configure --with-pyunbound --with-pythonmodule
PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests
  succeed for the python module.
- pythonmod logs the python error and traceback on failure.


git-svn-id: file:///svn/unbound/trunk@4966 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-22 13:01:29 +00:00
Wouter Wijngaards 022d5131b3 Fixup.
git-svn-id: file:///svn/unbound/trunk@4965 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-21 06:44:24 +00:00
Wouter Wijngaards 7458729d28 - Scrub NS records from NODATA responses as well.
git-svn-id: file:///svn/unbound/trunk@4964 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-21 06:37:00 +00:00
Wouter Wijngaards 7acf6a4a66 - Removed compile warnings in pythonmod sockaddr routines.
git-svn-id: file:///svn/unbound/trunk@4963 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-20 12:28:09 +00:00
Wouter Wijngaards 04d73b9192 - Add patch from Jan Vcelak for pythonmod,
add sockaddr_storage getters, add support for query callbacks,
  allow raw address access via comm_reply and update API documentation.


git-svn-id: file:///svn/unbound/trunk@4962 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-20 12:24:40 +00:00
Wouter Wijngaards f7e99131b9 - Scrub NS records from NXDOMAIN responses to stop fragmentation
poisoning of the cache.


git-svn-id: file:///svn/unbound/trunk@4961 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-20 09:44:40 +00:00
Wouter Wijngaards 069b0b8c90 - Support SO_REUSEPORT_LB in FreeBSD 12 with the so-reuseport: yes
option in unbound.conf.


git-svn-id: file:///svn/unbound/trunk@4960 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-19 09:36:27 +00:00
Ralph Dolmans 1ff7a89433 - added contrib config files to gitignore
git-svn-id: file:///svn/unbound/trunk@4959 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-14 09:51:31 +00:00
Ralph Dolmans 640d1cf929 - Bugfix min-client-subnet-ipv6
git-svn-id: file:///svn/unbound/trunk@4958 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-11-06 09:44:10 +00:00
Wouter Wijngaards c9955f9fdf - Fix #4152: Logs shows wrong time when using log-time-ascii: yes.
git-svn-id: file:///svn/unbound/trunk@4957 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 13:52:13 +00:00
Wouter Wijngaards 9a877e0e9a - remade makefile dependencies.
(note the make depend just done).


git-svn-id: file:///svn/unbound/trunk@4956 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 09:31:25 +00:00
Wouter Wijngaards 6b49224c85 make depend
git-svn-id: file:///svn/unbound/trunk@4955 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 09:30:57 +00:00
Wouter Wijngaards fd5e4e6019 - Fix #4126: RTT_band too low on VSAT links with 600+ms latency,
adds the option unknown-server-time-limit to unbound.conf that
  can be increased to avoid the problem.


git-svn-id: file:///svn/unbound/trunk@4954 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 09:21:41 +00:00
Wouter Wijngaards 8e2a100460 - Fix #4132: Openness/closeness of RANGE intervals in rpl files.
git-svn-id: file:///svn/unbound/trunk@4953 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 09:01:53 +00:00
Ralph Dolmans 359dcc3c5c Document min-client-subnet-ipv4/6 default value
git-svn-id: file:///svn/unbound/trunk@4952 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 08:55:55 +00:00
Ralph Dolmans 6021341118 - Add min-client-subnet-ipv6 and min-client-subnet-ipv4 options.
git-svn-id: file:///svn/unbound/trunk@4951 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 08:53:50 +00:00
Wouter Wijngaards d5922830d0 - Fix #4141: More randomness to rrset-roundrobin.
git-svn-id: file:///svn/unbound/trunk@4950 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 08:26:40 +00:00
Wouter Wijngaards 23505d30a5 - Fix #4190: Please create a "ANY" deny option, adds the option
deny-any: yes in unbound.conf.  This responds with an empty message
  to queries of type ANY.


git-svn-id: file:///svn/unbound/trunk@4949 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 08:07:37 +00:00
Wouter Wijngaards 0f83653e76 Move rcode code back.
git-svn-id: file:///svn/unbound/trunk@4948 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 07:49:49 +00:00
Wouter Wijngaards 20f0e8ad55 - Fix #4191: NXDOMAIN vs SERVFAIL during dns64 PTR query.
git-svn-id: file:///svn/unbound/trunk@4947 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-25 07:45:00 +00:00
Ralph Dolmans 140a165ab2 - Add markdel function to ECS slabhash.
- Limit ECS scope returned to client to the scope used for caching.      
 - Make lint like previous #4154 fix. 


git-svn-id: file:///svn/unbound/trunk@4946 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-24 13:50:18 +00:00
Wouter Wijngaards 5fec1c8b1f - Fix #4154: make ECS_MAX_TREESIZE configurable, with
the max-ecs-tree-size-ipv4 and max-ecs-tree-size-ipv6 options.


git-svn-id: file:///svn/unbound/trunk@4945 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-22 14:54:28 +00:00
Wouter Wijngaards 6bd4060ae0 portability.
git-svn-id: file:///svn/unbound/trunk@4944 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-22 10:19:30 +00:00
Wouter Wijngaards 84a8415357 - check that the dnstap socket file can be opened and exists, print
error if not.


git-svn-id: file:///svn/unbound/trunk@4943 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-22 10:17:38 +00:00
Wouter Wijngaards 6429b5c298 - Fix #4192: unbound-control-setup generates keys not readable by
group.


git-svn-id: file:///svn/unbound/trunk@4942 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-22 10:07:13 +00:00
Ralph Dolmans 6b5e7d78e3 - Change fast-server-num default to 3.
git-svn-id: file:///svn/unbound/trunk@4941 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-22 09:36:36 +00:00
Ralph Dolmans a8b2c64cbf More lint pleasing
git-svn-id: file:///svn/unbound/trunk@4940 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 16:38:25 +00:00
Ralph Dolmans 9268f0db50 Please lint by using proper types
git-svn-id: file:///svn/unbound/trunk@4939 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 16:33:04 +00:00
Ralph Dolmans 02bd3e2ff1 - Add fast-server-permil and fast-server-num options.
- Deprecate low-rtt and low-rtt-permil options.


git-svn-id: file:///svn/unbound/trunk@4938 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 16:03:46 +00:00
Wouter Wijngaards 2d28fba3bf - Squelch log of failed to tcp initiate after TCP Fastopen failure.
git-svn-id: file:///svn/unbound/trunk@4937 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 13:27:53 +00:00
Wouter Wijngaards 19aed2dcb1 Trunk has 1.8.2 in development.
git-svn-id: file:///svn/unbound/trunk@4936 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 12:09:44 +00:00
Wouter Wijngaards eed1e0789a - fastrpz.patch fix included.
git-svn-id: file:///svn/unbound/trunk@4935 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-08 10:33:09 +00:00
Wouter Wijngaards 837565c505 - iana port update.
git-svn-id: file:///svn/unbound/trunk@4933 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-05 15:18:08 +00:00
Wouter Wijngaards fece182cf5 - Set default for so-reuseport to no for FreeBSD. It is enabled
by default for Linux and DragonFlyBSD.  The setting can 
  be configured in unbound.conf to override the default.


git-svn-id: file:///svn/unbound/trunk@4932 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-05 15:07:19 +00:00
Wouter Wijngaards 945452bff4 - Squelch EADDRNOTAVAIL errors when the interface goes away,
this omits 'can't assign requested address' errors unless
  verbosity is set to a high value.


git-svn-id: file:///svn/unbound/trunk@4931 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-05 06:29:05 +00:00
Wouter Wijngaards 1c08a2ba55 - clang analyze test is used only when assertions are enabled.
git-svn-id: file:///svn/unbound/trunk@4930 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:42:50 +00:00
Wouter Wijngaards d967ceb98b Remove that fix, analyzer is for debug with assertions.
- Fix clang analyzer for optimize compile analysis.


git-svn-id: file:///svn/unbound/trunk@4929 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:32:33 +00:00
Wouter Wijngaards a3c3e13b2f remove unused diagnostic pragmas that themselves generate warnings
git-svn-id: file:///svn/unbound/trunk@4928 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:17:40 +00:00
Wouter Wijngaards 83a186f6cc Remove unused diagnostic pragmas that themselves generate warnings
git-svn-id: file:///svn/unbound/trunk@4927 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:17:11 +00:00
Wouter Wijngaards 2598f9bb18 line fixup
git-svn-id: file:///svn/unbound/trunk@4926 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:13:19 +00:00
Wouter Wijngaards ba28c48efc Remove unused variable from contrib fastrpz/rpz.c
git-svn-id: file:///svn/unbound/trunk@4925 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:12:29 +00:00
Wouter Wijngaards 98234d1017 - updated contrib/fastrpz.patch to apply for this version
git-svn-id: file:///svn/unbound/trunk@4924 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 12:00:06 +00:00
Wouter Wijngaards 99a92b3483 - Fix testlock code to set noreturn on error routine.
git-svn-id: file:///svn/unbound/trunk@4923 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 10:53:40 +00:00
Wouter Wijngaards c85ff492d0 - Fix clang analyzer for optimize compile analysis.
git-svn-id: file:///svn/unbound/trunk@4922 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 10:51:05 +00:00
Wouter Wijngaards b09cfb8fb1 - dnscrypt.c removed sizeof to get array bounds.
git-svn-id: file:///svn/unbound/trunk@4921 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 10:47:12 +00:00
Wouter Wijngaards 966a958ca5 Fixup fastrpz.patch
git-svn-id: file:///svn/unbound/trunk@4920 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-02 10:34:00 +00:00
Wouter Wijngaards 885069e1f6 - tag for release 1.8.1rc1.
git-svn-id: file:///svn/unbound/trunk@4918 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-01 11:28:05 +00:00
Wouter Wijngaards 077b38e2c5 note down that memory leak #4149 is fixed.
git-svn-id: file:///svn/unbound/trunk@4917 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-10-01 09:36:15 +00:00
Wouter Wijngaards 9be04e6fac - Fix #4188: IPv6 forwarders without ipv6 result in SERVFAIL, fixes
qname minimisation with a forwarder when connectivity has issues
  from rejecting responses.


git-svn-id: file:///svn/unbound/trunk@4916 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-27 08:19:29 +00:00
Wouter Wijngaards 377d5b426a - Add SSL cleanup for tcp timeout.
git-svn-id: file:///svn/unbound/trunk@4915 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-25 09:01:13 +00:00
Wouter Wijngaards f82a128909 - Perform TLS SNI indication of the host that is being contacted
for DNS over TLS service.  It sets the configured tls auth name.
  This is useful for hosts that apart from the DNS over TLS services
  also provide other (web) services.


git-svn-id: file:///svn/unbound/trunk@4914 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-25 08:31:42 +00:00
Wouter Wijngaards 216759e955 - Fix #4156: Fix systemd service manager state change notification.
git-svn-id: file:///svn/unbound/trunk@4913 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 12:30:22 +00:00
Wouter Wijngaards 9b6caf5a5b - Fix that with harden-below-nxdomain and qname minisation enabled
some iterator states for nonresponsive domains can get into a
  state where they waited for an empty list.
- Stop UDP to TCP failover after timeouts that causes the ping count
  to be reset by the TCP time measurement (that exists for TLS),
  because that causes the UDP part to not be measured as timeout.


git-svn-id: file:///svn/unbound/trunk@4912 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 11:25:52 +00:00
Wouter Wijngaards 5c25bbd93f fix error print
git-svn-id: file:///svn/unbound/trunk@4911 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 07:44:11 +00:00
Wouter Wijngaards d8937492cb fixup 3
git-svn-id: file:///svn/unbound/trunk@4910 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 07:35:09 +00:00
Wouter Wijngaards e91d85edb5 Fixup
git-svn-id: file:///svn/unbound/trunk@4909 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 07:32:40 +00:00
Wouter Wijngaards 5089db7331 - Fix unbound for openssl in FIPS mode, it uses the digests with
the EVP call contexts.


git-svn-id: file:///svn/unbound/trunk@4908 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 07:28:55 +00:00
Wouter Wijngaards 8e20d628e8 - Fix compile on Mac for unbound, provide explicit_bzero when libc
does not have it.


git-svn-id: file:///svn/unbound/trunk@4907 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-17 07:06:57 +00:00
Wouter Wijngaards d275505df6 - annotate exit functions with noreturn in unbound-control.
git-svn-id: file:///svn/unbound/trunk@4906 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 14:43:43 +00:00
Wouter Wijngaards f7516e6b2b - nicer bio free code in unbound-anchor.
git-svn-id: file:///svn/unbound/trunk@4905 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 12:49:37 +00:00
Wouter Wijngaards 898d4c8dd9 - Fix memory leak when message parse fails partway through copy.
- remove unused udpsize assignment in message encode.


git-svn-id: file:///svn/unbound/trunk@4904 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 12:30:44 +00:00
Wouter Wijngaards 2e9d09b961 - initialize statistics totals for printout.
- in authzone check that node exists before adding rrset.
	- in unbound-anchor, use readwrite memory BIO.
	- assertion in autotrust that packed rrset is formed correctly.


git-svn-id: file:///svn/unbound/trunk@4903 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 12:20:41 +00:00
Wouter Wijngaards 8dd6efe5ed - remove unused variable assignment from iterator scrub routine.
- check for null in delegation point during iterator refetch
  in forward zone.
- neater pointer cast in libunbound context quit routine.


git-svn-id: file:///svn/unbound/trunk@4902 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 10:36:22 +00:00
Wouter Wijngaards 635df9c806 - unit test has clang analysis.
git-svn-id: file:///svn/unbound/trunk@4901 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 10:24:08 +00:00
Wouter Wijngaards 75b8b8c875 - Free memory leak in config strlist append.
- make sure nsec3 comparison salt is initialized.


git-svn-id: file:///svn/unbound/trunk@4900 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 10:23:30 +00:00
Wouter Wijngaards 90f0530234 Fix lint found flaw.
git-svn-id: file:///svn/unbound/trunk@4899 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 10:23:01 +00:00
Wouter Wijngaards d744827f93 Better sbuffer assertion.
git-svn-id: file:///svn/unbound/trunk@4898 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 10:00:57 +00:00
Wouter Wijngaards fe8b22caa1 - in testcode, free async ids, initialise array, and check for null
pointer during test of the test.  And use exit for return to note
  irregular program stop.


git-svn-id: file:///svn/unbound/trunk@4897 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 09:45:07 +00:00
Wouter Wijngaards 9a82526b91 - exit log routine is annotated as noreturn function.
- free memory leaks in config strlist and str2list insert functions.
- do not move unused argv variable after getopt.
- Remove unused if clause in testcode.


git-svn-id: file:///svn/unbound/trunk@4896 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 08:58:21 +00:00
Wouter Wijngaards 225a6d9c6e - Fix seed for random backup code to use explicit zero when wiped.
git-svn-id: file:///svn/unbound/trunk@4895 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-13 07:49:51 +00:00
Wouter Wijngaards 87c8dd5434 - Fix initialisation in remote.c
git-svn-id: file:///svn/unbound/trunk@4894 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-11 14:11:50 +00:00
Wouter Wijngaards a09c4bbdc2 - Fix spelling errors.
git-svn-id: file:///svn/unbound/trunk@4893 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-11 13:28:21 +00:00
Wouter Wijngaards d01651c305 - Fix to squelch respip warning in unit test, it is printed at
higher verbosity settings.


git-svn-id: file:///svn/unbound/trunk@4892 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-11 13:24:31 +00:00
Wouter Wijngaards 00982fc3db - Fixed unused return value warnings in contrib/fastrpz.patch for
asprintf.


git-svn-id: file:///svn/unbound/trunk@4891 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-11 13:19:55 +00:00
Wouter Wijngaards d8f890a43a - iana port update.
git-svn-id: file:///svn/unbound/trunk@4890 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-10 12:35:01 +00:00
Wouter Wijngaards a58681a718 1.8.1 in svn trunk.
git-svn-id: file:///svn/unbound/trunk@4889 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-10 12:32:28 +00:00
Wouter Wijngaards c9d33fb9f7 1.8.0 release.
git-svn-id: file:///svn/unbound/trunk@4888 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-10 12:30:29 +00:00
Wouter Wijngaards 254df71810 - Fix spelling error in header, from getdns commit by Andreas Gelmini.
git-svn-id: file:///svn/unbound/trunk@4886 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-05 05:33:38 +00:00
Wouter Wijngaards 194dc32059 explain ip-ratelimit-factor causes the log line and it is a per-query log line.
git-svn-id: file:///svn/unbound/trunk@4885 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-04 09:26:51 +00:00
Ralph Dolmans 987c1c97e5 - More explicitly mention the type of ratelimit when applying ip-ratelimit.
git-svn-id: file:///svn/unbound/trunk@4884 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-04 09:16:07 +00:00
Wouter Wijngaards 25c8497ba6 - Tag for 1.8.0rc1 release.
git-svn-id: file:///svn/unbound/trunk@4882 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-09-04 07:15:06 +00:00
Wouter Wijngaards 5577e55400 - Disable minimal-responses in subnet unit tests.
git-svn-id: file:///svn/unbound/trunk@4881 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-31 14:59:10 +00:00
Wouter Wijngaards 27472f1270 better locking.
git-svn-id: file:///svn/unbound/trunk@4880 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-30 09:21:05 +00:00
Wouter Wijngaards 30a14c2716 - Fix that a local-zone with a local-zone-type that is transparent
in a view with view-first, makes queries check for answers from the
  local-zones defined outside of views.


git-svn-id: file:///svn/unbound/trunk@4879 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-30 09:06:07 +00:00
Wouter Wijngaards d4a69e4d2a flex.
git-svn-id: file:///svn/unbound/trunk@4878 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-30 09:02:29 +00:00
Wouter Wijngaards 000e75581b Fixup that it does not set prefetch_ttl twice, but sets the new serve_expired_ttl member of the reply ttls.
git-svn-id: file:///svn/unbound/trunk@4877 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-30 08:03:29 +00:00
Ralph Dolmans 2e5e31e8ac - Added serve-expired-ttl and serve-expired-ttl-reset options.
git-svn-id: file:///svn/unbound/trunk@4876 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-28 14:21:56 +00:00
Ralph Dolmans ae2653fcc5 - Disable minimal-responses in ipsecmod unit tests.
git-svn-id: file:///svn/unbound/trunk@4875 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-28 14:11:21 +00:00
Wouter Wijngaards f7118f29b9 - Fix lintflags for lint on FreeBSD.
git-svn-id: file:///svn/unbound/trunk@4874 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-27 13:42:27 +00:00
Wouter Wijngaards 57a5e75840 Fixup test and lint hook.
git-svn-id: file:///svn/unbound/trunk@4873 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-27 13:29:48 +00:00
Wouter Wijngaards 8d14e7c0a4 - next release is called 1.8.0.
git-svn-id: file:///svn/unbound/trunk@4872 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-27 13:20:12 +00:00
Wouter Wijngaards e0745813f4 - Set defaults to yes for a number of options to increase speed and
resilience of the server.  The so-reuseport, harden-below-nxdomain,
  and minimal-responses options are enabled by default.  They used
  to be disabled by default, waiting to make sure they worked.  They
  are enabled by default now, and can be disabled explicitly by
  setting them to "no" in the unbound.conf config file.  The reuseport
  and minimal options increases speed of the server, and should be
  otherwise harmless.  The harden-below-nxdomain option works well
  together with the recently default enabled qname minimisation, this
  causes more fetches to use information from the cache.


git-svn-id: file:///svn/unbound/trunk@4871 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-27 13:18:19 +00:00
George Thessalonikefs 0171d06aa2 - #4140: Expose repinfo (comm_reply) to the inplace_callbacks. This
gives access to reply information for the client's communication
  point when the callback is called before the mesh state (modules).
  Changes to C and Python's inplace_callback signatures were also
  necessary.


git-svn-id: file:///svn/unbound/trunk@4870 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-22 10:51:13 +00:00
Wouter Wijngaards 4daf8f5bdb - Fix only misc failure from log-servfail when val-log-level is not
enabled.


git-svn-id: file:///svn/unbound/trunk@4869 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 14:31:37 +00:00
Wouter Wijngaards 8893735a2d edns-subnet retain rcode when no return_msg, for log-servfail.
git-svn-id: file:///svn/unbound/trunk@4868 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 14:25:07 +00:00
Wouter Wijngaards 00ba747be7 - #4146: num.query.subnet and num.query.subnet_cache counters.
git-svn-id: file:///svn/unbound/trunk@4867 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 14:14:28 +00:00
Wouter Wijngaards 504ef71975 and documentation.
git-svn-id: file:///svn/unbound/trunk@4866 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 07:14:48 +00:00
Wouter Wijngaards 9926fcac4b flex and bison re-run.
git-svn-id: file:///svn/unbound/trunk@4865 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 07:10:49 +00:00
Wouter Wijngaards 01d8dc2240 - log-local-actions: yes option for unbound.conf that logs all the
local zone actions, a patch from Saksham Manchanda (Secure64).


git-svn-id: file:///svn/unbound/trunk@4864 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-21 07:10:09 +00:00
Wouter Wijngaards 4fe427ded2 - log-servfail: yes prints log lines that say why queries are
returning SERVFAIL to clients.


git-svn-id: file:///svn/unbound/trunk@4863 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 15:22:05 +00:00
Wouter Wijngaards b0ca964984 and printout for these cases too.
git-svn-id: file:///svn/unbound/trunk@4862 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 15:09:23 +00:00
Wouter Wijngaards e8c4f20f66 - added more servfail printout statements, to the iterator.
git-svn-id: file:///svn/unbound/trunk@4861 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 15:01:35 +00:00
Wouter Wijngaards b0daf867c2 and the error looks good.
git-svn-id: file:///svn/unbound/trunk@4860 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 14:17:48 +00:00
Wouter Wijngaards 8385c462ed - print servfail info to log as error.
git-svn-id: file:///svn/unbound/trunk@4859 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 13:29:27 +00:00
Ralph Dolmans afd4063f20 - Fix classification for QTYPE=CNAME queries when QNAME minimisation is enabled.
git-svn-id: file:///svn/unbound/trunk@4858 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 12:48:47 +00:00
Wouter Wijngaards ed24498f2e - Set libunbound to increase current, because the libunbound change
to the event callback function signature.  That needs programs,
  that use it, to recompile against the new header definition.


git-svn-id: file:///svn/unbound/trunk@4857 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-17 09:07:06 +00:00
Wouter Wijngaards f2b12c0761 - Fix contrib/fastrpz.patch.
git-svn-id: file:///svn/unbound/trunk@4856 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-16 10:29:00 +00:00
Wouter Wijngaards df85836b15 - Fix warning on compile without threads.
git-svn-id: file:///svn/unbound/trunk@4855 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-16 10:28:11 +00:00
Wouter Wijngaards 3f2b6828e5 Test unit test for reordering.
git-svn-id: file:///svn/unbound/trunk@4854 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-15 09:40:30 +00:00
Wouter Wijngaards 1958d9fbd5 - Fix segfault in auth-zone read and reorder of RRSIGs.
git-svn-id: file:///svn/unbound/trunk@4853 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-15 09:26:13 +00:00
Wouter Wijngaards 0c04b5eaf5 - Upgraded crosscompile script to include libunbound DLL in the
zipfile.


git-svn-id: file:///svn/unbound/trunk@4852 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-14 14:52:09 +00:00
Wouter Wijngaards 8e5a32f4dc - Fix that printout of error for cycle targets is a verbosity 4
printout and does not wrongly print it is a memory error.


git-svn-id: file:///svn/unbound/trunk@4851 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-14 07:27:57 +00:00
Wouter Wijngaards efe5c8e6be - Fix #4144: dns64 module caches wrong (negative) information.
git-svn-id: file:///svn/unbound/trunk@4850 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-10 08:03:17 +00:00
Wouter Wijngaards 1e61604aab use closer of stub and forward if both configured.
git-svn-id: file:///svn/unbound/trunk@4849 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 13:00:06 +00:00
Wouter Wijngaards 488eaf09ce Fixup log printout.
git-svn-id: file:///svn/unbound/trunk@4848 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 12:56:49 +00:00
Wouter Wijngaards 8b1012613e documentation.
git-svn-id: file:///svn/unbound/trunk@4847 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 12:48:33 +00:00
Wouter Wijngaards 256ab3d935 - Patch for stub-no-cache and forward-no-cache options that disable
caching for the contents of that stub or forward, for when you
  want immediate changes visible, from Bjoern A. Zeeb.


git-svn-id: file:///svn/unbound/trunk@4846 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 12:44:40 +00:00
Wouter Wijngaards a07337fd6d Breakout at end.
git-svn-id: file:///svn/unbound/trunk@4845 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 09:07:31 +00:00
Wouter Wijngaards be79ffa371 - document --enable-subnet in doc/README.
git-svn-id: file:///svn/unbound/trunk@4844 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 08:48:04 +00:00
Wouter Wijngaards c580e0e33c Fixup
git-svn-id: file:///svn/unbound/trunk@4843 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 08:46:13 +00:00
Wouter Wijngaards d2f7999b4e - unbound-checkconf checks if modules exist and prints if they are
not compiled in the name of the wrong module.


git-svn-id: file:///svn/unbound/trunk@4842 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-09 08:33:56 +00:00
Wouter Wijngaards 611e37aa2d (On the patch)
- make depend, yacc, lex, doc, headers.  And log the limit exceeded
  message only on high verbosity, so as to not spam the logs when
  it is busy.


git-svn-id: file:///svn/unbound/trunk@4841 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 12:48:49 +00:00
Ralph Dolmans 3f2d186694 - Make capsforid fallback QNAME minimisation aware.
git-svn-id: file:///svn/unbound/trunk@4840 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 12:43:49 +00:00
Wouter Wijngaards 73f01304f0 tcp-connection-limit in example config.
git-svn-id: file:///svn/unbound/trunk@4839 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 12:28:57 +00:00
Wouter Wijngaards 77bd7d228b Fix comment reference to variable name in header file.
git-svn-id: file:///svn/unbound/trunk@4838 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 12:03:46 +00:00
Wouter Wijngaards b97b04a9db yacc and lex.
git-svn-id: file:///svn/unbound/trunk@4837 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 12:02:10 +00:00
Wouter Wijngaards 6e4583a528 redid the make depend.
git-svn-id: file:///svn/unbound/trunk@4836 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 11:58:06 +00:00
Wouter Wijngaards 586b811b87 - Patch to implement tcp-connection-limit from Jim Hague (Sinodun).
This limits the number of simultaneous TCP client connections
  from a nominated netblock.
And a simple test for TCP connection limit.


git-svn-id: file:///svn/unbound/trunk@4835 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 11:57:42 +00:00
Wouter Wijngaards 070019c9be - Fix #4142: unbound.service.in: improvements and fixes.
Add unit dependency ordering (based on systemd-resolved).
  Add 'CAP_SYS_RESOURCE' to 'CapabilityBoundingSet' (fixes warnings
  about missing privileges during startup). Add 'AF_INET6' to
  'RestrictAddressFamilies' (without it IPV6 can't work). From
  Guido Shanahan.


git-svn-id: file:///svn/unbound/trunk@4834 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-07 08:30:22 +00:00
George Thessalonikefs ce04bcb463 please lint.
git-svn-id: file:///svn/unbound/trunk@4833 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-06 09:00:49 +00:00
Wouter Wijngaards cf1bfbba5d test post hook.
git-svn-id: file:///svn/unbound/trunk@4832 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-06 07:41:41 +00:00
Wouter Wijngaards a4fd088875 change for post hook
git-svn-id: file:///svn/unbound/trunk@4831 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-06 07:30:11 +00:00
Wouter Wijngaards 27023b3f21 - Fix for #4136: Fix to unconditionally call destroy in daemon.c.
git-svn-id: file:///svn/unbound/trunk@4830 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-06 07:18:05 +00:00
George Thessalonikefs b2a7933045 Make sure that we don't randomly fail the pylib ratelimiting tests.
git-svn-id: file:///svn/unbound/trunk@4829 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-03 15:57:48 +00:00
George Thessalonikefs 749d1b9ebc - Expose if a query (or a subquery) was ratelimited (not src IP
ratelimiting) to libunbound under 'ub_result.was_ratelimited'.
  This also introduces a change to 'ub_event_callback_type' in
  libunbound/unbound-event.h.
- Tidy pylib tests.


git-svn-id: file:///svn/unbound/trunk@4828 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-03 14:00:46 +00:00
Wouter Wijngaards 87bdb489f9 - New fix for #4136: This one ignores lex without without
yylex_destroy.


git-svn-id: file:///svn/unbound/trunk@4827 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-03 11:10:55 +00:00
Wouter Wijngaards 37e9f5591a - Revert previous change for #4136: because it introduces build
problems.


git-svn-id: file:///svn/unbound/trunk@4826 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-03 09:47:53 +00:00
Wouter Wijngaards d546e7766d - iana port list update.
git-svn-id: file:///svn/unbound/trunk@4825 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-01 14:07:54 +00:00
Wouter Wijngaards 62f69f9b40 - Fix to remove systemd sockaddr function check, that is not
always present.  Make socket activation more lenient.  But not
  different when socket activation is not used.


git-svn-id: file:///svn/unbound/trunk@4824 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-08-01 13:49:27 +00:00
Wouter Wijngaards 168bc963d3 edns keepalive in example.conf
git-svn-id: file:///svn/unbound/trunk@4823 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 13:59:34 +00:00
Wouter Wijngaards 1f148e632f remove unused variable
git-svn-id: file:///svn/unbound/trunk@4822 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 13:36:45 +00:00
Wouter Wijngaards c887ae1022 - Fix #4139: Fix unbound-host leaks memory on ANY.
git-svn-id: file:///svn/unbound/trunk@4821 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 11:58:19 +00:00
Wouter Wijngaards 375d3e7520 document -d on streamtcp man page.
git-svn-id: file:///svn/unbound/trunk@4820 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 10:36:01 +00:00
Wouter Wijngaards 3b171545b6 error message changed.
git-svn-id: file:///svn/unbound/trunk@4819 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 10:33:17 +00:00
Wouter Wijngaards aa5efa172d idle timeout is in milliseconds, fix test config.
git-svn-id: file:///svn/unbound/trunk@4818 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 10:30:42 +00:00
Wouter Wijngaards a2961e50fb For windows portability, example.conf documentation.
git-svn-id: file:///svn/unbound/trunk@4817 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 10:24:09 +00:00
Wouter Wijngaards adc498d29d test 3 works outside srcdir longtest
git-svn-id: file:///svn/unbound/trunk@4816 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 08:52:40 +00:00
Wouter Wijngaards 1ff3e51ee1 Make test 6 work in outside srcdir longtest.
git-svn-id: file:///svn/unbound/trunk@4815 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 08:41:55 +00:00
Wouter Wijngaards f9c0f359a7 please lint.
git-svn-id: file:///svn/unbound/trunk@4814 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 08:14:52 +00:00
Wouter Wijngaards cc538f4f9f - Please doxygen so it passes.
git-svn-id: file:///svn/unbound/trunk@4813 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 08:10:20 +00:00
Wouter Wijngaards 900cd200a2 more comments (from commit messages).
git-svn-id: file:///svn/unbound/trunk@4812 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 08:00:57 +00:00
Wouter Wijngaards 45e73bcc8e Insert comments for documentation purposes.
git-svn-id: file:///svn/unbound/trunk@4811 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:55:47 +00:00
Wouter Wijngaards 26eaf2d1ee And these source files.
git-svn-id: file:///svn/unbound/trunk@4810 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:48:58 +00:00
Wouter Wijngaards 2f32ef7646 Another patch from Jim Hague:
- Fix 'make depend' to work when build dir is not project root.


git-svn-id: file:///svn/unbound/trunk@4809 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:27:16 +00:00
Wouter Wijngaards b7abbd1d72 - Fix mesh.c incompatible pointer pass.
- yacc and lex.


git-svn-id: file:///svn/unbound/trunk@4808 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:23:58 +00:00
Wouter Wijngaards f364edafd3 - From Wouter: make depend, the dependencies in the patches did not
apply cleanly.


git-svn-id: file:///svn/unbound/trunk@4807 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:21:39 +00:00
Wouter Wijngaards e3f08cb2a2 - Implement progressive backoff of TCP idle/keepalive timeout.
git-svn-id: file:///svn/unbound/trunk@4806 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:20:15 +00:00
Wouter Wijngaards a92b00ef3c - Correct and expand manual page entries for keepalive and idle timeout.
git-svn-id: file:///svn/unbound/trunk@4805 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:19:26 +00:00
Wouter Wijngaards 3dbdde7fed - Add edns-tcp-keepalive and edns-tcp-keepalive timeout options
and implement option in client responses.


git-svn-id: file:///svn/unbound/trunk@4804 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:18:34 +00:00
Wouter Wijngaards 6da37e5ecd - Error if EDNS Keepalive received over UDP.
implement and add test.


git-svn-id: file:///svn/unbound/trunk@4803 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:16:25 +00:00
Wouter Wijngaards 007123ee2c - Sort out test runs when the build directory isn't the project
root directory.
- Add config tcp-idle-timeout (default 30s). This applies to
  client connections only; the timeout on TCP connections upstream
  is unaffected.


git-svn-id: file:///svn/unbound/trunk@4802 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-31 07:15:12 +00:00
Wouter Wijngaards 10c085f81d - Fix #4136: insufficiency from mismatch of FLEX capability between
released tarball and build host.


git-svn-id: file:///svn/unbound/trunk@4801 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-30 09:58:05 +00:00
Wouter Wijngaards 1d315e11cf - Fix man page, say that chroot is enabled by default.
git-svn-id: file:///svn/unbound/trunk@4800 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-27 09:19:57 +00:00
Wouter Wijngaards c91b657a40 Attribute and put fix in section.
git-svn-id: file:///svn/unbound/trunk@4799 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-26 07:10:24 +00:00
Wouter Wijngaards 60f59271d6 - Fix #4135: 64-bit Windows Installer Creates Entries Under The
Wrong Registry Key.


git-svn-id: file:///svn/unbound/trunk@4798 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-26 06:59:57 +00:00
Wouter Wijngaards 40abe08ac8 - Fix use-systemd readiness signalling, only when use-systemd is yes
and not in signal handler.


git-svn-id: file:///svn/unbound/trunk@4797 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-23 13:05:39 +00:00
Wouter Wijngaards ae1790b8e8 fixup for :
git-svn-id: file:///svn/unbound/trunk@4796 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-20 12:52:37 +00:00
Wouter Wijngaards aa5fb8b10b - Fix #4131: for solaris, error YY_CURRENT_BUFFER undeclared.
git-svn-id: file:///svn/unbound/trunk@4795 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-20 11:53:57 +00:00
Wouter Wijngaards 6de329359c better line about fix suggestion
git-svn-id: file:///svn/unbound/trunk@4794 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-20 08:58:30 +00:00
Wouter Wijngaards 2e34a8f643 double spaces.
git-svn-id: file:///svn/unbound/trunk@4793 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-20 08:56:47 +00:00
Wouter Wijngaards bded93f69b - Fix #4130: print text describing -dd and unbound-checkconf on
config file read error at startup, the errors may have been moved
  away by the startup process.


git-svn-id: file:///svn/unbound/trunk@4792 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-20 05:42:38 +00:00
Wouter Wijngaards 38e77d50f2 - Fix #4129 unbound-control error message with wrong cert permissions
is too cryptic.


git-svn-id: file:///svn/unbound/trunk@4791 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-19 06:22:11 +00:00
Wouter Wijngaards f8e585f308 nicer code, in function.
git-svn-id: file:///svn/unbound/trunk@4790 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 15:07:09 +00:00
Wouter Wijngaards 5bda4f9822 Fixup cache size test for msg cache.
git-svn-id: file:///svn/unbound/trunk@4789 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 14:56:02 +00:00
Wouter Wijngaards d2d7b987fa brackets added.
git-svn-id: file:///svn/unbound/trunk@4788 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 14:44:20 +00:00
Wouter Wijngaards 7579216922 - Resize ratelimit and ip-ratelimit caches if changed on reload.
git-svn-id: file:///svn/unbound/trunk@4787 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 14:42:38 +00:00
Wouter Wijngaards 330c6e1cb0 - Fix that ratelimit and ip-ratelimit are applied after reload of
git-svn-id: file:///svn/unbound/trunk@4786 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 14:27:44 +00:00
Wouter Wijngaards 41e5a66b73 Fixup
git-svn-id: file:///svn/unbound/trunk@4785 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 12:30:53 +00:00
Wouter Wijngaards cc5ab744c5 - Print error if SSL name verification configured but not available
in the ssl library.


git-svn-id: file:///svn/unbound/trunk@4784 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 12:26:32 +00:00
Wouter Wijngaards 0ae750e552 - Fix #4127 unbound -h does not list -p help.
git-svn-id: file:///svn/unbound/trunk@4783 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-17 07:03:37 +00:00
Wouter Wijngaards cabc120f22 for outgoing UDP sockets.
git-svn-id: file:///svn/unbound/trunk@4782 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-16 10:30:44 +00:00
Wouter Wijngaards c96c2d8a45 - Squelch can't bind socket errors with Permission denied unless
verbosity is 4 or higher, for UDP sockets.


git-svn-id: file:///svn/unbound/trunk@4781 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-16 10:27:12 +00:00
Wouter Wijngaards 8aa53f027d - Fix qname minimisation NXDOMAIN validation lookup failures causing
error_supers assertion fails.


git-svn-id: file:///svn/unbound/trunk@4780 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-16 10:21:34 +00:00
Wouter Wijngaards 4bf9d12419 - Fix for 4126 that the #define for UNKNOWN_SERVER_NICENESS can be more
easily changed to adjust default rtt assumptions.


git-svn-id: file:///svn/unbound/trunk@4779 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-12 14:15:03 +00:00
Wouter Wijngaards f93746b1af - Fix to improve systemd socket activation code file descriptor
assignment.


git-svn-id: file:///svn/unbound/trunk@4778 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-12 10:35:33 +00:00
Wouter Wijngaards 23dc22b78d - Note in documentation that the cert name match code needs
git-svn-id: file:///svn/unbound/trunk@4777 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-10 08:02:32 +00:00
Wouter Wijngaards 5e3c30beac - Fix round robin for failed addresses with prefer-ip6: yes
git-svn-id: file:///svn/unbound/trunk@4776 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 14:40:35 +00:00
Wouter Wijngaards 86f16bef93 Fix round robin for failed addresses with prefer-ip6: yes
git-svn-id: file:///svn/unbound/trunk@4775 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 14:14:19 +00:00
Wouter Wijngaards f2e90b0872 - Note RFC8162 support. SMIMEA record type can be read in by the
zone record parser.


git-svn-id: file:///svn/unbound/trunk@4774 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 12:06:05 +00:00
Wouter Wijngaards 1249e0db3f - Note RFC8162 support.
git-svn-id: file:///svn/unbound/trunk@4773 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 11:56:38 +00:00
Wouter Wijngaards 15c4dd79f4 - iana port update.
git-svn-id: file:///svn/unbound/trunk@4772 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 06:48:44 +00:00
Wouter Wijngaards e324a7819a - Fix documentation ambiguity for tls-win-cert in tls-upstream and
forward-tls-upstream docs.


git-svn-id: file:///svn/unbound/trunk@4771 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-06 05:39:08 +00:00
Wouter Wijngaards 81e9f82a8d - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will not pass
if DNSSEC is not enabled.  New option -R allows fallback from
  resolv.conf to direct queries.


git-svn-id: file:///svn/unbound/trunk@4770 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-04 10:02:16 +00:00
Wouter Wijngaards 5d298ed474 - Fix permission denied printed for auth zone probe random port nrs.
git-svn-id: file:///svn/unbound/trunk@4769 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-03 13:58:49 +00:00
Wouter Wijngaards 82e1e3959f - Better documentation for unblock-lan-zones and insecure-lan-zones
config statements.


git-svn-id: file:///svn/unbound/trunk@4768 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-03 08:54:01 +00:00
Wouter Wijngaards 7181c0fa6a - Update libunbound/python/examples/dnssec_test.py example code to
also set the 20326 trust anchor for the root in the example code.


git-svn-id: file:///svn/unbound/trunk@4767 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-02 14:46:31 +00:00
Wouter Wijngaards 49f27c06af Note that fix works to decrease problem, and is included for next release.
git-svn-id: file:///svn/unbound/trunk@4766 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-02 08:55:04 +00:00
Wouter Wijngaards 7247718e12 - Fix typo on man page in ip-address description.
git-svn-id: file:///svn/unbound/trunk@4765 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-02 07:19:12 +00:00
Wouter Wijngaards 61acc76244 - Fix checking for libhiredis printout in configure output.
git-svn-id: file:///svn/unbound/trunk@4764 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-07-02 07:09:30 +00:00
Wouter Wijngaards 2faa4f9ee2 And documentation.
git-svn-id: file:///svn/unbound/trunk@4763 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-29 13:03:57 +00:00
Wouter Wijngaards 2beae211ee - dns64-ignore-aaaa: config option to list domain names for which the
existing AAAA is ignored and dns64 processing is used on the A
  record.


git-svn-id: file:///svn/unbound/trunk@4762 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-29 12:58:52 +00:00
Wouter Wijngaards d3ff7a9333 - log port number with err_addr logs.
git-svn-id: file:///svn/unbound/trunk@4761 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-29 08:34:41 +00:00
Wouter Wijngaards 23df700f15 explain num.tcp and num.tls
git-svn-id: file:///svn/unbound/trunk@4760 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-28 09:14:31 +00:00
Wouter Wijngaards 755233c720 - num.queries.tls counter for queries over TLS.
git-svn-id: file:///svn/unbound/trunk@4759 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-28 08:15:47 +00:00
Wouter Wijngaards bca54a8b25 - Patch, do not export python from pkg-config, from Petr Menšík.
git-svn-id: file:///svn/unbound/trunk@4758 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-27 06:07:31 +00:00
Wouter Wijngaards b5aab36d41 - #4109: Fix that package config depends on python unconditionally.
git-svn-id: file:///svn/unbound/trunk@4757 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-27 05:46:36 +00:00
Wouter Wijngaards d7cfe91cb3 - Fix that auth-zone does not start the wait timer without checking
if the wait timer has already been started.
(the code is part of the previous commit).



git-svn-id: file:///svn/unbound/trunk@4756 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-26 13:56:23 +00:00
Wouter Wijngaards a31d45b13e - Fix that auth-zone master reply with current SOA serial does not
stop scan of masters for an updated zone.


git-svn-id: file:///svn/unbound/trunk@4755 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-26 13:48:36 +00:00
Wouter Wijngaards 23f475bccc - Tentative fix for permission denied on IPv6 address on FreeBSD.
git-svn-id: file:///svn/unbound/trunk@4754 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-26 08:01:44 +00:00
Wouter Wijngaards 025fdd0049 Document behaviour.
git-svn-id: file:///svn/unbound/trunk@4753 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-21 12:51:14 +00:00
Wouter Wijngaards 5bb6dbe21c And moved -C to front.
git-svn-id: file:///svn/unbound/trunk@4752 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-21 12:39:49 +00:00
Wouter Wijngaards c225ced1a9 - Fix usage printout for unbound-host, hostname has to be last
argument on BSDs and Windows.


git-svn-id: file:///svn/unbound/trunk@4751 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-21 12:31:42 +00:00
Wouter Wijngaards 3a58ad15e8 Note contents of release 1.7.3
git-svn-id: file:///svn/unbound/trunk@4750 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-21 10:00:17 +00:00
Wouter Wijngaards 5106ad7a2c - #4108: systemd reload hang fix.
git-svn-id: file:///svn/unbound/trunk@4747 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-21 07:11:12 +00:00
Wouter Wijngaards 8c044a616b - Fix windows unbound-control no cert bad file descriptor error.
git-svn-id: file:///svn/unbound/trunk@4746 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-19 13:13:35 +00:00
Wouter Wijngaards 9ccf611954 add trailing newline.
git-svn-id: file:///svn/unbound/trunk@4745 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-19 09:59:48 +00:00
Wouter Wijngaards 5dfcf122d1 - Windows example service.conf edited with more windows specific
configuration.


git-svn-id: file:///svn/unbound/trunk@4744 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-19 09:57:39 +00:00
Wouter Wijngaards 7b092127cb - Fix for unbound-control on Windows and set TCP socket parameters
more closely.


git-svn-id: file:///svn/unbound/trunk@4743 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-19 09:40:59 +00:00
Wouter Wijngaards b26257248d - Fix unbound-checkconf for control-use-cert.
git-svn-id: file:///svn/unbound/trunk@4742 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-18 12:15:21 +00:00
Wouter Wijngaards 3c7d270958 Changelog note, fix is part of 1.7.3rc2.
git-svn-id: file:///svn/unbound/trunk@4741 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-18 09:46:40 +00:00
Wouter Wijngaards c15eae814f - Fix that control-use-cert: no works for 127.0.0.1 to disable certs.
git-svn-id: file:///svn/unbound/trunk@4738 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-18 09:04:35 +00:00
Wouter Wijngaards 0e72e06886 - Print warning when control-use-cert is used with an IP-address
in unbound-control, and that TLS is enabled.


git-svn-id: file:///svn/unbound/trunk@4737 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-18 08:40:30 +00:00
Wouter Wijngaards abff4d1237 - unbound-control auth_zone_transfer _zone_ option starts the probe
sequence for a master to transfer the zone from and transfers when
  a new zone version is available.


git-svn-id: file:///svn/unbound/trunk@4736 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-15 15:01:31 +00:00
Wouter Wijngaards 386f23334b - unbound-control auth_zone_reload _zone_ option rereads the zonefile.
git-svn-id: file:///svn/unbound/trunk@4735 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-15 13:42:41 +00:00
Wouter Wijngaards a523683d4c - trunk has 1.7.4.
git-svn-id: file:///svn/unbound/trunk@4734 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-15 11:55:23 +00:00
Wouter Wijngaards b25332e1f4 - tag for 1.7.3rc1.
git-svn-id: file:///svn/unbound/trunk@4732 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-15 05:38:39 +00:00
Wouter Wijngaards a6ec2c6fc7 - Fix nettle compile.
git-svn-id: file:///svn/unbound/trunk@4731 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-14 12:08:09 +00:00
Wouter Wijngaards 9cb404ba5f - Fix that first control-interface determines if TLS is used. Warn
when IP address interfaces are used without TLS.


git-svn-id: file:///svn/unbound/trunk@4730 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-14 08:14:43 +00:00
Wouter Wijngaards 12251022ec - #4103: Fix that auth-zone does not insist on SOA record first in
file for url downloads.


git-svn-id: file:///svn/unbound/trunk@4729 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-14 07:09:01 +00:00
Ralph Dolmans 00a0cabf7f - Don't count CNAME response types received during qname minimisation as query
restart.


git-svn-id: file:///svn/unbound/trunk@4728 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 13:09:14 +00:00
Wouter Wijngaards d6ed0e868f remove unreachable point for portablity
git-svn-id: file:///svn/unbound/trunk@4727 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 13:02:52 +00:00
Wouter Wijngaards 700ad78f10 Fix snprintf size.
git-svn-id: file:///svn/unbound/trunk@4726 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 12:39:48 +00:00
Wouter Wijngaards d65accbb23 - remade dependencies in the Makefile.
git-svn-id: file:///svn/unbound/trunk@4725 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 12:23:56 +00:00
Wouter Wijngaards 78767f2014 - Fix buffer size warning in unit test.
git-svn-id: file:///svn/unbound/trunk@4724 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 11:01:14 +00:00
Wouter Wijngaards 21af42a281 Continue to read also when signals are sent.
git-svn-id: file:///svn/unbound/trunk@4723 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 10:50:51 +00:00
Wouter Wijngaards 0b0ece9db0 better documentation in header file
git-svn-id: file:///svn/unbound/trunk@4722 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 10:15:08 +00:00
Wouter Wijngaards 23edc18cac - Rename tls-additional-ports to tls-additional-port, because every
line adds one port.


git-svn-id: file:///svn/unbound/trunk@4721 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 08:45:57 +00:00
Wouter Wijngaards 7153c94bd7 Fixup error print for unix pipe.
git-svn-id: file:///svn/unbound/trunk@4720 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 08:15:44 +00:00
Wouter Wijngaards 4df697b4b7 Accurate printout in status output.
git-svn-id: file:///svn/unbound/trunk@4719 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 08:05:03 +00:00
Wouter Wijngaards 7fd32916e8 - #4102 for NSD, but for Unbound. Named unix pipes do not use
certificate and key files, access can be restricted with file and
  directory permissions.  The option control-use-cert is no longer
  used, and ignored if found in unbound.conf.


git-svn-id: file:///svn/unbound/trunk@4718 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-12 07:43:52 +00:00
Wouter Wijngaards 3f837bc440 trunk is 1.7.3 in development.
git-svn-id: file:///svn/unbound/trunk@4717 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-11 10:05:03 +00:00
Wouter Wijngaards f0769bed93 note OpenBSD accept4.
git-svn-id: file:///svn/unbound/trunk@4716 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-11 09:08:41 +00:00
Wouter Wijngaards a1bfc07105 - Patch to fix openwrt for mac os build darwin detection in configure.
git-svn-id: file:///svn/unbound/trunk@4713 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-06 05:31:12 +00:00
Wouter Wijngaards beba72d6db adjust test, for timer too slow for old machines.
git-svn-id: file:///svn/unbound/trunk@4712 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-05 08:09:00 +00:00
Wouter Wijngaards a4a5bfaa2f - Fix crash if ratelimit taken into use with unbound-control
instead of with unbound.conf.


git-svn-id: file:///svn/unbound/trunk@4711 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-05 07:06:19 +00:00
Wouter Wijngaards 62ea384d19 accept4 also on OpenBSD
git-svn-id: file:///svn/unbound/trunk@4710 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-05 06:59:05 +00:00
Wouter Wijngaards 53b1e11eba better fix for #4100
git-svn-id: file:///svn/unbound/trunk@4709 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-04 14:07:08 +00:00
Wouter Wijngaards 7fae96eb1e Track bug.nr 4100
git-svn-id: file:///svn/unbound/trunk@4708 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-04 12:50:32 +00:00
Wouter Wijngaards d386641820 - Fix stub reprime when it becomes useless.
git-svn-id: file:///svn/unbound/trunk@4707 be551aaa-1e26-0410-a405-d3ace91eadb9
2018-06-04 12:28:33 +00:00
381 changed files with 20323 additions and 8062 deletions
+16 -1
View File
@@ -4,6 +4,7 @@
/Makefile
/autom4te.cache/
/config.h
/config.h.in~
/config.log
/config.status
/dnstap/dnstap_config.h
@@ -18,6 +19,7 @@
/doc/unbound.conf.5
/libtool
/libunbound.la
/_unbound.la
/smallapp/unbound-control-setup.sh
/unbound
/unbound-anchor
@@ -36,4 +38,17 @@
/streamtcp
/testbound
/unittest
/contrib/libunbound.pc
/contrib/unbound.service
/contrib/unbound.socket
/dnstap/dnstap.pb-c.c
/dnstap/dnstap.pb-c.h
/libunbound/python/libunbound_wrap.c
/libunbound/python/unbound.py
/pythonmod/interface.h
/pythonmod/unboundmodule.py
/testdata/result.*
/testdata/.done-*
/testdata/.perfstats.txt
/doc/html
/doc/xml
+16
View File
@@ -0,0 +1,16 @@
sudo: false
language: c
compiler:
- gcc
addons:
apt:
packages:
- libssl-dev
- libevent-dev
- libexpat-dev
- clang
script:
- ./configure --enable-debug --disable-flto
- make
- make test
- (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
+517 -534
View File
File diff suppressed because it is too large Load Diff
+37
View File
@@ -0,0 +1,37 @@
# Unbound
[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound)
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
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
have any feedback, we would love to hear from you. Dont hesitate to
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
or post a message on the [Unbound mailing list](https://nlnetlabs.nl/mailman/listinfo/unbound-users).
You can lean more about Unbound by reading our
[documentation](https://nlnetlabs.nl/documentation/unbound/).
## Compiling
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
installed. Unbound can be compiled and installed using:
```
./configure && make && make install
```
You can use libevent if you want. libevent is useful when using many (10000)
outgoing ports. By default max 256 ports are opened at the same time and the
builtin alternative is equally capable and a little faster.
Use the `--with-libevent=dir` configure option to compile Unbound with libevent
support.
## Unbound configuration
All of Unbound's configuration options are described in the man pages, which
will be installed and are available on the Unbound
[documentation page](https://nlnetlabs.nl/documentation/unbound/).
An example configuration file is located in
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
Vendored
+4 -4
View File
@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9390,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
+14
View File
@@ -72,6 +72,19 @@
# define be64toh(x) OSSwapBigToHostInt64(x)
#endif
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
#ifndef be64toh
#if defined(__sun) || defined(_AIX)
# if __BIG_ENDIAN__
# define be64toh(n) (n)
# define htobe64(n) (n)
# else
# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
# endif
#endif
#endif /* be64toh */
/** the unit test testframe for cachedb, its module state contains
* a cache for a couple queries (in memory). */
struct testframe_moddata {
@@ -446,6 +459,7 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
msg->rep->ttl -= adjust;
else msg->rep->ttl = 0;
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_subtract((struct packed_rrset_data*)msg->
+1
View File
@@ -140,6 +140,7 @@ nodevrandom:
static inline void
_rs_init(u_char *buf, size_t n)
{
assert(buf);
if (n < KEYSZ + IVSZ)
return;
+1 -1
View File
@@ -1,4 +1,4 @@
#! /bin/sh
#!/usr/bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2016 Free Software Foundation, Inc.
+61 -2
View File
@@ -1,5 +1,11 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* apply the noreturn attribute to a function that exits the program */
#undef ATTR_NORETURN
/* apply the weak attribute to a symbol */
#undef ATTR_WEAK
/* Directory to chroot to */
#undef CHROOT_DIR
@@ -9,6 +15,9 @@
/* Do sha512 definitions in config.h */
#undef COMPAT_SHA512
/* Command line arguments used with configure */
#undef CONFCMDLINE
/* Pathname to the Unbound configuration file */
#undef CONFIGFILE
@@ -45,6 +54,9 @@
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "noreturn" attribute */
#undef HAVE_ATTR_NORETURN
/* Whether the C compiler accepts the "unused" attribute */
#undef HAVE_ATTR_UNUSED
@@ -60,6 +72,9 @@
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
/* Define to 1 if you have the `ctime_r' function. */
#undef HAVE_CTIME_R
@@ -74,6 +89,10 @@
if you don't. */
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
you don't. */
#undef HAVE_DECL_EVSIGNAL_ASSIGN
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
don't. */
#undef HAVE_DECL_INET_NTOP
@@ -154,6 +173,9 @@
/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
/* Define to 1 if you have the `event_assign' function. */
#undef HAVE_EVENT_ASSIGN
/* Define to 1 if you have the `event_base_free' function. */
#undef HAVE_EVENT_BASE_FREE
@@ -169,6 +191,9 @@
/* Define to 1 if you have the <event.h> header file. */
#undef HAVE_EVENT_H
/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
#undef HAVE_EVP_AES_256_CBC
/* Define to 1 if you have the `EVP_cleanup' function. */
#undef HAVE_EVP_CLEANUP
@@ -178,6 +203,9 @@
/* Define to 1 if you have the `EVP_dss1' function. */
#undef HAVE_EVP_DSS1
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#undef HAVE_EVP_MD_CTX_NEW
@@ -199,6 +227,9 @@
/* Define to 1 if you have the <expat.h> header file. */
#undef HAVE_EXPAT_H
/* Define to 1 if you have the `explicit_bzero' function. */
#undef HAVE_EXPLICIT_BZERO
/* Define to 1 if you have the `fcntl' function. */
#undef HAVE_FCNTL
@@ -247,6 +278,9 @@
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
#undef HAVE_HIREDIS_HIREDIS_H
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX
/* If you have HMAC_Update */
#undef HAVE_HMAC_UPDATE
@@ -382,7 +416,7 @@
/* Define to 1 if you have the `RAND_cleanup' function. */
#undef HAVE_RAND_CLEANUP
/* Define to 1 if you have the `reallocarray' function. */
/* If we have reallocarray(3) */
#undef HAVE_REALLOCARRAY
/* Define to 1 if you have the `recvmsg' function. */
@@ -439,9 +473,15 @@
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
/* Define to 1 if you have the `SSL_get0_peername' function. */
#undef HAVE_SSL_GET0_PEERNAME
@@ -574,6 +614,9 @@
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
/* Define to 1 if you have the `_beginthreadex' function. */
#undef HAVE__BEGINTHREADEX
@@ -651,6 +694,9 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* if REUSEPORT is enabled by default */
#undef REUSEPORT_DEFAULT
/* default rootkey location */
#undef ROOT_ANCHOR_FILE
@@ -732,6 +778,9 @@
/* Define to 1 to use ipsecmod support. */
#undef USE_IPSECMOD
/* Define to 1 to use ipset support */
#undef USE_IPSET
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
@@ -929,8 +978,14 @@
#ifndef _OPENBSD_SOURCE
#define _OPENBSD_SOURCE 1
#endif
#ifndef UNBOUND_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
/** Use small-ldns codebase */
@@ -1144,6 +1199,11 @@ char *strsep(char **stringp, const char *delim);
int isblank(int c);
#endif
#ifndef HAVE_EXPLICIT_BZERO
#define explicit_bzero unbound_explicit_bzero
void explicit_bzero(void* buf, size_t len);
#endif
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
@@ -1176,7 +1236,6 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size);
# endif
#endif /* HAVE_LIBRESSL */
#ifndef HAVE_ARC4RANDOM
void explicit_bzero(void* buf, size_t len);
int getentropy(void* buf, size_t len);
uint32_t arc4random(void);
void arc4random_buf(void* buf, size_t n);
Vendored
+1 -1
View File
@@ -1,4 +1,4 @@
#! /bin/sh
#!/usr/bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc.
Vendored
+603 -374
View File
File diff suppressed because it is too large Load Diff
+163 -19
View File
@@ -10,16 +10,16 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[7])
m4_define([VERSION_MICRO],[2])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
m4_define([VERSION_MINOR],[9])
m4_define([VERSION_MICRO],[3])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=7
LIBUNBOUND_REVISION=10
LIBUNBOUND_AGE=5
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=3
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.0.2 had 0:14:0
@@ -80,6 +80,15 @@ LIBUNBOUND_AGE=5
# 1.7.0 had 7:8:5
# 1.7.1 had 7:9:5
# 1.7.2 had 7:10:5
# 1.7.3 had 7:11:5
# 1.8.0 had 8:0:0 # changes the event callback function signature
# 1.8.1 had 8:1:0
# 1.8.2 had 8:2:0
# 1.8.3 had 8:3:0
# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
# 1.9.1 had 9:1:1
# 1.9.2 had 9:2:1
# 1.9.3 had 9:3:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -103,6 +112,10 @@ AC_SUBST(LIBUNBOUND_CURRENT)
AC_SUBST(LIBUNBOUND_REVISION)
AC_SUBST(LIBUNBOUND_AGE)
cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
CFLAGS="$CFLAGS"
AC_AIX
if test "$ac_cv_header_minix_config_h" = "yes"; then
@@ -308,11 +321,36 @@ __attribute__((weak)) void f(int x) { printf("%d", x); }
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])
fi
])dnl End of CHECK_WEAK_ATTRIBUTE
CHECK_WEAK_ATTRIBUTE
AC_DEFUN([CHECK_NORETURN_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
[ac_cv_c_noreturn_attribute=no
AC_TRY_COMPILE(
[ #include <stdio.h>
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
], [
f(1);
],
[ac_cv_c_noreturn_attribute="yes"],
[ac_cv_c_noreturn_attribute="no"])
])
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])
fi
])dnl End of CHECK_NORETURN_ATTRIBUTE
CHECK_NORETURN_ATTRIBUTE
if test "$srcdir" != "."; then
CPPFLAGS="$CPPFLAGS -I$srcdir"
fi
@@ -322,16 +360,37 @@ AC_DEFUN([ACX_YYLEX_DESTROY], [
if echo %% | $LEX -t 2>&1 | grep yylex_destroy >/dev/null 2>&1; then
AC_DEFINE(LEX_HAS_YYLEX_DESTROY, 1, [if lex has yylex_destroy])
AC_MSG_RESULT(yes)
else AC_MSG_RESULT(no); fi
else AC_MSG_RESULT(no);
LEX=":"
fi
])
AC_DEFUN([ACX_YYLEX_OPTION], [
AC_MSG_CHECKING([for lex %option])
if cat <<EOF | $LEX -t 2>&1 | grep yy_delete_buffer >/dev/null 2>&1; then
%option nounput
%%
EOF
AC_MSG_RESULT(yes)
else AC_MSG_RESULT(no);
LEX=":"
fi
])
AC_PROG_LEX
if test "$LEX" != "" -a "$LEX" != ":"; then
ACX_YYLEX_DESTROY
fi
if test "$LEX" != "" -a "$LEX" != ":"; then
ACX_YYLEX_OPTION
fi
AC_PROG_YACC
AC_CHECK_PROG(doxygen, doxygen, doxygen)
AC_CHECK_TOOL(STRIP, strip)
ACX_LIBTOOL_C_ONLY
PKG_PROG_PKG_CONFIG
# Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.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],,, [AC_INCLUDES_DEFAULT])
@@ -414,6 +473,17 @@ ACX_CHECK_NONBLOCKING_BROKEN
ACX_MKDIR_ONE_ARG
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
# check if we can use SO_REUSEPORT
if echo "$host" | grep -i -e linux -e dragonfly >/dev/null; then
AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default])
else
AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default])
fi
# Include systemd.m4 - begin
sinclude(systemd.m4)
# Include systemd.m4 - end
# set memory allocation checking if requested
AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
[ enable to memory allocation statistics, for debug purposes ]),
@@ -584,7 +654,9 @@ if test x_$ub_test_python != x_no; then
CPPFLAGS="$PYTHON_CPPFLAGS"
fi
ub_have_python=yes
PC_PY_DEPENDENCY="python"
PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
[PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
[PC_PY_DEPENDENCY="python"])
AC_SUBST(PC_PY_DEPENDENCY)
# Check for SWIG
@@ -721,12 +793,12 @@ 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],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@@ -1137,6 +1209,14 @@ large outgoing port ranges. ])
AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
AC_CHECK_FUNCS([event_assign]) # in libevent, for thread-safety
AC_CHECK_DECLS([evsignal_assign], [], [], [AC_INCLUDES_DEFAULT
#ifdef HAVE_EVENT_H
# include <event.h>
#else
# include "event2/event.h"
#endif
])
PC_LIBEVENT_DEPENDENCY="libevent"
AC_SUBST(PC_LIBEVENT_DEPENDENCY)
if test -n "$BAK_LDFLAGS_SET"; then
@@ -1176,9 +1256,9 @@ AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
[specify explicit path for libhiredis.]),
[ ],[ withval="no" ])
AC_MSG_CHECKING(for libhiredis)
found_libhiredis="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libhiredis)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
@@ -1225,10 +1305,6 @@ if test x_$enable_static_exe = x_yes; then
fi
fi
# Include systemd.m4 - begin
sinclude(systemd.m4)
# Include systemd.m4 - end
# set lock checking if requested
AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
[ enable to check lock and unlock calls, for debug purposes ]),
@@ -1324,7 +1400,7 @@ AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
if echo $build_os | grep darwin8 > /dev/null; then
if echo $target_os | grep darwin8 > /dev/null; then
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
fi
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
@@ -1372,15 +1448,32 @@ AC_REPLACE_FUNCS(strlcpy)
AC_REPLACE_FUNCS(memmove)
AC_REPLACE_FUNCS(gmtime_r)
AC_REPLACE_FUNCS(isblank)
AC_REPLACE_FUNCS(explicit_bzero)
dnl without CTIME, ARC4-functions and without reallocarray.
LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
AC_REPLACE_FUNCS(reallocarray)
AC_MSG_CHECKING([for reallocarray])
AC_LINK_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
[[
#ifndef _OPENBSD_SOURCE
#define _OPENBSD_SOURCE 1
#endif
#include <stdlib.h>
int main(void) {
void* p = reallocarray(NULL, 10, 100);
free(p);
return 0;
}
]])], [AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_REALLOCARRAY, 1, [If we have reallocarray(3)])
], [
AC_MSG_RESULT(no)
AC_LIBOBJ(reallocarray)
])
if test "$USE_NSS" = "no"; then
AC_REPLACE_FUNCS(arc4random)
AC_REPLACE_FUNCS(arc4random_uniform)
if test "$ac_cv_func_arc4random" = "no"; then
AC_LIBOBJ(explicit_bzero)
AC_LIBOBJ(arc4_lock)
AC_CHECK_FUNCS([getentropy],,[
if test "$USE_WINSOCK" = 1; then
@@ -1515,6 +1608,47 @@ case "$enable_ipsecmod" in
;;
esac
# check for ipset if requested
AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module]))
case "$enable_ipset" in
yes)
AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support])
IPSET_SRC="ipset/ipset.c"
AC_SUBST(IPSET_SRC)
IPSET_OBJ="ipset.lo"
AC_SUBST(IPSET_OBJ)
# mnl
AC_ARG_WITH(libmnl, AC_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
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/libmnl/libmnl.h"; then
found_libmnl="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)
LIBS="$LIBS -lmnl"
break;
fi
done
if test x_$found_libmnl != x_yes; then
AC_ERROR([Could not find libmnl, libmnl.h])
fi
;;
no|*)
# nothing
;;
esac
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
@@ -1589,8 +1723,14 @@ AHX_CONFIG_EXT_FLAGS
dnl includes
[
#ifndef _OPENBSD_SOURCE
#define _OPENBSD_SOURCE 1
#endif
#ifndef UNBOUND_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
/** Use small-ldns codebase */
@@ -1705,6 +1845,11 @@ char *strsep(char **stringp, const char *delim);
int isblank(int c);
#endif
#ifndef HAVE_EXPLICIT_BZERO
#define explicit_bzero unbound_explicit_bzero
void explicit_bzero(void* buf, size_t len);
#endif
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
@@ -1737,7 +1882,6 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size);
# endif
#endif /* HAVE_LIBRESSL */
#ifndef HAVE_ARC4RANDOM
void explicit_bzero(void* buf, size_t len);
int getentropy(void* buf, size_t len);
uint32_t arc4random(void);
void arc4random_buf(void* buf, size_t n);
+2
View File
@@ -38,3 +38,5 @@ distribution but may be helpful.
* unbound-querycachedb.py: utility to show data stored in cachedb backend
for a particular query name and type. It requires dnspython and (for
redis backend) redis Python modules.
* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from
stdin. Used with fuzzers, patch from Jacob Hoffman-Andrews.
+187 -193
View File
@@ -1,14 +1,10 @@
Description: based on the included patch contrib/fastrpz.patch
Author: fastrpz@farsightsecurity.com
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
===================================================================
RCS file: ./RCS/Makefile.in,v
retrieving revision 1.1
Index: unbound-1.7.0~rc1/Makefile.in
===================================================================
--- unbound-1.7.0~rc1.orig/Makefile.in
+++ unbound-1.7.0~rc1/Makefile.in
diff --git a/Makefile.in b/Makefile.in
index e9042712..870d503b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
DNSTAP_SRC=@DNSTAP_SRC@
@@ -18,25 +14,25 @@ Index: unbound-1.7.0~rc1/Makefile.in
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
@@ -126,7 +128,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
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 \
@@ -137,7 +139,7 @@ slabhash.lo timehist.lo tube.lo winsock_
@@ -139,7 +141,7 @@ autotrust.lo val_anchor.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.lo authzone.lo\
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
-$(IPSECMOD_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) respip.lo
-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.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
@@ -400,6 +402,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscry
@@ -408,6 +410,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h
@@ -48,11 +44,11 @@ Index: unbound-1.7.0~rc1/Makefile.in
# Python Module
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
pythonmod/interface.h \
Index: unbound-1.7.0~rc1/config.h.in
===================================================================
--- unbound-1.7.0~rc1.orig/config.h.in
+++ unbound-1.7.0~rc1/config.h.in
@@ -1228,4 +1228,11 @@ void *unbound_stat_realloc_log(void *ptr
diff --git a/config.h.in b/config.h.in
index 1bfe4426..0136421d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1315,4 +1315,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
/** the version of unbound-control that this software implements */
#define UNBOUND_CONTROL_VERSION 1
@@ -65,10 +61,10 @@ Index: unbound-1.7.0~rc1/config.h.in
+#undef FASTRPZ_LIB_OPEN
+/** turn on fastrpz response policy zones */
+#undef ENABLE_FASTRPZ
Index: unbound-1.7.0~rc1/configure.ac
===================================================================
--- unbound-1.7.0~rc1.orig/configure.ac
+++ unbound-1.7.0~rc1/configure.ac
diff --git a/configure.ac b/configure.ac
index 811ad007..a8346f11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
sinclude(acx_python.m4)
sinclude(ac_pkg_swig.m4)
@@ -77,7 +73,7 @@ Index: unbound-1.7.0~rc1/configure.ac
sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
@@ -1453,6 +1454,9 @@ case "$enable_ipsecmod" in
@@ -1649,6 +1650,9 @@ case "$enable_ipset" in
;;
esac
@@ -87,11 +83,11 @@ Index: unbound-1.7.0~rc1/configure.ac
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
Index: unbound-1.7.0~rc1/daemon/daemon.c
===================================================================
--- unbound-1.7.0~rc1.orig/daemon/daemon.c
+++ unbound-1.7.0~rc1/daemon/daemon.c
@@ -90,6 +90,9 @@
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 96cc443e..d08b2e56 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -91,6 +91,9 @@
#include "sldns/keyraw.h"
#include "respip/respip.h"
#include <signal.h>
@@ -101,36 +97,36 @@ Index: unbound-1.7.0~rc1/daemon/daemon.c
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
@@ -461,6 +464,14 @@ daemon_create_workers(struct daemon* dae
@@ -460,6 +463,14 @@ daemon_create_workers(struct daemon* daemon)
dt_apply_cfg(daemon->dtenv, daemon->cfg);
#else
fatal_exit("dnstap enabled in config but not built with dnstap support");
#endif
}
+#endif
+ }
+ if(daemon->cfg->rpz_enable) {
+#ifdef ENABLE_FASTRPZ
+ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
+#else
+ fatal_exit("fastrpz enabled in config"
+ " but not built with fastrpz");
+#endif
+ }
#endif
}
for(i=0; i<daemon->num; i++) {
if(!(daemon->workers[i] = worker_create(daemon, i,
shufport+numport*i/daemon->num,
@@ -710,6 +721,9 @@ daemon_cleanup(struct daemon* daemon)
@@ -726,6 +737,9 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv);
#endif
daemon->dnscenv = NULL;
+#endif
+#ifdef ENABLE_FASTRPZ
+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
+#endif
#endif
daemon->cfg = NULL;
}
Index: unbound-1.7.0~rc1/daemon/daemon.h
===================================================================
--- unbound-1.7.0~rc1.orig/daemon/daemon.h
+++ unbound-1.7.0~rc1/daemon/daemon.h
@@ -134,6 +134,11 @@ struct daemon {
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 5749dbef..64ce230f 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -136,6 +136,11 @@ struct daemon {
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
@@ -142,11 +138,11 @@ Index: unbound-1.7.0~rc1/daemon/daemon.h
};
/**
Index: unbound-1.7.0~rc1/daemon/worker.c
===================================================================
--- unbound-1.7.0~rc1.orig/daemon/worker.c
+++ unbound-1.7.0~rc1/daemon/worker.c
@@ -74,6 +74,9 @@
diff --git a/daemon/worker.c b/daemon/worker.c
index 263fcddf..e6bc84bd 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -75,6 +75,9 @@
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/sbuffer.h"
@@ -156,7 +152,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
@@ -527,8 +530,27 @@ answer_norec_from_cache(struct worker* w
@@ -533,8 +536,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
/* not secure */
secure = 0;
break;
@@ -182,9 +178,9 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
+ }
+#endif
/* return this delegation from the cache */
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
@@ -689,6 +711,23 @@ answer_from_cache(struct worker* worker,
@@ -699,6 +721,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
secure = 0;
}
} else secure = 0;
@@ -206,9 +202,9 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
+ }
+#endif
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
@@ -1291,6 +1330,15 @@ worker_handle_request(struct comm_point*
@@ -1410,6 +1449,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen);
goto send_reply;
@@ -224,7 +220,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
}
/* If we've found a local alias, replace the qname with the alias
@@ -1339,12 +1387,21 @@ lookup_cache:
@@ -1458,12 +1506,21 @@ lookup_cache:
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
@@ -248,7 +244,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
/* prefetch it if the prefetch TTL expired.
* Note that if there is more than one pass
* its qname must be that used for cache
@@ -1398,11 +1455,19 @@ lookup_cache:
@@ -1518,11 +1575,19 @@ lookup_cache:
lock_rw_unlock(&e->lock);
}
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
@@ -270,14 +266,14 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
goto send_reply;
}
verbose(VERB_ALGO, "answer norec from cache -- "
Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
===================================================================
--- unbound-1.7.0~rc1.orig/doc/unbound.conf.5.in
+++ unbound-1.7.0~rc1/doc/unbound.conf.5.in
@@ -1581,6 +1581,81 @@ It must be /96 or shorter. The default
.B dns64\-synthall: \fI<yes or no>\fR
Debug option, default no. If enabled, synthesize all AAAA records
despite the presence of actual AAAA records.
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index b1d8c790..10c0aa58 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -1801,6 +1801,81 @@ 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 "Response Policy Zone Rewriting"
+.LP
+Response policy zone rewriting is controlled with the
@@ -356,10 +352,11 @@ Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
.SS "DNSCrypt Options"
.LP
The
Index: unbound-1.7.0~rc1/fastrpz/librpz.h
===================================================================
diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
new file mode 100644
index 00000000..645279d1
--- /dev/null
+++ unbound-1.7.0~rc1/fastrpz/librpz.h
+++ b/fastrpz/librpz.h
@@ -0,0 +1,957 @@
+/*
+ * Define the interface from a DNS resolver to the Response Policy Zone
@@ -1318,11 +1315,12 @@ Index: unbound-1.7.0~rc1/fastrpz/librpz.h
+#endif /* LIBRPZ_LIB_OPEN */
+
+#endif /* LIBRPZ_H */
Index: unbound-1.7.0~rc1/fastrpz/rpz.c
===================================================================
diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
new file mode 100644
index 00000000..c5ab7801
--- /dev/null
+++ unbound-1.7.0~rc1/fastrpz/rpz.c
@@ -0,0 +1,1357 @@
+++ b/fastrpz/rpz.c
@@ -0,0 +1,1352 @@
+/*
+ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
+ *
@@ -1438,8 +1436,6 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
+static void
+log_fnc(librpz_log_level_t level, void* ATTR_UNUSED(ctx), const char* buf)
+{
+ char label_buf[sizeof("rpz ")+8];
+
+ /* Setting librpz_log_level overrides the unbound "verbose" level. */
+ if(level > LIBRPZ_LOG_TRACE1 &&
+ level <= librpz->log_level_val(LIBRPZ_LOG_INVALID))
@@ -1949,12 +1945,9 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
+ case st_ck_ns:
+ /* An NSDNAME or NSIP check failed for lack of cached data. */
+ return false;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+ default:
+ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
+ rpz->st);
+#pragma clang diagnostic pop
+ }
+
+ /* Wait for a trigger. */
@@ -2680,10 +2673,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
+}
+
+#endif /* ENABLE_FASTRPZ */
Index: unbound-1.7.0~rc1/fastrpz/rpz.h
===================================================================
diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
new file mode 100644
index 00000000..5d7e31c5
--- /dev/null
+++ unbound-1.7.0~rc1/fastrpz/rpz.h
+++ b/fastrpz/rpz.h
@@ -0,0 +1,138 @@
+/*
+ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
@@ -2823,10 +2817,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.h
+
+#endif /* ENABLE_FASTRPZ */
+#endif /* UNBOUND_FASTRPZ_RPZ_H */
Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
===================================================================
diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
new file mode 100644
index 00000000..21235355
--- /dev/null
+++ unbound-1.7.0~rc1/fastrpz/rpz.m4
+++ b/fastrpz/rpz.m4
@@ -0,0 +1,64 @@
+# fastrpz/rpz.m4
+
@@ -2892,10 +2887,10 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
+ fi
+])
Index: unbound-1.7.0~rc1/iterator/iterator.c
===================================================================
--- unbound-1.7.0~rc1.orig/iterator/iterator.c
+++ unbound-1.7.0~rc1/iterator/iterator.c
diff --git a/iterator/iterator.c b/iterator/iterator.c
index c906c271..55bf2180 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -68,6 +68,9 @@
#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
@@ -2904,9 +2899,9 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
+#include "fastrpz/rpz.h"
+#endif
int
iter_init(struct module_env* env, int id)
@@ -511,6 +514,23 @@ handle_cname_response(struct module_qsta
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
@@ -551,6 +554,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(*mname, r->rk.dname) == 0 &&
!iter_find_rrset_in_prepend_answer(iq, r)) {
@@ -2930,7 +2925,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
/* Add this relevant CNAME rrset to the prepend list.*/
if(!iter_add_prepend_answer(qstate, iq, r))
return 0;
@@ -519,6 +539,9 @@ handle_cname_response(struct module_qsta
@@ -559,6 +579,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
/* Other rrsets in the section are ignored. */
}
@@ -2940,7 +2935,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
msg->rep->ns_numrrsets; i++) {
@@ -1148,6 +1171,7 @@ processInitRequest(struct module_qstate*
@@ -1195,6 +1218,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
uint8_t* delname;
size_t delnamelen;
struct dns_msg* msg = NULL;
@@ -2948,7 +2943,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* check effort */
@@ -1223,8 +1247,7 @@ processInitRequest(struct module_qstate*
@@ -1281,8 +1305,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(msg) {
/* handle positive cache response */
@@ -2958,7 +2953,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
if(verbosity >= VERB_ALGO) {
log_dns_msg("msg from cache lookup", &msg->qinfo,
msg->rep);
@@ -1232,7 +1255,22 @@ processInitRequest(struct module_qstate*
@@ -1290,7 +1313,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
(int)msg->rep->ttl,
(int)msg->rep->prefetch_ttl);
}
@@ -2981,7 +2976,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0;
size_t slen = 0;
@@ -2552,6 +2590,62 @@ processQueryResponse(struct module_qstat
@@ -2714,6 +2752,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
@@ -3041,10 +3036,10 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
+ }
+ }
+#endif
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
if(iq->minimisation_state != DONOT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
LDNS_RCODE_NOERROR) {
@@ -3273,12 +3367,44 @@ processFinished(struct module_qstate* qs
@@ -3467,12 +3561,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
* but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
@@ -3089,11 +3084,11 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = iq->response;
return 0;
Index: unbound-1.7.0~rc1/iterator/iterator.h
===================================================================
--- unbound-1.7.0~rc1.orig/iterator/iterator.h
+++ unbound-1.7.0~rc1/iterator/iterator.h
@@ -383,6 +383,16 @@ struct iter_qstate {
diff --git a/iterator/iterator.h b/iterator/iterator.h
index a2f1b570..e1e4a738 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -386,6 +386,16 @@ struct iter_qstate {
*/
int minimise_count;
@@ -3110,11 +3105,11 @@ Index: unbound-1.7.0~rc1/iterator/iterator.h
/**
* Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. */
Index: unbound-1.7.0~rc1/services/cache/dns.c
===================================================================
--- unbound-1.7.0~rc1.orig/services/cache/dns.c
+++ unbound-1.7.0~rc1/services/cache/dns.c
@@ -876,6 +876,14 @@ dns_cache_store(struct module_env* env,
diff --git a/services/cache/dns.c b/services/cache/dns.c
index aa4efec7..5dd3412e 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -945,6 +945,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct regional* region, uint32_t flags)
{
struct reply_info* rep = NULL;
@@ -3129,11 +3124,11 @@ Index: unbound-1.7.0~rc1/services/cache/dns.c
/* alloc, malloc properly (not in region, like msg is) */
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
Index: unbound-1.7.0~rc1/services/mesh.c
===================================================================
--- unbound-1.7.0~rc1.orig/services/mesh.c
+++ unbound-1.7.0~rc1/services/mesh.c
@@ -59,6 +59,9 @@
diff --git a/services/mesh.c b/services/mesh.c
index 27f91940..f1bd4e90 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -60,6 +60,9 @@
#include "sldns/wire2str.h"
#include "services/localzone.h"
#include "util/data/dname.h"
@@ -3141,9 +3136,9 @@ Index: unbound-1.7.0~rc1/services/mesh.c
+#include "fastrpz/rpz.h"
+#endif
#include "respip/respip.h"
#include "services/listen_dnsport.h"
/** subtract timers and the values do not overflow or become negative */
@@ -1050,6 +1053,13 @@ mesh_send_reply(struct mesh_state* m, in
@@ -1076,6 +1079,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL;
@@ -3157,7 +3152,7 @@ Index: unbound-1.7.0~rc1/services/mesh.c
/* send the reply */
/* We don't reuse the encoded answer if either the previous or current
* response has a local alias. We could compare the alias records
@@ -1199,6 +1209,7 @@ struct mesh_state* mesh_area_find(struct
@@ -1255,6 +1265,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
key.s.is_valrec = valrec;
key.s.qinfo = *qinfo;
key.s.query_flags = qflags;
@@ -3165,7 +3160,7 @@ Index: unbound-1.7.0~rc1/services/mesh.c
/* We are searching for a similar mesh state when we DO want to
* aggregate the state. Thus unique is set to NULL. (default when we
* desire aggregation).*/
@@ -1245,6 +1256,10 @@ int mesh_state_add_reply(struct mesh_sta
@@ -1301,6 +1312,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
if(!r)
return 0;
r->query_reply = *rep;
@@ -3176,11 +3171,11 @@ Index: unbound-1.7.0~rc1/services/mesh.c
r->edns = *edns;
if(edns->opt_list) {
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
Index: unbound-1.7.0~rc1/util/config_file.c
===================================================================
--- unbound-1.7.0~rc1.orig/util/config_file.c
+++ unbound-1.7.0~rc1/util/config_file.c
@@ -1323,6 +1323,8 @@ config_delete(struct config_file* cfg)
diff --git a/util/config_file.c b/util/config_file.c
index 119b2223..ce43a234 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -1434,6 +1434,8 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_socket_path);
free(cfg->dnstap_identity);
free(cfg->dnstap_version);
@@ -3188,12 +3183,12 @@ Index: unbound-1.7.0~rc1/util/config_file.c
+ free(cfg->rpz_cstr);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
#ifdef USE_IPSECMOD
Index: unbound-1.7.0~rc1/util/config_file.h
===================================================================
--- unbound-1.7.0~rc1.orig/util/config_file.h
+++ unbound-1.7.0~rc1/util/config_file.h
@@ -431,6 +431,11 @@ struct config_file {
config_delstrlist(cfg->python_script);
diff --git a/util/config_file.h b/util/config_file.h
index b3ef930a..56173b80 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -494,6 +494,11 @@ struct config_file {
/** true to disable DNSSEC lameness check in iterator */
int disable_dnssec_lame_check;
@@ -3205,11 +3200,11 @@ Index: unbound-1.7.0~rc1/util/config_file.h
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
int ip_ratelimit;
/** number of slabs for ip_ratelimit cache */
Index: unbound-1.7.0~rc1/util/configlexer.lex
===================================================================
--- unbound-1.7.0~rc1.orig/util/configlexer.lex
+++ unbound-1.7.0~rc1/util/configlexer.lex
@@ -412,6 +412,10 @@ dnstap-log-forwarder-query-messages{COLO
diff --git a/util/configlexer.lex b/util/configlexer.lex
index 7a972908..2d03ffc7 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -439,6 +439,10 @@ dnstap-log-forwarder-query-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
dnstap-log-forwarder-response-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
@@ -3220,11 +3215,11 @@ Index: unbound-1.7.0~rc1/util/configlexer.lex
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
Index: unbound-1.7.0~rc1/util/configparser.y
===================================================================
--- unbound-1.7.0~rc1.orig/util/configparser.y
+++ unbound-1.7.0~rc1/util/configparser.y
@@ -124,6 +124,7 @@ extern struct config_parser_state* cfg_p
diff --git a/util/configparser.y b/util/configparser.y
index 10227a2f..a519fcc7 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
@@ -3232,7 +3227,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
%token VAR_DISABLE_DNSSEC_LAME_CHECK
@@ -158,7 +159,7 @@ extern struct config_parser_state* cfg_p
@@ -171,7 +172,7 @@ extern struct config_parser_state* cfg_parser;
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -3241,8 +3236,8 @@ Index: unbound-1.7.0~rc1/util/configparser.y
forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
@@ -2384,6 +2385,50 @@ dt_dnstap_log_forwarder_response_message
(strcmp($2, "yes")==0);
@@ -2726,6 +2727,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
free($2);
}
;
+rpzstart: VAR_RPZ
@@ -3269,7 +3264,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
+
+ OUTYY(("P(rpz_zone:%s)\n", $2));
+ old_cstr = cfg_parser->cfg->rpz_cstr;
+ asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
+ (void)asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
+ if(!new_cstr)
+ yyerror("out of memory");
+ free(old_cstr);
@@ -3282,7 +3277,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
+
+ OUTYY(("P(rpz_option:%s)\n", $2));
+ old_cstr = cfg_parser->cfg->rpz_cstr;
+ asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
+ (void)asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
+ if(!new_cstr)
+ yyerror("out of memory");
+ free(old_cstr);
@@ -3292,11 +3287,11 @@ Index: unbound-1.7.0~rc1/util/configparser.y
pythonstart: VAR_PYTHON
{
OUTYY(("\nP(python:)\n"));
Index: unbound-1.7.0~rc1/util/data/msgencode.c
===================================================================
--- unbound-1.7.0~rc1.orig/util/data/msgencode.c
+++ unbound-1.7.0~rc1/util/data/msgencode.c
@@ -585,6 +585,35 @@ insert_section(struct reply_info* rep, s
diff --git a/util/data/msgencode.c b/util/data/msgencode.c
index a51a4b9b..475dfce9 100644
--- a/util/data/msgencode.c
+++ b/util/data/msgencode.c
@@ -590,6 +590,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
return RETVAL_OK;
}
@@ -3332,10 +3327,10 @@ Index: unbound-1.7.0~rc1/util/data/msgencode.c
/** store query section in wireformat buffer, return RETVAL */
static int
insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
@@ -750,6 +779,19 @@ reply_info_encode(struct query_info* qin
return 0;
@@ -777,6 +806,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
sldns_buffer_write_u16_at(buffer, 10, arcount);
}
sldns_buffer_write_u16_at(buffer, 10, arcount);
+#ifdef ENABLE_FASTRPZ
+ } else if(rep->security == sec_status_rpz_rewritten) {
+ /* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */
@@ -3352,13 +3347,13 @@ Index: unbound-1.7.0~rc1/util/data/msgencode.c
}
sldns_buffer_flip(buffer);
return 1;
Index: unbound-1.7.0~rc1/util/data/packed_rrset.c
===================================================================
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.c
+++ unbound-1.7.0~rc1/util/data/packed_rrset.c
@@ -254,6 +254,10 @@ sec_status_to_string(enum sec_status s)
case sec_status_indeterminate: return "sec_status_indeterminate";
diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
index 7b9d5494..e44b2ce5 100644
--- a/util/data/packed_rrset.c
+++ b/util/data/packed_rrset.c
@@ -255,6 +255,10 @@ sec_status_to_string(enum sec_status s)
case sec_status_insecure: return "sec_status_insecure";
case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
case sec_status_secure: return "sec_status_secure";
+#ifdef ENABLE_FASTRPZ
+ case sec_status_rpz_rewritten: return "sec_status_rpz_rewritten";
@@ -3367,12 +3362,12 @@ Index: unbound-1.7.0~rc1/util/data/packed_rrset.c
}
return "unknown_sec_status_value";
}
Index: unbound-1.7.0~rc1/util/data/packed_rrset.h
===================================================================
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.h
+++ unbound-1.7.0~rc1/util/data/packed_rrset.h
@@ -189,7 +189,15 @@ enum sec_status {
sec_status_insecure,
diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
index 3a5335dd..20113217 100644
--- a/util/data/packed_rrset.h
+++ b/util/data/packed_rrset.h
@@ -193,7 +193,15 @@ enum sec_status {
sec_status_secure_sentinel_fail,
/** SECURE means that the object (RRset or message) validated
* according to local policy. */
- sec_status_secure
@@ -3388,11 +3383,11 @@ Index: unbound-1.7.0~rc1/util/data/packed_rrset.h
};
/**
Index: unbound-1.7.0~rc1/util/netevent.c
===================================================================
--- unbound-1.7.0~rc1.orig/util/netevent.c
+++ unbound-1.7.0~rc1/util/netevent.c
@@ -54,6 +54,9 @@
diff --git a/util/netevent.c b/util/netevent.c
index 9e2ba92b..06ede4e6 100644
--- a/util/netevent.c
+++ b/util/netevent.c
@@ -57,6 +57,9 @@
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
@@ -3402,7 +3397,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
/* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */
@@ -585,6 +588,9 @@ comm_point_udp_ancil_callback(int fd, sh
@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
struct cmsghdr* cmsg;
#endif /* S_SPLINT_S */
@@ -3412,7 +3407,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -674,6 +680,9 @@ comm_point_udp_callback(int fd, short ev
@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
int i;
struct sldns_buffer *buffer;
@@ -3422,7 +3417,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -717,6 +726,9 @@ comm_point_udp_callback(int fd, short ev
@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
(void)comm_point_send_udp_msg(rep.c, buffer,
(struct sockaddr*)&rep.addr, rep.addrlen);
}
@@ -3432,9 +3427,9 @@ Index: unbound-1.7.0~rc1/util/netevent.c
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
another UDP port. Note rep.c cannot be reused with TCP fd. */
break;
@@ -2956,6 +2968,9 @@ comm_point_send_reply(struct comm_reply
comm_point_start_listening(repinfo->c, -1,
repinfo->c->tcp_timeout_msec);
@@ -3152,6 +3164,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
repinfo->c->tcp_timeout_msec);
}
}
+#ifdef ENABLE_FASTRPZ
+ rpz_end(repinfo);
@@ -3442,7 +3437,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
}
void
@@ -2965,6 +2980,9 @@ comm_point_drop_reply(struct comm_reply*
@@ -3161,6 +3176,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
return;
log_assert(repinfo && repinfo->c);
log_assert(repinfo->c->type != comm_tcp_accept);
@@ -3451,22 +3446,22 @@ Index: unbound-1.7.0~rc1/util/netevent.c
+#endif
if(repinfo->c->type == comm_udp)
return;
reclaim_tcp_handler(repinfo->c);
@@ -2984,6 +3002,9 @@ comm_point_start_listening(struct comm_p
if(repinfo->c->tcp_req_info)
@@ -3182,6 +3200,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
{
verbose(VERB_ALGO, "comm point start listening %d",
c->fd==-1?newfd:c->fd);
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
c->fd==-1?newfd:c->fd, msec);
+#ifdef ENABLE_FASTRPZ
+ rpz_end(&c->repinfo);
+#endif
if(c->type == comm_tcp_accept && !c->tcp_free) {
/* no use to start listening no free slots. */
return;
Index: unbound-1.7.0~rc1/util/netevent.h
===================================================================
--- unbound-1.7.0~rc1.orig/util/netevent.h
+++ unbound-1.7.0~rc1/util/netevent.h
@@ -119,6 +119,10 @@ struct comm_reply {
diff --git a/util/netevent.h b/util/netevent.h
index d80c72b3..0233292f 100644
--- a/util/netevent.h
+++ b/util/netevent.h
@@ -120,6 +120,10 @@ struct comm_reply {
/** return type 0 (none), 4(IP4), 6(IP6) */
int srctype;
/* DnsCrypt context */
@@ -3477,11 +3472,11 @@ Index: unbound-1.7.0~rc1/util/netevent.h
#ifdef USE_DNSCRYPT
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
uint8_t nmkey[crypto_box_BEFORENMBYTES];
Index: unbound-1.7.0~rc1/validator/validator.c
===================================================================
--- unbound-1.7.0~rc1.orig/validator/validator.c
+++ unbound-1.7.0~rc1/validator/validator.c
@@ -2688,6 +2688,12 @@ ds_response_to_ke(struct module_qstate*
diff --git a/validator/validator.c b/validator/validator.c
index fa8d5419..5628ef0b 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -2755,6 +2755,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
default:
/* NSEC proof did not work, try next */
break;
@@ -3494,7 +3489,7 @@ Index: unbound-1.7.0~rc1/validator/validator.c
}
sec = nsec3_prove_nods(qstate->env, ve,
@@ -2721,6 +2727,12 @@ ds_response_to_ke(struct module_qstate*
@@ -2788,6 +2794,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
default:
/* NSEC3 proof did not work */
break;
@@ -3507,4 +3502,3 @@ Index: unbound-1.7.0~rc1/validator/validator.c
}
/* Apparently, no available NSEC/NSEC3 proved NODATA, so
+2 -1
View File
@@ -7,7 +7,8 @@ Name: unbound
Description: Library with validating, recursive, and caching DNS resolver
URL: http://www.unbound.net
Version: @PACKAGE_VERSION@
Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@
Requires.private: @PC_PY_DEPENDENCY@
Libs: -L${libdir} -lunbound -lssl -lcrypto
Libs.private: @SSLLIB@ @LIBS@
Cflags: -I${includedir}
+1
View File
@@ -14,6 +14,7 @@ int ub_ctx_set_option(ub_ctx*, string, string);
int ub_ctx_get_option(ub_ctx*, string, +string*);
int ub_ctx_config(ub_ctx*, string);
int ub_ctx_set_fwd(ub_ctx*, string);
int ub_ctx_set_tls(ub_ctx*, bool(int));
int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
int ub_ctx_resolvconf(ub_ctx*, string);
int ub_ctx_hosts(ub_ctx*, string);
+148
View File
@@ -0,0 +1,148 @@
>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001
From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
Date: Wed, 2 Jan 2019 22:52:51 -0800
Subject: [PATCH] Add unbound-fuzzme.
This is a small program that simply parses a packet provided on stdout,
for the purposes of fuzzing.
---
.gitignore | 1 +
Makefile.in | 22 ++++++++++++++++++++--
smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 2 deletions(-)
create mode 100644 smallapp/unbound-fuzzme.c
diff --git a/.gitignore b/.gitignore
index f4527fd8..6163f905 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@
/unbound-checkconf
/unbound-control
/unbound-control-setup
+/unbound-fuzzme
/unbound-host
/unbound.h
/asynclook
diff --git a/Makefile.in b/Makefile.in
index af5b10f6..dacf1ab5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \
worker.lo @WIN_DAEMON_OBJ@
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
+FUZZME_SRC=smallapp/unbound-fuzzme.c
+FUZZME_OBJ=unbound-fuzzme.lo
+FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
+$(COMPAT_OBJ)
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
rsrc_unbound_checkconf.o
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
+ $(FUZZME_SRC) \
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
+ $(FUZZME_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL
all: $(COMMON_OBJ) $(ALLTARGET)
-alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET)
+alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET)
# compat with BSD make, register suffix, and an implicit rule to actualise it.
.SUFFIXES: .lo
@@ -325,6 +331,9 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+unbound-fuzzme$(EXEEXT): $(FUZZME_OBJ_LINK) libunbound.la
+ $(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
clean:
rm -f *.o *.d *.lo *~ tags
- rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
+ rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
rm -f $(ALL_SRC:.c=.lint)
rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
rm -rf autom4te.cache .libs build doc/html doc/xml
@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
$(srcdir)/validator/val_neg.h
+unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.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)/util/net_help.h $(srcdir)/util/ub_event.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h \
diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c
new file mode 100644
index 00000000..74ae5204
--- /dev/null
+++ b/smallapp/unbound-fuzzme.c
@@ -0,0 +1,38 @@
+/*
+ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing).
+ *
+ */
+#include "config.h"
+#include "util/regional.h"
+#include "util/fptr_wlist.h"
+#include "sldns/sbuffer.h"
+
+#define SZ 10000
+
+int main() {
+ char buffer[SZ];
+ size_t n_read = fread(buffer, 1, SZ, stdin);
+ if (n_read == SZ) {
+ printf("input too big\n");
+ return 1;
+ }
+ sldns_buffer *pkt = sldns_buffer_new(n_read);
+ sldns_buffer_init_frm_data(pkt, buffer, n_read);
+
+ struct regional *region = regional_create();
+
+ struct msg_parse* prs;
+ struct edns_data edns;
+ prs = (struct msg_parse*)malloc(sizeof(struct msg_parse));
+ if(!prs) {
+ printf("out of memory on incoming message\n");
+ return 1;
+ }
+ memset(prs, 0, sizeof(*prs));
+ memset(&edns, 0, sizeof(edns));
+ sldns_buffer_set_position(pkt, 0);
+ if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) {
+ printf("parse error\n");
+ return 1;
+ }
+}
--
2.17.1
+2 -2
View File
@@ -39,13 +39,13 @@ start() {
# 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
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
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;
+5 -2
View File
@@ -1,6 +1,9 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
[Install]
WantedBy=multi-user.target
@@ -10,7 +13,7 @@ ExecReload=/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
@@ -21,7 +24,7 @@ ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
RestrictAddressFamilies=AF_INET AF_UNIX
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
+22 -21
View File
@@ -62,7 +62,7 @@
/** dump one rrset zonefile line */
static int
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
{
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
@@ -73,7 +73,7 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
/** dump rrset key and data info */
static int
dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now)
{
size_t i;
@@ -99,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
/** dump lruhash rrset cache */
static int
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
{
struct lruhash_entry* e;
/* lruhash already locked by caller */
@@ -118,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
/** dump rrset cache */
static int
dump_rrset_cache(SSL* ssl, struct worker* worker)
dump_rrset_cache(RES* ssl, struct worker* worker)
{
struct rrset_cache* r = worker->env.rrset_cache;
size_t slab;
@@ -137,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
/** dump message to rrset reference */
static int
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
{
char* nm, *tp, *cl;
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
@@ -164,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
/** dump message entry */
static int
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
time_t now)
{
size_t i;
@@ -246,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
/** dump lruhash msg cache */
static int
dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
{
struct lruhash_entry* e;
struct query_info* k;
@@ -274,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
/** dump msg cache */
static int
dump_msg_cache(SSL* ssl, struct worker* worker)
dump_msg_cache(RES* ssl, struct worker* worker)
{
struct slabhash* sh = worker->env.msg_cache;
size_t slab;
@@ -291,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker)
}
int
dump_cache(SSL* ssl, struct worker* worker)
dump_cache(RES* ssl, struct worker* worker)
{
if(!dump_rrset_cache(ssl, worker))
return 0;
@@ -302,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker)
/** read a line from ssl into buffer */
static int
ssl_read_buf(SSL* ssl, sldns_buffer* buf)
ssl_read_buf(RES* ssl, sldns_buffer* buf)
{
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
sldns_buffer_capacity(buf));
@@ -310,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf)
/** check fixed text on line */
static int
read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
{
if(!ssl_read_buf(ssl, buf)) return 0;
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
@@ -318,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
/** load an RR into rrset */
static int
load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
unsigned int i, int is_rrsig, int* go_on, time_t now)
{
@@ -435,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
/** load an rrset entry */
static int
load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
{
char* s = (char*)sldns_buffer_begin(buf);
struct regional* region = worker->scratchpad;
@@ -519,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
/** load rrset cache */
static int
load_rrset_cache(SSL* ssl, struct worker* worker)
load_rrset_cache(RES* ssl, struct worker* worker)
{
sldns_buffer* buf = worker->env.scratch_buffer;
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
@@ -575,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
/** load a msg rrset reference */
static int
load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
struct regional *region, struct ub_packed_rrset_key** rrset,
int* go_on)
{
@@ -620,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
/** load a msg entry */
static int
load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
{
struct regional* region = worker->scratchpad;
struct query_info qinf;
@@ -653,6 +653,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
rep.qdcount = (uint16_t)qdcount;
rep.ttl = (time_t)ttl;
rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
rep.security = (enum sec_status)security;
if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
log_warn("error too many rrsets");
@@ -685,7 +686,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
/** load msg cache */
static int
load_msg_cache(SSL* ssl, struct worker* worker)
load_msg_cache(RES* ssl, struct worker* worker)
{
sldns_buffer* buf = worker->env.scratch_buffer;
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
@@ -698,7 +699,7 @@ load_msg_cache(SSL* ssl, struct worker* worker)
}
int
load_cache(SSL* ssl, struct worker* worker)
load_cache(RES* ssl, struct worker* worker)
{
if(!load_rrset_cache(ssl, worker))
return 0;
@@ -709,7 +710,7 @@ load_cache(SSL* ssl, struct worker* worker)
/** print details on a delegation point */
static void
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
{
char buf[257];
struct delegpt_addr* a;
@@ -785,7 +786,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
/** print main dp info */
static void
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
{
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
@@ -813,7 +814,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
return;
}
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
size_t nmlen, int ATTR_UNUSED(nmlabs))
{
/* deep links into the iterator module */
+4 -3
View File
@@ -72,6 +72,7 @@
#ifndef DAEMON_DUMPCACHE_H
#define DAEMON_DUMPCACHE_H
struct worker;
#include "daemon/remote.h"
/**
* Dump cache(s) to text
@@ -80,7 +81,7 @@ struct worker;
* ptrs to the caches.
* @return false on ssl print error.
*/
int dump_cache(SSL* ssl, struct worker* worker);
int dump_cache(RES* ssl, struct worker* worker);
/**
* Load cache(s) from text
@@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker);
* ptrs to the caches.
* @return false on ssl error.
*/
int load_cache(SSL* ssl, struct worker* worker);
int load_cache(RES* ssl, struct worker* worker);
/**
* Print the delegation used to lookup for this name.
@@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker);
* @param nmlabs: labels in name.
* @return false on ssl error.
*/
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
size_t nmlen, int nmlabs);
#endif /* DAEMON_DUMPCACHE_H */
+31 -18
View File
@@ -76,6 +76,7 @@
#include "util/shm_side/shm_main.h"
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h"
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
@@ -104,10 +105,8 @@ static int sig_record_reload = 0;
/** cleaner ssl memory freeup */
static void* comp_meth = NULL;
#endif
#ifdef LEX_HAS_YYLEX_DESTROY
/** remove buffers for parsing and init */
int ub_c_lex_destroy(void);
#endif
/** used when no other sighandling happens, so we don't die
* when multiple signals in quick succession are sent to us.
@@ -182,15 +181,8 @@ static void
signal_handling_playback(struct worker* wrk)
{
#ifdef SIGHUP
if(sig_record_reload) {
# ifdef HAVE_SYSTEMD
sd_notify(0, "RELOADING=1");
# endif
if(sig_record_reload)
worker_sighandler(SIGHUP, wrk);
# ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
# endif
}
#endif
if(sig_record_quit)
worker_sighandler(SIGTERM, wrk);
@@ -279,11 +271,20 @@ daemon_init(void)
free(daemon);
return NULL;
}
daemon->tcl = tcl_list_create();
if(!daemon->tcl) {
acl_list_delete(daemon->acl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
if(gettimeofday(&daemon->time_boot, NULL) < 0)
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);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
@@ -574,6 +575,9 @@ void
daemon_fork(struct daemon* daemon)
{
int have_view_respip_cfg = 0;
#ifdef HAVE_SYSTEMD
int ret;
#endif
log_assert(daemon);
if(!(daemon->views = views_create()))
@@ -584,6 +588,8 @@ 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(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
if(daemon->cfg->dnscrypt) {
#ifdef USE_DNSCRYPT
daemon->dnscenv = dnsc_create();
@@ -657,12 +663,20 @@ daemon_fork(struct daemon* daemon)
/* Start resolver service on main thread. */
#ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
ret = sd_notify(0, "READY=1");
if(ret <= 0 && getenv("NOTIFY_SOCKET"))
fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
"access/permission to use the socket presented by systemd.",
getenv("NOTIFY_SOCKET"),
(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
#endif
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(daemon->workers[0]);
#ifdef HAVE_SYSTEMD
sd_notify(0, "STOPPING=1");
if (daemon->workers[0]->need_to_exit)
sd_notify(0, "STOPPING=1");
else
sd_notify(0, "RELOADING=1");
#endif
log_info("service stopped (%s).", PACKAGE_STRING);
@@ -738,18 +752,18 @@ daemon_delete(struct daemon* daemon)
ub_randfree(daemon->rand);
alloc_clear(&daemon->superalloc);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
free(daemon->chroot);
free(daemon->pidfile);
free(daemon->env);
#ifdef HAVE_SSL
listen_sslctx_delete_ticket_keys();
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
#endif
free(daemon);
#ifdef LEX_HAS_YYLEX_DESTROY
/* lex cleanup */
ub_c_lex_destroy();
#endif
/* libcrypto cleanup */
#ifdef HAVE_SSL
# if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
@@ -764,7 +778,7 @@ daemon_delete(struct daemon* daemon)
# endif
# ifdef HAVE_OPENSSL_CONFIG
EVP_cleanup();
# if OPENSSL_VERSION_NUMBER < 0x10100000
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE)
ENGINE_cleanup();
# endif
CONF_modules_free();
@@ -800,9 +814,8 @@ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
{
daemon->cfg = cfg;
config_apply(cfg);
if(!daemon->env->msg_cache ||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {
slabhash_delete(daemon->env->msg_cache);
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
+2
View File
@@ -113,6 +113,8 @@ struct daemon {
struct module_stack mods;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** TCP connection limit, limit connections from client IPs */
struct tcl_list* tcl;
/** local authority zones */
struct local_zones* local_zones;
/** last time of statistics printout */
+373 -269
View File
File diff suppressed because it is too large Load Diff
+21 -6
View File
@@ -73,6 +73,8 @@ struct rc_state {
/** the ssl state */
SSL* ssl;
#endif
/** file descriptor */
int fd;
/** the rc this is part of */
struct daemon_remote* rc;
};
@@ -103,6 +105,19 @@ struct daemon_remote {
#endif
};
/**
* Connection to print to, either SSL or plain over fd
*/
struct remote_stream {
#ifdef HAVE_SSL
/** SSL structure, nonNULL if using SSL */
SSL* ssl;
#endif
/** file descriptor for plain transfer */
int fd;
};
typedef struct remote_stream RES;
/**
* Create new remote control state for the daemon.
* @param cfg: config file with key file settings.
@@ -166,26 +181,26 @@ void daemon_remote_exec(struct worker* worker);
* @param text: the text.
* @return false on connection failure.
*/
int ssl_print_text(SSL* ssl, const char* text);
int ssl_print_text(RES* ssl, const char* text);
/**
* printf style printing to the ssl connection
* @param ssl: the SSL connection to print to. Blocking.
* @param ssl: the RES connection to print to. Blocking.
* @param format: printf style format string.
* @return success or false on a network failure.
*/
int ssl_printf(SSL* ssl, const char* format, ...)
int ssl_printf(RES* ssl, const char* format, ...)
ATTR_FORMAT(printf, 2, 3);
/**
* Read until \n is encountered
* If SSL signals EOF, the string up to then is returned (without \n).
* @param ssl: the SSL connection to read from. blocking.
* If stream signals EOF, the string up to then is returned (without \n).
* @param ssl: the RES connection to read from. blocking.
* @param buf: buffer to read to.
* @param max: size of buffer.
* @return false on connection failure.
*/
int ssl_read_line(SSL* ssl, char* buf, size_t max);
int ssl_read_line(RES* ssl, char* buf, size_t max);
#endif /* HAVE_SSL */
#endif /* DAEMON_REMOTE_H */
+54 -2
View File
@@ -63,6 +63,12 @@
#include "services/authzone.h"
#include "validator/val_kcache.h"
#include "validator/val_neg.h"
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
#ifdef HAVE_SSL
#include <openssl/ssl.h>
#endif
/** add timers and the values do not overflow or become negative */
static void
@@ -71,7 +77,7 @@ stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long l
#ifndef S_SPLINT_S
(*d_sec) += add_sec;
(*d_usec) += add_usec;
if((*d_usec) > 1000000) {
if((*d_usec) >= 1000000) {
(*d_usec) -= 1000000;
(*d_sec)++;
}
@@ -124,6 +130,33 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
(unsigned)worker->env.mesh->stats_jostled);
}
#ifdef CLIENT_SUBNET
/** Set the EDNS Subnet stats. */
static void
set_subnet_stats(struct worker* worker, struct ub_server_stats* svr,
int reset)
{
int m = modstack_find(&worker->env.mesh->mods, "subnet");
struct subnet_env* sne;
if(m == -1)
return;
sne = (struct subnet_env*)worker->env.modinfo[m];
if(reset && !worker->env.cfg->stat_cumulative) {
lock_rw_wrlock(&sne->biglock);
} else {
lock_rw_rdlock(&sne->biglock);
}
svr->num_query_subnet = (long long)(sne->num_msg_nocache + sne->num_msg_cache);
svr->num_query_subnet_cache = (long long)sne->num_msg_cache;
if(reset && !worker->env.cfg->stat_cumulative) {
sne->num_msg_cache = 0;
sne->num_msg_nocache = 0;
}
lock_rw_unlock(&sne->biglock);
}
#endif /* CLIENT_SUBNET */
/** Set the neg cache stats. */
static void
set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
@@ -298,9 +331,18 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
}
lock_rw_unlock(&worker->env.auth_zones->lock);
}
s->svr.mem_stream_wait =
(long long)tcp_req_info_get_stream_buffer_size();
/* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset);
#ifdef CLIENT_SUBNET
/* EDNS Subnet usage numbers */
set_subnet_stats(worker, &s->svr, reset);
#else
s->svr.num_query_subnet = 0;
s->svr.num_query_subnet_cache = 0;
#endif
/* get tcp accept usage */
s->svr.tcp_accept_usage = 0;
@@ -374,6 +416,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qclass_big += a->svr.qclass_big;
total->svr.qtcp += a->svr.qtcp;
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA;
@@ -428,8 +472,16 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
stats->qclass[qclass]++;
else stats->qclass_big++;
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
if(c->type != comm_udp)
if(c->type != comm_udp) {
stats->qtcp++;
if(c->ssl != NULL) {
stats->qtls++;
#ifdef HAVE_SSL
if(SSL_session_reused(c->ssl))
stats->qtls_resume++;
#endif
}
}
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
stats->qipv6++;
if( (flags&BIT_QR) )
+62 -22
View File
@@ -67,6 +67,7 @@
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#include <openssl/ssl.h>
#ifndef S_SPLINT_S
/* splint chokes on this system header file */
@@ -87,30 +88,20 @@
# include "nss.h"
#endif
/** print usage. */
static void usage(void)
/** print build options. */
static void
print_build_options(void)
{
const char** m;
const char *evnm="event", *evsys="", *evmethod="";
time_t t;
struct timeval now;
struct ub_event_base* base;
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help\n");
printf("-c file config file to read instead of %s\n", CONFIGFILE);
printf(" file format is described in unbound.conf(5).\n");
printf("-d do not fork into the background.\n");
printf("-v verbose (more times to increase verbosity)\n");
#ifdef UB_ON_WINDOWS
printf("-w opt windows option: \n");
printf(" install, remove - manage the services entry\n");
printf(" service - used to start from services control panel\n");
#endif
printf("Version %s\n", PACKAGE_VERSION);
printf("Version %s\n\n", PACKAGE_VERSION);
printf("Configure line: %s\n", CONFCMDLINE);
base = ub_default_event_base(0,&t,&now);
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
printf("linked libs: %s %s (it uses %s), %s\n",
printf("Linked libs: %s %s (it uses %s), %s\n",
evnm, evsys, evmethod,
#ifdef HAVE_SSL
# ifdef SSLEAY_VERSION
@@ -124,16 +115,42 @@ static void usage(void)
"nettle"
#endif
);
printf("linked modules:");
printf("Linked modules:");
for(m = module_list_avail(); *m; m++)
printf(" %s", *m);
printf("\n");
#ifdef USE_DNSCRYPT
printf("DNSCrypt feature available\n");
#endif
#ifdef USE_TCP_FASTOPEN
printf("TCP Fastopen feature available\n");
#endif
ub_event_base_free(base);
printf("\nBSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
}
/** print usage. */
static void
usage(void)
{
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help.\n");
printf("-c file config file to read instead of %s\n", CONFIGFILE);
printf(" file format is described in unbound.conf(5).\n");
printf("-d do not fork into the background.\n");
printf("-p do not create a pidfile.\n");
printf("-v verbose (more times to increase verbosity).\n");
printf("-V show version number and build options.\n");
#ifdef UB_ON_WINDOWS
printf("-w opt windows option: \n");
printf(" install, remove - manage the services entry\n");
printf(" service - used to start from services control panel\n");
#endif
printf("\nVersion %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
ub_event_base_free(base);
}
#ifndef unbound_testbound
@@ -429,6 +446,24 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
if(!(daemon->listen_sslctx = listen_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
fatal_exit("could not set up listen SSL_CTX");
if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
}
}
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
}
}
#endif
if(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0) {
if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
}
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert)))
@@ -626,8 +661,10 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char*
fatal_exit("Could not alloc config defaults");
if(!config_read(cfg, cfgfile, daemon->chroot)) {
if(errno != ENOENT)
fatal_exit("Could not read config file: %s",
cfgfile);
fatal_exit("Could not read config file: %s."
" Maybe try unbound -dd, it stays on "
"the commandline to see more errors, "
"or unbound-checkconf", cfgfile);
log_warn("Continuing with default config settings");
}
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
@@ -698,7 +735,7 @@ main(int argc, char* argv[])
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
log_ident_set(log_ident_default);
/* parse the options */
while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) {
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
switch(c) {
case 'c':
cfgfile = optarg;
@@ -719,6 +756,9 @@ main(int argc, char* argv[])
case 'w':
winopt = optarg;
break;
case 'V':
print_build_options();
return 0;
case '?':
case 'h':
default:
@@ -727,7 +767,7 @@ main(int argc, char* argv[])
}
}
argc -= optind;
argv += optind;
/* argv += optind; not using further arguments */
if(winopt) {
#ifdef UB_ON_WINDOWS
+140 -88
View File
@@ -66,6 +66,7 @@
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#include "util/tube.h"
#include "util/edns.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "validator/autotrust.h"
@@ -477,6 +478,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
* Then check if it needs validation, if so, this routine fails,
* so that iterator can prime and validator can verify rrsets.
*/
struct edns_data edns_bak;
uint16_t udpsize = edns->udp_size;
int secure = 0;
time_t timenow = *worker->env.now;
@@ -509,7 +511,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
msg->rep, LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
return 0;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
@@ -534,19 +536,22 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
}
}
/* return this delegation from the cache */
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
return 0;
msg->rep->flags |= BIT_QR|BIT_RA;
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
repinfo->c, worker->scratchpad) ||
!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
repinfo->c->buffer, 0, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
edns->opt_list = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
@@ -614,6 +619,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
struct reply_info* rep, uint16_t id, uint16_t flags,
struct comm_reply* repinfo, struct edns_data* edns)
{
struct edns_data edns_bak;
time_t timenow = *worker->env.now;
uint16_t udpsize = edns->udp_size;
struct reply_info* encode_rep = rep;
@@ -623,7 +629,9 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
&& worker->env.need_to_validate;
*partial_repp = NULL; /* avoid accidental further pass */
if(worker->env.cfg->serve_expired) {
/* always lock rrsets, rep->ttl is ignored */
if(worker->env.cfg->serve_expired_ttl &&
rep->serve_expired_ttl < timenow)
return 0;
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
return 0;
/* below, rrsets with ttl before timenow become TTL 0 in
@@ -652,10 +660,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(!reply_check_cname_chain(qinfo, rep)) {
/* cname chain invalid, redo iterator steps */
verbose(VERB_ALGO, "Cache reply: cname chain broken");
bail_out:
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
return 0;
goto bail_out;
}
}
/* check security status of the cached answer */
@@ -667,7 +672,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
goto bail_out;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
@@ -695,12 +700,13 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
}
} else secure = 0;
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
goto bail_out;
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
if(worker->daemon->use_response_ip && !partial_rep &&
@@ -715,8 +721,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(encode_rep != rep)
secure = 0; /* if rewritten, it can't be considered "secure" */
if(!encode_rep || *alias_rrset) {
sldns_buffer_clear(repinfo->c->buffer);
sldns_buffer_flip(repinfo->c->buffer);
if(!encode_rep)
*need_drop = 1;
else {
@@ -728,11 +732,13 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(!*partial_repp)
goto bail_out;
}
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
} else if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
repinfo->c, worker->scratchpad) ||
!reply_info_answer_encode(qinfo, encode_rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
edns->opt_list = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
@@ -747,20 +753,28 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
}
/* go and return this buffer to the client */
return 1;
bail_out:
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
return 0;
}
/** Reply to client and perform prefetch to keep cache up to date.
* If the buffer for the reply is empty, it indicates that only prefetch is
* necessary and the reply should be suppressed (because it's dropped or
* being deferred). */
/** Reply to client and perform prefetch to keep cache up to date. */
static void
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
uint16_t flags, struct comm_reply* repinfo, time_t leeway)
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
{
/* first send answer to client to keep its latency
* as small as a cachereply */
if(sldns_buffer_limit(repinfo->c->buffer) != 0)
if(!noreply) {
if(repinfo->c->tcp_req_info) {
sldns_buffer_copy(
repinfo->c->tcp_req_info->spool_buffer,
repinfo->c->buffer);
}
comm_point_send_reply(repinfo);
}
server_stats_prefetch(&worker->stats, worker);
/* create the prefetch in the mesh as a normal lookup without
@@ -779,10 +793,11 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
* @param num: number of strings in array.
* @param edns: edns reply information.
* @param worker: worker with scratch region.
* @param repinfo: reply information for a communication point.
*/
static void
chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
struct worker* worker)
struct worker* worker, struct comm_reply* repinfo)
{
int i;
unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
@@ -815,7 +830,7 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
LDNS_RCODE_NOERROR, edns, worker->scratchpad))
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad))
edns->opt_list = NULL;
if(sldns_buffer_capacity(pkt) >=
sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
@@ -825,9 +840,9 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
/** Reply with one string */
static void
chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
struct worker* worker)
struct worker* worker, struct comm_reply* repinfo)
{
chaos_replystr(pkt, (char**)&str, 1, edns, worker);
chaos_replystr(pkt, (char**)&str, 1, edns, worker, repinfo);
}
/**
@@ -835,9 +850,11 @@ chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
* @param pkt: buffer
* @param edns: edns reply information.
* @param w: worker with scratch region.
* @param repinfo: reply information for a communication point.
*/
static void
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w,
struct comm_reply* repinfo)
{
#define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */
#define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */
@@ -848,7 +865,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
if(!w->env.need_to_validate) {
/* no validator module, reply no trustanchors */
chaos_replystr(pkt, NULL, 0, edns, w);
chaos_replystr(pkt, NULL, 0, edns, w, repinfo);
return;
}
@@ -882,7 +899,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
}
lock_basic_unlock(&w->env.anchors->lock);
chaos_replystr(pkt, str_array, num, edns, w);
chaos_replystr(pkt, str_array, num, edns, w, repinfo);
regional_free_all(w->scratchpad);
}
@@ -891,12 +908,13 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
* @param w: worker
* @param qinfo: query info. Pointer into packet buffer.
* @param edns: edns info from query.
* @param repinfo: reply information for a communication point.
* @param pkt: packet buffer.
* @return: true if a reply is to be sent.
*/
static int
answer_chaos(struct worker* w, struct query_info* qinfo,
struct edns_data* edns, sldns_buffer* pkt)
answer_chaos(struct worker* w, struct query_info* qinfo,
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* pkt)
{
struct config_file* cfg = w->env.cfg;
if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
@@ -912,13 +930,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
char buf[MAXHOSTNAMELEN+1];
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
buf[MAXHOSTNAMELEN] = 0;
chaos_replyonestr(pkt, buf, edns, w);
chaos_replyonestr(pkt, buf, edns, w, repinfo);
} else {
log_err("gethostname: %s", strerror(errno));
chaos_replyonestr(pkt, "no hostname", edns, w);
chaos_replyonestr(pkt, "no hostname", edns, w, repinfo);
}
}
else chaos_replyonestr(pkt, cfg->identity, edns, w);
else chaos_replyonestr(pkt, cfg->identity, edns, w, repinfo);
return 1;
}
if(query_dname_compare(qinfo->qname,
@@ -929,8 +947,8 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
if(cfg->hide_version)
return 0;
if(cfg->version==NULL || cfg->version[0]==0)
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
else chaos_replyonestr(pkt, cfg->version, edns, w);
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w, repinfo);
else chaos_replyonestr(pkt, cfg->version, edns, w, repinfo);
return 1;
}
if(query_dname_compare(qinfo->qname,
@@ -938,7 +956,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
{
if(cfg->hide_trustanchor)
return 0;
chaos_trustanchor(pkt, edns, w);
chaos_trustanchor(pkt, edns, w, repinfo);
return 1;
}
@@ -1073,11 +1091,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct ub_packed_rrset_key* alias_rrset = NULL;
struct reply_info* partial_rep = NULL;
struct query_info* lookup_qinfo = &qinfo;
struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */
struct respip_client_info* cinfo = NULL, cinfo_tmp;
memset(&qinfo, 0, sizeof(qinfo));
if(error != NETEVENT_NOERROR) {
if(error != NETEVENT_NOERROR || !repinfo) {
/* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0;
@@ -1156,16 +1174,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* check if this query should be dropped based on source ip rate limiting */
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
*worker->env.now)) {
*worker->env.now, c->buffer)) {
/* See if we are passed through with slip factor */
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
ub_random_max(worker->env.rnd,
worker->env.cfg->ip_ratelimit_factor) == 1) {
worker->env.cfg->ip_ratelimit_factor) == 0) {
char addrbuf[128];
addr_to_str(&repinfo->addr, repinfo->addrlen,
addrbuf, sizeof(addrbuf));
verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
verbose(VERB_QUERY, "ip_ratelimit allowed through for ip address %s because of slip in ip_ratelimit_factor",
addrbuf);
} else {
worker->stats.num_queries_ip_ratelimited++;
@@ -1193,7 +1211,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(worker->env.cfg->log_queries) {
char ip[128];
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
}
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
@@ -1246,29 +1264,52 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(edns.edns_present && edns.edns_version != 0) {
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_short_bufsize) {
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
(int)edns.udp_size);
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
edns.udp_size = NORMAL_UDP_SIZE;
if(edns.edns_present) {
struct edns_option* edns_opt;
if(edns.edns_version != 0) {
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
if(edns.udp_size < NORMAL_UDP_SIZE &&
worker->daemon->cfg->harden_short_bufsize) {
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
(int)edns.udp_size);
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
edns.udp_size = NORMAL_UDP_SIZE;
}
if(c->type != comm_udp) {
edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
if(edns_opt && edns_opt->opt_len > 0) {
edns.ext_rcode = 0;
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list = NULL;
verbose(VERB_ALGO, "query with bad edns keepalive.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, LDNS_RCODE_FORMERR, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
}
}
if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
c->type == comm_udp) {
@@ -1298,7 +1339,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(c->type != comm_udp)
edns.udp_size = 65535; /* max size for TCP replies */
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
&edns, c->buffer)) {
&edns, repinfo, c->buffer)) {
server_stats_insrcode(&worker->stats, c->buffer);
regional_free_all(worker->scratchpad);
goto send_reply;
@@ -1325,7 +1366,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
if(worker->env.auth_zones &&
auth_zones_answer(worker->env.auth_zones, &worker->env,
&qinfo, &edns, c->buffer, worker->scratchpad)) {
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
@@ -1438,7 +1479,8 @@ lookup_cache:
lock_rw_unlock(&e->lock);
reply_and_prefetch(worker, lookup_qinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
repinfo, leeway);
repinfo, leeway,
(partial_rep || need_drop));
if(!partial_rep) {
rc = 0;
regional_free_all(worker->scratchpad);
@@ -1521,8 +1563,17 @@ send_reply_rc:
if(worker->env.cfg->log_replies)
{
struct timeval tv = {0, 0};
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
tv, 1, c->buffer);
if(qinfo.local_alias && qinfo.local_alias->rrset &&
qinfo.local_alias->rrset->rk.dname) {
/* log original qname, before the local alias was
* used to resolve that CNAME to something else */
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
tv, 1, c->buffer);
} else {
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
tv, 1, c->buffer);
}
}
#ifdef USE_DNSCRYPT
if(!dnsc_handle_uncurved_request(repinfo)) {
@@ -1633,14 +1684,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
(((unsigned int)worker->thread_num)<<17);
/* shift thread_num so it does not match out pid bits */
if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
seed = 0;
explicit_bzero(&seed, sizeof(seed));
log_err("could not init random numbers.");
tube_delete(worker->cmd);
free(worker->ports);
free(worker);
return NULL;
}
seed = 0;
explicit_bzero(&seed, sizeof(seed));
#ifdef USE_DNSTAP
if(daemon->cfg->dnstap) {
log_assert(daemon->dtenv != NULL);
@@ -1708,9 +1759,13 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->comsig = NULL;
}
worker->front = listen_create(worker->base, ports,
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
worker->daemon->listen_sslctx, dtenv, worker_handle_request,
worker);
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
cfg->do_tcp_keepalive
? cfg->tcp_keepalive_timeout
: cfg->tcp_idle_timeout,
worker->daemon->tcl,
worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker);
if(!worker->front) {
log_err("could not create listening sockets");
worker_delete(worker);
@@ -1760,8 +1815,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
worker->env = *worker->daemon->env;
comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
if(worker->thread_num == 0)
log_set_time(worker->env.now);
worker->env.worker = worker;
worker->env.worker_base = worker->base;
worker->env.send_query = &worker_send_query;
@@ -1867,7 +1920,6 @@ worker_delete(struct worker* worker)
comm_timer_delete(worker->env.probe_timer);
free(worker->ports);
if(worker->thread_num == 0) {
log_set_time(NULL);
#ifdef UB_ON_WINDOWS
wsvc_desetup_worker(worker);
#endif /* UB_ON_WINDOWS */
@@ -1972,22 +2024,22 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
}
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
}
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
}
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
}
@@ -2000,13 +2052,13 @@ int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
{
log_assert(0);
return 0;
log_assert(0);
return 0;
}
int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);
return 0;
log_assert(0);
return 0;
}
+177 -28
View File
@@ -48,6 +48,9 @@
#include "util/fptr_wlist.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/storage/dnstree.h"
#include "util/data/dname.h"
#include "sldns/str2wire.h"
/******************************************************************************
* *
@@ -67,12 +70,9 @@ static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
#define MAX_PTR_QNAME_IPV4 30
/**
* Per-query module-specific state. This is usually a dynamically-allocated
* structure, but in our case we only need to store one variable describing the
* state the query is in. So we repurpose the minfo pointer by storing an
* integer in there.
* State of DNS64 processing for a query.
*/
enum dns64_qstate {
enum dns64_state {
DNS64_INTERNAL_QUERY, /**< Internally-generated query, no DNS64
processing. */
DNS64_NEW_QUERY, /**< Query for which we're the first module in
@@ -81,6 +81,19 @@ enum dns64_qstate {
for which this sub-query is finished. */
};
/**
* Per-query module-specific state. For the DNS64 module.
*/
struct dns64_qstate {
/** State of the DNS64 module. */
enum dns64_state state;
/** If the dns64 module started with no_cache bool set in the qstate,
* a message to tell it to not modify the cache contents, then this
* is true. The dns64 module is then free to modify that flag for
* its own purposes.
* Otherwise, it is false, the dns64 module was not told to no_cache */
int started_no_cache_store;
};
/******************************************************************************
* *
@@ -111,6 +124,11 @@ struct dns64_env {
* This is the CIDR length of the prefix. It needs to be between 0 and 96.
*/
int prefix_net;
/**
* Tree of names for which AAAA is ignored. always synthesize from A.
*/
rbtree_type ignore_aaaa;
};
@@ -284,6 +302,40 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
* *
******************************************************************************/
/**
* insert ignore_aaaa element into the tree
* @param dns64_env: module env.
* @param str: string with domain name.
* @return false on failure.
*/
static int
dns64_insert_ignore_aaaa(struct dns64_env* dns64_env, char* str)
{
/* parse and insert element */
struct name_tree_node* node;
node = (struct name_tree_node*)calloc(1, sizeof(*node));
if(!node) {
log_err("out of memory");
return 0;
}
node->name = sldns_str2wire_dname(str, &node->len);
if(!node->name) {
free(node);
log_err("cannot parse dns64-ignore-aaaa: %s", str);
return 0;
}
node->labs = dname_count_labels(node->name);
node->dclass = LDNS_RR_CLASS_IN;
if(!name_tree_insert(&dns64_env->ignore_aaaa, node,
node->name, node->len, node->labs, node->dclass)) {
/* ignore duplicate element */
free(node->name);
free(node);
return 1;
}
return 1;
}
/**
* This function applies the configuration found in the parsed configuration
* file \a cfg to this instance of the dns64 module. Currently only the DNS64
@@ -295,6 +347,7 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
static int
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
{
struct config_strlist* s;
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
@@ -311,6 +364,11 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
cfg->dns64_prefix);
return 0;
}
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
if(!dns64_insert_ignore_aaaa(dns64_env, s->str))
return 0;
}
name_tree_init_parents(&dns64_env->ignore_aaaa);
return 1;
}
@@ -329,7 +387,8 @@ dns64_init(struct module_env* env, int id)
log_err("malloc failure");
return 0;
}
env->modinfo[id] = (void*)dns64_env;
env->modinfo[id] = (void*)dns64_env;
name_tree_init(&dns64_env->ignore_aaaa);
if (!dns64_apply_cfg(dns64_env, env->cfg)) {
log_err("dns64: could not apply configuration settings.");
return 0;
@@ -337,6 +396,16 @@ dns64_init(struct module_env* env, int id)
return 1;
}
/** free ignore AAAA elements */
static void
free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg))
{
struct name_tree_node* n = (struct name_tree_node*)node;
if(!n) return;
free(n->name);
free(n);
}
/**
* Deinitializes this instance of the dns64 module.
*
@@ -346,8 +415,14 @@ dns64_init(struct module_env* env, int id)
void
dns64_deinit(struct module_env* env, int id)
{
struct dns64_env* dns64_env;
if (!env)
return;
dns64_env = (struct dns64_env*)env->modinfo[id];
if(dns64_env) {
traverse_postorder(&dns64_env->ignore_aaaa, free_ignore_aaaa_node,
NULL);
}
free(env->modinfo[id]);
env->modinfo[id] = NULL;
}
@@ -405,7 +480,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
if (subq) {
subq->curmod = id;
subq->ext_state[id] = module_state_initial;
subq->minfo[id] = NULL;
subq->minfo[id] = NULL;
}
return module_wait_subquery;
@@ -440,6 +515,25 @@ generate_type_A_query(struct module_qstate* qstate, int id)
return module_wait_subquery;
}
/**
* See if query name is in the always synth config.
* The ignore-aaaa list has names for which the AAAA for the domain is
* ignored and the A is always used to create the answer.
* @param qstate: query state.
* @param id: module id.
* @return true if the name is covered by ignore-aaaa.
*/
static int
dns64_always_synth_for_qname(struct module_qstate* qstate, int id)
{
struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id];
int labs = dname_count_labels(qstate->qinfo.qname);
struct name_tree_node* node = name_tree_lookup(&dns64_env->ignore_aaaa,
qstate->qinfo.qname, qstate->qinfo.qname_len, labs,
qstate->qinfo.qclass);
return (node != NULL);
}
/**
* Handles the "pass" event for a query. This event is received when a new query
* is received by this module. The query may have been generated internally by
@@ -456,7 +550,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
static enum module_ext_state
handle_event_pass(struct module_qstate* qstate, int id)
{
if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
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"))
@@ -464,12 +559,20 @@ handle_event_pass(struct module_qstate* qstate, int id)
return handle_ipv6_ptr(qstate, id);
if (qstate->env->cfg->dns64_synthall &&
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
return generate_type_A_query(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");
return generate_type_A_query(qstate, id);
}
/* We are finished when our sub-query is finished. */
if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
return module_finished;
/* Otherwise, pass request to next module. */
@@ -490,6 +593,7 @@ handle_event_pass(struct module_qstate* qstate, int id)
static enum module_ext_state
handle_event_moddone(struct module_qstate* qstate, int id)
{
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
/*
* In many cases we have nothing special to do. From most to least common:
*
@@ -501,17 +605,36 @@ 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 ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|| (qstate->query_flags & BIT_CD)
|| (qstate->return_msg &&
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)))
return module_finished;
/* 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);
/* 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");
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))
log_err("out of memory");
/* do nothing */
return module_finished;
}
/**
@@ -530,6 +653,7 @@ void
dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
struct dns64_qstate* iq;
(void)outbound;
verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
id, strextstate(qstate->ext_state[id]),
@@ -539,7 +663,12 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
switch(event) {
case module_event_new:
/* Tag this query as being new and fall through. */
qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
iq = (struct dns64_qstate*)regional_alloc(
qstate->region, sizeof(*iq));
qstate->minfo[id] = iq;
iq->state = DNS64_NEW_QUERY;
iq->started_no_cache_store = qstate->no_cache_store;
qstate->no_cache_store = 1;
/* fallthrough */
case module_event_pass:
qstate->ext_state[id] = handle_event_pass(qstate, id);
@@ -551,6 +680,11 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
qstate->ext_state[id] = module_finished;
break;
}
if(qstate->ext_state[id] == module_finished) {
iq = (struct dns64_qstate*)qstate->minfo[id];
if(iq && iq->state != DNS64_INTERNAL_QUERY)
qstate->no_cache_store = iq->started_no_cache_store;
}
}
static void
@@ -677,8 +811,9 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
* Build the actual reply.
*/
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets,
rep->ar_numrrsets, rep->rrset_count, rep->security);
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
rep->rrset_count, rep->security);
if(!cp)
return;
@@ -705,6 +840,12 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
LDNS_RR_CLASS_IN, 0);
/* Delete negative AAAA in msg cache for CNAMEs,
* stored by the iterator module */
if(i != 0) /* if not the first RR */
msg_cache_remove(super->env, dk->rk.dname,
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
LDNS_RR_CLASS_IN, 0);
} else {
dk->entry.hash = fk->entry.hash;
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
@@ -756,9 +897,10 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
* initial query's domain name.
*/
answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
log_assert(answer);
answer->rk.dname = super->qinfo.qname;
answer->rk.dname_len = super->qinfo.qname_len;
if(answer) {
answer->rk.dname = super->qinfo.qname;
answer->rk.dname_len = super->qinfo.qname_len;
}
}
/**
@@ -774,6 +916,7 @@ void
dns64_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id];
log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
&qstate->qinfo);
log_query_info(VERB_ALGO, "super is", &super->qinfo);
@@ -782,15 +925,21 @@ dns64_inform_super(struct module_qstate* qstate, int id,
* Signal that the sub-query is finished, no matter whether we are
* successful or not. This lets the state machine terminate.
*/
super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED;
if(!super_dq) {
super_dq = (struct dns64_qstate*)regional_alloc(super->region,
sizeof(*super_dq));
super->minfo[id] = super_dq;
memset(super_dq, 0, sizeof(*super_dq));
super_dq->started_no_cache_store = super->no_cache_store;
}
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
|| !reply_find_answer_rrset(&qstate->qinfo,
qstate->return_msg->rep))
|| !qstate->return_msg->rep) {
return;
}
/* Use return code from A query in response to client. */
if (super->return_rcode != LDNS_RCODE_NOERROR)
@@ -805,7 +954,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
}
/* Store the generated response in cache. */
if (!super->no_cache_store &&
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))
log_err("out of memory");
+2 -1
View File
@@ -772,12 +772,13 @@ key_get_es_version(uint8_t version[2])
const char *name;
};
const int num_versions = 2;
struct es_version es_versions[] = {
{{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
{{0x00, 0x02}, "X25519-XChacha20Poly1305"},
};
int i;
for(i=0; i < (int)sizeof(es_versions); i++){
for(i=0; i < num_versions; i++){
if(es_versions[i].es_version[0] == version[0] &&
es_versions[i].es_version[1] == version[1]){
return es_versions[i].name;
+17
View File
@@ -39,6 +39,10 @@
#include "config.h"
#include <string.h>
#include <sys/time.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <errno.h>
#include "sldns/sbuffer.h"
#include "util/config_file.h"
#include "util/net_help.h"
@@ -118,6 +122,18 @@ dt_msg_init(const struct dt_env *env,
}
}
/* check that the socket file can be opened and exists, print error if not */
static void
check_socket_file(const char* socket_path)
{
struct stat statbuf;
memset(&statbuf, 0, sizeof(statbuf));
if(stat(socket_path, &statbuf) < 0) {
log_warn("could not open dnstap-socket-path: %s, %s",
socket_path, strerror(errno));
}
}
struct dt_env *
dt_create(const char *socket_path, unsigned num_workers)
{
@@ -134,6 +150,7 @@ dt_create(const char *socket_path, unsigned num_workers)
socket_path);
log_assert(socket_path != NULL);
log_assert(num_workers > 0);
check_socket_file(socket_path);
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
if (!env)
+999 -3
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -76,6 +76,8 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
Disable support for RSASHA256 and RSASHA512 crypto.
* --disable-gost
Disable support for GOST crypto, RFC 5933.
* --enable-subnet
Enable EDNS client subnet processing.
* 'make test' runs a series of self checks.
+65
View File
@@ -0,0 +1,65 @@
## Created a module to support the ipset that could add the domain's ip to a list easily.
### Purposes:
* In my case, I can't access the facebook, twitter, youtube and thousands web site for some reason. VPN is a solution. But the internet too slow whether all traffics pass through the vpn.
So, I set up a transparent proxy to proxy the traffic which has been blocked only.
At the final step, I need to install a dns service which would work with ipset well to launch the system.
I did some research for this. Unfortunately, Unbound, My favorite dns service doesn't support ipset yet. So, I decided to implement it by my self and contribute the patch. It's good for me and the community.
```
# unbound.conf
server:
...
local-zone: "facebook.com" ipset
local-zone: "twitter.com" ipset
local-zone: "instagram.com" ipset
more social website
ipset:
name-v4: "gfwlist"
```
```
# iptables
iptables -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
iptables -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
```
* This patch could work with iptables rules to batch block the IPs.
```
# unbound.conf
server:
...
local-zone: "facebook.com" ipset
local-zone: "twitter.com" ipset
local-zone: "instagram.com" ipset
more social website
ipset:
name-v4: "blacklist"
name-v6: "blacklist6"
```
```
# iptables
iptables -A INPUT -m set --set blacklist src -j DROP
ip6tables -A INPUT -m set --set blacklist6 src -j DROP
```
### Notes:
* To enable this module the root privileges is required.
* Please create a set with ipset command first. eg. **ipset -N blacklist iphash**
### How to use:
```
./configure --enable-ipset
make && make install
```
### Configuration:
```
# unbound.conf
server:
...
local-zone: "example.com" ipset
ipset:
name-v4: "blacklist"
```
+116 -22
View File
@@ -103,7 +103,8 @@ server:
# so-sndbuf: 0
# use SO_REUSEPORT to distribute queries over threads.
# so-reuseport: no
# at extreme load it could be better to turn it off to distribute even.
# so-reuseport: yes
# use IP_TRANSPARENT so the interface: addresses can be non-local
# and you can config non-existing IPs that are going to work later on
@@ -123,6 +124,9 @@ server:
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
# max-udp-size: 4096
# max memory to use for stream(tcp and tls) waiting result buffers.
# stream-wait-size: 4m
# buffer size for handling DNS data. No messages larger than this
# size can be sent or received, by UDP or TCP. In bytes.
# msg-buffer-size: 65552
@@ -145,6 +149,10 @@ server:
# msec to wait before close of port on timeout UDP. 0 disables.
# delay-close: 0
# 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
# 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
@@ -212,6 +220,15 @@ server:
# Default is 0, system default MSS.
# outgoing-tcp-mss: 0
# Idle TCP timeout, connection closed in milliseconds
# tcp-idle-timeout: 30000
# Enable EDNS TCP keepalive option.
# edns-tcp-keepalive: no
# Timeout for EDNS TCP keepalive, in msec.
# edns-tcp-keepalive-timeout: 120000
# Use systemd socket activation for UDP, TCP, and control sockets.
# use-systemd: no
@@ -309,6 +326,17 @@ server:
# timetoresolve, fromcache and responsesize.
# log-replies: no
# log with tag 'query' and 'reply' instead of 'info' for
# filtering log-queries and log-replies from the log.
# log-tag-queryreply: no
# log the local-zone actions, like local-zone type inform is enabled
# also for the other local zone types.
# log-local-actions: no
# print log lines that say why queries return SERVFAIL to clients.
# log-servfail: no
# the pid file. Can be an absolute path outside of chroot/work dir.
# pidfile: "@UNBOUND_PIDFILE@"
@@ -357,7 +385,7 @@ server:
# harden-dnssec-stripped: yes
# Harden against queries that fall under dnssec-signed nxdomain names.
# harden-below-nxdomain: no
# harden-below-nxdomain: yes
# Harden the referral path by performing additional queries for
# infrastructure data. Validates the replies (if possible).
@@ -433,18 +461,24 @@ server:
# if yes, perform key lookups adjacent to normal lookups.
# prefetch-key: no
# deny queries of type ANY with an empty response.
# deny-any: no
# if yes, Unbound rotates RRSet order in response.
# rrset-roundrobin: no
# if yes, Unbound doesn't insert authority/additional sections
# into response messages when those sections are not required.
# minimal-responses: no
# minimal-responses: yes
# true to disable DNSSEC lameness check in iterator.
# disable-dnssec-lame-check: no
# module configuration of the server. A string with identifiers
# separated by spaces. Syntax: "[dns64] [validator] iterator"
# most modules have to be listed at the beginning of the line,
# except cachedb(just before iterator), and python (at the beginning,
# or, just before the iterator).
# module-config: "validator iterator"
# File with trusted keys, kept uptodate using RFC5011 probes,
@@ -459,7 +493,7 @@ server:
# trust anchor signaling sends a RFC8145 key tag query after priming.
# trust-anchor-signaling: yes
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
# root-key-sentinel: yes
@@ -527,6 +561,16 @@ server:
# Serve expired responses from cache, with TTL 0 in the response,
# and then attempt to fetch the data afresh.
# serve-expired: no
#
# Limit serving of expired responses to configured seconds after
# expiration. 0 disables the limit.
# serve-expired-ttl: 0
#
# Set the TTL of expired records to the serve-expired-ttl value after a
# failed attempt to retrieve the record from upstream. This makes sure
# that the expired records will be served as long as there are queries
# for it.
# serve-expired-ttl-reset: no
# Have the validator log failed validations for your diagnosis.
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
@@ -610,6 +654,9 @@ server:
# local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
# And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
# Add example.com into ipset
# local-zone: "example.com" ipset
# If unbound is running service for the local host then it is useful
# to perform lan-wide lookups to the upstream, and unblock the
# long list of local-zones above. If this unbound is a dns server
@@ -633,6 +680,7 @@ server:
# o typetransparent resolves normally for other types and other names
# o inform acts like transparent, but logs client IP address
# o inform_deny drops queries and logs client IP address
# o inform_redirect redirects queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, resolve in
# that way but ignore local data for that name
# o noview breaks out of that view towards global local-zones.
@@ -675,6 +723,19 @@ server:
# tls-service-pem: "path/to/publiccertfile.pem"
# tls-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"
# cipher setting for TLSv1.3
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# Add the secret file for TLS Session Ticket.
# Secret file must be 80 bytes of random data.
# First key use to encrypt and decrypt TLS session tickets.
# Other keys use to decrypt only.
# requires restart to take effect.
# tls-session-ticket-keys: "path/to/secret_file1"
# tls-session-ticket-keys: "path/to/secret_file2"
# request upstream over TLS (with plain DNS inside the TLS stream).
# Default is no. Can be turned on and off with unbound-control.
# tls-upstream: no
@@ -686,12 +747,15 @@ server:
# tls-win-cert: no
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-ports: portno for each of the port numbers.
# tls-additional-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
# DNS64 ignore AAAA records for these domains and use A instead.
# dns64-ignore-aaaa: "example.com"
# ratelimit for uncached, new queries, this limits recursion effort.
# ratelimiting is experimental, and may help against randomqueryflood.
# if 0(default) it is disabled, otherwise state qps allowed per zone.
@@ -725,11 +789,14 @@ server:
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10
# what is considered a low rtt (ping time for upstream server), in msec
# low-rtt: 45
# select low rtt this many times out of 1000. 0 means the fast server
# select is disabled. prefetches are not sped up.
# low-rtt-permil: 0
# Limit the number of connections simultaneous from a netblock
# tcp-connection-limit: 192.0.2.0/24 12
# select from the fastest servers this many times out of 1000. 0 means
# the fast server select is disabled. prefetches are not sped up.
# fast-server-permil: 0
# the number of servers that will be used in the fast server selection.
# fast-server-num: 3
# Specific options for ipsecmod. unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
@@ -763,6 +830,8 @@ server:
# Python config section. To enable:
# o use --with-pythonmodule to configure before compiling.
# o list python in the module-config string (above) to enable.
# It can be at the start, it gets validated results, or just before
# the iterator and process before DNSSEC validation.
# o and give a python-script to run.
python:
# Script file to load
@@ -774,18 +843,20 @@ remote-control:
# set up the keys and certificates with unbound-control-setup.
# control-enable: no
# Set to no and use an absolute path as control-interface to use
# a unix local named pipe for unbound-control.
# control-use-cert: yes
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
# set to an absolute path to use a unix local name pipe, certificates
# are not used for that, so key and cert files need not be present.
# control-interface: 127.0.0.1
# control-interface: ::1
# port number for remote control operations.
# control-port: 8953
# for localhost, you can disable use of TLS by setting this to "no"
# For local sockets this option is ignored, and TLS is not used.
# control-use-cert: "yes"
# unbound server key file.
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
@@ -812,6 +883,7 @@ remote-control:
# stub-prime: no
# stub-first: no
# stub-tls-upstream: no
# stub-no-cache: no
# stub-zone:
# name: "example.org"
# stub-host: ns.example.com.
@@ -828,6 +900,7 @@ remote-control:
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
# forward-first: no
# forward-tls-upstream: no
# forward-no-cache: no
# forward-zone:
# name: "example.org"
# forward-host: fwd.example.com
@@ -843,15 +916,25 @@ remote-control:
# notifies.
# auth-zone:
# name: "."
# master: 199.9.14.201 # b.root-servers.net
# master: 192.33.4.12 # c.root-servers.net
# master: 199.7.91.13 # d.root-servers.net
# master: 192.5.5.241 # f.root-servers.net
# master: 192.112.36.4 # g.root-servers.net
# master: 193.0.14.129 # k.root-servers.net
# master: 192.0.47.132 # xfr.cjr.dns.icann.org
# master: 192.0.32.132 # xfr.lax.dns.icann.org
# master: 2001:500:200::b # b.root-servers.net
# master: 2001:500:2::c # c.root-servers.net
# master: 2001:500:2d::d # d.root-servers.net
# master: 2001:500:2f::f # f.root-servers.net
# master: 2001:500:12::d0d # g.root-servers.net
# master: 2001:7fd::1 # k.root-servers.net
# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
# fallback-enabled: yes
# for-downstream: no
# for-upstream: yes
# fallback-enabled: yes
# master: b.root-servers.net
# master: c.root-servers.net
# master: e.root-servers.net
# master: f.root-servers.net
# master: g.root-servers.net
# master: k.root-servers.net
# auth-zone:
# name: "example.org"
# for-downstream: yes
@@ -899,7 +982,7 @@ remote-control:
# Enable external backend DB as auxiliary cache. Specify the backend name
# (default is "testframe", which has no use other than for debugging and
# testing) and backend-specific options. The 'cachedb' module must be
# included in module-config.
# included in module-config, just before the iterator module.
# cachedb:
# backend: "testframe"
# # secret seed string to calculate hashed keys
@@ -912,3 +995,14 @@ remote-control:
# redis-server-port: 6379
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# IPSet
# Add specify domain into set via ipset.
# Note: To enable ipset needs run unbound as root user.
# ipset:
# # set name for ip v4 addresses
# name-v4: "list-v4"
# # set name for ip v6 addresses
# name-v6: "list-v6"
#
+10
View File
@@ -20,6 +20,7 @@
.B ub_ctx_config,
.B ub_ctx_set_fwd,
.B ub_ctx_set_stub,
.B ub_ctx_set_tls,
.B ub_ctx_resolvconf,
.B ub_ctx_hosts,
.B ub_ctx_add_ta,
@@ -72,6 +73,9 @@
\fIint\fR isprime);
.LP
\fIint\fR
\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
.LP
\fIint\fR
\fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
@@ -227,6 +231,12 @@ for different zones, or to add multiple addresses for a particular zone.
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_set_tls
Enable DNS over TLS (DoT) for machines set with
.B ub_ctx_set_fwd.
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_resolvconf
By default the root servers are queried and full resolver mode is used, but
you can use this call to read the list of nameservers to use from the
+5
View File
@@ -109,6 +109,11 @@ It does so, because the tool when used for bootstrapping the recursive
resolver, cannot use that recursive resolver itself because it is bootstrapping
that server.
.TP
.B \-R
Allow fallback from \-f resolv.conf file to direct root servers query.
It allows you to prefer local resolvers, but fallback automatically
to direct root query if they do not respond or do not support DNSSEC.
.TP
.B \-v
More verbose. Once prints informational messages, multiple times may enable
large debug amounts (such as full certificates or byte\-dumps of downloaded
+35
View File
@@ -293,6 +293,18 @@ ips are dropped before checking the cache.
List the auth zones that are configured. Printed one per line with a
status, indicating if the zone is expired and current serial number.
.TP
.B auth_zone_reload \fIzone\fR
Reload the auth zone from zonefile. The zonefile is read in overwriting
the current contents of the zone in memory. This changes the auth zone
contents itself, not the cache contents. Such cache contents exists if
you set unbound to validate with for-upstream yes and that can be cleared
with \fBflush_zone\fR \fIzone\fR.
.TP
.B auth_zone_transfer \fIzone\fR
Transfer the auth zone from master. The auth zone probe sequence is started,
where the masters are probed to see if they have an updated zone (with the SOA
serial check). And then the zone is transferred for a newer zone version.
.TP
.B view_list_local_zones \fIview\fR
\fIlist_local_zones\fR for given view.
.TP
@@ -310,6 +322,9 @@ status, indicating if the zone is expired and current serial number.
.TP
.B view_local_data_remove \fIview\fR \fIname
\fIlocal_data_remove\fR for given view.
.TP
.B view_local_datas \fIview\fR
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
.SH "EXIT CODE"
The unbound\-control program exits with status code 1 on error, 0 on success.
.SH "SET UP"
@@ -484,6 +499,10 @@ Memory in bytes in use by the iterator module.
Memory in bytes in use by the validator module. Includes the key cache and
negative cache.
.TP
.I mem.streamwait
Memory in bytes in used by the TCP and TLS stream wait buffers. These are
answers waiting to be 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.
@@ -515,6 +534,14 @@ Number of queries that were made using TCP towards the unbound server.
Number of queries that the unbound server made using TCP outgoing towards
other servers.
.TP
.I num.query.tls
Number of queries that were made using TLS towards the unbound server.
These are also counted in num.query.tcp, because TLS uses TCP.
.TP
.I num.query.tls.resume
Number of TLS session resumptions, these are queries over TLS towards
the unbound server where the client negotiated a TLS session resumption key.
.TP
.I num.query.ipv6
Number of queries that were made using IPv6 towards the unbound server.
.TP
@@ -625,6 +652,14 @@ answered using cached data.
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
These queries would otherwise have been sent to the internet, but are now
answered using cached data.
.TP
.I num.query.subnet
Number of queries that got an answer that contained EDNS client subnet data.
.TP
.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.
.SH "FILES"
.TP
.I @ub_conf_file@
+5 -3
View File
@@ -12,20 +12,20 @@
\- unbound DNS lookup utility
.SH "SYNOPSIS"
.B unbound\-host
.RB [ \-C
.IR configfile ]
.RB [ \-vdhr46D ]
.RB [ \-c
.IR class ]
.RB [ \-t
.IR type ]
.I hostname
.RB [ \-y
.IR key ]
.RB [ \-f
.IR keyfile ]
.RB [ \-F
.IR namedkeyfile ]
.RB [ \-C
.IR configfile ]
.I hostname
.SH "DESCRIPTION"
.B Unbound\-host
uses the unbound validating resolver to query for the hostname and display
@@ -86,6 +86,8 @@ are read.
.B \-C \fIconfigfile
Uses the specified unbound.conf to prime
.IR libunbound (3).
Pass it as first argument if you want to override some options from the
config file with further arguments on the commandline.
.TP
.B \-r
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
+4 -1
View File
@@ -54,7 +54,7 @@ resolvers are using the same port number (53).
The available options are:
.TP
.B \-h
Show the version and commandline option help.
Show the version number and commandline option help, and exit.
.TP
.B \-c\fI cfgfile
Set the config file with settings for unbound to read instead of reading the
@@ -76,6 +76,9 @@ concurrently.
.B \-v
Increase verbosity. If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.TP
.B \-V
Show the version number and build options, and exit.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\-checkconf\fR(8),
+232 -60
View File
@@ -121,7 +121,7 @@ interface and port number), if not specified the default port (from
\fBport\fR) is used.
.TP
.B ip\-address: \fI<ip address[@port]>
Same as interface: (for easy of compatibility with nsd.conf).
Same as interface: (for ease of compatibility with nsd.conf).
.TP
.B interface\-automatic: \fI<yes or no>
Detect source interface on UDP queries and copy them to replies. This
@@ -207,6 +207,16 @@ 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.
.TP
.B stream\-wait\-size: \fI<number>
Number of bytes size maximum to use for waiting stream buffers. Default is
4 megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
megabytes or gigabytes (1024*1024 bytes in a megabyte). As TCP and TLS streams
queue up multiple results, the amount of memory used for these buffers does
not exceed this number, otherwise the responses are dropped. This manages
the total memory usage of the server (under heavy use), the number of requests
that can be queued up per connection is also limited, with further requests
waiting in TCP buffers.
.TP
.B msg\-buffer\-size: \fI<number>
Number of bytes size of the message buffers. Default is 65552 bytes, enough
for 64 Kb packets, the maximum DNS message size. No message larger than this
@@ -253,6 +263,12 @@ eg. 1500 msec. When timeouts happen you need extra sockets, it checks
the ID and remote IP of packets, and unwanted packets are added to the
unwanted packet counter.
.TP
.B unknown\-server\-time\-limit: \fI<msec>
The wait time in msec for waiting for an unknown server to reply.
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 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
@@ -278,12 +294,14 @@ to so\-rcvbuf.
.B so\-reuseport: \fI<yes or no>
If yes, then open dedicated listening sockets for incoming queries for each
thread and try to set the SO_REUSEPORT socket option on each socket. May
distribute incoming queries to threads more evenly. Default is no. On Linux
it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX it may
also work. You can enable it (on any platform and kernel),
distribute incoming queries to threads more evenly. Default is yes.
On Linux it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX
it may also work. You can enable it (on any platform and kernel),
it then attempts to open the port and passes the option if it was available
at compile time, if that works it is used, if it fails, it continues
silently (unless verbosity 3) without the option.
At extreme load it could be better to turn it off to distribute the queries
evenly, reported for Linux systems (4.4.x).
.TP
.B ip\-transparent: \fI<yes or no>
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
@@ -314,11 +332,9 @@ Must be set to a power of 2.
.TP
.B cache\-max\-ttl: \fI<seconds>
Time to live maximum for RRsets and messages in the cache. Default is
86400 seconds (1 day). If the maximum kicks in, responses to clients
still get decrementing TTLs based on the original (larger) values.
When the internal TTL expires, the cache item has expired.
86400 seconds (1 day). When the TTL expires, the cache item has expired.
Can be set lower to force the resolver to query for data often, and not
trust (very large) TTL values.
trust (very large) TTL values. Downstream clients also see the lower TTL.
.TP
.B cache\-min\-ttl: \fI<seconds>
Time to live minimum for RRsets and messages in the cache. Default is 0.
@@ -389,6 +405,37 @@ Note that not all platform supports socket option to set MSS (TCP_MAXSEG).
Default is system default MSS determined by interface MTU and
negotiation between Unbound and other servers.
.TP
.B tcp-idle-timeout: \fI<msec>\fR
The period Unbound will wait for a query on a TCP connection.
If this timeout expires Unbound closes the connection.
This option defaults to 30000 milliseconds.
When the number of free incoming TCP buffers falls below 50% of the
total number configured, the option value used is progressively
reduced, first 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 timeout of
200 milliseconds is observed regardless of the option value used.
.TP
.B edns-tcp-keepalive: \fI<yes or no>\fR
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,
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 tcp\-upstream: \fI<yes or no>
Enable or disable whether the upstream queries use TCP only for transport.
Default is no. Useful in tunneling scenarios.
@@ -403,22 +450,25 @@ Enabled or disable whether the upstream queries use TLS only for transport.
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
TCP wireformat. The other server must support this (see
\fBtls\-service\-key\fR).
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-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.
.TP
.B ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
file the last is used.
.TP
.B tls\-service\-key: \fI<file>
If enabled, the server provider TLS service on its TCP sockets. The clients
have to use tls\-upstream: yes. The file is the private key for the TLS
session. The public certificate is in the tls\-service\-pem file. Default
is "", turned off. Requires a restart (a reload is not enough) if changed,
because the private key is read while root permissions are held and before
chroot (if any). Normal DNS TCP service is not provided and gives errors,
this service is best run with a different \fBport:\fR config or \fI@port\fR
suffixes in the \fBinterface\fR config.
If enabled, the server provides TLS service on the TCP ports marked
implicitly or explicitly for TLS service with tls\-port. The file must
contain the private key for the TLS session, the public certificate is in
the tls\-service\-pem file and it must also be specified if tls\-service\-key
is specified. The default is "", turned off. Enabling or disabling
this service requires a restart (a reload is not enough), because the
key is read while root permissions are held and before chroot (if any).
The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide
normal DNS TCP service.
.TP
.B ssl\-service\-key: \fI<file>
Alternate syntax for \fBtls\-service\-key\fR.
@@ -452,11 +502,32 @@ If no cert bundle, it uses only these certificates. Default is no.
On windows this option uses the certificates from the cert store. Use
the tls\-cert\-bundle option on other systems.
.TP
.B tls\-additional\-ports: \fI<portnr>
List portnumbers as tls\-additional\-ports, and when interfaces are defined,
.B tls\-additional\-port: \fI<portnr>
List portnumbers as tls\-additional\-port, and when interfaces are defined,
eg. with the @port suffix, as this port number, they provide dns over TLS
service. Can list multiple, each on a new statement.
.TP
.B tls-session-ticket-keys: \fI<file>
If not "", lists files with 80 bytes of random contents that are used to
perform TLS session resumption for clients using the unbound server.
These files contain the secret key for the TLS session tickets.
First key use to encrypt and decrypt TLS session tickets.
Other keys use to decrypt only. With this you can roll over to new keys,
by generating a new first file and allowing decrypt of the old file by
listing it after the first file for some time, after the wait clients are not
using the old key any more and the old key can be removed.
One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat
The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key. Then there is 32 bytes random
data for an AES key and then 32 bytes random data for the HMAC key.
.TP
.B tls\-ciphers: \fI<string with cipher list>
Set the list of ciphers to allow when serving TLS. Use "" for defaults,
and that is the default.
.TP
.B tls\-ciphersuites: \fI<string with ciphersuites list>
Set the list of ciphersuites to allow when serving TLS. This is for newer
TLS 1.3 connections. Use "" for defaults, and that is the default.
.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
Default is no.
@@ -466,12 +537,18 @@ Enable or disable whether the unbound server forks into the background as
a daemon. Set the value to \fIno\fR when unbound runs as systemd service.
Default is yes.
.TP
.B tcp\-connection\-limit: \fI<IP netblock> <limit>
Allow up to \fIlimit\fR simultaneous TCP connections from the given netblock.
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>
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.
The order of the access\-control statements therefore does not matter.
.IP
The action \fIdeny\fR stops queries from hosts from that netblock.
.IP
@@ -552,13 +629,16 @@ In the last case the path is adjusted to remove the unused portion.
The pidfile can be either a relative path to the working directory, or
an absolute path relative to the original root. It is written just prior
to chroot and dropping permissions. This allows the pidfile to be
/var/run/unbound.pid and the chroot to be /var/unbound, for example.
/var/run/unbound.pid and the chroot to be /var/unbound, for example. Note that
Unbound is not able to remove the pidfile after termination when it is located
outside of the chroot directory.
.IP
Additionally, unbound may need to access /dev/random (for entropy)
from inside the chroot.
.IP
If given a chroot is done to the given directory. The default is
"@UNBOUND_CHROOT_DIR@". If you give "" no chroot is performed.
If given a chroot is done to the given directory. By default chroot is
enabled and the default is "@UNBOUND_CHROOT_DIR@". If you give "" no
chroot is performed.
.TP
.B username: \fI<name>
If given, after binding the port the user privileges are dropped. Default is
@@ -618,6 +698,21 @@ Default is no. Note that it takes time to print these
lines which makes the server (significantly) slower. Odd (nonprintable)
characters in names are printed as '?'.
.TP
.B log\-tag\-queryreply: \fI<yes or no>
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\-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
types of local zones.
.TP
.B log\-servfail: \fI<yes or no>
Print log lines that say why queries return SERVFAIL to clients.
This is separate from the verbosity debug logs, much smaller, and printed
at the error level, not the info level of debug info from verbosity.
.TP
.B pidfile: \fI<filename>
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
So,
@@ -700,7 +795,7 @@ noerror for empty nonterminals, hence this is possible. Very old software
might return nxdomain for empty nonterminals (that usually happen for reverse
IP address lookups), and thus may be incompatible with this. To try to avoid
this only DNSSEC-secure nxdomains are used, because the old software does not
have DNSSEC. Default is off.
have DNSSEC. Default is on.
The nxdomain must be secure, this means nsec3 with optout is insufficient.
.TP
.B harden\-referral\-path: \fI<yes or no>
@@ -737,7 +832,7 @@ Can be given multiple times, for different domains.
.TP
.B qname\-minimisation: \fI<yes or no>
Send minimum amount of information to upstream servers to enhance privacy.
Only sent minimum required labels of the QNAME and set QTYPE to A when
Only send minimum required labels of the QNAME and set QTYPE to A when
possible. Best effort approach; full QNAME and original QTYPE will be sent when
upstream replies with a RCODE other than NOERROR, except when receiving
NXDOMAIN from a DNSSEC signed zone. Default is yes.
@@ -801,12 +896,18 @@ 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>
.B prefetch\-key: \fI<yes or no>
If yes, fetch the DNSKEYs earlier in the validation process, when a DS
record is encountered. This lowers the latency of requests. It does use
a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
.TP
.B rrset-roundrobin: \fI<yes or no>
.B deny\-any: \fI<yes or no>
If yes, deny queries of type ANY with an empty response. Default is no.
If disabled, unbound responds with a short list of resource records if some
can be found in the cache and makes the upstream type ANY query if there
are none.
.TP
.B rrset\-roundrobin: \fI<yes or no>
If yes, Unbound rotates RRSet order in response (the random number is taken
from the query ID, for speed and thread safety). Default is no.
.TP
@@ -814,9 +915,11 @@ from the query ID, for speed and thread safety). Default is no.
If yes, Unbound doesn't 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 no, because the DNS
This 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.
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.
.TP
.B disable-dnssec-lame-check: \fI<yes or no>
If true, disables the DNSSEC lameness check in the iterator. This check
@@ -832,6 +935,12 @@ Setting this to "iterator" will result in a non\-validating server.
Setting this to "validator iterator" will turn on DNSSEC validation.
The ordering of the modules is important.
You must also set trust\-anchors for validation to be useful.
The default is "validator iterator". When the server is built with
EDNS client subnet support the default is "subnetcache validator iterator".
Most modules that need to be listed here have to be listed at the beginning
of the line. The cachedb module has to be listed just before the iterator.
The python module can be listed in different places, it then processes the
output of the module it is just before.
.TP
.B trust\-anchor\-file: \fI<filename>
File with trusted keys for validation. Both DS and DNSKEY entries can appear
@@ -964,6 +1073,17 @@ If enabled, unbound attempts to serve old responses from cache with a
TTL of 0 in the response without waiting for the actual resolution to finish.
The actual resolution answer ends up in the cache later on. Default is "no".
.TP
.B serve\-expired\-ttl: \fI<seconds>
Limit serving of expired responses to configured seconds after expiration. 0
disables the limit. This option only applies when \fBserve\-expired\fR is
enabled. The default is 0.
.TP
.B serve\-expired\-ttl\-reset: \fI<yes or no>
Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a
failed attempt to retrieve the record from upstream. This makes sure that the
expired records will be served as long as there are queries for it. Default is
"no".
.TP
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
List of keysize and iteration count values, separated by spaces, surrounded
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
@@ -1012,7 +1132,7 @@ Number of bytes size of the aggressive negative cache. Default is 1 megabyte.
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
or gigabytes (1024*1024 bytes in a megabyte).
.TP
.B unblock\-lan\-zones: \fI<yesno>
.B unblock\-lan\-zones: \fI<yes or no>
Default is disabled. If enabled, then for private address space,
the reverse lookups are no longer filtered. This allows unbound when
running as dns service on a host where it provides service for that host,
@@ -1023,7 +1143,7 @@ as a (DHCP-) DNS network resolver for a group of machines, where such
lookups should be filtered (RFC compliance), this also stops potential
data leakage about the local network to the upstream DNS servers.
.TP
.B insecure\-lan\-zones: \fI<yesno>
.B insecure\-lan\-zones: \fI<yes or no>
Default is disabled. If enabled, then reverse lookups in private
address space are not validated. This is usually required whenever
\fIunblock\-lan\-zones\fR is used.
@@ -1032,7 +1152,7 @@ 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,
always_transparent, always_refuse, always_nxdomain, noview,
inform_redirect, always_transparent, always_refuse, always_nxdomain, 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.
@@ -1093,6 +1213,10 @@ looking up infected names are logged, eg. to run antivirus on them.
The query is dropped, like 'deny', and logged, like 'inform'. Ie. find
infected machines without answering the queries.
.TP 10
\h'5'\fIinform_redirect\fR
The query is redirected, like 'redirect', and logged, like 'inform'.
Ie. answer queries with fixed data and also log the machines that ask.
.TP 10
\h'5'\fIalways_transparent\fR
Like transparent, but ignores local data and resolves normally.
.TP 10
@@ -1248,7 +1372,8 @@ TTL can be inserted like this: "2001:DB8::4 7200 www.example.com"
Assign tags to localzones. Tagged localzones will only be applied when the
used access-control element has a matching tag. Tags must be defined in
\fIdefine\-tags\fR. Enclose list of tags in quotes ("") and put spaces between
tags.
tags. When there are multiple tags it checks if the intersection of the
list of tags for the query and local\-zone\-tag is non-empty.
.TP 5
.B local\-zone\-override: \fI<zone> <IP netblock> <type>
Override the localzone type for queries from addresses matching netblock.
@@ -1331,22 +1456,20 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the
factor given.
.TP 5
.B low\-rtt: \fI<msec time>
Set the time in millisecond that is considere a low ping time for fast
server selection with the low\-rtt\-permil option, that turns this on or off.
The default is 45 msec, a number from IPv6 quick response documents.
.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
servers 90 percent of the time, and would perform normal exploration of random
servers for the remaining time. When prefetch is enabled (or serve\-expired),
such prefetches are not sped up, because there is no one waiting for it, and it
presents a good moment to perform server exploration. The
\fBfast\-server\-num\fR option can be used to specify the size of the fastest
servers set. The default for fast\-server\-permil is 0.
.TP 5
.B low\-rtt\-permil: \fI<number>
Specify how many times out of 1000 to pick the fast server from the low
rtt band. 0 turns the feature off. A value of 900 would pick the fast
server when such fast servers are available 90 percent of the time, and
the remaining time perform normal exploration of random servers.
When prefetch is enabled (or serve\-expired), such prefetches are not
sped up, because there is no one waiting for it, and it presents a good
moment to perform server exploration. The low\-rtt option can be used
to specify which servers are picked for fast server selection, servers
with a ping roundtrip time below that value are considered.
The default for low\-rtt\-permil is 0.
.B fast\-server\-num: \fI<number>
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.
.SS "Remote Control Options"
In the
.B remote\-control:
@@ -1369,6 +1492,14 @@ 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
the server for the change to take effect.
.IP
If you set it to an absolute path, a local socket is used. The local socket
does not use the certificates and keys, so those files need not be present.
To restrict access, unbound sets permissions on the file to the user and
group that is configured, the access bits are set to allow the group members
to access the control socket file. Put users that need to access the socket
in the that group. To restrict access further, create a directory to put
the control socket in and restrict access to that directory.
.TP 5
.B control\-port: \fI<port number>
The port number to listen on for IPv4 or IPv6 control interfaces,
@@ -1377,11 +1508,9 @@ If you change this and permissions have been dropped, you must restart
the server for the change to take effect.
.TP 5
.B control\-use\-cert: \fI<yes or no>
Whether to require certificate authentication of control connections.
The default is "yes".
This should not be changed unless there are other mechanisms in place
to prevent untrusted users from accessing the remote control
interface.
For localhost control-interface you can disable the use of TLS by setting
this option to "no", default is "yes". For local sockets, TLS is disabled
and the value of this option is ignored.
.TP 5
.B server\-key\-file: \fI<private key file>
Path to the server private key, by default unbound_server.key.
@@ -1464,6 +1593,10 @@ Default is no.
.TP
.B stub\-ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBstub\-tls\-upstream\fR.
.TP
.B stub\-no\-cache: \fI<yes or no>
Default is no. If enabled, data inside the stub is not cached. This is
useful when you want immediate changes to be visible.
.SS "Forward Zone Options"
.LP
There may be multiple
@@ -1500,19 +1633,22 @@ If you leave out the '#' and auth name from the forward\-addr, any
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
.TP
.B forward\-first: \fI<yes or no>
If enabled, a query is attempted without the forward clause if it fails.
The data could not be retrieved and would have caused SERVFAIL because
the servers are unreachable, instead it is tried without this clause.
The default is no.
If a forwarded query is met with a SERVFAIL error, and this option is
enabled, unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified. The default is "no".
.TP
.B forward\-tls\-upstream: \fI<yes or no>
Enabled or disable whether the queries to this forwarder use TLS for transport.
Default is no.
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\cert to
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
load CA certs, otherwise the connections cannot be authenticated.
.TP
.B forward\-ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBforward\-tls\-upstream\fR.
.TP
.B forward\-no\-cache: \fI<yes or no>
Default is no. If enabled, data inside the forward is not cached. This is
useful when you want immediate changes to be visible.
.SS "Authority Zone Options"
.LP
Authority zones are configured with \fBauth\-zone:\fR, and each one must
@@ -1529,6 +1665,13 @@ lookups of that data.
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
uses the SOA timer values and performs SOA UDP queries to detect zone changes.
.LP
If the update fetch fails, the timers in the SOA record are used to time
another fetch attempt. Until the SOA expiry timer is reached. Then the
zone is expired. When a zone is expired, queries are SERVFAIL, and
any new serial number is accepted from the master (even if older), and if
fallback is enabled, the fallback activates to fetch from the upstream instead
of the SERVFAIL.
.TP
.B name: \fI<zone name>
Name of the authority zone.
@@ -1536,6 +1679,7 @@ Name of the authority zone.
.B master: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails.
With the "ip#name" notation a AXFR over TLS can be used.
.TP
.B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example
@@ -1587,7 +1731,9 @@ data (eg. from the master servers).
There may be multiple
.B view:
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the
\fBlocal\-data\fR elements. Views can also contain view\-first,
response\-ip, response\-ip\-data and local\-data\-ptr elements.
View can be mapped to requests by specifying the
view name in an \fBaccess\-control\-view\fR element. Options from matching
views will override global options. Global options will be used if no matching
view is found, or when the matching view does not have the option specified.
@@ -1624,7 +1770,8 @@ clause gives the settings for the \fIpython\fR(1) script module. This module
acts like the iterator and validator modules do, on queries and answers.
To enable the script module it has to be compiled into the daemon,
and the word "python" has to be put in the \fBmodule\-config:\fR option
(usually first, or between the validator and iterator).
(usually first, or between the validator and iterator). Multiple instances of
the python module are supported by adding the word "python" more than once.
.LP
If the \fBchroot:\fR option is enabled, you should make sure Python's
library directory structure is bind mounted in the new root environment, see
@@ -1633,7 +1780,8 @@ absolute path relative to the new root, or as a relative path to the working
directory.
.TP
.B python\-script: \fI<python file>\fR
The script file to load.
The script file to load. Repeat this option for every python module instance
added to the \fBmodule\-config:\fR option.
.SS "DNS64 Module Options"
.LP
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
@@ -1647,6 +1795,12 @@ It must be /96 or shorter. The default prefix is 64:ff9b::/96.
.B dns64\-synthall: \fI<yes or no>\fR
Debug option, default no. If enabled, synthesize all AAAA records
despite the presence of actual AAAA records.
.TP
.B dns64\-ignore\-aaaa: \fI<name>\fR
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 "DNSCrypt Options"
.LP
The
@@ -1762,6 +1916,24 @@ to expose to third parties for IPv6. Defaults to 56.
.B max\-client\-subnet\-ipv4: \fI<number>\fR
Specifies the maximum prefix length of the client source address we are willing
to expose to third parties for IPv4. Defaults to 24.
.TP
.B min\-client\-subnet\-ipv6: \fI<number>\fR
Specifies the minimum prefix length of the IPv6 source mask we are willing to
accept in queries. Shorter source masks result in REFUSED answers. Source mask
of 0 is always accepted. Default is 0.
.TP
.B min\-client\-subnet\-ipv4: \fI<number>\fR
Specifies the minimum prefix length of the IPv4 source mask we are willing to
accept in queries. Shorter source masks result in REFUSED answers. Source mask
of 0 is always accepted. Default is 0.
.TP
.B max\-ecs\-tree\-size\-ipv4: \fI<number>\fR
Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
This number applies for each qname/qclass/qtype tuple. Defaults to 100.
.TP
.B max\-ecs\-tree\-size\-ipv6: \fI<number>\fR
Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
This number applies for each qname/qclass/qtype tuple. Defaults to 100.
.SS "Opportunistic IPsec Support Module Options"
.LP
The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
+9 -3
View File
@@ -612,18 +612,24 @@ RECURSIVE = YES
EXCLUDE = ./build \
./compat \
./contrib \
util/configparser.c \
util/configparser.h \
util/configlexer.c \
util/locks.h \
pythonmod/doc \
pythonmod/examples \
pythonmod/unboundmodule.py \
pythonmod/interface.h \
pythonmod/examples/resgen.py \
pythonmod/examples/resmod.py \
pythonmod/examples/resip.py \
pythonmod/ubmodule-msg.py \
pythonmod/ubmodule-tst.py \
unboundmodule.py \
libunbound/python/unbound.py \
libunbound/python/libunbound_wrap.c \
libunbound/python/doc \
libunbound/python/examples \
./ldns-src \
README.md \
doc/control_proto_spec.txt \
doc/requirements.txt
+1 -1
View File
@@ -119,7 +119,7 @@ node_size(const struct addrtree *tree, const struct addrnode *n)
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count)
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count)
{
struct addrtree *tree;
log_assert(delfunc != NULL);
+3 -3
View File
@@ -66,10 +66,10 @@ struct addrtree {
struct addrnode *root;
/** Number of elements in the tree (not always equal to number of
* nodes) */
unsigned int node_count;
uint32_t node_count;
/** Maximum number of allowed nodes, will be enforced by LRU list.
* Excluding the root node, 0 for unlimited */
unsigned int max_node_count;
uint32_t max_node_count;
/** Size of tree in bytes */
size_t size_bytes;
/** Maximum prefix length we are willing to cache. */
@@ -137,7 +137,7 @@ size_t addrtree_size(const struct addrtree *tree);
*/
struct addrtree *
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count);
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count);
/**
* Free tree and all nodes below.
+76 -25
View File
@@ -55,8 +55,7 @@
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "sldns/sbuffer.h"
#define ECS_MAX_TREESIZE 100
#include "iterator/iter_utils.h"
/** externally called */
void
@@ -93,6 +92,7 @@ subnet_new_qstate(struct module_qstate *qstate, int id)
return 0;
qstate->minfo[id] = sq;
memset(sq, 0, sizeof(*sq));
sq->started_no_cache_store = qstate->no_cache_store;
return 1;
}
@@ -150,7 +150,9 @@ int ecs_whitelist_check(struct query_info* qinfo,
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
qstate->no_cache_store = 0;
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo)) {
qstate->no_cache_store = 0;
}
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
qstate->env->cfg->client_subnet_always_forward) ||
@@ -177,6 +179,14 @@ int ecs_whitelist_check(struct query_info* qinfo,
}
void
subnet_markdel(void* key)
{
struct msgreply_entry *e = (struct msgreply_entry*)key;
e->key.qtype = 0;
e->key.qclass = 0;
}
int
subnetmod_init(struct module_env *env, int id)
{
@@ -193,6 +203,7 @@ subnetmod_init(struct module_env *env, int id)
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
msg_cache_sizefunc, query_info_compare, query_entry_delete,
subnet_data_delete, NULL);
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
if(!sn_env->subnet_msg_cache) {
log_err("subnet: could not create cache");
free(sn_env);
@@ -291,13 +302,13 @@ get_tree(struct subnet_msg_cache_data *data, struct ecs_data *edns,
if (!data->tree4)
data->tree4 = addrtree_create(
cfg->max_client_subnet_ipv4, &delfunc,
&sizefunc, env, ECS_MAX_TREESIZE);
&sizefunc, env, cfg->max_ecs_tree_size_ipv4);
tree = data->tree4;
} else {
if (!data->tree6)
data->tree6 = addrtree_create(
cfg->max_client_subnet_ipv6, &delfunc,
&sizefunc, env, ECS_MAX_TREESIZE);
&sizefunc, env, cfg->max_ecs_tree_size_ipv6);
tree = data->tree6;
}
return tree;
@@ -323,33 +334,37 @@ update_cache(struct module_qstate *qstate, int id)
/* Step 1, general qinfo lookup */
struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
&qstate->qinfo, 1);
int acquired_lock = (lru_entry != NULL);
int need_to_insert = (lru_entry == NULL);
if (!lru_entry) {
void* data = calloc(1,
sizeof(struct subnet_msg_cache_data));
if(!data) {
log_err("malloc failed");
return;
}
qinf = qstate->qinfo;
qinf.qname = memdup(qstate->qinfo.qname,
qstate->qinfo.qname_len);
if(!qinf.qname) {
free(data);
log_err("memdup failed");
return;
}
mrep_entry = query_info_entrysetup(&qinf, NULL, h);
mrep_entry = query_info_entrysetup(&qinf, data, h);
free(qinf.qname); /* if qname 'consumed', it is set to NULL */
if (!mrep_entry) {
free(data);
log_err("query_info_entrysetup failed");
return;
}
lru_entry = &mrep_entry->entry;
lock_rw_wrlock(&lru_entry->lock);
lru_entry->data = calloc(1,
sizeof(struct subnet_msg_cache_data));
if (!lru_entry->data) {
log_err("malloc failed");
return;
}
}
/* lru_entry->lock is locked regardless of how we got here,
* either from the slabhash_lookup, or above in the new allocated */
/* Step 2, find the correct tree */
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
lock_rw_unlock(&lru_entry->lock);
log_err("Subnet cache insertion failed");
return;
}
@@ -357,7 +372,7 @@ update_cache(struct module_qstate *qstate, int id)
rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
lock_quick_unlock(&sne->alloc.lock);
if (!rep) {
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
lock_rw_unlock(&lru_entry->lock);
log_err("Subnet cache insertion failed");
return;
}
@@ -374,10 +389,9 @@ update_cache(struct module_qstate *qstate, int id)
edns->subnet_source_mask,
sq->ecs_server_in.subnet_scope_mask, rep,
rep->ttl, *qstate->env->now);
if (acquired_lock) {
lock_rw_unlock(&lru_entry->lock);
} else {
lock_rw_unlock(&lru_entry->lock);
lock_rw_unlock(&lru_entry->lock);
if (need_to_insert) {
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
NULL);
}
@@ -464,7 +478,12 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
memset(c_out, 0, sizeof(*c_out));
if (!qstate->return_msg) return module_error;
if (!qstate->return_msg) {
/* already an answer and its not a message, but retain
* the actual rcode, instead of module_error, so send
* module_finished */
return module_finished;
}
/* We have not asked for subnet data */
if (!sq->subnet_sent) {
@@ -482,9 +501,11 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
* is still usefull to put it in the edns subnet cache for
* when a client explicitly asks for subnet specific answer. */
verbose(VERB_QUERY, "subnet: Authority indicates no support");
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
if(!sq->started_no_cache_store) {
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
}
if (sq->subnet_downstream)
cp_edns_bad_response(c_out, c_in);
return module_finished;
@@ -510,7 +531,10 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
}
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
if(!sq->started_no_cache_store) {
update_cache(qstate, id);
}
sne->num_msg_nocache++;
lock_rw_unlock(&sne->biglock);
if (sq->subnet_downstream) {
@@ -520,6 +544,19 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
c_out->subnet_source_mask = c_in->subnet_source_mask;
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
c_out->subnet_scope_mask = s_in->subnet_scope_mask;
/* Limit scope returned to client to scope used for caching. */
if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if(c_out->subnet_scope_mask >
qstate->env->cfg->max_client_subnet_ipv4) {
c_out->subnet_scope_mask =
qstate->env->cfg->max_client_subnet_ipv4;
}
}
else if(c_out->subnet_scope_mask >
qstate->env->cfg->max_client_subnet_ipv6) {
c_out->subnet_scope_mask =
qstate->env->cfg->max_client_subnet_ipv6;
}
c_out->subnet_validdata = 1;
}
return module_finished;
@@ -691,8 +728,20 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
return;
}
/* Limit to minimum allowed source mask */
if(sq->ecs_client_in.subnet_source_mask != 0 && (
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 &&
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv4) ||
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 &&
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv6))) {
qstate->return_rcode = LDNS_RCODE_REFUSED;
qstate->ext_state[id] = module_finished;
return;
}
lock_rw_wrlock(&sne->biglock);
if (lookup_and_reply(qstate, id, sq)) {
sne->num_msg_cache++;
lock_rw_unlock(&sne->biglock);
verbose(VERB_QUERY, "subnet: answered from cache");
qstate->ext_state[id] = module_finished;
@@ -741,10 +790,12 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
/* Query handed back by next module, we have a 'final' answer */
if(sq && event == module_event_moddone) {
qstate->ext_state[id] = eval_response(qstate, id, sq);
if(qstate->ext_state[id] == module_finished) {
if(qstate->ext_state[id] == module_finished &&
qstate->return_msg) {
ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate);
}
qstate->no_cache_store = sq->started_no_cache_store;
return;
}
if(sq && outbound) {
+9
View File
@@ -61,6 +61,10 @@ struct subnet_env {
/** allocation service */
struct alloc_cache alloc;
lock_rw_type biglock;
/** number of messages from cache */
size_t num_msg_cache;
/** number of messages not from cache */
size_t num_msg_nocache;
};
struct subnet_msg_cache_data {
@@ -79,6 +83,8 @@ struct subnet_qstate {
struct ecs_data ecs_server_out;
int subnet_downstream;
int subnet_sent;
/** has the subnet module been started with no_cache_store? */
int started_no_cache_store;
};
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
@@ -127,4 +133,7 @@ int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
int id, void* cbargs);
/** mark subnet msg to be deleted */
void subnet_markdel(void* key);
#endif /* SUBNETMOD_H */
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/sh
# install - install a program, script, or datafile
scriptversion=2013-12-25.23; # UTC
+2
View File
@@ -341,6 +341,8 @@ ipsecmod_handle_query(struct module_qstate* qstate,
qstate->env->cfg->ipsecmod_max_ttl;
qstate->return_msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(
qstate->return_msg->rep->ttl);
qstate->return_msg->rep->serve_expired_ttl = qstate->return_msg->rep->ttl +
qstate->env->cfg->serve_expired_ttl;
}
}
}
Executable
+353
View File
@@ -0,0 +1,353 @@
/**
* \file
* This file implements the ipset module. It can handle packets by putting
* the A and AAAA addresses that are configured in unbound.conf as type
* ipset (local-zone statements) into a firewall rule IPSet. For firewall
* blacklist and whitelist usage.
*/
#include "config.h"
#include "ipset/ipset.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "services/cache/dns.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "sldns/parseutil.h"
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/ipset/ip_set.h>
#define BUFF_LEN 256
/**
* Return an error
* @param qstate: our query state
* @param id: module id
* @param rcode: error code (DNS errcode).
* @return: 0 for use by caller, to make notation easy, like:
* return error_response(..).
*/
static int error_response(struct module_qstate* qstate, int id, int rcode) {
verbose(VERB_QUERY, "return error response %s",
sldns_lookup_by_id(sldns_rcodes, rcode)?
sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??");
qstate->return_rcode = rcode;
qstate->return_msg = NULL;
qstate->ext_state[id] = module_finished;
return 0;
}
static struct mnl_socket * open_mnl_socket() {
struct mnl_socket *mnl;
mnl = mnl_socket_open(NETLINK_NETFILTER);
if (!mnl) {
log_err("ipset: could not open netfilter.");
return NULL;
}
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
mnl_socket_close(mnl);
log_err("ipset: could not bind netfilter.");
return NULL;
}
return mnl;
}
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
struct nlattr *nested[2];
static char buffer[BUFF_LEN];
if (strlen(setname) >= IPSET_MAXNAMELEN) {
errno = ENAMETOOLONG;
return -1;
}
if (af != AF_INET && af != AF_INET6) {
errno = EAFNOSUPPORT;
return -1;
}
nlh = mnl_nlmsg_put_header(buffer);
nlh->nlmsg_type = IPSET_CMD_ADD | (NFNL_SUBSYS_IPSET << 8);
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL;
nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
nfg->nfgen_family = af;
nfg->version = NFNETLINK_V0;
nfg->res_id = htons(0);
mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
mnl_attr_put(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
nested[0] = mnl_attr_nest_start(nlh, IPSET_ATTR_DATA);
nested[1] = mnl_attr_nest_start(nlh, IPSET_ATTR_IP);
mnl_attr_put(nlh, (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6)
| NLA_F_NET_BYTEORDER, (af == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr)), ipaddr);
mnl_attr_nest_end(nlh, nested[1]);
mnl_attr_nest_end(nlh, nested[0]);
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
return -1;
}
return 0;
}
static int ipset_update(struct module_env *env, struct dns_msg *return_msg, struct ipset_env *ie) {
int ret;
struct mnl_socket *mnl;
size_t i, j;
const char *setname;
struct ub_packed_rrset_key *rrset;
struct packed_rrset_data *d;
int af;
static char dname[BUFF_LEN];
const char *s;
int dlen, plen;
struct config_strlist *p;
size_t rr_len, rd_len;
uint8_t *rr_data;
mnl = (struct mnl_socket *)ie->mnl;
if (!mnl) {
// retry to create mnl socket
mnl = open_mnl_socket();
if (!mnl) {
return -1;
}
ie->mnl = mnl;
}
for (i = 0; i < return_msg->rep->rrset_count; ++i) {
setname = NULL;
rrset = return_msg->rep->rrsets[i];
if (rrset->rk.type == htons(LDNS_RR_TYPE_A)) {
af = AF_INET;
if ((ie->v4_enabled == 1)) {
setname = ie->name_v4;
}
} else {
af = AF_INET6;
if ((ie->v6_enabled == 1)) {
setname = ie->name_v6;
}
}
if (setname) {
dlen = sldns_wire2str_dname_buf(rrset->rk.dname, rrset->rk.dname_len, dname, BUFF_LEN);
if (dlen == 0) {
log_err("bad domain name");
return -1;
}
if (dname[dlen - 1] == '.') {
dlen--;
}
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
plen = strlen(p->str);
if (dlen >= plen) {
s = dname + (dlen - plen);
if (strncasecmp(p->str, s, plen) == 0) {
d = (struct packed_rrset_data*)rrset->entry.data;
/* to d->count, not d->rrsig_count, because we do not want to add the RRSIGs, only the addresses */
for (j = 0; j < d->count; j++) {
rr_len = d->rr_len[j];
rr_data = d->rr_data[j];
rd_len = sldns_read_uint16(rr_data);
if (rr_len - 2 >= rd_len) {
ret = add_to_ipset(mnl, 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;
break;
}
}
}
break;
}
}
}
}
}
return 0;
}
int ipset_init(struct module_env* env, int id) {
struct ipset_env *ipset_env;
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
if (!ipset_env) {
log_err("malloc failure");
return 0;
}
env->modinfo[id] = (void *)ipset_env;
ipset_env->mnl = NULL;
ipset_env->name_v4 = env->cfg->ipset_name_v4;
ipset_env->name_v6 = env->cfg->ipset_name_v6;
ipset_env->v4_enabled = !ipset_env->name_v4 || (strlen(ipset_env->name_v4) == 0) ? 0 : 1;
ipset_env->v6_enabled = !ipset_env->name_v6 || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;
if ((ipset_env->v4_enabled < 1) && (ipset_env->v6_enabled < 1)) {
log_err("ipset: set name no configuration?");
return 0;
}
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;
}
static int ipset_new(struct module_qstate* qstate, int id) {
struct ipset_qstate *iq = (struct ipset_qstate *)regional_alloc(
qstate->region, sizeof(struct ipset_qstate));
qstate->minfo[id] = iq;
if (!iq) {
return 0;
}
memset(iq, 0, sizeof(*iq));
/* initialise it */
/* TODO */
return 1;
}
void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
struct outbound_entry *outbound) {
struct ipset_env *ie = (struct ipset_env *)qstate->env->modinfo[id];
struct ipset_qstate *iq = (struct ipset_qstate *)qstate->minfo[id];
verbose(VERB_QUERY, "ipset[module %d] operate: extstate:%s event:%s",
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
if (iq) {
log_query_info(VERB_QUERY, "ipset operate: query", &qstate->qinfo);
}
/* perform ipset state machine */
if ((event == module_event_new || event == module_event_pass) && !iq) {
if (!ipset_new(qstate, id)) {
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
}
iq = (struct ipset_qstate*)qstate->minfo[id];
}
if (iq && (event == module_event_pass || event == module_event_new)) {
qstate->ext_state[id] = module_wait_module;
return;
}
if (iq && (event == module_event_moddone)) {
if (qstate->return_msg && qstate->return_msg->rep) {
ipset_update(qstate->env, qstate->return_msg, ie);
}
qstate->ext_state[id] = module_finished;
return;
}
if (iq && outbound) {
/* ipset does not need to process responses at this time
* ignore it.
ipset_process_response(qstate, iq, ie, id, outbound, event);
*/
return;
}
if (event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
}
if (!iq && (event == module_event_moddone)) {
/* during priming, module done but we never started */
qstate->ext_state[id] = module_finished;
return;
}
log_err("bad event for ipset");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
void ipset_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) {
/* ipset does not use subordinate requests at this time */
verbose(VERB_ALGO, "ipset inform_super was called");
}
void ipset_clear(struct module_qstate *qstate, int id) {
struct cachedb_qstate *iq;
if (!qstate) {
return;
}
iq = (struct cachedb_qstate *)qstate->minfo[id];
if (iq) {
/* free contents of iq */
/* TODO */
}
qstate->minfo[id] = NULL;
}
size_t ipset_get_mem(struct module_env *env, int id) {
struct ipset_env *ie = (struct ipset_env *)env->modinfo[id];
if (!ie) {
return 0;
}
return sizeof(*ie);
}
/**
* The ipset function block
*/
static struct module_func_block ipset_block = {
"ipset",
&ipset_init, &ipset_deinit, &ipset_operate,
&ipset_inform_super, &ipset_clear, &ipset_get_mem
};
struct module_func_block * ipset_get_funcblock(void) {
return &ipset_block;
}
Executable
+79
View File
@@ -0,0 +1,79 @@
/**
* ipset.h
*
* Author: Kevin Chou
* Email: k9982874@gmail.com
*/
#ifndef IPSET_H
#define IPSET_H
/** \file
*
* This file implements the ipset module. It can handle packets by putting
* the A and AAAA addresses that are configured in unbound.conf as type
* ipset (local-zone statements) into a firewall rule IPSet. For firewall
* blacklist and whitelist usage.
*
* To use the IPset module, install the libmnl-dev (or libmnl-devel) package
* and configure with --enable-ipset. And compile. Then enable the ipset
* module in unbound.conf with module-config: "ipset validator iterator"
* then create it with ipset -N blacklist iphash and then add
* local-zone: "example.com." ipset
* statements for the zones where you want the addresses of the names
* looked up added to the set.
*
* Set the name of the set with
* ipset:
* name-v4: "blacklist"
* name-v6: "blacklist6"
* in unbound.conf. The set can be used in this way:
* iptables -A INPUT -m set --set blacklist src -j DROP
* ip6tables -A INPUT -m set --set blacklist6 src -j DROP
*/
#include "util/module.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ipset_env {
void* mnl;
int v4_enabled;
int v6_enabled;
const char *name_v4;
const char *name_v6;
};
struct ipset_qstate {
int dummy;
};
/** Init the ipset module */
int ipset_init(struct module_env* env, int id);
/** Deinit the ipset module */
void ipset_deinit(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */
void ipset_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** Subordinate query done, inform this super request of its conclusion */
void ipset_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** clear the ipset query-specific contents out of qstate */
void ipset_clear(struct module_qstate* qstate, int id);
/** return memory estimate for ipset module */
size_t ipset_get_mem(struct module_env* env, int id);
/**
* Get the function block with pointers to the ipset functions
* @return the function block for "ipset".
*/
struct module_func_block* ipset_get_funcblock(void);
#ifdef __cplusplus
}
#endif
#endif /* IPSET_H */
+2
View File
@@ -85,6 +85,8 @@ struct delegpt {
uint8_t ssl_upstream;
/** delegpt from authoritative zone that is locally hosted */
uint8_t auth_dp;
/*** no cache */
int no_cache;
};
/**
+7
View File
@@ -239,6 +239,11 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
s->name, p->str);
return 0;
}
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(tls_auth_name)
log_err("no name verification functionality in "
"ssl library, ignored name for %s", p->str);
#endif
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
tls_auth_name)) {
log_err("out of memory");
@@ -267,6 +272,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
* last resort will ask for parent-side NS record and thus
* fallback to the internet name servers on a failure */
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
/* Do not cache if set. */
dp->no_cache = s->no_cache;
/* use SSL for queries to this forwarder */
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
verbose(VERB_QUERY, "Forward zone server list:");
+7
View File
@@ -252,6 +252,11 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
s->name, p->str);
return 0;
}
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(auth_name)
log_err("no name verification functionality in "
"ssl library, ignored name for %s", p->str);
#endif
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
auth_name)) {
log_err("out of memory");
@@ -278,6 +283,8 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
* last resort will ask for parent-side NS record and thus
* fallback to the internet name servers on a failure */
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
/* Do not cache if set. */
dp->no_cache = s->no_cache;
/* ssl_upstream */
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
delegpt_log(VERB_QUERY, dp);
+28 -13
View File
@@ -316,6 +316,18 @@ sub_of_pkt(sldns_buffer* pkt, uint8_t* zone, uint8_t* comprname)
return dname_subdomain_c(zone, buf);
}
/** Check if there are SOA records in the authority section (negative) */
static int
soa_in_auth(struct msg_parse* msg)
{
struct rrset_parse* rrset;
for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
if(rrset->type == LDNS_RR_TYPE_SOA &&
rrset->section == LDNS_SECTION_AUTHORITY)
return 1;
return 0;
}
/**
* This routine normalizes a response. This includes removing "irrelevant"
* records from the answer and additional sections and (re)synthesizing
@@ -437,7 +449,9 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
rrset->rrset_all_next =
nx->rrset_all_next;
nx->rrset_all_next = rrset;
prev = nx;
/* prev = nx; unused, enable if there
* is other rrset removal code after
* this */
}
}
@@ -495,6 +509,19 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
/* we don't want NS sets for NXDOMAIN answers,
* because they could contain poisonous contents,
* from. eg. fragmentation attacks, inserted after
* long RRSIGs in the packet get to the packet
* border and such */
/* also for NODATA answers */
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN ||
(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR
&& soa_in_auth(msg) && msg->an_rrsets == 0)) {
remove_rrset("normalize: removing irrelevant "
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(nsset == NULL) {
nsset = rrset;
} else {
@@ -593,18 +620,6 @@ store_rrset(sldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, now);
}
/** Check if there are SOA records in the authority section (negative) */
static int
soa_in_auth(struct msg_parse* msg)
{
struct rrset_parse* rrset;
for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
if(rrset->type == LDNS_RR_TYPE_SOA &&
rrset->section == LDNS_SECTION_AUTHORITY)
return 1;
return 0;
}
/**
* Check if right hand name in NSEC is within zone
* @param rrset: the NSEC rrset
+208 -14
View File
@@ -282,10 +282,13 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
static int
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist,
size_t* num_suitable_results)
{
int got_it = 0;
struct delegpt_addr* a;
*num_suitable_results = 0;
if(dp->bogus)
return 0; /* NS bogus, all bogus, nothing found */
for(a=dp->result_list; a; a = a->next_result) {
@@ -301,11 +304,58 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
} else if(a->sel_rtt < *best_rtt) {
*best_rtt = a->sel_rtt;
}
(*num_suitable_results)++;
}
}
return got_it;
}
/** compare two rtts, return -1, 0 or 1 */
static int
rtt_compare(const void* x, const void* y)
{
if(*(int*)x == *(int*)y)
return 0;
if(*(int*)x > *(int*)y)
return 1;
return -1;
}
/** get RTT for the Nth fastest server */
static int
nth_rtt(struct delegpt_addr* result_list, size_t num_results, size_t n)
{
int rtt_band;
size_t i;
int* rtt_list, *rtt_index;
if(num_results < 1 || n >= num_results) {
return -1;
}
rtt_list = calloc(num_results, sizeof(int));
if(!rtt_list) {
log_err("malloc failure: allocating rtt_list");
return -1;
}
rtt_index = rtt_list;
for(i=0; i<num_results && result_list; i++) {
if(result_list->sel_rtt != -1) {
*rtt_index = result_list->sel_rtt;
rtt_index++;
}
result_list=result_list->next_result;
}
qsort(rtt_list, num_results, sizeof(*rtt_list), rtt_compare);
log_assert(n > 0);
rtt_band = rtt_list[n-1];
free(rtt_list);
return rtt_band;
}
/** filter the address list, putting best targets at front,
* returns number of best targets (or 0, no suitable targets) */
static int
@@ -314,12 +364,13 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
struct delegpt* dp, int* selected_rtt, int open_target,
struct sock_list* blacklist, time_t prefetch)
{
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND, nth;
size_t num_results;
struct delegpt_addr* a, *n, *prev=NULL;
/* fillup sel_rtt and find best rtt in the bunch */
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
&low_rtt, blacklist);
&low_rtt, blacklist, &num_results);
if(got_num == 0)
return 0;
if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
@@ -329,14 +380,19 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
return 0 to force the caller to fetch more */
}
if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
low_rtt < env->cfg->low_rtt &&
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
if(env->cfg->fast_server_permil != 0 && prefetch == 0 &&
num_results > env->cfg->fast_server_num &&
ub_random_max(env->rnd, 1000) < env->cfg->fast_server_permil) {
/* the query is not prefetch, but for a downstream client,
* there is a low_rtt (fast) server. We choose that x% of the
* time */
/* pick rtt numbers from 0..LOWBAND_RTT */
rtt_band = env->cfg->low_rtt - low_rtt;
* there are more servers available then the fastest N we want
* to choose from. Limit our choice to the fastest servers. */
nth = nth_rtt(dp->result_list, num_results,
env->cfg->fast_server_num);
if(nth > 0) {
rtt_band = nth - low_rtt;
if(rtt_band > RTT_BAND)
rtt_band = RTT_BAND;
}
}
got_num = 0;
@@ -375,11 +431,34 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
int got_num6 = 0;
int low_rtt6 = 0;
int i;
int attempt = -1; /* filter to make sure addresses have
less attempts on them than the first, to force round
robin when all the IPv6 addresses fail */
int num4ok = 0; /* number ip4 at low attempt count */
int num4_lowrtt = 0;
prev = NULL;
a = dp->result_list;
for(i = 0; i < got_num; i++) {
swap_to_front = 0;
if(a->addr.ss_family != AF_INET6 && attempt == -1) {
/* if we only have ip4 at low attempt count,
* then ip6 is failing, and we need to
* select one of the remaining IPv4 addrs */
attempt = a->attempts;
num4ok++;
num4_lowrtt = a->sel_rtt;
} else if(a->addr.ss_family != AF_INET6 && attempt == a->attempts) {
num4ok++;
if(num4_lowrtt == 0 || a->sel_rtt < num4_lowrtt) {
num4_lowrtt = a->sel_rtt;
}
}
if(a->addr.ss_family == AF_INET6) {
if(attempt == -1) {
attempt = a->attempts;
} else if(a->attempts > attempt) {
break;
}
got_num6++;
swap_to_front = 1;
if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) {
@@ -401,6 +480,9 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
if(got_num6 > 0) {
got_num = got_num6;
*selected_rtt = low_rtt6;
} else if(num4ok > 0) {
got_num = num4ok;
*selected_rtt = num4_lowrtt;
}
}
return got_num;
@@ -800,10 +882,35 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
return 1;
}
/** compare rrsets and sort canonically. Compares rrset name, type, class.
* return 0 if equal, +1 if x > y, and -1 if x < y.
*/
static int
rrset_canonical_sort_cmp(const void* x, const void* y)
{
struct ub_packed_rrset_key* rrx = *(struct ub_packed_rrset_key**)x;
struct ub_packed_rrset_key* rry = *(struct ub_packed_rrset_key**)y;
int r = dname_canonical_compare(rrx->rk.dname, rry->rk.dname);
if(r != 0)
return r;
if(rrx->rk.type != rry->rk.type) {
if(ntohs(rrx->rk.type) > ntohs(rry->rk.type))
return 1;
else return -1;
}
if(rrx->rk.rrset_class != rry->rk.rrset_class) {
if(ntohs(rrx->rk.rrset_class) > ntohs(rry->rk.rrset_class))
return 1;
else return -1;
}
return 0;
}
int
reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
{
size_t i;
struct ub_packed_rrset_key** sorted_p, **sorted_q;
if(p->flags != q->flags ||
p->qdcount != q->qdcount ||
/* do not check TTL, this may differ */
@@ -817,16 +924,43 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
p->ar_numrrsets != q->ar_numrrsets ||
p->rrset_count != q->rrset_count)
return 0;
/* sort the rrsets in the authority and additional sections before
* compare, the query and answer sections are ordered in the sequence
* they should have (eg. one after the other for aliases). */
sorted_p = (struct ub_packed_rrset_key**)regional_alloc_init(
region, p->rrsets, sizeof(*sorted_p)*p->rrset_count);
if(!sorted_p) return 0;
log_assert(p->an_numrrsets + p->ns_numrrsets + p->ar_numrrsets <=
p->rrset_count);
qsort(sorted_p + p->an_numrrsets, p->ns_numrrsets,
sizeof(*sorted_p), rrset_canonical_sort_cmp);
qsort(sorted_p + p->an_numrrsets + p->ns_numrrsets, p->ar_numrrsets,
sizeof(*sorted_p), rrset_canonical_sort_cmp);
sorted_q = (struct ub_packed_rrset_key**)regional_alloc_init(
region, q->rrsets, sizeof(*sorted_q)*q->rrset_count);
if(!sorted_q) {
regional_free_all(region);
return 0;
}
log_assert(q->an_numrrsets + q->ns_numrrsets + q->ar_numrrsets <=
q->rrset_count);
qsort(sorted_q + q->an_numrrsets, q->ns_numrrsets,
sizeof(*sorted_q), rrset_canonical_sort_cmp);
qsort(sorted_q + q->an_numrrsets + q->ns_numrrsets, q->ar_numrrsets,
sizeof(*sorted_q), rrset_canonical_sort_cmp);
/* compare the rrsets */
for(i=0; i<p->rrset_count; i++) {
if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
if(!rrset_canonical_equal(region, p->rrsets[i],
q->rrsets[i])) {
if(!rrset_equal(sorted_p[i], sorted_q[i])) {
if(!rrset_canonical_equal(region, sorted_p[i],
sorted_q[i])) {
regional_free_all(region);
return 0;
}
regional_free_all(region);
}
}
regional_free_all(region);
return 1;
}
@@ -1077,6 +1211,19 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z)
}
}
void
iter_scrub_nxdomain(struct dns_msg* msg)
{
if(msg->rep->an_numrrsets == 0)
return;
memmove(msg->rep->rrsets, msg->rep->rrsets+msg->rep->an_numrrsets,
sizeof(struct ub_packed_rrset_key*) *
(msg->rep->rrset_count-msg->rep->an_numrrsets));
msg->rep->rrset_count -= msg->rep->an_numrrsets;
msg->rep->an_numrrsets = 0;
}
void iter_dec_attempts(struct delegpt* dp, int d)
{
struct delegpt_addr* a;
@@ -1184,3 +1331,50 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp)
return 0;
return 1;
}
int
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
{
struct iter_hints_stub *stub;
struct delegpt *dp;
/* Check for stub. */
stub = hints_lookup_stub(qstate->env->hints, qinf->qname,
qinf->qclass, NULL);
dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass);
/* see if forward or stub is more pertinent */
if(stub && stub->dp && dp) {
if(dname_strict_subdomain(dp->name, dp->namelabs,
stub->dp->name, stub->dp->namelabs)) {
stub = NULL; /* ignore stub, forward is lower */
} else {
dp = NULL; /* ignore forward, stub is lower */
}
}
/* check stub */
if (stub != NULL && stub->dp != NULL) {
if(stub->dp->no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
dname_str(stub->dp->name, dpname);
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
}
return (stub->dp->no_cache);
}
/* Check for forward. */
if (dp) {
if(dp->no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
dname_str(dp->name, dpname);
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
}
return (dp->no_cache);
}
return 0;
}
+16
View File
@@ -334,6 +334,13 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
uint8_t* z);
/**
* Prepare an NXDOMAIN message to be used for a subdomain answer by removing all
* RRs from the ANSWER section.
* @param msg: the response to scrub.
*/
void iter_scrub_nxdomain(struct dns_msg* msg);
/**
* Remove query attempts from all available ips. For 0x20.
* @param dp: delegpt.
@@ -369,4 +376,13 @@ int iter_ds_toolow(struct dns_msg* msg, struct delegpt* dp);
*/
int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
/**
* Lookup if no_cache is set in stub or fwd.
* @param qstate: query state with env with hints and fwds.
* @param qinf: query name to lookup for.
* @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);
#endif /* ITERATOR_ITER_UTILS_H */
+233 -35
View File
@@ -69,6 +69,9 @@
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
int
iter_init(struct module_env* env, int id)
{
@@ -230,11 +233,12 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
qstate->qinfo.qname, qstate->qinfo.qname_len);
if(!dpns) {
/* not interested */
/* this can happen, for eg. qname minimisation asked
* for an NXDOMAIN to be validated, and used qtype
* A for that, and the error of that, the name, is
* not listed in super_iq->dp */
verbose(VERB_ALGO, "subq error, but not interested");
log_query_info(VERB_ALGO, "superq", &super->qinfo);
if(super_iq->dp)
delegpt_log(VERB_ALGO, super_iq->dp);
log_assert(0);
return;
} else {
/* see if the failure did get (parent-lame) info */
@@ -303,14 +307,49 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
if((msg=msg_cache_lookup(qstate->env,
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
qstate->query_flags, 0, 0))
qstate->query_flags, 0,
qstate->env->cfg->serve_expired_ttl_reset))
!= NULL) {
if(qstate->env->cfg->serve_expired_ttl_reset) {
struct reply_info* rep =
(struct reply_info*)msg->entry.data;
if(rep && *qstate->env->now +
qstate->env->cfg->serve_expired_ttl >
rep->serve_expired_ttl) {
rep->serve_expired_ttl =
*qstate->env->now +
qstate->env->cfg->serve_expired_ttl;
}
}
lock_rw_unlock(&msg->entry.lock);
return error_response(qstate, id, rcode);
}
/* serving expired contents, but nothing is cached
* at all, so the servfail cache entry is useful
* (stops waste of time on this servfail NORR_TTL) */
} else {
/* don't overwrite existing (non-expired) data in
* cache with a servfail */
struct msgreply_entry* msg;
if((msg=msg_cache_lookup(qstate->env,
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
qstate->query_flags, *qstate->env->now, 0))
!= NULL) {
struct reply_info* rep = (struct reply_info*)
msg->entry.data;
if(FLAGS_GET_RCODE(rep->flags) ==
LDNS_RCODE_NOERROR ||
FLAGS_GET_RCODE(rep->flags) ==
LDNS_RCODE_NXDOMAIN) {
/* we have a good entry,
* don't overwrite */
lock_rw_unlock(&msg->entry.lock);
return error_response(qstate, id, rcode);
}
lock_rw_unlock(&msg->entry.lock);
}
}
memset(&err, 0, sizeof(err));
err.flags = (uint16_t)(BIT_QR | BIT_RA);
@@ -318,6 +357,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
err.qdcount = 1;
err.ttl = NORR_TTL;
err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
err.serve_expired_ttl = NORR_TTL;
/* do not waste time trying to validate this servfail */
err.security = sec_status_indeterminate;
verbose(VERB_ALGO, "store error response in message cache");
@@ -536,7 +576,7 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
/** see if last resort is possible - does config allow queries to parent */
static int
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
uint16_t qclass)
uint16_t qclass, struct delegpt** retdp)
{
struct delegpt* fwddp;
struct iter_hints_stub* stub;
@@ -549,12 +589,14 @@ can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
/* has_parent side is turned off for stub_first, where we
* are allowed to go to the parent */
stub->dp->has_parent_side_NS) {
if(retdp) *retdp = stub->dp;
return 0;
}
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
/* has_parent_side is turned off for forward_first, where
* we are allowed to go to the parent */
fwddp->has_parent_side_NS) {
if(retdp) *retdp = fwddp;
return 0;
}
return 1;
@@ -787,6 +829,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
iq->dp = delegpt_copy(stub_dp, qstate->region);
if(!iq->dp) {
log_err("out of memory priming stub");
errinf(qstate, "malloc failure, priming stub");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return 1; /* return 1 to make module stop, with error */
}
@@ -805,6 +848,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
verbose(VERB_ALGO, "could not prime stub");
errinf(qstate, "could not generate lookup for stub prime");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return 1; /* return 1 to make module stop, with error */
}
@@ -820,6 +864,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
fptr_ok(fptr_whitelist_modenv_kill_sub(
qstate->env->kill_sub));
(*qstate->env->kill_sub)(subq);
errinf(qstate, "malloc failure, in stub prime");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return 1; /* return 1 to make module stop, with error */
}
@@ -903,6 +948,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
return 1; /* just fallback */
}
lock_rw_unlock(&z->lock);
errinf(qstate, "malloc failure");
return 0;
}
dp->name = regional_alloc_init(qstate->region,
@@ -914,6 +960,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
return 1; /* just fallback */
}
lock_rw_unlock(&z->lock);
errinf(qstate, "malloc failure");
return 0;
}
dp->namelen = z->namelen;
@@ -1000,7 +1047,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
if(iq->depth == ie->max_dependency_depth)
return;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass))
iq->qchase.qclass, NULL))
return;
/* is this query the same as the nscheck? */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
@@ -1104,7 +1151,7 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
struct delegpt* dp;
uint8_t* delname = iq->qchase.qname;
size_t delnamelen = iq->qchase.qname_len;
if(iq->refetch_glue) {
if(iq->refetch_glue && iq->dp) {
delname = iq->dp->name;
delnamelen = iq->dp->namelen;
}
@@ -1157,6 +1204,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->query_restart_count > MAX_RESTART_COUNT) {
verbose(VERB_QUERY, "request has exceeded the maximum number"
" of query restarts with %d", iq->query_restart_count);
errinf(qstate, "request has exceeded the maximum number "
"restarts (eg. indirections)");
if(iq->qchase.qname)
errinf_dname(qstate, "stop at", iq->qchase.qname);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -1168,6 +1219,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->depth > ie->max_dependency_depth) {
verbose(VERB_QUERY, "request has exceeded the maximum "
"dependency depth with depth of %d", iq->depth);
errinf(qstate, "request has exceeded the maximum dependency "
"depth (eg. nameserver lookup recursion)");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -1184,10 +1237,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
*/
if (iq->refetch_glue &&
iq->dp &&
!can_have_last_resort(qstate->env,
iq->dp->name,
iq->dp->namelen,
iq->qchase.qclass)) {
!can_have_last_resort(qstate->env, iq->dp->name,
iq->dp->namelen, iq->qchase.qclass, NULL)) {
iq->refetch_glue = 0;
}
@@ -1196,7 +1247,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* This either results in a query restart (CNAME cache response), a
* terminating response (ANSWER), or a cache miss (null). */
if(qstate->blacklist) {
if (iter_stub_fwd_no_cache(qstate, &iq->qchase)) {
/* Asked to not query cache. */
verbose(VERB_ALGO, "no-cache set, going to the network");
qstate->no_cache_lookup = 1;
qstate->no_cache_store = 1;
msg = NULL;
} else if(qstate->blacklist) {
/* if cache, or anything else, was blacklisted then
* getting older results from cache is a bad idea, no cache */
verbose(VERB_ALGO, "cache blacklisted, going to the network");
@@ -1240,9 +1297,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_ALGO, "returning CNAME response from "
"cache");
if(!handle_cname_response(qstate, iq, msg,
&sname, &slen))
&sname, &slen)) {
errinf(qstate, "failed to prepend CNAME "
"components, malloc failure");
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
iq->qchase.qname = sname;
iq->qchase.qname_len = slen;
/* This *is* a query restart, even if it is a cheap
@@ -1260,6 +1320,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* if from cache, NULL, else insert 'cache IP' len=0 */
if(qstate->reply_origin)
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_SERVFAIL)
errinf(qstate, "SERVFAIL in cache");
/* it is an answer, response, to final state */
verbose(VERB_ALGO, "returning answer from cache.");
iq->response = msg;
@@ -1271,6 +1333,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
{
if(!iq->dp) {
log_err("alloc failure for forward dp");
errinf(qstate, "malloc failure for forward zone");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->refetch_glue = 0;
@@ -1290,6 +1353,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->refetch_glue) {
if(!iq->dp) {
log_err("internal or malloc fail: no dp for refetch");
errinf(qstate, "malloc failure, for delegation info");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
delname = iq->dp->name;
@@ -1300,7 +1364,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass))) {
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) {
/* remove first label from delname, root goes to hints,
* but only to fetch glue, not for qtype=DS. */
/* also when prefetching an NS record, fetch it again from
@@ -1349,12 +1413,14 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qchase.qclass);
if(!iq->dp) {
log_err("internal error: no hints dp");
errinf(qstate, "no hints for this class");
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
iq->dp = delegpt_copy(iq->dp, qstate->region);
if(!iq->dp) {
log_err("out of memory in safety belt");
errinf(qstate, "malloc failure, in safety belt");
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
@@ -1382,7 +1448,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* now will also exceed the rate, keeping cache fresh */
(void)infra_ratelimit_inc(qstate->env->infra_cache,
iq->dp->name, iq->dp->namelen,
*qstate->env->now);
*qstate->env->now, &qstate->qinfo,
qstate->reply);
/* see if we are passed through with slip factor */
if(qstate->env->cfg->ratelimit_factor != 0 &&
ub_random_max(qstate->env->rnd,
@@ -1398,6 +1465,9 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
log_nametypeclass(VERB_ALGO, "ratelimit exceeded with "
"delegation point", iq->dp->name,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
qstate->was_ratelimited = 1;
errinf(qstate, "query was ratelimited");
errinf_dname(qstate, "for zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
@@ -1416,9 +1486,29 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
*/
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
iq->dp)) {
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass)) {
struct delegpt* retdp = NULL;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
if(retdp) {
verbose(VERB_QUERY, "cache has stub "
"or fwd but no addresses, "
"fallback to config");
iq->dp = delegpt_copy(retdp,
qstate->region);
if(!iq->dp) {
log_err("out of memory in "
"stub/fwd fallback");
errinf(qstate, "malloc failure, for fallback to config");
return error_response(qstate,
id, LDNS_RCODE_SERVFAIL);
}
break;
}
verbose(VERB_ALGO, "useless dp "
"but cannot go up, servfail");
delegpt_log(VERB_ALGO, iq->dp);
errinf(qstate, "no useful nameservers, "
"and cannot go up");
errinf_dname(qstate, "for zone", iq->dp->name);
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
@@ -1438,6 +1528,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp = delegpt_copy(iq->dp, qstate->region);
if(!iq->dp) {
log_err("out of memory in safety belt");
errinf(qstate, "malloc failure, in safety belt, for root");
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
@@ -1492,6 +1583,7 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_hints_stub* stub;
if(!iq->dp) {
log_err("internal or malloc fail: no dp for refetch");
errinf(qstate, "malloc failure, no delegation info");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Do not send queries above stub, do not set delname to dp if
@@ -1779,9 +1871,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
log_assert(iq->dp);
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
iq->qchase.qclass)) {
iq->qchase.qclass, NULL)) {
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
errinf(qstate, "all the configured stub or forward servers failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -1789,7 +1883,6 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
struct delegpt* p = hints_lookup_root(qstate->env->hints,
iq->qchase.qclass);
if(p) {
struct delegpt_ns* ns;
struct delegpt_addr* a;
iq->chase_flags &= ~BIT_RD; /* go to authorities */
for(ns = p->nslist; ns; ns=ns->next) {
@@ -1841,6 +1934,8 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
int qs = 0;
verbose(VERB_ALGO, "try parent-side target name");
if(!query_for_targets(qstate, iq, ie, id, 1, &qs)) {
errinf(qstate, "could not fetch nameserver");
errinf_dname(qstate, "at zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += qs;
@@ -1852,6 +1947,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(iq->depth == ie->max_dependency_depth) {
verbose(VERB_QUERY, "maxdepth and need more nameservers, fail");
errinf(qstate, "cannot fetch more nameservers because at max dependency depth");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->depth > 0 && iq->target_count &&
@@ -1860,6 +1956,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d", s, iq->target_count[1]);
errinf(qstate, "exceeded the maximum number of glue fetches");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* mark cycle targets for parent-side lookups */
@@ -1872,7 +1969,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
(ie->supports_ipv4 && !ns->done_pside4)) &&
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
iq->qchase.qclass)) {
iq->qchase.qclass, NULL)) {
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
"because it is also a stub/forward,",
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
@@ -1885,9 +1982,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
/* Send the AAAA request. */
if(!generate_parentside_target_query(qstate, iq, id,
ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, iq->qchase.qclass))
LDNS_RR_TYPE_AAAA, iq->qchase.qclass)) {
errinf_dname(qstate, "could not generate nameserver AAAA lookup for", ns->name);
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
ns->done_pside6 = 1;
query_count++;
}
@@ -1895,9 +1994,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
/* Send the A request. */
if(!generate_parentside_target_query(qstate, iq, id,
ns->name, ns->namelen,
LDNS_RR_TYPE_A, iq->qchase.qclass))
LDNS_RR_TYPE_A, iq->qchase.qclass)) {
errinf_dname(qstate, "could not generate nameserver A lookup for", ns->name);
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
ns->done_pside4 = 1;
query_count++;
}
@@ -1918,6 +2019,8 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
iq->deleg_msg?iq->deleg_msg->rep:
(iq->response?iq->response->rep:NULL));
errinf(qstate, "all servers for this domain failed,");
errinf_dname(qstate, "at zone", iq->dp->name);
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
/* fail -- no more targets, no more hope of targets, no hope
* of a response. */
@@ -1951,6 +2054,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
}
/* robustcheck for internal error: we are not underneath the dp */
if(!dname_subdomain_c(iq->dsns_point, iq->dp->name)) {
errinf_dname(qstate, "for DS query parent-child nameserver search the query is not under the zone", iq->dp->name);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -1971,6 +2075,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len,
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -2001,6 +2106,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
struct delegpt_addr* target;
struct outbound_entry* outq;
int auth_fallback = 0;
uint8_t* qout_orig = NULL;
size_t qout_orig_len = 0;
/* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral,
@@ -2016,11 +2123,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->referral_count > MAX_REFERRAL_COUNT) {
verbose(VERB_QUERY, "request has exceeded the maximum "
"number of referrrals with %d", iq->referral_count);
errinf(qstate, "exceeded the maximum of referrals");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->sent_count > MAX_SENT_COUNT) {
verbose(VERB_QUERY, "request has exceeded the maximum "
"number of sends with %d", iq->sent_count);
errinf(qstate, "exceeded the maximum number of sends");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -2028,6 +2137,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* or another failure occurred */
if(!iq->dp) {
verbose(VERB_QUERY, "Failed to get a delegation, giving up");
errinf(qstate, "failed to get a delegation (eg. prime failure)");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!ie->supports_ipv6)
@@ -2045,7 +2155,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
if(iq->minimisation_state == INIT_MINIMISE_STATE) {
if(iq->minimisation_state == INIT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
/* (Re)set qinfo_out to (new) delegation point, except when
* qinfo_out is already a subdomain of dp. This happens when
* increasing by more than one label at once (QNAMEs with more
@@ -2070,6 +2181,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int labdiff = qchaselabs -
dname_count_labels(iq->qinfo_out.qname);
qout_orig = iq->qinfo_out.qname;
qout_orig_len = iq->qinfo_out.qname_len;
iq->qinfo_out.qname = iq->qchase.qname;
iq->qinfo_out.qname_len = iq->qchase.qname_len;
iq->minimise_count++;
@@ -2187,9 +2300,10 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* no internet fallback */
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
" servfail");
errinf(qstate, "auth zone lookup failed, fallback is off");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->dp && iq->dp->auth_dp) {
if(iq->dp->auth_dp) {
/* we wanted to fallback, but had no delegpt, only the
* auth zone generated delegpt, create an actual one */
iq->auth_zone_avoid = 1;
@@ -2212,6 +2326,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int extra = 0;
size_t naddr, nres, navail;
if(!query_for_targets(qstate, iq, ie, id, -1, &extra)) {
errinf(qstate, "could not fetch nameservers for 0x20 fallback");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->num_target_queries += extra;
@@ -2220,6 +2335,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* wait to get all targets, we want to try em */
verbose(VERB_ALGO, "wait for all targets for fallback");
qstate->ext_state[id] = module_wait_reply;
/* undo qname minimise step because we'll get back here
* to do it again */
if(qout_orig && iq->minimise_count > 0) {
iq->minimise_count--;
iq->qinfo_out.qname = qout_orig;
iq->qinfo_out.qname_len = qout_orig_len;
}
return 0;
}
/* did we do enough fallback queries already? */
@@ -2292,6 +2414,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
"missing target");
if(!query_for_targets(qstate, iq, ie, id,
1, &qs)) {
errinf(qstate, "could not fetch nameserver");
errinf_dname(qstate, "at zone", iq->dp->name);
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
@@ -2351,17 +2475,28 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_current_queries);
qstate->ext_state[id] = module_wait_reply;
}
/* undo qname minimise step because we'll get back here
* to do it again */
if(qout_orig && iq->minimise_count > 0) {
iq->minimise_count--;
iq->qinfo_out.qname = qout_orig;
iq->qinfo_out.qname_len = qout_orig_len;
}
return 0;
}
/* if not forwarding, check ratelimits per delegationpoint name */
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now)) {
iq->dp->namelen, *qstate->env->now, &qstate->qinfo,
qstate->reply)) {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
verbose(VERB_ALGO, "query exceeded ratelimits");
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
@@ -2526,6 +2661,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* DNAME to a subdomain loop; do not recurse */
type = RESPONSE_TYPE_ANSWER;
}
} else if(type == RESPONSE_TYPE_CNAME &&
iq->qchase.qtype == LDNS_RR_TYPE_CNAME &&
iq->minimisation_state == MINIMISE_STATE &&
query_dname_compare(iq->qchase.qname, iq->qinfo_out.qname) == 0) {
/* The minimised query for full QTYPE and hidden QTYPE can be
* classified as CNAME response type, even when the original
* QTYPE=CNAME. This should be treated as answer response type.
*/
type = RESPONSE_TYPE_ANSWER;
}
/* handle each of the type cases */
@@ -2570,11 +2714,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
if(iq->minimisation_state != DONOT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
LDNS_RCODE_NOERROR) {
if(qstate->env->cfg->qname_minimisation_strict)
return final_state(iq);
if(qstate->env->cfg->qname_minimisation_strict) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
LDNS_RCODE_NXDOMAIN) {
iter_scrub_nxdomain(iq->response);
return final_state(iq);
}
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
/* Best effort qname-minimisation.
* Stop minimising and send full query when
* RCODE is not NOERROR. */
@@ -2607,6 +2759,12 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_ALGO,
"could not validate NXDOMAIN "
"response");
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
fptr_ok(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
}
}
return next_state(iq, QUERYTARGETS_STATE);
@@ -2674,11 +2832,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp = delegpt_from_message(iq->response, qstate->region);
if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
if(!iq->dp)
if(!iq->dp) {
errinf(qstate, "malloc failure, for delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp))
qstate->region, iq->dp)) {
errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->store_parent_NS && query_dname_compare(iq->dp->name,
iq->store_parent_NS->name) == 0)
iter_merge_retry_counts(iq->dp, iq->store_parent_NS);
@@ -2740,8 +2902,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* Process the CNAME response. */
if(!handle_cname_response(qstate, iq, iq->response,
&sname, &snamelen))
&sname, &snamelen)) {
errinf(qstate, "malloc failure, CNAME info");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* cache the CNAME response under the current query */
/* NOTE : set referral=1, so that rrsets get stored but not
* the partial query answer (CNAME only). */
@@ -2754,16 +2918,18 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
/* Clear the query state, since this is a query restart. */
iq->deleg_msg = NULL;
iq->dp = NULL;
iq->dsns_point = NULL;
iq->auth_zone_response = 0;
/* Note the query restart. */
iq->query_restart_count++;
iq->sent_count = 0;
if(iq->minimisation_state != MINIMISE_STATE)
/* Only count as query restart when it is not an extra
* query as result of qname minimisation. */
iq->query_restart_count++;
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
@@ -2840,6 +3006,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp->name, iq->dp->namelen, qstate->qinfo.qclass)) {
verbose(VERB_ALGO, "auth zone response bad, and no"
" fallback possible, servfail");
errinf_dname(qstate, "response is bad, no fallback, "
"for auth zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
verbose(VERB_ALGO, "auth zone response was bad, "
@@ -2930,6 +3098,8 @@ processPrimeResponse(struct module_qstate* qstate, int id)
qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = iq->response;
} else {
errinf(qstate, "prime response did not get an answer");
errinf_dname(qstate, "for", qstate->qinfo.qname);
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
qstate->return_msg = NULL;
}
@@ -3073,6 +3243,7 @@ processDSNSResponse(struct module_qstate* qstate, int id,
foriq->dp = delegpt_from_message(qstate->return_msg, forq->region);
if(!foriq->dp) {
log_err("out of memory in dsns dp alloc");
errinf(qstate, "malloc failure, in DS search");
return; /* dp==NULL in QUERYTARGETS makes SERVFAIL */
}
/* success, go query the querytargets in the new dp (and go down) */
@@ -3173,6 +3344,8 @@ processClassResponse(struct module_qstate* qstate, int id,
to->rep->ttl = from->rep->ttl;
if(from->rep->prefetch_ttl < to->rep->prefetch_ttl)
to->rep->prefetch_ttl = from->rep->prefetch_ttl;
if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
}
/* are we done? */
foriq->num_current_queries --;
@@ -3211,6 +3384,8 @@ processCollectClass(struct module_qstate* qstate, int id)
c, qstate, id, iq, INIT_REQUEST_STATE,
FINISHED_STATE, &subq,
(int)!(qstate->query_flags&BIT_CD))) {
errinf(qstate, "could not generate class ANY"
" lookup query");
return error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
}
@@ -3257,6 +3432,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
(iq->response?iq->response->rep:NULL));
if(!iq->response) {
verbose(VERB_ALGO, "No response is set, servfail");
errinf(qstate, "(no response found at query finish)");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -3421,12 +3597,13 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(event == module_event_noreply || event == module_event_error) {
if(event == module_event_noreply && iq->sent_count >= 3 &&
qstate->env->cfg->use_caps_bits_for_id &&
!iq->caps_fallback) {
!iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
/* start fallback */
iq->caps_fallback = 1;
iq->caps_server = 0;
iq->caps_reply = NULL;
iq->caps_response = NULL;
iq->caps_minimisation_state = DONOT_MINIMISE_STATE;
iq->state = QUERYTARGETS_STATE;
iq->num_current_queries--;
/* need fresh attempts for the 0x20 fallback, if
@@ -3441,6 +3618,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|| !qstate->reply) {
log_err("Bad event combined with response");
outbound_list_remove(&iq->outlist, outbound);
errinf(qstate, "module iterator received wrong internal event with a response message");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
}
@@ -3493,6 +3671,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
iq->caps_server = 0;
iq->caps_reply = NULL;
iq->caps_response = NULL;
iq->caps_minimisation_state = DONOT_MINIMISE_STATE;
iq->state = QUERYTARGETS_STATE;
iq->num_current_queries--;
verbose(VERB_DETAIL, "Capsforid: scrub failed, starting fallback with no response");
@@ -3512,15 +3691,30 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response->rep);
if(event == module_event_capsfail || iq->caps_fallback) {
if(qstate->env->cfg->qname_minimisation &&
iq->minimisation_state != DONOT_MINIMISE_STATE) {
/* Skip QNAME minimisation for next query, since that
* one has to match the current query. */
iq->minimisation_state = SKIP_MINIMISE_STATE;
}
/* for fallback we care about main answer, not additionals */
/* removing that makes comparison more likely to succeed */
caps_strip_reply(iq->response->rep);
if(iq->caps_fallback &&
iq->caps_minimisation_state != iq->minimisation_state) {
/* QNAME minimisation state has changed, restart caps
* fallback. */
iq->caps_fallback = 0;
}
if(!iq->caps_fallback) {
/* start fallback */
iq->caps_fallback = 1;
iq->caps_server = 0;
iq->caps_reply = iq->response->rep;
iq->caps_response = iq->response;
iq->caps_minimisation_state = iq->minimisation_state;
iq->state = QUERYTARGETS_STATE;
iq->num_current_queries--;
verbose(VERB_DETAIL, "Capsforid: starting fallback");
@@ -3552,6 +3746,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_DETAIL, "Capsforid fallback: "
"getting different replies, failed");
outbound_list_remove(&iq->outlist, outbound);
errinf(qstate, "0x20 failed, then got different replies in fallback");
(void)error_response(qstate, id,
LDNS_RCODE_SERVFAIL);
return;
@@ -3590,6 +3785,7 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
if((event == module_event_new || event == module_event_pass) &&
iq == NULL) {
if(!iter_new(qstate, id)) {
errinf(qstate, "malloc failure, new iterator module allocation");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
}
@@ -3607,11 +3803,13 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
errinf(qstate, "iterator module got the error event");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
}
log_err("bad event for iterator");
errinf(qstate, "iterator module received wrong event");
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
+4 -1
View File
@@ -83,7 +83,7 @@ struct rbtree_type;
/** how nice is a server without further information, in msec
* Equals rtt initial timeout value.
*/
#define UNKNOWN_SERVER_NICENESS 376
extern int UNKNOWN_SERVER_NICENESS;
/** maximum timeout before a host is deemed unsuitable, in msec.
* After host_ttl this will be timed out and the host will be tried again.
* Equals RTT_MAX_TIMEOUT
@@ -371,6 +371,9 @@ struct iter_qstate {
/** QNAME minimisation state, RFC7816 */
enum minimisation_state minimisation_state;
/** State for capsfail: QNAME minimisation state for comparisons. */
enum minimisation_state caps_minimisation_state;
/**
* The query info that is sent upstream. Will be a subset of qchase
* when qname minimisation is enabled.
+30 -19
View File
@@ -57,9 +57,16 @@ context_finalize(struct ub_ctx* ctx)
{
struct config_file* cfg = ctx->env->cfg;
verbosity = cfg->verbosity;
if(ctx->logfile_override)
if(ctx_logfile_overridden && !ctx->logfile_override) {
log_file(NULL); /* clear that override */
ctx_logfile_overridden = 0;
}
if(ctx->logfile_override) {
ctx_logfile_overridden = 1;
log_file(ctx->log_out);
else log_init(cfg->logfile, cfg->use_syslog, NULL);
} else {
log_init(cfg->logfile, cfg->use_syslog, NULL);
}
config_apply(cfg);
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
@@ -71,9 +78,8 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1))
return UB_INITFAIL;
if(!ctx->env->msg_cache ||
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {
slabhash_delete(ctx->env->msg_cache);
ctx->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
@@ -294,26 +300,29 @@ context_serialize_answer(struct ctx_query* q, int err, sldns_buffer* pkt,
* o uint32 id
* o uint32 error_code
* o uint32 msg_security
* o uint32 was_ratelimited
* o uint32 length of why_bogus string (+1 for eos); 0 absent.
* o why_bogus_string
* o the remainder is the answer msg from resolver lookup.
* remainder can be length 0.
*/
size_t size_of_uint32s = 6 * sizeof(uint32_t);
size_t pkt_len = pkt?sldns_buffer_remaining(pkt):0;
size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0;
uint8_t* p;
*len = sizeof(uint32_t)*5 + pkt_len + wlen;
*len = size_of_uint32s + pkt_len + wlen;
p = (uint8_t*)malloc(*len);
if(!p) return NULL;
sldns_write_uint32(p, UB_LIBCMD_ANSWER);
sldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum);
sldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err);
sldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security);
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen);
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)q->res->was_ratelimited);
sldns_write_uint32(p+5*sizeof(uint32_t), (uint32_t)wlen);
if(wlen > 0)
memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen);
memmove(p+size_of_uint32s, q->res->why_bogus, wlen);
if(pkt_len > 0)
memmove(p+5*sizeof(uint32_t)+wlen,
memmove(p+size_of_uint32s+wlen,
sldns_buffer_begin(pkt), pkt_len);
return p;
}
@@ -322,21 +331,23 @@ struct ctx_query*
context_deserialize_answer(struct ub_ctx* ctx,
uint8_t* p, uint32_t len, int* err)
{
size_t size_of_uint32s = 6 * sizeof(uint32_t);
struct ctx_query* q = NULL ;
int id;
size_t wlen;
if(len < 5*sizeof(uint32_t)) return NULL;
if(len < size_of_uint32s) return NULL;
log_assert( sldns_read_uint32(p) == UB_LIBCMD_ANSWER);
id = (int)sldns_read_uint32(p+sizeof(uint32_t));
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
if(!q) return NULL;
*err = (int)sldns_read_uint32(p+2*sizeof(uint32_t));
q->msg_security = sldns_read_uint32(p+3*sizeof(uint32_t));
wlen = (size_t)sldns_read_uint32(p+4*sizeof(uint32_t));
if(len > 5*sizeof(uint32_t) && wlen > 0) {
if(len >= 5*sizeof(uint32_t)+wlen)
q->res->was_ratelimited = (int)sldns_read_uint32(p+4*sizeof(uint32_t));
wlen = (size_t)sldns_read_uint32(p+5*sizeof(uint32_t));
if(len > size_of_uint32s && wlen > 0) {
if(len >= size_of_uint32s+wlen)
q->res->why_bogus = (char*)memdup(
p+5*sizeof(uint32_t), wlen);
p+size_of_uint32s, wlen);
if(!q->res->why_bogus) {
/* pass malloc failure to the user callback */
q->msg_len = 0;
@@ -345,9 +356,9 @@ context_deserialize_answer(struct ub_ctx* ctx,
}
q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
}
if(len > 5*sizeof(uint32_t)+wlen) {
q->msg_len = len - 5*sizeof(uint32_t) - wlen;
q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen,
if(len > size_of_uint32s+wlen) {
q->msg_len = len - size_of_uint32s - wlen;
q->msg = (uint8_t*)memdup(p+size_of_uint32s+wlen,
q->msg_len);
if(!q->msg) {
/* pass malloc failure to the user callback */
@@ -388,12 +399,12 @@ struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
uint8_t*
context_serialize_quit(uint32_t* len)
{
uint8_t* p = (uint8_t*)malloc(sizeof(uint32_t));
uint32_t* p = (uint32_t*)malloc(sizeof(uint32_t));
if(!p)
return NULL;
*len = sizeof(uint32_t);
sldns_write_uint32(p, UB_LIBCMD_QUIT);
return p;
return (uint8_t*)p;
}
enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len)
+3
View File
@@ -52,6 +52,9 @@ struct tube;
struct sldns_buffer;
struct ub_event_base;
/** store that the logfile has a debug override */
extern int ctx_logfile_overridden;
/**
* The context structure
*
+27 -12
View File
@@ -79,6 +79,9 @@
#include <iphlpapi.h>
#endif /* UB_ON_WINDOWS */
/** store that the logfile has a debug override */
int ctx_logfile_overridden = 0;
/** create context functionality, but no pipes */
static struct ub_ctx* ub_ctx_create_nopipe(void)
{
@@ -90,7 +93,8 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
#endif
checklock_start();
log_init(NULL, 0, NULL); /* logs to stderr */
if(!ctx_logfile_overridden)
log_init(NULL, 0, NULL); /* logs to stderr */
log_ident_set("libunbound");
#ifdef USE_WINSOCK
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
@@ -109,13 +113,13 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
alloc_init(&ctx->superalloc, NULL, 0);
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
seed = 0;
explicit_bzero(&seed, sizeof(seed));
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
seed = 0;
explicit_bzero(&seed, sizeof(seed));
lock_basic_init(&ctx->qqpipe_lock);
lock_basic_init(&ctx->rrpipe_lock);
lock_basic_init(&ctx->cfglock);
@@ -328,6 +332,10 @@ ub_ctx_delete(struct ub_ctx* ctx)
ub_randfree(ctx->seed_rnd);
alloc_clear(&ctx->superalloc);
traverse_postorder(&ctx->queries, delq, NULL);
if(ctx_logfile_overridden) {
log_file(NULL);
ctx_logfile_overridden = 0;
}
free(ctx);
#ifdef USE_WINSOCK
WSACleanup();
@@ -392,7 +400,6 @@ ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta)
}
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_NOMEM;
}
lock_basic_unlock(&ctx->cfglock);
@@ -412,7 +419,6 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
}
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_NOMEM;
}
lock_basic_unlock(&ctx->cfglock);
@@ -432,7 +438,6 @@ int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
dup)) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_NOMEM;
}
lock_basic_unlock(&ctx->cfglock);
@@ -452,7 +457,6 @@ ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
}
if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
lock_basic_unlock(&ctx->cfglock);
free(dup);
return UB_NOMEM;
}
lock_basic_unlock(&ctx->cfglock);
@@ -473,6 +477,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
{
lock_basic_lock(&ctx->cfglock);
log_file((FILE*)out);
ctx_logfile_overridden = 1;
ctx->logfile_override = 1;
ctx->log_out = out;
lock_basic_unlock(&ctx->cfglock);
@@ -728,7 +733,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
*async_id = 0;
lock_basic_lock(&ctx->cfglock);
if(!ctx->finalized) {
int r = context_finalize(ctx);
r = context_finalize(ctx);
if(r) {
lock_basic_unlock(&ctx->cfglock);
return r;
@@ -962,7 +967,6 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
return UB_NOMEM;
}
if(!cfg_strlist_insert(&s->addrs, dupl)) {
free(dupl);
lock_basic_unlock(&ctx->cfglock);
errno=ENOMEM;
return UB_NOMEM;
@@ -971,6 +975,19 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
return UB_NOERROR;
}
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls)
{
lock_basic_lock(&ctx->cfglock);
if(ctx->finalized) {
lock_basic_unlock(&ctx->cfglock);
errno=EINVAL;
return UB_AFTERFINAL;
}
ctx->env->cfg->ssl_upstream = tls;
lock_basic_unlock(&ctx->cfglock);
return UB_NOERROR;
}
int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
int isprime)
{
@@ -1045,7 +1062,6 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
}
if(!cfg_strlist_insert(&elem->addrs, a)) {
lock_basic_unlock(&ctx->cfglock);
free(a);
errno = ENOMEM;
return UB_NOMEM;
}
@@ -1143,7 +1159,7 @@ int
ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
{
FILE* in;
char buf[1024], ldata[1024];
char buf[1024], ldata[2048];
char* parse, *addr, *name, *ins;
lock_basic_lock(&ctx->cfglock);
if(ctx->finalized) {
@@ -1233,7 +1249,6 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
ins)) {
lock_basic_unlock(&ctx->cfglock);
fclose(in);
free(ins);
errno=ENOMEM;
return UB_NOMEM;
}
+37 -32
View File
@@ -187,7 +187,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
}
seed = 0;
explicit_bzero(&seed, sizeof(seed));
libworker_delete(w);
return NULL;
}
@@ -207,7 +207,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
hash_set_raninit((uint32_t)ub_random(w->env->rnd));
}
}
seed = 0;
explicit_bzero(&seed, sizeof(seed));
if(eb)
w->base = comm_base_create_event(eb);
@@ -222,11 +222,10 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
}
numports = cfg_condense_ports(cfg, &ports);
if(numports == 0) {
int locked = !w->is_bg || w->is_bg_thread;
libworker_delete(w);
if(locked) {
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
}
libworker_delete(w);
return NULL;
}
w->back = outside_network_create(w->base, cfg->msg_buffer_size,
@@ -521,8 +520,9 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
/** fillup fg results */
static void
libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
enum sec_status s, char* why_bogus)
enum sec_status s, char* why_bogus, int was_ratelimited)
{
q->res->was_ratelimited = was_ratelimited;
if(why_bogus)
q->res->why_bogus = strdup(why_bogus);
if(rcode != 0) {
@@ -546,13 +546,13 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
void
libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
char* why_bogus)
char* why_bogus, int was_ratelimited)
{
struct ctx_query* q = (struct ctx_query*)arg;
/* fg query is done; exit comm base */
comm_base_exit(q->w->base);
libworker_fillup_fg(q, rcode, buf, s, why_bogus);
libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited);
}
/** setup qinfo and edns */
@@ -603,16 +603,16 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
NULL, 0, NULL, 0, NULL)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
w->back->udp_buff, sec_status_insecure, NULL, 0);
libworker_delete(w);
free(qinfo.qname);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
w->back->udp_buff, sec_status_insecure, NULL, 0);
libworker_delete(w);
free(qinfo.qname);
return UB_NOERROR;
@@ -634,7 +634,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
void
libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
enum sec_status s, char* why_bogus)
enum sec_status s, char* why_bogus, int was_ratelimited)
{
struct ctx_query* q = (struct ctx_query*)arg;
ub_event_callback_type cb = q->cb_event;
@@ -656,8 +656,8 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
sec = 1;
else if(s == sec_status_secure)
sec = 2;
(*cb)(cb_arg, rcode, (void*)sldns_buffer_begin(buf),
(int)sldns_buffer_limit(buf), sec, why_bogus);
(*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL),
(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited);
}
}
@@ -684,15 +684,15 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
w->back->udp_buff, sec_status_insecure, NULL, 0);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
w->back->udp_buff, sec_status_insecure, NULL, 0);
return UB_NOERROR;
}
/* process new query */
@@ -710,7 +710,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
/** add result to the bg worker result queue */
static void
add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
int err, char* reason)
int err, char* reason, int was_ratelimited)
{
uint8_t* msg = NULL;
uint32_t len = 0;
@@ -724,19 +724,23 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
lock_basic_lock(&w->ctx->cfglock);
if(reason)
q->res->why_bogus = strdup(reason);
q->res->was_ratelimited = was_ratelimited;
if(pkt) {
q->msg_len = sldns_buffer_remaining(pkt);
q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len);
if(!q->msg)
msg = context_serialize_answer(q, UB_NOMEM,
NULL, &len);
else msg = context_serialize_answer(q, err,
NULL, &len);
} else msg = context_serialize_answer(q, err, NULL, &len);
if(!q->msg) {
msg = context_serialize_answer(q, UB_NOMEM, NULL, &len);
} else {
msg = context_serialize_answer(q, err, NULL, &len);
}
} else {
msg = context_serialize_answer(q, err, NULL, &len);
}
lock_basic_unlock(&w->ctx->cfglock);
} else {
if(reason)
q->res->why_bogus = strdup(reason);
q->res->was_ratelimited = was_ratelimited;
msg = context_serialize_answer(q, err, pkt, &len);
(void)rbtree_delete(&w->ctx->queries, q->node.key);
w->ctx->num_async--;
@@ -755,7 +759,7 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
void
libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
char* why_bogus)
char* why_bogus, int was_ratelimited)
{
struct ctx_query* q = (struct ctx_query*)arg;
@@ -773,12 +777,13 @@ libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
return;
}
q->msg_security = s;
if(!buf)
if(!buf) {
buf = q->w->env->scratch_buffer;
}
if(rcode != 0) {
error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
}
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus);
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus, was_ratelimited);
}
@@ -803,7 +808,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
return;
}
if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
add_bg_result(w, q, NULL, UB_SYNTAX, NULL);
add_bg_result(w, q, NULL, UB_SYNTAX, NULL, 0);
return;
}
qid = 0;
@@ -816,15 +821,15 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
NULL, 0, NULL, 0, NULL)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
free(qinfo.qname);
return;
}
if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
free(qinfo.qname);
return;
}
@@ -832,7 +837,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
add_bg_result(w, q, NULL, UB_NOMEM, NULL);
add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
}
free(qinfo.qname);
}
@@ -29,6 +29,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")
dnssecParse("nic.cz")
dnssecParse("nonexistent-domain-blablabla.cz")
+19 -7
View File
@@ -33,12 +33,26 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
%begin %{
/* store state of warning output, restored at later pop */
#pragma GCC diagnostic push
/* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
#pragma GCC diagnostic ignored "-Wcast-function-type"
%}
%module unbound
%{
/* restore state of warning output, remove the functioncast ignore */
#pragma GCC diagnostic pop
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "libunbound/unbound.h"
%}
@@ -108,7 +122,7 @@
%inline %{
void ub_ctx_free_dbg (struct ub_ctx* c) {
printf("******** UB_CTX free 0x%lX ************\n", (long unsigned int)c);
printf("******** UB_CTX free 0x%p ************\n", c);
ub_ctx_delete(c);
}
@@ -228,6 +242,7 @@
RR_TYPE_MAILA = 254,
/** any type (wildcard) */
RR_TYPE_ANY = 255,
RR_TYPE_CAA = 257,
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
RR_TYPE_DLV = 32769,
@@ -648,7 +663,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
%inline %{
void ub_resolve_free_dbg (struct ub_result* r) {
printf("******** UB_RESOLVE free 0x%lX ************\n", (long unsigned int)r);
printf("******** UB_RESOLVE free 0x%p ************\n", r);
ub_resolve_free(r);
}
%}
@@ -809,8 +824,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
"""
return self.rcode2str[self.rcode]
__swig_getmethods__["rcode_str"] = _get_rcode_str
if _newclass:rcode_str = _swig_property(_get_rcode_str)
rcode_str = property(_get_rcode_str)
def _get_raw_data(self):
"""Result data, a list of network order DNS rdata items.
@@ -819,15 +833,13 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
"""
return self._ub_result_data(self)
__swig_getmethods__["rawdata"] = _get_raw_data
rawdata = property(_get_raw_data, doc="Returns raw data, a list of rdata items. To decode RAW data use the :attr:`data` attribute which returns an instance of :class:`ub_data` containing the conversion functions.")
def _get_data(self):
if not self.havedata: return None
return ub_data(self._ub_result_data(self))
__swig_getmethods__["data"] = _get_data
__swig_getmethods__["packet"] = _packet
packet = property(_packet)
data = property(_get_data, doc="Returns :class:`ub_data` instance containing various decoding functions or None")
%}
+1
View File
@@ -20,6 +20,7 @@ ub_ctx_set_event
ub_ctx_set_fwd
ub_ctx_set_option
ub_ctx_set_stub
ub_ctx_set_tls
ub_ctx_trustedkeys
ub_ctx_zone_add
ub_ctx_zone_remove
+1 -1
View File
@@ -170,7 +170,7 @@ struct ub_event {
struct ub_event_vmt* vmt;
};
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int);
/**
* Create a resolving and validation context.
+28
View File
@@ -203,6 +203,12 @@ struct ub_result {
*/
char* why_bogus;
/**
* If the query or one of its subqueries was ratelimited. Useful if
* ratelimiting is enabled and answer is SERVFAIL.
*/
int was_ratelimited;
/**
* TTL for the result, in seconds. If the security is bogus, then
* you also cannot trust this value.
@@ -303,6 +309,17 @@ int ub_ctx_config(struct ub_ctx* ctx, const char* fname);
*/
int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
/**
* Use DNS over TLS to send queries to machines set with ub_ctx_set_fwd().
*
* @param ctx: context.
* At this time it is only possible to set configuration before the
* first resolve is done.
* @param tls: enable or disable DNS over TLS
* @return 0 if OK, else error.
*/
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
/**
* Add a stub zone, with given address to send to. This is for custom
* root hints or pointing to a local authoritative dns server.
@@ -674,6 +691,8 @@ struct ub_server_stats {
long long qtcp;
/** number of outgoing queries over TCP */
long long qtcp_outgoing;
/** number of queries over (DNS over) TLS */
long long qtls;
/** number of queries over IPv6 */
long long qipv6;
/** number of queries with QR bit */
@@ -757,6 +776,15 @@ struct ub_server_stats {
/** number of times neg cache records were used to generate NXDOMAIN
* responses. */
long long num_neg_cache_nxdomain;
/** number of queries answered from edns-subnet specific data */
long long num_query_subnet;
/** 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 bytes in the stream wait buffers */
long long mem_stream_wait;
/** number of TLS connection resume */
long long qtls_resume;
};
/**
+3 -3
View File
@@ -89,15 +89,15 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
/** mesh callback with fg results */
void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf,
enum sec_status s, char* why_bogus);
enum sec_status s, char* why_bogus, int was_ratelimited);
/** mesh callback with bg results */
void libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf,
enum sec_status s, char* why_bogus);
enum sec_status s, char* why_bogus, int was_ratelimited);
/** mesh callback with event results */
void libworker_event_done_cb(void* arg, int rcode, struct sldns_buffer* buf,
enum sec_status s, char* why_bogus);
enum sec_status s, char* why_bogus, int was_ratelimited);
/**
* Worker signal handler function. User argument is the worker itself.
+4 -2
View File
@@ -2124,7 +2124,7 @@ fi
# a configuration failure hint, and exit.
func_fatal_configuration ()
{
func__fatal_error ${1+"$@"} \
func_fatal_error ${1+"$@"} \
"See the $PACKAGE documentation for more information." \
"Fatal configuration error."
}
@@ -7272,10 +7272,12 @@ func_mode_link ()
# -tp=* Portland pgcc target processor selection
# --sysroot=* for sysroot support
# -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
# -specs=* GCC specs files
# -stdlib=* select c++ std lib with clang
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-specs=*)
func_quote_for_eval "$arg"
arg=$func_quote_for_eval_result
func_append compile_command " $arg"
+93 -37
View File
@@ -1,6 +1,6 @@
#!/bin/sh
# Build unbound distribution tar from the SVN repository.
# Build unbound distribution tar from the git repository.
#
# Copyright (c) 2007, NLnet Labs. All rights reserved.
#
@@ -42,7 +42,7 @@ cwd=`pwd`
# Utility functions.
usage () {
cat >&2 <<EOF
Usage $0: [-h] [-s] [-d SVN_root] [-w ...args...]
Usage $0: [-h] [-s] [-u git_url] [-b git_branch] [-w ...args...]
Generate a distribution tar file for unbound.
-h This usage information.
@@ -51,8 +51,10 @@ Generate a distribution tar file for unbound.
-rc <nr> Build a release candidate, the given string will be added
to the version number
(which will then be unbound-<version>rc<number>)
-d SVN_root Retrieve the unbound source from the specified repository.
Detected from svn working copy if not specified.
-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.
-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.
@@ -115,16 +117,20 @@ replace_version () {
replace_text "$1" "VERSION_MICRO\],\[$v1" "VERSION_MICRO\],\[$v2"
}
check_svn_root () {
# Check if SVNROOT is specified.
if [ -z "$SVNROOT" ]; then
if svn info 2>&1 | grep "not a working copy" >/dev/null; then
if test -z "$SVNROOT"; then
error "SVNROOT must be specified (using -d)"
fi
check_git_repo () {
# Check if git repo and branch are specified.
if [ -z "$GITREPO" ]; then
if git status 2>&1 | grep "not a git repository" >/dev/null; then
error "specify repo (using -u) or use settings detected by starting from working copy directory"
else
eval `svn info | grep 'URL:' | sed -e 's/URL: /url=/' | head -1`
SVNROOT="$url"
GITREPO="`git config --get remote.origin.url`"
fi
fi
if [ -z "$GITBRANCH" ]; then
if git status 2>&1 | grep "not a git repository" >/dev/null; then
error "specify branch (using -b) or use settings detected by starting from working copy directory"
else
GITBRANCH="`git branch | grep '^\*' | sed -e 's/^\* //'`"
fi
fi
}
@@ -181,6 +187,7 @@ DOWIN="no"
W64="yes"
WINSSL=""
WINEXPAT=""
MINJ=""
# Parse the command line arguments.
while [ "$1" ]; do
@@ -188,8 +195,12 @@ while [ "$1" ]; do
"-h")
usage
;;
"-d")
SVNROOT="$2"
"-u")
GITREPO="$2"
shift
;;
"-b")
GITBRANCH="$2"
shift
;;
"-s")
@@ -239,8 +250,9 @@ if [ "$DOWIN" = "yes" ]; then
makensis="makensis" # from mingw32-nsis package
# flags for crosscompiled dependency libraries
cross_flag=""
shared_cross_flag=""
check_svn_root
check_git_repo
create_temp_dir
# crosscompile openssl for windows.
@@ -249,24 +261,37 @@ if [ "$DOWIN" = "yes" ]; then
info "winssl tar unpack"
(cd ..; gzip -cd $WINSSL) | tar xf - || error_cleanup "tar unpack of $WINSSL failed"
sslinstall="`pwd`/sslinstall"
cp -r openssl-* openssl_shared
cd openssl-* || error_cleanup "no openssl-X dir in tarball"
# configure for crosscompile, without CAPI because it fails
# 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-shared no-asm -DOPENSSL_NO_CAPIENG mingw64"
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw64"
else
sslflags="no-shared no-asm -DOPENSSL_NO_CAPIENG mingw"
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw"
fi
info "winssl: Configure $sslflags"
CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" $sslflags || error_cleanup "OpenSSL Configure failed"
info "winssl: Configure no-shared $sslflags"
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"
info "winssl: make"
make || error_cleanup "OpenSSL crosscompile failed"
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
# only install sw not docs, which take a long time.
info "winssl: make install_sw"
make install_sw || error_cleanup "OpenSSL install failed"
cross_flag="$cross_flag --with-ssl=$sslinstall"
cd ..
# shared compile
sslsharedinstall="`pwd`/sslsharedinstall"
cd openssl_shared
info "winssl: Configure shared $sslflags"
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"
info "winssl: make"
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
info "winssl: make install_sw"
make install_sw || error_cleanup "OpenSSL install failed"
shared_cross_flag="$shared_cross_flag --with-ssl=$sslsharedinstall"
cd ..
fi
if test -n "$WINEXPAT"; then
@@ -277,18 +302,22 @@ if [ "$DOWIN" = "yes" ]; then
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"
#info "wxp: make"
#make || error_cleanup "libexpat crosscompile failed"
info "wxp: make"
make $MINJ || error_cleanup "libexpat crosscompile failed"
info "wxp: make install"
make install || error_cleanup "libexpat install failed"
cross_flag="$cross_flag --with-libexpat=$wxpinstall"
shared_cross_flag="$shared_cross_flag --with-libexpat=$wxpinstall"
cd ..
fi
info "SVNROOT is $SVNROOT"
info "Exporting source from SVN."
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
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"
cd unbound || error_cleanup "Unbound not exported correctly from git"
rm -rf .git || error_cleanup "Failed to remove .git tracking information"
# on a re-configure the cache may no longer be valid...
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
@@ -320,6 +349,10 @@ if [ "$DOWIN" = "yes" ]; then
rm -r autom4te* || echo "ignored"
fi
if test "`uname`" = "Linux"; then
(cd ..; cp -r unbound unbound_shared)
fi
# procedure for making unbound installer on mingw.
info "Creating windows dist unbound $version"
info "Calling configure"
@@ -338,9 +371,26 @@ if [ "$DOWIN" = "yes" ]; then
|| error_cleanup "Could not configure"
fi
info "Calling make"
make || error_cleanup "Could not make"
make $MINJ || error_cleanup "Could not make"
info "Make complete"
if test "`uname`" = "Linux"; then
info "Make DLL"
cd ../unbound_shared
echo "$configure"' --enable-debug --disable-flto '"$* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag""
if test "$W64" = "no"; then
$configure --enable-debug --disable-flto $* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag" \
|| error_cleanup "Could not configure"
else
$configure --enable-debug --disable-flto $* $shared_cross_flag \
|| error_cleanup "Could not configure"
fi
info "Calling make for DLL"
make $MINJ || error_cleanup "Could not make DLL"
info "Make DLL complete"
cd ../unbound
fi
info "Unbound version: $version"
file="unbound-$version.zip"
rm -f $file
@@ -360,17 +410,19 @@ if [ "$DOWIN" = "yes" ]; then
cp ../root.key .
cp ../doc/example.conf ../doc/Changelog .
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
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/lib/libcrypto.dll.a ../../sslsharedinstall/lib/libssl.dll.a ../../sslsharedinstall/bin/libcrypto*.dll ../../sslsharedinstall/bin/libssl*.dll ../../wxpinstall/bin/libexpat*.dll ../../wxpinstall/lib/libexpat.dll.a libunbound/.
# zipfile
zip ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog
zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound
info "Testing $file"
(cd .. ; zip -T $file )
# installer
info "Creating installer"
quadversion=`cat ../config.h | grep RSRC_PACKAGE_VERSION | sed -e 's/#define RSRC_PACKAGE_VERSION //' -e 's/,/\\./g'`
cat ../winrc/setup.nsi | sed -e 's/define VERSION.*$/define VERSION "'$version'"/' -e 's/define QUADVERSION.*$/define QUADVERSION "'$quadversion'"/' > ../winrc/setup_ed.nsi
if test "$W64" = "yes"; then
if test "$W64" = "no"; then
mv ../winrc/setup_ed.nsi ../winrc/setup_ed_old.nsi
cat ../winrc/setup_ed_old.nsi | sed -e 's/PROGRAMFILES/PROGRAMFILES64/' > ../winrc/setup_ed.nsi
cat ../winrc/setup_ed_old.nsi | sed -e 's/PROGRAMFILES64/PROGRAMFILES/' -e 's/SetRegView 64/SetRegView 32/' > ../winrc/setup_ed.nsi
fi
"$makensis" ../winrc/setup_ed.nsi
info "Created installer"
@@ -390,20 +442,24 @@ if [ "$DOWIN" = "yes" ]; then
exit 0
fi
check_svn_root
check_git_repo
# Start the packaging process.
info "SVNROOT is $SVNROOT"
info "SNAPSHOT is $SNAPSHOT"
info "GITREPO is $GITREPO"
info "GITBRANCH is $GITBRANCH"
info "SNAPSHOT is $SNAPSHOT"
#question "Do you wish to continue with these settings?" || error "User abort."
create_temp_dir
info "Exporting source from SVN."
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
info "Exporting source from git."
# --depth=1 and --no-tags reduce the download size.
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
cd unbound || error_cleanup "Unbound not exported correctly from git"
rm -rf .git || error_cleanup "Failed to remove .git tracking information"
info "Adding libtool utils (libtoolize)."
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
+4 -1
View File
@@ -1,8 +1,11 @@
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_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))
return True
def deinit(id):
log_info("pythonmod: deinit called, module id is %d" % id)
return True
+19
View File
@@ -54,6 +54,25 @@ Script file must contain four compulsory functions:
return True
.. function:: init_standard(id, env)
Initialize module internals, like database etc.
Called just once on module load.
*Preferred* over the init() function above as this function's signature is the
same as the C counterpart and allows for extra functionality during init.
The previously accessible configuration options can now be found in env.cfg.
:param id: module identifier (integer)
:param env: :class:`module_env` module environment
::
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))
return True
.. function:: deinit(id)
Deinitialize module internals.
+53 -8
View File
@@ -40,9 +40,12 @@ The callback function's prototype is the following:
.. code-block:: python
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
"""Function that will be registered as an inplace callback function.
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering with a resolved query.
:param qinfo: query_info struct;
:param qstate: module qstate. It contains the available opt_lists; It
SHOULD NOT be altered;
@@ -54,7 +57,13 @@ The callback function's prototype is the following:
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh states.
:return: True on success, False on failure.
"""
.. note:: The function's name is irrelevant.
@@ -76,9 +85,12 @@ The callback function's prototype is the following:
.. code-block:: python
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
"""Function that will be registered as an inplace callback function.
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering from the cache.
:param qinfo: query_info struct;
:param qstate: module qstate. None;
:param rep: reply_info struct;
@@ -90,7 +102,17 @@ The callback function's prototype is the following:
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
For demonstration purposes we want to see if EDNS option 65002 is present
and reply with a new value.
"""
.. note:: The function's name is irrelevant.
@@ -112,9 +134,12 @@ The callback function's prototype is the following:
.. code-block:: python
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
"""Function that will be registered as an inplace callback function.
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering from local data.
:param qinfo: query_info struct;
:param qstate: module qstate. None;
:param rep: reply_info struct;
@@ -126,7 +151,14 @@ The callback function's prototype is the following:
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
"""
.. note:: The function's name is irrelevant.
@@ -148,9 +180,12 @@ The callback function's prototype is the following:
.. code-block:: python
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
"""Function that will be registered as an inplace callback function.
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering with SERVFAIL.
:param qinfo: query_info struct;
:param qstate: module qstate. If not None the relevant opt_lists are
available here;
@@ -163,7 +198,17 @@ The callback function's prototype is the following:
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
For demonstration purposes we want to reply with an empty EDNS code '65003'
and log the IP address(es) of the client(s).
"""
.. note:: The function's name is irrelevant.
+29 -4
View File
@@ -103,42 +103,67 @@ Inplace callbacks
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
:param region: :class:`regional`
.. function:: register_inplace_cb_reply(py_cb, env)
.. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region)
Function prototype for callback functions used in
`register_inplace_cb_query`_.
:param qinfo: :class:`query_info`
:param flags: query flags (integer)
:param qstate: :class:`module_qstate`
:param addr: :class:`sockaddr_storage`
:param zone: zone name in wire format (bytes)
:param region: :class:`regional`
.. function:: register_inplace_cb_reply(py_cb, env, id)
Register py_cb as an inplace reply callback function.
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
:param env: :class:`module_env`
:param id: Module ID.
:return: True on success, False otherwise
:rtype: boolean
.. function:: register_inplace_cb_reply_cache(py_cb, env)
.. function:: register_inplace_cb_reply_cache(py_cb, env, id)
Register py_cb as an inplace reply_cache callback function.
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
:param env: :class:`module_env`
:param id: Module ID.
:return: True on success, False otherwise
:rtype: boolean
.. function:: register_inplace_cb_reply_local(py_cb, env)
.. function:: register_inplace_cb_reply_local(py_cb, env, id)
Register py_cb as an inplace reply_local callback function.
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
:param env: :class:`module_env`
:param id: Module ID.
:return: True on success, False otherwise
:rtype: boolean
.. function:: register_inplace_cb_reply_servfail(py_cb, env)
.. function:: register_inplace_cb_reply_servfail(py_cb, env, id)
Register py_cb as an inplace reply_servfail callback function.
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
:param env: :class:`module_env`
:param id: Module ID.
:return: True on success, False otherwise
:rtype: boolean
.. function:: register_inplace_cb_query(py_cb, env, id)
Register py_cb as an inplace query callback function.
:param py_cb: Python function that follows `inplace_cb_query`_'s prototype. **Must** be callable.
:param env: :class:`module_env`
:param id: Module ID.
:return: True on success, False otherwise
:rtype: boolean
Logging
-------
+30
View File
@@ -514,3 +514,33 @@ pythonmod_qstate
Here you can keep your own private data (each thread has own data object).
sockaddr_storage
-------------------------
.. class:: sockaddr_storage
The :class:`sockaddr_storage` provides these data attributes:
.. attribute:: family
Address family name as a string. Possible values are `ip4`, `ip6`, and `unix`.
.. attribute:: addr
Address in presentation format.
.. attribute:: raw_addr
Address in network wire format.
.. attribute:: port
Port number. Invalid for Unix address.
.. attribute:: flowinfo
Flow info value. Valid only for IPv6 address.
.. attribute:: scope_id
Scope ID value. Valid only for IPv6 address.
+567
View File
@@ -0,0 +1,567 @@
#!/usr/bin/env python3
#
# A plugin for the Unbound DNS resolver to resolve DNS records in
# multicast DNS [RFC 6762] via Avahi.
#
# Copyright (C) 2018-2019 Internet Real-Time Lab, Columbia University
# http://www.cs.columbia.edu/irt/
#
# Written by Jan Janak <janakj@cs.columbia.edu>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#
# Dependendies:
# Unbound with pythonmodule configured for Python 3
# dnspython [http://www.dnspython.org]
# pydbus [https://github.com/LEW21/pydbus]
#
# To enable Python 3 support, configure Unbound as follows:
# PYTHON_VERSION=3 ./configure --with-pythonmodule
#
# The plugin in meant to be used as a fallback resolver that resolves
# records in multicast DNS if the upstream server cannot be reached or
# provides no answer (NXDOMAIN).
#
# mDNS requests for negative records, i.e., records for which Avahi
# returns no answer (NXDOMAIN), are expensive. Since there is no
# single authoritative server in mDNS, such requests terminate only
# via a timeout. The timeout is about a second (if MDNS_TIMEOUT is not
# configured), or the value configured via MDNS_TIMEOUT. The
# corresponding Unbound thread will be blocked for this amount of
# time. For this reason, it is important to configure an appropriate
# number of threads in unbound.conf and limit the RR types and names
# that will be resolved via Avahi via the environment variables
# described later.
#
# An example unbound.conf with the plugin enabled:
#
# | server:
# | module-config: "validator python iterator"
# | num-threads: 32
# | cache-max-negative-ttl: 60
# | cache-max-ttl: 60
#
#
# The plugin can also be run interactively. Provide the name and
# record type to be resolved as command line arguments and the
# resolved record will be printed to standard output:
#
# $ ./avahi-resolver.py voip-phx4.phxnet.org A
# voip-phx4.phxnet.org. 120 IN A 10.4.3.2
#
#
# The behavior of the plugin can be controlled via the following
# environment variables:
#
# DBUS_SYSTEM_BUS_ADDRESS
#
# The address of the system DBus bus, in the format expected by DBus,
# e.g., unix:path=/run/avahi/system-bus.sock
#
#
# DEBUG
#
# Set this environment variable to "yes", "true", "on", or "1" to
# enable debugging. In debugging mode, the plugin will output a lot
# more information about what it is doing either to the standard
# output (when run interactively) or to Unbound via log_info and
# log_error.
#
# By default debugging is disabled.
#
#
# MDNS_TTL
#
# Avahi does not provide the TTL value for the records it returns.
# This environment variable can be used to configure the TTL value for
# such records.
#
# The default value is 120 seconds.
#
#
# MDNS_TIMEOUT
#
# The maximum amount of time (in milliseconds) an Avahi request is
# allowed to run. This value sets the time it takes to resolve
# negative (non-existent) records in Avahi. If unset, the request
# terminates when Avahi sends the "AllForNow" signal, telling the
# client that more records are unlikely to arrive. This takes roughly
# about one second. You may need to configure a longer value here on
# slower networks, e.g., networks that relay mDNS packets such as
# MANETs.
#
#
# MDNS_GETONE
#
# If set to "true", "1", or "on", an Avahi request will terminate as
# soon as at least one record has been found. If there are multiple
# nodes in the mDNS network publishing the same record, only one (or
# subset) will be returned.
#
# If set to "false", "0", or "off", the plugin will gather records for
# MDNS_TIMEOUT and return all records found. This is only useful in
# networks where multiple nodes are known to publish different records
# under the same name and the client needs to be able to obtain them
# all. When configured this way, all Avahi requests will always take
# MDNS_TIMEOUT to complete!
#
# This option is set to true by default.
#
#
# MDNS_REJECT_TYPES
#
# A comma-separated list of record types that will NOT be resolved in
# mDNS via Avahi. Use this environment variable to prevent specific
# record types from being resolved via Avahi. For example, if your
# network does not support IPv6, you can put AAAA on this list.
#
# The default value is an empty list.
#
# Example: MDNS_REJECT_TYPES=aaaa,mx,soa
#
#
# MDNS_ACCEPT_TYPES
#
# If set, a record type will be resolved via Avahi if and only if it
# is present on this comma-separated list. In other words, this is a
# whitelist.
#
# The default value is an empty list which means all record types will
# be resolved via Avahi.
#
# Example: MDNS_ACCEPT_TYPES=a,ptr,txt,srv,aaaa,cname
#
#
# MDNS_REJECT_NAMES
#
# If the name being resolved matches the regular expression in this
# environment variable, the name will NOT be resolved via Avahi. In
# other words, this environment variable provides a blacklist.
#
# The default value is empty--no names will be reject.
#
# Example: MDNS_REJECT_NAMES=(^|\.)example\.com\.$
#
#
# MDNS_ACCEPT_NAMES
#
# If set to a regular expression, a name will be resolved via Avahi if
# and only if it matches the regular expression. In other words, this
# variable provides a whitelist.
#
# The default value is empty--all names will be resolved via Avahi.
#
# Example: MDNS_ACCEPT_NAMES=^.*\.example\.com\.$
#
import os
import re
import array
import threading
import traceback
import dns.rdata
import dns.rdatatype
import dns.rdataclass
from queue import Queue
from gi.repository import GLib
from pydbus import SystemBus
IF_UNSPEC = -1
PROTO_UNSPEC = -1
sysbus = None
avahi = None
trampoline = dict()
thread_local = threading.local()
dbus_thread = None
dbus_loop = None
def str2bool(v):
if v.lower() in ['false', 'no', '0', 'off', '']:
return False
return True
def dbg(msg):
if DEBUG != False:
log_info('avahi-resolver: %s' % msg)
#
# Although pydbus has an internal facility for handling signals, we
# cannot use that with Avahi. When responding from an internal cache,
# Avahi sends the first signal very quickly, before pydbus has had a
# chance to subscribe for the signal. This will result in lost signal
# and missed data:
#
# https://github.com/LEW21/pydbus/issues/87
#
# As a workaround, we subscribe to all signals before creating a
# record browser and do our own signal matching and dispatching via
# the following function.
#
def signal_dispatcher(connection, sender, path, interface, name, args):
o = trampoline.get(path, None)
if o is None:
return
if name == 'ItemNew': o.itemNew(*args)
elif name == 'ItemRemove': o.itemRemove(*args)
elif name == 'AllForNow': o.allForNow(*args)
elif name == 'Failure': o.failure(*args)
class RecordBrowser:
def __init__(self, callback, name, type_, timeout=None, getone=True):
self.callback = callback
self.records = []
self.error = None
self.getone = getone
self.timer = None if timeout is None else GLib.timeout_add(timeout, self.timedOut)
self.browser_path = avahi.RecordBrowserNew(IF_UNSPEC, PROTO_UNSPEC, name, dns.rdataclass.IN, type_, 0)
trampoline[self.browser_path] = self
self.browser = sysbus.get('.Avahi', self.browser_path)
self.dbg('Created RecordBrowser(name=%s, type=%s, getone=%s, timeout=%s)'
% (name, dns.rdatatype.to_text(type_), getone, timeout))
def dbg(self, msg):
dbg('[%s] %s' % (self.browser_path, msg))
def _done(self):
del trampoline[self.browser_path]
self.dbg('Freeing')
self.browser.Free()
if self.timer is not None:
self.dbg('Removing timer')
GLib.source_remove(self.timer)
self.callback(self.records, self.error)
def itemNew(self, interface, protocol, name, class_, type_, rdata, flags):
self.dbg('Got signal ItemNew')
self.records.append((name, class_, type_, rdata))
if self.getone:
self._done()
def itemRemove(self, interface, protocol, name, class_, type_, rdata, flags):
self.dbg('Got signal ItemRemove')
self.records.remove((name, class_, type_, rdata))
def failure(self, error):
self.dbg('Got signal Failure')
self.error = Exception(error)
self._done()
def allForNow(self):
self.dbg('Got signal AllForNow')
if self.timer is None:
self._done()
def timedOut(self):
self.dbg('Timed out')
self._done()
return False
#
# This function runs the main event loop for DBus (GLib). This
# function must be run in a dedicated worker thread.
#
def dbus_main():
global sysbus, avahi, dbus_loop
dbg('Connecting to system DBus')
sysbus = SystemBus()
dbg('Subscribing to .Avahi.RecordBrowser signals')
sysbus.con.signal_subscribe('org.freedesktop.Avahi',
'org.freedesktop.Avahi.RecordBrowser',
None, None, None, 0, signal_dispatcher)
avahi = sysbus.get('.Avahi', '/')
dbg("Connected to Avahi Daemon: %s (API %s) [%s]"
% (avahi.GetVersionString(), avahi.GetAPIVersion(), avahi.GetHostNameFqdn()))
dbg('Starting DBus main loop')
dbus_loop = GLib.MainLoop()
dbus_loop.run()
#
# This function must be run in the DBus worker thread. It creates a
# new RecordBrowser instance and once it has finished doing it thing,
# it will send the result back to the original thread via the queue.
#
def start_resolver(queue, *args, **kwargs):
try:
RecordBrowser(lambda *v: queue.put_nowait(v), *args, **kwargs)
except Exception as e:
queue.put_nowait((None, e))
return False
#
# To resolve a request, we setup a queue, post a task to the DBus
# worker thread, and wait for the result (or error) to arrive over the
# queue. If the worker thread reports an error, raise the error as an
# exception.
#
def resolve(*args, **kwargs):
try:
queue = thread_local.queue
except AttributeError:
dbg('Creating new per-thread queue')
queue = Queue()
thread_local.queue = queue
GLib.idle_add(lambda: start_resolver(queue, *args, **kwargs))
records, error = queue.get()
queue.task_done()
if error is not None:
raise error
return records
def parse_type_list(lst):
return list(map(dns.rdatatype.from_text, [v.strip() for v in lst.split(',') if len(v)]))
def init(*args, **kwargs):
global dbus_thread, DEBUG
global MDNS_TTL, MDNS_GETONE, MDNS_TIMEOUT
global MDNS_REJECT_TYPES, MDNS_ACCEPT_TYPES
global MDNS_REJECT_NAMES, MDNS_ACCEPT_NAMES
DEBUG = str2bool(os.environ.get('DEBUG', str(False)))
MDNS_TTL = int(os.environ.get('MDNS_TTL', 120))
dbg("TTL for records from Avahi: %d" % MDNS_TTL)
MDNS_REJECT_TYPES = parse_type_list(os.environ.get('MDNS_REJECT_TYPES', ''))
if MDNS_REJECT_TYPES:
dbg('Types NOT resolved via Avahi: %s' % MDNS_REJECT_TYPES)
MDNS_ACCEPT_TYPES = parse_type_list(os.environ.get('MDNS_ACCEPT_TYPES', ''))
if MDNS_ACCEPT_TYPES:
dbg('ONLY resolving the following types via Avahi: %s' % MDNS_ACCEPT_TYPES)
v = os.environ.get('MDNS_REJECT_NAMES', None)
MDNS_REJECT_NAMES = re.compile(v, flags=re.I | re.S) if v is not None else None
if MDNS_REJECT_NAMES is not None:
dbg('Names NOT resolved via Avahi: %s' % MDNS_REJECT_NAMES.pattern)
v = os.environ.get('MDNS_ACCEPT_NAMES', None)
MDNS_ACCEPT_NAMES = re.compile(v, flags=re.I | re.S) if v is not None else None
if MDNS_ACCEPT_NAMES is not None:
dbg('ONLY resolving the following names via Avahi: %s' % MDNS_ACCEPT_NAMES.pattern)
v = os.environ.get('MDNS_TIMEOUT', None)
MDNS_TIMEOUT = int(v) if v is not None else None
if MDNS_TIMEOUT is not None:
dbg('Avahi request timeout: %s' % MDNS_TIMEOUT)
MDNS_GETONE = str2bool(os.environ.get('MDNS_GETONE', str(True)))
dbg('Terminate Avahi requests on first record: %s' % MDNS_GETONE)
dbus_thread = threading.Thread(target=dbus_main)
dbus_thread.daemon = True
dbus_thread.start()
def deinit(*args, **kwargs):
dbus_loop.quit()
dbus_thread.join()
return True
def inform_super(id, qstate, superqstate, qdata):
return True
def get_rcode(msg):
if not msg:
return RCODE_SERVFAIL
return msg.rep.flags & 0xf
def rr2text(rec, ttl):
name, class_, type_, rdata = rec
wire = array.array('B', rdata).tostring()
return '%s. %d %s %s %s' % (
name,
ttl,
dns.rdataclass.to_text(class_),
dns.rdatatype.to_text(type_),
dns.rdata.from_wire(class_, type_, wire, 0, len(wire), None))
def operate(id, event, qstate, qdata):
qi = qstate.qinfo
name = qi.qname_str
type_ = qi.qtype
type_str = dns.rdatatype.to_text(type_)
class_ = qi.qclass
class_str = dns.rdataclass.to_text(class_)
rc = get_rcode(qstate.return_msg)
if event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS:
qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
if event != MODULE_EVENT_MODDONE:
log_err("avahi-resolver: Unexpected event %d" % event)
qstate.ext_state[id] = MODULE_ERROR
return True
qstate.ext_state[id] = MODULE_FINISHED
# Only resolve via Avahi if we got NXDOMAIn from the upstream DNS
# server, or if we could not reach the upstream DNS server. If we
# got some records for the name from the upstream DNS server
# already, do not resolve the record in Avahi.
if rc != RCODE_NXDOMAIN and rc != RCODE_SERVFAIL:
return True
dbg("Got request for '%s %s %s'" % (name, class_str, type_str))
# Avahi only supports the IN class
if class_ != RR_CLASS_IN:
dbg('Rejected, Avahi only supports the IN class')
return True
# Avahi does not support meta queries (e.g., ANY)
if dns.rdatatype.is_metatype(type_):
dbg('Rejected, Avahi does not support the type %s' % type_str)
return True
# If we have a type blacklist and the requested type is on the
# list, reject it.
if MDNS_REJECT_TYPES and type_ in MDNS_REJECT_TYPES:
dbg('Rejected, type %s is on the blacklist' % type_str)
return True
# If we have a type whitelist and if the requested type is not on
# the list, reject it.
if MDNS_ACCEPT_TYPES and type_ not in MDNS_ACCEPT_TYPES:
dbg('Rejected, type %s is not on the whitelist' % type_str)
return True
# If we have a name blacklist and if the requested name matches
# the blacklist, reject it.
if MDNS_REJECT_NAMES is not None:
if MDNS_REJECT_NAMES.search(name):
dbg('Rejected, name %s is on the blacklist' % name)
return True
# If we have a name whitelist and if the requested name does not
# match the whitelist, reject it.
if MDNS_ACCEPT_NAMES is not None:
if not MDNS_ACCEPT_NAMES.search(name):
dbg('Rejected, name %s is not on the whitelist' % name)
return True
dbg("Resolving '%s %s %s' via Avahi" % (name, class_str, type_str))
recs = resolve(name, type_, getone=MDNS_GETONE, timeout=MDNS_TIMEOUT)
if not recs:
dbg('Result: Not found (NXDOMAIN)')
qstate.return_rcode = RCODE_NXDOMAIN
return True
m = DNSMessage(name, type_, class_, PKT_QR | PKT_RD | PKT_RA)
for r in recs:
s = rr2text(r, MDNS_TTL)
dbg('Result: %s' % s)
m.answer.append(s)
if not m.set_return_msg(qstate):
raise Exception("Error in set_return_msg")
if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
raise Exception("Error in storeQueryInCache")
qstate.return_msg.rep.security = 2
qstate.return_rcode = RCODE_NOERROR
return True
#
# It does not appear to be sufficient to check __name__ to determine
# whether we are being run in interactive mode. As a workaround, try
# to import module unboundmodule and if that fails, assume we're being
# run in interactive mode.
#
try:
import unboundmodule
embedded = True
except ImportError:
embedded = False
if __name__ == '__main__' and not embedded:
import sys
def log_info(msg):
print(msg)
def log_err(msg):
print('ERROR: %s' % msg, file=sys.stderr)
if len(sys.argv) != 3:
print('Usage: %s <name> <rr_type>' % sys.argv[0])
sys.exit(2)
name = sys.argv[1]
type_str = sys.argv[2]
try:
type_ = dns.rdatatype.from_text(type_str)
except dns.rdatatype.UnknownRdatatype:
log_err('Unsupported DNS record type "%s"' % type_str)
sys.exit(2)
if dns.rdatatype.is_metatype(type_):
log_err('Meta record type "%s" cannot be resolved via Avahi' % type_str)
sys.exit(2)
init()
try:
recs = resolve(name, type_, getone=MDNS_GETONE, timeout=MDNS_TIMEOUT)
if not len(recs):
print('%s not found (NXDOMAIN)' % name)
sys.exit(1)
for r in recs:
print(rr2text(r, MDNS_TTL))
finally:
deinit()
+1 -1
View File
@@ -78,7 +78,7 @@ def init_standard(id, env):
extra functionality during init.
..note:: This function is preferred by unbound over the old init function.
..note:: The previously accessible configuration options can now be found in
env.cgf.
env.cfg.
"""
log_info("python: inited script {}".format(env.cfg.python_script))
+113 -16
View File
@@ -6,18 +6,18 @@
Copyright (c) 2016, NLnet Labs.
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 organization nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
@@ -43,6 +43,8 @@
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
# intentionally bogus. The reply will contain an empty EDNS option
# with option code 65003.
# Unbound will also log the source address(es) of the client(s) that made
# the request.
# (unbound needs to be validating for this example to work)
# Useful functions:
@@ -70,9 +72,11 @@
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region):
"""Function that will be registered as an inplace callback function.
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering with a resolved query.
:param qinfo: query_info struct;
:param qstate: module qstate. It contains the available opt_lists; It
SHOULD NOT be altered;
@@ -84,16 +88,25 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
"""
log_info("python: called back while replying.")
return True
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region):
"""Function that will be registered as an inplace callback function.
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering from the cache.
:param qinfo: query_info struct;
:param qstate: module qstate. None;
:param rep: reply_info struct;
@@ -105,10 +118,17 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
For demonstration purposes we want to see if EDNS option 65002 is present
and reply with a new value.
"""
log_info("python: called back while answering from cache.")
# Inspect the incoming EDNS options.
@@ -134,9 +154,11 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region):
"""Function that will be registered as an inplace callback function.
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering from local data.
:param qinfo: query_info struct;
:param qstate: module qstate. None;
:param rep: reply_info struct;
@@ -148,7 +170,14 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
"""
log_info("python: called back while replying with local data or chaos"
" reply.")
@@ -156,9 +185,11 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
region):
"""Function that will be registered as an inplace callback function.
region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called when answering with SERVFAIL.
:param qinfo: query_info struct;
:param qstate: module qstate. If not None the relevant opt_lists are
available here;
@@ -171,23 +202,81 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
reply. It can be populated with EDNS options;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_list_out.
:param **kwargs: Dictionary that may contain parameters added in a future
release. Current parameters:
``repinfo``: Reply information for a communication point (comm_reply).
It is None when the callback happens in the mesh
states(modules).
:return: True on success, False on failure.
For demonstration purposes we want to reply with an empty EDNS code '65003'.
For demonstration purposes we want to reply with an empty EDNS code '65003'
and log the IP address(es) of the client(s).
"""
log_info("python: called back while servfail.")
# Append the example ENDS option
b = bytearray.fromhex("")
edns_opt_list_append(opt_list_out, 65003, b, region)
# Log the client(s) IP address(es)
comm_reply = kwargs['repinfo']
if comm_reply:
# If it is not None this callback was called before the query reached
# the mesh states(modules). There is only one client associated with
# this query.
addr = comm_reply.addr
port = comm_reply.port
addr_family = comm_reply.family
log_info("python: Client IP: {}({}), port: {}"
"".format(addr, addr_family, port))
else:
# If it is not None this callback was called while the query is in the
# mesh states(modules). In this case they may be multiple clients
# waiting for this query.
# The following code is the same as with the resip.py example.
rl = qstate.mesh_info.reply_list
while (rl):
if rl.query_reply:
q = rl.query_reply
log_info("python: Client IP: {}({}), port: {}"
"".format(q.addr, q.family, q.port))
rl = rl.next
return True
def inplace_query_callback(qinfo, flags, qstate, addr, zone, region, **kwargs):
"""
Function that will be registered as an inplace callback function.
It will be called before sending a query to a backend server.
:param qinfo: query_info struct;
:param flags: flags of the query;
:param qstate: module qstate. opt_lists are available here;
:param addr: struct sockaddr_storage. Address of the backend server;
:param zone: zone name in binary;
:param region: region to allocate temporary data. Needs to be used when we
want to append a new option to opt_lists.
:param **kwargs: Dictionary that may contain parameters added in a future
release.
"""
log_info("python: outgoing query to {}@{}".format(addr.addr, addr.port))
return True
def init_standard(id, env):
"""New version of the init function.
"""
New version of the init function.
The function's signature is the same as the C counterpart and allows for
extra functionality during init.
..note:: This function is preferred by unbound over the old init function.
..note:: The previously accessible configuration options can now be found in
env.cgf.
env.cfg.
"""
log_info("python: inited script {}".format(env.cfg.python_script))
@@ -211,15 +300,23 @@ def init_standard(id, env):
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env, id):
return False
# Register the inplace_query_callback function as an inplace callback
# before sending a query to a backend server.
if not register_inplace_cb_query(inplace_query_callback, env, id):
return False
return True
def init(id, cfg):
"""Previous version init function.
"""
Previous version of the init function.
..note:: This function is still supported for backwards compatibility when
the init_standard function is missing. When init_standard is
present this function SHOULD be omitted to avoid confusion to the
reader.
"""
return True
+10 -10
View File
@@ -47,7 +47,7 @@ def deinit(id): return True
def inform_super(id, qstate, superqstate, qdata): return True
def operate(id, event, qstate, qdata):
print "Operate", event,"state:",qstate
print("Operate {} state: {}".format(event, qstate))
# Please note that if this module blocks, by moving to the validator
# to validate or iterator to lookup or spawn a subquery to look up,
@@ -61,14 +61,14 @@ def operate(id, event, qstate, qdata):
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA)
#append RR
if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
rl = qstate.mesh_info.reply_list
while (rl):
if rl.query_reply:
q = rl.query_reply
# The TTL of 0 is mandatory, otherwise it ends up in
# the cache, and is returned to other IP addresses.
msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family))
rl = rl.next
rl = qstate.mesh_info.reply_list
while (rl):
if rl.query_reply:
q = rl.query_reply
# The TTL of 0 is mandatory, otherwise it ends up in
# the cache, and is returned to other IP addresses.
msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family))
rl = rl.next
#set qstate.return_msg
if not msg.set_return_msg(qstate):
@@ -90,7 +90,7 @@ def operate(id, event, qstate, qdata):
log_info("pythonmod: iterator module done")
qstate.ext_state[id] = MODULE_FINISHED
return True
log_err("pythonmod: bad event")
qstate.ext_state[id] = MODULE_ERROR
return True
+322 -129
View File
@@ -1,17 +1,40 @@
/*
* interface.i: unbound python module
*/
%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"
%}
%module unboundmodule
%{
/* restore state of warning output, remove the functioncast ignore */
#pragma GCC diagnostic pop
/**
* \file
* This is the interface between the unbound server and a python module
* called to perform operations on queries.
*/
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#include <stdarg.h>
#include "config.h"
#include "util/log.h"
@@ -43,15 +66,21 @@
i = 0;
while (i < len) {
i += name[i] + 1;
i += ((unsigned int)name[i]) + 1;
cnt++;
}
list = PyList_New(cnt);
i = 0; cnt = 0;
while (i < len) {
PyList_SetItem(list, cnt, PyBytes_FromStringAndSize(name + i + 1, name[i]));
i += name[i] + 1;
char buf[LDNS_MAX_LABELLEN+1];
if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
i+(int)((unsigned int)name[i]) < len) {
memmove(buf, name + i + 1, (unsigned int)name[i]);
buf[(unsigned int)name[i]] = 0;
PyList_SetItem(list, cnt, PyString_FromString(buf));
}
i += ((unsigned int)name[i]) + 1;
cnt++;
}
return list;
@@ -159,33 +188,28 @@ struct query_info {
%}
%inline %{
PyObject* dnameAsStr(const char* dname) {
PyObject* dnameAsStr(PyObject* dname) {
char buf[LDNS_MAX_DOMAINLEN+1];
buf[0] = '\0';
dname_str((uint8_t*)dname, buf);
return PyBytes_FromString(buf);
dname_str((uint8_t*)PyBytes_AsString(dname), buf);
return PyString_FromString(buf);
}
%}
%extend query_info {
%pythoncode %{
def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
__swig_getmethods__["qtype_str"] = _get_qtype_str
if _newclass:qtype_str = _swig_property(_get_qtype_str)
qtype_str = property(_get_qtype_str)
def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
__swig_getmethods__["qclass_str"] = _get_qclass_str
if _newclass:qclass_str = _swig_property(_get_qclass_str)
qclass_str = property(_get_qclass_str)
__swig_getmethods__["qname"] = _unboundmodule._get_qname
if _newclass:qname = _swig_property(_unboundmodule._get_qname)
qname = property(_unboundmodule._get_qname)
__swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
qname_list = property(_unboundmodule._get_qname_components)
def _get_qname_str(self): return dnameAsStr(self.qname)
__swig_getmethods__["qname_str"] = _get_qname_str
if _newclass:qname_str = _swig_property(_get_qname_str)
qname_str = property(_get_qname_str)
%}
}
@@ -225,22 +249,17 @@ uint16_t ntohs(uint16_t netshort);
%extend packed_rrset_key {
%pythoncode %{
def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
__swig_getmethods__["type_str"] = _get_type_str
if _newclass:type_str = _swig_property(_get_type_str)
type_str = property(_get_type_str)
def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
__swig_getmethods__["rrset_class_str"] = _get_class_str
if _newclass:rrset_class_str = _swig_property(_get_class_str)
rrset_class_str = property(_get_class_str)
__swig_getmethods__["dname"] = _unboundmodule._get_dname
if _newclass:dname = _swig_property(_unboundmodule._get_dname)
dname = property(_unboundmodule._get_dname)
__swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components
if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components)
dname_list = property(_unboundmodule._get_dname_components)
def _get_dname_str(self): return dnameAsStr(self.dname)
__swig_getmethods__["dname_str"] = _get_dname_str
if _newclass:dname_str = _swig_property(_get_dname_str)
dname_str = property(_get_dname_str)
%}
}
@@ -338,14 +357,11 @@ struct packed_rrset_data {
%extend packed_rrset_data {
%pythoncode %{
def _get_data_rr_len(self): return RRSetData_RRLen(self)
__swig_getmethods__["rr_len"] = _get_data_rr_len
if _newclass:rr_len = _swig_property(_get_data_rr_len)
rr_len = property(_get_data_rr_len)
def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
__swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
rr_ttl = property(_get_data_rr_ttl)
def _get_data_rr_data(self): return RRSetData_RRData(self)
__swig_getmethods__["rr_data"] = _get_data_rr_data
if _newclass:rr_len = _swig_property(_get_data_rr_data)
rr_data = property(_get_data_rr_data)
%}
}
@@ -417,12 +433,166 @@ struct dns_msg {
%extend reply_info {
%pythoncode %{
def _rrset_ref_get(self): return ReplyInfo_Ref(self)
__swig_getmethods__["ref"] = _rrset_ref_get
if _newclass:ref = _swig_property(_rrset_ref_get)
ref = property(_rrset_ref_get)
def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
__swig_getmethods__["rrsets"] = _rrset_rrsets_get
if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
rrsets = property(_rrset_rrsets_get)
%}
}
/* ************************************************************************************ *
Structure sockaddr_storage
* ************************************************************************************ */
struct sockaddr_storage {};
%inline %{
static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
if (ss == NULL) {
return 0;
}
switch (ss->ss_family) {
case AF_INET: return sizeof(struct sockaddr_in);
case AF_INET6: return sizeof(struct sockaddr_in6);
#ifdef HAVE_SYS_UN_H
case AF_UNIX: return sizeof(struct sockaddr_un);
#endif
default:
return 0;
}
}
PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
if (ss == NULL) {
return Py_None;
}
switch (ss->ss_family) {
case AF_INET: return PyUnicode_FromString("ip4");
case AF_INET6: return PyUnicode_FromString("ip6");
case AF_UNIX: return PyUnicode_FromString("unix");
default:
return Py_None;
}
}
PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
const struct sockaddr *sa;
size_t sa_len;
char name[NI_MAXHOST] = {0};
if (ss == NULL) {
return Py_None;
}
sa = (struct sockaddr *)ss;
sa_len = _sockaddr_storage_len(ss);
if (sa_len == 0) {
return Py_None;
}
if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
return Py_None;
}
return PyUnicode_FromString(name);
}
PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
size_t sa_len;
if (ss == NULL) {
return Py_None;
}
sa_len = _sockaddr_storage_len(ss);
if (sa_len == 0) {
return Py_None;
}
if (ss->ss_family == AF_INET) {
const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
}
if (ss->ss_family == AF_INET6) {
const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
}
#ifdef HAVE_SYS_UN_H
if (ss->ss_family == AF_UNIX) {
const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
return PyBytes_FromString(sa->sun_path);
}
#endif
return Py_None;
}
PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
if (ss == NULL) {
return Py_None;
}
if (ss->ss_family == AF_INET) {
const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
return PyInt_FromLong(ntohs(sa4->sin_port));
}
if (ss->ss_family == AF_INET6) {
const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
return PyInt_FromLong(ntohs(sa6->sin6_port));
}
return Py_None;
}
PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
const struct sockaddr_in6 *sa6;
if (ss == NULL || ss->ss_family != AF_INET6) {
return Py_None;
}
sa6 = (struct sockaddr_in6 *)ss;
return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
}
PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
const struct sockaddr_in6 *sa6;
if (ss == NULL || ss->ss_family != AF_INET6) {
return Py_None;
}
sa6 = (struct sockaddr_in6 *)ss;
return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
}
%}
%extend sockaddr_storage {
%pythoncode %{
def _family_get(self): return _sockaddr_storage_family(self)
family = property(_family_get)
def _addr_get(self): return _sockaddr_storage_addr(self)
addr = property(_addr_get)
def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
raw_addr = property(_raw_addr_get)
def _port_get(self): return _sockaddr_storage_port(self)
port = property(_port_get)
def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
flowinfo = property(_flowinfo_get)
def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
scope_id = property(_scope_id_get)
%}
}
@@ -438,54 +608,21 @@ struct mesh_reply {
struct comm_reply query_reply;
};
%rename(_addr) comm_reply::addr;
struct comm_reply {
struct sockaddr_storage addr;
};
%inline %{
PyObject* _comm_reply_addr_get(struct comm_reply* reply) {
char dest[64];
reply_addr2str(reply, dest, 64);
if (dest[0] == 0)
return Py_None;
return PyBytes_FromString(dest);
}
PyObject* _comm_reply_family_get(struct comm_reply* reply) {
int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
switch(af) {
case AF_INET: return PyBytes_FromString("ip4");
case AF_INET6: return PyBytes_FromString("ip6");
case AF_UNIX: return PyBytes_FromString("unix");
}
return Py_None;
}
PyObject* _comm_reply_port_get(struct comm_reply* reply) {
uint16_t port;
port = ntohs(((struct sockaddr_in*)&(reply->addr))->sin_port);
return PyInt_FromLong(port);
}
%}
%extend comm_reply {
%pythoncode %{
def _addr_get(self): return _comm_reply_addr_get(self)
__swig_getmethods__["addr"] = _addr_get
if _newclass:addr = _swig_property(_addr_get)
def _addr_get(self): return _sockaddr_storage_addr(self._addr)
addr = property(_addr_get)
def _port_get(self): return _comm_reply_port_get(self)
__swig_getmethods__["port"] = _port_get
if _newclass:port = _swig_property(_port_get)
def _port_get(self): return _sockaddr_storage_port(self._addr)
port = property(_port_get)
def _family_get(self): return _comm_reply_family_get(self)
__swig_getmethods__["family"] = _family_get
if _newclass:family = _swig_property(_family_get)
def _family_get(self): return _sockaddr_storage_family(self._addr)
family = property(_family_get)
%}
}
@@ -520,12 +657,10 @@ struct edns_option {
%extend edns_option {
%pythoncode %{
def _opt_code_get(self): return _edns_option_opt_code_get(self)
__swig_getmethods__["code"] = _opt_code_get
if _newclass: opt_code = _swig_property(_opt_code_get)
code = property(_opt_code_get)
def _opt_data_get(self): return _edns_option_opt_data_get(self)
__swig_getmethods__["data"] = _opt_data_get
if _newclass: opt_data = _swig_property(_opt_data_get)
data = property(_opt_data_get)
%}
}
@@ -552,11 +687,9 @@ struct edns_data {
%extend edns_data {
%pythoncode %{
def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
__swig_getmethods__["opt_list_iter"] = _opt_list_iter
if _newclass:opt_list_iter = _swig_property(_opt_list_iter)
opt_list_iter = property(_opt_list_iter)
def _opt_list(self): return _edns_data_opt_list_get(self)
__swig_getmethods__["opt_list"] = _opt_list
if _newclass:opt_list = _swig_property(_opt_list)
opt_list = property(_opt_list)
%}
}
@@ -757,34 +890,25 @@ struct module_qstate {
_unboundmodule._ext_state_set(self, id, state)
def __ext_state_get(self): return ExtState(self)
__swig_getmethods__["ext_state"] = __ext_state_get
if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
ext_state = property(__ext_state_get) #, __ext_state_set
def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
__swig_getmethods__["edns_opts_front_in_iter"] = _edns_opts_front_in_iter
if _newclass:edns_opts_front_in_iter = _swig_property(_edns_opts_front_in_iter)
edns_opts_front_in_iter = property(_edns_opts_front_in_iter)
def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
__swig_getmethods__["edns_opts_back_out_iter"] = _edns_opts_back_out_iter
if _newclass:edns_opts_back_out_iter = _swig_property(_edns_opts_back_out_iter)
edns_opts_back_out_iter = property(_edns_opts_back_out_iter)
def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
__swig_getmethods__["edns_opts_back_in_iter"] = _edns_opts_back_in_iter
if _newclass:edns_opts_back_in_iter = _swig_property(_edns_opts_back_in_iter)
edns_opts_back_in_iter = property(_edns_opts_back_in_iter)
def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
__swig_getmethods__["edns_opts_front_out_iter"] = _edns_opts_front_out_iter
if _newclass:edns_opts_front_out_iter = _swig_property(_edns_opts_front_out_iter)
edns_opts_front_out_iter = property(_edns_opts_front_out_iter)
def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
__swig_getmethods__["edns_opts_front_in"] = _edns_opts_front_in
if _newclass:edns_opts_front_in = _swig_property(_edns_opts_front_in)
edns_opts_front_in = property(_edns_opts_front_in)
def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
__swig_getmethods__["edns_opts_back_out"] = _edns_opts_back_out
if _newclass:edns_opts_back_out = _swig_property(_edns_opts_back_out)
edns_opts_back_out = property(_edns_opts_back_out)
def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
__swig_getmethods__["edns_opts_back_in"] = _edns_opts_back_in
if _newclass:edns_opts_back_in = _swig_property(_edns_opts_back_in)
edns_opts_back_in = property(_edns_opts_back_in)
def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
__swig_getmethods__["edns_opts_front_out"] = _edns_opts_front_out
if _newclass:edns_opts_front_out = _swig_property(_edns_opts_front_out)
edns_opts_front_out = property(_edns_opts_front_out)
%}
}
@@ -883,14 +1007,14 @@ struct config_file {
struct config_strlist* local_zones_nodefault;
struct config_strlist* local_data;
int remote_control_enable;
struct config_strlist* control_ifs;
struct config_strlist_head control_ifs;
int control_port;
char* server_key_file;
char* server_cert_file;
char* control_key_file;
char* control_cert_file;
int do_daemonize;
char* python_script;
struct config_strlist* python_script;
};
/* ************************************************************************************ *
@@ -954,35 +1078,28 @@ struct delegpt {
%extend delegpt {
%pythoncode %{
__swig_getmethods__["dname"] = _unboundmodule._get_dp_dname
if _newclass:dname = _swig_property(_unboundmodule._get_dp_dname)
dname = property(_unboundmodule._get_dp_dname)
__swig_getmethods__["dname_list"] = _unboundmodule._get_dp_dname_components
if _newclass:dname_list = _swig_property(_unboundmodule._get_dp_dname_components)
dname_list = property(_unboundmodule._get_dp_dname_components)
def _get_dname_str(self): return dnameAsStr(self.dname)
__swig_getmethods__["dname_str"] = _get_dname_str
if _newclass:dname_str = _swig_property(_get_dname_str)
dname_str = property(_get_dname_str)
%}
}
%extend delegpt_ns {
%pythoncode %{
__swig_getmethods__["dname"] = _unboundmodule._get_dpns_dname
if _newclass:dname = _swig_property(_unboundmodule._get_dpns_dname)
dname = property(_unboundmodule._get_dpns_dname)
__swig_getmethods__["dname_list"] = _unboundmodule._get_dpns_dname_components
if _newclass:dname_list = _swig_property(_unboundmodule._get_dpns_dname_components)
dname_list = property(_unboundmodule._get_dpns_dname_components)
def _get_dname_str(self): return dnameAsStr(self.dname)
__swig_getmethods__["dname_str"] = _get_dname_str
if _newclass:dname_str = _swig_property(_get_dname_str)
dname_str = property(_get_dname_str)
%}
}
%extend delegpt_addr {
%pythoncode %{
def _addr_get(self): return _delegpt_addr_addr_get(self)
__swig_getmethods__["addr"] = _addr_get
if _newclass:addr = _swig_property(_addr_get)
addr = property(_addr_get)
%}
}
@@ -992,6 +1109,7 @@ struct delegpt {
%rename ("MODULE_STATE_INITIAL") "module_state_initial";
%rename ("MODULE_WAIT_REPLY") "module_wait_reply";
%rename ("MODULE_WAIT_MODULE") "module_wait_module";
%rename ("MODULE_RESTART_NEXT") "module_restart_next";
%rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
%rename ("MODULE_ERROR") "module_error";
%rename ("MODULE_FINISHED") "module_finished";
@@ -1000,6 +1118,7 @@ enum module_ext_state {
module_state_initial = 0,
module_wait_reply,
module_wait_module,
module_restart_next,
module_wait_subquery,
module_error,
module_finished
@@ -1081,7 +1200,7 @@ int checkList(PyObject *l)
for (i=0; i < PyList_Size(l); i++)
{
item = PyList_GetItem(l, i);
if (!PyBytes_Check(item))
if (!PyBytes_Check(item) && !PyUnicode_Check(item))
return 0;
}
return 1;
@@ -1096,23 +1215,40 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
PyObject* item;
int i;
size_t len;
char* s;
PyObject* ascstr;
for (i=0; i < PyList_Size(l); i++)
{
ascstr = NULL;
item = PyList_GetItem(l, i);
if(PyObject_TypeCheck(item, &PyBytes_Type)) {
s = PyBytes_AsString(item);
} else {
ascstr = PyUnicode_AsASCIIString(item);
s = PyBytes_AsString(ascstr);
}
len = sldns_buffer_remaining(qb);
if(qsec) {
if(sldns_str2wire_rr_question_buf(PyBytes_AsString(item),
if(sldns_str2wire_rr_question_buf(s,
sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
!= 0)
!= 0) {
if(ascstr)
Py_DECREF(ascstr);
return 0;
}
} else {
if(sldns_str2wire_rr_buf(PyBytes_AsString(item),
if(sldns_str2wire_rr_buf(s,
sldns_buffer_current(qb), &len, NULL, default_ttl,
NULL, 0, NULL, 0) != 0)
NULL, 0, NULL, 0) != 0) {
if(ascstr)
Py_DECREF(ascstr);
return 0;
}
}
if(ascstr)
Py_DECREF(ascstr);
sldns_buffer_skip(qb, len);
sldns_buffer_write_u16_at(qb, count_offset,
@@ -1365,11 +1501,12 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct regional* region, int id, void* python_callback)
struct comm_reply* repinfo, struct regional* region, int id,
void* python_callback)
{
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
PyObject *py_rep, *py_region;
PyObject *result;
PyObject *py_rep, *py_repinfo, *py_region;
PyObject *py_args, *py_kwargs, *result;
int res = 0;
PyGILState_STATE gstate = PyGILState_Ensure();
@@ -1381,15 +1518,21 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
SWIGTYPE_p_p_edns_option, 0);
py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
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);
result = PyObject_CallFunction(func, "OOOiOOO", py_qinfo, py_qstate,
py_rep, rcode, py_edns, py_opt_list_out, py_region);
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}", "repinfo", py_repinfo);
result = PyObject_Call(func, py_args, py_kwargs);
Py_XDECREF(py_edns);
Py_XDECREF(py_qstate);
Py_XDECREF(py_opt_list_out);
Py_XDECREF(py_qinfo);
Py_XDECREF(py_rep);
Py_XDECREF(py_repinfo);
Py_XDECREF(py_region);
Py_XDECREF(py_args);
Py_XDECREF(py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
@@ -1430,6 +1573,54 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
return python_inplace_cb_register(inplace_cb_reply_servfail,
py_cb, env, id);
}
int python_inplace_cb_query_generic(
struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, struct regional* region, int id,
void* python_callback)
{
int res = 0;
PyObject *func = python_callback;
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);
PyObject *py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
PyObject *py_kwargs = Py_BuildValue("{}");
PyObject *result = PyObject_Call(func, py_args, py_kwargs);
if (result) {
res = PyInt_AsLong(result);
}
Py_XDECREF(py_qinfo);
Py_XDECREF(py_qstate);
Py_XDECREF(py_addr);
Py_XDECREF(py_zone);
Py_XDECREF(py_region);
Py_XDECREF(py_args);
Py_XDECREF(py_kwargs);
Py_XDECREF(result);
PyGILState_Release(gstate);
return res;
}
static int register_inplace_cb_query(PyObject* py_cb,
struct module_env* env, int id)
{
int ret = inplace_cb_register(python_inplace_cb_query_generic,
inplace_cb_query, (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,
@@ -1444,3 +1635,5 @@ static int register_inplace_cb_reply_local(PyObject* py_cb,
struct module_env* env, int id);
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);
+221 -44
View File
@@ -64,6 +64,15 @@ typedef struct PyThreadState PyThreadState;
typedef void* PyGILState_STATE;
#endif
/**
* counter for python module instances
* incremented by pythonmod_init(...)
*/
int py_mod_count = 0;
/** Python main thread */
PyThreadState* mainthr;
/**
* Global state for the module.
*/
@@ -72,8 +81,6 @@ struct pythonmod_env {
/** Python script filename. */
const char* fname;
/** Python main thread */
PyThreadState* mainthr;
/** Python module. */
PyObject* module;
@@ -110,13 +117,149 @@ struct pythonmod_qstate {
#include "pythonmod/interface.h"
#endif
/** log python error */
static void
log_py_err(void)
{
char *result = NULL;
const char* iomod = "cStringIO";
PyObject *modStringIO = NULL;
PyObject *modTB = NULL;
PyObject *obFuncStringIO = NULL;
PyObject *obStringIO = NULL;
PyObject *obFuncTB = NULL;
PyObject *argsTB = NULL;
PyObject *obResult = NULL;
PyObject *ascstr = NULL;
PyObject *exc_typ, *exc_val, *exc_tb;
/* Fetch the error state now before we cruch it */
/* exc val contains the error message
* exc tb contains stack traceback and other info. */
PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
PyErr_NormalizeException(&exc_typ, &exc_val, &exc_tb);
/* Import the modules we need - cStringIO and traceback */
modStringIO = PyImport_ImportModule("cStringIO");
if (modStringIO==NULL) {
/* python 1.4 and before */
modStringIO = PyImport_ImportModule("StringIO");
iomod = "StringIO";
}
if (modStringIO==NULL) {
/* python 3 */
modStringIO = PyImport_ImportModule("io");
iomod = "io";
}
if (modStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot ImportModule cStringIO or StringIO or io");
goto cleanup;
}
modTB = PyImport_ImportModule("traceback");
if (modTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot ImportModule traceback");
goto cleanup;
}
/* Construct a cStringIO object */
obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
if (obFuncStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString %s.StringIO", iomod);
goto cleanup;
}
obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
if (obStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot call %s.StringIO()", iomod);
goto cleanup;
}
/* Get the traceback.print_exception function, and call it. */
obFuncTB = PyObject_GetAttrString(modTB, "print_exception");
if (obFuncTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString traceback.print_exception");
goto cleanup;
}
argsTB = Py_BuildValue("OOOOO", (exc_typ ? exc_typ : Py_None),
(exc_val ? exc_val : Py_None), (exc_tb ? exc_tb : Py_None),
Py_None, obStringIO);
if (argsTB==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot BuildValue for print_exception");
goto cleanup;
}
obResult = PyObject_CallObject(obFuncTB, argsTB);
if (obResult==NULL) {
PyErr_Print();
log_err("pythonmod: cannot print exception, "
"call traceback.print_exception() failed");
goto cleanup;
}
/* Now call the getvalue() method in the StringIO instance */
Py_DECREF(obFuncStringIO);
obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
if (obFuncStringIO==NULL) {
log_err("pythonmod: cannot print exception, "
"cannot GetAttrString StringIO.getvalue");
goto cleanup;
}
Py_DECREF(obResult);
obResult = PyObject_CallObject(obFuncStringIO, NULL);
if (obResult==NULL) {
log_err("pythonmod: cannot print exception, "
"call StringIO.getvalue() failed");
goto cleanup;
}
/* And it should be a string all ready to go - duplicate it. */
if (!PyString_Check(obResult) && !PyUnicode_Check(obResult)) {
log_err("pythonmod: cannot print exception, "
"StringIO.getvalue() result did not String_Check"
" or Unicode_Check");
goto cleanup;
}
if(PyString_Check(obResult)) {
result = PyString_AsString(obResult);
} else {
ascstr = PyUnicode_AsASCIIString(obResult);
result = PyBytes_AsString(ascstr);
}
log_err("pythonmod: python error: %s", result);
cleanup:
Py_XDECREF(modStringIO);
Py_XDECREF(modTB);
Py_XDECREF(obFuncStringIO);
Py_XDECREF(obStringIO);
Py_XDECREF(obFuncTB);
Py_XDECREF(argsTB);
Py_XDECREF(obResult);
Py_XDECREF(ascstr);
/* clear the exception, by not restoring it */
/* Restore the exception state */
/* PyErr_Restore(exc_typ, exc_val, exc_tb); */
}
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;
PyGILState_STATE gil;
int init_standard = 1;
int init_standard = 1, i = 0;
#if PY_MAJOR_VERSION < 3
PyObject* PyFileObject = NULL;
#endif
struct config_strlist* cfg_item = env->cfg->python_script;
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
if (!pe)
@@ -128,14 +271,21 @@ int pythonmod_init(struct module_env* env, int id)
env->modinfo[id] = (void*) pe;
/* Initialize module */
pe->fname = env->cfg->python_script;
pe->fname=NULL; i = 0;
while (cfg_item!=NULL) {
if (py_mod_idx==i++) {
pe->fname=cfg_item->str;
break;
}
cfg_item = cfg_item->next;
}
if(pe->fname==NULL || pe->fname[0]==0) {
log_err("pythonmod: no script given.");
log_err("pythonmod[%d]: no script given.", py_mod_idx);
return 0;
}
/* Initialize Python libraries */
if (!Py_IsInitialized())
if (py_mod_count==1 && !Py_IsInitialized())
{
#if PY_MAJOR_VERSION >= 3
wchar_t progname[8];
@@ -151,33 +301,43 @@ int pythonmod_init(struct module_env* env, int id)
Py_Initialize();
PyEval_InitThreads();
SWIG_init();
pe->mainthr = PyEval_SaveThread();
mainthr = PyEval_SaveThread();
}
gil = PyGILState_Ensure();
/* Initialize Python */
PyRun_SimpleString("import sys \n");
PyRun_SimpleString("sys.path.append('.') \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)
{
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
if (py_mod_count==1) {
/* Initialize Python */
PyRun_SimpleString("import sys \n");
PyRun_SimpleString("sys.path.append('.') \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)
{
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
}
}
/* Check Python file load */
if ((script_py = fopen(pe->fname, "r")) == NULL)
/* uses python to open the file, this works on other platforms,
* eg. Windows, to open the file in the correct mode for python */
#if PY_MAJOR_VERSION < 3
PyFileObject = PyFile_FromString((char*)pe->fname, "r");
script_py = PyFile_AsFile(PyFileObject);
#else
script_py = _Py_fopen(pe->fname, "r");
#endif
if (script_py == NULL)
{
log_err("pythonmod: can't open file %s for reading", pe->fname);
PyGILState_Release(gil);
@@ -187,20 +347,38 @@ int pythonmod_init(struct module_env* env, int id)
/* Load file */
pe->module = PyImport_AddModule("__main__");
pe->dict = PyModule_GetDict(pe->module);
pe->data = Py_None;
Py_INCREF(pe->data);
pe->data = PyDict_New();
Py_XINCREF(pe->data);
PyModule_AddObject(pe->module, "mod_env", pe->data);
/* TODO: deallocation of pe->... if an error occurs */
if (PyRun_SimpleFile(script_py, pe->fname) < 0)
{
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
log_err("pythonmod: can't parse Python script %s", pe->fname);
/* print the error to logs too, run it again */
fseek(script_py, 0, SEEK_SET);
/* we don't run the file, like this, because then side-effects
* s = PyRun_File(script_py, pe->fname, Py_file_input,
* PyModule_GetDict(PyImport_AddModule("__main__")), pe->dict);
* could happen (again). Instead we parse the file again to get
* the error string in the logs, for when the daemon has stderr
* removed. SimpleFile run already printed to stderr, for then
* this is called from unbound-checkconf or unbound -dd the user
* has a nice formatted error.
*/
/* ignore the NULL return of _node, it is NULL due to the parse failure
* that we are expecting */
(void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input);
log_py_err();
PyGILState_Release(gil);
fclose(script_py);
return 0;
}
#if PY_MAJOR_VERSION < 3
Py_XDECREF(PyFileObject);
#else
fclose(script_py);
#endif
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL)
{
@@ -244,7 +422,7 @@ int pythonmod_init(struct module_env* env, int id)
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function init");
PyErr_Print();
log_py_err();
Py_XDECREF(res);
Py_XDECREF(py_init_arg);
PyGILState_Release(gil);
@@ -274,7 +452,7 @@ void pythonmod_deinit(struct module_env* env, int id)
res = PyObject_CallFunction(pe->func_deinit, "i", id);
if (PyErr_Occurred()) {
log_err("pythonmod: Exception occurred in function deinit");
PyErr_Print();
log_py_err();
}
/* Free result if any */
Py_XDECREF(res);
@@ -282,9 +460,11 @@ void pythonmod_deinit(struct module_env* env, int id)
Py_XDECREF(pe->data);
PyGILState_Release(gil);
PyEval_RestoreThread(pe->mainthr);
Py_Finalize();
pe->mainthr = NULL;
if(--py_mod_count==0) {
PyEval_RestoreThread(mainthr);
Py_Finalize();
mainthr = NULL;
}
}
pe->fname = NULL;
free(pe);
@@ -312,7 +492,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function inform_super");
PyErr_Print();
log_py_err();
qstate->ext_state[id] = module_error;
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
@@ -342,8 +522,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate));
/* Initialize per query data */
pq->data = Py_None;
Py_INCREF(pq->data);
pq->data = PyDict_New();
}
/* Call operate */
@@ -353,7 +532,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
if (PyErr_Occurred())
{
log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event));
PyErr_Print();
log_py_err();
qstate->ext_state[id] = module_error;
}
else if ((res == NULL) || (!PyObject_IsTrue(res)))
@@ -374,8 +553,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
return;
pq = (struct pythonmod_qstate*)qstate->minfo[id];
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id,
(unsigned long int)pq);
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%p", id, pq);
if(pq != NULL)
{
PyGILState_STATE gil = PyGILState_Ensure();
@@ -391,8 +569,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
size_t pythonmod_get_mem(struct module_env* env, int id)
{
struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id];
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id,
(unsigned long int)pe);
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%p", id, pe);
if(!pe)
return 0;
return sizeof(*pe);
+10 -1
View File
@@ -72,5 +72,14 @@ size_t pythonmod_get_mem(struct module_env* env, int id);
int python_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct regional* region, int id, void* python_callback);
struct comm_reply* repinfo, 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_generic(
struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, struct regional* region, int id,
void* python_callback);
#endif /* PYTHONMOD_H */
+12 -6
View File
@@ -172,7 +172,7 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
if(!(node=respip_find_or_create(set, ipstr, 1)))
return 0;
if(node->action != respip_none) {
log_warn("duplicate response-ip action for '%s', overridden.",
verbose(VERB_QUERY, "duplicate response-ip action for '%s', overridden.",
ipstr);
}
if(strcmp(actnstr, "deny") == 0)
@@ -183,6 +183,8 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
action = respip_inform;
else if(strcmp(actnstr, "inform_deny") == 0)
action = respip_inform_deny;
else if(strcmp(actnstr, "inform_redirect") == 0)
action = respip_inform_redirect;
else if(strcmp(actnstr, "always_transparent") == 0)
action = respip_always_transparent;
else if(strcmp(actnstr, "always_refuse") == 0)
@@ -245,7 +247,8 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
struct packed_rrset_data* pd;
struct sockaddr* sa;
int ret;
if(raddr->action != respip_redirect) {
if(raddr->action != respip_redirect
&& raddr->action != respip_inform_redirect) {
log_err("cannot parse response-ip-data %s: response-ip "
"action for %s is not redirect", rrstr, netblock);
return 0;
@@ -358,6 +361,7 @@ respip_set_apply_cfg(struct respip_set* set, char* const* tagname, int num_tags,
free(pd);
pd = np;
}
addr_tree_init_parents(&set->ip_tree);
return 1;
}
@@ -451,7 +455,7 @@ respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
* This function returns the copied rrset key on success, and NULL on memory
* allocation failure.
*/
struct ub_packed_rrset_key*
static struct ub_packed_rrset_key*
copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
{
struct ub_packed_rrset_key* ck = regional_alloc(region,
@@ -611,8 +615,9 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
* EDNS0 OPT RR in the additional section appended on sending it out),
* so the total number of RRsets is an_numrrsets. */
new_rep = construct_reply_info_base(region, rep->flags,
rep->qdcount, rep->ttl, rep->prefetch_ttl, an_numrrsets,
0, 0, an_numrrsets, sec_status_insecure);
rep->qdcount, rep->ttl, rep->prefetch_ttl,
rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
sec_status_insecure);
if(!new_rep)
return NULL;
if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
@@ -749,7 +754,8 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action,
*new_repp = new_rep;
return 1;
} else if(action == respip_static || action == respip_redirect ||
action == respip_always_nxdomain) {
action == respip_always_nxdomain ||
action == respip_inform_redirect) {
/* Since we don't know about other types of the owner name,
* we generally return NOERROR/NODATA unless an NXDOMAIN action
* is explicitly specified. */
+431 -117
View File
File diff suppressed because it is too large Load Diff
+26 -5
View File
@@ -309,6 +309,9 @@ struct auth_probe {
/** we only want to do lookups for making config work (for notify),
* don't proceed with UDP SOA probe queries */
int only_lookup;
/** we have seen a new lease this scan, because one of the masters
* replied with the current SOA serial version */
int have_new_lease;
/** once notified, or the timeout has been reached. a scan starts. */
/** the scan specific target (notify source), or NULL if none */
@@ -324,6 +327,8 @@ struct auth_probe {
/** the SOA probe udp event.
* on the workers event base. */
struct comm_point* cp;
/** is the cp for ip6 or ip4 */
int cp_is_ip6;
/** timeout for packets.
* on the workers event base. */
struct comm_timer* timer;
@@ -375,6 +380,8 @@ struct auth_transfer {
* data or add of duplicate data). Flag is cleared once the retry
* with axfr is done. */
int ixfr_fail;
/** we saw an ixfr-indicating timeout, count of them */
int ixfr_possible_timeout_count;
/** we are doing IXFR right now */
int on_ixfr;
/** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
@@ -393,6 +400,9 @@ struct auth_transfer {
/** the transfer (TCP) to the master.
* on the workers event base. */
struct comm_point* cp;
/** timeout for the transfer.
* on the workers event base. */
struct comm_timer* timer;
};
/** list of addresses */
@@ -509,12 +519,13 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
* @param qinfo: query info (parsed).
* @param edns: edns info (parsed).
* @param buf: buffer with query ID and flags, also for reply.
* @param repinfo: reply information for a communication point.
* @param temp: temporary storage region.
* @return false if not answered
*/
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf,
struct regional* temp);
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
/**
* Find the auth zone that is above the given qname.
@@ -588,8 +599,14 @@ int auth_zones_notify(struct auth_zones* az, struct module_env* env,
* returns 0 if no soa record in the notify */
int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
/** for the zone and if not already going, starts the probe sequence.
* false if zone cannot be found. This is like a notify arrived and was
* accepted for that zone. */
int auth_zones_startprobesequence(struct auth_zones* az,
struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass);
/** read auth zone from zonefile. caller must lock zone. false on failure */
int auth_zone_read_zonefile(struct auth_zone* z);
int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg);
/** find serial number of zone or false if none (no SOA record) */
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
@@ -635,12 +652,16 @@ int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
struct comm_reply* repinfo);
/** xfer probe timeout callback, part of task_probe */
void auth_xfer_probe_timer_callback(void* arg);
/** xfer transfer timeout callback, part of task_transfer */
void auth_xfer_transfer_timer_callback(void* arg);
/** mesh callback for task_probe on lookup of host names */
void auth_xfer_probe_lookup_callback(void* arg, int rcode,
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
int was_ratelimited);
/** mesh callback for task_transfer on lookup of host names */
void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
int was_ratelimited);
/*
* Compares two 32-bit serial numbers as defined in RFC1982. Returns
+22 -1
View File
@@ -40,6 +40,7 @@
*/
#include "config.h"
#include "iterator/iter_delegpt.h"
#include "iterator/iter_utils.h"
#include "validator/val_nsec.h"
#include "validator/val_utils.h"
#include "services/cache/dns.h"
@@ -109,7 +110,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
}
/** delete message from message cache */
static void
void
msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint16_t flags)
{
@@ -547,6 +548,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
if(r->prefetch_ttl > now)
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
else msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->security = r->security;
msg->rep->an_numrrsets = r->an_numrrsets;
msg->rep->ns_numrrsets = r->ns_numrrsets;
@@ -601,6 +603,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->qdcount = 1;
msg->rep->ttl = d->ttl - now;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->security = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -638,6 +641,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->qdcount = 1;
msg->rep->ttl = d->ttl - now;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->security = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -696,6 +700,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
newd->rr_ttl[0] = newd->ttl;
msg->rep->ttl = newd->ttl;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(newd->ttl);
msg->rep->serve_expired_ttl = newd->ttl + SERVE_EXPIRED_TTL;
sldns_write_uint16(newd->rr_data[0], newlen);
memmove(newd->rr_data[0] + sizeof(uint16_t), newname, newlen);
msg->rep->an_numrrsets ++;
@@ -717,6 +722,19 @@ fill_any(struct module_env* env,
int i, num=6; /* number of RR types to look up */
log_assert(lookup[num] == 0);
if(env->cfg->deny_any) {
/* return empty message */
msg = dns_msg_create(qname, qnamelen, qtype, qclass,
region, 0);
if(!msg) {
return NULL;
}
/* set NOTIMPL for RFC 8482 */
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
msg->rep->security = sec_status_indeterminate;
return msg;
}
for(i=0; i<num; i++) {
/* look up this RR for inclusion in type ANY response */
struct ub_packed_rrset_key* rrset = rrset_cache_lookup(
@@ -897,12 +915,15 @@ dns_cache_lookup(struct module_env* env,
struct dns_msg* msg;
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
&& data->security == sec_status_secure
&& (data->an_numrrsets == 0 ||
ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
&& (msg=tomsg(env, &k, data, region, now, scratch))){
lock_rw_unlock(&e->lock);
msg->qinfo.qname=qname;
msg->qinfo.qname_len=qnamelen;
/* check that DNSSEC really works out */
msg->rep->security = sec_status_unchecked;
iter_scrub_nxdomain(msg);
return msg;
}
lock_rw_unlock(&e->lock);
+12
View File
@@ -238,4 +238,16 @@ struct msgreply_entry* msg_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, time_t now, int wr);
/**
* Remove entry from the message cache. For unwanted entries.
* @param env: with message cache.
* @param qname: query name, in wireformat
* @param qnamelen: length of qname, including terminating 0.
* @param qtype: query type, host order.
* @param qclass: query class, host order.
* @param flags: flags
*/
void msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
uint16_t qtype, uint16_t qclass, uint16_t flags);
#endif /* SERVICES_CACHE_DNS_H */
+80 -26
View File
@@ -41,6 +41,8 @@
#include "config.h"
#include "sldns/rrdef.h"
#include "sldns/str2wire.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "services/cache/infra.h"
#include "util/storage/slabhash.h"
#include "util/storage/lookup3.h"
@@ -215,6 +217,18 @@ static int infra_ratelimit_cfg_insert(struct infra_cache* infra,
return 1;
}
/** setup domain limits tree (0 on failure) */
static int
setup_domain_limits(struct infra_cache* infra, struct config_file* cfg)
{
name_tree_init(&infra->domain_limits);
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
return 0;
}
name_tree_init_parents(&infra->domain_limits);
return 1;
}
struct infra_cache*
infra_create(struct config_file* cfg)
{
@@ -230,23 +244,19 @@ infra_create(struct config_file* cfg)
return NULL;
}
infra->host_ttl = cfg->host_ttl;
name_tree_init(&infra->domain_limits);
infra_dp_ratelimit = cfg->ratelimit;
if(cfg->ratelimit != 0) {
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
&rate_deldatafunc, NULL);
if(!infra->domain_rates) {
infra_delete(infra);
return NULL;
}
/* insert config data into ratelimits */
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
infra_delete(infra);
return NULL;
}
name_tree_init_parents(&infra->domain_limits);
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
&rate_deldatafunc, NULL);
if(!infra->domain_rates) {
infra_delete(infra);
return NULL;
}
/* insert config data into ratelimits */
if(!setup_domain_limits(infra, cfg)) {
infra_delete(infra);
return NULL;
}
infra_ip_ratelimit = cfg->ip_ratelimit;
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
@@ -287,12 +297,28 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
if(!infra)
return infra_create(cfg);
infra->host_ttl = cfg->host_ttl;
infra_dp_ratelimit = cfg->ratelimit;
infra_ip_ratelimit = cfg->ip_ratelimit;
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
sizeof(struct infra_data)+INFRA_BYTES_NAME);
if(maxmem != slabhash_get_size(infra->hosts) ||
cfg->infra_cache_slabs != infra->hosts->size) {
/* divide cachesize by slabs and multiply by slabs, because if the
* cachesize is not an even multiple of slabs, that is the resulting
* size of the slabhash */
if(!slabhash_is_size(infra->hosts, maxmem, cfg->infra_cache_slabs) ||
!slabhash_is_size(infra->domain_rates, cfg->ratelimit_size,
cfg->ratelimit_slabs) ||
!slabhash_is_size(infra->client_ip_rates, cfg->ip_ratelimit_size,
cfg->ip_ratelimit_slabs)) {
infra_delete(infra);
infra = infra_create(cfg);
} else {
/* reapply domain limits */
traverse_postorder(&infra->domain_limits, domain_limit_free,
NULL);
if(!setup_domain_limits(infra, cfg)) {
infra_delete(infra);
return NULL;
}
}
return infra;
}
@@ -784,7 +810,7 @@ static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
}
/** find data item in array for ip addresses */
struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
struct comm_reply* repinfo, int wr)
{
struct ip_rate_key key;
@@ -883,7 +909,8 @@ int infra_rate_max(void* data, time_t now)
}
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow)
size_t namelen, time_t timenow, struct query_info* qinfo,
struct comm_reply* replylist)
{
int lim, max;
struct lruhash_entry* entry;
@@ -906,9 +933,19 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
lock_rw_unlock(&entry->lock);
if(premax < lim && max >= lim) {
char buf[257];
char buf[257], qnm[257], ts[12], cs[12], ip[128];
dname_str(name, buf);
verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim);
dname_str(qinfo->qname, qnm);
sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
ip[0]=0;
if(replylist) {
addr_to_str((struct sockaddr_storage *)&replylist->addr,
replylist->addrlen, ip, sizeof(ip));
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
} else {
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
}
}
return (max < lim);
}
@@ -967,7 +1004,7 @@ infra_get_mem(struct infra_cache* infra)
}
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow)
struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer)
{
int max;
struct lruhash_entry* entry;
@@ -986,11 +1023,28 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
lock_rw_unlock(&entry->lock);
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
char client_ip[128];
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
repinfo->addrlen, client_ip, sizeof(client_ip));
verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip,
infra_ip_ratelimit);
qnm[0]=0;
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
(void)sldns_wire2str_rrquestion_buf(
sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
qnm, sizeof(qnm));
if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
qnm[strlen(qnm)-1] = 0; /*remove newline*/
if(strchr(qnm, '\t'))
*strchr(qnm, '\t') = ' ';
if(strchr(qnm, '\t'))
*strchr(qnm, '\t') = ' ';
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s",
client_ip, infra_ip_ratelimit, qnm);
} else {
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)",
client_ip, infra_ip_ratelimit);
}
}
return (max <= infra_ip_ratelimit);
}
+7 -2
View File
@@ -366,12 +366,15 @@ long long infra_get_host_rto(struct infra_cache* infra,
* @param name: zone name
* @param namelen: zone name length
* @param timenow: what time it is now.
* @param qinfo: for logging, query name.
* @param replylist: for logging, querier's address (if any).
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit or if in the previous second the ratelimit was exceeded.
* Failures like alloc failures are not returned (probably as 1).
*/
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow);
size_t namelen, time_t timenow, struct query_info* qinfo,
struct comm_reply* replylist);
/**
* Decrement the query rate counter for a delegation point.
@@ -410,10 +413,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
* @param infra: infra cache
* @param repinfo: information about client
* @param timenow: what time it is now.
* @param buffer: with query for logging.
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit and the query should be dropped. */
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow);
struct comm_reply* repinfo, time_t timenow,
struct sldns_buffer* buffer);
/**
* Get memory used by the infra cache.
+2 -2
View File
@@ -81,8 +81,8 @@ void rrset_cache_delete(struct rrset_cache* r)
struct rrset_cache* rrset_cache_adjust(struct rrset_cache *r,
struct config_file* cfg, struct alloc_cache* alloc)
{
if(!r || !cfg || cfg->rrset_cache_slabs != r->table.size ||
cfg->rrset_cache_size != slabhash_get_size(&r->table))
if(!r || !cfg || !slabhash_is_size(&r->table, cfg->rrset_cache_size,
cfg->rrset_cache_slabs))
{
rrset_cache_delete(r);
r = rrset_cache_create(cfg, alloc);
+448 -16
View File
@@ -53,6 +53,9 @@
#include "util/config_file.h"
#include "util/net_help.h"
#include "sldns/sbuffer.h"
#include "services/mesh.h"
#include "util/fptr_wlist.h"
#include "util/locks.h"
#ifdef HAVE_NETDB_H
#include <netdb.h>
@@ -70,6 +73,18 @@
/** number of queued TCP connections for listen() */
#define TCP_BACKLOG 256
/** number of simultaneous requests a client can have */
#define TCP_MAX_REQ_SIMULTANEOUS 32
#ifndef THREADS_DISABLED
/** lock on the counter of stream buffer memory */
static lock_basic_type stream_wait_count_lock;
#endif
/** size (in bytes) of stream wait buffers */
static size_t stream_wait_count = 0;
/** is the lock initialised for stream wait buffers */
static int stream_wait_lock_inited = 0;
/**
* Debug print of the getaddrinfo returned address.
* @param addr: the address returned.
@@ -247,6 +262,26 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
}
#endif /* SO_REUSEADDR */
#ifdef SO_REUSEPORT
# ifdef SO_REUSEPORT_LB
/* on FreeBSD 12 we have SO_REUSEPORT_LB that does loadbalance
* like SO_REUSEPORT on Linux. This is what the users want
* with the config option in unbound.conf; if we actually
* need local address and port reuse they'll also need to
* have SO_REUSEPORT set for them, assume it was _LB they want.
*/
if (reuseport && *reuseport &&
setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
#ifdef ENOPROTOOPT
if(errno != ENOPROTOOPT || verbosity >= 3)
log_warn("setsockopt(.. SO_REUSEPORT_LB ..) failed: %s",
strerror(errno));
#endif
/* this option is not essential, we can continue */
*reuseport = 0;
}
# else /* no SO_REUSEPORT_LB */
/* try to set SO_REUSEPORT so that incoming
* queries are distributed evenly among the receiving threads.
* Each thread must have its own socket bound to the same port,
@@ -263,6 +298,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
/* this option is not essential, we can continue */
*reuseport = 0;
}
# endif /* SO_REUSEPORT_LB */
#else
(void)reuseport;
#endif /* defined(SO_REUSEPORT) */
@@ -564,7 +600,12 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
/* detect freebsd jail with no ipv6 permission */
if(family==AF_INET6 && errno==EINVAL)
*noproto = 1;
else if(errno != EADDRINUSE) {
else if(errno != EADDRINUSE &&
!(errno == EACCES && verbosity < 4 && !listen)
#ifdef EADDRNOTAVAIL
&& !(errno == EADDRNOTAVAIL && verbosity < 4 && !listen)
#endif
) {
log_err_addr("can't bind socket", strerror(errno),
(struct sockaddr_storage*)addr, addrlen);
}
@@ -572,7 +613,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
close(s);
#else /* USE_WINSOCK */
if(WSAGetLastError() != WSAEADDRINUSE &&
WSAGetLastError() != WSAEADDRNOTAVAIL) {
WSAGetLastError() != WSAEADDRNOTAVAIL &&
!(WSAGetLastError() == WSAEACCES && verbosity < 4 && !listen)) {
log_err_addr("can't bind socket",
wsa_strerror(WSAGetLastError()),
(struct sockaddr_storage*)addr, addrlen);
@@ -809,9 +851,16 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
#ifdef ENOPROTOOPT
/* squelch ENOPROTOOPT: freebsd server mode with kernel support
disabled, except when verbosity enabled for debugging */
if(errno != ENOPROTOOPT || verbosity >= 3)
if(errno != ENOPROTOOPT || verbosity >= 3) {
#endif
if(errno == EPERM) {
log_warn("Setting TCP Fast Open as server failed: %s ; this could likely be because sysctl net.inet.tcp.fastopen.enabled, net.inet.tcp.fastopen.server_enable, or net.ipv4.tcp_fastopen is disabled", strerror(errno));
} else {
log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
}
#ifdef ENOPROTOOPT
}
#endif
log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
}
#endif
return s;
@@ -1059,7 +1108,7 @@ set_recvpktinfo(int s, int family)
/** see if interface is ssl, its port number == the ssl port number */
static int
if_is_ssl(const char* ifname, const char* port, int ssl_port,
struct config_strlist* tls_additional_ports)
struct config_strlist* tls_additional_port)
{
struct config_strlist* s;
char* p = strchr(ifname, '@');
@@ -1067,7 +1116,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
return 1;
if(p && atoi(p+1) == ssl_port)
return 1;
for(s = tls_additional_ports; s; s = s->next) {
for(s = tls_additional_port; s; s = s->next) {
if(p && atoi(p+1) == atoi(s->str))
return 1;
if(!p && atoi(port) == atoi(s->str))
@@ -1089,7 +1138,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
* @param rcv: receive buffer size for UDP
* @param snd: send buffer size for UDP
* @param ssl_port: ssl service port number
* @param tls_additional_ports: list of additional ssl service port numbers.
* @param tls_additional_port: list of additional ssl service port numbers.
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
* set to false on exit if reuseport failed due to no kernel support.
* @param transparent: set IP_TRANSPARENT socket option.
@@ -1103,7 +1152,7 @@ static int
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
struct addrinfo *hints, const char* port, struct listen_port** list,
size_t rcv, size_t snd, int ssl_port,
struct config_strlist* tls_additional_ports, int* reuseport,
struct config_strlist* tls_additional_port, int* reuseport,
int transparent, int tcp_mss, int freebind, int use_systemd,
int dnscrypt_port)
{
@@ -1170,7 +1219,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
}
if(do_tcp) {
int is_ssl = if_is_ssl(ifname, port, ssl_port,
tls_additional_ports);
tls_additional_port);
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss,
freebind, use_systemd)) == -1) {
@@ -1216,7 +1265,8 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, void* sslctx,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
struct tcl_list* tcp_conn_limit, void* sslctx,
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
{
struct listen_dnsport* front = (struct listen_dnsport*)
@@ -1232,6 +1282,10 @@ listen_create(struct comm_base* base, struct listen_port* ports,
free(front);
return NULL;
}
if(!stream_wait_lock_inited) {
lock_basic_init(&stream_wait_count_lock);
stream_wait_lock_inited = 1;
}
/* create comm points as needed */
while(ports) {
@@ -1243,10 +1297,14 @@ listen_create(struct comm_base* base, struct listen_port* ports,
else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt)
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, bufsize, cb, cb_arg);
tcp_accept_count, tcp_idle_timeout,
tcp_conn_limit, bufsize, front->udp_buff,
cb, cb_arg);
else if(ports->ftype == listen_type_ssl) {
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, bufsize, cb, cb_arg);
tcp_accept_count, tcp_idle_timeout,
tcp_conn_limit, bufsize, front->udp_buff,
cb, cb_arg);
cp->ssl = sslctx;
} else if(ports->ftype == listen_type_udpancil ||
ports->ftype == listen_type_udpancil_dnscrypt)
@@ -1317,6 +1375,10 @@ listen_delete(struct listen_dnsport* front)
#endif
sldns_buffer_free(front->udp_buff);
free(front);
if(stream_wait_lock_inited) {
stream_wait_lock_inited = 0;
lock_basic_destroy(&stream_wait_count_lock);
}
}
struct listen_port*
@@ -1356,7 +1418,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_ports,
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
@@ -1370,7 +1432,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_ports,
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
@@ -1386,7 +1448,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_ports,
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
@@ -1400,7 +1462,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
do_tcp, &hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_ports,
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
@@ -1474,3 +1536,373 @@ void listen_start_accept(struct listen_dnsport* listen)
}
}
struct tcp_req_info*
tcp_req_info_create(struct sldns_buffer* spoolbuf)
{
struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req));
if(!req) {
log_err("malloc failure for new stream outoforder processing structure");
return NULL;
}
memset(req, 0, sizeof(*req));
req->spool_buffer = spoolbuf;
return req;
}
void
tcp_req_info_delete(struct tcp_req_info* req)
{
if(!req) return;
tcp_req_info_clear(req);
/* cp is pointer back to commpoint that owns this struct and
* called delete on us */
/* spool_buffer is shared udp buffer, not deleted here */
free(req);
}
void tcp_req_info_clear(struct tcp_req_info* req)
{
struct tcp_req_open_item* open, *nopen;
struct tcp_req_done_item* item, *nitem;
if(!req) return;
/* free outstanding request mesh reply entries */
open = req->open_req_list;
while(open) {
nopen = open->next;
mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp);
free(open);
open = nopen;
}
req->open_req_list = NULL;
req->num_open_req = 0;
/* free pending writable result packets */
item = req->done_req_list;
while(item) {
nitem = item->next;
lock_basic_lock(&stream_wait_count_lock);
stream_wait_count -= (sizeof(struct tcp_req_done_item)
+item->len);
lock_basic_unlock(&stream_wait_count_lock);
free(item->buf);
free(item);
item = nitem;
}
req->done_req_list = NULL;
req->num_done_req = 0;
req->read_is_closed = 0;
}
void
tcp_req_info_remove_mesh_state(struct tcp_req_info* req, struct mesh_state* m)
{
struct tcp_req_open_item* open, *prev = NULL;
if(!req || !m) return;
open = req->open_req_list;
while(open) {
if(open->mesh_state == m) {
struct tcp_req_open_item* next;
if(prev) prev->next = open->next;
else req->open_req_list = open->next;
/* caller has to manage the mesh state reply entry */
next = open->next;
free(open);
req->num_open_req --;
/* prev = prev; */
open = next;
continue;
}
prev = open;
open = open->next;
}
}
/** setup listening for read or write */
static void
tcp_req_info_setup_listen(struct tcp_req_info* req)
{
int wr = 0;
int rd = 0;
if(req->cp->tcp_byte_count != 0) {
/* cannot change, halfway through */
return;
}
if(!req->cp->tcp_is_reading)
wr = 1;
if(req->num_open_req + req->num_done_req < TCP_MAX_REQ_SIMULTANEOUS &&
!req->read_is_closed)
rd = 1;
if(wr) {
req->cp->tcp_is_reading = 0;
comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
} else if(rd) {
req->cp->tcp_is_reading = 1;
comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
/* and also read it (from SSL stack buffers), so
* no event read event is expected since the remainder of
* the TLS frame is sitting in the buffers. */
req->read_again = 1;
} else {
comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
comm_point_listen_for_rw(req->cp, 0, 0);
}
}
/** remove first item from list of pending results */
static struct tcp_req_done_item*
tcp_req_info_pop_done(struct tcp_req_info* req)
{
struct tcp_req_done_item* item;
log_assert(req->num_done_req > 0 && req->done_req_list);
item = req->done_req_list;
lock_basic_lock(&stream_wait_count_lock);
stream_wait_count -= (sizeof(struct tcp_req_done_item)+item->len);
lock_basic_unlock(&stream_wait_count_lock);
req->done_req_list = req->done_req_list->next;
req->num_done_req --;
return item;
}
/** Send given buffer and setup to write */
static void
tcp_req_info_start_write_buf(struct tcp_req_info* req, uint8_t* buf,
size_t len)
{
sldns_buffer_clear(req->cp->buffer);
sldns_buffer_write(req->cp->buffer, buf, len);
sldns_buffer_flip(req->cp->buffer);
req->cp->tcp_is_reading = 0; /* we are now writing */
}
/** pick up the next result and start writing it to the channel */
static void
tcp_req_pickup_next_result(struct tcp_req_info* req)
{
if(req->num_done_req > 0) {
/* unlist the done item from the list of pending results */
struct tcp_req_done_item* item = tcp_req_info_pop_done(req);
tcp_req_info_start_write_buf(req, item->buf, item->len);
free(item->buf);
free(item);
}
}
/** the read channel has closed */
int
tcp_req_info_handle_read_close(struct tcp_req_info* req)
{
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
/* reset byte count for (potential) partial read */
req->cp->tcp_byte_count = 0;
/* if we still have results to write, pick up next and write it */
if(req->num_done_req != 0) {
tcp_req_pickup_next_result(req);
tcp_req_info_setup_listen(req);
return 1;
}
/* if nothing to do, this closes the connection */
if(req->num_open_req == 0 && req->num_done_req == 0)
return 0;
/* otherwise, we must be waiting for dns resolve, wait with timeout */
req->read_is_closed = 1;
tcp_req_info_setup_listen(req);
return 1;
}
void
tcp_req_info_handle_writedone(struct tcp_req_info* req)
{
/* back to reading state, we finished this write event */
sldns_buffer_clear(req->cp->buffer);
if(req->num_done_req == 0 && req->read_is_closed) {
/* no more to write and nothing to read, close it */
comm_point_drop_reply(&req->cp->repinfo);
return;
}
req->cp->tcp_is_reading = 1;
/* see if another result needs writing */
tcp_req_pickup_next_result(req);
/* see if there is more to write, if not stop_listening for writing */
/* see if new requests are allowed, if so, start_listening
* for reading */
tcp_req_info_setup_listen(req);
}
void
tcp_req_info_handle_readdone(struct tcp_req_info* req)
{
struct comm_point* c = req->cp;
/* we want to read up several requests, unless there are
* pending answers */
req->is_drop = 0;
req->is_reply = 0;
req->in_worker_handle = 1;
sldns_buffer_set_limit(req->spool_buffer, 0);
/* handle the current request */
/* this calls the worker handle request routine that could give
* a cache response, or localdata response, or drop the reply,
* or schedule a mesh entry for later */
fptr_ok(fptr_whitelist_comm_point(c->callback));
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
req->in_worker_handle = 0;
/* there is an answer, put it up. It is already in the
* c->buffer, just send it. */
/* since we were just reading a query, the channel is
* clear to write to */
send_it:
c->tcp_is_reading = 0;
comm_point_stop_listening(c);
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
return;
}
req->in_worker_handle = 0;
/* it should be waiting in the mesh for recursion.
* If mesh failed to add a new entry and called commpoint_drop_reply.
* Then the mesh state has been cleared. */
if(req->is_drop) {
/* the reply has been dropped, stream has been closed. */
return;
}
/* If mesh failed(mallocfail) and called commpoint_send_reply with
* something like servfail then we pick up that reply below. */
if(req->is_reply) {
goto send_it;
}
sldns_buffer_clear(c->buffer);
/* if pending answers, pick up an answer and start sending it */
tcp_req_pickup_next_result(req);
/* if answers pending, start sending answers */
/* read more requests if we can have more requests */
tcp_req_info_setup_listen(req);
}
int
tcp_req_info_add_meshstate(struct tcp_req_info* req,
struct mesh_area* mesh, struct mesh_state* m)
{
struct tcp_req_open_item* item;
log_assert(req && mesh && m);
item = (struct tcp_req_open_item*)malloc(sizeof(*item));
if(!item) return 0;
item->next = req->open_req_list;
item->mesh = mesh;
item->mesh_state = m;
req->open_req_list = item;
req->num_open_req++;
return 1;
}
/** Add a result to the result list. At the end. */
static int
tcp_req_info_add_result(struct tcp_req_info* req, uint8_t* buf, size_t len)
{
struct tcp_req_done_item* last = NULL;
struct tcp_req_done_item* item;
size_t space;
/* see if we have space */
space = sizeof(struct tcp_req_done_item) + len;
lock_basic_lock(&stream_wait_count_lock);
if(stream_wait_count + space > stream_wait_max) {
lock_basic_unlock(&stream_wait_count_lock);
verbose(VERB_ALGO, "drop stream reply, no space left, in stream-wait-size");
return 0;
}
stream_wait_count += space;
lock_basic_unlock(&stream_wait_count_lock);
/* find last element */
last = req->done_req_list;
while(last && last->next)
last = last->next;
/* create new element */
item = (struct tcp_req_done_item*)malloc(sizeof(*item));
if(!item) {
log_err("malloc failure, for stream result list");
return 0;
}
item->next = NULL;
item->len = len;
item->buf = memdup(buf, len);
if(!item->buf) {
free(item);
log_err("malloc failure, adding reply to stream result list");
return 0;
}
/* link in */
if(last) last->next = item;
else req->done_req_list = item;
req->num_done_req++;
return 1;
}
void
tcp_req_info_send_reply(struct tcp_req_info* req)
{
if(req->in_worker_handle) {
/* reply from mesh is in the spool_buffer */
/* copy now, so that the spool buffer is free for other tasks
* before the callback is done */
sldns_buffer_clear(req->cp->buffer);
sldns_buffer_write(req->cp->buffer,
sldns_buffer_begin(req->spool_buffer),
sldns_buffer_limit(req->spool_buffer));
sldns_buffer_flip(req->cp->buffer);
req->is_reply = 1;
return;
}
/* now that the query has been handled, that mesh_reply entry
* should be removed, from the tcp_req_info list,
* the mesh state cleanup removes then with region_cleanup and
* replies_sent true. */
/* see if we can send it straight away (we are not doing
* anything else). If so, copy to buffer and start */
if(req->cp->tcp_is_reading && req->cp->tcp_byte_count == 0) {
/* buffer is free, and was ready to read new query into,
* but we are now going to use it to send this answer */
tcp_req_info_start_write_buf(req,
sldns_buffer_begin(req->spool_buffer),
sldns_buffer_limit(req->spool_buffer));
/* switch to listen to write events */
comm_point_stop_listening(req->cp);
comm_point_start_listening(req->cp, -1,
req->cp->tcp_timeout_msec);
return;
}
/* queue up the answer behind the others already pending */
if(!tcp_req_info_add_result(req, sldns_buffer_begin(req->spool_buffer),
sldns_buffer_limit(req->spool_buffer))) {
/* drop the connection, we are out of resources */
comm_point_drop_reply(&req->cp->repinfo);
}
}
size_t tcp_req_info_get_stream_buffer_size(void)
{
size_t s;
if(!stream_wait_lock_inited)
return stream_wait_count;
lock_basic_lock(&stream_wait_count_lock);
s = stream_wait_count;
lock_basic_unlock(&stream_wait_count_lock);
return s;
}
+137 -3
View File
@@ -47,6 +47,7 @@ struct listen_list;
struct config_file;
struct addrinfo;
struct sldns_buffer;
struct tcl_list;
/**
* Listening for queries structure.
@@ -137,6 +138,8 @@ void listening_ports_free(struct listen_port* list);
* @param bufsize: size of datagram buffer.
* @param tcp_accept_count: max number of simultaneous TCP connections
* from clients.
* @param tcp_idle_timeout: idle timeout for TCP connections in msec.
* @param tcp_conn_limit: TCP connection limit info.
* @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled.
* @param cb: callback function when a request arrives. It is passed
@@ -145,9 +148,10 @@ void listening_ports_free(struct listen_port* list);
* @return: the malloced listening structure, ready for use. NULL on error.
*/
struct listen_dnsport* listen_create(struct comm_base* base,
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
void* sslctx, struct dt_env *dtenv, comm_point_callback_type* cb,
void* cb_arg);
struct listen_port* ports, size_t bufsize,
int tcp_accept_count, int tcp_idle_timeout,
struct tcl_list* tcp_conn_limit, void* sslctx,
struct dt_env *dtenv, comm_point_callback_type* cb, void* cb_arg);
/**
* delete the listening structure
@@ -233,4 +237,134 @@ int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
*/
int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
/**
* TCP request info. List of requests outstanding on the channel, that
* are asked for but not yet answered back.
*/
struct tcp_req_info {
/** the TCP comm point for this. Its buffer is used for read/write */
struct comm_point* cp;
/** the buffer to use to spool reply from mesh into,
* it can then be copied to the result list and written.
* it is a pointer to the shared udp buffer. */
struct sldns_buffer* spool_buffer;
/** are we in worker_handle function call (for recursion callback)*/
int in_worker_handle;
/** is the comm point dropped (by worker handle).
* That means we have to disconnect the channel. */
int is_drop;
/** is the comm point set to send_reply (by mesh new client in worker
* handle), if so answer is available in c.buffer */
int is_reply;
/** read channel has closed, just write pending results */
int read_is_closed;
/** read again */
int read_again;
/** number of outstanding requests */
int num_open_req;
/** list of outstanding requests */
struct tcp_req_open_item* open_req_list;
/** number of pending writeable results */
int num_done_req;
/** list of pending writable result packets, malloced one at a time */
struct tcp_req_done_item* done_req_list;
};
/**
* List of open items in TCP channel
*/
struct tcp_req_open_item {
/** next in list */
struct tcp_req_open_item* next;
/** the mesh area of the mesh_state */
struct mesh_area* mesh;
/** the mesh state */
struct mesh_state* mesh_state;
};
/**
* List of done items in TCP channel
*/
struct tcp_req_done_item {
/** next in list */
struct tcp_req_done_item* next;
/** the buffer with packet contents */
uint8_t* buf;
/** length of the buffer */
size_t len;
};
/**
* Create tcp request info structure that keeps track of open
* requests on the TCP channel that are resolved at the same time,
* and the pending results that have to get written back to that client.
* @param spoolbuf: shared buffer
* @return new structure or NULL on alloc failure.
*/
struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf);
/**
* Delete tcp request structure. Called by owning commpoint.
* Removes mesh entry references and stored results from the lists.
* @param req: the tcp request info
*/
void tcp_req_info_delete(struct tcp_req_info* req);
/**
* Clear tcp request structure. Removes list entries, sets it up ready
* for the next connection.
* @param req: tcp request info structure.
*/
void tcp_req_info_clear(struct tcp_req_info* req);
/**
* Remove mesh state entry from list in tcp_req_info.
* caller has to manage the mesh state reply entry in the mesh state.
* @param req: the tcp req info that has the entry removed from the list.
* @param m: the state removed from the list.
*/
void tcp_req_info_remove_mesh_state(struct tcp_req_info* req,
struct mesh_state* m);
/**
* Handle write done of the last result packet
* @param req: the tcp req info.
*/
void tcp_req_info_handle_writedone(struct tcp_req_info* req);
/**
* Handle read done of a new request from the client
* @param req: the tcp req info.
*/
void tcp_req_info_handle_readdone(struct tcp_req_info* req);
/**
* Add mesh state to the tcp req list of open requests.
* So the comm_reply can be removed off the mesh reply list when
* the tcp channel has to be closed (for other reasons then that that
* request was done, eg. channel closed by client or some format error).
* @param req: tcp req info structure. It keeps track of the simultaneous
* requests and results on a tcp (or TLS) channel.
* @param mesh: mesh area for the state.
* @param m: mesh state to add.
* @return 0 on failure (malloc failure).
*/
int tcp_req_info_add_meshstate(struct tcp_req_info* req,
struct mesh_area* mesh, struct mesh_state* m);
/**
* Send reply on tcp simultaneous answer channel. May queue it up.
* @param req: request info structure.
*/
void tcp_req_info_send_reply(struct tcp_req_info* req);
/** the read channel has closed
* @param req: request. remaining queries are looked up and answered.
* @return zero if nothing to do, just close the tcp.
*/
int tcp_req_info_handle_read_close(struct tcp_req_info* req);
/** get the size of currently used tcp stream wait buffers (in bytes) */
size_t tcp_req_info_get_stream_buffer_size(void);
#endif /* LISTEN_DNSPORT_H */
+106 -46
View File
@@ -464,7 +464,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
return 0;
}
log_assert(z->dclass == rrclass);
if(z->type == local_zone_redirect &&
if((z->type == local_zone_redirect ||
z->type == local_zone_inform_redirect) &&
query_dname_compare(z->name, nm) != 0) {
log_err("local-data in redirect zone must reside at top of zone"
", not at %s", rrstr);
@@ -481,7 +482,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
/* Reject it if we would end up having CNAME and other data (including
* another CNAME) for a redirect zone. */
if(z->type == local_zone_redirect && node->rrsets) {
if((z->type == local_zone_redirect ||
z->type == local_zone_inform_redirect) && node->rrsets) {
const char* othertype = NULL;
if (rrtype == LDNS_RR_TYPE_CNAME)
othertype = "other";
@@ -1146,8 +1148,9 @@ void local_zones_print(struct local_zones* zones)
/** encode answer consisting of 1 rrset */
static int
local_encode(struct query_info* qinfo, struct module_env* env,
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
struct ub_packed_rrset_key* rrset, int ansec, int rcode)
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
int rcode)
{
struct reply_info rep;
uint16_t udpsize;
@@ -1165,23 +1168,22 @@ local_encode(struct query_info* qinfo, struct module_env* env,
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, temp)
|| !reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2),
buf, 0, 0, temp, udpsize, edns,
(int)(edns->bits&EDNS_DO), 0))
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
repinfo, temp) || !reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
*(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
}
return 1;
}
/** encode local error answer */
static void
local_error_encode(struct query_info* qinfo, struct module_env* env,
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
int rcode, int r)
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
struct regional* temp, int rcode, int r)
{
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
@@ -1189,7 +1191,7 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
edns->bits &= EDNS_DO;
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
rcode, edns, temp))
rcode, edns, repinfo, temp))
edns->opt_list = NULL;
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
@@ -1310,7 +1312,8 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
/** answer local data match */
static int
local_data_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf,
struct regional* temp, int labs, struct local_data** ldp,
enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
size_t tag_datas_size, char** tagname, int num_tags)
@@ -1322,7 +1325,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
key.name = qinfo->qname;
key.namelen = qinfo->qname_len;
key.namelabs = labs;
if(lz_type == local_zone_redirect) {
if(lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
@@ -1339,7 +1343,7 @@ local_data_answer(struct local_zone* z, struct module_env* env,
* chain. */
if(qinfo->local_alias)
return 1;
return local_encode(qinfo, env, edns, buf, temp,
return local_encode(qinfo, env, edns, repinfo, buf, temp,
&r, 1, LDNS_RCODE_NOERROR);
}
}
@@ -1354,7 +1358,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
return 0;
/* Special case for alias matching. See local_data_answer(). */
if(lz_type == local_zone_redirect &&
if((lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect) &&
qinfo->qtype != LDNS_RR_TYPE_CNAME &&
lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
qinfo->local_alias =
@@ -1369,34 +1374,66 @@ local_data_answer(struct local_zone* z, struct module_env* env,
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
return 1;
}
if(lz_type == local_zone_redirect) {
if(lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect) {
/* convert rrset name to query name; like a wildcard */
struct ub_packed_rrset_key r = *lr->rrset;
r.rk.dname = qinfo->qname;
r.rk.dname_len = qinfo->qname_len;
return local_encode(qinfo, env, edns, buf, temp, &r, 1,
return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1,
LDNS_RCODE_NOERROR);
}
return local_encode(qinfo, env, edns, buf, temp, lr->rrset, 1,
return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1,
LDNS_RCODE_NOERROR);
}
/**
* See if the local zone does not cover the name, eg. the name is not
* in the zone and the zone is transparent */
static int
local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
int labs)
{
struct local_data key;
struct local_data* ld = NULL;
struct local_rrset* lr = NULL;
if(z->type == local_zone_always_transparent)
return 1;
if(z->type != local_zone_transparent
&& z->type != local_zone_typetransparent
&& z->type != local_zone_inform)
return 0;
key.node.key = &key;
key.name = qinfo->qname;
key.namelen = qinfo->qname_len;
key.namelabs = labs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
if(z->type == local_zone_transparent || z->type == local_zone_inform)
return (ld == NULL);
if(ld)
lr = local_data_find_type(ld, qinfo->qtype, 1);
/* local_zone_typetransparent */
return (lr == NULL);
}
/**
* answer in case where no exact match is found
* @param z: zone for query
* @param env: module environment
* @param qinfo: query
* @param edns: edns from query
* Answer in case where no exact match is found.
* @param z: zone for query.
* @param env: module environment.
* @param qinfo: query.
* @param edns: edns from query.
* @param repinfo: source address for checks. may be NULL.
* @param buf: buffer for answer.
* @param temp: temp region for encoding
* @param temp: temp region for encoding.
* @param ld: local data, if NULL, no such name exists in localdata.
* @param lz_type: type of the local zone
* @param lz_type: type of the local zone.
* @return 1 if a reply is to be sent, 0 if not.
*/
static int
lz_zone_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct local_data* ld, enum localzone_type lz_type)
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
struct local_data* ld, enum localzone_type lz_type)
{
if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
/** no reply at all, signal caller by clearing buffer. */
@@ -1405,11 +1442,12 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
return 1;
} else if(lz_type == local_zone_refuse
|| lz_type == local_zone_always_refuse) {
local_error_encode(qinfo, env, edns, buf, temp,
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
return 1;
} else if(lz_type == local_zone_static ||
lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect ||
lz_type == local_zone_always_nxdomain) {
/* for static, reply nodata or nxdomain
* for redirect, reply nodata */
@@ -1418,12 +1456,13 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
* or using closest match for NSEC.
* or using closest match for returning delegation downwards
*/
int rcode = (ld || lz_type == local_zone_redirect)?
int rcode = (ld || lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect)?
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
if(z->soa)
return local_encode(qinfo, env, edns, buf, temp,
return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa, 0, rcode);
local_error_encode(qinfo, env, edns, buf, temp, rcode,
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA));
return 1;
} else if(lz_type == local_zone_typetransparent
@@ -1438,9 +1477,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
if(ld && ld->rrsets) {
int rcode = LDNS_RCODE_NOERROR;
if(z->soa)
return local_encode(qinfo, env, edns, buf, temp,
return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa, 0, rcode);
local_error_encode(qinfo, env, edns, buf, temp, rcode,
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA));
return 1;
}
@@ -1459,7 +1498,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
dname_str(z->name, zname);
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip,
snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
(unsigned)port);
log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
}
@@ -1543,10 +1582,6 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
(z = local_zones_lookup(view->local_zones,
qinfo->qname, qinfo->qname_len, labs,
qinfo->qclass, qinfo->qtype))) {
if(z->type != local_zone_noview)
verbose(VERB_ALGO,
"using localzone from view: %s",
view->name);
lock_rw_rdlock(&z->lock);
lzt = z->type;
}
@@ -1554,10 +1589,24 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
lock_rw_unlock(&z->lock);
z = NULL;
}
if(z && (lzt == local_zone_transparent ||
lzt == local_zone_typetransparent ||
lzt == local_zone_inform ||
lzt == local_zone_always_transparent) &&
local_zone_does_not_cover(z, qinfo, labs)) {
lock_rw_unlock(&z->lock);
z = NULL;
}
if(view->local_zones && !z && !view->isfirst){
lock_rw_unlock(&view->lock);
return 0;
}
if(z && verbosity >= VERB_ALGO) {
char zname[255+1];
dname_str(z->name, zname);
verbose(VERB_ALGO, "using localzone %s %s from view %s",
zname, local_zone_type2str(lzt), view->name);
}
lock_rw_unlock(&view->lock);
}
if(!z) {
@@ -1570,27 +1619,35 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
return 0;
}
lock_rw_rdlock(&z->lock);
lzt = lz_type(taglist, taglen, z->taglist, z->taglen,
tagactions, tagactionssize, z->type, repinfo,
z->override_tree, &tag, tagname, num_tags);
lock_rw_unlock(&zones->lock);
if(z && verbosity >= VERB_ALGO) {
char zname[255+1];
dname_str(z->name, zname);
verbose(VERB_ALGO, "using localzone %s %s", zname,
local_zone_type2str(lzt));
}
}
if((lzt == local_zone_inform || lzt == local_zone_inform_deny)
&& repinfo)
if((env->cfg->log_local_actions ||
lzt == local_zone_inform ||
lzt == local_zone_inform_deny ||
lzt == local_zone_inform_redirect)
&& repinfo)
lz_inform_print(z, qinfo, repinfo);
if(lzt != local_zone_always_refuse
&& lzt != local_zone_always_transparent
&& lzt != local_zone_always_nxdomain
&& local_data_answer(z, env, qinfo, edns, buf, temp, labs, &ld, lzt,
tag, tag_datas, tag_datas_size, tagname, num_tags)) {
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
lock_rw_unlock(&z->lock);
/* We should tell the caller that encode is deferred if we found
* a local alias. */
return !qinfo->local_alias;
}
r = lz_zone_answer(z, env, qinfo, edns, buf, temp, ld, lzt);
r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
lock_rw_unlock(&z->lock);
return r && !qinfo->local_alias; /* see above */
}
@@ -1608,6 +1665,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_nodefault: return "nodefault";
case local_zone_inform: return "inform";
case local_zone_inform_deny: return "inform_deny";
case local_zone_inform_redirect: return "inform_redirect";
case local_zone_always_transparent: return "always_transparent";
case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain";
@@ -1634,6 +1692,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_inform;
else if(strcmp(type, "inform_deny") == 0)
*t = local_zone_inform_deny;
else if(strcmp(type, "inform_redirect") == 0)
*t = local_zone_inform_redirect;
else if(strcmp(type, "always_transparent") == 0)
*t = local_zone_always_transparent;
else if(strcmp(type, "always_refuse") == 0)
+4
View File
@@ -83,6 +83,8 @@ enum localzone_type {
local_zone_inform,
/** log client address, and block (drop) */
local_zone_inform_deny,
/** log client address, and direct */
local_zone_inform_redirect,
/** resolve normally, even when there is local data */
local_zone_always_transparent,
/** answer with error, even when there is local data */
@@ -491,6 +493,8 @@ enum respip_action {
respip_inform = local_zone_inform,
/** log query source and don't answer query */
respip_inform_deny = local_zone_inform_deny,
/** log query source and redirect */
respip_inform_redirect = local_zone_inform_redirect,
/** resolve normally, even when there is response-ip data */
respip_always_transparent = local_zone_always_transparent,
/** answer with 'refused' response */
+141 -69
View File
@@ -55,11 +55,13 @@
#include "util/fptr_wlist.h"
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "services/localzone.h"
#include "util/data/dname.h"
#include "respip/respip.h"
#include "services/listen_dnsport.h"
/** subtract timers and the values do not overflow or become negative */
static void
@@ -83,7 +85,7 @@ timeval_add(struct timeval* d, const struct timeval* add)
#ifndef S_SPLINT_S
d->tv_sec += add->tv_sec;
d->tv_usec += add->tv_usec;
if(d->tv_usec > 1000000 ) {
if(d->tv_usec >= 1000000 ) {
d->tv_usec -= 1000000;
d->tv_sec++;
}
@@ -352,6 +354,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
int was_detached = 0;
int was_noreply = 0;
int added = 0;
struct sldns_buffer* r_buffer = rep->c->buffer;
if(rep->c->tcp_req_info) {
r_buffer = rep->c->tcp_req_info->spool_buffer;
}
if(!unique)
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
/* does this create a new reply state? */
@@ -385,9 +391,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!s) {
log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
edns->opt_list = NULL;
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
comm_point_send_reply(rep);
return;
@@ -401,9 +407,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(!s->s.edns_opts_front_in) {
log_err("mesh_state_create: out of memory; SERVFAIL");
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
NULL, LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
edns->opt_list = NULL;
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
comm_point_send_reply(rep);
return;
@@ -428,16 +434,23 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
/* add reply to s */
if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
log_err("mesh_new_client: out of memory; SERVFAIL");
servfail_mem:
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
NULL, LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
edns->opt_list = NULL;
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
qinfo, qid, qflags, edns);
comm_point_send_reply(rep);
if(added)
mesh_state_delete(&s->s);
return;
}
if(rep->c->tcp_req_info) {
if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
log_err("mesh_new_client: out of memory add tcpreqinfo");
goto servfail_mem;
}
}
/* update statistics */
if(was_detached) {
log_assert(mesh->num_detached_states > 0);
@@ -631,8 +644,8 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
mesh_run(mesh, e->qstate->mesh_info, event, e);
}
struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags, int prime,
int valrec)
{
@@ -693,6 +706,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
mstate->s.no_cache_lookup = 0;
mstate->s.no_cache_store = 0;
mstate->s.need_refetch = 0;
mstate->s.was_ratelimited = 0;
/* init modules */
for(i=0; i<env->mesh->mods.num; i++) {
@@ -730,9 +744,13 @@ mesh_state_cleanup(struct mesh_state* mstate)
mesh = mstate->s.env->mesh;
/* drop unsent replies */
if(!mstate->replies_sent) {
struct mesh_reply* rep;
struct mesh_reply* rep = mstate->reply_list;
struct mesh_cb* cb;
for(rep=mstate->reply_list; rep; rep=rep->next) {
/* in tcp_req_info, the mstates linked are removed, but
* the reply_list is now NULL, so the remove-from-empty-list
* takes no time and also it does not do the mesh accounting */
mstate->reply_list = NULL;
for(; rep; rep=rep->next) {
comm_point_drop_reply(&rep->query_reply);
mesh->num_reply_addrs--;
}
@@ -740,7 +758,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
mstate->cb_list = cb->next;
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
sec_status_unchecked, NULL);
sec_status_unchecked, NULL, 0);
mesh->num_reply_addrs--;
}
}
@@ -968,7 +986,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
{
int secure;
char* reason = NULL;
/* bogus messages are not made into servfail, sec_status passed
int was_ratelimited = m->s.was_ratelimited;
/* bogus messages are not made into servfail, sec_status passed
* to the callback function */
if(rep && rep->security == sec_status_secure)
secure = 1;
@@ -977,22 +996,23 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
rcode = LDNS_RCODE_SERVFAIL;
if(!rcode && (rep->security == sec_status_bogus ||
rep->security == sec_status_secure_sentinel_fail)) {
if(!(reason = errinf_to_str(&m->s)))
if(!(reason = errinf_to_str_bogus(&m->s)))
rcode = LDNS_RCODE_SERVFAIL;
}
/* send the reply */
if(rcode) {
if(rcode == LDNS_RCODE_SERVFAIL) {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, rcode, &r->edns, m->s.region))
rep, rcode, &r->edns, NULL, m->s.region))
r->edns.opt_list = NULL;
} else {
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
&r->edns, m->s.region))
&r->edns, NULL, m->s.region))
r->edns.opt_list = NULL;
}
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL,
was_ratelimited);
} else {
size_t udp_size = r->edns.udp_size;
sldns_buffer_clear(r->buf);
@@ -1002,7 +1022,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
r->edns.bits &= EDNS_DO;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, m->s.region) ||
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->buf, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
@@ -1010,11 +1030,11 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
{
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
sec_status_unchecked, NULL);
sec_status_unchecked, NULL, 0);
} else {
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
rep->security, reason);
rep->security, reason, was_ratelimited);
}
}
free(reason);
@@ -1027,11 +1047,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
* @param rcode: if not 0, error code.
* @param rep: reply to send (or NULL if rcode is set).
* @param r: reply entry
* @param r_buffer: buffer to use for reply entry.
* @param prev: previous reply, already has its answer encoded in buffer.
* @param prev_buffer: buffer for previous reply.
*/
static void
mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
struct mesh_reply* r, struct mesh_reply* prev)
struct mesh_reply* r, struct sldns_buffer* r_buffer,
struct mesh_reply* prev, struct sldns_buffer* prev_buffer)
{
struct timeval end_time;
struct timeval duration;
@@ -1059,7 +1082,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
* and still reuse the previous answer if they are the same, but that
* would be complicated and error prone for the relatively minor case.
* So we err on the side of safety. */
if(prev && prev->qflags == r->qflags &&
if(prev && prev_buffer && prev->qflags == r->qflags &&
!prev->local_alias && !r->local_alias &&
prev->edns.edns_present == r->edns.edns_present &&
prev->edns.bits == r->edns.bits &&
@@ -1067,28 +1090,26 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
== 0) {
/* if the previous reply is identical to this one, fix ID */
if(prev->query_reply.c->buffer != r->query_reply.c->buffer)
sldns_buffer_copy(r->query_reply.c->buffer,
prev->query_reply.c->buffer);
sldns_buffer_write_at(r->query_reply.c->buffer, 0,
&r->qid, sizeof(uint16_t));
sldns_buffer_write_at(r->query_reply.c->buffer, 12,
r->qname, m->s.qinfo.qname_len);
if(prev_buffer != r_buffer)
sldns_buffer_copy(r_buffer, prev_buffer);
sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
sldns_buffer_write_at(r_buffer, 12, r->qname,
m->s.qinfo.qname_len);
comm_point_send_reply(&r->query_reply);
} else if(rcode) {
m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias;
if(rcode == LDNS_RCODE_SERVFAIL) {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, rcode, &r->edns, m->s.region))
rep, rcode, &r->edns, NULL, m->s.region))
r->edns.opt_list = NULL;
} else {
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
&r->edns, m->s.region))
&r->edns, NULL, m->s.region))
r->edns.opt_list = NULL;
}
error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
r->qid, r->qflags, &r->edns);
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
r->qflags, &r->edns);
comm_point_send_reply(&r->query_reply);
} else {
size_t udp_size = r->edns.udp_size;
@@ -1099,18 +1120,20 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, m->s.region) ||
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
!apply_edns_options(&r->edns, &edns_bak,
m->s.env->cfg, r->query_reply.c,
m->s.region) ||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->query_reply.c->buffer, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
(int)(r->edns.bits & EDNS_DO), secure))
r->qflags, r_buffer, 0, 1, m->s.env->scratch,
udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
secure))
{
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, LDNS_RCODE_SERVFAIL, &r->edns, m->s.region))
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
r->edns.opt_list = NULL;
error_encode(r->query_reply.c->buffer,
LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid,
r->qflags, &r->edns);
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
&m->s.qinfo, r->qid, r->qflags, &r->edns);
}
r->edns = edns_bak;
comm_point_send_reply(&r->query_reply);
@@ -1125,19 +1148,17 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
timehist_insert(m->s.env->mesh->histogram, &duration);
if(m->s.env->cfg->stat_extended) {
uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(r->
query_reply.c->buffer, 2));
uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(
r_buffer, 2));
if(secure) m->s.env->mesh->ans_secure++;
m->s.env->mesh->ans_rcode[ rc ] ++;
if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r->
query_reply.c->buffer)) == 0)
if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r_buffer)) == 0)
m->s.env->mesh->ans_nodata++;
}
/* Log reply sent */
if(m->s.env->cfg->log_replies) {
log_reply_info(0, &m->s.qinfo, &r->query_reply.addr,
r->query_reply.addrlen, duration, 0,
r->query_reply.c->buffer);
r->query_reply.addrlen, duration, 0, r_buffer);
}
}
@@ -1145,9 +1166,19 @@ void mesh_query_done(struct mesh_state* mstate)
{
struct mesh_reply* r;
struct mesh_reply* prev = NULL;
struct sldns_buffer* prev_buffer = NULL;
struct mesh_cb* c;
struct reply_info* rep = (mstate->s.return_msg?
mstate->s.return_msg->rep:NULL);
if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL))
&& mstate->s.env->cfg->log_servfail
&& !mstate->s.env->cfg->val_log_squelch) {
char* err = errinf_to_str_servfail(&mstate->s);
if(err)
log_err("%s", err);
free(err);
}
for(r = mstate->reply_list; r; r = r->next) {
/* if a response-ip address block has been stored the
* information should be logged for each client. */
@@ -1164,9 +1195,19 @@ void mesh_query_done(struct mesh_state* mstate)
if(mstate->s.is_drop)
comm_point_drop_reply(&r->query_reply);
else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info) {
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
prev_buffer = NULL;
}
mesh_send_reply(mstate, mstate->s.return_rcode, rep,
r, prev);
r, r_buffer, prev, prev_buffer);
if(r->query_reply.c->tcp_req_info) {
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
r_buffer = NULL;
}
prev = r;
prev_buffer = r_buffer;
}
}
mstate->replies_sent = 1;
@@ -1197,6 +1238,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
mesh->mods.mod[ref->s->s.curmod]->inform_super));
(*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s,
ref->s->s.curmod, &ref->s->s);
/* copy state that is always relevant to super */
copy_state_to_super(&mstate->s, ref->s->s.curmod, &ref->s->s);
}
}
@@ -1297,30 +1340,24 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
log_assert(!qinfo->local_alias->next && dsrc->count == 1 &&
qinfo->local_alias->rrset->rk.type ==
htons(LDNS_RR_TYPE_CNAME));
/* Technically, we should make a local copy for the owner
* name of the RRset, but in the case of the first (and
* currently only) local alias RRset, the owner name should
* point to the qname of the corresponding query, which should
* be valid throughout the lifetime of this mesh_reply. So
* we can skip copying. */
log_assert(qinfo->local_alias->rrset->rk.dname ==
sldns_buffer_at(rep->c->buffer, LDNS_HEADER_SIZE));
/* we should make a local copy for the owner name of
* the RRset */
r->local_alias->rrset->rk.dname_len =
qinfo->local_alias->rrset->rk.dname_len;
r->local_alias->rrset->rk.dname = regional_alloc_init(
s->s.region, qinfo->local_alias->rrset->rk.dname,
qinfo->local_alias->rrset->rk.dname_len);
if(!r->local_alias->rrset->rk.dname)
return 0;
d = regional_alloc_init(s->s.region, dsrc,
sizeof(struct packed_rrset_data)
+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t));
/* the rrset is not packed, like in the cache, but it is
* individualy allocated with an allocator from localzone. */
d = regional_alloc_zero(s->s.region, sizeof(*d));
if(!d)
return 0;
r->local_alias->rrset->entry.data = d;
d->rr_len = (size_t*)((uint8_t*)d +
sizeof(struct packed_rrset_data));
d->rr_data = (uint8_t**)&(d->rr_len[1]);
d->rr_ttl = (time_t*)&(d->rr_data[1]);
d->rr_len[0] = dsrc->rr_len[0];
d->rr_ttl[0] = dsrc->rr_ttl[0];
d->rr_data[0] = regional_alloc_init(s->s.region,
dsrc->rr_data[0], d->rr_len[0]);
if(!d->rr_data[0])
if(!rrset_insert_rr(s->s.region, d, dsrc->rr_data[0],
dsrc->rr_len[0], dsrc->rr_ttl[0], "CNAME local alias"))
return 0;
} else
r->local_alias = NULL;
@@ -1374,7 +1411,7 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
/* module is looping. Stop it. */
log_err("internal error: looping module (%s) stopped",
mesh->mods.mod[mstate->s.curmod]->name);
log_query_info(VERB_QUERY, "pass error for qstate",
log_query_info(0, "pass error for qstate",
&mstate->s.qinfo);
s = module_error;
}
@@ -1595,3 +1632,38 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
m->prev->next = m->next;
else *fp = m->next;
}
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
struct comm_point* cp)
{
struct mesh_reply* n, *prev = NULL;
n = m->reply_list;
/* when in mesh_cleanup, it sets the reply_list to NULL, so that
* there is no accounting twice */
if(!n) return; /* nothing to remove, also no accounting needed */
while(n) {
if(n->query_reply.c == cp) {
/* unlink it */
if(prev) prev->next = n->next;
else m->reply_list = n->next;
/* delete it, but allocated in m region */
mesh->num_reply_addrs--;
/* prev = prev; */
n = n->next;
continue;
}
prev = n;
n = n->next;
}
/* it was not detached (because it had a reply list), could be now */
if(!m->reply_list && !m->cb_list
&& m->super_set.count == 0) {
mesh->num_detached_states++;
}
/* if not replies any more in mstate, it is no longer a reply_state */
if(!m->reply_list && !m->cb_list) {
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
}
}
+16 -6
View File
@@ -65,7 +65,7 @@ struct respip_client_info;
* Maximum number of mesh state activations. Any more is likely an
* infinite loop in the module. It is then terminated.
*/
#define MESH_MAX_ACTIVATION 3000
#define MESH_MAX_ACTIVATION 10000
/**
* Max number of references-to-references-to-references.. search size.
@@ -223,10 +223,11 @@ struct mesh_reply {
/**
* Mesh result callback func.
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus,
* was_ratelimited);
*/
typedef void (*mesh_cb_func_type)(void*, int, struct sldns_buffer*, enum sec_status,
char*);
typedef void (*mesh_cb_func_type)(void* cb_arg, int rcode, struct sldns_buffer*,
enum sec_status, char* why_bogus, int was_ratelimited);
/**
* Callback to result routine
@@ -242,9 +243,8 @@ struct mesh_cb {
uint16_t qflags;
/** buffer for reply */
struct sldns_buffer* buf;
/** callback routine for results. if rcode != 0 buf has message.
* called as cb(cb_arg, rcode, buf, sec_state);
* called as cb(cb_arg, rcode, buf, sec_state, why_bogus, was_ratelimited);
*/
mesh_cb_func_type cb;
/** user arg for callback */
@@ -633,4 +633,14 @@ void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp,
void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
struct mesh_state** lp);
/**
* Remove mesh reply entry from the reply entry list. Searches for
* the comm_point pointer.
* @param mesh: to update the counters.
* @param m: the mesh state.
* @param cp: the comm_point to remove from the list.
*/
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
struct comm_point* cp);
#endif /* SERVICES_MESH_H */
+17 -2
View File
@@ -60,6 +60,9 @@
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
#ifdef USE_IPSET
#include "ipset/ipset.h"
#endif
/** count number of modules (words) in the string */
static int
@@ -113,8 +116,14 @@ modstack_config(struct module_stack* stack, const char* module_conf)
for(i=0; i<stack->num; i++) {
stack->mod[i] = module_factory(&module_conf);
if(!stack->mod[i]) {
log_err("Unknown value for next module: '%s'",
module_conf);
char md[256];
snprintf(md, sizeof(md), "%s", module_conf);
if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
log_err("Unknown value in module-config, module: '%s'."
" This module is not present (not compiled in),"
" See the list of linked modules with unbound -h",
md);
return 0;
}
}
@@ -139,6 +148,9 @@ module_list_avail(void)
#endif
#ifdef CLIENT_SUBNET
"subnetcache",
#endif
#ifdef USE_IPSET
"ipset",
#endif
"respip",
"validator",
@@ -167,6 +179,9 @@ module_funcs_avail(void)
#endif
#ifdef CLIENT_SUBNET
&subnetmod_get_funcblock,
#endif
#ifdef USE_IPSET
&ipset_get_funcblock,
#endif
&respip_get_funcblock,
&val_get_funcblock,
+151 -105
View File
@@ -48,6 +48,7 @@
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
#include "services/cache/infra.h"
#include "iterator/iterator.h"
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
@@ -62,6 +63,9 @@
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
#include <openssl/x509v3.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
@@ -360,10 +364,17 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
comm_point_close(pend->c);
return 0;
}
verbose(VERB_ALGO, "the query is using TLS encryption, for %s",
(w->tls_auth_name?w->tls_auth_name:"an unauthenticated connection"));
#ifdef USE_WINSOCK
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
#endif
pend->c->ssl_shake_state = comm_ssl_shake_write;
if(w->tls_auth_name) {
#ifdef HAVE_SSL
(void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name);
#endif
}
#ifdef HAVE_SSL_SET1_HOST
if(w->tls_auth_name) {
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
@@ -373,10 +384,30 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
log_err("SSL_set1_host failed");
pend->c->fd = s;
SSL_free(pend->c->ssl);
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
}
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
/* openssl 1.0.2 has this function that can be used for
* set1_host like verification */
if(w->tls_auth_name) {
X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
log_err("X509_VERIFY_PARAM_set1_host failed");
pend->c->fd = s;
SSL_free(pend->c->ssl);
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
}
#else
verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
#endif /* HAVE_SSL_SET1_HOST */
}
w->pkt = NULL;
@@ -751,7 +782,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
}
#endif
if(numavailports == 0) {
if(numavailports == 0 || num_ports == 0) {
log_err("no outgoing ports available");
outside_network_delete(outnet);
return NULL;
@@ -1036,6 +1067,8 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
int freebind = 0;
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
sa.sin6_port = (in_port_t)htons((uint16_t)port);
sa.sin6_flowinfo = 0;
sa.sin6_scope_id = 0;
if(pfxlen != 0) {
freebind = 1;
sai6_putrandom(&sa, pfxlen, rnd);
@@ -1258,6 +1291,13 @@ outnet_tcptimer(void* arg)
} else {
/* it was in use */
struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting;
if(pend->c->ssl) {
#ifdef HAVE_SSL
SSL_shutdown(pend->c->ssl);
SSL_free(pend->c->ssl);
pend->c->ssl = NULL;
#endif
}
comm_point_close(pend->c);
pend->query = NULL;
pend->next_free = outnet->tcp_free;
@@ -1470,7 +1510,6 @@ serviced_delete(struct serviced_query* sq)
/* clear up the pending query */
if(sq->status == serviced_query_UDP_EDNS ||
sq->status == serviced_query_UDP ||
sq->status == serviced_query_PROBE_EDNS ||
sq->status == serviced_query_UDP_EDNS_FRAG ||
sq->status == serviced_query_UDP_EDNS_fallback) {
struct pending* p = (struct pending*)sq->pending;
@@ -1597,15 +1636,7 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
sq->last_rtt = rtt;
verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
if(sq->status == serviced_initial) {
if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) {
/* perform EDNS lame probe - check if server is
* EDNS lame (EDNS queries to it are dropped) */
verbose(VERB_ALGO, "serviced query: send probe to see "
" if use of EDNS causes timeouts");
/* even 700 msec may be too small */
rtt = 1000;
sq->status = serviced_query_PROBE_EDNS;
} else if(vs != -1) {
if(vs != -1) {
sq->status = serviced_query_UDP_EDNS;
} else {
sq->status = serviced_query_UDP;
@@ -1859,7 +1890,7 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
if(!sq->pending) {
/* delete from tree so that a retry by above layer does not
* clash with this entry */
log_err("serviced_tcp_initiate: failed to send tcp query");
verbose(VERB_ALGO, "serviced_tcp_initiate: failed to send tcp query");
serviced_callbacks(sq, NETEVENT_CLOSED, NULL, NULL);
}
}
@@ -1882,7 +1913,7 @@ serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
sq->last_sent_time = *sq->outnet->now_tv;
if(sq->tcp_upstream || sq->ssl_upstream) {
timeout = rtt;
if(rtt >= 376 && rtt < TCP_AUTH_QUERY_TIMEOUT)
if(rtt >= UNKNOWN_SERVER_NICENESS && rtt < TCP_AUTH_QUERY_TIMEOUT)
timeout = TCP_AUTH_QUERY_TIMEOUT;
} else {
timeout = TCP_AUTH_QUERY_TIMEOUT;
@@ -1937,17 +1968,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
struct timeval now = *sq->outnet->now_tv;
int fallback_tcp = 0;
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
int rto = 0;
if(sq->status == serviced_query_PROBE_EDNS) {
/* non-EDNS probe failed; we do not know its status,
* keep trying with EDNS, timeout may not be caused
* by EDNS. */
sq->status = serviced_query_UDP_EDNS;
}
if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
/* fallback to 1480/1280 */
sq->status = serviced_query_UDP_EDNS_FRAG;
@@ -1975,14 +1999,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
return 0;
}
if(rto >= RTT_MAX_TIMEOUT) {
fallback_tcp = 1;
/* UDP does not work, fallback to TCP below */
} else {
serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep);
return 0;
}
} else if(error != NETEVENT_NOERROR) {
}
if(error != NETEVENT_NOERROR) {
/* udp returns error (due to no ID or interface available) */
serviced_callbacks(sq, error, c, rep);
return 0;
@@ -1995,9 +2013,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
#endif
if(!fallback_tcp) {
if( (sq->status == serviced_query_UDP_EDNS
||sq->status == serviced_query_UDP_EDNS_FRAG)
if( (sq->status == serviced_query_UDP_EDNS
||sq->status == serviced_query_UDP_EDNS_FRAG)
&& (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL
@@ -2011,19 +2028,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
}
return 0;
} else if(sq->status == serviced_query_PROBE_EDNS) {
/* probe without EDNS succeeds, so we conclude that this
* host likely has EDNS packets dropped */
log_addr(VERB_DETAIL, "timeouts, concluded that connection to "
"host drops EDNS packets", &sq->addr, sq->addrlen);
/* only store noEDNS in cache if domain is noDNSSEC */
if(!sq->want_dnssec)
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
log_err("Out of memory caching no edns for host");
}
sq->status = serviced_query_UDP;
} else if(sq->status == serviced_query_UDP_EDNS &&
} else if(sq->status == serviced_query_UDP_EDNS &&
!sq->edns_lame_known) {
/* now we know that edns queries received answers store that */
log_addr(VERB_ALGO, "serviced query: EDNS works for",
@@ -2033,7 +2038,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
log_err("Out of memory caching edns works");
}
sq->edns_lame_known = 1;
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
!sq->edns_lame_known && (LDNS_RCODE_WIRE(
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
@@ -2051,12 +2056,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
} else {
log_addr(VERB_ALGO, "serviced query: EDNS fails, but "
"not stored because need DNSSEC for", &sq->addr,
"not stored because need DNSSEC for", &sq->addr,
sq->addrlen);
}
sq->status = serviced_query_UDP;
}
if(now.tv_sec > sq->last_sent_time.tv_sec ||
}
if(now.tv_sec > sq->last_sent_time.tv_sec ||
(now.tv_sec == sq->last_sent_time.tv_sec &&
now.tv_usec > sq->last_sent_time.tv_usec)) {
/* convert from microseconds to milliseconds */
@@ -2072,11 +2077,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
sq->last_rtt, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
}
}
} /* end of if_!fallback_tcp */
}
/* perform TC flag check and TCP fallback after updating our
* cache entries for EDNS status and RTT times */
if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) {
if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer))) {
/* fallback to TCP */
/* this discards partial UDP contents */
if(sq->status == serviced_query_UDP_EDNS ||
@@ -2190,39 +2194,48 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
{
struct sockaddr_storage* addr;
socklen_t addrlen;
int i;
int try;
/* select interface */
if(addr_is_ip6(to_addr, to_addrlen)) {
if(outnet->num_ip6 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip6);
addr = &outnet->ip6_ifs[i].addr;
addrlen = outnet->ip6_ifs[i].addrlen;
} else {
if(outnet->num_ip4 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip4);
addr = &outnet->ip4_ifs[i].addr;
addrlen = outnet->ip4_ifs[i].addrlen;
}
int i, try, pnum;
struct port_if* pif;
/* create fd */
for(try = 0; try<1000; try++) {
int port = 0;
int freebind = 0;
int noproto = 0;
int inuse = 0;
int port = ub_random(outnet->rnd)&0xffff;
int fd = -1;
/* select interface */
if(addr_is_ip6(to_addr, to_addrlen)) {
if(outnet->num_ip6 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip6);
pif = &outnet->ip6_ifs[i];
} else {
if(outnet->num_ip4 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip4);
pif = &outnet->ip4_ifs[i];
}
addr = &pif->addr;
addrlen = pif->addrlen;
pnum = ub_random_max(outnet->rnd, pif->avail_total);
if(pnum < pif->inuse) {
/* port already open */
port = pif->out[pnum]->number;
} else {
/* unused ports in start part of array */
port = pif->avail_ports[pnum - pif->inuse];
}
if(addr_is_ip6(to_addr, to_addrlen)) {
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
sa.sin6_port = (in_port_t)htons((uint16_t)port);
@@ -2268,11 +2281,60 @@ outnet_comm_point_for_udp(struct outside_network* outnet,
return cp;
}
/** setup SSL for comm point */
static int
setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
int fd, char* host)
{
cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
if(!cp->ssl) {
log_err("cannot create SSL object");
return 0;
}
#ifdef USE_WINSOCK
comm_point_tcp_win_bio_cb(cp, cp->ssl);
#endif
cp->ssl_shake_state = comm_ssl_shake_write;
/* https verification */
#ifdef HAVE_SSL_SET1_HOST
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
/* because we set SSL_VERIFY_PEER, in netevent in
* ssl_handshake, it'll check if the certificate
* verification has succeeded */
/* SSL_VERIFY_PEER is set on the sslctx */
/* and the certificates to verify with are loaded into
* it with SSL_load_verify_locations or
* SSL_CTX_set_default_verify_paths */
/* setting the hostname makes openssl verify the
* host name in the x509 certificate in the
* SSL connection*/
if(!SSL_set1_host(cp->ssl, host)) {
log_err("SSL_set1_host failed");
return 0;
}
}
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
/* openssl 1.0.2 has this function that can be used for
* set1_host like verification */
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
log_err("X509_VERIFY_PARAM_set1_host failed");
return 0;
}
}
#else
(void)host;
#endif /* HAVE_SSL_SET1_HOST */
return 1;
}
struct comm_point*
outnet_comm_point_for_tcp(struct outside_network* outnet,
comm_point_callback_type* cb, void* cb_arg,
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
sldns_buffer* query, int timeout)
sldns_buffer* query, int timeout, int ssl, char* host)
{
struct comm_point* cp;
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
@@ -2292,6 +2354,16 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
}
cp->repinfo.addrlen = to_addrlen;
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
/* setup for SSL (if needed) */
if(ssl) {
if(!setup_comm_ssl(cp, outnet, fd, host)) {
log_err("cannot setup XoT");
comm_point_delete(cp);
return NULL;
}
}
/* set timeout on TCP connection */
comm_point_start_listening(cp, fd, timeout);
/* copy scratch buffer to cp->buffer */
@@ -2348,36 +2420,11 @@ outnet_comm_point_for_http(struct outside_network* outnet,
/* setup for SSL (if needed) */
if(ssl) {
cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
if(!cp->ssl) {
if(!setup_comm_ssl(cp, outnet, fd, host)) {
log_err("cannot setup https");
comm_point_delete(cp);
return NULL;
}
#ifdef USE_WINSOCK
comm_point_tcp_win_bio_cb(cp, cp->ssl);
#endif
cp->ssl_shake_state = comm_ssl_shake_write;
/* https verification */
#ifdef HAVE_SSL_SET1_HOST
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
/* because we set SSL_VERIFY_PEER, in netevent in
* ssl_handshake, it'll check if the certificate
* verification has succeeded */
/* SSL_VERIFY_PEER is set on the sslctx */
/* and the certificates to verify with are loaded into
* it with SSL_load_verify_locations or
* SSL_CTX_set_default_verify_paths */
/* setting the hostname makes openssl verify the
* host name in the x509 certificate in the
* SSL connection*/
if(!SSL_set1_host(cp->ssl, host)) {
log_err("SSL_set1_host failed");
comm_point_delete(cp);
return NULL;
}
}
#endif /* HAVE_SSL_SET1_HOST */
}
/* set timeout on TCP connection */
@@ -2482,7 +2529,6 @@ serviced_get_mem(struct serviced_query* sq)
s += sizeof(*sb);
if(sq->status == serviced_query_UDP_EDNS ||
sq->status == serviced_query_UDP ||
sq->status == serviced_query_PROBE_EDNS ||
sq->status == serviced_query_UDP_EDNS_FRAG ||
sq->status == serviced_query_UDP_EDNS_fallback) {
s += sizeof(struct pending);
+3 -3
View File
@@ -359,8 +359,6 @@ struct serviced_query {
serviced_query_TCP_EDNS,
/** TCP without EDNS sent */
serviced_query_TCP,
/** probe to test EDNS lameness (EDNS is dropped) */
serviced_query_PROBE_EDNS,
/** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */
serviced_query_UDP_EDNS_fallback,
/** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */
@@ -572,12 +570,14 @@ struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
* @param timeout: timeout for the TCP connection.
* timeout in milliseconds, or -1 for no (change to the) timeout.
* So seconds*1000.
* @param ssl: set to true for TLS.
* @param host: hostname for host name verification of TLS (or NULL if no TLS).
* @return tcp_out commpoint, or NULL.
*/
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
comm_point_callback_type* cb, void* cb_arg,
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
struct sldns_buffer* query, int timeout);
struct sldns_buffer* query, int timeout, int ssl, char* host);
/**
* Create http commpoint suitable for communication to the destination.
+2 -5
View File
@@ -341,12 +341,9 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 52 */
{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/*53 */
#ifdef DRAFT_RRTYPES
/* 53 */
{LDNS_RR_TYPE_SMIMEA, "SMIMEA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#else
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
#endif
/* 54 */
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
/* 55
* Hip ends with 0 or more Rendezvous Servers represented as dname's.

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