Compare commits

...
134 Commits
Author SHA1 Message Date
Wouter Wijngaards e12d274954 fixup for duplication of NSECs / NSEC3s after following CNAMEs
(esp. wildcard CNAMEs and in-zone CNAMEs that then include nodata or
nxdomain proofs) where the CNAME is followed again to include more NSECs.


git-svn-id: file:///svn/unbound/trunk@787 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 13:41:31 +00:00
Wouter Wijngaards 9ade3e4811 nonRD fix.
git-svn-id: file:///svn/unbound/trunk@786 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 12:06:32 +00:00
Wouter Wijngaards 2c2eaecc6c nonRD fix.
git-svn-id: file:///svn/unbound/trunk@785 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 11:02:01 +00:00
Wouter Wijngaards 16906c53e6 log verbosity
git-svn-id: file:///svn/unbound/trunk@784 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 09:34:06 +00:00
Wouter Wijngaards b6d9b4bfcc CNAME chain marked as NXDOMAIN normalized to unbound preferred format.
git-svn-id: file:///svn/unbound/trunk@783 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 09:13:56 +00:00
Wouter Wijngaards 6bb12a5776 show it.
git-svn-id: file:///svn/unbound/trunk@782 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:41:41 +00:00
Wouter Wijngaards bce6c3405b nodefault test.
git-svn-id: file:///svn/unbound/trunk@781 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:26:57 +00:00
Wouter Wijngaards aa0c26ddec - tests for localdata multiple RR, and implicit zones.
- can specify TXT records for local data.



git-svn-id: file:///svn/unbound/trunk@780 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:10:45 +00:00
Wouter Wijngaards a1cbd214a5 Reduced operation sensitivity of message.
git-svn-id: file:///svn/unbound/trunk@779 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 16:18:09 +00:00
Wouter Wijngaards f64778a893 memory footprint improvements.
git-svn-id: file:///svn/unbound/trunk@778 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 15:52:41 +00:00
Wouter Wijngaards 9d3b5fa30d rfc2308 compliance.
git-svn-id: file:///svn/unbound/trunk@777 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 13:25:11 +00:00
Wouter Wijngaards 99590f93bd test and fixes.
git-svn-id: file:///svn/unbound/trunk@776 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 16:13:16 +00:00
Wouter Wijngaards b72563dcb7 local zone answers.
git-svn-id: file:///svn/unbound/trunk@775 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 13:48:58 +00:00
Wouter Wijngaards 6b0cf42b32 defaults.
git-svn-id: file:///svn/unbound/trunk@774 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 09:30:44 +00:00
Wouter Wijngaards 8df2959959 localzone internal data structures.
git-svn-id: file:///svn/unbound/trunk@773 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-21 16:19:31 +00:00
Wouter Wijngaards 1cda904545 localzon setup.
git-svn-id: file:///svn/unbound/trunk@772 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-20 16:38:41 +00:00
Wouter Wijngaards 416129dedb localzone and localdata configuration setup.
git-svn-id: file:///svn/unbound/trunk@771 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-20 14:48:33 +00:00
Wouter Wijngaards b9c417481b keep tcp address around for acl.
git-svn-id: file:///svn/unbound/trunk@770 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 16:31:22 +00:00
Wouter Wijngaards eda6528c14 access-control
git-svn-id: file:///svn/unbound/trunk@769 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 15:32:55 +00:00
Wouter Wijngaards fc8657c421 unit test for addr_in_common.
git-svn-id: file:///svn/unbound/trunk@767 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 13:21:30 +00:00
Wouter Wijngaards 5f50f5d2b4 unit test for addr_mask.
git-svn-id: file:///svn/unbound/trunk@766 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 13:02:15 +00:00
Wouter Wijngaards 31f803201d port from beta-0.7.1
git-svn-id: file:///svn/unbound/trunk@763 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 11:04:05 +00:00
Wouter Wijngaards ff975871ab fixup leaking unbound daemons.
git-svn-id: file:///svn/unbound/trunk@755 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 09:06:56 +00:00
Wouter Wijngaards 99a9914605 No downcasing for NSEC and RRSIG
git-svn-id: file:///svn/unbound/trunk@754 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 08:55:19 +00:00
Wouter Wijngaards 435fbd1794 acl list setup. 8 to tab in net_help.
git-svn-id: file:///svn/unbound/trunk@753 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 16:25:37 +00:00
Wouter Wijngaards fe09abe4e6 0.8 in trunk for auth features development.
git-svn-id: file:///svn/unbound/trunk@752 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 13:03:04 +00:00
Wouter Wijngaards e900e44f9f todo item is not needed at this time.
git-svn-id: file:///svn/unbound/trunk@750 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 12:53:57 +00:00
Wouter Wijngaards bfbac6bb36 Jakob in Credits.
git-svn-id: file:///svn/unbound/trunk@749 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-15 15:42:10 +00:00
Wouter Wijngaards cc21a1ca9a review fixups.
git-svn-id: file:///svn/unbound/trunk@748 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-15 14:27:47 +00:00
Wouter Wijngaards 919b1ab1b6 authority choices.
git-svn-id: file:///svn/unbound/trunk@747 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-14 15:07:54 +00:00
Wouter Wijngaards ad69492495 to 0.7
git-svn-id: file:///svn/unbound/trunk@745 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-14 13:38:13 +00:00
Wouter Wijngaards 2b2cfd7e4b fixup test for new default.
git-svn-id: file:///svn/unbound/trunk@744 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-14 09:51:22 +00:00
Wouter Wijngaards 84a3dbe660 testbed update.
git-svn-id: file:///svn/unbound/trunk@743 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-14 09:03:51 +00:00
Wouter Wijngaards d7b0d86b09 libevent signal problem has different signal handler registrations, and thus
needs handling in testbound, so that on a good exit, it does the exit.


git-svn-id: file:///svn/unbound/trunk@742 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-13 16:15:04 +00:00
Wouter Wijngaards bce5467f59 remove debug print.
git-svn-id: file:///svn/unbound/trunk@741 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-13 15:53:25 +00:00
Wouter Wijngaards a6ae1d6194 - bugreports to unbound-bugs@nlnetlabs.nl
- fixup testbound so it exits cleanly.
       - cleanup the caches on a reload, so that rrsetID numbers won't clash.


git-svn-id: file:///svn/unbound/trunk@740 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-12 13:58:34 +00:00
Wouter Wijngaards 0ee5532396 Fixup for signal handling. No more dangling unbound processes after
test suite.


git-svn-id: file:///svn/unbound/trunk@739 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-12 11:10:11 +00:00
Wouter Wijngaards 7c5182d3fd review.
git-svn-id: file:///svn/unbound/trunk@738 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-09 22:54:54 +00:00
Wouter Wijngaards d41f40b028 safer default interfaces.
git-svn-id: file:///svn/unbound/trunk@737 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-09 14:15:21 +00:00
Wouter Wijngaards 518e7511d7 default config file location, example conf installed.
git-svn-id: file:///svn/unbound/trunk@736 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-09 13:52:13 +00:00
Wouter Wijngaards 6048ba67fa Ldns fixup.
git-svn-id: file:///svn/unbound/trunk@735 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-09 09:50:48 +00:00
Wouter Wijngaards 0eddfd7528 new L root.
git-svn-id: file:///svn/unbound/trunk@734 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-08 13:02:02 +00:00
Wouter Wijngaards 3ed2f28b76 Fixup chroot (Thanks Jakob).
git-svn-id: file:///svn/unbound/trunk@733 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-08 10:44:30 +00:00
Wouter Wijngaards e9277fc201 harden off has more consequences.
git-svn-id: file:///svn/unbound/trunk@732 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 16:05:55 +00:00
Wouter Wijngaards 5d5f08e4fd fixup test.
git-svn-id: file:///svn/unbound/trunk@731 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 15:45:31 +00:00
Wouter Wijngaards a06131872d Harden dnssec stripped zones.
git-svn-id: file:///svn/unbound/trunk@730 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 15:32:27 +00:00
Wouter Wijngaards d2892aa5ab alloc id overflow handling.
git-svn-id: file:///svn/unbound/trunk@729 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 14:39:50 +00:00
Wouter Wijngaards 27c8952a2c touch up clear and verbose.
git-svn-id: file:///svn/unbound/trunk@728 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 13:22:12 +00:00
Wouter Wijngaards 5b966557cc chroot fixup.
git-svn-id: file:///svn/unbound/trunk@727 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 12:48:37 +00:00
Wouter Wijngaards 734abf9323 Fixup of reload bug.
git-svn-id: file:///svn/unbound/trunk@726 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-01 09:48:20 +00:00
Wouter Wijngaards 2725ad55fc hash clear function.
git-svn-id: file:///svn/unbound/trunk@725 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-31 16:15:44 +00:00
Wouter Wijngaards f79c387f3f - fix horrible oversight in sorting rrset references in a message,
sort per reference key pointer, not on referencepointer itself.
        - pidfile: "/etc/unbound/unbound.pid" is now the default.
        - tests changed to reflect the updated default.


git-svn-id: file:///svn/unbound/trunk@724 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-31 14:46:05 +00:00
Wouter Wijngaards 2e9785cfb5 better chroot support, and also default chroot and userchange.
git-svn-id: file:///svn/unbound/trunk@723 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-31 10:56:31 +00:00
Wouter Wijngaards 75c30382ba Build fix outside sourcedir.
git-svn-id: file:///svn/unbound/trunk@722 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-31 08:30:47 +00:00
Wouter Wijngaards fe44f5918a max ttl option.
git-svn-id: file:///svn/unbound/trunk@721 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-31 07:46:30 +00:00
Wouter Wijngaards 63dc8ffde2 ttl not greedy.
git-svn-id: file:///svn/unbound/trunk@720 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-30 21:40:16 +00:00
Wouter Wijngaards 2bb408e2aa Quieter low verbosity logging.
git-svn-id: file:///svn/unbound/trunk@719 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-30 14:59:01 +00:00
Wouter Wijngaards 0eb3149af5 Assertion incorrect. Compressed packets can be larger.
git-svn-id: file:///svn/unbound/trunk@718 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-30 13:40:43 +00:00
Wouter Wijngaards 298e1fd688 overload mode: too many queries situation is detected and queries are dropped.
git-svn-id: file:///svn/unbound/trunk@717 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-23 14:44:51 +00:00
Wouter Wijngaards 861483ac82 dnssec lame servers are used as last effort.
git-svn-id: file:///svn/unbound/trunk@716 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-23 12:37:18 +00:00
Wouter Wijngaards f92d51b3fe dnssec lameness detection improved to disable detection when not sure.
git-svn-id: file:///svn/unbound/trunk@715 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-23 08:30:21 +00:00
Wouter Wijngaards 633daf4bc7 dnssec lame detection.
git-svn-id: file:///svn/unbound/trunk@714 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-22 15:25:37 +00:00
Wouter Wijngaards b247774236 Detect recursion-lameness.
git-svn-id: file:///svn/unbound/trunk@713 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-22 12:05:46 +00:00
Wouter Wijngaards 63aa7463e8 ISO C
git-svn-id: file:///svn/unbound/trunk@712 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-22 09:14:29 +00:00
Wouter Wijngaards 280352760c Fixup tests.
git-svn-id: file:///svn/unbound/trunk@711 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-22 06:25:46 +00:00
Wouter Wijngaards f8dcdf6e3a And manual entry.
git-svn-id: file:///svn/unbound/trunk@710 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 18:11:04 +00:00
Wouter Wijngaards 2885210384 Donotquery for netblocks.
git-svn-id: file:///svn/unbound/trunk@709 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 18:09:11 +00:00
Wouter Wijngaards 253a6e0143 root-hints can be read from file.
git-svn-id: file:///svn/unbound/trunk@708 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 14:02:53 +00:00
Wouter Wijngaards 90df76f931 nicer error, random() improved.
git-svn-id: file:///svn/unbound/trunk@707 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 12:10:13 +00:00
Wouter Wijngaards 391504fd03 rework ldns-src inclusion.
git-svn-id: file:///svn/unbound/trunk@706 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 10:38:27 +00:00
Jelte Jansen da79cd57d9 hit me baby one more time
git-svn-id: file:///svn/unbound/trunk@705 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 08:37:27 +00:00
Wouter Wijngaards c8c099960a outgoing interfaces setting possible.
git-svn-id: file:///svn/unbound/trunk@704 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 08:32:36 +00:00
Jelte Jansen 3a84f02606 bsd-generated configlexer
git-svn-id: file:///svn/unbound/trunk@703 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 08:11:57 +00:00
Wouter Wijngaards 086b257b1d - lex fix
- unsecure validation neater
- const cast warning removal


git-svn-id: file:///svn/unbound/trunk@702 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-19 08:03:08 +00:00
Wouter Wijngaards f22716c237 Added yacc and lex files.
git-svn-id: file:///svn/unbound/trunk@701 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 22:49:08 +00:00
Wouter Wijngaards c74ae3212b and config.h.in.
git-svn-id: file:///svn/unbound/trunk@700 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 22:40:10 +00:00
Wouter Wijngaards b40163446e configure, ready to go.
git-svn-id: file:///svn/unbound/trunk@699 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 22:38:15 +00:00
Wouter Wijngaards ce11690aa1 keep cache of prealloced blocks.
git-svn-id: file:///svn/unbound/trunk@698 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 22:17:02 +00:00
Wouter Wijngaards 6f49c2fe55 regional nicer, remove region-allocator.
git-svn-id: file:///svn/unbound/trunk@697 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 20:31:43 +00:00
Wouter Wijngaards 63bef95aac regional.
git-svn-id: file:///svn/unbound/trunk@696 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 15:40:31 +00:00
Wouter Wijngaards f768fc1148 Ldns included.
git-svn-id: file:///svn/unbound/trunk@695 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 13:05:41 +00:00
Wouter Wijngaards 8e54424abc Fixup test with shorter timeout values.
git-svn-id: file:///svn/unbound/trunk@694 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 09:33:37 +00:00
Wouter Wijngaards c41d12bb94 Tests update.
git-svn-id: file:///svn/unbound/trunk@693 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 09:24:57 +00:00
Wouter Wijngaards 268ada0d33 errors have addresses with them.
git-svn-id: file:///svn/unbound/trunk@692 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-18 09:04:55 +00:00
Wouter Wijngaards 907ab3d99a failover to next server.
git-svn-id: file:///svn/unbound/trunk@691 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 19:23:01 +00:00
Wouter Wijngaards f12875c910 unit test fix.
git-svn-id: file:///svn/unbound/trunk@690 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 17:43:00 +00:00
Wouter Wijngaards 482658b1cc Faster timeouts, based on extracts of our logs.
git-svn-id: file:///svn/unbound/trunk@689 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 17:40:35 +00:00
Wouter Wijngaards 75792c34dc fixup insecure glue on referrals.
git-svn-id: file:///svn/unbound/trunk@688 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 15:48:54 +00:00
Wouter Wijngaards be0bdf0260 fixup test, less logging.
git-svn-id: file:///svn/unbound/trunk@687 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 14:49:12 +00:00
Wouter Wijngaards 08549c7610 remove warning.
git-svn-id: file:///svn/unbound/trunk@686 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 14:27:45 +00:00
Wouter Wijngaards 108539c94c fixup crashy.
git-svn-id: file:///svn/unbound/trunk@685 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 14:22:14 +00:00
Wouter Wijngaards a4d4d0fe3a no debug on low verbosity.
git-svn-id: file:///svn/unbound/trunk@684 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 14:10:46 +00:00
Wouter Wijngaards 9e732da50b Arc4random.
git-svn-id: file:///svn/unbound/trunk@683 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 12:08:34 +00:00
Wouter Wijngaards fe33f7c72c resolution fix.
git-svn-id: file:///svn/unbound/trunk@682 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-17 07:34:13 +00:00
Wouter Wijngaards 631ccb58bf size_t no underflow.
git-svn-id: file:///svn/unbound/trunk@681 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-16 14:39:27 +00:00
Wouter Wijngaards 189fafa1da buffer overflow code audit.
git-svn-id: file:///svn/unbound/trunk@680 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-16 13:03:57 +00:00
Wouter Wijngaards 4260a18fb1 assertions, zero termination for gethostname, log_hex without malloc.
git-svn-id: file:///svn/unbound/trunk@679 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-16 12:26:09 +00:00
Wouter Wijngaards 79f840acd4 require ldns-testns.
git-svn-id: file:///svn/unbound/trunk@678 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-15 14:47:22 +00:00
Wouter Wijngaards fed59bca84 fixup addr6 check.
git-svn-id: file:///svn/unbound/trunk@677 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-15 14:42:37 +00:00
Wouter Wijngaards aecdb781fc Fixup compression, and test for byteformat compression results.
git-svn-id: file:///svn/unbound/trunk@676 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-15 14:19:17 +00:00
Wouter Wijngaards bef17e9e7c fixup ip6 tcp.
git-svn-id: file:///svn/unbound/trunk@675 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-15 09:10:26 +00:00
Wouter Wijngaards 25da698bf1 disable rpath option.
git-svn-id: file:///svn/unbound/trunk@674 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-11 07:34:44 +00:00
Wouter Wijngaards 3aea7c2630 Fixup tests.
git-svn-id: file:///svn/unbound/trunk@673 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-10 09:33:27 +00:00
Wouter Wijngaards d4424931f4 no more AD bits, except when DO is set.
git-svn-id: file:///svn/unbound/trunk@672 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 15:33:40 +00:00
Wouter Wijngaards a5ac86f410 Fixup event callback checks.
git-svn-id: file:///svn/unbound/trunk@671 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 12:04:13 +00:00
Wouter Wijngaards aed61e4d8a whitelist does not work on events, due to deletions.
git-svn-id: file:///svn/unbound/trunk@670 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 11:58:58 +00:00
Wouter Wijngaards c46e1a1ee8 cleaner.
git-svn-id: file:///svn/unbound/trunk@669 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 07:53:35 +00:00
Wouter Wijngaards 2bfe2d5fe3 plan changes.
git-svn-id: file:///svn/unbound/trunk@668 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 07:46:57 +00:00
Wouter Wijngaards 75bfcb8c91 No early logfile open.
git-svn-id: file:///svn/unbound/trunk@667 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 07:43:32 +00:00
Wouter Wijngaards f4049b54c4 logfile first open bad permissions.
git-svn-id: file:///svn/unbound/trunk@666 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-09 07:11:14 +00:00
Wouter Wijngaards 9fec5d86d3 forgot whitelist entry.
git-svn-id: file:///svn/unbound/trunk@665 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-08 09:00:13 +00:00
Wouter Wijngaards f856eef411 fix warning on solaris.
git-svn-id: file:///svn/unbound/trunk@664 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 13:13:48 +00:00
Wouter Wijngaards 24d1ed15c4 please gcc more.
git-svn-id: file:///svn/unbound/trunk@663 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 13:02:50 +00:00
Wouter Wijngaards 26c4e7a182 please gcc on BSD.
git-svn-id: file:///svn/unbound/trunk@662 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 12:57:24 +00:00
Wouter Wijngaards 8e55996b7c function pointer whitelist for module operations. completing fptr work.
git-svn-id: file:///svn/unbound/trunk@661 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 12:42:25 +00:00
Wouter Wijngaards 2a547a35a7 function pointer whitelists on data types.
git-svn-id: file:///svn/unbound/trunk@660 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 11:41:12 +00:00
Wouter Wijngaards 9a60182c86 fptr whitelist network code callbacks.
git-svn-id: file:///svn/unbound/trunk@659 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-05 08:05:06 +00:00
Wouter Wijngaards 107a915c67 unbreak trunk.
git-svn-id: file:///svn/unbound/trunk@658 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-04 15:24:20 +00:00
Wouter Wijngaards 41e847df18 security audit changes.
git-svn-id: file:///svn/unbound/trunk@657 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-04 15:10:11 +00:00
Wouter Wijngaards 7ccfb10392 fixup nasty cache overwriting bug.
git-svn-id: file:///svn/unbound/trunk@656 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-03 19:11:50 +00:00
Wouter Wijngaards d4614cf1ce fixup cname out of unsec zone.
git-svn-id: file:///svn/unbound/trunk@655 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-03 13:33:23 +00:00
Wouter Wijngaards a740dfe195 Fixup and test.
git-svn-id: file:///svn/unbound/trunk@654 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-03 12:20:55 +00:00
Wouter Wijngaards a73089c5f0 loopfix.
git-svn-id: file:///svn/unbound/trunk@653 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-03 08:36:47 +00:00
Wouter Wijngaards 759f666177 regress test for CNAMEd address for nameserver.
git-svn-id: file:///svn/unbound/trunk@652 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-03 06:46:26 +00:00
Wouter Wijngaards e7883b13f4 crash fixup.
git-svn-id: file:///svn/unbound/trunk@651 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-01 14:55:08 +00:00
Wouter Wijngaards f0015b8919 skip unused tests.
git-svn-id: file:///svn/unbound/trunk@650 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-10-01 12:16:19 +00:00
Wouter Wijngaards 1115d50dce unbound-checkconf test.
git-svn-id: file:///svn/unbound/trunk@649 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-28 14:33:35 +00:00
Wouter Wijngaards dc34bb36b3 do lint, depend.
git-svn-id: file:///svn/unbound/trunk@648 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-26 15:01:22 +00:00
Wouter Wijngaards 8f8627a0c3 unbound-checkconf.
git-svn-id: file:///svn/unbound/trunk@647 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-26 13:39:49 +00:00
Wouter Wijngaards c2f8d43f9d fixup tests.
git-svn-id: file:///svn/unbound/trunk@646 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-26 11:29:37 +00:00
Wouter Wijngaards 6a482dc7f2 fixup test.
git-svn-id: file:///svn/unbound/trunk@645 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-26 11:15:42 +00:00
Wouter Wijngaards bc9f482b2a syslog feature.
git-svn-id: file:///svn/unbound/trunk@644 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-26 10:19:28 +00:00
Wouter Wijngaards 8659118a5e done items.
git-svn-id: file:///svn/unbound/trunk@643 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-25 14:01:30 +00:00
Wouter Wijngaards 01db268dff 0.5 release tag.
git-svn-id: file:///svn/unbound/trunk@642 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-09-25 13:00:26 +00:00
225 changed files with 52758 additions and 2511 deletions
+80 -39
View File
@@ -28,12 +28,13 @@ doxygen=@doxygen@
libtool=@libtool@
ldnsdir=@ldnsdir@
staticexe=@staticexe@
configfile=@ub_conf_file@
YACC=@YACC@
LEX=@LEX@
CC=@CC@
CPPFLAGS=-I. @CPPFLAGS@ @DEFS@
CFLAGS=-I. @CFLAGS@
CPPFLAGS=-I$(srcdir) @CPPFLAGS@ @DEFS@
CFLAGS=@CFLAGS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
LIBOBJS=@LIBOBJS@
@@ -46,38 +47,46 @@ endif
BUILD=build/
LINT=splint
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list
# compat with openssl linux edition.
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned
INSTALL=$(srcdir)/install-sh
COMMON_SRC=$(wildcard services/*.c services/cache/*.c util/*.c \
util/data/*.c util/storage/*.c iterator/*.c validator/*.c) \
COMMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/services/*.c \
$(srcdir)/services/cache/*.c $(srcdir)/util/*.c \
$(srcdir)/util/data/*.c $(srcdir)/util/storage/*.c \
$(srcdir)/iterator/*.c $(srcdir)/validator/*.c)) \
util/configparser.c util/configlexer.c testcode/checklocks.c
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
UNITTEST_SRC=$(wildcard testcode/unit*.c) testcode/readhex.c \
testcode/ldns-testpkts.c $(COMMON_SRC)
UNITTEST_SRC=$(patsubst $(srcdir)/%,%, \
$(wildcard $(srcdir)/testcode/unit*.c)) \
testcode/readhex.c testcode/ldns-testpkts.c checkconf/worker_cb.c \
$(COMMON_SRC)
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
DAEMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/daemon/*.c)) \
$(COMMON_SRC)
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
CHECKCONF_SRC=checkconf/unbound-checkconf.c checkconf/worker_cb.c $(COMMON_SRC)
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \
testcode/fake_event.c $(filter-out util/netevent.c \
daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c \
services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
LOCKVERIFY_SRC=testcode/lock_verify.c $(COMMON_SRC)
LOCKVERIFY_SRC=testcode/lock_verify.c checkconf/worker_cb.c $(COMMON_SRC)
LOCKVERIFY_OBJ=$(addprefix $(BUILD),$(LOCKVERIFY_SRC:.c=.o)) $(COMPAT_OBJ)
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c $(COMMON_SRC)
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c checkconf/worker_cb.c \
$(COMMON_SRC)
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.o)) $(COMPAT_OBJ)
SIGNIT_SRC=testcode/signit.c $(COMMON_SRC)
SIGNIT_SRC=testcode/signit.c checkconf/worker_cb.c $(COMMON_SRC)
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.o)) $(COMPAT_OBJ)
MEMSTATS_SRC=testcode/memstats.c $(COMMON_SRC)
MEMSTATS_SRC=testcode/memstats.c checkconf/worker_cb.c $(COMMON_SRC)
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.o)) $(COMPAT_OBJ)
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
$(MEMSTATS_SRC)
$(MEMSTATS_SRC) $(CHECKCONF_SRC)
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \
$(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
@@ -85,47 +94,62 @@ COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS)
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS)
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -release $(VERSION)
.PHONY: clean realclean doc lint all install uninstall tests test download_ldns strip
$(BUILD)%.o: $(srcdir)/%.c
$(INFO) Build $<
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
@if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
$Q$(COMPILE) -c $< -o $@
.PHONY: clean realclean doc lint all install uninstall tests test
all: $(COMMON_OBJ) unbound unbound-checkconf
all: $(COMMON_OBJ) unbound
tests: unittest testbound lock-verify pktview signit memstats
tests: all unittest testbound lock-verify pktview signit memstats
test: tests
bash testcode/do-tests.sh
unbound: $(DAEMON_OBJ)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
ifeq ($(patsubst ldns-src%,ldns-src,$(ldnsdir)),ldns-src)
ldnslib=$(ldnsdir)/lib/libldns.a
$(ldnslib):
@if test ! -z "$(ldnsdir)"; \
then (cd $(ldnsdir) && $(MAKE)); fi
else
ldnslib=
endif
unittest: $(UNITTEST_OBJ)
unbound: $(DAEMON_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(DAEMON_OBJ)) $(LIBS)
testbound: $(TESTBOUND_OBJ)
unbound-checkconf: $(CHECKCONF_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(CHECKCONF_OBJ)) $(LIBS)
lock-verify: $(LOCKVERIFY_OBJ)
unittest: $(UNITTEST_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(UNITTEST_OBJ)) $(LIBS)
pktview: $(PKTVIEW_OBJ)
testbound: $(TESTBOUND_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(TESTBOUND_OBJ)) $(LIBS)
signit: $(SIGNIT_OBJ)
lock-verify: $(LOCKVERIFY_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(LOCKVERIFY_OBJ)) $(LIBS)
memstats: $(MEMSTATS_OBJ)
pktview: $(PKTVIEW_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
$Q$(LINK) -o $@ $(sort $(PKTVIEW_OBJ)) $(LIBS)
signit: $(SIGNIT_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $(sort $(SIGNIT_OBJ)) $(LIBS)
memstats: $(MEMSTATS_OBJ) $(ldnslib)
$(INFO) Link $@
$Q$(LINK) -o $@ $(sort $(MEMSTATS_OBJ)) $(LIBS)
#testcode/ldns-testpkts.c: $(ldnsdir)/examples/ldns-testpkts.c \
# $(ldnsdir)/examples/ldns-testpkts.h
@@ -136,8 +160,7 @@ util/config_file.c: util/configparser.h
util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
$(INFO) Lex $<
ifeq "$(strip $(LEX))" ":"
$Qecho "Need to rebuild lexer, but no lex program"
exit 1
$Qecho "rebuild lexer, but no lex program, skipped"
else
@if test ! -d util; then $(INSTALL) -d util; fi
$Qecho "#include \"util/configyyrename.h\"" > $@
@@ -157,6 +180,7 @@ realclean: clean
rm -f config.status config.log config.h.in config.h
rm -f configure config.sub config.guess ltmain.sh aclocal.m4 libtool
rm -f util/configlexer.c util/configparser.c util/configparser.h
if test -d ldns-src; then rm -rf ldns-src; fi
rm -f Makefile
$(BUILD)%.lint: $(srcdir)/%.c
@@ -175,22 +199,39 @@ ifdef doxygen
$(doxygen) $(srcdir)/doc/unbound.doxygen
endif
strip:
strip unbound
strip unbound-checkconf
install:
$(INSTALL) -d $(bindir)
$(INSTALL) -d $(mandir)
$(INSTALL) -d $(mandir)/man8
$(INSTALL) -d $(mandir)/man5
$(LIBTOOL) --mode=install cp unbound $(bindir)/unbound
$(LIBTOOL) --mode=install cp unbound-checkconf $(bindir)/unbound-checkconf
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.8 $(mandir)/man8
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-checkconf.8 $(mandir)/man8
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.conf.5 $(mandir)/man5
if test ! -e $(configfile); then $(INSTALL) -d `dirname $(configfile)`; $(INSTALL) -c -m 644 $(srcdir)/doc/example.conf $(configfile); fi
uninstall:
rm -f -- $(bindir)/unbound
rm -f -- $(mandir)/man8/unbound.8 $(mandir)/man5/unbound.conf.5
rm -f -- $(bindir)/unbound $(bindir)/unbound-checkconf
rm -f -- $(mandir)/man8/unbound.8 $(mandir)/man8/unbound-checkconf.8 $(mandir)/man5/unbound.conf.5
@echo
@echo "You still need to remove `dirname $(configfile)` , $(configfile) by hand"
download_ldns:
svn export https://www.nlnetlabs.nl/ldns/svn/trunk/makedist.sh ldns_makedist.sh
./ldns_makedist.sh -s -d https://www.nlnetlabs.nl/ldns/svn/trunk
mv ldns-*_pre_*.tar.gz ldns-src.tar.gz
rm ldns-*_pre_*.tar.gz.sha1 ldns_makedist.sh
# Automatic dependencies.
$(BUILD)%.d: $(srcdir)/%.c
$(INFO) Depend $<
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
@if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
$Q$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $(CFLAGS) $< \
| sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.o $@ : !g'\'' > $@; \
+10
View File
@@ -0,0 +1,10 @@
Unbound README
* ./configure && make && make install
* on BSDs and Solaris use gmake (GNU make).
* If it complains that no libevent can be found; libevent is useful when
using many (10000) outgoing ports. By default 16 ports are used and the
builtin alternative is equally capable.
* More detailed README, README.svn, README.tests in doc directory
* manual pages can be found in doc directory, and are installed, unbound(8).
* example configuration file doc/example.conf
+215
View File
@@ -0,0 +1,215 @@
/*
* checkconf/unbound-checkconf.c - config file checker for unbound.conf file.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* The config checker checks for syntax and other errors in the unbound.conf
* file, and can be used to check for errors before the server is started
* or sigHUPped.
* Exit status 1 means an error.
*/
#include "config.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include "services/localzone.h"
#include <pwd.h>
/** Give checkconf usage, and exit (1). */
static void
usage()
{
printf("Usage: unbound-checkconf [file]\n");
printf(" Checks unbound configuration file for errors.\n");
printf("file if omitted %s is used.\n", CONFIGFILE);
printf("-h show this usage help.\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
exit(1);
}
/** check if module works with config */
static void
check_mod(struct config_file* cfg, struct module_func_block* fb)
{
struct module_env env;
memset(&env, 0, sizeof(env));
env.cfg = cfg;
env.scratch = regional_create();
env.scratch_buffer = ldns_buffer_new(BUFSIZ);
if(!env.scratch || !env.scratch_buffer)
fatal_exit("out of memory");
if(!(*fb->init)(&env, 0)) {
fatal_exit("bad config for %s module", fb->name);
}
(*fb->deinit)(&env, 0);
ldns_buffer_free(env.scratch_buffer);
regional_destroy(env.scratch);
}
/** check configuration for errors */
static void
morechecks(struct config_file* cfg)
{
int i;
struct sockaddr_storage a;
socklen_t alen;
struct config_str2list* acl;
struct local_zones* zs;
for(i=0; i<cfg->num_ifs; i++) {
if(!ipstrtoaddr(cfg->ifs[i], UNBOUND_DNS_PORT, &a, &alen)) {
fatal_exit("cannot parse interface specified as '%s'",
cfg->ifs[i]);
}
}
for(i=0; i<cfg->num_out_ifs; i++) {
if(!ipstrtoaddr(cfg->out_ifs[i], UNBOUND_DNS_PORT,
&a, &alen)) {
fatal_exit("cannot parse outgoing-interface "
"specified as '%s'", cfg->out_ifs[i]);
}
}
for(acl=cfg->acls; acl; acl = acl->next) {
if(!netblockstrtoaddr(acl->str, UNBOUND_DNS_PORT, &a, &alen,
&i)) {
fatal_exit("cannot parse access control address %s %s",
acl->str, acl->str2);
}
}
if(cfg->verbosity < 0)
fatal_exit("verbosity value < 0");
if(cfg->num_threads < 0 || cfg->num_threads > 10000)
fatal_exit("num_threads value weird");
if(!cfg->do_ip4 && !cfg->do_ip6)
fatal_exit("ip4 and ip6 are both disabled, pointless");
if(!cfg->do_udp && !cfg->do_tcp)
fatal_exit("udp and tcp are both disabled, pointless");
if(cfg->chrootdir && strncmp(cfg->chrootdir, cfg->directory,
strlen(cfg->chrootdir)) != 0)
fatal_exit("working directory %s not in chrootdir %s",
cfg->directory, cfg->chrootdir);
if(cfg->chrootdir && cfg->pidfile && cfg->pidfile[0] &&
strncmp(cfg->chrootdir, cfg->pidfile,
strlen(cfg->chrootdir)) != 0)
fatal_exit("pid file %s not in chrootdir %s",
cfg->pidfile, cfg->chrootdir);
if(cfg->chrootdir && cfg->logfile && cfg->logfile[0] &&
strncmp(cfg->chrootdir, cfg->logfile,
strlen(cfg->chrootdir)) != 0)
fatal_exit("log file %s not in chrootdir %s",
cfg->logfile, cfg->chrootdir);
if(strcmp(cfg->module_conf, "iterator") != 0 &&
strcmp(cfg->module_conf, "validator iterator") != 0) {
fatal_exit("module conf '%s' is not known to work",
cfg->module_conf);
}
if(cfg->username && cfg->username[0]) {
struct passwd *pwd;
if((pwd = getpwnam(cfg->username)) == NULL)
fatal_exit("user '%s' does not exist.", cfg->username);
endpwent();
}
if(!(zs = local_zones_create()))
fatal_exit("out of memory");
if(!local_zones_apply_cfg(zs, cfg))
fatal_exit("failed local-zone, local-data configuration");
local_zones_print(zs); /* @@@ DEBUG */
local_zones_delete(zs);
}
/** check config file */
static void
checkconf(char* cfgfile)
{
struct config_file* cfg = config_create();
if(!cfg)
fatal_exit("out of memory");
if(!config_read(cfg, cfgfile)) {
/* config_read prints messages to stderr */
config_delete(cfg);
exit(1);
}
morechecks(cfg);
check_mod(cfg, iter_get_funcblock());
check_mod(cfg, val_get_funcblock());
config_delete(cfg);
printf("unbound-checkconf: no errors in %s\n", cfgfile);
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
extern char* optarg;
/** Main routine for checkconf */
int main(int argc, char* argv[])
{
int c;
char* f;
log_ident_set("unbound-checkconf");
log_init(NULL, 0, NULL);
checklock_start();
/* parse the options */
while( (c=getopt(argc, argv, "h")) != -1) {
switch(c) {
case '?':
case 'h':
default:
usage();
}
}
argc -= optind;
argv += optind;
if(argc != 0 && argc != 1)
usage();
if(argc == 1)
f = argv[0];
else f = CONFIGFILE;
checkconf(f);
checklock_stop();
return 0;
}
+116
View File
@@ -0,0 +1,116 @@
/*
* checkconf/worker_cb.c - fake callback routines to make fptr_wlist work
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains fake callback functions, so that the symbols exist
* and the fptr_wlist continues to work even if the daemon/worker is not
* linked into the resulting program.
*/
#include "config.h"
#include "util/log.h"
struct comm_reply;
struct comm_point;
struct module_qstate;
int worker_handle_control_cmd(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
int worker_handle_request(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(repinfo))
{
log_assert(0);
return 0;
}
int worker_handle_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int worker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
{
log_assert(0);
return 0;
}
struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
}
void
worker_alloc_cleanup(void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int
acl_list_cmp(const void* ATTR_UNUSED(k1), const void* ATTR_UNUSED(k2))
{
log_assert(0);
return 0;
}
Vendored Executable
+1500
View File
File diff suppressed because it is too large Load Diff
+426
View File
@@ -0,0 +1,426 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Pathname to the Unbound configuration file */
#undef CONFIGFILE
/* Define if you want to use debug lock checking (slow). */
#undef ENABLE_LOCK_CHECKS
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "unused" attribute */
#undef HAVE_ATTR_UNUSED
/* Define to 1 if your system has a working `chown' function. */
#undef HAVE_CHOWN
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `event_base_free' function. */
#undef HAVE_EVENT_BASE_FREE
/* Define to 1 if you have the `event_base_once' function. */
#undef HAVE_EVENT_BASE_ONCE
/* Define to 1 if you have the <event.h> header file. */
#undef HAVE_EVENT_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `rt' library (-lrt). */
#undef HAVE_LIBRT
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <openssl/err.h> header file. */
#undef HAVE_OPENSSL_ERR_H
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if the system has the type `pthread_rwlock_t'. */
#undef HAVE_PTHREAD_RWLOCK_T
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
#undef HAVE_PTHREAD_SPINLOCK_T
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Using Solaris threads */
#undef HAVE_SOLARIS_THREADS
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to the maximum message length to pass to syslog. */
#undef MAXSYSLOGMSGLEN
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 'int' or type of struct msghdr.msg_iovlen. */
#undef TYPE_MSGIOVLEN
/* use statistics for allocs and frees, for debug use */
#undef UNBOUND_ALLOC_STATS
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* in_addr_t */
#undef in_addr_t
/* in_port_t */
#undef in_port_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `short' if <sys/types.h> does not define. */
#undef int16_t
/* Define to `int' if <sys/types.h> does not define. */
#undef int32_t
/* Define to `long long' if <sys/types.h> does not define. */
#undef int64_t
/* Define to `char' if <sys/types.h> does not define. */
#undef int8_t
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to 'int' if not defined */
#undef socklen_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `unsigned char' if <sys/types.h> does not define. */
#undef u_char
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define to `unsigned short' if <sys/types.h> does not define. */
#undef uint16_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef uint32_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef uint64_t
/* Define to `unsigned char' if <sys/types.h> does not define. */
#undef uint8_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <errno.h>
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
#ifdef HAVE_ATTR_FORMAT
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
#else /* !HAVE_ATTR_FORMAT */
# define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
#endif /* !HAVE_ATTR_FORMAT */
#if defined(DOXYGEN)
# define ATTR_UNUSED(x) x
#elif defined(__cplusplus)
# define ATTR_UNUSED(x)
#elif defined(HAVE_ATTR_UNUSED)
# define ATTR_UNUSED(x) x __attribute__((unused))
#else /* !HAVE_ATTR_UNUSED */
# define ATTR_UNUSED(x) x
#endif /* !HAVE_ATTR_UNUSED */
#ifndef HAVE_FSEEKO
#define fseeko fseek
#define ftello ftell
#endif /* HAVE_FSEEKO */
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
/* using version of libevent that is not threadsafe. */
# define LIBEVENT_SIGNAL_PROBLEM 1
#endif
#ifndef RAND_MAX
#define RAND_MAX 2147483647
#endif
#ifndef IPV6_MIN_MTU
#define IPV6_MIN_MTU 1280
#endif /* IPV6_MIN_MTU */
#ifndef CHECKED_INET6
# define CHECKED_INET6
# ifdef AF_INET6
# define INET6
# else
# define AF_INET6 28
# endif
#endif /* CHECKED_INET6 */
/* maximum nesting of included files */
#define MAXINCLUDES 10
#ifndef HAVE_SNPRINTF
#include <stdarg.h>
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#endif /* HAVE_SNPRINTF */
#ifndef HAVE_INET_PTON
int inet_pton(int af, const char* src, void* dst);
#endif /* HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifndef HAVE_INET_ATON
int inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifndef HAVE_MEMMOVE
void *memmove(void *dest, const void *src, size_t n);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#ifndef HAVE_GETADDRINFO
struct sockaddr_storage;
#include "compat/fake-rfc2553.h"
#endif
#include "ldns/ldns.h"
#ifdef UNBOUND_ALLOC_STATS
# define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__)
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
void *unbound_stat_realloc(void *ptr, size_t size);
void *unbound_stat_malloc_log(size_t size, const char* file, int line,
const char* func);
void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file,
int line, const char* func);
void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
#endif /* UNBOUND_ALLOC_STATS */
/** default port for DNS traffic. */
#define UNBOUND_DNS_PORT 53
Vendored Executable
+1616
View File
File diff suppressed because it is too large Load Diff
Vendored Executable
+25701
View File
File diff suppressed because it is too large Load Diff
+96 -17
View File
@@ -2,11 +2,40 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(unbound, 0.5, wouter@nlnetlabs.nl, unbound)
AC_INIT(unbound, 0.8, unbound-bugs@nlnetlabs.nl, unbound)
CFLAGS=
AC_AIX
dnl
dnl By default set $sysconfdir to /etc and $localstatedir to /var
dnl
case "$prefix" in
NONE)
case "$sysconfdir" in
'${prefix}/etc')
sysconfdir=/etc
;;
esac
case "$localstatedir" in
'${prefix}/var')
localstatedir=/var
;;
esac
;;
esac
#
# Determine configuration file
ub_conf_file=${sysconfdir}/unbound/unbound.conf
AC_ARG_WITH([conf_file],
AC_HELP_STRING([--with-conf-file=path], [Pathname to the Unbound configuration file]),
[ub_conf_file=$withval])
AC_SUBST(ub_conf_file)
# the eval is to evaluate shell expansion twice, once
# for $nsd_conf_file and once for the ${prefix} within it.
AC_DEFINE_UNQUOTED(CONFIGFILE, ["`eval echo $ub_conf_file`"], [Pathname to the Unbound configuration file])
dnl routine to help check for compiler flags.
AC_DEFUN([CHECK_COMPILER_FLAG],
[
@@ -251,6 +280,15 @@ if test "$srcdir" != "."; then
CPPFLAGS="$CPPFLAGS -I$srcdir";
fi
# skip these tests, we do not need them.
AC_DEFUN([AC_PROG_F77], [:])
AC_DEFUN([AC_PROG_FC], [:])
AC_DEFUN([AC_PROG_CXX], [:])
AC_DEFUN([AC_PROG_CXXCPP], [:])
AC_DEFUN([AC_PROG_OBJC], [:])
AC_DEFUN([AC_PROG_OBJCCPP], [:])
AC_DEFUN([AC_LIBTOOL_CXX], [:])
AC_DEFUN([AC_LIBTOOL_F77], [:])
# Use libtool
AC_CHECK_PROGS(libtool, [glibtool libtool15 libtool], [./libtool])
AC_PATH_TOOL(AR, ar, [false])
@@ -269,7 +307,7 @@ AC_PROG_LIBTOOL
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h syslog.h],,, [AC_INCLUDES_DEFAULT])
# check for types
AC_CHECK_TYPE(int8_t, char)
@@ -356,6 +394,12 @@ fi
CHECK_YYUNPUT
# add option to disable the evil rpath
dnl Check whether to use rpath or not
AC_ARG_ENABLE(rpath,
[ --disable-rpath disable hardcoded rpath (default=enabled)],
enable_rpath=$enableval, enable_rpath=yes)
# Checks for libraries.
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
[enable SSL (will check /usr/local/ssl
@@ -383,7 +427,9 @@ AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
AC_MSG_RESULT(found in $ssldir)
HAVE_SSL=yes
LDFLAGS="$LDFLAGS -L$ssldir/lib";
RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib"
if test "x$enable_rpath" = xyes; then
RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib"
fi
AC_CHECK_LIB(crypto, HMAC_CTX_init,, [
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
])
@@ -457,14 +503,16 @@ if test x_$withval != x_no; then
LDFLAGS="$thedir/.libs/*.o $LDFLAGS";
else
AC_MSG_ERROR([Cannot find the libevent library in $withval
You can restart configure with --with-libevent=no to use a builtin alternative.
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
many outgoing ports. ])
fi
else
AC_MSG_RESULT(found in $thedir)
LDFLAGS="$LDFLAGS -L$thedir/lib";
RUNTIME_PATH="$RUNTIME_PATH -R$thedir/lib"
if test "x$enable_rpath" = xyes; then
RUNTIME_PATH="$RUNTIME_PATH -R$thedir/lib"
fi
fi
AC_SUBST(RUNTIME_PATH)
AC_SEARCH_LIBS(event_set, [event])
@@ -513,6 +561,19 @@ AC_TYPE_SIGNAL
AC_FUNC_FSEEKO
AC_SYS_LARGEFILE
# check this after all other compilation checks, since the linking of the lib
# may break checks after this.
AC_ARG_WITH(ldns,
AC_HELP_STRING([--with-ldns=PATH specify prefix of path of ldns library to use])
, [ specialldnsdir="$withval"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval -L$withval/lib -lldns"
ldnsdir="$withval"
AC_SUBST(ldnsdir)
])
AC_CHECK_LIB(ldns, ldns_rr_new, [
dnl ldns was found, check compat functions
AC_REPLACE_FUNCS(inet_aton)
AC_REPLACE_FUNCS(inet_pton)
AC_REPLACE_FUNCS(inet_ntop)
@@ -525,20 +586,38 @@ if test $ac_cv_func_getaddrinfo = no; then
AC_LIBOBJ([fake-rfc2553])
fi
# check this after all other compilation checks, since the linking of the lib
# may break checks after this.
AC_ARG_WITH(ldns,
AC_HELP_STRING([--with-ldns=PATH specify prefix of path of ldns library to use])
, [ specialldnsdir="$withval"
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval -L$withval/lib -lldns"
ldnsdir="$withval"
AC_SUBST(ldnsdir)
] , [
dnl use the builtin ldns-src.tar.gz file to build ldns.
if test ! -f $srcdir/ldns-src.tar.gz; then
AC_MSG_ERROR([No ldns library found and no ldns-src.tar.gz, use --with-ldns=path.])
fi
echo "****************************************************************"
echo "*** ***"
echo "*** ldns library not found (--with-ldns= to specify by hand) ***"
echo "*** Building ldns library from package included in this one. ***"
echo "*** ***"
echo "****************************************************************"
if test -d ldns-src; then rm -rf ldns-src; fi
mkdir ldns-src; cp $srcdir/ldns-src.tar.gz ldns-src/ldns-src.tar.gz; (cd ldns-src; gzip -cd ldns-src.tar.gz | tar xf -); rm -f ldns-src/ldns-src.tar.gz
ldnsdir=`ls -d ldns-src/ldns*`
AC_MSG_NOTICE([Configure $ldnsdir])
echo "(cd $ldnsdir; ./configure)"
(cd $ldnsdir; ./configure)
AC_MSG_NOTICE([Finished $ldnsdir configure])
CPPFLAGS="$CPPFLAGS -I$ldnsdir/include"
LDFLAGS="$LDFLAGS $ldnsdir/lib/*.o"
AC_SUBST(ldnsdir)
dnl use ldns compat functions
AC_DEFINE(HAVE_INET_ATON)
AC_DEFINE(HAVE_INET_PTON)
AC_DEFINE(HAVE_INET_NTOP)
AC_DEFINE(HAVE_SNPRINTF)
AC_DEFINE(HAVE_STRLCPY)
AC_DEFINE(HAVE_MEMMOVE)
AC_DEFINE(HAVE_GETADDRINFO)
])
AC_CHECK_LIB(ldns, ldns_rr_new,, [AC_MSG_ERROR([Can't find ldns library])])
AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [512], [Define to the maximum message length to pass to syslog.])
AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [5120], [Define to the maximum message length to pass to syslog.])
AH_BOTTOM([
#include <stdio.h>
+246
View File
@@ -0,0 +1,246 @@
/*
* daemon/acl_list.h - client access control storage for the server.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file helps the server keep out queries from outside sources, that
* should not be answered.
*/
#include "config.h"
#include "daemon/acl_list.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
int
acl_list_cmp(const void* k1, const void* k2)
{
struct acl_addr* n1 = (struct acl_addr*)k1;
struct acl_addr* n2 = (struct acl_addr*)k2;
int r = sockaddr_cmp_addr(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
if(r != 0) return r;
if(n1->net < n2->net)
return -1;
if(n1->net > n2->net)
return 1;
return 0;
}
struct acl_list*
acl_list_create()
{
struct acl_list* acl = (struct acl_list*)calloc(1,
sizeof(struct acl_list));
if(!acl)
return NULL;
acl->region = regional_create();
if(!acl->region) {
acl_list_delete(acl);
return NULL;
}
return acl;
}
void
acl_list_delete(struct acl_list* acl)
{
if(!acl)
return;
regional_destroy(acl->region);
free(acl->tree);
free(acl);
}
/** insert new address into acl_list structure */
static int
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
int complain_duplicates)
{
struct acl_addr* node = regional_alloc(acl->region,
sizeof(struct acl_addr));
if(!node)
return 0;
node->node.key = node;
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
node->control = control;
if(!rbtree_insert(acl->tree, &node->node)) {
if(complain_duplicates)
verbose(VERB_DETAIL, "duplicate acl address ignored.");
}
return 1;
}
/** apply acl_list string */
static int
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
int complain_duplicates)
{
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
enum acl_access control;
if(strcmp(s2, "allow") == 0)
control = acl_allow;
else if(strcmp(s2, "deny") == 0)
control = acl_deny;
else if(strcmp(s2, "refuse") == 0)
control = acl_refuse;
else {
log_err("access control type %s unknown", str);
return 0;
}
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse access control: %s %s", str, s2);
return 0;
}
if(!acl_list_insert(acl, &addr, addrlen, net, control,
complain_duplicates)) {
log_err("out of memory");
return 0;
}
return 1;
}
/** read acl_list config */
static int
read_acl_list(struct acl_list* acl, struct config_file* cfg)
{
struct config_str2list* p;
for(p = cfg->acls; p; p = p->next) {
log_assert(p->str && p->str2);
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
return 0;
}
return 1;
}
/** initialise parent pointers in the tree */
static void
acl_list_init_parents(struct acl_list* acl)
{
struct acl_addr* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct acl_addr*, acl->tree) {
node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) {
prev = node;
continue;
}
m = addr_in_common(&prev->addr, prev->net, &node->addr,
node->net, node->addrlen);
/* sort order like: ::/0, 1::/2, 1::/4, ... 2::/2 */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
if(p->net <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
int
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
{
regional_free_all(acl->region);
free(acl->tree);
acl->tree = rbtree_create(acl_list_cmp);
if(!acl->tree)
return 0;
if(!read_acl_list(acl, cfg))
return 0;
/* insert defaults, with '0' to ignore them if they are duplicates */
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
return 0;
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
return 0;
acl_list_init_parents(acl);
return 1;
}
enum acl_access
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen)
{
/* lookup in the tree */
rbnode_t* res = NULL;
struct acl_addr* result;
struct acl_addr key;
key.node.key = &key;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
key.net = (addr_is_ip6(addr, addrlen)?128:32);
if(rbtree_find_less_equal(acl->tree, &key, &res)) {
/* exact */
result = (struct acl_addr*)res;
return result->control;
} else {
/* smaller element (or no element) */
int m;
result = (struct acl_addr*)res;
if(!result || result->addrlen != addrlen)
return acl_deny;
/* count number of bits matched */
m = addr_in_common(&result->addr, result->net, addr,
key.net, addrlen);
while(result) { /* go up until addr is inside netblock */
if(result->net <= m)
return result->control;
result = result->parent;
}
}
return acl_deny;
}
size_t
acl_list_get_mem(struct acl_list* acl)
{
if(!acl) return 0;
return sizeof(*acl) + regional_get_mem(acl->region);
}
+134
View File
@@ -0,0 +1,134 @@
/*
* daemon/acl_list.h - client access control storage for the server.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file keeps track of the list of clients that are allowed to
* access the server.
*/
#ifndef DAEMON_ACL_LIST_H
#define DAEMON_ACL_LIST_H
#include "util/rbtree.h"
struct config_file;
struct regional;
/**
* Enumeration of access control options for an address range.
* Allow or deny access.
*/
enum acl_access {
/** disallow any access whatsoever, drop it */
acl_deny = 0,
/** disallow access, send a polite 'REFUSED' reply */
acl_refuse,
/** allow full access */
acl_allow
};
/**
* Access control storage structure
*/
struct acl_list {
/** regional for allocation */
struct regional* region;
/**
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
rbtree_t* tree;
};
/**
*
* An address span with access control information
*/
struct acl_addr {
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** netblock size */
int net;
/** parent node in acl tree that encompasses this entry */
struct acl_addr* parent;
/** access control on this netblock */
enum acl_access control;
};
/**
* Create acl structure
* @return new structure or NULL on error.
*/
struct acl_list* acl_list_create();
/**
* Delete acl structure.
* @param acl: to delete.
*/
void acl_list_delete(struct acl_list* acl);
/**
* Process access control config.
* @param acl: where to store.
* @param cfg: config options.
* @return 0 on error.
*/
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
/**
* Lookup address to see its access control status.
* @param acl: structure for address storage.
* @param addr: address to check
* @param addrlen: length of addr.
* @return: what to do with message from this address.
*/
enum acl_access acl_list_lookup(struct acl_list* acl,
struct sockaddr_storage* addr, socklen_t addrlen);
/**
* Get memory used by acl structure.
* @param acl: structure for address storage.
* @return bytes in use.
*/
size_t acl_list_get_mem(struct acl_list* acl);
/** compare two acl list entries */
int acl_list_cmp(const void* k1, const void* k2);
#endif /* DAEMON_ACL_LIST_H */
+37 -10
View File
@@ -42,6 +42,7 @@
#include "config.h"
#include "daemon/daemon.h"
#include "daemon/worker.h"
#include "daemon/acl_list.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
@@ -49,9 +50,11 @@
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
#include "services/localzone.h"
#include "util/module.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include "util/fptr_wlist.h"
#include <signal.h>
/** How many quit requests happened. */
@@ -67,6 +70,8 @@ static int sig_record_reload = 0;
static RETSIGTYPE record_sigh(int sig)
{
#ifdef LIBEVENT_SIGNAL_PROBLEM
verbose(VERB_OPS, "quit on signal, no cleanup and statistics, "
"because installed libevent version is not threadsafe");
exit(0);
#endif
switch(sig)
@@ -105,10 +110,10 @@ signal_handling_record()
static void
signal_handling_playback(struct worker* wrk)
{
if(sig_record_quit)
worker_sighandler(SIGTERM, wrk);
if(sig_record_reload)
worker_sighandler(SIGHUP, wrk);
if(sig_record_quit)
worker_sighandler(SIGTERM, wrk);
sig_record_quit = 0;
sig_record_reload = 0;
}
@@ -131,6 +136,12 @@ daemon_init()
return NULL;
}
alloc_init(&daemon->superalloc, NULL, 0);
daemon->acl = acl_list_create();
if(!daemon->acl) {
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@@ -243,6 +254,8 @@ daemon_desetup_modules(struct daemon* daemon)
{
int i;
for(i=0; i<daemon->num_modules; i++) {
log_assert(fptr_whitelist_mod_deinit(
daemon->modfunc[i]->deinit));
(*daemon->modfunc[i]->deinit)(daemon->env, i);
}
daemon->num_modules = 0;
@@ -266,11 +279,11 @@ static void daemon_setup_modules(struct daemon* daemon)
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
daemon->env->send_packet = &worker_send_packet;
daemon->env->send_query = &worker_send_query;
daemon->env->need_to_validate = 0; /* set by module init below */
for(i=0; i<daemon->num_modules; i++) {
log_info("init module %d: %s", i, daemon->modfunc[i]->name);
verbose(VERB_OPS, "init module %d: %s",
i, daemon->modfunc[i]->name);
log_assert(fptr_whitelist_mod_init(daemon->modfunc[i]->init));
if(!(*daemon->modfunc[i]->init)(daemon->env, i)) {
fatal_exit("module init for module %s failed",
daemon->modfunc[i]->name);
@@ -380,7 +393,7 @@ daemon_stop_others(struct daemon* daemon)
worker_send_cmd(daemon->workers[i],
daemon->workers[0]->front->udp_buff, worker_cmd_quit);
}
/** wait for them to quit */
/* wait for them to quit */
for(i=1; i<daemon->num; i++) {
/* join it to make sure its dead */
verbose(VERB_ALGO, "join %d", i);
@@ -393,6 +406,12 @@ void
daemon_fork(struct daemon* daemon)
{
log_assert(daemon);
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
fatal_exit("Could not setup access control list");
if(!(daemon->local_zones = local_zones_create()))
fatal_exit("Could not create local zones: out of memory");
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
fatal_exit("Could not set up local zones");
/* setup modules */
daemon_setup_modules(daemon);
@@ -417,13 +436,12 @@ daemon_fork(struct daemon* daemon)
/* Start resolver service on main thread. */
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(daemon->workers[0]);
log_info("service stopped (%s).", PACKAGE_STRING);
/* we exited! a signal happened! Stop other threads */
daemon_stop_others(daemon);
if(daemon->workers[0]->need_to_restart)
daemon->need_to_exit = 0;
else daemon->need_to_exit = 1;
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
}
void
@@ -435,6 +453,15 @@ daemon_cleanup(struct daemon* daemon)
don't die on multiple reload signals for example. */
signal_handling_record();
log_thread_set(NULL);
/* clean up caches because
* a) RRset IDs will be recycled after a reload, causing collisions
* b) validation config can change, thus rrset, msg, keycache clear
* The infra cache is kept, the timing and edns info is still valid */
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
/* key cache is cleared by module desetup during next daemon_init() */
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
free(daemon->workers);
@@ -456,7 +483,7 @@ daemon_delete(struct daemon* daemon)
infra_delete(daemon->env->infra_cache);
}
alloc_clear(&daemon->superalloc);
free(daemon->cwd);
acl_list_delete(daemon->acl);
free(daemon->pidfile);
free(daemon->env);
free(daemon);
+6 -2
View File
@@ -50,6 +50,8 @@ struct listen_port;
struct slabhash;
struct module_env;
struct rrset_cache;
struct acl_list;
struct local_zones;
/**
* Structure holding worker list.
@@ -58,8 +60,6 @@ struct rrset_cache;
struct daemon {
/** The config settings */
struct config_file* cfg;
/** current working directory */
char* cwd;
/** pidfile that is used */
char* pidfile;
/** port number that has ports opened. */
@@ -80,6 +80,10 @@ struct daemon {
int num_modules;
/** the module callbacks, array of num_modules length */
struct module_func_block** modfunc;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** local authority zones */
struct local_zones* local_zones;
};
/**
+63 -37
View File
@@ -61,12 +61,13 @@ void* unbound_start_brk = 0;
/** print usage. */
static void usage()
{
printf("usage: unbound [options]\n");
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help\n");
printf("-c file config file to read, unbound.conf(5).\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 (multiple times increase verbosity)\n");
printf("-v verbose (more times to increase verbosity)\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
@@ -81,7 +82,8 @@ checkrlimits(struct config_file* cfg)
(int)cfg->incoming_num_tcp:0));
size_t ifs = (size_t)(cfg->num_ifs==0?1:cfg->num_ifs);
size_t listen_num = list*ifs;
size_t outnum = cfg->outgoing_num_ports*ifs + cfg->outgoing_num_tcp;
size_t out_ifs = (size_t)(cfg->num_out_ifs==0?1:cfg->num_out_ifs);
size_t outnum = cfg->outgoing_num_ports*out_ifs + cfg->outgoing_num_tcp;
size_t misc = 4; /* logfile, pidfile, stdout... */
size_t perthread = listen_num + outnum + 2/*cmdpipe*/ + 2/*libevent*/
+ misc;
@@ -109,24 +111,15 @@ checkrlimits(struct config_file* cfg)
}
}
/** to changedir, logfile */
/** set verbosity, check rlimits, cache settings */
static void
apply_dir(struct daemon* daemon, struct config_file* cfg, int cmdline_verbose)
apply_settings(struct daemon* daemon, struct config_file* cfg,
int cmdline_verbose)
{
/* apply if they have changed */
daemon->cfg = cfg;
verbosity = cmdline_verbose + cfg->verbosity;
if(cfg->directory && cfg->directory[0]) {
if(!daemon->cwd || strcmp(daemon->cwd, cfg->directory) != 0) {
if(chdir(cfg->directory)) {
log_err("Could not chdir to %s: %s",
cfg->directory, strerror(errno));
}
free(daemon->cwd);
if(!(daemon->cwd = strdup(cfg->directory)))
log_err("cwd: malloc failed");
}
}
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) {
@@ -183,7 +176,8 @@ readpid (const char* file)
return -1;
}
pid = strtol(pidbuf, &t, 10);
pidbuf[sizeof(pidbuf)-1] = 0;
pid = (pid_t)strtol(pidbuf, &t, 10);
if (*t && *t != '\n') {
return -1;
@@ -220,7 +214,12 @@ static void
checkoldpid(struct config_file* cfg)
{
pid_t old;
if((old = readpid(cfg->pidfile)) != -1) {
char* file = cfg->pidfile;
if(cfg->chrootdir && cfg->chrootdir[0] &&
strncmp(file, cfg->chrootdir, strlen(cfg->chrootdir))==0) {
file += strlen(cfg->chrootdir);
}
if((old = readpid(file)) != -1) {
/* see if it is still alive */
if(kill(old, 0) == 0 || errno == EPERM)
log_warn("unbound is already running as pid %u.",
@@ -262,35 +261,62 @@ detach(struct config_file* cfg)
static void
do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
{
uid_t uid;
gid_t gid;
/* initialize, but not to 0 (root) */
memset(&uid, -12, sizeof(uid));
memset(&gid, -12, sizeof(gid));
log_assert(cfg);
/* daemonize last to be able to print error to user */
if(cfg->chrootdir && cfg->chrootdir[0])
if(chroot(cfg->chrootdir))
fatal_exit("unable to chroot: %s", strerror(errno));
if(cfg->directory && cfg->directory[0]) {
if(chdir(cfg->directory)) {
fatal_exit("Could not chdir to %s: %s",
cfg->directory, strerror(errno));
}
verbose(VERB_DETAIL, "chdir to %s", cfg->directory);
}
if(cfg->username && cfg->username[0]) {
struct passwd *pwd;
if((pwd = getpwnam(cfg->username)) == NULL)
fatal_exit("user '%s' does not exist.", cfg->username);
if(setgid(pwd->pw_gid) != 0)
fatal_exit("unable to set group id: %s", strerror(errno));
if(setuid(pwd->pw_uid) != 0)
fatal_exit("unable to set user id: %s", strerror(errno));
uid = pwd->pw_uid;
gid = pwd->pw_gid;
endpwent();
}
if(cfg->chrootdir && cfg->chrootdir[0]) {
if(chroot(cfg->chrootdir))
fatal_exit("unable to chroot to %s: %s",
cfg->chrootdir, strerror(errno));
verbose(VERB_DETAIL, "chroot to %s", cfg->chrootdir);
}
if(cfg->username && cfg->username[0]) {
if(setgid(gid) != 0)
fatal_exit("unable to set group id of %s: %s",
cfg->username, strerror(errno));
if(setuid(uid) != 0)
fatal_exit("unable to set user id of %s: %s",
cfg->username, strerror(errno));
verbose(VERB_DETAIL, "drop user privileges, run as %s",
cfg->username);
}
/* check old pid file before forking */
if(cfg->pidfile && cfg->pidfile[0]) {
checkoldpid(cfg);
}
/* init logfile just before fork */
log_init(cfg->logfile);
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
if(!debug_mode && cfg->do_daemonize) {
detach(cfg);
}
if(cfg->pidfile && cfg->pidfile[0]) {
writepid(cfg->pidfile, getpid());
if(!(daemon->pidfile = strdup(cfg->pidfile)))
char* pf = cfg->pidfile;
if(cfg->chrootdir && cfg->chrootdir[0] &&
strncmp(pf, cfg->chrootdir, strlen(cfg->chrootdir))==0)
pf += strlen(cfg->chrootdir);
writepid(pf, getpid());
if(!(daemon->pidfile = strdup(pf)))
log_err("pidf: malloc failed");
}
}
@@ -303,7 +329,7 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
* @param debug_mode: if set, do not daemonize.
*/
static void
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
run_daemon(char* cfgfile, int cmdline_verbose, int debug_mode)
{
struct config_file* cfg = NULL;
struct daemon* daemon = NULL;
@@ -313,15 +339,15 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
fatal_exit("alloc failure");
while(!daemon->need_to_exit) {
if(done_chroot)
log_info("Restart of %s.", PACKAGE_STRING);
else log_info("Start of %s.", PACKAGE_STRING);
verbose(VERB_OPS, "Restart of %s.", PACKAGE_STRING);
else verbose(VERB_OPS, "Start of %s.", PACKAGE_STRING);
/* config stuff */
if(!(cfg = config_create()))
fatal_exit("Could not alloc config defaults");
if(!config_read(cfg, cfgfile))
fatal_exit("Could not read config file: %s", cfgfile);
apply_dir(daemon, cfg, cmdline_verbose);
apply_settings(daemon, cfg, cmdline_verbose);
/* prepare */
if(!daemon_open_shared_ports(daemon))
@@ -329,7 +355,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
if(!done_chroot) {
do_chroot(daemon, cfg, debug_mode);
done_chroot = 1;
}
} else log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
/* work */
daemon_fork(daemon);
@@ -359,14 +385,14 @@ int
main(int argc, char* argv[])
{
int c;
const char* cfgfile = NULL;
char* cfgfile = CONFIGFILE;
int cmdline_verbose = 0;
int debug_mode = 0;
/* take debug snapshot of heap */
unbound_start_brk = sbrk(0);
log_init(NULL);
log_init(NULL, 0, NULL);
/* parse the options */
while( (c=getopt(argc, argv, "c:dhv")) != -1) {
switch(c) {
@@ -396,6 +422,6 @@ main(int argc, char* argv[])
}
run_daemon(cfgfile, cmdline_verbose, debug_mode);
log_init(NULL); /* close logfile */
log_init(NULL, 0, NULL); /* close logfile */
return 0;
}
+88 -65
View File
@@ -45,10 +45,11 @@
#include "util/random.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
#include "daemon/acl_list.h"
#include "util/netevent.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/storage/slabhash.h"
#include "services/listen_dnsport.h"
#include "services/outside_network.h"
@@ -57,9 +58,11 @@
#include "services/cache/infra.h"
#include "services/cache/dns.h"
#include "services/mesh.h"
#include "services/localzone.h"
#include "util/data/msgparse.h"
#include "util/data/msgencode.h"
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -134,6 +137,8 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
iter = 0;
val = 0;
for(i=0; i<worker->env.mesh->num_modules; i++) {
log_assert(fptr_whitelist_mod_get_mem(worker->env.mesh->
modfunc[i]->get_mem));
if(strcmp(worker->env.mesh->modfunc[i]->name, "validator")==0)
val += (*worker->env.mesh->modfunc[i]->get_mem)
(&worker->env, i);
@@ -141,10 +146,11 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
(&worker->env, i);
}
me = sizeof(*worker) + sizeof(*worker->base) + sizeof(*worker->comsig)
+ comm_point_get_mem(worker->cmd_com) +
sizeof(worker->rndstate) + region_get_mem(worker->scratchpad)+
sizeof(*worker->env.scratch_buffer) +
ldns_buffer_capacity(worker->env.scratch_buffer);
+ comm_point_get_mem(worker->cmd_com)
+ sizeof(worker->rndstate)
+ regional_get_mem(worker->scratchpad)
+ sizeof(*worker->env.scratch_buffer)
+ ldns_buffer_capacity(worker->env.scratch_buffer);
if(cur_serv) {
me += serviced_get_mem(cur_serv);
}
@@ -174,8 +180,7 @@ worker_send_cmd(struct worker* worker, ldns_buffer* buffer,
log_err("write socket: %s", strerror(errno));
}
/** process incoming replies from the network */
static int
int
worker_handle_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info)
{
@@ -206,8 +211,7 @@ worker_handle_reply(struct comm_point* c, void* arg, int error,
return 0;
}
/** process incoming serviced query replies from the network */
static int
int
worker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info)
{
@@ -286,13 +290,7 @@ worker_check_request(ldns_buffer* pkt, struct worker* worker)
return 0;
}
/** process control messages from the main thread.
* @param c: comm point to read from.
* @param arg: worker.
* @param error: error status of comm point.
* @param reply_info: not used.
*/
static int
int
worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
struct comm_reply* ATTR_UNUSED(reply_info))
{
@@ -364,6 +362,7 @@ deleg_remove_nonsecure_additional(struct reply_info* rep)
(rep->rrset_count - i - 1));
rep->ar_numrrsets--;
rep->rrset_count--;
i--;
}
}
}
@@ -394,7 +393,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
qinfo->qname_len, qinfo->qtype, qinfo->qclass,
worker->scratchpad, &msg, timenow);
if(!dp) { /* no delegation, need to reprime */
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 0;
}
if(must_validate) {
@@ -402,7 +401,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
case sec_status_unchecked:
/* some rrsets have not been verified yet, go and
* let validator do that */
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 0;
case sec_status_bogus:
/* some rrsets are bogus, reply servfail */
@@ -412,7 +411,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
edns->bits &= EDNS_DO;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 1;
case sec_status_secure:
/* all rrsets are secure */
@@ -441,7 +440,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
}
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 1;
}
@@ -514,7 +513,7 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
bail_out:
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 0;
}
}
@@ -529,7 +528,7 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
&mrentry->key, id, flags, edns);
rrset_array_unlock_touch(worker->env.rrset_cache,
worker->scratchpad, rep->ref, rep->rrset_count);
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
return 1;
} else if( rep->security == sec_status_unchecked && must_validate) {
verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
@@ -562,7 +561,7 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
* is bad while holding locks. */
rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
rep->ref, rep->rrset_count);
region_free_all(worker->scratchpad);
regional_free_all(worker->scratchpad);
/* go and return this buffer to the client */
return 1;
}
@@ -629,10 +628,11 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
if(cfg->hide_identity)
return 0;
if(cfg->identity==NULL || cfg->identity[0]==0) {
char buf[MAXHOSTNAMELEN];
if (gethostname(buf, MAXHOSTNAMELEN) == 0)
char buf[MAXHOSTNAMELEN+1];
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
buf[MAXHOSTNAMELEN] = 0;
chaos_replystr(pkt, buf, edns);
else {
} else {
log_err("gethostname: %s", strerror(errno));
chaos_replystr(pkt, "no hostname", edns);
}
@@ -655,8 +655,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
return 0;
}
/** handles callbacks from listening event interface */
static int
int
worker_handle_request(struct comm_point* c, void* arg, int error,
struct comm_reply* repinfo)
{
@@ -666,11 +665,28 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct lruhash_entry* e;
struct query_info qinfo;
struct edns_data edns;
enum acl_access acl;
if(error != NETEVENT_NOERROR) {
log_err("handle request called with err=%d", error);
/* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0;
}
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
repinfo->addrlen);
if(acl == acl_deny) {
comm_point_drop_reply(repinfo);
return 0;
} else if(acl == acl_refuse) {
ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
ldns_buffer_write_at(c->buffer, 4,
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
log_buf(VERB_ALGO, "refuse", c->buffer);
return 1;
}
if((ret=worker_check_request(c->buffer, worker)) != 0) {
verbose(VERB_ALGO, "worker check request: bad query.");
if(ret != -1) {
@@ -729,6 +745,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
LDNS_RCODE_SERVFAIL);
ldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
ldns_buffer_write_at(c->buffer, 4,
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
ldns_buffer_flip(c->buffer);
return 1;
}
@@ -738,6 +756,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
&edns, c->buffer)) {
return 1;
}
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
c->buffer, worker->scratchpad)) {
return (ldns_buffer_limit(c->buffer) != 0);
}
h = query_info_hash(&qinfo);
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
@@ -765,59 +787,46 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
server_stats_querymiss(&worker->stats, worker);
/* grab a work request structure for this new request */
/* @@@ TODO implement overload mode */
if(0 && worker->env.mesh->all.count > worker->request_size) {
/* we could get this due to a slow tcp incoming query,
that started before we performed listen_pushback */
verbose(VERB_DETAIL, "worker: too many incoming requests "
"active. dropping incoming query.");
verbose(VERB_ALGO, "currently servicing %d of %d queries",
(int)worker->env.mesh->all.count,
(int)worker->request_size);
if(worker->env.mesh->all.count > worker->request_size) {
verbose(VERB_ALGO, "Too many requests active. "
"dropping incoming query.");
worker->stats.num_query_list_exceeded++;
comm_point_drop_reply(repinfo);
query_info_clear(&qinfo);
return 0;
}
mesh_new_client(worker->env.mesh, &qinfo,
ldns_buffer_read_u16_at(c->buffer, 2),
&edns, repinfo, *(uint16_t*)ldns_buffer_begin(c->buffer));
if(0) { /* TODO overload mode does not work yet. */
if(worker->env.mesh->all.count == worker->request_size) {
/* the max request number has been reached, stop accepting */
listen_pushback(worker->front);
}
}
worker_mem_report(worker, NULL);
return 0;
}
/** worker signal callback */
void
worker_sighandler(int sig, void* arg)
{
/* note that log, print, syscalls here give race conditions. */
/* we still print DETAIL logs, because this is extensive per message
* logging anyway, and the operator may then have an interest
* in the cause for unbound to exit */
struct worker* worker = (struct worker*)arg;
switch(sig) {
case SIGHUP:
log_info("caught signal SIGHUP");
worker->need_to_restart = 1;
verbose(VERB_DETAIL, "caught signal SIGHUP");
comm_base_exit(worker->base);
break;
case SIGINT:
log_info("caught signal SIGINT");
worker->need_to_restart = 0;
verbose(VERB_DETAIL, "caught signal SIGINT");
worker->need_to_exit = 1;
comm_base_exit(worker->base);
break;
case SIGQUIT:
log_info("caught signal SIGQUIT");
worker->need_to_restart = 0;
verbose(VERB_DETAIL, "caught signal SIGQUIT");
worker->need_to_exit = 1;
comm_base_exit(worker->base);
break;
case SIGTERM:
log_info("caught signal SIGTERM");
worker->need_to_restart = 0;
verbose(VERB_DETAIL, "caught signal SIGTERM");
worker->need_to_exit = 1;
comm_base_exit(worker->base);
break;
default:
@@ -863,7 +872,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
{
unsigned int seed;
int startport;
worker->need_to_restart = 0;
worker->need_to_exit = 0;
worker->base = comm_base_create();
if(!worker->base) {
log_err("could not create event handling base");
@@ -901,10 +910,12 @@ worker_init(struct worker* worker, struct config_file *cfg,
(((unsigned int)worker->thread_num)<<17);
/* shift thread_num so it does not match out pid bits */
if(!ub_initstate(seed, worker->rndstate, RND_STATE_SIZE)) {
seed = 0;
log_err("could not init random numbers.");
worker_delete(worker);
return 0;
}
seed = 0;
worker->front = listen_create(worker->base, ports,
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
worker_handle_request, worker);
@@ -917,8 +928,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
cfg->outgoing_num_ports * worker->thread_num;
worker->back = outside_network_create(worker->base,
cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
cfg->ifs, cfg->num_ifs, cfg->do_ip4, cfg->do_ip6, startport,
cfg->do_tcp?cfg->outgoing_num_tcp:0,
cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
startport, cfg->do_tcp?cfg->outgoing_num_tcp:0,
worker->daemon->env->infra_cache, worker->rndstate);
if(!worker->back) {
log_err("could not create outgoing sockets");
@@ -937,8 +948,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
}
/* we use the msg_buffer_size as a good estimate for what the
* user wants for memory usage sizes */
worker->scratchpad = region_create_custom(malloc, free,
cfg->msg_buffer_size, cfg->msg_buffer_size/4, 32, 1);
worker->scratchpad = regional_create_custom(cfg->msg_buffer_size);
if(!worker->scratchpad) {
log_err("malloc failure");
worker_delete(worker);
@@ -949,8 +959,11 @@ worker_init(struct worker* worker, struct config_file *cfg,
server_stats_init(&worker->stats);
alloc_init(&worker->alloc, &worker->daemon->superalloc,
worker->thread_num);
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
worker->env = *worker->daemon->env;
worker->env.worker = worker;
worker->env.send_packet = &worker_send_packet;
worker->env.send_query = &worker_send_query;
worker->env.alloc = &worker->alloc;
worker->env.rnd = worker->rndstate;
worker->env.scratch = worker->scratchpad;
@@ -980,9 +993,11 @@ worker_delete(struct worker* worker)
{
if(!worker)
return;
mesh_stats(worker->env.mesh, "mesh has");
server_stats_log(&worker->stats, worker->thread_num);
worker_mem_report(worker, NULL);
if(worker->env.mesh && verbosity >= VERB_OPS) {
mesh_stats(worker->env.mesh, "mesh has");
server_stats_log(&worker->stats, worker->thread_num);
worker_mem_report(worker, NULL);
}
mesh_delete(worker->env.mesh);
ldns_buffer_free(worker->env.scratch_buffer);
listen_delete(worker->front);
@@ -1001,7 +1016,7 @@ worker_delete(struct worker* worker)
close(worker->cmd_recv_fd);
worker->cmd_recv_fd = -1;
alloc_clear(&worker->alloc);
region_destroy(worker->scratchpad);
regional_destroy(worker->scratchpad);
free(worker);
}
@@ -1038,7 +1053,7 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
struct module_qstate* q)
{
struct worker* worker = q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)region_alloc(
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
q->region, sizeof(*e));
if(!e)
return NULL;
@@ -1052,3 +1067,11 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
}
return e;
}
void
worker_alloc_cleanup(void* arg)
{
struct worker* worker = (struct worker*)arg;
slabhash_clear(&worker->env.rrset_cache->table);
slabhash_clear(worker->env.msg_cache);
}
+30 -5
View File
@@ -57,7 +57,7 @@ struct config_file;
struct daemon;
struct listen_port;
struct ub_randstate;
struct region;
struct regional;
/** size of table used for random numbers. large to be more secure. */
#define RND_STATE_SIZE 256
@@ -99,14 +99,14 @@ struct worker {
/** random() table for this worker. */
struct ub_randstate* rndstate;
/** do we need to restart (instead of exit) ? */
int need_to_restart;
/** do we need to restart or quit (on signal) */
int need_to_exit;
/** allocation cache for this thread */
struct alloc_cache alloc;
/** per thread statistics */
struct server_stats stats;
/** thread scratch region */
struct region* scratchpad;
/** thread scratch regional */
struct regional* scratchpad;
/** module environment passed to modules, changed for this thread */
struct module_env env;
@@ -192,4 +192,29 @@ struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
struct sockaddr_storage* addr, socklen_t addrlen,
struct module_qstate* q);
/**
* process control messages from the main thread.
* @param c: comm point to read from.
* @param arg: worker.
* @param error: error status of comm point.
* @param reply_info: not used.
*/
int worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info);
/** handles callbacks from listening event interface */
int worker_handle_request(struct comm_point* c, void* arg, int error,
struct comm_reply* repinfo);
/** process incoming replies from the network */
int worker_handle_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info);
/** process incoming serviced query replies from the network */
int worker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info);
/** cleanup the cache to remove all rrset IDs from it, arg is worker */
void worker_alloc_cleanup(void* arg);
#endif /* DAEMON_WORKER_H */
+2
View File
@@ -5,3 +5,5 @@ from the University of California and from Verisign. The Java prototype
was made in further cooperation with Geoff Sisson and Roy Arends from Nominet.
At NLnet Labs, Jelte Jansen and Mark Santcroos reviewed the unbound C sources.
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
+293
View File
@@ -1,9 +1,302 @@
28 November 2007: Wouter
- Changeup plan for 0.8 - no complication needed, a simple solution
has been chosen for authoritative features.
- you can use single quotes in the config file, so it is possible
to specify TXT records in local data.
- fixup small memory problem in implicit transparent zone creation.
- test for implicit zone creation and multiple RR RRsets local data.
- local-zone nodefault test.
- show testbound testlist on commit.
- iterator normalizer changes CNAME chains ending in NXDOMAIN where
the packet got rcode NXDOMAIN into rcode NOERROR. (since the initial
domain exists).
- nicer verbosity: 0 and 1 levels.
- lower nonRDquery chance of eliciting wrongly typed validation
requiring message from the cache.
- fix for nonRDquery validation typing; nodata is detected when
SOA record in auth section (all validation-requiring nodata messages
have a SOA record in authority, so this is OK for the validator),
and NS record is needed to be a referral.
- duplicate checking when adding NSECs for a CNAME, and test.
27 November 2007: Wouter
- per suggestion in rfc2308, replaced default max-ttl value with 1 day.
- set size of msgparse lookup table to 32, from 1024, so that its size
is below the 2048 regional large size threshold, and does not cause
a call to malloc when a message is parsed.
- update of memstats tool to print number of allocation calls.
This is what is taking time (not space) and indicates the avg size
of the allocations as well. region_alloc stat is removed.
22 November 2007: Wouter
- noted EDNS in-the-middle dropping trouble as a TODO.
At this point theoretical, no user trouble has been reported.
- added all default AS112 zones.
- answers from local zone content.
* positive answer, the rrset in question
* nodata answer (exist, but not that type).
* nxdomain answer (domain does not exist).
* empty-nonterminal answer.
* But not: wildcard, nsec, referral, rrsig, cname/dname,
or additional section processing, NS put in auth.
- test for correct working of static and transparent and couple
of important defaults (localhost, as112, reverses).
Also checks deny and refuse settings.
- fixup implicit zone generation and AA bit for NXDOMAIN on localdata.
21 November 2007: Wouter
- local zone internal data setup.
20 November 2007: Wouter
- 0.8 - str2list config support for double string config options.
- local-zone and local-data options, config storage and documentation.
19 November 2007: Wouter
- do not downcase NSEC and RRSIG for verification. Follows
draft-ietf-dnsext-dnssec-bis-updates-06.txt.
- fixup leaking unbound daemons at end of tests.
- README file updated.
- nice libevent not found error.
- README talks about gnu make.
- 0.8: unit test for addr_mask and fixups for it.
and unit test for addr_in_common().
- 0.8: access-control config file element.
and unit test rpl replay file.
- 0.8: fixup address reporting from netevent.
16 November 2007: Wouter
- privilege separation is not needed in unbound at this time.
TODO item marked as such.
- created beta-0.7 branch for support.
- tagged 0.7 for beta release.
- moved trunk to 0.8 for 0.8(auth features) development.
- 0.8: access control list setup.
15 November 2007: Wouter
- review fixups from Jelte.
14 November 2007: Wouter
- testbed script does not recreate configure, since its in svn now.
- fixup checkconf test so that it does not test
/etc/unbound/unbound.conf.
- tag 0.6.
13 November 2007: Wouter
- remove debug print.
- fixup testbound exit when LIBEVENT_SIGNAL_PROBLEM exists.
12 November 2007: Wouter
- fixup signal handling where SIGTERM could be ignored if a SIGHUP
arrives later on.
- bugreports to unbound-bugs@nlnetlabs.nl
- fixup testbound so it exits cleanly.
- cleanup the caches on a reload, so that rrsetID numbers won't clash.
9 November 2007: Wouter
- took ldns snapshot in repo.
- default config file is /etc/unbound/unbound.conf.
If it doesn't exist, it is installed with the doc/example.conf file.
The file is not deleted on uninstall.
- default listening is not all, but localhost interfaces.
8 November 2007: Wouter
- Fixup chroot and drop user privileges.
- new L root ip address in default hints.
1 November 2007: Wouter
- Fixup of crash on reload, due to anchors in env not NULLed after
dealloc during deinit.
- Fixup of chroot call. Happens after privileges are dropped, so
that checking the passwd entry still works.
- minor touch up of clear() hashtable function.
- VERB_DETAIL prints out what chdir, username, chroot is being done.
- when id numbers run out, caches are cleared, as in design notes.
Tested with a mock setup with very few bits in id, it worked.
- harden-dnssec-stripped: yes is now default. It insists on dnssec
data for trust anchors. Included tests for the feature.
31 October 2007: Wouter
- cache-max-ttl config option.
- building outside sourcedir works again.
- defaults more secure:
username: "unbound"
chroot: "/etc/unbound"
The operator can override them to be less secure ("") if necessary.
- fix horrible oversight in sorting rrset references in a message,
sort per reference key pointer, not on referencepointer itself.
- pidfile: "/etc/unbound/unbound.pid" is now the default.
- tests changed to reflect the updated default.
- created hashtable clear() function that respects locks.
30 October 2007: Wouter
- fixup assertion failure that relied on compressed names to be
smaller than uncompressed names. A packet from comrite.com was seen
to be compressed to a larger size. Added it as unit test.
- quieter logging at low verbosity level for common tcp messages.
- no greedy TTL update.
23 October 2007: Wouter
- fixup (grand-)parent problem for dnssec-lameness detection.
- fixup tests to do additional section processing for lame replies,
since the detection needs that.
- no longer trust in query section in reply during dnssec lame detect.
- dnssec lameness does not make the server never ever queried, but
non-preferred. If no other servers exist or answer, the dnssec lame
server is used; the fastest dnssec lame server is chosen.
- added test then when trust anchor cannot be primed (nodata), the
insecure mode from unbound works.
- Fixup max queries per thread, any more are dropped.
22 October 2007: Wouter
- added donotquerylocalhost config option. Can be turned off for
out test cases.
- ISO C compat changes.
- detect RA-no-AA lameness, as LAME.
- DNSSEC-lameness detection, as LAME.
See notes in requirements.txt for choices made.
- tests for lameness detection.
- added all to make test target; need unbound for fwd tests.
- testbound does not pollute /etc/unbound.
19 October 2007: Wouter
- added configure (and its files) to svn, so that the trunk is easier
to use. ./configure, config.guess, config.sub, ltmain.sh,
and config.h.in.
- added yacc/lex generated files, util/configlexer.c,
util/configparser.c util/configparser.h, to svn.
- without lex no attempt to use it.
- unsecure response validation collated into one block.
- remove warning about const cast of cfgfile name.
- outgoing-interfaces can be different from service interfaces.
- ldns-src configure is done during unbound configure and
ldns-src make is done during unbound make, and so inherits the
make arguments from the unbound make invocation.
- nicer error when libevent problem causes instant exit on signal.
- read root hints from a root hint file (like BIND does).
18 October 2007: Wouter
- addresses are logged with errors.
- fixup testcode fake event to remove pending before callback
since the callback may create new pending items.
- tests updated because retries are now in iterator module.
- ldns-testpkts code is checked for differences between unbound
and ldns by makedist.sh.
- ldns trunk from today added in svn repo for fallback in case
no ldns is installed on the system.
make download_ldns refreshes the tarball with ldns svn trunk.
- ldns-src.tar.gz is used if no ldns is found on the system, and
statically linked into unbound.
- start of regional allocator code.
- regional uses less memory and variables, simplified code.
- remove of region-allocator.
- alloc cache keeps a cache of recently released regional blocks,
up to a maximum.
- make unit test cleanly free memory.
17 October 2007: Wouter
- fixup another cycle detect and ns-addr timeout resolution bug.
This time by refusing delegations from the cache without addresses
when resolving a mandatory-glue nameserver-address for that zone.
We're going to have to ask a TLD server anyway; might as well be
the TLD server for this name. And this resolves a lot of cases where
the other nameserver names lead to cycles or are not available.
- changed random generator from random(3) clone to arc4random wrapped
for thread safety. The random generator is initialised with
entropy from the system.
- fix crash where failure to prime DNSKEY tried to print null pointer
in the log message.
- removed some debug prints, only verb_algo (4) enables them.
- fixup test; new random generator took new paths; such as one
where no scripted answer was available.
- mark insecure RRs as insecure.
- fixup removal of nonsecure items from the additional.
- reduced timeout values to more realistic, 376 msec (262 msec has
90% of roundtrip times, 512 msec has 99% of roundtrip times.)
- server selection failover to next server after timeout (376 msec).
16 October 2007: Wouter
- no malloc in log_hex.
- assertions around system calls.
- protect against gethostname without ending zero.
- ntop output is null terminated by unbound.
- pidfile content null termination
- various snprintf use sizeof(stringbuf) instead of fixed constant.
- changed loopdetect % 8 with & 0x7 since % can become negative for
weird negative input and particular interpretation of integer math.
- dname_pkt_copy checks length of result, to protect result buffers.
prints an error, this should not happen. Bad strings should have
been rejected earlier in the program.
- remove a size_t underflow from msgreply size func.
15 October 2007: Wouter
- nicer warning.
- fix IP6 TCP, wrong definition check. With test package.
- fixup the fact that the query section was not compressed to,
the code was there but was called by value instead of by reference.
And test for the case, uses xxd and nc.
- more portable ip6 check for sockaddr types.
8 October 2007: Wouter
- --disable-rpath option in configure for 64bit systems with
several dynamic lib dirs.
7 October 2007: Wouter
- fixup tests for no AD bit in non-DO queries.
- test that makes sure AD bit is not set on non-DO query.
6 October 2007: Wouter
- removed logfile open early. It did not have the proper permissions;
it was opened as root instead of the user. And we cannot change user
id yet, since chroot and bind ports need to be done.
- callback checks for event callbacks done from mini_event. Because
of deletions cannot do this from netevent. This means when using
libevent the protection does not work on event-callbacks.
- fixup too small reply (did not zero counts).
- fixup reply no longer AD bit when query without DO bit.
5 October 2007: Wouter
- function pointer whitelist.
4 October 2007: Wouter
- overwrite sensitive random seed value after use.
- switch to logfile very soon if not -d (console attached).
- error messages do not reveal the trustanchor contents.
- start work on function pointer whitelists.
3 October 2007: Wouter
- fix for multiple empty nonterminals, after multiple DSes in the
chain of trust.
- mesh checks if modules are looping, and stops them.
- refetch with CNAMEd nameserver address regression test added.
- fixup line count bug in testcode, so testbound prints correct line
number with parse errors.
- unit test for multiple ENT case.
- fix for cname out of validated unsec zone.
- fixup nasty id=0 reuse. Also added assertions to detect its
return (the assertion catches in the existing test cases).
1 October 2007: Wouter
- skip F77, CXX, objC tests in configure step.
- fixup crash in refetch glue after a CNAME.
and protection against similar failures (with error print).
28 September 2007: Wouter
- test case for unbound-checkconf, fixed so it also checks the
interface: statements.
26 September 2007: Wouter
- SIGHUP will reopen the log file.
- Option to log to syslog.
- please lint, fixup tests (that went to syslog on open, oops).
- config check program.
25 September 2007: Wouter
- tests for NSEC3. Fixup bitmap checks for NSEC3.
- positive ANY response needs to check if wildcard expansion, and
check that original data did not exist.
- tests for NSEC3 that wrong use of OPTOUT is bad. For insecure
delegation, for abuse of child zone apex nsec3.
- create 0.5 release tag.
24 September 2007: Wouter
- do not make test programs by default.
+9 -2
View File
@@ -9,7 +9,7 @@ This software is under BSD license, see LICENSE for details.
or get a beta version from the svn repository at
http://unbound.net/svn/
* Needs the following libraries
* Uses the following libraries;
* ldns http://www.nlnetlabs.nl/ldns/ (BSD license)
* libevent http://www.monkey.org/~provos/libevent/ (BSD license)
@@ -18,10 +18,17 @@ This software is under BSD license, see LICENSE for details.
* autoreconf (autoheader && autoconf), if ./configure is missing.
* Make and install: ./configure; make; make install
* Use GNU make; default on linux, often called 'gmake' on BSD and Solaris.
* --with-ldns=/path/to/ldns
If ldns is not detected on the system, a prepackaged tarball
of the ldns library is used to compile and statically link against.
If detected on the system, it will dynamically link against it.
* --with-libevent=/path/to/libevent
Can be set to either the system install or the build directory.
--with-libevent=no gives a builtin alternative implementation.
libevent is useful when having many (thousands) of outgoing ports.
This improves randomization and spoof resistance. For the default
of 16 ports the builtin alternative works well.
* --without-pthreads
This disables pthreads, and uses Solaris thr library or no threading.
Without this option the pthreads library is detected automatically.
@@ -56,4 +63,4 @@ o Other code origins are from the NSD (NLnet Labs) and LDNS (NLnet Labs)
projects. Such as buffer, region-allocator and red-black tree code.
o See Credits file for contributors.
* mailto:wouter@nlnetlabs.nl
* mailto:unbound-bugs@nlnetlabs.nl
+5 -2
View File
@@ -1,6 +1,9 @@
README unbound tests
There is a test setup for unbound.
There is a test setup for unbound. Use
make test
To make and run the tests. The results are summarized at the end.
You can also run ./unittest by hand, if the system lacks other debug tools.
testdata/ contains the data for tests.
testcode/ contains scripts and c code for the tests.
@@ -8,4 +11,4 @@ testcode/ contains scripts and c code for the tests.
do-tests.sh : runs all the tests in the testdata directory.
testbed.sh : compiles on a set of (user specific) hosts and runs do-tests.
Tests are run using tpkg.
Tests are run using testcode/mini_tpkg.sh.
+8 -3
View File
@@ -23,7 +23,6 @@ o memory profile; and if needed put serviced queries under qstate->region
o check query, option to enforce presence of qdsection in noerror answers.
o configuration option where port 53 is used for send and receive, no other
ports are used.
o prime sequence in multiple queries, if glue missing from prime sequence.
o (option) to not send replies to clients after a timeout of (say 5 secs) has
passed, but keep task active for later retries by client.
o private TTL feature
@@ -49,7 +48,13 @@ o timers rfc 5011 support.
o Treat YXDOMAIN from a DNAME properly, in iterator (not throwaway), validator.
o grab ports nonconsequtive and change the set after a while (change within
a given range). Could be bad for OS if wrong port. unsure if it helps secure.
o workaround for nxdomain responses for ENT DS queries. Not look at rcode and
look at valid empty nonterminal proof that is inside the packet.
o make timeout backoffs randomized (a couple percent random) to spread traffic.
o inspect date on executable, then warn user in log if its more than 1 year.
o proactively prime root, stubs and trust anchors, feature.
early failure, faster on first query, but more traffic.
o use privilege separation, to change privilege options during reload securely
not needed.
o check if for PowerDNS(2.9.21) CNAME in Answer section & rcode=NXDOMAIN needs
to be fixed up to be rcode=NOERROR?
o On Windows use CryptGenRandom() to get random seed for arc4random.
o Think about intermediate firewalls dropping EDNS UDP & handling that.
+82 -10
View File
@@ -13,14 +13,16 @@ server:
# whitespace is not necessary, but looks cleaner.
# verbosity number, 0 is least verbose. 1 is default.
verbosity: 2
verbosity: 1
# number of threads to create. 1 disables threading.
# num-threads: 1
# specify the interfaces to answer queries from by ip-address.
# If you give none the default (all) interface is used.
# The default is to listen to localhost (127.0.0.1 and ::1).
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
# specify every interface on a new 'interface:' labelled line.
# The listen interfaces are not changed on reload, only on restart.
# interface: 192.0.2.153
# interface: 192.0.2.154
# interface: 2001:DB8::5
@@ -28,6 +30,13 @@ server:
# port to answer queries from
# port: 53
# specify the interfaces to send outgoing queries to authoritative
# server from by ip-address. If none, the default (all) interface
# is used. Specify every interface on a 'outgoing-interface:' line.
# outgoing-interface: 192.0.2.153
# outgoing-interface: 2001:DB8::5
# outgoing-interface: 2001:DB8::6
# unbound needs to send packets to authoritative nameservers.
# it uses a range of ports for that.
# the start number of the port range
@@ -69,6 +78,10 @@ server:
# the number of slabs must be a power of 2.
# more slabs reduce lock contention, but fragment memory usage.
# rrset-cache-slabs: 4
# the time to live (TTL) value cap for RRsets and messages in the
# cache. Items are not cached for longer. In seconds.
# cache-max-ttl: 86400
# the time to live (TTL) value for cached roundtrip times and
# EDNS version information for hosts. In seconds.
@@ -100,23 +113,43 @@ server:
# Enable TCP, "yes" or "no".
# do-tcp: yes
# control which clients are allowed to make (recursive) queries
# to this server. Specify classless netblocks with /size and action.
# By default everything is refused, except for localhost.
# Choose deny (drop message), refuse (polite error reply), allow.
# access-control: 0.0.0.0/0 refuse
# access-control: 127.0.0.0/8 allow
# access-control: ::0/0 refuse
# access-control: ::1 allow
# if given, a chroot(2) is done to the given directory.
# i.e. you can chroot to the working directory, for example,
# for extra security, but make sure all files are in that directory.
# chroot: "/some/directory"
# If you give "" no chroot is performed.
# chroot: "/etc/unbound"
# if given, user privileges are dropped (after binding port),
# and the given username is assumed. Default is nothing "".
# and the given username is assumed. Default is user "unbound".
# If you give "" no priviliges are dropped.
# username: "unbound"
# the working directory.
# directory: "/etc/unbound"
# the log file, "" means log to stderr.
# the log file, "" means log to stderr.
# Use of this option sets use-syslog to "no".
# logfile: ""
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
# log to, with identity "unbound". If yes, it overrides the logfile.
# use-syslog: yes
# the pid file.
# pidfile: "unbound.pid"
# pidfile: "/etc/unbound/unbound.pid"
# file to read root hints from.
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
# root-hints: ""
# enable to not answer id.server and hostname.bind queries.
# hide-identity: no
@@ -149,12 +182,21 @@ server:
# Harden against out of zone rrsets, to avoid spoofing attempts.
# harden-glue: yes
# Harden against receiving dnssec-stripped data. If you turn it
# off, failing to validate dnskey data for a trustanchor will
# trigger insecure mode for that zone (like without a trustanchor).
# Default on, which insists on dnssec data for trust-anchored zones.
# harden-dnssec-stripped: yes
# Do not query the following addresses. No DNS queries are sent there.
# List one address per entry. To block other ports than the default
# DNS port, use "1.2.3.4@123" to block port 123 for 1.2.3.4.
# do-not-query-address: 127.0.0.1
# List one address per entry. List classless netblocks with /size,
# do-not-query-address: 127.0.0.1/8
# do-not-query-address: ::1
# if yes, the above default do-not-query-address entries are present.
# if no, localhost can be queried (for testing and debugging).
# do-not-query-localhost: yes
# module configuration of the server. A string with identifiers
# separated by spaces. "iterator" or "validator iterator"
# module-config: "validator iterator"
@@ -213,6 +255,36 @@ server:
# more slabs reduce lock contention, but fragment memory usage.
# key-cache-slabs: 4
# a number of locally served zones can be configured.
# local-zone: <zone> <type>
# local-data: "<resource record string>"
# o deny serves local data (if any), else, drops queries.
# o refuse serves local data (if any), else, replies with error.
# o static serves local data, else, nxdomain or nodata answer.
# o transparent serves local data, else, resolves normally .
# o redirect serves the zone data for any subdomain in the zone.
# o nodefault can be used to normally resolve AS112 zones.
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
# the default content is omitted, or you can omit it with 'nodefault'.
#
# If you configure local-data without specifying local-zone, by
# default a transparent local-zone is created for the data.
#
# You can add locally served data with
# local-zone: "local." static
# local-data: "mycomputer.local. IN A 192.0.2.51"
# local-data: 'mytext.local TXT "content of text record"'
#
# You can override certain queries with
# local-data: "adserver.example.com A 127.0.0.1"
#
# You can redirect a domain to a fixed address with
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
# local-zone: "example.com" redirect
# local-data: "example.com A 192.0.2.3"
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
+18 -13
View File
@@ -153,7 +153,8 @@ Styleguide:
*** Bigger and Better
* Config file syntax checker program. Tests on checker.
* Logging first class feature with config options.
* with logfile turnover to avoid Gbs of logs.
X with logfile turnover to avoid Gbs of logs.
* use syslog optional.
* donotqueryaddresses with trie for blocking entire netblocks.
* Memory overhaul, special allocators for hashtable caches, and mesh qstates.
* keep a preallocated list of region-chunks per worker thread.
@@ -162,14 +163,15 @@ Styleguide:
to avoid name-collision with nsd regions, 'regional'.
* read root hints from file.
* failover to next server in 1 second, instead of 100 seconds on one server.
* failure to return answer, w. reason (donotq, noanswer servers, cannot
X failure to return answer, w. reason (donotq, noanswer servers, cannot
find servers, validationfail w.classification, error),
with threadno, starttime and endtime and qname/type/class, prime/qflags,
from-clients, from-internal, has-subrequests, a nice error report,
so that an excerpt from those times can be made from the logs.
logfileparsing tool that makes these excerpts and emails them.
Not done; user can change verbosity and kill -HUP.
* clear cache as a callback from the new-rrset-id routine.
* make overload mode work; phase 0 all ok, phase 1 some threads close ports,
X make overload mode work; phase 0 all ok, phase 1 some threads close ports,
to let other threads pick up work. phase 2, all threads closed, so all open
the ports again and drop all non-cache-reply queries.
Keep mutexed num-overloaded-threads counter. thread incs it when it hits
@@ -179,8 +181,10 @@ Styleguide:
if phase 1, start servicing, phase is 0 again. Make robust against delays.
readme: max about 1 second worth of incoming queries, 10k perhaps,
or 1/number of seconds it takes start up of 10k.
* should the source include a copy of the ldns lib for ease of building by
new users.
Not done. Implement drop when full.
* the source includes a copy of the ldns lib for ease of building by
new users. Detect system installed ldns, if installed ldns is OK; use
dynamic linking against it, otherwise static linking against packaged ldns.
* no greedy TTL algo (and test).
* maximum TTL, cap incoming values, and config option.
@@ -199,14 +203,18 @@ Styleguide:
can be used to block AS112 traffic, option to unblock a zone.
* after checking acl, do iter: static, blacklist, forwards, recurse.
* Forward-local-zone to NSD.
- include in package, autoforkexec on localhost to do so.
- in package, autoforkexec on localhost to do so.
- not included. Not necessary for localhost and AS112 service.
* forward local zone to remote server.
- not included. Not necessary for localhost and AS112 service.
* stub zones - send queries for a zone to configged nameserver.
- Can be used for complicated setups. So, run auth server on a
different port or pc, and stub it on the resolver. Resolver is
not auth for zones, but resolution works. This enforces the split
of recursive and auth servers.
* test local zones
* for speed
* for correctness on corner cases
* for validation
* in case you get data on localzone in an answer (from rootserver).
*** Library use
* Create library that can do:
@@ -236,11 +244,8 @@ Styleguide:
*** Features features
* aggressive negative caching for NSEC, NSEC3.
* multiple queries per question, server exploration, server selection.
* option to use real entropy for randomness (mix it in once in a while).
* check query, enforce qdsection, checking for forgery-resilience.
* NSID support.
* support TSIG on queries, for validating resolver deployment.
* Be able to prime roots using several queries (like, get only NS first).
* Nicer statistics
* private TTL, dTLS features.
* retry-mode, where a bogus result triggers a retry-mode query, where a list
@@ -302,10 +307,10 @@ treeshrew/
unbound.c for validating caching recursive dns server.
scheduler.c for the modules.
libunbound-all/
libunbound/
app linkable. Can be configged to do whatever,
validator, iterator, validating iterator, forwarding stub.
libunbound-fwd/
libforwardbound/
app linkable forwarding stub. Small lib.
ask_cachor/ *.c *.h
+79
View File
@@ -121,3 +121,82 @@ o The harden-glue feature, when yes all out of zone glue is deleted, when
as more glue is present for the recursive service to use. The feature
is implemented so as to minimise the security risk, while trying to
keep this performance gain.
o The method by which dnssec-lameness is detected is not secure. DNSSEC lame
is when a server has the zone in question, but lacks dnssec data, such as
signatures. The method to detect dnssec lameness looks at nonvalidated
data from the parent of a zone. This can be used, by spoofing the parent,
to create a false sense of dnssec-lameness in the child, or a false sense
or dnssec-non-lameness in the child. The first results in the server marked
lame, and not used for 900 seconds, and the second will result in a
validator failure (SERVFAIL again), when the query is validated later on.
Concluding, a spoof of the parent delegation can be used for many cases
of denial of service. I.e. a completely different NS set could be returned,
or the information withheld. All of these alterations can be caught by
the validator if the parent is signed, and result in 900 seconds bogus.
The dnssec-lameness detection is used to detect operator failures,
before the validator will properly verify the messages.
Also for zones for which no chain of trust exists, but a DS is given by the
parent, dnssec-lameness detection enables. This delivers dnnsec to our
clients when possible (for client validators).
The following issue needs to be resolved:
a server that serves both a parent and child zone, where
parent is signed, but child is not. The server must not be marked
lame for the parent zone, because the child answer is not signed.
Instead of a false positive, we want false negatives; failure to
detect dnssec-lameness is less of a problem than marking honest
servers lame. dnssec-lameness is a config error and deserves the trouble.
So, only messages that identify the zone are used to mark the zone
lame. The zone is identified by SOA or NS RRsets in the answer/auth.
That includes almost all negative responses and also A, AAAA qtypes.
That would be most responses from servers.
For referrals, delegations that add a single label can be checked to be
from their zone, this covers most delegation-centric zones.
So possibly, for complicated setups, with multiple (parent-child) zones
on a server, dnssec-lameness detection does not work - no dnssec-lameness
is detected. Instead the zone that is dnssec-lame becomes bogus.
o authority features.
This is a recursive server, and authority features are out of scope.
However, some authority features are expected in a recursor. Things like
localhost, reverse lookup for 127.0.0.1, or blocking AS112 traffic.
Also redirection of domain names with fixed data is needed by service
providers. Limited support is added specifically to address this.
Adding full authority support, requires much more code, and more complex
maintenance.
The limited support allows adding some static data (for localhost and so),
and to respond with a fixed rcode (NXDOMAIN) for domains (such as AS112).
You can put authority data on a separate server, and set the server in
unbound.conf as stub for those zones, this allows clients to access data
from the server without making unbound authoritative for the zones.
o the access control denies queries before any other processing.
This denies queries that are not authoritative, or version.bind, or any.
And thus prevents cache-snooping (denied hosts cannot make non-recursive
queries and get answers from the cache).
o If a client makes a query without RD bit, in the case of a returned
message from cache which is:
answer section: empty
auth section: NS record present, no SOA record, no DS record,
maybe NSEC or NSEC3 records present.
additional: A records or other relevant records.
A SOA record would indicate that this was a NODATA answer.
A DS records would indicate a referral.
Absence of NS record would indicate a NODATA answer as well.
Then the receiver does not know whether this was a referral
with attempt at no-DS proof) or a nodata answer with attempt
at no-data proof. It could be determined by attempting to prove
either condition; and looking if only one is valid, but both
proofs could be valid, or neither could be valid, which creates
doubt. This case is validated by unbound as a 'referral' which
ascertains that RRSIGs are OK (and not omitted), but does not
check NSEC/NSEC3.
+45
View File
@@ -0,0 +1,45 @@
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.Dd @date@
.Dt unbound-checkconf 8
.Sh NAME
unbound-checkconf
.Nd Check unbound configuration file for errors.
.Sh SYNOPSIS
.Nm unbound-checkconf
.Op Fl h
.Op cfgfile
.Sh DESCRIPTION
.Ic Unbound-checkconf
checks the configuration file for the
.Xr unbound 8
DNS resolver for syntax and other errors.
The config file syntax is
described in
.Xr unbound.conf 5 .
.Pp
The available options are:
.Bl -tag -width indent
.It Fl h
Show the version and commandline option help.
.It cfgfile
The config file to read with settings for unbound. It is checked.
If omitted, the config file at the default location is checked.
.Sh EXIT CODE
The unbound-checkconf program exits with status code 1 on error,
0 for a correct config file.
.El
.Sh FILES
.Bl -tag -width indent
.It Pa /etc/unbound/unbound.conf
unbound configuration file.
.El
.Sh SEE ALSO
.Xr unbound.conf 5 ,
.Xr unbound 8 .
+6 -3
View File
@@ -27,18 +27,21 @@ The available options are:
.It Fl h
Show the version and commandline option help.
.It Fl c Ar cfgfile
Set the config file to read with settings for unbound. The syntax is
Set the config file with settings for unbound to read instead of the
file at default location /etc/unbound/unbound.conf. The syntax is
described in
.Xr unbound.conf 5 .
.It Fl d
Debug flag, do not fork into the background, but stay attached to the
console.
console. This flag will also delay writing to the logfile until the
thread-spawn time. So that most config and setup errors appear on stderr.
.It Fl v
Increase verbosity. If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.El
.Sh SEE ALSO
.Xr unbound.conf 5 .
.Xr unbound.conf 5 ,
.Xr unbound-checkconf 8 .
.Sh AUTHORS
.Ic Unbound
developers are mentioned in the CREDITS file in the distribution.
+191 -16
View File
@@ -23,6 +23,10 @@ The notation is: attribute: value.
.Pp
Comments start with # and last to the end of line. Empty lines are
ignored as is whitespace at the beginning of a line.
.Pp
The utility
.Xr unbound-checkconf 8
can be used to check unbound.conf prior to usage.
.Sh EXAMPLE
An example config file is shown below. Copy this to /etc/unbound/unbound.conf
and start the server with:
@@ -39,11 +43,17 @@ example.conf file with all the options.
# unbound.conf(5) config file for unbound(8).
server:
directory: "/etc/unbound"
username: unbound # make sure it can write to pidfile, logfile.
username: unbound # make sure it can write to pidfile.
chroot: "/etc/unbound"
logfile: "/etc/unbound/unbound.log"
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
pidfile: "/etc/unbound/unbound.pid"
# verbosity: 1 # uncomment and increase to get more logging.
# listen on all interfaces, answer queries from the local subnet.
interface: 0.0.0.0
interface: ::0
access-control: 10.0.0.0/8 allow
access-control: 2001:DB8::/64 allow
.fi
.Sh FILE FORMAT
There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute
@@ -55,7 +65,7 @@ directive. It can appear anywhere, and takes a single filename as an argument.
Processing continues as if the text from the included file was copied into
the config file at that point.
.Ss Server Options
There may only be one
These options are part of the
.Ic server:
clause.
.Bl -tag -width indent
@@ -71,8 +81,21 @@ The number of threads to create to serve clients. Use 1 for no threading.
.It \fBport:\fR <port number>
The port number, default 53, on which the server responds to queries.
.It \fBinterface:\fR <ip address>
Interface to use to connect to the network. Can be given multiple times to
work on several interfaces. If none are given the default (all) is used.
Interface to use to connect to the network. This interface is listened to
for queries from clients, and answers to clients are given from it.
Can be given multiple times to work on several interfaces. If none are
given the default is to listen to localhost.
The interfaces are not changed on a reload (kill -HUP) but only on restart.
.It \fBoutgoing-interface:\fR <ip address>
Interface to use to connect to the network. This interface is used to send
queries to authoritative servers and receive their replies. Can be given
multiple times to work on several interfaces. If none are given the
default (all) is used. You can specify the same interfaces in
.Ic interface:
and
.Ic outgoing-interface:
lines, the interfaces are then used for both purposes. Outgoing queries are
sent via a random outgoing interface to counter spoofing.
.It \fBoutgoing-port:\fR <port number>
The starting port number where the outgoing query port range is allocated.
Default is 1053.
@@ -101,11 +124,21 @@ Must be set to a power of 2. Setting (close) to the number of cpus is a
reasonable guess.
.It \fBnum-queries-per-thread:\fR <number>
The number of queries that every thread will service simultaneously.
If more queries arrive that need servicing, they are dropped. This forces
the client to resend after a timeout; allowing the server time to work on
the existing queries. Default 1024.
.It \fBrrset-cache-size:\fR <number>
Number of bytes size of the RRset cache. Default is 4 megabytes.
.It \fBrrset-cache-slabs:\fR <number>
Number of slabs in the RRset cache. Slabs reduce lock contention by threads.
Must be set to a power of 2.
.It \fBcache-max-ttl:\fR <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.
Can be set lower to force the resolver to query for data often, and not
trust (very large) TTL values.
.It \fBinfra-host-ttl:\fR <seconds>
Time to live for entries in the host cache. The host cache contains
roundtrip timing and EDNS support information. Default is 900.
@@ -128,11 +161,19 @@ Enable or disable whether ip6 queries are answered. Default is yes.
Enable or disable whether UDP queries are answered. Default is yes.
.It \fBdo-tcp:\fR <yes or no>
Enable or disable whether TCP queries are answered. Default is yes.
.It \fBaccess-control:\fR <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 deny, refuse or allow.
Deny stops queries from hosts from that netblock.
Refuse stops queries too, but sends a DNS rcode REFUSED error message back.
Allow gives access to clients from that netblock.
By default only localhost is allowed, the rest is refused.
.It \fBchroot:\fR <directory>
If given a chroot is done to the given directory. The default is none ("").
If given a chroot is done to the given directory. The default is
"/etc/unbound". If you give "" no chroot is performed.
.It \fBusername:\fR <name>
If given, after binding the port the user privileges are dropped. Default is
not to change user, username: "".
"unbound". If you give username: "" no user change is performed.
.Pp
If this user is not capable of binding the
port, reloads (by signal HUP) will still retain the opened ports.
@@ -144,10 +185,31 @@ Sets the working directory for the program.
If "" is given, logging goes to stderr, or nowhere once daemonized.
The logfile is appended to, in the following format:
[seconds since 1970] unbound[pid:tid]: type: message.
If this option is given, the use-syslog is option is set to "no".
The logfile is reopened (for append) when the config file is reread, on
SIGHUP.
.It \fBuse-syslog:\fR <yes or no>
Sets unbound to send log messages to the syslogd, using
.Xr syslog 3 .
The log facility LOG_DAEMON is used, with identity "unbound".
The logfile setting is overridden when use-syslog is turned on.
The default is to log to syslog.
.It \fBpidfile:\fR <filename>
The process id is written to the file. Default is "unbound.pid". So,
kill -HUP `cat /etc/unbound/unbound.pid` will trigger a reload,
kill -QUIT `cat /etc/unbound/unbound.pid` will gracefully terminate.
The process id is written to the file. Default is "/etc/unbound/unbound.pid".
So,
.nf
kill -HUP `cat /etc/unbound/unbound.pid`
.fi
triggers a reload,
.nf
kill -QUIT `cat /etc/unbound/unbound.pid`
.fi
gracefully terminates.
.It \fBroot-hints:\fR <filename>
Read the root hints from this file. Default is nothing, using builtin hints
for the IN class. The file has the format of zone files, with root
nameserver names and addresses only. The default may become outdated,
when servers change, therefore it is good practice to use a root-hints file.
.It \fBhide-identity:\fR <yes or no>
If enabled id.server and hostname.bind queries are refused.
.It \fBidentity:\fR <string>
@@ -183,10 +245,23 @@ wise to send these, and could be necessary for operation if TSIG or EDNS
payload is very large.
.It \fBharden-glue:\fR <yes or no>
Will trust glue only if it is within the servers authority. Default is on.
.It \fBharden-dnssec-stripped:\fR <yes or no>
Require DNSSEC data for trust-anchored zones, if such data is absent,
the zone becomes bogus. If turned off, and no DNSSEC data is received
(or the DNSKEY data fails to validate), then the zone is made insecure,
this behaves like there is no trust anchor. You could turn this off if
you are sometimes behind an intrusive firewall (of some sort) that
removes DNSSEC data from packets, or a zone changes from signed to
unsigned to badly signed often. If turned off you run the risk of a
downgrade attack that disables security for a zone. Default is on.
.It \fBdo-not-query-address:\fR <IP address>
Do not query the given IP address. Can be IP4 or IP6. By default the
DNS port is blocked for that address. Appending the character '@' and then
the portnumber will block other port numbers.
Do not query the given IP address. Can be IP4 or IP6. Append /num to
indicate a classless delegation netblock, for example like
10.2.3.4/24 or 2001::11/64.
.It \fBdo-not-query-localhost:\fR <yes or no>
If yes, localhost is added to the do-not-query-address entries, both
IP6 ::1 and IP4 127.0.0.1/8. If no, then localhost can be used to send
queries to. Default is yes.
.It \fBmodule-config:\fR <"module names">
Module configuration, a list of module names separated by spaces, surround
the string with quotes (""). The modules can be validator, iterator.
@@ -246,6 +321,102 @@ Number of bytes size of the key cache. Default is 4 megabytes.
Number of slabs in the key cache. Slabs reduce lock contention by threads.
Must be set to a power of 2. Setting (close) to the number of cpus is a
reasonable guess.
.It \fBlocal-zone:\fR <zone> <type>
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, 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.
.Bl -tag -width indent
.It \fIdeny\fR
Do not send an answer, drop the query.
If there is a match from local data, the query is answered.
.It \fIrefuse\fR
Send an error message reply, with rcode REFUSED.
If there is a match from local data, the query is answered.
.It \fIstatic\fR
If there is a match from local data, the query is answered.
Otherwise, the query is answered with nodata or nxdomain.
For a negative answer a SOA is included in the answer if present
as local-data for the zone apex domain.
.It \fItransparent\fR
If there is a match from local data, the query is answered.
Otherwise, the query is resolved normally.
If no local-zone is given local-data causes a transparent zone
to be created by default.
.It \fIredirect\fR
The query is answered from the local data for the zone name.
There may be no local data beneath the zone name.
This answers queries for the zone, and all subdomains of the zone
with the local data for the zone.
It can be used to redirect a domain to a different address, with
local-zone: "example.com." redirect and
local-data: "example.com. A 127.0.0.1"
queries for www.example.com and www.foo.example.com are redirected.
.It \fInodefault\fR
Used to turn off default contents for AS112 zones. The other types
also turn off default contents for the zone. The 'nodefault' option
has no other effect than turning off default contents for the
given zone.
.El
The default zones are localhost, reverse 127.0.0.1 and ::1, and the AS112
zones. The AS112 zones are reverse DNS zones for private use and reserved
IP addresses for which the servers on the internet cannot provide correct
answers. They are configured by default to give nxdomain (no reverse
information) answers. The defaults can be turned off by specifying your
own local-zone of that name, or using the 'nodefault' type. Below is a
list of the default zone contents.
.Bl -tag -width indent
.It \fIlocalhost\fR
The IP4 and IP6 localhost information is given. NS and SOA records are provided
for completeness and to satisfy some DNS update tools. Default content:
.nf
local-zone: "localhost." static
local-data: "localhost. 10800 IN NS localhost."
local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "localhost. 10800 IN A 127.0.0.1"
local-data: "localhost. 10800 IN AAAA ::1"
.fi
.It \fIreverse IPv4 loopback\fR
Default content:
.nf
local-zone: "127.in-addr.arpa." static
local-data: "127.in-addr.arpa. 10800 IN NS localhost."
local-data: "127.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost."
.fi
.It \fIreverse IPv6 loopback\fR
Default content:
.nf
local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." static
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost."
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost."
.fi
.It \fIreverse RFC1918 local use zones\fR
Reverse data for zones 10.in-addr.arpa, 16.172.in-addr.arpa to
31.172.in-addr.arpa, 168.192.in-addr.arpa.
The \fBlocal-zone:\fR is set static and as \fBlocal-data:\fR SOA and NS
records are provided.
.It \fIreverse RFC3330 IP4 this, link-local, testnet and broadcast\fR
Reverse data for zones 0.in-addr.arpa, 254.169.in-addr.arpa,
2.0.192.in-addr.arpa, 255.255.255.255.in-addr.arpa.
.It \fIreverse RFC4291 IP6 unspecified\fR
Reverse data for zone 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.
.It \fIreverse RFC4193 IPv6 Locally Assigned Local Addresses\fR
Reverse data for zone D.F.ip6.arpa.
.It \fIreverse RFC4291 IPv6 Link Local Addresses\fR
Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa.
.El
.\" End of local-zone listing.
.It \fBlocal-data:\fR "<resource record string>"
Configure local data, which is served in reply to queries for it.
The query has to match exactly unless you configure the local-zone as
redirect. If not matched exactly, the local-zone type determines
further processing. If local-data is configured that is not a subdomain of
a local-zone, a transparent local-zone is configured.
For record types such as TXT, use single quotes, as in
local-data: 'example. TXT "text"'.
.El
.Ss Stub Zone Options
There may be multiple
@@ -311,16 +482,20 @@ server:
.Sh FILES
.Bl -tag -width indent
.It Pa /etc/unbound
default unbound working directory
default unbound working directory and default
.Xr chroot 2
location.
.It Pa unbound.conf
unbound configuration file.
.It Pa unbound.pid
default unbound pidfile with process ID of the running daemon.
.It Pa unbound.log
unbound log file.
unbound log file. default is to log to
.Xr syslog 3 .
.El
.Sh SEE ALSO
.Xr unbound 8
.Xr unbound 8 ,
.Xr unbound-checkconf 8 .
.Sh AUTHORS
.Ic Unbound
was written by NLnet Labs. Please see CREDITS file
+2 -1
View File
@@ -495,7 +495,8 @@ EXCLUDE = ./build \
util/configparser.c \
util/configparser.h \
util/configlexer.c \
util/locks.h
util/locks.h \
./ldns-src
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
+23 -19
View File
@@ -42,23 +42,24 @@
#include "config.h"
#include "iterator/iter_delegpt.h"
#include "services/cache/dns.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/data/dname.h"
#include "util/data/packed_rrset.h"
#include "util/data/msgreply.h"
#include "util/net_help.h"
struct delegpt*
delegpt_create(struct region* region)
delegpt_create(struct regional* region)
{
struct delegpt* dp=(struct delegpt*)region_alloc(region, sizeof(*dp));
struct delegpt* dp=(struct delegpt*)regional_alloc(
region, sizeof(*dp));
if(!dp)
return NULL;
memset(dp, 0, sizeof(*dp));
return dp;
}
struct delegpt* delegpt_copy(struct delegpt* dp, struct region* region)
struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
{
struct delegpt* copy = delegpt_create(region);
struct delegpt_ns* ns;
@@ -80,15 +81,15 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct region* region)
}
int
delegpt_set_name(struct delegpt* dp, struct region* region, uint8_t* name)
delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name)
{
dp->namelabs = dname_count_size_labels(name, &dp->namelen);
dp->name = region_alloc_init(region, name, dp->namelen);
dp->name = regional_alloc_init(region, name, dp->namelen);
return dp->name != 0;
}
int
delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name)
delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name)
{
struct delegpt_ns* ns;
size_t len;
@@ -97,14 +98,14 @@ delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name)
* adding the same server as a dependency twice */
if(delegpt_find_ns(dp, name, len))
return 1;
ns = (struct delegpt_ns*)region_alloc(region,
ns = (struct delegpt_ns*)regional_alloc(region,
sizeof(struct delegpt_ns));
if(!ns)
return 0;
ns->next = dp->nslist;
ns->namelen = len;
dp->nslist = ns;
ns->name = region_alloc_init(region, name, ns->namelen);
ns->name = regional_alloc_init(region, name, ns->namelen);
ns->resolved = 0;
return 1;
}
@@ -124,7 +125,7 @@ delegpt_find_ns(struct delegpt* dp, uint8_t* name, size_t namelen)
}
int
delegpt_add_target(struct delegpt* dp, struct region* region,
delegpt_add_target(struct delegpt* dp, struct regional* region,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
socklen_t addrlen)
{
@@ -138,10 +139,10 @@ delegpt_add_target(struct delegpt* dp, struct region* region,
}
int
delegpt_add_addr(struct delegpt* dp, struct region* region,
delegpt_add_addr(struct delegpt* dp, struct regional* region,
struct sockaddr_storage* addr, socklen_t addrlen)
{
struct delegpt_addr* a = (struct delegpt_addr*)region_alloc(region,
struct delegpt_addr* a = (struct delegpt_addr*)regional_alloc(region,
sizeof(struct delegpt_addr));
if(!a)
return 0;
@@ -152,6 +153,7 @@ delegpt_add_addr(struct delegpt* dp, struct region* region,
dp->usable_list = a;
memcpy(&a->addr, addr, addrlen);
a->addrlen = addrlen;
a->attempts = 0;
return 1;
}
@@ -189,12 +191,14 @@ delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
}
}
void delegpt_log(struct delegpt* dp)
void delegpt_log(enum verbosity_value v, struct delegpt* dp)
{
char buf[LDNS_MAX_DOMAINLEN+1];
struct delegpt_ns* ns;
struct delegpt_addr* a;
size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0;
if(verbosity < v)
return;
dname_str(dp->name, buf);
if(dp->nslist == NULL && dp->target_list == NULL) {
log_info("DelegationPoint<%s>: empty", buf);
@@ -212,7 +216,7 @@ void delegpt_log(struct delegpt* dp)
log_info(" %s%s", buf, (ns->resolved?"*":""));
}
for(a = dp->target_list; a; a = a->next_target) {
log_addr(" ", &a->addr, a->addrlen);
log_addr(VERB_ALGO, " ", &a->addr, a->addrlen);
}
}
}
@@ -253,7 +257,7 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
}
struct delegpt*
delegpt_from_message(struct dns_msg* msg, struct region* region)
delegpt_from_message(struct dns_msg* msg, struct regional* region)
{
struct ub_packed_rrset_key* ns_rrset = NULL;
struct delegpt* dp;
@@ -302,7 +306,7 @@ delegpt_from_message(struct dns_msg* msg, struct region* region)
}
int
delegpt_rrset_add_ns(struct delegpt* dp, struct region* region,
delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* ns_rrset)
{
struct packed_rrset_data* nsdata = (struct packed_rrset_data*)
@@ -321,7 +325,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct region* region,
}
int
delegpt_add_rrset_A(struct delegpt* dp, struct region* region,
delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* ak)
{
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
@@ -344,7 +348,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct region* region,
}
int
delegpt_add_rrset_AAAA(struct delegpt* dp, struct region* region,
delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* ak)
{
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
@@ -367,7 +371,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct region* region,
}
int
delegpt_add_rrset(struct delegpt* dp, struct region* region,
delegpt_add_rrset(struct delegpt* dp, struct regional* region,
struct ub_packed_rrset_key* rrset)
{
if(!rrset)
+30 -24
View File
@@ -42,7 +42,8 @@
#ifndef ITERATOR_ITER_DELEGPT_H
#define ITERATOR_ITER_DELEGPT_H
struct region;
#include "util/log.h"
struct regional;
struct delegpt_ns;
struct delegpt_addr;
struct dns_msg;
@@ -103,55 +104,59 @@ struct delegpt_addr {
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** number of attempts for this addr */
int attempts;
};
/**
* Create new delegation point.
* @param region: where to allocate it.
* @param regional: where to allocate it.
* @return new delegation point or NULL on error.
*/
struct delegpt* delegpt_create(struct region* region);
struct delegpt* delegpt_create(struct regional* regional);
/**
* Create a copy of a delegation point.
* @param dp: delegation point to copy.
* @param region: where to allocate it.
* @param regional: where to allocate it.
* @return new delegation point or NULL on error.
*/
struct delegpt* delegpt_copy(struct delegpt* dp, struct region* region);
struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* regional);
/**
* Set name of delegation point.
* @param dp: delegation point.
* @param region: where to allocate the name copy.
* @param regional: where to allocate the name copy.
* @param name: name to use.
* @return false on error.
*/
int delegpt_set_name(struct delegpt* dp, struct region* region, uint8_t* name);
int delegpt_set_name(struct delegpt* dp, struct regional* regional,
uint8_t* name);
/**
* Add a name to the delegation point.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param name: domain name in wire format.
* @return false on error.
*/
int delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name);
int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
uint8_t* name);
/**
* Add NS rrset; calls add_ns repeatedly.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param ns_rrset: NS rrset.
* return 0 on alloc error.
*/
int delegpt_rrset_add_ns(struct delegpt* dp, struct region* region,
int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* ns_rrset);
/**
* Add target address to the delegation point.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param name: name for which target was found (must be in nslist).
* This name is marked resolved.
* @param namelen: length of name.
@@ -159,49 +164,49 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct region* region,
* @param addrlen: the length of addr.
* @return false on error.
*/
int delegpt_add_target(struct delegpt* dp, struct region* region,
int delegpt_add_target(struct delegpt* dp, struct regional* regional,
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
socklen_t addrlen);
/**
* Add A RRset to delegpt.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param rrset: RRset A to add.
* @return 0 on alloc error.
*/
int delegpt_add_rrset_A(struct delegpt* dp, struct region* region,
int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset);
/**
* Add AAAA RRset to delegpt.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param rrset: RRset AAAA to add.
* @return 0 on alloc error.
*/
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct region* region,
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset);
/**
* Add any RRset to delegpt.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param rrset: RRset to add, NS, A, AAAA.
* @return 0 on alloc error.
*/
int delegpt_add_rrset(struct delegpt* dp, struct region* region,
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
struct ub_packed_rrset_key* rrset);
/**
* Add address to the delegation point. No servername is associated or checked.
* @param dp: delegation point.
* @param region: where to allocate the info.
* @param regional: where to allocate the info.
* @param addr: the address.
* @param addrlen: the length of addr.
* @return false on error.
*/
int delegpt_add_addr(struct delegpt* dp, struct region* region,
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
struct sockaddr_storage* addr, socklen_t addrlen);
/**
@@ -216,9 +221,10 @@ struct delegpt_ns* delegpt_find_ns(struct delegpt* dp, uint8_t* name,
/**
* Print the delegation point to the log. For debugging.
* @param v: verbosity value that is needed to emit to log.
* @param dp: delegation point.
*/
void delegpt_log(struct delegpt* dp);
void delegpt_log(enum verbosity_value v, struct delegpt* dp);
/**
* Add all usable targets to the result list.
@@ -247,11 +253,11 @@ size_t delegpt_count_missing_targets(struct delegpt* dp);
* find "glue" in either the ADDITIONAL section or the ANSWER section.
*
* @param msg: the dns message, referral.
* @param region: where to allocate delegation point.
* @param regional: where to allocate delegation point.
* @return new delegation point or NULL on alloc error, or if the
* message was not appropriate.
*/
struct delegpt* delegpt_from_message(struct dns_msg* msg,
struct region* region);
struct regional* regional);
#endif /* ITERATOR_ITER_DELEGPT_H */
+92 -21
View File
@@ -43,18 +43,24 @@
*/
#include "config.h"
#include "iterator/iter_donotq.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
/** compare two donotq entries */
static int
int
donotq_cmp(const void* k1, const void* k2)
{
struct iter_donotq_addr* n1 = (struct iter_donotq_addr*)k1;
struct iter_donotq_addr* n2 = (struct iter_donotq_addr*)k2;
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr, n2->addrlen);
int r = sockaddr_cmp_addr(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
if(r != 0) return r;
if(n1->net < n2->net)
return -1;
if(n1->net > n2->net)
return 1;
return 0;
}
struct iter_donotq*
@@ -64,7 +70,7 @@ donotq_create()
sizeof(struct iter_donotq));
if(!dq)
return NULL;
dq->region = region_create(malloc, free);
dq->region = regional_create();
if(!dq->region) {
donotq_delete(dq);
return NULL;
@@ -77,7 +83,7 @@ donotq_delete(struct iter_donotq* dq)
{
if(!dq)
return;
region_destroy(dq->region);
regional_destroy(dq->region);
free(dq->tree);
free(dq);
}
@@ -85,17 +91,37 @@ donotq_delete(struct iter_donotq* dq)
/** insert new address into donotq structure */
static int
donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
socklen_t addrlen)
socklen_t addrlen, int net)
{
struct iter_donotq_addr* node = region_alloc(dq->region,
struct iter_donotq_addr* node = regional_alloc(dq->region,
sizeof(struct iter_donotq_addr));
if(!node)
return 0;
node->node.key = node;
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
if(!rbtree_insert(dq->tree, &node->node)) {
log_warn("duplicate donotquery address ignored.");
verbose(VERB_DETAIL, "duplicate donotquery address ignored.");
}
return 1;
}
/** apply donotq string */
static int
donotq_str_cfg(struct iter_donotq* dq, const char* str)
{
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse donotquery netblock: %s", str);
return 0;
}
if(!donotq_insert(dq, &addr, addrlen, net)) {
log_err("out of memory");
return 0;
}
return 1;
}
@@ -105,23 +131,42 @@ static int
read_donotq(struct iter_donotq* dq, struct config_file* cfg)
{
struct config_strlist* p;
struct sockaddr_storage addr;
socklen_t addrlen;
for(p = cfg->donotqueryaddrs; p; p = p->next) {
log_assert(p->str);
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
log_err("cannot parse donotquery ip address: '%s'",
p->str);
if(!donotq_str_cfg(dq, p->str))
return 0;
}
if(!donotq_insert(dq, &addr, addrlen)) {
log_err("out of memory");
return 0;
}
}
return 1;
}
/** initialise parent pointers in the tree */
static void
donotq_init_parents(struct iter_donotq* donotq)
{
struct iter_donotq_addr* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct iter_donotq_addr*, donotq->tree) {
node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) {
prev = node;
continue;
}
m = addr_in_common(&prev->addr, prev->net, &node->addr,
node->net, node->addrlen);
/* sort order like: ::/0, 1::/2, 1::/4, ... 2::/2 */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
if(p->net <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
int
donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
{
@@ -131,6 +176,13 @@ donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
return 0;
if(!read_donotq(dq, cfg))
return 0;
if(cfg->donotquery_localhost) {
if(!donotq_str_cfg(dq, "127.0.0.0/8"))
return 0;
if(!donotq_str_cfg(dq, "::1"))
return 0;
}
donotq_init_parents(dq);
return 1;
}
@@ -139,12 +191,31 @@ donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
socklen_t addrlen)
{
/* lookup in the tree */
rbnode_t* res = NULL;
struct iter_donotq_addr* result;
struct iter_donotq_addr key;
key.node.key = &key;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
if(rbtree_search(donotq->tree, &key))
key.net = (addr_is_ip6(addr, addrlen)?128:32);
if(rbtree_find_less_equal(donotq->tree, &key, &res)) {
/* exact */
return 1;
} else {
/* smaller element (or no element) */
int m;
result = (struct iter_donotq_addr*)res;
if(!result || result->addrlen != addrlen)
return 0;
/* count number of bits matched */
m = addr_in_common(&result->addr, result->net, addr,
key.net, addrlen);
while(result) { /* go up until addr is inside netblock */
if(result->net <= m)
return 1;
result = result->parent;
}
}
return 0;
}
@@ -152,5 +223,5 @@ size_t
donotq_get_mem(struct iter_donotq* donotq)
{
if(!donotq) return 0;
return sizeof(*donotq) + region_get_mem(donotq->region);
return sizeof(*donotq) + regional_get_mem(donotq->region);
}
+12 -6
View File
@@ -45,16 +45,16 @@
#include "util/rbtree.h"
struct iter_env;
struct config_file;
struct region;
struct regional;
/**
* Iterator donotqueryaddresses structure
*/
struct iter_donotq {
/** region for allocation */
struct region* region;
/** regional for allocation */
struct regional* region;
/**
* Tree of the single addresses that are blocked.
* Tree of the address spans that are blocked.
* contents of type iter_donotq_addr.
*/
rbtree_t* tree;
@@ -62,15 +62,19 @@ struct iter_donotq {
/**
* Iterator donotquery address.
* A single address that must not be used to send queries to.
* An address span that must not be used to send queries to.
*/
struct iter_donotq_addr {
/** redblacktree node, key is this structure: addr and addrlen */
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** netblock size */
int net;
/** parent node in donotq tree that encompasses this entry */
struct iter_donotq_addr* parent;
};
/**
@@ -110,5 +114,7 @@ int donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
*/
size_t donotq_get_mem(struct iter_donotq* donotq);
/** compare two donotq entries */
int donotq_cmp(const void* k1, const void* k2);
#endif /* ITERATOR_ITER_DONOTQ_H */
+9 -10
View File
@@ -42,14 +42,13 @@
#include "config.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_delegpt.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/data/dname.h"
/** compare two fwd entries */
static int
int
fwd_cmp(const void* k1, const void* k2)
{
int m;
@@ -71,7 +70,7 @@ forwards_create()
sizeof(struct iter_forwards));
if(!fwd)
return NULL;
fwd->region = region_create(malloc, free);
fwd->region = regional_create();
if(!fwd->region) {
forwards_delete(fwd);
return NULL;
@@ -84,7 +83,7 @@ forwards_delete(struct iter_forwards* fwd)
{
if(!fwd)
return;
region_destroy(fwd->region);
regional_destroy(fwd->region);
free(fwd->tree);
free(fwd);
}
@@ -93,13 +92,13 @@ forwards_delete(struct iter_forwards* fwd)
static int
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
{
struct iter_forward_zone* node = region_alloc(fwd->region,
struct iter_forward_zone* node = regional_alloc(fwd->region,
sizeof(struct iter_forward_zone));
if(!node)
return 0;
node->node.key = node;
node->dclass = c;
node->name = region_alloc_init(fwd->region, dp->name, dp->namelen);
node->name = regional_alloc_init(fwd->region, dp->name, dp->namelen);
if(!node->name)
return 0;
node->namelen = dp->namelen;
@@ -229,8 +228,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
return 0;
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
return 0;
log_info("Forward zone server list:");
delegpt_log(dp);
verbose(VERB_DETAIL, "Forward zone server list:");
delegpt_log(VERB_DETAIL, dp);
}
return 1;
}
@@ -289,5 +288,5 @@ forwards_get_mem(struct iter_forwards* fwd)
{
if(!fwd)
return 0;
return sizeof(*fwd) + region_get_mem(fwd->region);
return sizeof(*fwd) + regional_get_mem(fwd->region);
}
+6 -3
View File
@@ -46,14 +46,14 @@
struct iter_env;
struct config_file;
struct delegpt;
struct region;
struct regional;
/**
* Iterator forward zones structure
*/
struct iter_forwards {
/** region where forward zone server addresses are allocated */
struct region* region;
/** regional where forward zone server addresses are allocated */
struct regional* region;
/**
* Zones are stored in this tree. Sort order is specially chosen.
* first sorted on qtype. Then on dname in nsec-like order, so that
@@ -125,4 +125,7 @@ struct delegpt* forwards_lookup(struct iter_forwards* fwd,
*/
size_t forwards_get_mem(struct iter_forwards* fwd);
/** compare two fwd entries */
int fwd_cmp(const void* k1, const void* k2);
#endif /* ITERATOR_ITER_FWD_H */
+136 -14
View File
@@ -42,14 +42,13 @@
#include "config.h"
#include "iterator/iter_hints.h"
#include "iterator/iter_delegpt.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "util/data/dname.h"
/** compare two hint entries */
static int
int
stub_cmp(const void* k1, const void* k2)
{
int m;
@@ -71,7 +70,7 @@ hints_create()
sizeof(struct iter_hints));
if(!hints)
return NULL;
hints->region = region_create(malloc, free);
hints->region = regional_create();
if(!hints->region) {
hints_delete(hints);
return NULL;
@@ -84,14 +83,14 @@ hints_delete(struct iter_hints* hints)
{
if(!hints)
return;
region_destroy(hints->region);
regional_destroy(hints->region);
free(hints->tree);
free(hints);
}
/** add hint to delegation hints */
static int
ah(struct delegpt* dp, struct region* r, const char* sv, const char* ip)
ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip)
{
struct sockaddr_storage addr;
socklen_t addrlen;
@@ -113,7 +112,7 @@ ah(struct delegpt* dp, struct region* r, const char* sv, const char* ip)
/** obtain compiletime provided root hints */
static struct delegpt*
compile_time_root_prime(struct region* r)
compile_time_root_prime(struct regional* r)
{
/* from:
; This file is made available by InterNIC
@@ -141,7 +140,7 @@ compile_time_root_prime(struct region* r)
if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "192.36.148.17")) return 0;
if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "192.58.128.30")) return 0;
if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "193.0.14.129")) return 0;
if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "198.32.64.12")) return 0;
if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "199.7.83.42")) return 0;
if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "202.12.27.33")) return 0;
return dp;
}
@@ -150,13 +149,13 @@ compile_time_root_prime(struct region* r)
static int
hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp)
{
struct iter_hints_stub* node = region_alloc(hints->region,
struct iter_hints_stub* node = regional_alloc(hints->region,
sizeof(struct iter_hints_stub));
if(!node)
return 0;
node->node.key = node;
node->hint_class = c;
node->name = region_alloc_init(hints->region, dp->name, dp->namelen);
node->name = regional_alloc_init(hints->region, dp->name, dp->namelen);
if(!node->name)
return 0;
node->namelen = dp->namelen;
@@ -286,7 +285,127 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
return 0;
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
return 0;
delegpt_log(dp);
delegpt_log(VERB_DETAIL, dp);
}
return 1;
}
/** read root hints from file */
static int
read_root_hints(struct iter_hints* hints, char* fname)
{
int lineno = 0;
uint32_t default_ttl = 0;
ldns_rdf* origin = NULL;
ldns_rdf* prev_rr = NULL;
struct delegpt* dp;
ldns_rr* rr = NULL;
ldns_status status;
uint16_t c = LDNS_RR_CLASS_IN;
FILE* f = fopen(fname, "r");
if(!f) {
log_err("could not read root hints %s: %s",
fname, strerror(errno));
return 0;
}
dp = delegpt_create(hints->region);
if(!dp) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
verbose(VERB_DETAIL, "Reading root hints from %s", fname);
while(!feof(f)) {
status = ldns_rr_new_frm_fp_l(&rr, f,
&default_ttl, &origin, &prev_rr, &lineno);
if(status == LDNS_STATUS_SYNTAX_EMPTY ||
status == LDNS_STATUS_SYNTAX_TTL ||
status == LDNS_STATUS_SYNTAX_ORIGIN)
continue;
if(status != LDNS_STATUS_OK) {
log_err("reading root hints %s %d: %s", fname,
lineno, ldns_get_errorstr_by_id(status));
fclose(f);
return 0;
}
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
if(!delegpt_add_ns(dp, hints->region,
ldns_rdf_data(ldns_rr_rdf(rr, 0)))) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
c = ldns_rr_get_class(rr);
if(!dp->name) {
if(!delegpt_set_name(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)))){
log_err("out of memory.");
fclose(f);
return 0;
}
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
struct sockaddr_in sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE);
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
(struct sockaddr_storage*)&sa, len)) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
struct sockaddr_in6 sa;
socklen_t len = (socklen_t)sizeof(sa);
memset(&sa, 0, len);
sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
memmove(&sa.sin6_addr,
ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE);
if(!delegpt_add_target(dp, hints->region,
ldns_rdf_data(ldns_rr_owner(rr)),
ldns_rdf_size(ldns_rr_owner(rr)),
(struct sockaddr_storage*)&sa, len)) {
log_err("out of memory reading root hints");
fclose(f);
return 0;
}
} else {
log_warn("root hints %s:%d skipping type %d",
fname, lineno, ldns_rr_get_type(rr));
}
ldns_rr_free(rr);
}
fclose(f);
if(!dp->name) {
log_warn("root hints %s: no NS content", fname);
return 1;
}
if(!hints_insert(hints, c, dp)) {
return 0;
}
delegpt_log(VERB_DETAIL, dp);
return 1;
}
/** read root hints list */
static int
read_root_hints_list(struct iter_hints* hints, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->root_hints; p; p = p->next) {
log_assert(p->str);
if(p->str && p->str[0]) {
if(!read_root_hints(hints, p->str))
return 0;
}
}
return 1;
}
@@ -298,7 +417,10 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
hints->tree = rbtree_create(stub_cmp);
if(!hints->tree)
return 0;
/* TODO: read root hints from file named in cfg */
/* read root hints */
if(!read_root_hints_list(hints, cfg))
return 0;
/* read stub hints */
if(!read_stubs(hints, cfg))
@@ -312,7 +434,7 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
return 0;
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
return 0;
delegpt_log(dp);
delegpt_log(VERB_DETAIL, dp);
}
init_parents(hints);
@@ -380,5 +502,5 @@ size_t
hints_get_mem(struct iter_hints* hints)
{
if(!hints) return 0;
return sizeof(*hints) + region_get_mem(hints->region);
return sizeof(*hints) + regional_get_mem(hints->region);
}
+6 -3
View File
@@ -46,14 +46,14 @@
struct iter_env;
struct config_file;
struct delegpt;
struct region;
struct regional;
/**
* Iterator hints structure
*/
struct iter_hints {
/** region where hints are allocated */
struct region* region;
/** regional where hints are allocated */
struct regional* region;
/**
* Hints are stored in this tree. Sort order is specially chosen.
* first sorted on qtype. Then on dname in nsec-like order, so that
@@ -134,4 +134,7 @@ struct delegpt* hints_lookup_stub(struct iter_hints* hints,
*/
size_t hints_get_mem(struct iter_hints* hints);
/** compare two hint entries */
int stub_cmp(const void* k1, const void* k2);
#endif /* ITERATOR_ITER_HINTS_H */
+20 -3
View File
@@ -100,8 +100,8 @@ response_type_from_cache(struct dns_msg* msg,
}
enum response_type
response_type_from_server(struct dns_msg* msg, struct query_info* request,
struct delegpt* dp)
response_type_from_server(int rdset,
struct dns_msg* msg, struct query_info* request, struct delegpt* dp)
{
uint8_t* origzone = (uint8_t*)"\000"; /* the default */
size_t origzonelen = 1;
@@ -111,8 +111,13 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
return RESPONSE_TYPE_THROWAWAY;
/* If the message is NXDOMAIN, then it answers the question. */
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN)
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
/* make sure its not recursive when we don't want it to */
if( (msg->rep->flags&BIT_RA) &&
!(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_LAME;
return RESPONSE_TYPE_ANSWER;
}
/* Other response codes mean (so far) to throw the response away as
* meaningless and move on to the next nameserver. */
@@ -193,6 +198,10 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
/* The normal way of detecting NOERROR/NODATA. */
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA &&
dname_subdomain_c(request->qname, s->rk.dname)) {
/* we do our own recursion, thank you */
if( (msg->rep->flags&BIT_RA) &&
!(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_LAME;
return RESPONSE_TYPE_ANSWER;
}
@@ -203,6 +212,11 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
* thought we were contacting, then it is an answer.*/
/* FIXME: is this correct? */
if(query_dname_compare(s->rk.dname, origzone) == 0) {
/* see if mistakenly a recursive server was
* deployed and is responding nonAA */
if( (msg->rep->flags&BIT_RA) &&
!(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_LAME;
return RESPONSE_TYPE_ANSWER;
}
/* If we are getting a referral upwards (or to
@@ -231,5 +245,8 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request,
/* If we've gotten this far, this is NOERROR/NODATA (which could
* be an entirely empty message) */
/* check if recursive answer; saying it has empty cache */
if( (msg->rep->flags&BIT_RA) && !(msg->rep->flags&BIT_AA) && !rdset)
return RESPONSE_TYPE_LAME;
return RESPONSE_TYPE_ANSWER;
}
+3 -2
View File
@@ -107,13 +107,14 @@ enum response_type response_type_from_cache(struct dns_msg* msg,
* relies somewhat on the originating zone to be accurate (for lameness
* detection, mostly).
*
* @param rdset: if RD bit was sent in query sent by unbound.
* @param msg: the message from the cache.
* @param request: the request that generated the response.
* @param dp: The delegation point that was being queried
* when the response was returned.
* @return the response type (CNAME or ANSWER).
*/
enum response_type response_type_from_server(struct dns_msg* msg,
struct query_info* request, struct delegpt* dp);
enum response_type response_type_from_server(int rdset,
struct dns_msg* msg, struct query_info* request, struct delegpt* dp);
#endif /* ITERATOR_ITER_RESPTYPE_H */
+16 -8
View File
@@ -44,7 +44,7 @@
#include "services/cache/rrset.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/data/msgparse.h"
@@ -224,22 +224,22 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
/** synthesize a CNAME rrset */
static struct rrset_parse*
synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
size_t aliaslen, struct region* region, struct msg_parse* msg,
size_t aliaslen, struct regional* region, struct msg_parse* msg,
struct rrset_parse* rrset, struct rrset_parse* prev,
struct rrset_parse* nx, ldns_buffer* pkt)
{
struct rrset_parse* cn = (struct rrset_parse*)region_alloc(region,
struct rrset_parse* cn = (struct rrset_parse*)regional_alloc(region,
sizeof(struct rrset_parse));
if(!cn)
return NULL;
memset(cn, 0, sizeof(*cn));
cn->rr_first = (struct rr_parse*)region_alloc(region,
cn->rr_first = (struct rr_parse*)regional_alloc(region,
sizeof(struct rr_parse));
if(!cn->rr_first)
return NULL;
cn->rr_last = cn->rr_first;
/* CNAME from sname to alias */
cn->dname = (uint8_t*)region_alloc(region, *snamelen);
cn->dname = (uint8_t*)regional_alloc(region, *snamelen);
if(!cn->dname)
return NULL;
dname_pkt_copy(pkt, cn->dname, *sname);
@@ -253,7 +253,7 @@ synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
/* allocate TTL + rdatalen + uncompressed dname */
memset(cn->rr_first, 0, sizeof(struct rr_parse));
cn->rr_first->outside_packet = 1;
cn->rr_first->ttl_data = (uint8_t*)region_alloc(region,
cn->rr_first->ttl_data = (uint8_t*)regional_alloc(region,
sizeof(uint32_t)+sizeof(uint16_t)+aliaslen);
if(!cn->rr_first->ttl_data)
return NULL;
@@ -312,7 +312,7 @@ pkt_sub(ldns_buffer* pkt, uint8_t* comprname, uint8_t* zone)
*/
static int
scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, struct region* region)
struct query_info* qinfo, struct regional* region)
{
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
@@ -350,6 +350,10 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
"too long");
return 0;
}
/* internally we have CNAME'd/DNAME'd chains ending
* in nxdomain with NOERROR rcode, change rcode
* to reflect this (if needed) */
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
/* check next cname */
@@ -392,6 +396,10 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
return 0;
prev = rrset;
rrset = rrset->rrset_all_next;
/* internally we have CNAME'd/DNAME'd chains ending
* in nxdomain with NOERROR rcode, change rcode
* to reflect this (if needed) */
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
continue;
}
@@ -545,7 +553,7 @@ scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg, uint8_t* zonename,
int
scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct region* region,
struct query_info* qinfo, uint8_t* zonename, struct regional* region,
struct module_env* env)
{
/* basic sanity checks */
+3 -3
View File
@@ -44,7 +44,7 @@
#define ITERATOR_ITER_SCRUB_H
struct msg_parse;
struct query_info;
struct region;
struct regional;
struct module_env;
/**
@@ -55,12 +55,12 @@ struct module_env;
* @param qinfo: the query info that was sent to the server. Checked.
* @param zonename: the name of the last delegation point.
* Used to determine out of bailiwick information.
* @param region: where to allocate (new) parts of the message.
* @param regional: where to allocate (new) parts of the message.
* @param env: module environment with config settings and cache.
* @return: false if the message is total waste. true if scrubbed with success.
*/
int scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct region* region,
struct query_info* qinfo, uint8_t* zonename, struct regional* regional,
struct module_env* env);
#endif /* ITERATOR_ITER_SCRUB_H */
+122 -14
View File
@@ -53,10 +53,12 @@
#include "util/module.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "validator/val_anchor.h"
/** fillup fetch policy array */
static void
@@ -132,19 +134,22 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
{
int rtt;
int lame;
int dnsseclame;
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
return -1; /* server is on the donotquery list */
}
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr)) {
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip6 available */
}
/* check lameness - need zone , class info */
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
name, namelen, &lame, &rtt, now)) {
name, namelen, &lame, &dnsseclame, &rtt, now)) {
if(lame)
return -1; /* server is lame */
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
return -1; /* server is unresponsive */
else if(dnsseclame)
return rtt+USEFUL_SERVER_TOP_TIMEOUT; /* nonpref */
else return rtt;
}
/* no server information present */
@@ -155,7 +160,8 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
* returns number of best targets (or 0, no suitable targets) */
static int
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, time_t now, struct delegpt* dp)
uint8_t* name, size_t namelen, time_t now, struct delegpt* dp,
int* best_rtt)
{
int got_num = 0, got_rtt = 0, thisrtt, swap_to_front;
struct delegpt_addr* a, *n, *prev=NULL;
@@ -196,23 +202,30 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
a = a->next_result;
}
}
*best_rtt = got_rtt;
return got_num;
}
struct delegpt_addr*
iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp,
uint8_t* name, size_t namelen)
uint8_t* name, size_t namelen, int* dnssec_expected)
{
time_t now = time(NULL);
int sel;
int selrtt;
struct delegpt_addr* a, *prev;
int num = iter_filter_order(iter_env, env, name, namelen, now, dp);
int num = iter_filter_order(iter_env, env, name, namelen, now, dp,
&selrtt);
if(num == 0)
return NULL;
if(selrtt >= USEFUL_SERVER_TOP_TIMEOUT)
*dnssec_expected = 0;
if(num == 1) {
a = dp->result_list;
if(++a->attempts < OUTBOUND_MSG_RETRY)
return a;
dp->result_list = a->next_result;
return a;
}
@@ -230,6 +243,8 @@ iter_server_selection(struct iter_env* iter_env,
}
if(!a) /* robustness */
return NULL;
if(++a->attempts < OUTBOUND_MSG_RETRY)
return a;
/* remove it from the delegation point result list */
if(prev)
prev->next_result = a->next_result;
@@ -238,9 +253,10 @@ iter_server_selection(struct iter_env* iter_env,
}
struct dns_msg*
dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg, struct region* region)
dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg,
struct regional* region)
{
struct dns_msg* m = (struct dns_msg*)region_alloc(region,
struct dns_msg* m = (struct dns_msg*)regional_alloc(region,
sizeof(struct dns_msg));
if(!m)
return NULL;
@@ -253,14 +269,14 @@ dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg, struct region* region)
}
struct dns_msg*
dns_copy_msg(struct dns_msg* from, struct region* region)
dns_copy_msg(struct dns_msg* from, struct regional* region)
{
struct dns_msg* m = (struct dns_msg*)region_alloc(region,
struct dns_msg* m = (struct dns_msg*)regional_alloc(region,
sizeof(struct dns_msg));
if(!m)
return NULL;
m->qinfo = from->qinfo;
if(!(m->qinfo.qname = region_alloc_init(region, from->qinfo.qname,
if(!(m->qinfo.qname = regional_alloc_init(region, from->qinfo.qname,
from->qinfo.qname_len)))
return NULL;
if(!(m->rep = reply_info_copy(from->rep, NULL, region)))
@@ -297,6 +313,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
qinf.qname_len = namelen;
qinf.qtype = t;
qinf.qclass = c;
log_assert(fptr_whitelist_modenv_detect_cycle(
qstate->env->detect_cycle));
return (*qstate->env->detect_cycle)(qstate, &qinf,
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming);
}
@@ -315,7 +333,8 @@ iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
LDNS_RR_TYPE_A, qstate->qinfo.qclass)) {
log_nametypeclass(VERB_DETAIL, "skipping target due "
"to dependency cycle (harden-glue: no may "
"fix this)", ns->name, LDNS_RR_TYPE_A,
"fix some of the cycles)",
ns->name, LDNS_RR_TYPE_A,
qstate->qinfo.qclass);
ns->resolved = 1;
}
@@ -323,20 +342,33 @@ iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
}
int
iter_dp_is_useless(uint16_t flags, struct delegpt* dp)
iter_dp_is_useless(struct module_qstate* qstate, struct delegpt* dp)
{
struct delegpt_ns* ns;
/* check:
* o all NS items are required glue.
* o no addresses are provided.
* o RD qflag is on.
* OR
* o no addresses are provided.
* o RD qflag is on.
* o the query is for one of the nameservers in dp,
* and that nameserver is a glue-name for this dp.
*/
if(!(flags&BIT_RD))
if(!(qstate->query_flags&BIT_RD))
return 0;
/* either available or unused targets */
if(dp->usable_list || dp->result_list)
return 0;
/* see if query is for one of the nameservers, which is glue */
if( (qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) &&
dname_subdomain_c(qstate->qinfo.qname, dp->name) &&
delegpt_find_ns(dp, qstate->qinfo.qname,
qstate->qinfo.qname_len))
return 1;
for(ns = dp->nslist; ns; ns = ns->next) {
if(ns->resolved) /* skip failed targets */
continue;
@@ -345,3 +377,79 @@ iter_dp_is_useless(uint16_t flags, struct delegpt* dp)
}
return 1;
}
int
iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
struct dns_msg* msg, uint16_t dclass)
{
/* information not available, !env->anchors can be common */
if(!env || !env->anchors || !dp || !dp->name || !msg || !msg->rep)
return 0;
/* a trust anchor exists with this name, RRSIGs expected */
if(anchor_find(env->anchors, dp->name, dp->namelabs, dp->namelen,
dclass))
return 1;
/* see if DS rrset was given, in AUTH section */
if(reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
LDNS_RR_TYPE_DS, dclass))
return 1;
return 0;
}
int
iter_msg_has_dnssec(struct dns_msg* msg)
{
size_t i;
if(!msg || !msg->rep)
return 0;
for(i=0; i<msg->rep->an_numrrsets + msg->rep->ns_numrrsets; i++) {
if(((struct packed_rrset_data*)msg->rep->rrsets[i]->
entry.data)->rrsig_count > 0)
return 1;
}
/* empty message has no DNSSEC info, with DNSSEC the reply is
* not empty (NSEC) */
return 0;
}
int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
enum response_type type, uint16_t dclass)
{
if(!msg || !dp || !msg->rep || !dp->name)
return 0;
/* SOA RRset - always from reply zone */
if(reply_find_rrset_section_an(msg->rep, dp->name, dp->namelen,
LDNS_RR_TYPE_SOA, dclass) ||
reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
LDNS_RR_TYPE_SOA, dclass))
return 1;
if(type == RESPONSE_TYPE_REFERRAL) {
size_t i;
/* if it adds a single label, i.e. we expect .com,
* and referral to example.com. NS ... , then origin zone
* is .com. For a referral to sub.example.com. NS ... then
* we do not know, since example.com. may be in between. */
for(i=0; i<msg->rep->an_numrrsets+msg->rep->ns_numrrsets;
i++) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_NS &&
ntohs(s->rk.rrset_class) == dclass) {
int l = dname_count_labels(s->rk.dname);
if(l == dp->namelabs + 1 &&
dname_strict_subdomain(s->rk.dname,
l, dp->name, dp->namelabs))
return 1;
}
}
return 0;
}
log_assert(type==RESPONSE_TYPE_ANSWER || type==RESPONSE_TYPE_CNAME);
/* not a referral, and not lame delegation (upwards), so,
* any NS rrset must be from the zone itself */
if(reply_find_rrset_section_an(msg->rep, dp->name, dp->namelen,
LDNS_RR_TYPE_NS, dclass) ||
reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
LDNS_RR_TYPE_NS, dclass))
return 1;
return 0;
}
+53 -12
View File
@@ -42,12 +42,13 @@
#ifndef ITERATOR_ITER_UTILS_H
#define ITERATOR_ITER_UTILS_H
#include "iterator/iter_resptype.h"
struct iter_env;
struct config_file;
struct module_env;
struct delegpt_addr;
struct delegpt;
struct region;
struct regional;
struct msg_parse;
struct ub_randstate;
struct query_info;
@@ -73,30 +74,32 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
* @param dp: delegation point with result list.
* @param name: zone name (for lameness check).
* @param namelen: length of name.
* @param dnssec_expected: set to 0, if a known dnssec-lame server is selected
* these are not preferred, but are used as a last resort.
* @return best target or NULL if no target.
* if not null, that target is removed from the result list in the dp.
*/
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp, uint8_t* name,
size_t namelen);
size_t namelen, int* dnssec_expected);
/**
* Allocate dns_msg from parsed msg, in region.
* Allocate dns_msg from parsed msg, in regional.
* @param pkt: packet.
* @param msg: parsed message (cleaned and ready for region allocation).
* @param region: region to use for allocation.
* @param msg: parsed message (cleaned and ready for regional allocation).
* @param regional: regional to use for allocation.
* @return newly allocated dns_msg, or NULL on memory error.
*/
struct dns_msg* dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg,
struct region* region);
struct regional* regional);
/**
* Copy a dns_msg to this region.
* @param from: dns message, also in region.
* @param region: region to use for allocation.
* Copy a dns_msg to this regional.
* @param from: dns message, also in regional.
* @param regional: regional to use for allocation.
* @return newly allocated dns_msg, or NULL on memory error.
*/
struct dns_msg* dns_copy_msg(struct dns_msg* from, struct region* region);
struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
/**
* Allocate a dns_msg with malloc/alloc structure and store in dns cache.
@@ -131,9 +134,47 @@ void iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp);
/**
* See if delegation is useful or offers immediately no targets for
* further recursion.
* @param flags: query flags.
* @param qstate: query state with RD flag and query name.
* @param dp: delegpt to check.
*/
int iter_dp_is_useless(uint16_t flags, struct delegpt* dp);
int iter_dp_is_useless(struct module_qstate* qstate, struct delegpt* dp);
/**
* See if delegation is expected to have DNSSEC information (RRSIGs) in
* its answers, or not. Inspects delegation point (name), trust anchors,
* and delegation message (DS RRset) to determine this.
* @param env: module env with trust anchors.
* @param dp: delegation point.
* @param msg: delegation message, with DS if a secure referral.
* @param dclass: class of query.
* @return 1 if dnssec is expected, 0 if not.
*/
int iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
struct dns_msg* msg, uint16_t dclass);
/**
* See if a message contains DNSSEC.
* This is examined by looking for RRSIGs. With DNSSEC a valid answer,
* nxdomain, nodata, referral or cname reply has RRSIGs in answer or auth
* sections, sigs on answer data, SOA, DS, or NSEC/NSEC3 records.
* @param msg: message to examine.
* @return true if DNSSEC information was found.
*/
int iter_msg_has_dnssec(struct dns_msg* msg);
/**
* See if a message is known to be from a certain zone.
* This looks for SOA or NS rrsets, for answers.
* For referrals, when one label is delegated, the zone is detected.
* Does not look at signatures.
* @param msg: the message to inspect.
* @param dp: delegation point with zone name to look for.
* @param type: type of message.
* @param dclass: class of query.
* @return true if message is certain to be from zone in dp->name.
* false if not sure (empty msg), or not from the zone.
*/
int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
enum response_type type, uint16_t dclass);
#endif /* ITERATOR_ITER_UTILS_H */
+119 -45
View File
@@ -54,12 +54,12 @@
#include "util/module.h"
#include "util/netevent.h"
#include "util/net_help.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/data/dname.h"
#include "util/data/msgencode.h"
#include "util/fptr_wlist.h"
/** iterator init */
static int
int
iter_init(struct module_env* env, int id)
{
struct iter_env* iter_env = (struct iter_env*)calloc(1,
@@ -76,8 +76,7 @@ iter_init(struct module_env* env, int id)
return 1;
}
/** iterator deinit */
static void
void
iter_deinit(struct module_env* env, int id)
{
struct iter_env* iter_env;
@@ -89,13 +88,14 @@ iter_deinit(struct module_env* env, int id)
forwards_delete(iter_env->fwds);
donotq_delete(iter_env->donotq);
free(iter_env);
env->modinfo[id] = NULL;
}
/** new query for iterator */
static int
iter_new(struct module_qstate* qstate, int id)
{
struct iter_qstate* iq = (struct iter_qstate*)region_alloc(
struct iter_qstate* iq = (struct iter_qstate*)regional_alloc(
qstate->region, sizeof(struct iter_qstate));
qstate->minfo[id] = iq;
if(!iq)
@@ -115,6 +115,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->referral_count = 0;
iq->wait_priming_stub = 0;
iq->refetch_glue = 0;
iq->dnssec_expected = 0;
iq->chase_flags = qstate->query_flags;
/* Start with the (current) qname. */
iq->qchase = qstate->qinfo;
@@ -187,7 +188,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
/* not interested */
verbose(VERB_ALGO, "subq error, but not interested");
log_query_info(VERB_ALGO, "superq", &super->qinfo);
delegpt_log(super_iq->dp);
delegpt_log(VERB_ALGO, super_iq->dp);
log_assert(0);
return;
}
@@ -223,10 +224,27 @@ error_response(struct module_qstate* qstate, int id, int rcode)
return 0;
}
/** check if prepend item is duplicate item */
static int
prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to,
struct ub_packed_rrset_key* dup)
{
size_t i;
for(i=0; i<to; i++) {
if(sets[i]->rk.type == dup->rk.type &&
sets[i]->rk.rrset_class == dup->rk.rrset_class &&
sets[i]->rk.dname_len == dup->rk.dname_len &&
query_dname_compare(sets[i]->rk.dname, dup->rk.dname)
== 0)
return 1;
}
return 0;
}
/** prepend the prepend list in the answer and authority section of dns_msg */
static int
iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
struct region* region)
struct regional* region)
{
struct iter_prep_list* p;
struct ub_packed_rrset_key** sets;
@@ -238,7 +256,7 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
if(num_an + num_ns == 0)
return 1;
verbose(VERB_ALGO, "prepending %d rrsets", (int)num_an + (int)num_ns);
sets = region_alloc(region, (num_an+num_ns+msg->rep->rrset_count) *
sets = regional_alloc(region, (num_an+num_ns+msg->rep->rrset_count) *
sizeof(struct ub_packed_rrset_key*));
if(!sets)
return 0;
@@ -252,6 +270,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
/* AUTH section */
num_ns = 0;
for(p = iq->ns_prepend_list; p; p = p->next) {
if(prepend_is_duplicate(sets+msg->rep->an_numrrsets+num_an,
num_ns, p->rrset) || prepend_is_duplicate(
msg->rep->rrsets+msg->rep->an_numrrsets,
msg->rep->ns_numrrsets, p->rrset))
continue;
sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
}
memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns,
@@ -282,7 +305,7 @@ static int
iter_add_prepend_answer(struct module_qstate* qstate, struct iter_qstate* iq,
struct ub_packed_rrset_key* rrset)
{
struct iter_prep_list* p = (struct iter_prep_list*)region_alloc(
struct iter_prep_list* p = (struct iter_prep_list*)regional_alloc(
qstate->region, sizeof(struct iter_prep_list));
if(!p)
return 0;
@@ -307,7 +330,7 @@ static int
iter_add_prepend_auth(struct module_qstate* qstate, struct iter_qstate* iq,
struct ub_packed_rrset_key* rrset)
{
struct iter_prep_list* p = (struct iter_prep_list*)region_alloc(
struct iter_prep_list* p = (struct iter_prep_list*)regional_alloc(
qstate->region, sizeof(struct iter_prep_list));
if(!p)
return 0;
@@ -432,6 +455,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
qflags |= BIT_CD;
/* attach subquery, lookup existing or make a new one */
log_assert(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) {
return 0;
}
@@ -440,10 +464,12 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
/* initialise the new subquery */
subq->curmod = id;
subq->ext_state[id] = module_state_initial;
subq->minfo[id] = region_alloc(subq->region,
subq->minfo[id] = regional_alloc(subq->region,
sizeof(struct iter_qstate));
if(!subq->minfo[id]) {
log_err("init subq: out of memory");
log_assert(fptr_whitelist_modenv_kill_sub(
qstate->env->kill_sub));
(*qstate->env->kill_sub)(subq);
return 0;
}
@@ -560,6 +586,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
subiq->dp = delegpt_copy(stub_dp, subq->region);
if(!subiq->dp) {
log_err("out of memory priming stub, copydp");
log_assert(fptr_whitelist_modenv_kill_sub(
qstate->env->kill_sub));
(*qstate->env->kill_sub)(subq);
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return 1; /* return 1 to make module stop, with error */
@@ -661,7 +689,9 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* handle positive cache response */
enum response_type type = response_type_from_cache(msg,
&iq->qchase);
log_dns_msg("msg from cache lookup", &msg->qinfo, msg->rep);
if(verbosity >= VERB_ALGO)
log_dns_msg("msg from cache lookup", &msg->qinfo,
msg->rep);
if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0;
@@ -706,6 +736,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* When re-fetching glue we also need to ask the parent.
*/
if(iq->refetch_glue) {
if(!iq->dp) {
log_err("internal or malloc fail: no dp for refetch");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
delname = iq->dp->name;
delnamelen = iq->dp->namelen;
} else {
@@ -716,11 +750,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
&& !dname_is_root(delname)) {
/* do not adjust root label, remove first label from delname */
dname_remove_label(&delname, &delnamelen);
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
}
while(1) {
/* Lookup the delegation in the cache. If null, then the cache needs
* to be primed for the qclass. */
/* Lookup the delegation in the cache. If null, then the
* cache needs to be primed for the qclass. */
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg, (uint32_t)time(NULL));
@@ -743,7 +778,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* see if this dp not useless.
* It is useless if:
* o all NS items are required glue.
* o all NS items are required glue.
* or the query is for NS item that is required glue.
* o no addresses are provided.
* o RD qflag is on.
* Instead, go up one level, and try to get even further
@@ -752,10 +788,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* could be useless but lead to loops (bumping into the
* same server reply) if useless-checked.
*/
if(iter_dp_is_useless(qstate->query_flags, iq->dp)) {
if(iter_dp_is_useless(qstate, iq->dp)) {
if(dname_is_root(iq->dp->name)) {
/* use safety belt */
verbose(VERB_OPS, "Priming problem: NS but "
verbose(VERB_DETAIL, "Cache has root NS but "
"no addresses. Fallback to the safety belt.");
iq->dp = hints_lookup_root(ie->hints,
iq->qchase.qclass);
@@ -774,8 +810,9 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
break;
} else {
log_info("cache delegation was useless:");
delegpt_log(iq->dp);
verbose(VERB_ALGO,
"cache delegation was useless:");
delegpt_log(VERB_ALGO, iq->dp);
/* go up */
delname = iq->dp->name;
delnamelen = iq->dp->namelen;
@@ -784,10 +821,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
} else break;
}
if(verbosity >= VERB_ALGO) {
log_info("cache delegation returns delegpt");
delegpt_log(iq->dp);
}
verbose(VERB_ALGO, "cache delegation returns delegpt");
delegpt_log(VERB_ALGO, iq->dp);
/* if the cache reply dp equals a validation anchor or msg has DS,
* then DNSSEC RRSIGs are expected in the reply */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env, iq->dp,
iq->deleg_msg, iq->qchase.qclass);
/* Reset the RD flag. If this is a query restart, then the RD
* will have been turned off. */
@@ -1031,7 +1071,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_DETAIL, "Failed to get a delegation, giving up");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
delegpt_log(iq->dp);
delegpt_log(VERB_ALGO, iq->dp);
if(iq->num_current_queries>0) {
/* already busy answering a query, this restart is because
@@ -1065,7 +1105,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
/* Select the next usable target, filtering out unsuitable targets. */
target = iter_server_selection(ie, qstate->env, iq->dp,
iq->dp->name, iq->dp->namelen);
iq->dp->name, iq->dp->namelen, &iq->dnssec_expected);
/* If no usable target was selected... */
if(!target) {
@@ -1126,6 +1166,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
log_query_info(VERB_DETAIL, "sending query:", &iq->qchase);
log_name_addr(VERB_DETAIL, "sending to target:", iq->dp->name,
&target->addr, target->addrlen);
log_assert(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(
iq->qchase.qname, iq->qchase.qname_len,
iq->qchase.qtype, iq->qchase.qclass,
@@ -1133,7 +1174,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
&target->addr, target->addrlen, qstate);
if(!outq) {
log_err("error sending query to auth server; skip this address");
log_addr("error for address:", &target->addr, target->addrlen);
log_addr(0, "error for address:",
&target->addr, target->addrlen);
return next_state(iq, QUERYTARGETS_STATE);
}
outbound_list_insert(&iq->outlist, outq);
@@ -1160,18 +1202,36 @@ static int
processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
int id)
{
int dnsseclame = 0;
enum response_type type;
iq->num_current_queries--;
if(iq->response == NULL) {
verbose(VERB_ALGO, "query response was timeout");
return next_state(iq, QUERYTARGETS_STATE);
}
type = response_type_from_server(iq->response, &iq->qchase, iq->dp);
type = response_type_from_server((int)(iq->chase_flags&BIT_RD),
iq->response, &iq->qchase, iq->dp);
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
/* When forwarding (RD bit is set), we handle referrals
* differently. No queries should be sent elsewhere */
type = RESPONSE_TYPE_ANSWER;
}
if(iq->dnssec_expected && !(iq->chase_flags&BIT_RD)
&& type != RESPONSE_TYPE_LAME
&& type != RESPONSE_TYPE_THROWAWAY
&& type != RESPONSE_TYPE_UNTYPED) {
/* a possible answer, see if it is missing DNSSEC */
/* but not when forwarding, so we dont mark fwder lame */
/* also make sure the answer is from the zone we expected,
* otherwise, (due to parent,child on same server), we
* might mark the server,zone lame inappropriately */
if(!iter_msg_has_dnssec(iq->response) &&
iter_msg_from_zone(iq->response, iq->dp, type,
iq->qchase.qclass)) {
type = RESPONSE_TYPE_LAME;
dnsseclame = 1;
}
}
/* handle each of the type cases */
if(type == RESPONSE_TYPE_ANSWER) {
@@ -1184,6 +1244,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
return final_state(iq);
@@ -1206,9 +1268,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp))
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
delegpt_log(iq->dp);
delegpt_log(VERB_ALGO, iq->dp);
/* Count this as a referral. */
iq->referral_count++;
/* see if the next dp is a trust anchor, or a DS was sent
* along, indicating dnssec is expected for next zone */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
iq->dp, iq->response, iq->qchase.qclass);
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
@@ -1216,6 +1282,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
verbose(VERB_ALGO, "cleared outbound list for next round");
@@ -1227,7 +1295,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* reset of the query state and go back to INIT_REQUEST_STATE).
*/
verbose(VERB_DETAIL, "query response was CNAME");
log_dns_msg("cname msg", &iq->response->qinfo, iq->response->rep);
if(verbosity >= VERB_ALGO)
log_dns_msg("cname msg", &iq->response->qinfo,
iq->response->rep);
/* Process the CNAME response. */
if(!handle_cname_response(qstate, iq, iq->response,
&sname, &snamelen))
@@ -1244,6 +1314,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Clear the query state, since this is a query restart. */
iq->deleg_msg = NULL;
iq->dp = NULL;
iq->dnssec_expected = 0;
/* Note the query restart. */
iq->query_restart_count++;
@@ -1253,6 +1324,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
verbose(VERB_ALGO, "cleared outbound list for query restart");
@@ -1260,15 +1333,18 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, INIT_REQUEST_STATE);
} else if(type == RESPONSE_TYPE_LAME) {
/* Cache the LAMEness. */
verbose(VERB_DETAIL, "query response was LAME");
verbose(VERB_DETAIL, "query response was %sLAME",
dnsseclame?"DNSSEC ":"");
if(qstate->reply) {
/* need addr for lameness cache, but we may have
* gotten this from cache, so test to be sure */
if(!infra_set_lame(qstate->env->infra_cache,
&qstate->reply->addr, qstate->reply->addrlen,
iq->dp->name, iq->dp->namelen, time(NULL)))
iq->dp->name, iq->dp->namelen, time(NULL),
dnsseclame))
log_err("mark host lame: out of memory");
} else log_err("lame response from cache");
} else log_err("%slame response from cache",
dnsseclame?"DNSSEC ":"");
} else if(type == RESPONSE_TYPE_THROWAWAY) {
/* LAME and THROWAWAY responses are handled the same way.
* In this case, the event is just sent directly back to
@@ -1317,7 +1393,7 @@ prime_supers(struct module_qstate* qstate, int id, struct module_qstate* forq)
}
log_query_info(VERB_DETAIL, "priming successful for", &qstate->qinfo);
delegpt_log(dp);
delegpt_log(VERB_ALGO, dp);
foriq->dp = dp;
foriq->deleg_msg = dns_copy_msg(qstate->return_msg, forq->region);
if(!foriq->deleg_msg) {
@@ -1352,7 +1428,7 @@ static int
processPrimeResponse(struct module_qstate* qstate, int id)
{
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
enum response_type type = response_type_from_server(iq->response,
enum response_type type = response_type_from_server(0, iq->response,
&iq->qchase, iq->dp);
if(type == RESPONSE_TYPE_ANSWER) {
qstate->return_rcode = LDNS_RCODE_NOERROR;
@@ -1430,7 +1506,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset))
log_err("out of memory adding targets");
verbose(VERB_ALGO, "added target response");
delegpt_log(foriq->dp);
delegpt_log(VERB_ALGO, foriq->dp);
} else {
verbose(VERB_ALGO, "iterator TargetResponse failed");
dpns->resolved = 1; /* fail the target */
@@ -1504,7 +1580,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
/**
/*
* Return priming query results to interestes super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
@@ -1514,7 +1590,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
* @param id: module id.
* @param super: the qstate to inform.
*/
static void
void
iter_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
@@ -1620,7 +1696,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* parse message */
prs = (struct msg_parse*)region_alloc(qstate->env->scratch,
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
sizeof(struct msg_parse));
if(!prs) {
log_err("out of memory on incoming message");
@@ -1661,8 +1737,7 @@ handle_it:
iter_handle(qstate, iq, ie, id);
}
/** iterator operate on a query */
static void
void
iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
@@ -1705,8 +1780,7 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/** iterator cleanup query state */
static void
void
iter_clear(struct module_qstate* qstate, int id)
{
struct iter_qstate* iq;
@@ -1720,8 +1794,8 @@ iter_clear(struct module_qstate* qstate, int id)
qstate->minfo[id] = NULL;
}
/** iterator alloc size routine */
static size_t iter_get_mem(struct module_env* env, int id)
size_t
iter_get_mem(struct module_env* env, int id)
{
struct iter_env* ie = (struct iter_env*)env->modinfo[id];
if(!ie)
+40 -2
View File
@@ -44,7 +44,7 @@
#define ITERATOR_ITERATOR_H
#include "services/outbound_list.h"
#include "util/data/msgreply.h"
struct module_func_block;
#include "util/module.h"
struct delegpt;
struct iter_hints;
struct iter_forwards;
@@ -58,12 +58,14 @@ struct iter_prep_list;
/** how nice is a server without further information, in msec
* Equals rtt initial timeout value.
*/
#define UNKNOWN_SERVER_NICENESS 3000
#define UNKNOWN_SERVER_NICENESS 376
/** 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
*/
#define USEFUL_SERVER_TOP_TIMEOUT 120000
/** number of retries on outgoing queries */
#define OUTBOUND_MSG_RETRY 4
/**
* Global state for the iterator.
@@ -223,6 +225,13 @@ struct iter_qstate {
/** the number of times this query as followed a referral. */
int referral_count;
/**
* expected dnssec information for this iteration step.
* If dnssec rrsigs are expected and not given, the server is marked
* lame (dnssec-lame).
*/
int dnssec_expected;
/**
* This is flag that, if true, means that this event is
* waiting for a stub priming query.
@@ -273,4 +282,33 @@ const char* iter_state_to_string(enum iter_state state);
*/
int iter_state_is_responsestate(enum iter_state s);
/** iterator init */
int iter_init(struct module_env* env, int id);
/** iterator deinit */
void iter_deinit(struct module_env* env, int id);
/** iterator operate on a query */
void iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound);
/**
* Return priming query results to interestes super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
* This is a callback from walk_supers.
*
* @param qstate: query state that finished.
* @param id: module id.
* @param super: the qstate to inform.
*/
void iter_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** iterator cleanup query state */
void iter_clear(struct module_qstate* qstate, int id);
/** iterator alloc size routine */
size_t iter_get_mem(struct module_env* env, int id);
#endif /* ITERATOR_ITERATOR_H */
BIN
View File
Binary file not shown.
+6909
View File
File diff suppressed because it is too large Load Diff
+9 -7
View File
@@ -148,15 +148,11 @@ if test -z "$LDNSDIR"; then
eval `grep 'ldnsdir=' Makefile`
LDNSDIR="$ldnsdir"
fi
if test -z "$LDNSDIR"; then
error "LDNSDIR not detected in Makefile, specify manually (using -l)"
fi
fi
# Start the packaging process.
info "SVNROOT is $SVNROOT"
info "SNAPSHOT is $SNAPSHOT"
info "LDNSDIR is $LDNSDIR"
#question "Do you wish to continue with these settings?" || error "User abort."
@@ -185,9 +181,15 @@ echo "#include \"util/configyyrename.h\"" > util/configlexer.c || error_cleanup
flex -i -t util/configlexer.lex >> util/configlexer.c || error_cleanup "Failed to create configlexer"
bison -y -d -o util/configparser.c util/configparser.y || error_cleanup "Failed to create configparser"
# copy ldns-testpkts from ldns examples
#cp $LDNSDIR/examples/ldns-testpkts.c testcode/ldns-testpkts.c || error_cleanup "copy ldns/examples/.. failed"
#cp $LDNSDIR/examples/ldns-testpkts.h testcode/ldns-testpkts.h || error_cleanup "copy ldns/examples/.. failed"
# check shared code, ldns-testpkts from ldns examples, if possible.
if test ! -z "$LDNSDIR"; then
if diff -q $LDNSDIR/examples/ldns-testpkts.c testcode/ldns-testpkts.c &&
diff -q $LDNSDIR/examples/ldns-testpkts.h testcode/ldns-testpkts.h; then
info "ldns-testpkts.c and ldns-testpkts.h are OK"
else
error_cleanup "ldns-testpkts is different in ldns and unbound"
fi
fi
find . -name .c-mode-rc.el -exec rm {} \;
find . -name .cvsignore -exec rm {} \;
+32 -29
View File
@@ -47,7 +47,7 @@
#include "util/data/dname.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/region-allocator.h"
#include "util/regional.h"
/** store rrsets in the rrset cache.
* @param env: module environment with caches.
@@ -103,10 +103,10 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
/** allocate rrset in region - no more locks needed */
static struct ub_packed_rrset_key*
copy_rrset(struct ub_packed_rrset_key* key, struct region* region,
copy_rrset(struct ub_packed_rrset_key* key, struct regional* region,
uint32_t now)
{
struct ub_packed_rrset_key* ck = region_alloc(region,
struct ub_packed_rrset_key* ck = regional_alloc(region,
sizeof(struct ub_packed_rrset_key));
struct packed_rrset_data* d;
struct packed_rrset_data* data = (struct packed_rrset_data*)
@@ -119,12 +119,12 @@ copy_rrset(struct ub_packed_rrset_key* key, struct region* region,
ck->entry.hash = key->entry.hash;
ck->entry.key = ck;
ck->rk = key->rk;
ck->rk.dname = region_alloc_init(region, key->rk.dname,
ck->rk.dname = regional_alloc_init(region, key->rk.dname,
key->rk.dname_len);
if(!ck->rk.dname)
return NULL;
dsize = packed_rrset_sizeof(data);
d = (struct packed_rrset_data*)region_alloc_init(region, data, dsize);
d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize);
if(!d)
return NULL;
ck->entry.data = d;
@@ -167,7 +167,7 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
/** add addr to additional section */
static void
addr_to_additional(struct ub_packed_rrset_key* rrset, struct region* region,
addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
struct dns_msg* msg, uint32_t now)
{
if((msg->rep->rrsets[msg->rep->rrset_count] =
@@ -179,8 +179,9 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct region* region,
/** find and add A and AAAA records for nameservers in delegpt */
static int
find_add_addrs(struct module_env* env, uint16_t qclass, struct region* region,
struct delegpt* dp, uint32_t now, struct dns_msg** msg)
find_add_addrs(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp, uint32_t now,
struct dns_msg** msg)
{
struct delegpt_ns* ns;
struct ub_packed_rrset_key* akey;
@@ -214,7 +215,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass, struct region* region,
/** find and add A and AAAA records for missing nameservers in delegpt */
int
cache_fill_missing(struct module_env* env, uint16_t qclass,
struct region* region, struct delegpt* dp)
struct regional* region, struct delegpt* dp)
{
struct delegpt_ns* ns;
struct ub_packed_rrset_key* akey;
@@ -250,7 +251,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
/** find and add DS or NSEC to delegation msg */
static void
find_add_ds(struct module_env* env, struct region* region,
find_add_ds(struct module_env* env, struct regional* region,
struct dns_msg* msg, struct delegpt* dp, uint32_t now)
{
/* Lookup the DS or NSEC at the delegation point. */
@@ -281,21 +282,21 @@ find_add_ds(struct module_env* env, struct region* region,
/** create referral message with NS and query */
static struct dns_msg*
create_msg(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct ub_packed_rrset_key* nskey,
struct regional* region, struct ub_packed_rrset_key* nskey,
struct packed_rrset_data* nsdata, uint32_t now)
{
struct dns_msg* msg = (struct dns_msg*)region_alloc(region,
struct dns_msg* msg = (struct dns_msg*)regional_alloc(region,
sizeof(struct dns_msg));
if(!msg)
return NULL;
msg->qinfo.qname = region_alloc_init(region, qname, qnamelen);
msg->qinfo.qname = regional_alloc_init(region, qname, qnamelen);
if(!msg->qinfo.qname)
return NULL;
msg->qinfo.qname_len = qnamelen;
msg->qinfo.qtype = qtype;
msg->qinfo.qclass = qclass;
/* non-packed reply_info, because it needs to grow the array */
msg->rep = (struct reply_info*)region_alloc(region,
msg->rep = (struct reply_info*)regional_alloc(region,
sizeof(struct reply_info)-sizeof(struct rrset_ref));
if(!msg->rep)
return NULL;
@@ -308,7 +309,8 @@ create_msg(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
* A rrset for every NS RR
* AAAA rrset for every NS RR
*/
msg->rep->rrsets = (struct ub_packed_rrset_key**)region_alloc(region,
msg->rep->rrsets = (struct ub_packed_rrset_key**)
regional_alloc(region,
(2 + nsdata->count*2)*sizeof(struct ub_packed_rrset_key*));
if(!msg->rep->rrsets)
return NULL;
@@ -323,7 +325,7 @@ create_msg(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct delegpt*
dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct dns_msg** msg, uint32_t now)
struct regional* region, struct dns_msg** msg, uint32_t now)
{
/* try to find closest NS rrset */
struct ub_packed_rrset_key* nskey;
@@ -366,22 +368,23 @@ dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
/** allocate dns_msg from query_info and reply_info */
static struct dns_msg*
gen_dns_msg(struct region* region, struct query_info* q, size_t num)
gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
{
struct dns_msg* msg = (struct dns_msg*)region_alloc(region,
struct dns_msg* msg = (struct dns_msg*)regional_alloc(region,
sizeof(struct dns_msg));
if(!msg)
return NULL;
memcpy(&msg->qinfo, q, sizeof(struct query_info));
msg->qinfo.qname = region_alloc_init(region, q->qname, q->qname_len);
msg->qinfo.qname = regional_alloc_init(region, q->qname, q->qname_len);
if(!msg->qinfo.qname)
return NULL;
/* allocate replyinfo struct and rrset key array separately */
msg->rep = (struct reply_info*)region_alloc(region,
msg->rep = (struct reply_info*)regional_alloc(region,
sizeof(struct reply_info) - sizeof(struct rrset_ref));
if(!msg->rep)
return NULL;
msg->rep->rrsets = (struct ub_packed_rrset_key**)region_alloc(region,
msg->rep->rrsets = (struct ub_packed_rrset_key**)
regional_alloc(region,
num * sizeof(struct ub_packed_rrset_key*));
if(!msg->rep->rrsets)
return NULL;
@@ -391,7 +394,7 @@ gen_dns_msg(struct region* region, struct query_info* q, size_t num)
/** generate dns_msg from cached message */
static struct dns_msg*
tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r,
struct region* region, uint32_t now, struct region* scratch)
struct regional* region, uint32_t now, struct regional* scratch)
{
struct dns_msg* msg;
size_t i;
@@ -424,7 +427,7 @@ tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r,
/** synthesize RRset-only response from cached RRset item */
static struct dns_msg*
rrset_msg(struct ub_packed_rrset_key* rrset, struct region* region,
rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
uint32_t now, struct query_info* q)
{
struct dns_msg* msg;
@@ -451,7 +454,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct region* region,
/** synthesize DNAME+CNAME response from cached DNAME item */
static struct dns_msg*
synth_dname_msg(struct ub_packed_rrset_key* rrset, struct region* region,
synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
uint32_t now, struct query_info* q)
{
struct dns_msg* msg;
@@ -485,7 +488,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct region* region,
msg->rep->flags |= LDNS_RCODE_YXDOMAIN;
return msg;
}
newname = (uint8_t*)region_alloc(region, newlen);
newname = (uint8_t*)regional_alloc(region, newlen);
if(!newname)
return NULL;
/* new name is concatenation of qname front (without DNAME owner)
@@ -493,7 +496,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct region* region,
memcpy(newname, q->qname, q->qname_len-rrset->rk.dname_len);
memmove(newname+(q->qname_len-rrset->rk.dname_len), dtarg, dtarglen);
/* create rest of CNAME rrset */
ck = (struct ub_packed_rrset_key*)region_alloc(region,
ck = (struct ub_packed_rrset_key*)regional_alloc(region,
sizeof(struct ub_packed_rrset_key));
if(!ck)
return NULL;
@@ -503,12 +506,12 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct region* region,
ck->rk.type = htons(LDNS_RR_TYPE_CNAME);
ck->rk.rrset_class = rrset->rk.rrset_class;
ck->rk.flags = 0;
ck->rk.dname = region_alloc_init(region, q->qname, q->qname_len);
ck->rk.dname = regional_alloc_init(region, q->qname, q->qname_len);
if(!ck->rk.dname)
return NULL;
ck->rk.dname_len = q->qname_len;
ck->entry.hash = rrset_key_hash(&ck->rk);
newd = (struct packed_rrset_data*)region_alloc(region,
newd = (struct packed_rrset_data*)regional_alloc(region,
sizeof(struct packed_rrset_data) + sizeof(size_t) +
sizeof(uint8_t*) + sizeof(uint32_t) + sizeof(uint16_t)
+ newlen);
@@ -535,7 +538,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct region* region,
struct dns_msg*
dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct region* scratch)
struct regional* region, struct regional* scratch)
{
struct lruhash_entry* e;
struct query_info k;
+4 -6
View File
@@ -46,7 +46,7 @@
struct module_env;
struct query_info;
struct reply_info;
struct region;
struct regional;
struct delegpt;
/**
@@ -107,7 +107,7 @@ void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
*/
struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct dns_msg** msg, uint32_t timenow);
struct regional* region, struct dns_msg** msg, uint32_t timenow);
/**
* Find cached message
@@ -124,7 +124,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
*/
struct dns_msg* dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct region* scratch);
struct regional* region, struct regional* scratch);
/**
* find and add A and AAAA records for missing nameservers in delegpt
@@ -135,8 +135,6 @@ struct dns_msg* dns_cache_lookup(struct module_env* env,
* @return false on alloc failure.
*/
int cache_fill_missing(struct module_env* env, uint16_t qclass,
struct region* region, struct delegpt* dp);
/** Find covering DNAME */
struct regional* region, struct delegpt* dp);
#endif /* SERVICES_CACHE_DNS_H */
+46 -24
View File
@@ -47,9 +47,7 @@
#include "util/net_help.h"
#include "util/config_file.h"
/** calculate size for the hashtable, does not count size of lameness,
* so the hashtable is a fixed number of items */
static size_t
size_t
infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
{
struct infra_host_key* key = (struct infra_host_key*)k;
@@ -57,8 +55,7 @@ infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
+ lock_get_mem(&key->entry.lock);
}
/** compare two addresses, returns -1, 0, or +1 */
static int
int
infra_host_compfunc(void* key1, void* key2)
{
struct infra_host_key* k1 = (struct infra_host_key*)key1;
@@ -66,8 +63,7 @@ infra_host_compfunc(void* key1, void* key2)
return sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
}
/** delete key, and destroy the lock */
static void
void
infra_host_delkeyfunc(void* k, void* ATTR_UNUSED(arg), int il)
{
struct infra_host_key* key = (struct infra_host_key*)k;
@@ -78,8 +74,7 @@ infra_host_delkeyfunc(void* k, void* ATTR_UNUSED(arg), int il)
free(key);
}
/** delete data and destroy the lameness hashtable */
static void
void
infra_host_deldatafunc(void* d, void* ATTR_UNUSED(arg))
{
struct infra_host_data* data = (struct infra_host_data*)d;
@@ -271,6 +266,7 @@ infra_lookup_lame(struct infra_host_data* host,
struct lruhash_entry* e;
struct infra_lame_key k;
struct infra_lame_data *d;
int dl;
if(!host->lameness)
return 0;
k.entry.hash = hash_lameness(name, namelen);
@@ -286,13 +282,12 @@ infra_lookup_lame(struct infra_host_data* host,
lock_rw_unlock(&e->lock);
return 0;
}
dl = d->isdnsseclame;
lock_rw_unlock(&e->lock);
return 1;
return dl?2:1;
}
/** calculate size, which is fixed, zonename does not count so that
* a fixed number of items is stored */
static size_t
size_t
infra_lame_sizefunc(void* k, void* ATTR_UNUSED(d))
{
struct infra_lame_key* key = (struct infra_lame_key*)k;
@@ -300,8 +295,7 @@ infra_lame_sizefunc(void* k, void* ATTR_UNUSED(d))
+ key->namelen + lock_get_mem(&key->entry.lock);
}
/** compare zone names, returns -1, 0, +1 */
static int
int
infra_lame_compfunc(void* key1, void* key2)
{
struct infra_lame_key* k1 = (struct infra_lame_key*)key1;
@@ -314,8 +308,7 @@ infra_lame_compfunc(void* key1, void* key2)
return query_dname_compare(k1->zonename, k2->zonename);
}
/** free key, lock and zonename */
static void
void
infra_lame_delkeyfunc(void* k, void* ATTR_UNUSED(arg), int il)
{
struct infra_lame_key* key = (struct infra_lame_key*)k;
@@ -327,8 +320,7 @@ infra_lame_delkeyfunc(void* k, void* ATTR_UNUSED(arg), int il)
free(key);
}
/** free the lameness data */
static void
void
infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg))
{
if(!d)
@@ -339,7 +331,7 @@ infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg))
int
infra_set_lame(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, time_t timenow)
uint8_t* name, size_t namelen, time_t timenow, int dnsseclame)
{
struct infra_host_data* data;
struct lruhash_entry* e;
@@ -370,6 +362,7 @@ infra_set_lame(struct infra_cache* infra,
k->entry.key = (void*)k;
k->entry.data = (void*)d;
d->ttl = timenow + infra->lame_ttl;
d->isdnsseclame = dnsseclame;
k->namelen = namelen;
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
if(!e) {
@@ -411,6 +404,23 @@ infra_set_lame(struct infra_cache* infra,
return 1;
}
void
infra_update_tcp_works(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen)
{
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
addrlen, 1);
struct infra_host_data* data;
if(!e)
return; /* doesn't exist */
data = (struct infra_host_data*)e->data;
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
/* do not disqualify this server altogether, it is better
* than nothing */
data->rtt.rto = RTT_MAX_TIMEOUT-1;
lock_rw_unlock(&e->lock);
}
int
infra_rtt_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
@@ -420,6 +430,7 @@ infra_rtt_update(struct infra_cache* infra,
addrlen, 1);
struct infra_host_data* data;
int needtoinsert = 0;
int rto = 1;
if(!e) {
if(!(e = new_host_entry(infra, addr, addrlen, timenow)))
return 0;
@@ -431,11 +442,13 @@ infra_rtt_update(struct infra_cache* infra,
if(roundtrip == -1)
rtt_lost(&data->rtt);
else rtt_update(&data->rtt, roundtrip);
if(data->rtt.rto > 0)
rto = data->rtt.rto;
if(needtoinsert)
slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
else { lock_rw_unlock(&e->lock); }
return 1;
return rto;
}
int
@@ -466,22 +479,31 @@ infra_edns_update(struct infra_cache* infra,
int
infra_get_lame_rtt(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, int* lame, int* rtt, time_t timenow)
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
int* rtt, time_t timenow)
{
struct infra_host_data* host;
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
addrlen, 0);
int lm;
if(!e)
return 0;
host = (struct infra_host_data*)e->data;
*rtt = rtt_unclamped(&host->rtt);
/* check lameness first, if so, ttl on host does not matter anymore */
if(infra_lookup_lame(host, name, namelen, timenow)) {
if((lm=infra_lookup_lame(host, name, namelen, timenow))) {
lock_rw_unlock(&e->lock);
*lame = 1;
if(lm == 1) {
*lame = 1;
*dnsseclame = 0;
} else {
*lame = 0;
*dnsseclame = 1;
}
return 1;
}
*lame = 0;
*dnsseclame = 0;
if(timenow > host->ttl) {
lock_rw_unlock(&e->lock);
return 0;
+47 -4
View File
@@ -91,6 +91,9 @@ struct infra_lame_key {
struct infra_lame_data {
/** TTL of this entry. absolute time. */
time_t ttl;
/** is the host lame (does not serve the zone authoritatively),
* or is the host dnssec lame (does not serve DNSSEC data) */
int isdnsseclame;
};
/**
@@ -172,7 +175,7 @@ int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
* @param name: domain name of zone apex.
* @param namelen: length of domain name.
* @param timenow: what time it is now.
* @return: 0 if not lame or unknown or timed out, true if lame.
* @return: 0 if not lame or unknown or timed out, 1 if lame, 2 if dnsseclame.
*/
int infra_lookup_lame(struct infra_host_data* host,
uint8_t* name, size_t namelen, time_t timenow);
@@ -185,11 +188,13 @@ int infra_lookup_lame(struct infra_host_data* host,
* @param name: domain name of zone apex.
* @param namelen: length of domain name.
* @param timenow: what time it is now.
* @param dnsseclame: if true the host is set dnssec lame.
* if false, the host is marked lame (not serving the zone).
* @return: 0 on error.
*/
int infra_set_lame(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, time_t timenow);
uint8_t* name, size_t namelen, time_t timenow, int dnsseclame);
/**
* Update rtt information for the host.
@@ -199,12 +204,21 @@ int infra_set_lame(struct infra_cache* infra,
* @param roundtrip: estimate of roundtrip time in milliseconds or -1 for
* timeout.
* @param timenow: what time it is now.
* @return: 0 on error.
* @return: 0 on error. new rto otherwise.
*/
int infra_rtt_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
int roundtrip, time_t timenow);
/**
* Update information for the host, store that a TCP transaction works.
* @param infra: infrastructure cache.
* @param addr: host address.
* @param addrlen: length of addr.
*/
void infra_update_tcp_works(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen);
/**
* Update edns information for the host.
* @param infra: infrastructure cache.
@@ -226,6 +240,8 @@ int infra_edns_update(struct infra_cache* infra,
* @param name: zone name.
* @param namelen: zone name length.
* @param lame: if function returns true, this returns lameness of the zone.
* @param dnsseclame: if function returns true, this returns if the zone
* is dnssec-lame.
* @param rtt: if function returns true, this returns avg rtt of the server.
* The rtt value is unclamped and reflects recent timeouts.
* @param timenow: what time it is now.
@@ -233,7 +249,8 @@ int infra_edns_update(struct infra_cache* infra,
*/
int infra_get_lame_rtt(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, int* lame, int* rtt, time_t timenow);
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
int* rtt, time_t timenow);
/**
* Get memory used by the infra cache.
@@ -242,4 +259,30 @@ int infra_get_lame_rtt(struct infra_cache* infra,
*/
size_t infra_get_mem(struct infra_cache* infra);
/** calculate size for the hashtable, does not count size of lameness,
* so the hashtable is a fixed number of items */
size_t infra_host_sizefunc(void* k, void* d);
/** compare two addresses, returns -1, 0, or +1 */
int infra_host_compfunc(void* key1, void* key2);
/** delete key, and destroy the lock */
void infra_host_delkeyfunc(void* k, void* arg, int il);
/** delete data and destroy the lameness hashtable */
void infra_host_deldatafunc(void* d, void* arg);
/** calculate size, which is fixed, zonename does not count so that
* a fixed number of items is stored */
size_t infra_lame_sizefunc(void* k, void* d);
/** compare zone names, returns -1, 0, +1 */
int infra_lame_compfunc(void* key1, void* key2);
/** free key, lock and zonename */
void infra_lame_delkeyfunc(void* k, void* arg, int il);
/** free the lameness data */
void infra_lame_deldatafunc(void* d, void* arg);
#endif /* SERVICES_CACHE_INFRA_H */
+5 -18
View File
@@ -44,7 +44,7 @@
#include "util/config_file.h"
#include "util/data/packed_rrset.h"
#include "util/data/msgreply.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/alloc.h"
struct rrset_cache* rrset_cache_create(struct config_file* cfg,
@@ -134,21 +134,6 @@ need_to_update_rrset(void* nd, void* cd, uint32_t timenow, int equal)
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal )
return 1;
/* o see if TTL is better than TTL in cache. */
/* if so, see if rrset+rdata is the same */
/* if so, update TTL in cache, even if trust is worse. */
if( newd->ttl > cached->ttl && equal ) {
/* if the cached rrset is bogus, and this one equal,
* do not update the TTL - let it expire. */
if(cached->security == sec_status_bogus)
return 0;
/* since all else is the same, use the best trust value */
if(newd->trust < cached->trust) {
newd->trust = cached->trust;
newd->security = cached->security;
}
return 1;
}
return 0;
}
@@ -177,6 +162,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
hashvalue_t h = k->entry.hash;
uint16_t rrset_type = ntohs(k->rk.type);
int equal = 0;
log_assert(ref->id != 0 && k->id != 0);
/* looks up item with a readlock - no editing! */
if((e=slabhash_lookup(&r->table, h, k, 0)) != 0) {
/* return id and key as they will be used in the cache
@@ -206,6 +192,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
/* use insert to update entry to manage lruhash
* cache size values nicely. */
}
log_assert(ref->key->id != 0);
slabhash_insert(&r->table, h, &k->entry, k->entry.data, alloc);
if(e) {
/* For NSEC, NSEC3, DNAME, when rdata is updated, update
@@ -284,12 +271,12 @@ rrset_array_unlock(struct rrset_ref* ref, size_t count)
}
void
rrset_array_unlock_touch(struct rrset_cache* r, struct region* scratch,
rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
struct rrset_ref* ref, size_t count)
{
hashvalue_t* h;
size_t i;
if(!(h = (hashvalue_t*)region_alloc(scratch,
if(!(h = (hashvalue_t*)regional_alloc(scratch,
sizeof(hashvalue_t)*count)))
log_warn("rrset LRU: memory allocation failed");
else /* store hash values */
+2 -2
View File
@@ -47,7 +47,7 @@
struct config_file;
struct alloc_cache;
struct rrset_ref;
struct region;
struct regional;
/**
* The rrset cache
@@ -181,7 +181,7 @@ void rrset_array_unlock(struct rrset_ref* ref, size_t count);
* duplicate references are allowed and handled.
* @param count: size of array.
*/
void rrset_array_unlock_touch(struct rrset_cache* r, struct region* scratch,
void rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
struct rrset_ref* ref, size_t count);
/**
+3 -2
View File
@@ -74,6 +74,7 @@ verbose_print_addr(struct addrinfo *addr)
(socklen_t)sizeof(buf)) == 0) {
strncpy(buf, "(null)", sizeof(buf));
}
buf[sizeof(buf)-1] = 0;
verbose(VERB_ALGO, "creating %s%s socket %s %d",
addr->ai_socktype==SOCK_DGRAM?"udp":
addr->ai_socktype==SOCK_STREAM?"tcp":"otherproto",
@@ -408,7 +409,7 @@ listening_ports_open(struct config_file* cfg)
if(cfg->num_ifs == 0) {
if(do_ip6) {
hints.ai_family = AF_INET6;
if(!ports_create_if(NULL, cfg->do_udp, do_tcp,
if(!ports_create_if("::1", cfg->do_udp, do_tcp,
&hints, portbuf, &list)) {
listening_ports_free(list);
return NULL;
@@ -416,7 +417,7 @@ listening_ports_open(struct config_file* cfg)
}
if(do_ip4) {
hints.ai_family = AF_INET;
if(!ports_create_if(NULL, cfg->do_udp, do_tcp,
if(!ports_create_if("127.0.0.1", cfg->do_udp, do_tcp,
&hints, portbuf, &list)) {
listening_ports_free(list);
return NULL;
+1030
View File
File diff suppressed because it is too large Load Diff
+215
View File
@@ -0,0 +1,215 @@
/*
* services/localzone.h - local zones authority service.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains functions to enable local zone authority service.
*/
#ifndef SERVICES_LOCALZONE_H
#define SERVICES_LOCALZONE_H
#include "util/rbtree.h"
struct ub_packed_rrset_key;
struct regional;
struct config_file;
struct edns_data;
struct query_info;
/**
* Local zone type
* This type determines processing for queries that did not match
* local-data directly.
*/
enum localzone_type {
/** drop query */
local_zone_deny = 0,
/** answer with error */
local_zone_refuse,
/** answer nxdomain or nodata */
local_zone_static,
/** resolve normally */
local_zone_transparent,
/** answer with data at zone apex */
local_zone_redirect,
/** remove default AS112 blocking contents for zone
* nodefault is used in config not during service. */
local_zone_nodefault
};
/**
* Authoritative local zones storage, shared.
* This tree is fixed at startup, so, readonly, no locks or mutexes necessary.
*/
struct local_zones {
/** rbtree of struct local_zone */
rbtree_t ztree;
};
/**
* Local zone. A locally served authoritative zone.
*/
struct local_zone {
/** rbtree node, key is name and class */
rbnode_t node;
/** parent zone, if any. */
struct local_zone* parent;
/** zone name, in uncompressed wireformat */
uint8_t* name;
/** length of zone name */
size_t namelen;
/** number of labels in zone name */
int namelabs;
/** the class of this zone.
* uses 'dclass' to not conflict with c++ keyword class. */
uint16_t dclass;
/** how to process zone */
enum localzone_type type;
/** in this region the zone's data is allocated.
* the struct local_zone itself is malloced. */
struct regional* region;
/** local data for this zone
* rbtree of struct local_data */
rbtree_t data;
/** if data contains zone apex SOA data, this is a ptr to it. */
struct ub_packed_rrset_key* soa;
};
/**
* Local data. One domain name, and the RRs to go with it.
*/
struct local_data {
/** rbtree node, key is name only */
rbnode_t node;
/** domain name */
uint8_t* name;
/** length of name */
size_t namelen;
/** number of labels in name */
int namelabs;
/** the data rrsets, with different types, linked list.
* If this list is NULL, the node is an empty non-terminal. */
struct local_rrset* rrsets;
};
/**
* A local data RRset
*/
struct local_rrset {
/** next in list */
struct local_rrset* next;
/** RRset data item */
struct ub_packed_rrset_key* rrset;
};
/**
* Create local zones storage
* @return new struct or NULL on error.
*/
struct local_zones* local_zones_create();
/**
* Delete local zones storage
* @param zones: to delete.
*/
void local_zones_delete(struct local_zones* zones);
/**
* Apply config settings; setup the local authoritative data.
* @param zones: is set up.
* @param cfg: config data.
* @return false on error.
*/
int local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg);
/**
* Compare two local_zone entries in rbtree. Sort hierarchical but not
* canonical
* @param z1: zone 1
* @param z2: zone 2
* @return: -1, 0, +1 comparison value.
*/
int local_zone_cmp(const void* z1, const void* z2);
/**
* Compare two local_data entries in rbtree. Sort canonical.
* @param d1: data 1
* @param d2: data 2
* @return: -1, 0, +1 comparison value.
*/
int local_data_cmp(const void* d1, const void* d2);
/**
* Delete one zone
* @param z: to delete.
*/
void local_zone_delete(struct local_zone* z);
/**
* Lookup zone that contains the given name, class.
* @param zones: the zones tree
* @param name: dname to lookup
* @param len: length of name.
* @param labs: labelcount of name.
* @param dclass: class to lookup.
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass);
/**
* Debug helper. Print all zones
* @param zones: the zones tree
*/
void local_zones_print(struct local_zones* zones);
/**
* Answer authoritatively for local zones.
* @param zones: the stored zones (shared, read only).
* @param qinfo: query info (parsed).
* @param edns: edns info (parsed).
* @param buf: buffer with query ID and flags, also for reply.
* @param temp: temporary storage region.
* @return true if answer is in buffer. false if query is not answered
* by authority data. If the reply should be dropped altogether, the return
* value is true, but the buffer is cleared (empty).
*/
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
struct edns_data* edns, ldns_buffer* buf, struct regional* temp);
#endif /* SERVICES_LOCALZONE_H */
+30 -17
View File
@@ -49,12 +49,13 @@
#include "util/log.h"
#include "util/net_help.h"
#include "util/module.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/data/msgencode.h"
#include "util/timehist.h"
#include "util/fptr_wlist.h"
#include "util/alloc.h"
/** compare two mesh_states */
static int
int
mesh_state_compare(const void* ap, const void* bp)
{
struct mesh_state* a = (struct mesh_state*)ap;
@@ -78,8 +79,7 @@ mesh_state_compare(const void* ap, const void* bp)
return query_info_compare(&a->s.qinfo, &b->s.qinfo);
}
/** compare two mesh references */
static int
int
mesh_state_ref_compare(const void* ap, const void* bp)
{
struct mesh_state_ref* a = (struct mesh_state_ref*)ap;
@@ -196,15 +196,15 @@ struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
uint16_t qflags, int prime)
{
region_type* region = region_create(malloc, free);
struct regional* region = alloc_reg_obtain(env->alloc);
struct mesh_state* mstate;
int i;
if(!region)
return NULL;
mstate = (struct mesh_state*)region_alloc(region,
mstate = (struct mesh_state*)regional_alloc(region,
sizeof(struct mesh_state));
if(!mstate) {
region_destroy(region);
alloc_reg_release(env->alloc, region);
return NULL;
}
memset(mstate, 0, sizeof(*mstate));
@@ -215,14 +215,15 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
mstate->reply_list = NULL;
rbtree_init(&mstate->super_set, &mesh_state_ref_compare);
rbtree_init(&mstate->sub_set, &mesh_state_ref_compare);
mstate->num_activated = 0;
/* init module qstate */
mstate->s.qinfo.qtype = qinfo->qtype;
mstate->s.qinfo.qclass = qinfo->qclass;
mstate->s.qinfo.qname_len = qinfo->qname_len;
mstate->s.qinfo.qname = region_alloc_init(region, qinfo->qname,
mstate->s.qinfo.qname = regional_alloc_init(region, qinfo->qname,
qinfo->qname_len);
if(!mstate->s.qinfo.qname) {
region_destroy(region);
alloc_reg_release(env->alloc, region);
return NULL;
}
/* remove all weird bits from qflags */
@@ -253,11 +254,12 @@ mesh_state_cleanup(struct mesh_state* mstate)
/* de-init modules */
mesh = mstate->s.env->mesh;
for(i=0; i<mesh->num_modules; i++) {
log_assert(fptr_whitelist_mod_clear(mesh->modfunc[i]->clear));
(*mesh->modfunc[i]->clear)(&mstate->s, i);
mstate->s.minfo[i] = NULL;
mstate->s.ext_state[i] = module_finished;
}
region_destroy(mstate->s.region);
alloc_reg_release(mstate->s.env->alloc, mstate->s.region);
}
void
@@ -348,9 +350,9 @@ int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
struct rbnode_t* n;
struct mesh_state_ref* subref; /* points to sub, inserted in super */
struct mesh_state_ref* superref; /* points to super, inserted in sub */
if( !(subref = region_alloc(super->s.region,
if( !(subref = regional_alloc(super->s.region,
sizeof(struct mesh_state_ref))) ||
!(superref = region_alloc(sub->s.region,
!(superref = regional_alloc(sub->s.region,
sizeof(struct mesh_state_ref))) ) {
log_err("mesh_state_attachment: out of memory");
return 0;
@@ -490,6 +492,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
/* make super runnable */
(void)rbtree_insert(&mesh->run, &ref->s->run_node);
/* callback the function to inform super of result */
log_assert(fptr_whitelist_mod_inform_super(
mesh->modfunc[ref->s->s.curmod]->inform_super));
(*mesh->modfunc[ref->s->s.curmod]->inform_super)(&mstate->s,
ref->s->s.curmod, &ref->s->s);
}
@@ -513,7 +517,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
struct comm_reply* rep, uint16_t qid, uint16_t qflags)
{
struct mesh_reply* r = region_alloc(s->s.region,
struct mesh_reply* r = regional_alloc(s->s.region,
sizeof(struct mesh_reply));
if(!r)
return 0;
@@ -550,6 +554,14 @@ static int
mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
enum module_ext_state s, enum module_ev* ev)
{
mstate->num_activated++;
if(mstate->num_activated > MESH_MAX_ACTIVATION) {
/* module is looping. Stop it. */
log_err("internal error: looping module stopped");
log_query_info(VERB_DETAIL, "pass error for qstate",
&mstate->s.qinfo);
s = module_error;
}
if(s == module_wait_module) {
/* start next module */
mstate->s.curmod++;
@@ -557,7 +569,6 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
log_err("Cannot pass to next module; at last module");
log_query_info(VERB_DETAIL, "pass error for qstate",
&mstate->s.qinfo);
log_assert(0); /* catch this for now */
mstate->s.curmod--;
return mesh_continue(mesh, mstate, module_error, ev);
}
@@ -590,12 +601,14 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
verbose(VERB_ALGO, "mesh_run: start");
while(mstate) {
/* run the module */
log_assert(fptr_whitelist_mod_operate(
mesh->modfunc[mstate->s.curmod]->operate));
(*mesh->modfunc[mstate->s.curmod]->operate)
(&mstate->s, ev, mstate->s.curmod, e);
/* examine results */
mstate->s.reply = NULL;
region_free_all(mstate->s.env->scratch);
regional_free_all(mstate->s.env->scratch);
s = mstate->s.ext_state[mstate->s.curmod];
verbose(VERB_ALGO, "mesh_run: %s module exit state is %s",
mesh->modfunc[mstate->s.curmod]->name, strextstate(s));
@@ -663,7 +676,7 @@ mesh_get_mem(struct mesh_area* mesh)
sizeof(struct th_buck)*mesh->histogram->num;
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
/* all, including m itself allocated in qstate region */
s += region_get_mem(m->s.region);
s += regional_get_mem(m->s.region);
}
return s;
}
+14
View File
@@ -57,6 +57,12 @@ struct reply_info;
struct outbound_entry;
struct timehist;
/**
* Maximum number of mesh state activations. Any more is likely an
* infinite loop in the module. It is then terminated.
*/
#define MESH_MAX_ACTIVATION 1000
/**
* Mesh of query states
*/
@@ -117,6 +123,8 @@ struct mesh_state {
/** set of substates (that this state needs to continue)
* contains struct mesh_state_ref* */
rbtree_t sub_set;
/** number of activations for the mesh state */
size_t num_activated;
};
/**
@@ -370,4 +378,10 @@ size_t mesh_get_mem(struct mesh_area* mesh);
int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime);
/** compare two mesh_states */
int mesh_state_compare(const void* ap, const void* bp);
/** compare two mesh references */
int mesh_state_ref_compare(const void* ap, const void* bp);
#endif /* SERVICES_MESH_H */
+57 -48
View File
@@ -50,6 +50,7 @@
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@@ -60,17 +61,13 @@
/** number of times to retry making a random ID that is unique. */
#define MAX_ID_RETRY 1000
/** number of retries on outgoing UDP queries */
#define OUTBOUND_UDP_RETRY 4
#define OUTBOUND_UDP_RETRY 1
/** callback for serviced query UDP answers */
static int serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep);
/** initiate TCP transaction for serviced query */
static void serviced_tcp_initiate(struct outside_network* outnet,
struct serviced_query* sq, ldns_buffer* buff);
/** compare function of pending rbtree */
static int
int
pending_cmp(const void* key1, const void* key2)
{
struct pending *p1 = (struct pending*)key1;
@@ -83,8 +80,7 @@ pending_cmp(const void* key1, const void* key2)
return sockaddr_cmp(&p1->addr, p1->addrlen, &p2->addr, p2->addrlen);
}
/** compare function of serviced query rbtree */
static int
int
serviced_cmp(const void* key1, const void* key2)
{
struct serviced_query* q1 = (struct serviced_query*)key1;
@@ -95,7 +91,7 @@ serviced_cmp(const void* key1, const void* key2)
if(q1->qbuflen > q2->qbuflen)
return 1;
log_assert(q1->qbuflen == q2->qbuflen);
/* FIXME: will not detect alternate casing of qname */
/* will not detect alternate casing of qname */
if((r = memcmp(q1->qbuf, q2->qbuf, q1->qbuflen)) != 0)
return r;
if(q1->dnssec != q2->dnssec) {
@@ -126,23 +122,24 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
int s;
log_assert(pend);
log_assert(pkt);
log_assert(w->addrlen > 0);
/* open socket */
#ifndef INET6
if(addr_is_ip6(addr))
#ifdef INET6
if(addr_is_ip6(&w->addr, w->addrlen))
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
else
#endif
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == -1) {
log_err("outgoing tcp: socket: %s", strerror(errno));
log_addr("failed address", &w->addr, w->addrlen);
log_addr(0, "failed address", &w->addr, w->addrlen);
return 0;
}
fd_set_nonblock(s);
if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
if(errno != EINPROGRESS) {
log_err("outgoing tcp: connect: %s", strerror(errno));
log_addr("failed address", &w->addr, w->addrlen);
log_addr(0, "failed address", &w->addr, w->addrlen);
close(s);
return 0;
}
@@ -153,6 +150,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
w->outnet->tcp_free = pend->next_free;
pend->next_free = NULL;
pend->query = w;
pend->c->repinfo.addrlen = w->addrlen;
memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen);
ldns_buffer_clear(pend->c->buffer);
ldns_buffer_write(pend->c->buffer, pkt, pkt_len);
ldns_buffer_flip(pend->c->buffer);
@@ -176,6 +175,7 @@ use_free_buffer(struct outside_network* outnet)
comm_point_callback_t* cb = w->cb;
void* cb_arg = w->cb_arg;
waiting_tcp_delete(w);
log_assert(fptr_whitelist_pending_tcp(cb));
(void)(*cb)(NULL, cb_arg, NETEVENT_CLOSED, NULL);
}
}
@@ -194,8 +194,7 @@ decomission_pending_tcp(struct outside_network* outnet,
use_free_buffer(outnet);
}
/** callback for pending tcp connections */
static int
int
outnet_tcp_cb(struct comm_point* c, void* arg, int error,
struct comm_reply *reply_info)
{
@@ -209,18 +208,19 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
/* check ID */
if(ldns_buffer_limit(c->buffer) < sizeof(uint16_t) ||
LDNS_ID_WIRE(ldns_buffer_begin(c->buffer))!=pend->id) {
log_addr("outnettcp: bad ID in reply, from:",
log_addr(VERB_DETAIL,
"outnettcp: bad ID in reply, from:",
&pend->query->addr, pend->query->addrlen);
error = NETEVENT_CLOSED;
}
}
log_assert(fptr_whitelist_pending_tcp(pend->query->cb));
(void)(*pend->query->cb)(c, pend->query->cb_arg, error, reply_info);
decomission_pending_tcp(outnet, pend);
return 0;
}
/** callback for incoming udp answers from the network */
static int
int
outnet_udp_cb(struct comm_point* c, void* arg, int error,
struct comm_reply *reply_info)
{
@@ -244,26 +244,20 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
key.addrlen = reply_info->addrlen;
verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
if(verbosity >= VERB_ALGO) {
log_addr("Incoming reply addr =", &reply_info->addr, reply_info->addrlen);
}
log_addr(VERB_ALGO, "Incoming reply addr =",
&reply_info->addr, reply_info->addrlen);
/* find it, see if this thing is a valid query response */
verbose(VERB_ALGO, "lookup size is %d entries", (int)outnet->pending->count);
p = (struct pending*)rbtree_search(outnet->pending, &key);
if(!p) {
verbose(VERB_DETAIL, "received unwanted or unsolicited udp reply dropped.");
if(verbosity >= VERB_ALGO)
log_hex("dropped message",
ldns_buffer_begin(c->buffer),
ldns_buffer_limit(c->buffer));
log_buf(VERB_ALGO, "dropped message", c->buffer);
return 0;
}
verbose(VERB_ALGO, "received udp reply.");
if(verbosity >= VERB_ALGO)
log_hex("udp message", ldns_buffer_begin(c->buffer),
ldns_buffer_limit(c->buffer));
log_buf(VERB_ALGO, "udp message", c->buffer);
if(p->c != c) {
verbose(VERB_DETAIL, "received reply id,addr on wrong port. "
"dropped.");
@@ -273,6 +267,7 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "outnet handle udp reply");
/* delete from tree first in case callback creates a retry */
(void)rbtree_delete(outnet->pending, p->node.key);
log_assert(fptr_whitelist_pending_udp(p->cb));
(void)(*p->cb)(p->c, p->cb_arg, NETEVENT_NOERROR, reply_info);
pending_delete(NULL, p);
return 0;
@@ -381,13 +376,13 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
}
/** callback for udp timeout */
static void
void
pending_udp_timer_cb(void *arg)
{
struct pending* p = (struct pending*)arg;
/* it timed out */
verbose(VERB_ALGO, "timeout udp");
log_assert(fptr_whitelist_pending_udp(p->cb));
(void)(*p->cb)(p->c, p->cb_arg, NETEVENT_TIMEOUT, NULL);
pending_delete(p->outnet, p);
}
@@ -492,6 +487,11 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->num_udp6 = done_6;
outnet->num_udp4 = done_4;
}
if(outnet->num_udp4 + outnet->num_udp6 == 0) {
log_err("Could not open any ports on outgoing interfaces");
outside_network_delete(outnet);
return NULL;
}
return outnet;
}
@@ -605,7 +605,6 @@ new_pending(struct outside_network* outnet, ldns_buffer* packet,
return NULL;
}
/* set */
/* id uses lousy random() TODO use better and entropy */
pend->id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
memcpy(&pend->addr, addr, addrlen);
@@ -646,7 +645,7 @@ select_port(struct outside_network* outnet, struct pending* pend,
log_assert(outnet && pend);
/* first select ip4 or ip6. */
if(addr_is_ip6(&pend->addr))
if(addr_is_ip6(&pend->addr, pend->addrlen))
nummax = (int)outnet->num_udp6;
else nummax = (int)outnet->num_udp4;
@@ -657,7 +656,6 @@ select_port(struct outside_network* outnet, struct pending* pend,
}
/* choose a random outgoing port and interface */
/* TODO: entropy source. */
precho = (double)ub_random(rnd) * (double)nummax /
((double)RAND_MAX + 1.0);
chosen = (int)precho;
@@ -666,7 +664,7 @@ select_port(struct outside_network* outnet, struct pending* pend,
if(chosen < 0) chosen = 0;
if(chosen >= nummax) chosen = nummax-1;
if(addr_is_ip6(&pend->addr))
if(addr_is_ip6(&pend->addr, pend->addrlen))
pend->c = outnet->udp6_ports[chosen];
else pend->c = outnet->udp4_ports[chosen];
log_assert(pend->c);
@@ -709,8 +707,7 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
return pend;
}
/** callback for outgoing TCP timer event */
static void
void
outnet_tcptimer(void* arg)
{
struct waiting_tcp* w = (struct waiting_tcp*)arg;
@@ -741,6 +738,7 @@ outnet_tcptimer(void* arg)
cb = w->cb;
cb_arg = w->cb_arg;
waiting_tcp_delete(w);
log_assert(fptr_whitelist_pending_tcp(cb));
(void)(*cb)(NULL, cb_arg, NETEVENT_TIMEOUT, NULL);
use_free_buffer(outnet);
}
@@ -767,7 +765,6 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
}
w->pkt = NULL;
w->pkt_len = 0;
/* id uses lousy random() TODO use better and entropy */
id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
LDNS_ID_SET(ldns_buffer_begin(packet), id);
memcpy(&w->addr, addr, addrlen);
@@ -1006,6 +1003,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
ldns_buffer_write(c->buffer, backup_p, backlen);
ldns_buffer_flip(c->buffer);
}
log_assert(fptr_whitelist_serviced_query(p->cb));
(void)(*p->cb)(c, p->cb_arg, error, rep);
p = n;
}
@@ -1018,16 +1016,19 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
serviced_delete(sq);
}
/** TCP reply or error callback for serviced queries */
static int
int
serviced_tcp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep)
{
struct serviced_query* sq = (struct serviced_query*)arg;
struct comm_reply r2;
sq->pending = NULL; /* removed after this callback */
if(error != NETEVENT_NOERROR && verbosity >= VERB_DETAIL)
log_addr("tcp error for address", &sq->addr, sq->addrlen);
if(error != NETEVENT_NOERROR)
log_addr(VERB_DETAIL, "tcp error for address",
&sq->addr, sq->addrlen);
if(error==NETEVENT_NOERROR)
infra_update_tcp_works(sq->outnet->infra, &sq->addr,
sq->addrlen);
if(error==NETEVENT_NOERROR && LDNS_RCODE_WIRE(ldns_buffer_begin(
c->buffer)) == LDNS_RCODE_FORMERR &&
sq->status == serviced_query_TCP_EDNS) {
@@ -1066,13 +1067,14 @@ serviced_tcp_initiate(struct outside_network* outnet,
}
}
static int
int
serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep)
{
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
struct timeval now;
int fallback_tcp = 0;
if(gettimeofday(&now, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
/* this option does not need current time */
@@ -1080,9 +1082,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
int rto = 0;
sq->retry++;
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
-1, (time_t)now.tv_sec))
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
-1, (time_t)now.tv_sec)))
log_err("out of memory in UDP exponential backoff");
if(sq->retry < OUTBOUND_UDP_RETRY) {
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
@@ -1092,8 +1095,13 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
return 0;
}
error = NETEVENT_TIMEOUT;
/* UDP does not work, fallback to TCP below */
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;
}
}
if(error == NETEVENT_NOERROR && sq->status == serviced_query_UDP_EDNS
&& LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
@@ -1110,8 +1118,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
}
return 0;
}
if(error != NETEVENT_NOERROR ||
LDNS_TC_WIRE(ldns_buffer_begin(c->buffer))) {
if(LDNS_TC_WIRE(ldns_buffer_begin(c->buffer)) ||
(error != NETEVENT_NOERROR && fallback_tcp) ) {
/* fallback to TCP */
/* this discards partial UDP contents */
if(sq->status == serviced_query_UDP_EDNS)
@@ -1128,6 +1136,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
int roundtime = (now.tv_sec - sq->last_sent_time.tv_sec)*1000
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
log_assert(roundtime >= 0);
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
roundtime, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
+28
View File
@@ -369,4 +369,32 @@ size_t outnet_get_mem(struct outside_network* outnet);
*/
size_t serviced_get_mem(struct serviced_query* sq);
/** callback for incoming udp answers from the network */
int outnet_udp_cb(struct comm_point* c, void* arg, int error,
struct comm_reply *reply_info);
/** callback for pending tcp connections */
int outnet_tcp_cb(struct comm_point* c, void* arg, int error,
struct comm_reply *reply_info);
/** callback for udp timeout */
void pending_udp_timer_cb(void *arg);
/** callback for outgoing TCP timer event */
void outnet_tcptimer(void* arg);
/** callback for serviced query UDP answers */
int serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep);
/** TCP reply or error callback for serviced queries */
int serviced_tcp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep);
/** compare function of pending rbtree */
int pending_cmp(const void* key1, const void* key2);
/** compare function of serviced query rbtree */
int serviced_cmp(const void* key1, const void* key2);
#endif /* OUTSIDE_NETWORK_H */
+18 -1
View File
@@ -63,7 +63,7 @@ static ub_thread_key_t thr_debug_key;
/** the list of threads, so all threads can be examined. NULL if unused. */
static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS];
/** do we check locking order */
int check_locking_order = 0;
int check_locking_order = 1;
/** the pid of this runset, reasonably unique. */
static pid_t check_lock_pid;
@@ -830,3 +830,20 @@ checklock_thrjoin(pthread_t thread)
}
#endif /* USE_THREAD_DEBUG */
int order_lock_cmp(const void* e1, const void* e2)
{
struct order_id* o1 = (struct order_id*)e1;
struct order_id* o2 = (struct order_id*)e2;
if(o1->thr < o2->thr) return -1;
if(o1->thr > o2->thr) return 1;
if(o1->instance < o2->instance) return -1;
if(o1->instance > o2->instance) return 1;
return 0;
}
int
codeline_cmp(const void* a, const void* b)
{
return strcmp((const char*)a, (const char*)b);
}
+12
View File
@@ -341,4 +341,16 @@ typedef pthread_key_t ub_thread_key_t;
#endif /* USE_THREAD_DEBUG */
/** keep track of lock id in lock-verify application */
struct order_id {
/** the thread id that created it */
int thr;
/** the instance number of creation */
int instance;
};
/** compare two order_ids */
int order_lock_cmp(const void* e1, const void* e2);
/** compare two codeline structs for rbtree */
int codeline_cmp(const void* a, const void* b);
#endif /* TESTCODE_CHECK_LOCKS_H */
+13 -1
View File
@@ -2,7 +2,9 @@
NEED_SPLINT='00-lint.tpkg'
NEED_DOXYGEN='01-doc.tpkg'
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg'
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg fwd_tcp_tc6.tpkg fwd_compress_c00c.tpkg'
NEED_XXD='fwd_compress_c00c.tpkg'
NEED_NC='fwd_compress_c00c.tpkg'
cd testdata;
sh ../testcode/mini_tpkg.sh clean
@@ -23,6 +25,16 @@ for test in `ls *.tpkg`; do
SKIP=1;
fi
fi
if echo $NEED_XXD | grep $test >/dev/null; then
if test ! -x "`which xxd`"; then
SKIP=1;
fi
fi
if echo $NEED_NC | grep $test >/dev/null; then
if test ! -x "`which nc`"; then
SKIP=1;
fi
fi
if test $SKIP -eq 0; then
echo $test
sh ../testcode/mini_tpkg.sh -a ../.. exe $test
+110 -6
View File
@@ -56,6 +56,7 @@
#include "testcode/replay.h"
#include "testcode/ldns-testpkts.h"
#include "util/log.h"
#include <signal.h>
/** Global variable: the scenario. Saved here for when event_init is done. */
static struct replay_scenario* saved_scenario = NULL;
@@ -178,7 +179,7 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
"with entry line %d", timenow,
p->start_step, p->end_step, (*entry)->lineno);
if(p->addrlen != 0)
log_addr("matched ip", &p->addr, p->addrlen);
log_addr(0, "matched ip", &p->addr, p->addrlen);
log_pkt("matched pkt: ", (*entry)->reply_list->reply);
return 1;
}
@@ -359,6 +360,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
else repinfo.c->type = comm_udp;
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL);
log_info("testbound: incoming QUERY");
log_pkt("query pkt", todo->match->reply_list->reply);
/* call the callback for incoming queries */
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
NETEVENT_NOERROR, &repinfo)) {
@@ -379,6 +381,9 @@ fake_pending_callback(struct replay_runtime* runtime,
struct fake_pending* p = runtime->pending_list;
struct comm_reply repinfo;
struct comm_point c;
void* cb_arg = p->cb_arg;
comm_point_callback_t* cb = p->callback;
memset(&c, 0, sizeof(c));
if(!p) fatal_exit("No pending queries.");
log_assert(todo->qname == NULL); /* or find that one */
@@ -392,12 +397,13 @@ fake_pending_callback(struct replay_runtime* runtime,
repinfo.c = &c;
repinfo.addrlen = p->addrlen;
memcpy(&repinfo.addr, &p->addr, p->addrlen);
if((*p->callback)(&c, p->cb_arg, error, &repinfo)) {
if(!p->serviced)
pending_list_delete(runtime, p);
if((*cb)(&c, cb_arg, error, &repinfo)) {
fatal_exit("unexpected: pending callback returned 1");
}
/* delete the pending item. */
ldns_buffer_free(c.buffer);
pending_list_delete(runtime, p);
}
/**
@@ -517,6 +523,7 @@ run_scenario(struct replay_runtime* runtime)
fatal_exit("testbound: there are unmatched answers.");
}
log_info("testbound: exiting fake runloop.");
runtime->exit_cleanly = 1;
}
/*********** Dummy routines ***********/
@@ -590,13 +597,19 @@ comm_base_dispatch(struct comm_base* b)
{
struct replay_runtime* runtime = (struct replay_runtime*)b;
run_scenario(runtime);
if(runtime->sig_cb)
(*runtime->sig_cb)(SIGTERM, runtime->sig_cb_arg);
else exit(0); /* OK exit when LIBEVENT_SIGNAL_PROBLEM exists */
}
void
comm_base_exit(struct comm_base* ATTR_UNUSED(b))
comm_base_exit(struct comm_base* b)
{
/* some sort of failure */
fatal_exit("testbound: comm_base_exit was called.");
struct replay_runtime* runtime = (struct replay_runtime*)b;
if(!runtime->exit_cleanly) {
/* some sort of failure */
fatal_exit("testbound: comm_base_exit was called.");
}
}
struct comm_signal*
@@ -959,4 +972,95 @@ size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c))
return 0;
}
/* fake for fptr wlist */
int outnet_udp_cb(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply *ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
int outnet_tcp_cb(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply *ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
{
log_assert(0);
}
void outnet_tcptimer(void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_udp_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_tcp_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_timer_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_signal_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void comm_point_local_handle_callback(int ATTR_UNUSED(fd),
short ATTR_UNUSED(event), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int serviced_udp_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
int serviced_tcp_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(reply_info))
{
log_assert(0);
return 0;
}
int pending_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);
return 0;
}
int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);
return 0;
}
/*********** End of Dummy routines ***********/
+3
View File
@@ -185,6 +185,7 @@ static void replyline(const char* line, ldns_pkt *reply)
} else if(str_keyword(&parse, "AD")) {
ldns_pkt_set_ad(reply, true);
} else if(str_keyword(&parse, "DO")) {
ldns_pkt_set_edns_udp_size(reply, 4096);
ldns_pkt_set_edns_do(reply, true);
} else {
error("could not parse REPLY: '%s'", parse);
@@ -533,6 +534,8 @@ read_datafile(const char* name)
verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
fclose(in);
ldns_rdf_deep_free(origin);
ldns_rdf_deep_free(prev_rr);
return list;
}
+3 -21
View File
@@ -46,18 +46,12 @@
#include "config.h"
#include "util/log.h"
#include "util/rbtree.h"
#include "util/locks.h"
#include "testcode/checklocks.h"
/* --- data structures --- */
struct lock_ref;
/** key for lock lookup */
struct order_id {
/** the thread id that created it */
int thr;
/** the instance number of creation */
int instance;
};
/** a lock */
struct order_lock {
/** rbnode in all tree */
@@ -103,18 +97,6 @@ usage()
printf("lock_verify <trace files>\n");
}
/** compare two order_ids */
int order_lock_cmp(const void* e1, const void* e2)
{
struct order_id* o1 = (struct order_id*)e1;
struct order_id* o2 = (struct order_id*)e2;
if(o1->thr < o2->thr) return -1;
if(o1->thr > o2->thr) return 1;
if(o1->instance < o2->instance) return -1;
if(o1->instance > o2->instance) return 1;
return 0;
}
/** read header entry.
* @param in: file to read header of.
* @return: False if it does not belong to the rest. */
@@ -403,7 +385,7 @@ main(int argc, char* argv[])
usage();
return 1;
}
log_init(NULL);
log_init(NULL, 0, NULL);
log_ident_set("lock-verify");
/* init */
all_locks = rbtree_create(order_lock_cmp);
+16 -42
View File
@@ -42,6 +42,8 @@
#include "config.h"
#include "util/log.h"
#include "util/rbtree.h"
#include "util/locks.h"
#include "testcode/checklocks.h"
#include <sys/stat.h>
/**
@@ -58,14 +60,8 @@ struct codeline {
uint64_t alloc;
/** number of bytes freed */
uint64_t free;
};
/**
* Other allocation stats
*/
struct alloc_misc {
/** number of region allocs */
uint64_t region_alloc;
/** number allocations and frees */
uint64_t calls;
};
/** print usage and exit */
@@ -77,13 +73,6 @@ usage()
exit(1);
}
/** compare two codeline structs for rbtree */
static int
codeline_cmp(const void* a, const void* b)
{
return strcmp((const char*)a, (const char*)b);
}
/** match logfile line to see if it needs accounting processing */
static int
match(char* line)
@@ -106,18 +95,6 @@ match(char* line)
return 0;
}
/** read up the region stats */
static void
read_region_stat(char* line, struct alloc_misc* misc)
{
long num = 0;
if(sscanf(line+50, "%ld", &num) != 1) {
printf("%s\n%s\n", line, line+50);
fatal_exit("unhandled region");
}
misc->region_alloc += num;
}
/** find or alloc codeline in tree */
static struct codeline*
get_codeline(rbtree_t* tree, char* key, char* func)
@@ -158,6 +135,7 @@ read_malloc_stat(char* line, rbtree_t* tree)
if(!cl)
fatal_exit("alloc failure");
cl->alloc += num;
cl->calls ++;
}
/** read up the calloc stats */
@@ -182,6 +160,7 @@ read_calloc_stat(char* line, rbtree_t* tree)
if(!cl)
fatal_exit("alloc failure");
cl->alloc += num*sz;
cl->calls ++;
}
/** get size of file */
@@ -197,7 +176,7 @@ get_file_size(const char* fname)
/** read the logfile */
static void
readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
readfile(rbtree_t* tree, const char* fname)
{
off_t total = get_file_size(fname);
off_t done = (off_t)0;
@@ -218,8 +197,6 @@ readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
if(!match(buf))
continue;
if(strncmp(buf+36, "region ", 7) == 0)
read_region_stat(buf, misc);
else if(strstr(buf+36, "malloc("))
read_malloc_stat(buf, tree);
else if(strstr(buf+36, "calloc("))
@@ -235,20 +212,19 @@ readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
/** print memory stats */
static void
printstats(rbtree_t* tree, struct alloc_misc* misc)
printstats(rbtree_t* tree)
{
struct codeline* cl;
uint64_t total = 0;
printf("%12lld in region alloc\n", (long long)misc->region_alloc);
total += misc->region_alloc;
uint64_t total = 0, tcalls = 0;
RBTREE_FOR(cl, struct codeline*, tree) {
printf("%12lld in %s %s\n", (long long)cl->alloc,
cl->codeline, cl->func);
printf("%12lld / %8lld in %s %s\n", (long long)cl->alloc,
(long long)cl->calls, cl->codeline, cl->func);
total += cl->alloc;
tcalls += cl->calls;
}
printf("------------\n");
printf("%12lld total in %ld code lines\n", (long long)total,
(long)tree->count);
printf("%12lld / %8lld total in %ld code lines\n", (long long)total,
(long long)tcalls, (long)tree->count);
printf("\n");
}
@@ -256,15 +232,13 @@ printstats(rbtree_t* tree, struct alloc_misc* misc)
int main(int argc, const char* argv[])
{
rbtree_t* tree = 0;
struct alloc_misc misc;
if(argc != 2) {
usage();
}
tree = rbtree_create(codeline_cmp);
if(!tree)
fatal_exit("alloc failure");
memset(&misc, 0, sizeof(misc));
readfile(tree, argv[1], &misc);
printstats(tree, &misc);
readfile(tree, argv[1]);
printstats(tree);
return 0;
}
+11 -2
View File
@@ -135,8 +135,10 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
parse = line;
while(isspace((int)*parse))
parse++;
if(!*parse || *parse == ';')
if(!*parse || *parse == ';') {
pos = ftello(in);
continue;
}
if(parse_keyword(&parse, "ADDRESS")) {
while(isspace((int)*parse))
parse++;
@@ -206,6 +208,8 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
} else if(parse_keyword(&remain, "QUERY")) {
mom->evt_type = repevt_front_query;
readentry = 1;
if(!extstrtoaddr("127.0.0.1", &mom->addr, &mom->addrlen))
fatal_exit("internal error");
} else if(parse_keyword(&remain, "CHECK_ANSWER")) {
mom->evt_type = repevt_front_reply;
readentry = 1;
@@ -227,13 +231,18 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
while(isspace((int)*remain))
remain++;
if(parse_keyword(&remain, "ADDRESS")) {
while(isspace((int)*remain))
remain++;
if(strlen(remain) > 0) /* remove \n */
remain[strlen(remain)-1] = 0;
printf("remain '%s'\n", remain);
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
log_err("line %d: could not parse ADDRESS: %s",
*lineno, remain);
free(mom);
return NULL;
}
}
}
if(readentry) {
mom->match = read_entry(in, name, lineno, ttl, or, prev);
+2
View File
@@ -228,6 +228,8 @@ struct replay_runtime {
void (*sig_cb)(int, void*);
/** signal handler user arg */
void *sig_cb_arg;
/** time to exit cleanly */
int exit_cleanly;
/** size of buffers */
size_t bufsize;
+1 -1
View File
@@ -236,7 +236,7 @@ process_nsec3(int argc, char* argv[])
/** main program */
int main(int argc, char* argv[])
{
log_init(NULL);
log_init(NULL, 0, NULL);
if(argc != 6) {
usage();
}
+4 -4
View File
@@ -43,10 +43,10 @@ function dotest()
fi
cat >makeconf.mak.$$ << EOF
configure: configure.ac
$AC_CMD
touch configure
Makefile: configure Makefile.in
#configure: configure.ac
# $AC_CMD
# touch configure
Makefile: Makefile.in #configure
./configure $CONFIGURE_FLAGS $DISABLE
touch Makefile
EOF
+7 -1
View File
@@ -135,6 +135,12 @@ setup_config(FILE* in, char* configfile, int* lineno,
if(!cfg) fatal_exit("could not open %s: %s",
configfile, strerror(errno));
line[MAX_LINE_LEN-1] = 0;
/* some basic settings to not pollute the host system */
fprintf(cfg, "server: use-syslog: no\n");
fprintf(cfg, " directory: \"\"\n");
fprintf(cfg, " chroot: \"\"\n");
fprintf(cfg, " username: \"\"\n");
fprintf(cfg, " pidfile: \"\"\n");
while(fgets(line, MAX_LINE_LEN-1, in)) {
parse = line;
(*lineno)++;
@@ -204,7 +210,7 @@ main(int argc, char* argv[])
char* init_optarg = optarg;
struct replay_scenario* scen = NULL;
log_init(NULL);
log_init(NULL, 0, NULL);
log_info("Start of %s testbound program.", PACKAGE_STRING);
/* determine commandline options for the daemon */
cfgfile[0] = 0;
+55 -92
View File
@@ -42,36 +42,24 @@
#include "testcode/unitmain.h"
#include "util/log.h"
#include "util/storage/lruhash.h"
#include "util/storage/slabhash.h" /* for the test structures */
/* --- test representation --- */
/** structure contains test key */
struct testkey {
/** the key id */
int id;
/** the entry */
struct lruhash_entry entry;
};
/** structure contains test data */
struct testdata {
/** data value */
int data;
};
/** use this type for the lruhash test key */
typedef struct slabhash_testkey testkey_t;
/** use this type for the lruhash test data */
typedef struct slabhash_testdata testdata_t;
/** sizefunc for lruhash */
static size_t test_sizefunc(void*, void*);
/** comparefunc for lruhash */
static int test_compfunc(void*, void*);
/** delkey for lruhash */
static void test_delkey(void*, void*, int);
/** deldata for lruhash */
static void test_deldata(void*, void*);
/* --- end test representation --- */
/** delete key */
static void delkey(struct slabhash_testkey* k) {
lock_rw_destroy(&k->entry.lock); free(k);}
/** delete data */
static void deldata(struct slabhash_testdata* d) {free(d);}
/** hash func, very bad to improve collisions */
static hashvalue_t myhash(int id) {return (hashvalue_t)id & 0x0f;}
/** allocate new key, fill in hash */
static struct testkey* newkey(int id) {
struct testkey* k = (struct testkey*)calloc(1, sizeof(struct testkey));
static testkey_t* newkey(int id) {
testkey_t* k = (testkey_t*)calloc(1, sizeof(testkey_t));
if(!k) fatal_exit("out of memory");
k->id = id;
k->entry.hash = myhash(id);
@@ -80,28 +68,23 @@ static struct testkey* newkey(int id) {
return k;
}
/** new data el */
static struct testdata* newdata(int val) {
struct testdata* d = (struct testdata*)calloc(1,
sizeof(struct testdata));
static testdata_t* newdata(int val) {
testdata_t* d = (testdata_t*)calloc(1,
sizeof(testdata_t));
if(!d) fatal_exit("out of memory");
d->data = val;
return d;
}
/** delete key */
static void delkey(struct testkey* k) {
lock_rw_destroy(&k->entry.lock); free(k);}
/** delete data */
static void deldata(struct testdata* d) {free(d);}
/** test bin_find_entry function and bin_overflow_remove */
static void
test_bin_find_entry(struct lruhash* table)
{
struct testkey* k = newkey(12);
struct testdata* d = newdata(128);
struct testkey* k2 = newkey(12 + 1024);
struct testkey* k3 = newkey(14);
struct testkey* k4 = newkey(12 + 1024*2);
testkey_t* k = newkey(12);
testdata_t* d = newdata(128);
testkey_t* k2 = newkey(12 + 1024);
testkey_t* k3 = newkey(14);
testkey_t* k4 = newkey(12 + 1024*2);
hashvalue_t h = myhash(12);
struct lruhash_bin bin;
memset(&bin, 0, sizeof(bin));
@@ -178,8 +161,8 @@ test_bin_find_entry(struct lruhash* table)
/** test lru_front lru_remove */
static void test_lru(struct lruhash* table)
{
struct testkey* k = newkey(12);
struct testkey* k2 = newkey(14);
testkey_t* k = newkey(12);
testkey_t* k2 = newkey(14);
lock_quick_lock(&table->lock);
unit_assert( table->lru_start == NULL && table->lru_end == NULL);
@@ -225,10 +208,10 @@ static void test_lru(struct lruhash* table)
static void
test_short_table(struct lruhash* table)
{
struct testkey* k = newkey(12);
struct testkey* k2 = newkey(14);
struct testdata* d = newdata(128);
struct testdata* d2 = newdata(129);
testkey_t* k = newkey(12);
testkey_t* k2 = newkey(14);
testdata_t* d = newdata(128);
testdata_t* d2 = newdata(129);
k->entry.data = d;
k2->entry.data = d2;
@@ -249,11 +232,11 @@ test_short_table(struct lruhash* table)
/** test adding a random element */
static void
testadd(struct lruhash* table, struct testdata* ref[])
testadd(struct lruhash* table, testdata_t* ref[])
{
int numtoadd = random() % HASHTESTMAX;
struct testdata* data = newdata(numtoadd);
struct testkey* key = newkey(numtoadd);
testdata_t* data = newdata(numtoadd);
testkey_t* key = newkey(numtoadd);
key->entry.data = data;
lruhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
ref[numtoadd] = data;
@@ -261,10 +244,10 @@ testadd(struct lruhash* table, struct testdata* ref[])
/** test adding a random element */
static void
testremove(struct lruhash* table, struct testdata* ref[])
testremove(struct lruhash* table, testdata_t* ref[])
{
int num = random() % HASHTESTMAX;
struct testkey* key = newkey(num);
testkey_t* key = newkey(num);
lruhash_remove(table, myhash(num), key);
ref[num] = NULL;
delkey(key);
@@ -272,12 +255,12 @@ testremove(struct lruhash* table, struct testdata* ref[])
/** test adding a random element */
static void
testlookup(struct lruhash* table, struct testdata* ref[])
testlookup(struct lruhash* table, testdata_t* ref[])
{
int num = random() % HASHTESTMAX;
struct testkey* key = newkey(num);
testkey_t* key = newkey(num);
struct lruhash_entry* en = lruhash_lookup(table, myhash(num), key, 0);
struct testdata* data = en? (struct testdata*)en->data : NULL;
testdata_t* data = en? (testdata_t*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -321,17 +304,17 @@ check_table(struct lruhash* table)
/* this assertion is specific to the unit test */
unit_assert( table->space_used ==
table->num * test_sizefunc(NULL, NULL) );
table->num * test_slabhash_sizefunc(NULL, NULL) );
lock_quick_unlock(&table->lock);
}
/** test adding a random element (unlimited range) */
static void
testadd_unlim(struct lruhash* table, struct testdata** ref)
testadd_unlim(struct lruhash* table, testdata_t** ref)
{
int numtoadd = random() % (HASHTESTMAX * 10);
struct testdata* data = newdata(numtoadd);
struct testkey* key = newkey(numtoadd);
testdata_t* data = newdata(numtoadd);
testkey_t* key = newkey(numtoadd);
key->entry.data = data;
lruhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
if(ref)
@@ -340,10 +323,10 @@ testadd_unlim(struct lruhash* table, struct testdata** ref)
/** test adding a random element (unlimited range) */
static void
testremove_unlim(struct lruhash* table, struct testdata** ref)
testremove_unlim(struct lruhash* table, testdata_t** ref)
{
int num = random() % (HASHTESTMAX*10);
struct testkey* key = newkey(num);
testkey_t* key = newkey(num);
lruhash_remove(table, myhash(num), key);
if(ref)
ref[num] = NULL;
@@ -352,12 +335,12 @@ testremove_unlim(struct lruhash* table, struct testdata** ref)
/** test adding a random element (unlimited range) */
static void
testlookup_unlim(struct lruhash* table, struct testdata** ref)
testlookup_unlim(struct lruhash* table, testdata_t** ref)
{
int num = random() % (HASHTESTMAX*10);
struct testkey* key = newkey(num);
testkey_t* key = newkey(num);
struct lruhash_entry* en = lruhash_lookup(table, myhash(num), key, 0);
struct testdata* data = en? (struct testdata*)en->data : NULL;
testdata_t* data = en? (testdata_t*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -377,17 +360,22 @@ static void
test_long_table(struct lruhash* table)
{
/* assuming it all fits in the hastable, this check will work */
struct testdata* ref[HASHTESTMAX * 100];
testdata_t* ref[HASHTESTMAX * 100];
size_t i;
memset(ref, 0, sizeof(ref));
/* test assumption */
if(0) log_info(" size %d x %d < %d", (int)test_sizefunc(NULL, NULL),
if(0) log_info(" size %d x %d < %d", (int)test_slabhash_sizefunc(NULL, NULL),
(int)HASHTESTMAX, (int)table->space_max);
unit_assert( test_sizefunc(NULL, NULL)*HASHTESTMAX < table->space_max);
unit_assert( test_slabhash_sizefunc(NULL, NULL)*HASHTESTMAX < table->space_max);
if(0) lruhash_status(table, "unit test", 1);
srandom(48);
for(i=0; i<1000; i++) {
/* what to do? */
if(i == 500) {
lruhash_clear(table);
memset(ref, 0, sizeof(ref));
continue;
}
switch(random() % 4) {
case 0:
case 3:
@@ -496,41 +484,16 @@ void lruhash_test()
struct lruhash* table ;
printf("lruhash test\n");
table = lruhash_create(2, 4096,
test_sizefunc, test_compfunc, test_delkey, test_deldata, NULL);
test_slabhash_sizefunc, test_slabhash_compfunc,
test_slabhash_delkey, test_slabhash_deldata, NULL);
test_bin_find_entry(table);
test_lru(table);
test_short_table(table);
test_long_table(table);
lruhash_delete(table);
table = lruhash_create(2, 4096,
test_sizefunc, test_compfunc, test_delkey, test_deldata, NULL);
test_slabhash_sizefunc, test_slabhash_compfunc,
test_slabhash_delkey, test_slabhash_deldata, NULL);
test_threaded_table(table);
lruhash_delete(table);
}
static size_t test_sizefunc(void* ATTR_UNUSED(key), void* ATTR_UNUSED(data))
{
return sizeof(struct testkey) + sizeof(struct testdata);
}
static int test_compfunc(void* key1, void* key2)
{
struct testkey* k1 = (struct testkey*)key1;
struct testkey* k2 = (struct testkey*)key2;
if(k1->id == k2->id)
return 0;
if(k1->id > k2->id)
return 1;
return -1;
}
static void test_delkey(void* key, void* ATTR_UNUSED(arg), int l)
{
if(l) { lock_rw_unlock(&((struct testkey*)key)->entry.lock); }
delkey((struct testkey*)key);
}
static void test_deldata(void* data, void* ATTR_UNUSED(arg))
{
deldata((struct testdata*)data);
}
+156 -11
View File
@@ -89,6 +89,42 @@ alloc_test() {
static void
net_test()
{
char* t4[] = {"\000\000\000\000",
"\200\000\000\000",
"\300\000\000\000",
"\340\000\000\000",
"\360\000\000\000",
"\370\000\000\000",
"\374\000\000\000",
"\376\000\000\000",
"\377\000\000\000",
"\377\200\000\000",
"\377\300\000\000",
"\377\340\000\000",
"\377\360\000\000",
"\377\370\000\000",
"\377\374\000\000",
"\377\376\000\000",
"\377\377\000\000",
"\377\377\200\000",
"\377\377\300\000",
"\377\377\340\000",
"\377\377\360\000",
"\377\377\370\000",
"\377\377\374\000",
"\377\377\376\000",
"\377\377\377\000",
"\377\377\377\200",
"\377\377\377\300",
"\377\377\377\340",
"\377\377\377\360",
"\377\377\377\370",
"\377\377\377\374",
"\377\377\377\376",
"\377\377\377\377",
"\377\377\377\377",
"\377\377\377\377",
};
unit_assert( str_is_ip6("::") );
unit_assert( str_is_ip6("::1") );
unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") );
@@ -117,6 +153,91 @@ net_test()
unit_assert( !is_pow2(23) );
unit_assert( !is_pow2(257) );
unit_assert( !is_pow2(259) );
/* test addr_mask */
if(1) {
struct sockaddr_in a4;
struct sockaddr_in6 a6;
socklen_t l4 = (socklen_t)sizeof(a4);
socklen_t l6 = (socklen_t)sizeof(a6);
int i;
a4.sin_family = AF_INET;
a6.sin6_family = AF_INET6;
for(i=0; i<35; i++) {
/* address 255.255.255.255 */
memcpy(&a4.sin_addr, "\377\377\377\377", 4);
addr_mask((struct sockaddr_storage*)&a4, l4, i);
unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0);
}
memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16);
addr_mask((struct sockaddr_storage*)&a6, l6, 128);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 122);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 120);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 64);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 0);
unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0);
}
/* test addr_in_common */
if(1) {
struct sockaddr_in a4, b4;
struct sockaddr_in6 a6, b6;
socklen_t l4 = (socklen_t)sizeof(a4);
socklen_t l6 = (socklen_t)sizeof(a6);
int i;
a4.sin_family = AF_INET;
b4.sin_family = AF_INET;
a6.sin6_family = AF_INET6;
b6.sin6_family = AF_INET6;
memcpy(&a4.sin_addr, "abcd", 4);
memcpy(&b4.sin_addr, "abcd", 4);
unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, 32, l4) == 32);
unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34,
(struct sockaddr_storage*)&b4, 32, l4) == 32);
for(i=0; i<=32; i++) {
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, i, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, i,
(struct sockaddr_storage*)&b4, 32, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, i,
(struct sockaddr_storage*)&b4, i, l4) == i);
}
for(i=0; i<=32; i++) {
memcpy(&a4.sin_addr, "\377\377\377\377", 4);
memcpy(&b4.sin_addr, t4[i], 4);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, 32, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&b4, 32,
(struct sockaddr_storage*)&a4, 32, l4) == i);
}
memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16);
memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16);
unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128,
(struct sockaddr_storage*)&b6, 128, l6) == 128);
unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129,
(struct sockaddr_storage*)&b6, 128, l6) == 128);
for(i=0; i<=128; i++) {
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, 128,
(struct sockaddr_storage*)&b6, i, l6) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, i,
(struct sockaddr_storage*)&b6, 128, l6) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, i,
(struct sockaddr_storage*)&b6, i, l6) == i);
}
}
}
#include "util/rtt.h"
@@ -124,17 +245,18 @@ net_test()
static void
rtt_test()
{
int init = 376;
int i;
struct rtt_info r;
rtt_init(&r);
/* initial value sensible */
unit_assert( rtt_timeout(&r) == 3000 );
unit_assert( rtt_timeout(&r) == init );
rtt_lost(&r);
unit_assert( rtt_timeout(&r) == 6000 );
unit_assert( rtt_timeout(&r) == init*2 );
rtt_lost(&r);
unit_assert( rtt_timeout(&r) == 12000 );
unit_assert( rtt_timeout(&r) == init*4 );
rtt_update(&r, 4000);
unit_assert( rtt_timeout(&r) >= 5000 );
unit_assert( rtt_timeout(&r) >= 2000 );
rtt_lost(&r);
for(i=0; i<100; i++) {
rtt_lost(&r);
@@ -158,36 +280,37 @@ infra_test()
int vs, to;
struct infra_host_key* k;
struct infra_host_data* d;
int init = 376;
slab = infra_create(cfg);
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), now, &vs, &to) );
unit_assert( vs == 0 && to == 3000 );
unit_assert( vs == 0 && to == init );
unit_assert( infra_rtt_update(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), -1, now) );
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), now, &vs, &to) );
unit_assert( vs == 0 && to == 6000 );
unit_assert( vs == 0 && to == init*2 );
unit_assert( infra_edns_update(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), -1, now) );
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), now, &vs, &to) );
unit_assert( vs == -1 && to == 6000 );
unit_assert( vs == -1 && to == init*2 );
now += cfg->host_ttl + 10;
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), now, &vs, &to) );
unit_assert( vs == 0 && to == 3000 );
unit_assert( vs == 0 && to == init );
unit_assert( infra_set_lame(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), zone, zonelen, now) );
(socklen_t)sizeof(int), zone, zonelen, now, 0) );
unit_assert( (d=infra_lookup_host(slab, (struct sockaddr_storage*)&one,
(socklen_t)sizeof(int), 0, now, &k)) );
unit_assert( d->ttl == now+cfg->host_ttl );
unit_assert( d->edns_version == 0 );
unit_assert( infra_lookup_lame(d, zone, zonelen, now) );
unit_assert( infra_lookup_lame(d, zone, zonelen, now)==1 );
unit_assert( !infra_lookup_lame(d, zone, zonelen,
now+cfg->lame_ttl+10) );
unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now) );
@@ -197,6 +320,27 @@ infra_test()
config_delete(cfg);
}
#include "util/random.h"
/** test randomness */
static void
rnd_test()
{
struct ub_randstate r;
int num = 100, i;
long int a[100];
unit_assert( ub_initstate((unsigned)time(NULL), &r, 256) );
for(i=0; i<num; i++) {
a[i] = ub_random(&r);
unit_assert(a[i] >= 0);
unit_assert((size_t)a[i] <= (size_t)RAND_MAX);
if(i > 5)
unit_assert(a[i] != a[i-1] || a[i] != a[i-2] ||
a[i] != a[i-3] || a[i] != a[i-4] ||
a[i] != a[i-5] || a[i] != a[i-6]);
}
ub_randfree(&r);
}
/**
* Main unit test program. Setup, teardown and report errors.
* @param argc: arg count.
@@ -205,7 +349,7 @@ infra_test()
int
main(int argc, char* argv[])
{
log_init(NULL);
log_init(NULL, 0, NULL);
if(argc != 1) {
printf("usage: %s\n", argv[0]);
printf("\tperforms unit tests.\n");
@@ -213,6 +357,7 @@ main(int argc, char* argv[])
}
printf("Start of %s unit test.\n", PACKAGE_STRING);
checklock_start();
rnd_test();
verify_test();
net_test();
dname_test();
+5 -7
View File
@@ -45,7 +45,7 @@
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "util/alloc.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "testcode/readhex.h"
@@ -206,10 +206,8 @@ test_buffers(ldns_buffer* pkt, ldns_buffer* out)
s1 = ldns_buffer2pkt_wire(&p1, pkt);
s2 = ldns_buffer2pkt_wire(&p2, out);
if(vbmp) {
log_hex("orig in hex", ldns_buffer_begin(pkt),
ldns_buffer_limit(pkt));
log_hex("unbound out in hex", ldns_buffer_begin(out),
ldns_buffer_limit(out));
log_buf(0, "orig in hex", pkt);
log_buf(0, "unbound out in hex", out);
printf("\npacket from unbound (%d):\n",
(int)ldns_buffer_limit(out));
ldns_pkt_print(stdout, p2);
@@ -260,7 +258,7 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
uint16_t id;
uint16_t flags;
uint32_t timenow = 0;
region_type *region = region_create(malloc, free);
struct regional* region = regional_create();
struct edns_data edns;
hex_to_buf(pkt, hex);
@@ -309,7 +307,7 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
query_info_clear(&qi);
reply_info_parsedelete(rep, alloc);
region_destroy(region);
regional_destroy(region);
}
/** simple test of parsing */
+43 -83
View File
@@ -43,29 +43,14 @@
#include "util/log.h"
#include "util/storage/slabhash.h"
/* --- test representation --- */
/** structure contains test key */
struct slabtestkey {
/** the key id */
int id;
/** the entry */
struct lruhash_entry entry;
};
/** structure contains test data */
struct slabtestdata {
/** data value */
int data;
};
/** use this type for the slabhash test key */
typedef struct slabhash_testkey testkey_t;
/** use this type for the slabhash test data */
typedef struct slabhash_testdata testdata_t;
/** sizefunc for lruhash */
static size_t test_sizefunc(void*, void*);
/** comparefunc for lruhash */
static int test_compfunc(void*, void*);
/** delkey for lruhash */
static void test_delkey(void*, void*, int);
/** deldata for lruhash */
static void test_deldata(void*, void*);
/* --- end test representation --- */
/** delete key */
static void delkey(struct slabhash_testkey* k) {
lock_rw_destroy(&k->entry.lock); free(k);}
/** hash func, very bad to improve collisions, both high and low bits */
static hashvalue_t myhash(int id) {
@@ -75,8 +60,8 @@ static hashvalue_t myhash(int id) {
}
/** allocate new key, fill in hash */
static struct slabtestkey* newkey(int id) {
struct slabtestkey* k = (struct slabtestkey*)calloc(1, sizeof(struct slabtestkey));
static testkey_t* newkey(int id) {
testkey_t* k = (testkey_t*)calloc(1, sizeof(testkey_t));
if(!k) fatal_exit("out of memory");
k->id = id;
k->entry.hash = myhash(id);
@@ -85,27 +70,22 @@ static struct slabtestkey* newkey(int id) {
return k;
}
/** new data el */
static struct slabtestdata* newdata(int val) {
struct slabtestdata* d = (struct slabtestdata*)calloc(1,
sizeof(struct slabtestdata));
static testdata_t* newdata(int val) {
testdata_t* d = (testdata_t*)calloc(1,
sizeof(testdata_t));
if(!d) fatal_exit("out of memory");
d->data = val;
return d;
}
/** delete key */
static void delkey(struct slabtestkey* k) {
lock_rw_destroy(&k->entry.lock); free(k);}
/** delete data */
static void deldata(struct slabtestdata* d) {free(d);}
/** test hashtable using short sequence */
static void
test_short_table(struct slabhash* table)
{
struct slabtestkey* k = newkey(12);
struct slabtestkey* k2 = newkey(14);
struct slabtestdata* d = newdata(128);
struct slabtestdata* d2 = newdata(129);
testkey_t* k = newkey(12);
testkey_t* k2 = newkey(14);
testdata_t* d = newdata(128);
testdata_t* d2 = newdata(129);
k->entry.data = d;
k2->entry.data = d2;
@@ -126,11 +106,11 @@ test_short_table(struct slabhash* table)
/** test adding a random element */
static void
testadd(struct slabhash* table, struct slabtestdata* ref[])
testadd(struct slabhash* table, testdata_t* ref[])
{
int numtoadd = random() % HASHTESTMAX;
struct slabtestdata* data = newdata(numtoadd);
struct slabtestkey* key = newkey(numtoadd);
testdata_t* data = newdata(numtoadd);
testkey_t* key = newkey(numtoadd);
key->entry.data = data;
slabhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
ref[numtoadd] = data;
@@ -138,10 +118,10 @@ testadd(struct slabhash* table, struct slabtestdata* ref[])
/** test adding a random element */
static void
testremove(struct slabhash* table, struct slabtestdata* ref[])
testremove(struct slabhash* table, testdata_t* ref[])
{
int num = random() % HASHTESTMAX;
struct slabtestkey* key = newkey(num);
testkey_t* key = newkey(num);
slabhash_remove(table, myhash(num), key);
ref[num] = NULL;
delkey(key);
@@ -149,12 +129,12 @@ testremove(struct slabhash* table, struct slabtestdata* ref[])
/** test adding a random element */
static void
testlookup(struct slabhash* table, struct slabtestdata* ref[])
testlookup(struct slabhash* table, testdata_t* ref[])
{
int num = random() % HASHTESTMAX;
struct slabtestkey* key = newkey(num);
testkey_t* key = newkey(num);
struct lruhash_entry* en = slabhash_lookup(table, myhash(num), key, 0);
struct slabtestdata* data = en? (struct slabtestdata*)en->data : NULL;
testdata_t* data = en? (testdata_t*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -198,7 +178,7 @@ check_lru_table(struct lruhash* table)
/* this assertion is specific to the unit test */
unit_assert( table->space_used ==
table->num * test_sizefunc(NULL, NULL) );
table->num * test_slabhash_sizefunc(NULL, NULL) );
lock_quick_unlock(&table->lock);
}
@@ -213,11 +193,11 @@ check_table(struct slabhash* table)
/** test adding a random element (unlimited range) */
static void
testadd_unlim(struct slabhash* table, struct slabtestdata** ref)
testadd_unlim(struct slabhash* table, testdata_t** ref)
{
int numtoadd = random() % (HASHTESTMAX * 10);
struct slabtestdata* data = newdata(numtoadd);
struct slabtestkey* key = newkey(numtoadd);
testdata_t* data = newdata(numtoadd);
testkey_t* key = newkey(numtoadd);
key->entry.data = data;
slabhash_insert(table, myhash(numtoadd), &key->entry, data, NULL);
if(ref)
@@ -226,10 +206,10 @@ testadd_unlim(struct slabhash* table, struct slabtestdata** ref)
/** test adding a random element (unlimited range) */
static void
testremove_unlim(struct slabhash* table, struct slabtestdata** ref)
testremove_unlim(struct slabhash* table, testdata_t** ref)
{
int num = random() % (HASHTESTMAX*10);
struct slabtestkey* key = newkey(num);
testkey_t* key = newkey(num);
slabhash_remove(table, myhash(num), key);
if(ref)
ref[num] = NULL;
@@ -238,12 +218,12 @@ testremove_unlim(struct slabhash* table, struct slabtestdata** ref)
/** test adding a random element (unlimited range) */
static void
testlookup_unlim(struct slabhash* table, struct slabtestdata** ref)
testlookup_unlim(struct slabhash* table, testdata_t** ref)
{
int num = random() % (HASHTESTMAX*10);
struct slabtestkey* key = newkey(num);
testkey_t* key = newkey(num);
struct lruhash_entry* en = slabhash_lookup(table, myhash(num), key, 0);
struct slabtestdata* data = en? (struct slabtestdata*)en->data : NULL;
testdata_t* data = en? (testdata_t*)en->data : NULL;
if(en) {
unit_assert(en->key);
unit_assert(en->data);
@@ -263,7 +243,7 @@ static void
test_long_table(struct slabhash* table)
{
/* assuming it all fits in the hastable, this check will work */
struct slabtestdata* ref[HASHTESTMAX * 100];
testdata_t* ref[HASHTESTMAX * 100];
size_t i;
memset(ref, 0, sizeof(ref));
/* test assumption */
@@ -271,6 +251,11 @@ test_long_table(struct slabhash* table)
srandom(48);
for(i=0; i<1000; i++) {
/* what to do? */
if(i == 500) {
slabhash_clear(table);
memset(ref, 0, sizeof(ref));
continue;
}
switch(random() % 4) {
case 0:
case 3:
@@ -378,39 +363,14 @@ void slabhash_test()
struct slabhash* table;
printf("slabhash test\n");
table = slabhash_create(4, 2, 5200,
test_sizefunc, test_compfunc, test_delkey, test_deldata, NULL);
test_slabhash_sizefunc, test_slabhash_compfunc,
test_slabhash_delkey, test_slabhash_deldata, NULL);
test_short_table(table);
test_long_table(table);
slabhash_delete(table);
table = slabhash_create(4, 2, 5200,
test_sizefunc, test_compfunc, test_delkey, test_deldata, NULL);
test_slabhash_sizefunc, test_slabhash_compfunc,
test_slabhash_delkey, test_slabhash_deldata, NULL);
test_threaded_table(table);
slabhash_delete(table);
}
static size_t test_sizefunc(void* ATTR_UNUSED(key), void* ATTR_UNUSED(data))
{
return sizeof(struct slabtestkey) + sizeof(struct slabtestdata);
}
static int test_compfunc(void* key1, void* key2)
{
struct slabtestkey* k1 = (struct slabtestkey*)key1;
struct slabtestkey* k2 = (struct slabtestkey*)key2;
if(k1->id == k2->id)
return 0;
if(k1->id > k2->id)
return 1;
return -1;
}
static void test_delkey(void* key, void* ATTR_UNUSED(arg), int l)
{
if(l) { lock_rw_unlock(&((struct slabtestkey*)key)->entry.lock); }
delkey((struct slabtestkey*)key);
}
static void test_deldata(void* data, void* ATTR_UNUSED(arg))
{
deldata((struct slabtestdata*)data);
}
+22 -20
View File
@@ -49,7 +49,7 @@
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/region-allocator.h"
#include "util/regional.h"
#include "util/alloc.h"
#include "util/rbtree.h"
#include "util/net_help.h"
@@ -86,8 +86,8 @@ entry_to_buf(struct entry* e, ldns_buffer* pkt)
/** entry to reply info conversion */
static void
entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, struct region*
region, ldns_buffer* pkt, struct query_info* qi,
entry_to_repinfo(struct entry* e, struct alloc_cache* alloc,
struct regional* region, ldns_buffer* pkt, struct query_info* qi,
struct reply_info** rep)
{
int ret;
@@ -109,8 +109,8 @@ entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, struct region*
/** extract DNSKEY rrset from answer and convert it */
static struct ub_packed_rrset_key*
extract_keys(struct entry* e, struct alloc_cache* alloc, struct region*
region, ldns_buffer* pkt)
extract_keys(struct entry* e, struct alloc_cache* alloc,
struct regional* region, ldns_buffer* pkt)
{
struct ub_packed_rrset_key* dnskey = NULL;
struct query_info qinfo;
@@ -167,15 +167,16 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
/** verify and test an entry - every rr in the message */
static void
verifytest_entry(struct entry* e, struct alloc_cache* alloc, struct region*
region, ldns_buffer* pkt, struct ub_packed_rrset_key* dnskey,
struct module_env* env, struct val_env* ve)
verifytest_entry(struct entry* e, struct alloc_cache* alloc,
struct regional* region, ldns_buffer* pkt,
struct ub_packed_rrset_key* dnskey, struct module_env* env,
struct val_env* ve)
{
struct query_info qinfo;
struct reply_info* rep = NULL;
size_t i;
region_free_all(region);
regional_free_all(region);
if(vsig) {
printf("verifying pkt:\n");
ldns_pkt_print(stdout, e->reply_list->reply);
@@ -205,15 +206,15 @@ find_rrset_type(struct reply_info* rep, uint16_t type)
/** DS sig test an entry - get DNSKEY and DS in entry and verify */
static void
dstest_entry(struct entry* e, struct alloc_cache* alloc, struct region*
region, ldns_buffer* pkt, struct module_env* env)
dstest_entry(struct entry* e, struct alloc_cache* alloc,
struct regional* region, ldns_buffer* pkt, struct module_env* env)
{
struct query_info qinfo;
struct reply_info* rep = NULL;
struct ub_packed_rrset_key* ds, *dnskey;
int ret;
region_free_all(region);
regional_free_all(region);
if(vsig) {
printf("verifying DS-DNSKEY match:\n");
ldns_pkt_print(stdout, e->reply_list->reply);
@@ -255,7 +256,7 @@ verifytest_file(const char* fname, const char* at_date)
* The answer rrset is the keyset that will be used for verification
*/
struct ub_packed_rrset_key* dnskey;
struct region* region = region_create(malloc, free);
struct regional* region = regional_create();
struct alloc_cache alloc;
ldns_buffer* buf = ldns_buffer_new(65535);
struct entry* e;
@@ -281,8 +282,9 @@ verifytest_file(const char* fname, const char* at_date)
verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
}
ub_packed_rrset_parsedelete(dnskey, &alloc);
delete_entry(list);
region_destroy(region);
regional_destroy(region);
alloc_clear(&alloc);
ldns_buffer_free(buf);
}
@@ -296,7 +298,7 @@ dstest_file(const char* fname)
* The first entry must be a query for DNSKEY.
* The answer rrset is the keyset that will be used for verification
*/
struct region* region = region_create(malloc, free);
struct regional* region = regional_create();
struct alloc_cache alloc;
ldns_buffer* buf = ldns_buffer_new(65535);
struct entry* e;
@@ -317,7 +319,7 @@ dstest_file(const char* fname)
}
delete_entry(list);
region_destroy(region);
regional_destroy(region);
alloc_clear(&alloc);
ldns_buffer_free(buf);
}
@@ -374,7 +376,7 @@ nsectest()
/** Test hash algo - NSEC3 hash it and compare result */
static void
nsec3_hash_test_entry(struct entry* e, rbtree_t* ct,
struct alloc_cache* alloc, struct region* region,
struct alloc_cache* alloc, struct regional* region,
ldns_buffer* buf)
{
struct query_info qinfo;
@@ -392,7 +394,7 @@ nsec3_hash_test_entry(struct entry* e, rbtree_t* ct,
entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep);
nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3);
answer = find_rrset_type(rep, LDNS_RR_TYPE_AAAA);
qname = region_alloc_init(region, qinfo.qname, qinfo.qname_len);
qname = regional_alloc_init(region, qinfo.qname, qinfo.qname_len);
/* check test is OK */
unit_assert(nsec3 && answer && qname);
@@ -429,7 +431,7 @@ nsec3_hash_test(const char* fname)
* The test does not perform canonicalization during the compare.
*/
rbtree_t ct;
struct region* region = region_create(malloc, free);
struct regional* region = regional_create();
struct alloc_cache alloc;
ldns_buffer* buf = ldns_buffer_new(65535);
struct entry* e;
@@ -447,7 +449,7 @@ nsec3_hash_test(const char* fname)
}
delete_entry(list);
region_destroy(region);
regional_destroy(region);
alloc_clear(&alloc);
ldns_buffer_free(buf);
}
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+52
View File
@@ -0,0 +1,52 @@
; config options
server:
hide-identity: no
hide-version: no
identity: "test-identity"
version: "test-version"
access-control: 20.0.0.0/8 allow
access-control: 20.40.0.0/16 refuse
access-control: 20.40.80.0/24 deny
CONFIG_END
SCENARIO_BEGIN Test access control list
; version.bind.
; allow
STEP 1 QUERY ADDRESS 20.1.2.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA
SECTION QUESTION
version.bind. CH TXT
SECTION ANSWER
version.bind. 0 CH TXT "test-version"
ENTRY_END
; refuse
STEP 3 QUERY ADDRESS 20.40.2.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR REFUSED
ENTRY_END
; deny (drop)
STEP 5 QUERY ADDRESS 20.40.80.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
; no answer must be pending
SCENARIO_END
+161
View File
@@ -0,0 +1,161 @@
; config options
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Fetch cnamed glue when missing or timed out.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
; is missing the glue!
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN CNAME ns2.example.com.
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY AA QR NOERROR
SECTION QUESTION
ns2.example.com. IN A
SECTION ANSWER
ns2.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; due to ordering of answer packets, this is still outstanding, remove it
STEP 21 CHECK_OUT_QUERY
ENTRY_BEGIN
ADJUST copy_id
MATCH qname qtype
REPLY QR
SECTION QUESTION
ns.example.com IN AAAA
ENTRY_END
SCENARIO_END
BIN
View File
Binary file not shown.
+5 -1
View File
@@ -8,9 +8,13 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
; But the pending query fails due to error (say TCP failure or malloc or ...)
; This is iterator/iterator.h OUTBOUND_MSG_RETRY number of errors.
STEP 2 ERROR
STEP 3 ERROR
STEP 4 ERROR
STEP 5 ERROR
; returns servfail
STEP 4 CHECK_ANSWER
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qname qtype
SECTION QUESTION
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+5 -1
View File
@@ -8,9 +8,13 @@ SECTION QUESTION
www.example.com. IN A
ENTRY_END
; But the pending query times out!
; OUTBOUND_MSG_RETRY times timeout.
STEP 2 TIMEOUT
STEP 3 TIMEOUT
STEP 4 TIMEOUT
STEP 5 TIMEOUT
; returns servfail
STEP 4 CHECK_ANSWER
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qname qtype
SECTION QUESTION
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+301
View File
@@ -0,0 +1,301 @@
; config options
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test dnssec-lame detection at ds point.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
; e.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.12.94.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
; response to DNSKEY priming query
; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
SECTION AUTHORITY
; no NS set. not needed for this test.
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.55
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
ENTRY_END
; fine DNSKEY response.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
ENTRY_END
; correct delegation with DS
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
; response for delegation to sub.example.com.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
RANGE_END
; This server is DNSSEC LAME!
; ns.sub.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.6
; response to DNSKEY priming query
; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
SECTION AUTHORITY
; dnssec-lameness detection depends on this information
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.sub.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
ENTRY_END
SCENARIO_END
+293
View File
@@ -0,0 +1,293 @@
; config options
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test dnssec-lame detection at ds point, which is ok.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
; e.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.12.94.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
; response to DNSKEY priming query
; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
SECTION AUTHORITY
; no NS set. not needed for this test.
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ns.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. UF7shD/gt1FOp2UHgLTNbPzVykklSXFMEtJ1xD+Hholwf/PIzd7zoaIttIYibNa4fUXCqMg22H9P7MRhfmFe6g== ;{id = 30899}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.55
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
ENTRY_END
; fine DNSKEY response.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
ENTRY_END
; correct delegation with DS
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
; response for delegation to sub.example.com.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
SECTION AUTHORITY
sub.example.com. IN NS ns.sub.example.com.
sub.example.com. IN NS ns.example.net.
sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFCW3ix0GD4BSvNLWIbROCJt5DAW9AhRt/kg9kBKJ20UBUdumrBUHqnskdA== ;{id = 2854}
SECTION ADDITIONAL
ns.sub.example.com. IN A 1.2.3.6
ENTRY_END
RANGE_END
; server is not DNSSEC lame.
; ns.sub.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.6
; response to DNSKEY priming query
; sub.example.com. 3600 IN DS 30899 RSASHA1 1 f7ed618f24d5e5202927e1d27bc2e84a141cb4b3
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
sub.example.com. IN DNSKEY
SECTION ANSWER
sub.example.com. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
sub.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20070926134150 20070829134150 30899 sub.example.com. uNGp99iznjD7oOX02XnQbDnbg75UwBHRvZSKYUorTKvPUnCWMHKdRsQ+mf+Fx3GZ+Fz9BVjoCmQqpnfgXLEYqw== ;{id = 30899}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.sub.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.sub.example.com. IN A
SECTION ANSWER
www.sub.example.com. IN A 11.11.11.11
www.sub.example.com. 3600 IN RRSIG A 5 4 3600 20070926134150 20070829134150 30899 sub.example.com. 0DqqRfRtm7VSEQ4mmBbzrKRqQAay3JAE8DPDGmjtokrrjN9F1G/HxozDV7bjdIh2EChlQea8FPwf/GepJMUVxg== ;{id = 30899}
ENTRY_END
SCENARIO_END
+235
View File
@@ -0,0 +1,235 @@
; config options
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test dnssec-lame detection at anchor point.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. IN NS ns.example.net.
SECTION ADDITIONAL
; this entry; glue will make unbound take this reference first.
; it is however, the lame server.
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
; e.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.12.94.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.55
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
ENTRY_END
; lame DNSKEY response.
; here without sigs (assuming server does unknown-RR type handling)
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
ENTRY_END
; the lame response. No RRSIGS.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
; the wrong answer.
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
; dnssec-lameness detection depends on this information
example.com. IN NS ns.example.com.
example.com. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
SCENARIO_END
+227
View File
@@ -0,0 +1,227 @@
; config options
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test dnssec-lame detection with anchor point that is ok.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
net. IN NS e.gtld-servers.net.
SECTION ADDITIONAL
e.gtld-servers.net. IN A 192.12.94.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.55
ENTRY_END
RANGE_END
; e.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.12.94.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.55
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.55
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
ENTRY_END
; the response is not lame at all.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
ENTRY_END
; response is not lame.
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
ENTRY_END
SCENARIO_END
+4 -1
View File
@@ -148,7 +148,7 @@ RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
@@ -162,10 +162,13 @@ SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
; make sure glue fetch is done.

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