mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
538
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e828d678ba | ||
|
|
f3c2d05728 | ||
|
|
4b73b5f299 | ||
|
|
ff7d68ca53 | ||
|
|
3fb98a72d2 | ||
|
|
6e8b4a7796 | ||
|
|
6f7eb3ea9f | ||
|
|
216747bb17 | ||
|
|
8f79119826 | ||
|
|
4106308bd5 | ||
|
|
c4c1f9e5ef | ||
|
|
b6f0b1af86 | ||
|
|
68027ab145 | ||
|
|
4a7ebfabcf | ||
|
|
9ce6119513 | ||
|
|
534eac6ae5 | ||
|
|
d3ff930b06 | ||
|
|
6c3a0b54ed | ||
|
|
2d444a5037 | ||
|
|
c99438c6a1 | ||
|
|
3f3cadd416 | ||
|
|
e183a66d60 | ||
|
|
d2eb78e871 | ||
|
|
5a66aecef9 | ||
|
|
f5e06689d1 | ||
|
|
5a00b31f86 | ||
|
|
cdbf091c0d | ||
|
|
4edb16296b | ||
|
|
aa64c58368 | ||
|
|
b4a01d6096 | ||
|
|
d63cb99649 | ||
|
|
dc0b1699e5 | ||
|
|
f82f971997 | ||
|
|
30b0fa1e8e | ||
|
|
1718a8e6b5 | ||
|
|
ebad5416d7 | ||
|
|
8833d44d01 | ||
|
|
da4d6ffee3 | ||
|
|
981fedea0e | ||
|
|
493921ef1f | ||
|
|
3a49e683ed | ||
|
|
3907876eac | ||
|
|
fcd9b34bb5 | ||
|
|
d63ec2dfcb | ||
|
|
6139943428 | ||
|
|
a76e43341f | ||
|
|
d63536289c | ||
|
|
d085a0039b | ||
|
|
3ebc480690 | ||
|
|
20dd979d00 | ||
|
|
623dba975a | ||
|
|
09707fc403 | ||
|
|
2dcc7016ac | ||
|
|
f887552763 | ||
|
|
72d348de6a | ||
|
|
7646c96259 | ||
|
|
d8809c672a | ||
|
|
7e3da817c3 | ||
|
|
c54fe82886 | ||
|
|
1fa40654d2 | ||
|
|
d79d75538b | ||
|
|
fa23ee8f31 | ||
|
|
51c23b0209 | ||
|
|
a3545867fc | ||
|
|
02080f6b18 | ||
|
|
07156bd5ea | ||
|
|
2a4e840be4 | ||
|
|
226298bbd3 | ||
|
|
5d46bb3879 | ||
|
|
a839a8ae01 | ||
|
|
79a6e9fbe2 | ||
|
|
16bbfc3461 | ||
|
|
d8090b8cae | ||
|
|
09845779d5 | ||
|
|
cb8374cce5 | ||
|
|
442e95620e | ||
|
|
af6f5a3f54 | ||
|
|
253d95a8ef | ||
|
|
57f2582790 | ||
|
|
d05d6b959a | ||
|
|
d4c904d091 | ||
|
|
5ac9bf3f9b | ||
|
|
f759fc5839 | ||
|
|
8903dc779f | ||
|
|
29b90c6e58 | ||
|
|
9b310f4084 | ||
|
|
7dfbcdf276 | ||
|
|
941b324187 | ||
|
|
21472c2393 | ||
|
|
488e4c66cd | ||
|
|
e8b8d42f8b | ||
|
|
e6a179e27a | ||
|
|
eb2283332b | ||
|
|
b2c3b4758b | ||
|
|
8bfbd81fec | ||
|
|
3d91a9fd56 | ||
|
|
facc6c6541 | ||
|
|
380b87e21a | ||
|
|
b60c4a472c | ||
|
|
82dffb1023 | ||
|
|
dc30e66ddc | ||
|
|
ec021e0d4b | ||
|
|
7963c9f463 | ||
|
|
710851e69a | ||
|
|
11f22074a9 | ||
|
|
55bb4c1275 | ||
|
|
b966dd8e06 | ||
|
|
06a91b0eaa | ||
|
|
3df64cc677 | ||
|
|
6943cab670 | ||
|
|
f635b47ade | ||
|
|
eb7f9a50f2 | ||
|
|
acdd4058d2 | ||
|
|
1b62399a6e | ||
|
|
e1e71eac3e | ||
|
|
aefd2df51f | ||
|
|
15020f7666 | ||
|
|
ae2d5276d2 | ||
|
|
ce0e9bef45 | ||
|
|
1dcc88b6e8 | ||
|
|
faa9dd7bf6 | ||
|
|
9303292b7f | ||
|
|
9f0b260c49 | ||
|
|
ab53baa6f5 | ||
|
|
554e4a939c | ||
|
|
45b3215594 | ||
|
|
3cb1cdeebd | ||
|
|
9a9d59ecaf | ||
|
|
1a4eaaabc5 | ||
|
|
ff8fd0be5c | ||
|
|
13d96540de | ||
|
|
e45e9f1ce0 | ||
|
|
05b9f4fd28 | ||
|
|
1089fd6dc1 | ||
|
|
366296ec14 | ||
|
|
7f9aa6734a | ||
|
|
9902a5f81d | ||
|
|
cd0a2b1af1 | ||
|
|
a374dfb669 | ||
|
|
79fa94834e | ||
|
|
e35d5f5a2d | ||
|
|
334e2b1e35 | ||
|
|
06847ff3be | ||
|
|
80c2c69fa7 | ||
|
|
8b752e359e | ||
|
|
d3b3d64ef3 | ||
|
|
c602ba7319 | ||
|
|
bdb6c153e4 | ||
|
|
d8a8730cac | ||
|
|
0532cdd357 | ||
|
|
e84b913585 | ||
|
|
a5027f5f56 | ||
|
|
06a58ca248 | ||
|
|
4700d79024 | ||
|
|
9d9884c442 | ||
|
|
c1c75929fa | ||
|
|
8cb3656b3e | ||
|
|
a90f173875 | ||
|
|
b266db3920 | ||
|
|
fd415d8833 | ||
|
|
b5a52f8c86 | ||
|
|
67271242bf | ||
|
|
008813f0a2 | ||
|
|
fa506e3cda | ||
|
|
df0c844eed | ||
|
|
199e6c586b | ||
|
|
21f740d313 | ||
|
|
e860d39f54 | ||
|
|
fe0b1da859 | ||
|
|
27811ffaa9 | ||
|
|
7d5ab2f4de | ||
|
|
5f5c00203e | ||
|
|
b4b0065554 | ||
|
|
c94e13220b | ||
|
|
368386c011 | ||
|
|
d5ebc63add | ||
|
|
d323e1bda8 | ||
|
|
36819adcc2 | ||
|
|
da46ea24d5 | ||
|
|
1aa1facabc | ||
|
|
78b2f1cc20 | ||
|
|
164f302011 | ||
|
|
cc39725cf3 | ||
|
|
63b2628a18 | ||
|
|
0f3eac4a0e | ||
|
|
72738471f1 | ||
|
|
c1e75c0369 | ||
|
|
b16c872a60 | ||
|
|
364441e0f5 | ||
|
|
ed95b07764 | ||
|
|
bf2307ca97 | ||
|
|
1ec96d8f07 | ||
|
|
3499d3c647 | ||
|
|
ee06aaaad9 | ||
|
|
af6c5dea43 | ||
|
|
b57771d42b | ||
|
|
6067ce6d2b | ||
|
|
081fd4fdae | ||
|
|
09a0e6ee30 | ||
|
|
a4f4d7b6ba | ||
|
|
e2a2dcdfd5 | ||
|
|
14b11384a4 | ||
|
|
a03f0a388e | ||
|
|
0b77c9d676 | ||
|
|
1c3ba0cef7 | ||
|
|
19c2ece763 | ||
|
|
310396190b | ||
|
|
a08fe8ca60 | ||
|
|
a95f5fd5cb | ||
|
|
a922a19d70 | ||
|
|
a8d0177b36 | ||
|
|
779b86fb22 | ||
|
|
e3453711e5 | ||
|
|
73484d3b36 | ||
|
|
f1c23891ab | ||
|
|
9b7843f879 | ||
|
|
5f4c9b0dfe | ||
|
|
3280e76527 | ||
|
|
46099259be | ||
|
|
56af87e2f3 | ||
|
|
bd5eeff364 | ||
|
|
2fea5663bd | ||
|
|
1a48bdebb5 | ||
|
|
f46c238552 | ||
|
|
7e300939c0 | ||
|
|
409bc229ef | ||
|
|
ee0087d5c7 | ||
|
|
d4f697f160 | ||
|
|
6e4bab2629 | ||
|
|
5c5ddbe859 | ||
|
|
ea506d0f68 | ||
|
|
27e334e813 | ||
|
|
8e48a5cf5f | ||
|
|
9bc81f31d8 | ||
|
|
c6db87d81d | ||
|
|
f90e80d3bc | ||
|
|
e60f92ea29 | ||
|
|
46b5e96c54 | ||
|
|
f5a197f96e | ||
|
|
196654efec | ||
|
|
a9c8d00d63 | ||
|
|
5e4cfcc665 | ||
|
|
193cb2fcc4 | ||
|
|
b57a2f15db | ||
|
|
8d2c08befd | ||
|
|
d9a9f73e82 | ||
|
|
e19da1b619 | ||
|
|
6ce60bcb61 | ||
|
|
ff026a1f3c | ||
|
|
a37730cee8 | ||
|
|
af11b54071 | ||
|
|
2a78803049 | ||
|
|
edf1ad369a | ||
|
|
52ea271a65 | ||
|
|
ae54e9013b | ||
|
|
8a3ae4d08a | ||
|
|
1cc54b080a | ||
|
|
63171a2522 | ||
|
|
2e023a5699 | ||
|
|
1c1fc36d76 | ||
|
|
42d7db578a | ||
|
|
d4a6380562 | ||
|
|
8133251662 | ||
|
|
5a8d314ce3 | ||
|
|
99f36a4e1e | ||
|
|
61a28c2ee5 | ||
|
|
2552a81b40 | ||
|
|
ab6f1d0fc7 | ||
|
|
c8a56bfa8f | ||
|
|
d1150541bb | ||
|
|
ead84a5a64 | ||
|
|
c6369e9ffa | ||
|
|
474afc9016 | ||
|
|
bd3c02bd59 | ||
|
|
32b1d900ff | ||
|
|
4eac399dfd | ||
|
|
c26fc84945 | ||
|
|
2b47ca080e | ||
|
|
348cbab016 | ||
|
|
a777329b7f | ||
|
|
92121f7878 | ||
|
|
ce8167a3bb | ||
|
|
937523285a | ||
|
|
8a0de6b519 | ||
|
|
e338143639 | ||
|
|
59570b0413 | ||
|
|
78adebf8ec | ||
|
|
b75c37252c | ||
|
|
48ad6477eb | ||
|
|
296f28e8d0 | ||
|
|
83e2cade5b | ||
|
|
ce0628ee55 | ||
|
|
bb5251da66 | ||
|
|
bfd0c5ec85 | ||
|
|
8092cd6331 | ||
|
|
7105ea9293 | ||
|
|
efb3697332 | ||
|
|
56a174bb0f | ||
|
|
9d2980de1a | ||
|
|
bfae29866b | ||
|
|
b248654aab | ||
|
|
7cc4ff05ad | ||
|
|
b4a9031cdb | ||
|
|
16cc196bf2 | ||
|
|
c79a99a577 | ||
|
|
a82c0eeece | ||
|
|
a62c1135fe | ||
|
|
ba0cad0bc3 | ||
|
|
7c1f9699d8 | ||
|
|
33a814683b | ||
|
|
beebe5ba0c | ||
|
|
225534e5ab | ||
|
|
3599fd9c60 | ||
|
|
5b162ead92 | ||
|
|
62428e17f6 | ||
|
|
079253670e | ||
|
|
91e863138b | ||
|
|
d1e92a0ebd | ||
|
|
3949bf2c82 | ||
|
|
a41375411e | ||
|
|
030832cf12 | ||
|
|
49a36d98bb | ||
|
|
ddae2885bd | ||
|
|
19193fd534 | ||
|
|
4e249c96e8 | ||
|
|
cae8361dcd | ||
|
|
429e130768 | ||
|
|
20d57ec58b | ||
|
|
e43c3daec2 | ||
|
|
64c4e69b07 | ||
|
|
a9e028564d | ||
|
|
99994a26b0 | ||
|
|
fe97f25b75 | ||
|
|
281030d576 | ||
|
|
8992e8c91f | ||
|
|
b34a6defc1 | ||
|
|
8cf5eae166 | ||
|
|
df8f236b62 | ||
|
|
273ff1201b | ||
|
|
91f585ed38 | ||
|
|
b9b226bdea | ||
|
|
8fffdca2a6 | ||
|
|
723845b350 | ||
|
|
31b677b35f | ||
|
|
c2e3baa81a | ||
|
|
7273b35243 | ||
|
|
dfe8e0dfa2 | ||
|
|
7ad8ffccf5 | ||
|
|
065c7c5dd8 | ||
|
|
71744b8bb2 | ||
|
|
3d2dfc4769 | ||
|
|
5e4f0d65ce | ||
|
|
aae44940c7 | ||
|
|
062c2cacfc | ||
|
|
ce65cdde71 | ||
|
|
b005fcd87b | ||
|
|
f11d6653d6 | ||
|
|
20d5e35576 | ||
|
|
3028fa50a8 | ||
|
|
e584933b2b | ||
|
|
d48abb9a84 | ||
|
|
37361a1d10 | ||
|
|
299cc0c689 | ||
|
|
707e5a915b | ||
|
|
649e265d6f | ||
|
|
9d4ca81959 | ||
|
|
68a57554a6 | ||
|
|
cc9fb69911 | ||
|
|
d3f397c686 | ||
|
|
ed8b859e31 | ||
|
|
011a7d8830 | ||
|
|
510606dd1c | ||
|
|
4e59c8344f | ||
|
|
4c8f334c15 | ||
|
|
2f52ecdd9c | ||
|
|
5d82b7c421 | ||
|
|
8ae9f26bce | ||
|
|
55f560a3ca | ||
|
|
51caffb454 | ||
|
|
ef1baf94f7 | ||
|
|
8b18d1a0a4 | ||
|
|
4481b9584c | ||
|
|
dec68aa9a9 | ||
|
|
c10712a82b | ||
|
|
d81e2c654f | ||
|
|
f5dcd84d27 | ||
|
|
7c4911c577 | ||
|
|
be4583ac84 | ||
|
|
068374740c | ||
|
|
f7d63b0927 | ||
|
|
9087b18234 | ||
|
|
19a3907657 | ||
|
|
762920232a | ||
|
|
f30fe71395 | ||
|
|
ec6f4bab46 | ||
|
|
0d2efc3f3f | ||
|
|
bb480068fa | ||
|
|
ae9fe1a10e | ||
|
|
dd19026e91 | ||
|
|
42d2c04ae1 | ||
|
|
db2557826a | ||
|
|
11d98df304 | ||
|
|
ec84fd2ca6 | ||
|
|
fe6eb5f665 | ||
|
|
90b00dfe57 | ||
|
|
023411f975 | ||
|
|
a97bfa08ec | ||
|
|
9c2a45c59e | ||
|
|
1b72e814e7 | ||
|
|
71b078611f | ||
|
|
1ef8cfcac5 | ||
|
|
6b8e316663 | ||
|
|
21d03697ca | ||
|
|
4c7f824e0a | ||
|
|
42244e1b4d | ||
|
|
2981adac66 | ||
|
|
91971db3d0 | ||
|
|
b4e8ab4254 | ||
|
|
198a7ce74d | ||
|
|
e103490376 | ||
|
|
f3658c210c | ||
|
|
1ba3682d9b | ||
|
|
39b7468bab | ||
|
|
a42e9aaaba | ||
|
|
a9b7194485 | ||
|
|
2ad55ba791 | ||
|
|
ac8dc59341 | ||
|
|
c1c1cd97e7 | ||
|
|
b23c373f4d | ||
|
|
e6da6c251c | ||
|
|
81ded6124d | ||
|
|
c417f733af | ||
|
|
63dcbe3d75 | ||
|
|
fb342b73d3 | ||
|
|
cccb5094a4 | ||
|
|
3330d5296c | ||
|
|
f95f98b12a | ||
|
|
7bb6358540 | ||
|
|
ca33c52086 | ||
|
|
aba3ba738f | ||
|
|
60da4369a4 | ||
|
|
b04e84ab9e | ||
|
|
d96de4c222 | ||
|
|
0ff5c52657 | ||
|
|
f532367412 | ||
|
|
94996b8a29 | ||
|
|
59e6f149a7 | ||
|
|
470806b097 | ||
|
|
8fcc82171a | ||
|
|
4d5b32ee59 | ||
|
|
816aa50dfc | ||
|
|
068c52d8f5 | ||
|
|
692caffe2c | ||
|
|
c97bb52d77 | ||
|
|
438634b718 | ||
|
|
d21cb609a8 | ||
|
|
668c0627c0 | ||
|
|
de0b6da9f4 | ||
|
|
5853f90076 | ||
|
|
022d5131b3 | ||
|
|
7458729d28 | ||
|
|
7acf6a4a66 | ||
|
|
04d73b9192 | ||
|
|
f7e99131b9 | ||
|
|
069b0b8c90 | ||
|
|
1ff7a89433 | ||
|
|
640d1cf929 | ||
|
|
c9955f9fdf | ||
|
|
9a877e0e9a | ||
|
|
6b49224c85 | ||
|
|
fd5e4e6019 | ||
|
|
8e2a100460 | ||
|
|
359dcc3c5c | ||
|
|
6021341118 | ||
|
|
d5922830d0 | ||
|
|
23505d30a5 | ||
|
|
0f83653e76 | ||
|
|
20f0e8ad55 | ||
|
|
140a165ab2 | ||
|
|
5fec1c8b1f | ||
|
|
6bd4060ae0 | ||
|
|
84a8415357 | ||
|
|
6429b5c298 | ||
|
|
6b5e7d78e3 | ||
|
|
a8b2c64cbf | ||
|
|
9268f0db50 | ||
|
|
02bd3e2ff1 | ||
|
|
2d28fba3bf | ||
|
|
19aed2dcb1 | ||
|
|
eed1e0789a | ||
|
|
837565c505 | ||
|
|
fece182cf5 | ||
|
|
945452bff4 | ||
|
|
1c08a2ba55 | ||
|
|
d967ceb98b | ||
|
|
a3c3e13b2f | ||
|
|
83a186f6cc | ||
|
|
2598f9bb18 | ||
|
|
ba28c48efc | ||
|
|
98234d1017 | ||
|
|
99a92b3483 | ||
|
|
c85ff492d0 | ||
|
|
b09cfb8fb1 | ||
|
|
966a958ca5 | ||
|
|
885069e1f6 | ||
|
|
077b38e2c5 | ||
|
|
9be04e6fac | ||
|
|
377d5b426a | ||
|
|
f82a128909 | ||
|
|
216759e955 | ||
|
|
9b6caf5a5b | ||
|
|
5c25bbd93f | ||
|
|
d8937492cb | ||
|
|
e91d85edb5 | ||
|
|
5089db7331 | ||
|
|
8e20d628e8 | ||
|
|
d275505df6 | ||
|
|
f7516e6b2b | ||
|
|
898d4c8dd9 | ||
|
|
2e9d09b961 | ||
|
|
8dd6efe5ed | ||
|
|
635df9c806 | ||
|
|
75b8b8c875 | ||
|
|
90f0530234 | ||
|
|
d744827f93 | ||
|
|
fe8b22caa1 | ||
|
|
9a82526b91 | ||
|
|
225a6d9c6e | ||
|
|
87c8dd5434 | ||
|
|
a09c4bbdc2 | ||
|
|
d01651c305 | ||
|
|
00982fc3db | ||
|
|
d8f890a43a | ||
|
|
a58681a718 | ||
|
|
c9d33fb9f7 | ||
|
|
254df71810 | ||
|
|
194dc32059 | ||
|
|
987c1c97e5 |
+17
-1
@@ -1,9 +1,11 @@
|
||||
*.lo
|
||||
*.o
|
||||
/.libs/
|
||||
/.source
|
||||
/Makefile
|
||||
/autom4te.cache/
|
||||
/config.h
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
@@ -18,6 +20,7 @@
|
||||
/doc/unbound.conf.5
|
||||
/libtool
|
||||
/libunbound.la
|
||||
/_unbound.la
|
||||
/smallapp/unbound-control-setup.sh
|
||||
/unbound
|
||||
/unbound-anchor
|
||||
@@ -36,4 +39,17 @@
|
||||
/streamtcp
|
||||
/testbound
|
||||
/unittest
|
||||
|
||||
/contrib/libunbound.pc
|
||||
/contrib/unbound.service
|
||||
/contrib/unbound.socket
|
||||
/dnstap/dnstap.pb-c.c
|
||||
/dnstap/dnstap.pb-c.h
|
||||
/libunbound/python/libunbound_wrap.c
|
||||
/libunbound/python/unbound.py
|
||||
/pythonmod/interface.h
|
||||
/pythonmod/unboundmodule.py
|
||||
/testdata/result.*
|
||||
/testdata/.done-*
|
||||
/testdata/.perfstats.txt
|
||||
/doc/html
|
||||
/doc/xml
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
sudo: false
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libssl-dev
|
||||
- libevent-dev
|
||||
- libexpat-dev
|
||||
- clang
|
||||
script:
|
||||
- ./configure --enable-debug --disable-flto
|
||||
- make
|
||||
- make test
|
||||
- (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
|
||||
+488
-543
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
# Unbound
|
||||
|
||||
[](https://travis-ci.org/NLnetLabs/unbound)
|
||||
[](https://repology.org/project/unbound/versions)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
|
||||
|
||||
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
|
||||
fast and lean and incorporates modern features based on open standards. If you
|
||||
have any feedback, we would love to hear from you. Don’t hesitate to
|
||||
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
|
||||
or post a message on the [Unbound mailing list](https://nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
You can lean more about Unbound by reading our
|
||||
[documentation](https://nlnetlabs.nl/documentation/unbound/).
|
||||
|
||||
## Compiling
|
||||
|
||||
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
|
||||
installed. Unbound can be compiled and installed using:
|
||||
|
||||
```
|
||||
./configure && make && make install
|
||||
```
|
||||
|
||||
You can use libevent if you want. libevent is useful when using many (10000)
|
||||
outgoing ports. By default max 256 ports are opened at the same time and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
|
||||
Use the `--with-libevent=dir` configure option to compile Unbound with libevent
|
||||
support.
|
||||
|
||||
## Unbound configuration
|
||||
|
||||
All of Unbound's configuration options are described in the man pages, which
|
||||
will be installed and are available on the Unbound
|
||||
[documentation page](https://nlnetlabs.nl/documentation/unbound/).
|
||||
|
||||
An example configuration file is located in
|
||||
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
|
||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -9390,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -9421,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
@@ -72,6 +72,19 @@
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#endif
|
||||
|
||||
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
|
||||
#ifndef be64toh
|
||||
#if defined(__sun) || defined(_AIX)
|
||||
# if __BIG_ENDIAN__
|
||||
# define be64toh(n) (n)
|
||||
# define htobe64(n) (n)
|
||||
# else
|
||||
# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
|
||||
# endif
|
||||
#endif
|
||||
#endif /* be64toh */
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
struct testframe_moddata {
|
||||
@@ -231,6 +244,8 @@ cachedb_init(struct module_env* env, int id)
|
||||
env->modinfo[id] = (void*)cachedb_env;
|
||||
if(!cachedb_apply_cfg(cachedb_env, env->cfg)) {
|
||||
log_err("cachedb: could not apply configuration settings.");
|
||||
free(cachedb_env);
|
||||
env->modinfo[id] = NULL;
|
||||
return 0;
|
||||
}
|
||||
/* see if a backend is selected */
|
||||
@@ -239,6 +254,8 @@ cachedb_init(struct module_env* env, int id)
|
||||
if(!(*cachedb_env->backend->init)(env, cachedb_env)) {
|
||||
log_err("cachedb: could not init %s backend",
|
||||
cachedb_env->backend->name);
|
||||
free(cachedb_env);
|
||||
env->modinfo[id] = NULL;
|
||||
return 0;
|
||||
}
|
||||
cachedb_env->enabled = 1;
|
||||
@@ -336,7 +353,11 @@ calc_hash(struct module_qstate* qstate, char* buf, size_t len)
|
||||
|
||||
/* hash the buffer */
|
||||
secalgo_hash_sha256(clear, clen, hash);
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(clear, clen);
|
||||
#else
|
||||
memset(clear, 0, clen);
|
||||
#endif
|
||||
|
||||
/* hex encode output for portability (some online dbs need
|
||||
* no nulls, no control characters, and so on) */
|
||||
|
||||
@@ -140,6 +140,7 @@ nodevrandom:
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
assert(buf);
|
||||
if (n < KEYSZ + IVSZ)
|
||||
return;
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||
* Copyright (c) 2014 Brent Cook <bcook@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* Derived from lib/libc/gen/arc4random.c from FreeBSD.
|
||||
*/
|
||||
static size_t
|
||||
getentropy_sysctl(u_char *buf, size_t size)
|
||||
{
|
||||
int mib[2];
|
||||
size_t len, done;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_ARND;
|
||||
done = 0;
|
||||
|
||||
do {
|
||||
len = size;
|
||||
if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
|
||||
return (done);
|
||||
done += len;
|
||||
buf += len;
|
||||
size -= len;
|
||||
} while (size > 0);
|
||||
|
||||
return (done);
|
||||
}
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
if (len <= 256 && getentropy_sysctl(buf, len) == len)
|
||||
return (0);
|
||||
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
+63
-84
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -15,20 +15,23 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "config.h"
|
||||
/*
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#define _GNU_SOURCE 1
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#define _GNU_SOURCE 1
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#ifdef SYS__sysctl
|
||||
#include <linux/sysctl.h>
|
||||
#endif
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -39,6 +42,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <link.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@@ -46,16 +50,18 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(HAVE_SSL)
|
||||
#ifndef HAVE_NETTLE
|
||||
#include <openssl/sha.h>
|
||||
#elif defined(HAVE_NETTLE)
|
||||
#else
|
||||
#include <nettle/sha.h>
|
||||
#define SHA512_CTX struct sha512_ctx
|
||||
#define SHA512_Init(x) sha512_init(x)
|
||||
#define SHA512_Update(x, b, s) sha512_update(x, s, b)
|
||||
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sysctl.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
@@ -75,29 +81,13 @@
|
||||
HD(b); \
|
||||
} while (0)
|
||||
|
||||
#if defined(HAVE_SSL)
|
||||
#define CRYPTO_SHA512_CTX SHA512_CTX
|
||||
#define CRYPTO_SHA512_INIT(x) SHA512_Init(x)
|
||||
#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c)
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
#elif defined(HAVE_NETTLE)
|
||||
#define CRYPTO_SHA512_CTX struct sha512_ctx
|
||||
#define CRYPTO_SHA512_INIT(x) sha512_init(x)
|
||||
#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
|
||||
#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
|
||||
#define HF(x) (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x)))
|
||||
#endif
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int getentropy_getrandom(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
@@ -105,6 +95,7 @@ static int getentropy_urandom(void *buf, size_t len);
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
@@ -113,18 +104,21 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
/*
|
||||
* Try descriptor-less getrandom()
|
||||
* Try descriptor-less getrandom(), in non-blocking mode.
|
||||
*
|
||||
* The design of Linux getrandom is broken. It has an
|
||||
* uninitialized phase coupled with blocking behaviour, which
|
||||
* is unacceptable from within a library at boot time without
|
||||
* possible recovery. See http://bugs.python.org/issue26839#msg267745
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (errno != ENOSYS)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -178,7 +172,7 @@ getentropy(void *buf, size_t len)
|
||||
* - Do the best under the circumstances....
|
||||
*
|
||||
* This code path exists to bring light to the issue that Linux
|
||||
* does not provide a failsafe API for entropy collection.
|
||||
* still does not provide a failsafe API for entropy collection.
|
||||
*
|
||||
* We hope this demonstrates that Linux should either retain their
|
||||
* sysctl ABI, or consider providing a new failsafe API which
|
||||
@@ -196,23 +190,7 @@ getentropy(void *buf, size_t len)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
@@ -221,7 +199,7 @@ getentropy_getrandom(void *buf, size_t len)
|
||||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, 0);
|
||||
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret != (int)len)
|
||||
@@ -269,7 +247,7 @@ start:
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
@@ -280,13 +258,11 @@ start:
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef SYS__sysctl
|
||||
@@ -311,17 +287,15 @@ getentropy_sysctl(void *buf, size_t len)
|
||||
goto sysctlfailed;
|
||||
i += chunk;
|
||||
}
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
sysctlfailed:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
static int cl[] = {
|
||||
static const int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC,
|
||||
@@ -346,6 +320,15 @@ static int cl[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
getentropy_phdr(struct dl_phdr_info *info, size_t ATTR_UNUSED(size), void *data)
|
||||
{
|
||||
SHA512_CTX *ctx = data;
|
||||
|
||||
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
@@ -357,7 +340,7 @@ getentropy_fallback(void *buf, size_t len)
|
||||
struct rusage ru;
|
||||
sigset_t sigset;
|
||||
struct stat st;
|
||||
CRYPTO_SHA512_CTX ctx;
|
||||
SHA512_CTX ctx;
|
||||
static pid_t lastpid;
|
||||
pid_t pid;
|
||||
size_t i, ii, m;
|
||||
@@ -374,7 +357,7 @@ getentropy_fallback(void *buf, size_t len)
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
int j;
|
||||
CRYPTO_SHA512_INIT(&ctx);
|
||||
SHA512_Init(&ctx);
|
||||
for (j = 0; j < repeat; j++) {
|
||||
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
|
||||
if (e != -1) {
|
||||
@@ -382,6 +365,8 @@ getentropy_fallback(void *buf, size_t len)
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
dl_iterate_phdr(getentropy_phdr, &ctx);
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
@@ -401,9 +386,6 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
@@ -528,33 +510,30 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HD(cnt);
|
||||
}
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
# ifdef AT_RANDOM
|
||||
#ifdef AT_RANDOM
|
||||
/* Not as random as you think but we take what we are given */
|
||||
p = (char *) getauxval(AT_RANDOM);
|
||||
if (p)
|
||||
HR(p, 16);
|
||||
# endif
|
||||
# ifdef AT_SYSINFO_EHDR
|
||||
#endif
|
||||
#ifdef AT_SYSINFO_EHDR
|
||||
p = (char *) getauxval(AT_SYSINFO_EHDR);
|
||||
if (p)
|
||||
HR(p, pgs);
|
||||
# endif
|
||||
# ifdef AT_BASE
|
||||
#endif
|
||||
#ifdef AT_BASE
|
||||
p = (char *) getauxval(AT_BASE);
|
||||
if (p)
|
||||
HD(p);
|
||||
# endif
|
||||
#endif /* HAVE_GETAUXVAL */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CRYPTO_SHA512_FINAL(results, &ctx);
|
||||
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
|
||||
SHA512_Final(results, &ctx);
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
|
||||
+25
-40
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */
|
||||
/* $OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -15,9 +15,12 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -43,14 +46,18 @@
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/host_info.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#endif
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
|
||||
#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
|
||||
@@ -75,10 +82,6 @@
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
|
||||
@@ -89,7 +92,7 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -138,22 +141,6 @@ getentropy(void *buf, size_t len)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
@@ -188,7 +175,7 @@ start:
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
@@ -199,18 +186,18 @@ start:
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
|
||||
static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
|
||||
static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
|
||||
#endif
|
||||
static int kmib[] = { CTL_KERN, KERN_USRSTACK };
|
||||
static int hwmib[] = { CTL_HW, HW_USERMEM };
|
||||
|
||||
@@ -230,9 +217,11 @@ getentropy_fallback(void *buf, size_t len)
|
||||
pid_t pid;
|
||||
size_t i, ii, m;
|
||||
char *p;
|
||||
#if TARGET_OS_OSX
|
||||
struct tcpstat tcpstat;
|
||||
struct udpstat udpstat;
|
||||
struct ipstat ipstat;
|
||||
#endif
|
||||
u_int64_t mach_time;
|
||||
unsigned int idata;
|
||||
void *addr;
|
||||
@@ -267,6 +256,7 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
|
||||
&idata, &ii, NULL, 0) == -1, idata);
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
ii = sizeof(tcpstat);
|
||||
HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
|
||||
&tcpstat, &ii, NULL, 0) == -1, tcpstat);
|
||||
@@ -278,6 +268,7 @@ getentropy_fallback(void *buf, size_t len)
|
||||
ii = sizeof(ipstat);
|
||||
HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
|
||||
&ipstat, &ii, NULL, 0) == -1, ipstat);
|
||||
#endif
|
||||
|
||||
HX((pid = getpid()) == -1, pid);
|
||||
HX((pid = getsid(pid)) == -1, pid);
|
||||
@@ -295,9 +286,6 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
@@ -419,14 +407,11 @@ getentropy_fallback(void *buf, size_t len)
|
||||
}
|
||||
|
||||
SHA512_Final(results, &ctx);
|
||||
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
|
||||
+29
-41
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.13 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -15,9 +15,12 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -34,6 +37,7 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <link.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@@ -67,17 +71,14 @@
|
||||
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
static int getentropy_urandom(void *buf, size_t len, const char *path,
|
||||
int devfscheck);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
@@ -86,7 +87,7 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -153,22 +154,6 @@ getentropy(void *buf, size_t len)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
|
||||
{
|
||||
@@ -204,7 +189,7 @@ start:
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
@@ -215,13 +200,11 @@ start:
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static const int cl[] = {
|
||||
@@ -249,6 +232,15 @@ static const int cl[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int
|
||||
getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
SHA512_CTX *ctx = data;
|
||||
|
||||
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
@@ -286,6 +278,8 @@ getentropy_fallback(void *buf, size_t len)
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
dl_iterate_phdr(getentropy_phdr, &ctx);
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
@@ -306,9 +300,6 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
@@ -428,14 +419,11 @@ getentropy_fallback(void *buf, size_t len)
|
||||
HD(cnt);
|
||||
}
|
||||
SHA512_Final(results, &ctx);
|
||||
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
|
||||
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD$ */
|
||||
/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -15,6 +15,9 @@
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
@@ -37,7 +40,7 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
#undef malloc
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
void *malloc ();
|
||||
#else
|
||||
/* provide a prototype */
|
||||
void *malloc (size_t n);
|
||||
#endif
|
||||
|
||||
/* Allocate an N-byte block of memory from the heap.
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
+5
-2
@@ -658,7 +658,7 @@ int vsnprintf(char* str, size_t size, const char* format, va_list arg)
|
||||
* are not their own functions. */
|
||||
|
||||
/* printout designation:
|
||||
* conversion specifier: x, d, u, s, c, n, m, p
|
||||
* conversion specifier: x, d, u, s, c, m, p
|
||||
* flags: # not supported
|
||||
* 0 zeropad (on the left)
|
||||
* - left adjust (right by default)
|
||||
@@ -798,7 +798,10 @@ int vsnprintf(char* str, size_t size, const char* format, va_list arg)
|
||||
minw, minus);
|
||||
break;
|
||||
case 'n':
|
||||
*va_arg(arg, int*) = ret;
|
||||
/* unsupported to harden against format string
|
||||
* exploitation,
|
||||
* handled like an unknown format specifier. */
|
||||
/* *va_arg(arg, int*) = ret; */
|
||||
break;
|
||||
case 'm':
|
||||
print_str(&at, &left, &ret, strerror(errno),
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/usr/bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
+74
-5
@@ -1,5 +1,11 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* apply the noreturn attribute to a function that exits the program */
|
||||
#undef ATTR_NORETURN
|
||||
|
||||
/* apply the weak attribute to a symbol */
|
||||
#undef ATTR_WEAK
|
||||
|
||||
/* Directory to chroot to */
|
||||
#undef CHROOT_DIR
|
||||
|
||||
@@ -9,6 +15,9 @@
|
||||
/* Do sha512 definitions in config.h */
|
||||
#undef COMPAT_SHA512
|
||||
|
||||
/* Command line arguments used with configure */
|
||||
#undef CONFCMDLINE
|
||||
|
||||
/* Pathname to the Unbound configuration file */
|
||||
#undef CONFIGFILE
|
||||
|
||||
@@ -45,6 +54,9 @@
|
||||
/* Whether the C compiler accepts the "format" attribute */
|
||||
#undef HAVE_ATTR_FORMAT
|
||||
|
||||
/* Whether the C compiler accepts the "noreturn" attribute */
|
||||
#undef HAVE_ATTR_NORETURN
|
||||
|
||||
/* Whether the C compiler accepts the "unused" attribute */
|
||||
#undef HAVE_ATTR_UNUSED
|
||||
|
||||
@@ -60,6 +72,9 @@
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
|
||||
#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#undef HAVE_CTIME_R
|
||||
|
||||
@@ -74,6 +89,10 @@
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
|
||||
|
||||
/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
|
||||
you don't. */
|
||||
#undef HAVE_DECL_EVSIGNAL_ASSIGN
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_NTOP
|
||||
@@ -154,6 +173,9 @@
|
||||
/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
|
||||
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
|
||||
/* Define to 1 if you have the `event_assign' function. */
|
||||
#undef HAVE_EVENT_ASSIGN
|
||||
|
||||
/* Define to 1 if you have the `event_base_free' function. */
|
||||
#undef HAVE_EVENT_BASE_FREE
|
||||
|
||||
@@ -169,6 +191,9 @@
|
||||
/* Define to 1 if you have the <event.h> header file. */
|
||||
#undef HAVE_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
|
||||
#undef HAVE_EVP_AES_256_CBC
|
||||
|
||||
/* Define to 1 if you have the `EVP_cleanup' function. */
|
||||
#undef HAVE_EVP_CLEANUP
|
||||
|
||||
@@ -178,6 +203,9 @@
|
||||
/* Define to 1 if you have the `EVP_dss1' function. */
|
||||
#undef HAVE_EVP_DSS1
|
||||
|
||||
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
|
||||
#undef HAVE_EVP_MD_CTX_NEW
|
||||
|
||||
@@ -199,6 +227,9 @@
|
||||
/* Define to 1 if you have the <expat.h> header file. */
|
||||
#undef HAVE_EXPAT_H
|
||||
|
||||
/* Define to 1 if you have the `explicit_bzero' function. */
|
||||
#undef HAVE_EXPLICIT_BZERO
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
@@ -247,6 +278,9 @@
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* Define to 1 if you have the `HMAC_Init_ex' function. */
|
||||
#undef HAVE_HMAC_INIT_EX
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
@@ -382,7 +416,7 @@
|
||||
/* Define to 1 if you have the `RAND_cleanup' function. */
|
||||
#undef HAVE_RAND_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `reallocarray' function. */
|
||||
/* If we have reallocarray(3) */
|
||||
#undef HAVE_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the `recvmsg' function. */
|
||||
@@ -439,9 +473,15 @@
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
|
||||
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_peername' function. */
|
||||
#undef HAVE_SSL_GET0_PEERNAME
|
||||
|
||||
@@ -574,9 +614,15 @@
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
|
||||
#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
|
||||
|
||||
/* Define to 1 if you have the `_beginthreadex' function. */
|
||||
#undef HAVE__BEGINTHREADEX
|
||||
|
||||
/* If HMAC_Init_ex() returns void */
|
||||
#undef HMAC_INIT_EX_RETURNS_VOID
|
||||
|
||||
/* if lex has yylex_destroy */
|
||||
#undef LEX_HAS_YYLEX_DESTROY
|
||||
|
||||
@@ -651,6 +697,9 @@
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* if REUSEPORT is enabled by default */
|
||||
#undef REUSEPORT_DEFAULT
|
||||
|
||||
/* default rootkey location */
|
||||
#undef ROOT_ANCHOR_FILE
|
||||
|
||||
@@ -666,6 +715,9 @@
|
||||
/* Shared data */
|
||||
#undef SHARE_DIR
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#undef SIZEOF_SIZE_T
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#undef SIZEOF_TIME_T
|
||||
|
||||
@@ -684,6 +736,9 @@
|
||||
/* Use win32 resources and API */
|
||||
#undef UB_ON_WINDOWS
|
||||
|
||||
/* the SYSLOG_FACILITY to use, default LOG_DAEMON */
|
||||
#undef UB_SYSLOG_FACILITY
|
||||
|
||||
/* default username */
|
||||
#undef UB_USERNAME
|
||||
|
||||
@@ -732,6 +787,9 @@
|
||||
/* Define to 1 to use ipsecmod support. */
|
||||
#undef USE_IPSECMOD
|
||||
|
||||
/* Define to 1 to use ipset support */
|
||||
#undef USE_IPSET
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
@@ -929,8 +987,14 @@
|
||||
|
||||
|
||||
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifndef UNBOUND_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
@@ -1144,6 +1208,11 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
#define explicit_bzero unbound_explicit_bzero
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
@@ -1158,6 +1227,10 @@ struct tm;
|
||||
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_REALLOCARRAY
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESSL
|
||||
# if !HAVE_DECL_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
@@ -1171,12 +1244,8 @@ uint32_t arc4random(void);
|
||||
# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
|
||||
uint32_t arc4random_uniform(uint32_t upper_bound);
|
||||
# endif
|
||||
# if !HAVE_DECL_REALLOCARRAY
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
# endif
|
||||
#endif /* HAVE_LIBRESSL */
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
int getentropy(void* buf, size_t len);
|
||||
uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
#! /bin/sh
|
||||
#!/usr/bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
+220
-22
@@ -10,16 +10,16 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[8])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
m4_define([VERSION_MINOR],[9])
|
||||
m4_define([VERSION_MICRO],[6])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=8
|
||||
LIBUNBOUND_REVISION=0
|
||||
LIBUNBOUND_AGE=0
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=6
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@@ -81,7 +81,17 @@ LIBUNBOUND_AGE=0
|
||||
# 1.7.1 had 7:9:5
|
||||
# 1.7.2 had 7:10:5
|
||||
# 1.7.3 had 7:11:5
|
||||
# 1.7.4 had 8:0:0 # changes the event callback function signature
|
||||
# 1.8.0 had 8:0:0 # changes the event callback function signature
|
||||
# 1.8.1 had 8:1:0
|
||||
# 1.8.2 had 8:2:0
|
||||
# 1.8.3 had 8:3:0
|
||||
# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
|
||||
# 1.9.1 had 9:1:1
|
||||
# 1.9.2 had 9:2:1
|
||||
# 1.9.3 had 9:3:1
|
||||
# 1.9.4 had 9:4:1
|
||||
# 1.9.5 had 9:5:1
|
||||
# 1.9.6 had 9:6:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -105,6 +115,10 @@ AC_SUBST(LIBUNBOUND_CURRENT)
|
||||
AC_SUBST(LIBUNBOUND_REVISION)
|
||||
AC_SUBST(LIBUNBOUND_AGE)
|
||||
|
||||
|
||||
cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
|
||||
AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
|
||||
|
||||
CFLAGS="$CFLAGS"
|
||||
AC_AIX
|
||||
if test "$ac_cv_header_minix_config_h" = "yes"; then
|
||||
@@ -310,11 +324,36 @@ __attribute__((weak)) void f(int x) { printf("%d", x); }
|
||||
AC_MSG_RESULT($ac_cv_c_weak_attribute)
|
||||
if test $ac_cv_c_weak_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
|
||||
AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
|
||||
fi
|
||||
])dnl End of CHECK_WEAK_ATTRIBUTE
|
||||
|
||||
CHECK_WEAK_ATTRIBUTE
|
||||
|
||||
AC_DEFUN([CHECK_NORETURN_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
|
||||
[ac_cv_c_noreturn_attribute=no
|
||||
AC_TRY_COMPILE(
|
||||
[ #include <stdio.h>
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
|
||||
], [
|
||||
f(1);
|
||||
],
|
||||
[ac_cv_c_noreturn_attribute="yes"],
|
||||
[ac_cv_c_noreturn_attribute="no"])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
|
||||
if test $ac_cv_c_noreturn_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
|
||||
AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
|
||||
fi
|
||||
])dnl End of CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
if test "$srcdir" != "."; then
|
||||
CPPFLAGS="$CPPFLAGS -I$srcdir"
|
||||
fi
|
||||
@@ -353,6 +392,8 @@ AC_CHECK_PROG(doxygen, doxygen, doxygen)
|
||||
AC_CHECK_TOOL(STRIP, strip)
|
||||
ACX_LIBTOOL_C_ONLY
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
@@ -391,6 +432,7 @@ AC_INCLUDES_DEFAULT
|
||||
# endif
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
|
||||
# add option to disable the evil rpath
|
||||
ACX_ARG_RPATH
|
||||
@@ -435,6 +477,17 @@ ACX_CHECK_NONBLOCKING_BROKEN
|
||||
ACX_MKDIR_ONE_ARG
|
||||
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||
|
||||
# check if we can use SO_REUSEPORT
|
||||
if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
|
||||
AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default])
|
||||
else
|
||||
AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default])
|
||||
fi
|
||||
|
||||
# Include systemd.m4 - begin
|
||||
sinclude(systemd.m4)
|
||||
# Include systemd.m4 - end
|
||||
|
||||
# set memory allocation checking if requested
|
||||
AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
|
||||
[ enable to memory allocation statistics, for debug purposes ]),
|
||||
@@ -450,6 +503,10 @@ if test x_$enable_alloc_nonregional = x_yes; then
|
||||
fi
|
||||
if test x_$enable_alloc_checks = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
|
||||
SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
|
||||
AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
|
||||
ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
|
||||
AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
|
||||
else
|
||||
if test x_$enable_alloc_lite = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
|
||||
@@ -553,6 +610,18 @@ fi
|
||||
|
||||
fi # end of non-mingw check of thread libraries
|
||||
|
||||
# Check for SYSLOG_FACILITY
|
||||
AC_ARG_WITH(syslog-facility, AC_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7], [ set SYSLOG_FACILITY, default DAEMON ]),
|
||||
[ UNBOUND_SYSLOG_FACILITY="$withval" ], [])
|
||||
case "${UNBOUND_SYSLOG_FACILITY}" in
|
||||
|
||||
LOCAL[[0-7]]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;;
|
||||
|
||||
*) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;;
|
||||
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
|
||||
|
||||
# Check for PyUnbound
|
||||
AC_ARG_WITH(pyunbound,
|
||||
AC_HELP_STRING([--with-pyunbound],
|
||||
@@ -605,7 +674,6 @@ if test x_$ub_test_python != x_no; then
|
||||
CPPFLAGS="$PYTHON_CPPFLAGS"
|
||||
fi
|
||||
ub_have_python=yes
|
||||
PKG_PROG_PKG_CONFIG
|
||||
PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
|
||||
[PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
|
||||
[PC_PY_DEPENDENCY="python"])
|
||||
@@ -740,17 +808,17 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/
|
||||
AC_DEFINE([HAVE_LIBRESSL], [1], [Define if we have LibreSSL])
|
||||
# libressl provides these compat functions, but they may also be
|
||||
# declared by the OS in libc. See if they have been declared.
|
||||
AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform,reallocarray])
|
||||
AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
@@ -773,6 +841,42 @@ AC_INCLUDES_DEFAULT
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
|
||||
if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
|
||||
# check function return type.
|
||||
AC_MSG_CHECKING(the return type of HMAC_Init_ex)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RAND_H
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
], [
|
||||
HMAC_CTX* hmac_ctx = NULL;
|
||||
void* hmac_key = NULL;
|
||||
const EVP_MD* digest = NULL;
|
||||
int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL);
|
||||
(void)x;
|
||||
])], [
|
||||
AC_MSG_RESULT(int)
|
||||
], [
|
||||
AC_MSG_RESULT(void)
|
||||
AC_DEFINE([HMAC_INIT_EX_RETURNS_VOID], 1, [If HMAC_Init_ex() returns void])
|
||||
])
|
||||
fi
|
||||
|
||||
fi
|
||||
AC_SUBST(SSLLIB)
|
||||
|
||||
@@ -1161,6 +1265,14 @@ large outgoing port ranges. ])
|
||||
AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
|
||||
AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
|
||||
AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
|
||||
AC_CHECK_FUNCS([event_assign]) # in libevent, for thread-safety
|
||||
AC_CHECK_DECLS([evsignal_assign], [], [], [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_EVENT_H
|
||||
# include <event.h>
|
||||
#else
|
||||
# include "event2/event.h"
|
||||
#endif
|
||||
])
|
||||
PC_LIBEVENT_DEPENDENCY="libevent"
|
||||
AC_SUBST(PC_LIBEVENT_DEPENDENCY)
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
@@ -1229,11 +1341,11 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
])
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
# set static linking for uninstalled libraries if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe],
|
||||
[ enable to compile executables statically against (event) libs, for debug purposes ]),
|
||||
[ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]),
|
||||
, )
|
||||
if test x_$enable_static_exe = x_yes; then
|
||||
staticexe="-static"
|
||||
@@ -1249,9 +1361,22 @@ if test x_$enable_static_exe = x_yes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Include systemd.m4 - begin
|
||||
sinclude(systemd.m4)
|
||||
# Include systemd.m4 - end
|
||||
# set full static linking if requested
|
||||
AC_ARG_ENABLE(fully-static, AC_HELP_STRING([--enable-fully-static],
|
||||
[ enable to compile fully static ]),
|
||||
, )
|
||||
if test x_$enable_fully_static = x_yes; then
|
||||
staticexe="-all-static"
|
||||
if test "$on_mingw" = yes; then
|
||||
# for static compile, include gdi32 and zlib here.
|
||||
if echo $LIBS | grep 'lgdi32' >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -lgdi32"
|
||||
fi
|
||||
LIBS="$LIBS -lz"
|
||||
fi
|
||||
fi
|
||||
|
||||
# set lock checking if requested
|
||||
AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
|
||||
@@ -1396,15 +1521,33 @@ AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
AC_REPLACE_FUNCS(isblank)
|
||||
AC_REPLACE_FUNCS(explicit_bzero)
|
||||
dnl without CTIME, ARC4-functions and without reallocarray.
|
||||
LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
|
||||
AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
|
||||
AC_REPLACE_FUNCS(reallocarray)
|
||||
AC_MSG_CHECKING([for reallocarray])
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
|
||||
[[
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
int main(void) {
|
||||
void* p = reallocarray(NULL, 10, 100);
|
||||
free(p);
|
||||
return 0;
|
||||
}
|
||||
]])], [AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_REALLOCARRAY, 1, [If we have reallocarray(3)])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_LIBOBJ(reallocarray)
|
||||
])
|
||||
AC_CHECK_DECLS([reallocarray])
|
||||
if test "$USE_NSS" = "no"; then
|
||||
AC_REPLACE_FUNCS(arc4random)
|
||||
AC_REPLACE_FUNCS(arc4random_uniform)
|
||||
if test "$ac_cv_func_arc4random" = "no"; then
|
||||
AC_LIBOBJ(explicit_bzero)
|
||||
AC_LIBOBJ(arc4_lock)
|
||||
AC_CHECK_FUNCS([getentropy],,[
|
||||
if test "$USE_WINSOCK" = 1; then
|
||||
@@ -1427,6 +1570,9 @@ if test "$USE_NSS" = "no"; then
|
||||
fi
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
;;
|
||||
*freebsd*|*FreeBSD)
|
||||
AC_LIBOBJ(getentropy_freebsd)
|
||||
;;
|
||||
*linux*|Linux|*)
|
||||
AC_LIBOBJ(getentropy_linux)
|
||||
AC_CHECK_FUNCS([SHA512_Update],,[
|
||||
@@ -1539,6 +1685,47 @@ case "$enable_ipsecmod" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for ipset if requested
|
||||
AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module]))
|
||||
case "$enable_ipset" in
|
||||
yes)
|
||||
AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support])
|
||||
IPSET_SRC="ipset/ipset.c"
|
||||
AC_SUBST(IPSET_SRC)
|
||||
IPSET_OBJ="ipset.lo"
|
||||
AC_SUBST(IPSET_OBJ)
|
||||
|
||||
# mnl
|
||||
AC_ARG_WITH(libmnl, AC_HELP_STRING([--with-libmnl=path],
|
||||
[specify explicit path for libmnl.]),
|
||||
[ ],[ withval="yes" ])
|
||||
found_libmnl="no"
|
||||
AC_MSG_CHECKING(for libmnl)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/libmnl/libmnl.h"; then
|
||||
found_libmnl="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
LIBS="$LIBS -lmnl"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
AC_ERROR([Could not find libmnl, libmnl.h])
|
||||
fi
|
||||
;;
|
||||
no|*)
|
||||
# nothing
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
|
||||
@@ -1613,8 +1800,14 @@ AHX_CONFIG_EXT_FLAGS
|
||||
|
||||
dnl includes
|
||||
[
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifndef UNBOUND_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
@@ -1729,6 +1922,11 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
#define explicit_bzero unbound_explicit_bzero
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
@@ -1743,6 +1941,10 @@ struct tm;
|
||||
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_REALLOCARRAY
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESSL
|
||||
# if !HAVE_DECL_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
@@ -1756,12 +1958,8 @@ uint32_t arc4random(void);
|
||||
# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
|
||||
uint32_t arc4random_uniform(uint32_t upper_bound);
|
||||
# endif
|
||||
# if !HAVE_DECL_REALLOCARRAY
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
# endif
|
||||
#endif /* HAVE_LIBRESSL */
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
int getentropy(void* buf, size_t len);
|
||||
uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
|
||||
@@ -38,3 +38,14 @@ distribution but may be helpful.
|
||||
* unbound-querycachedb.py: utility to show data stored in cachedb backend
|
||||
for a particular query name and type. It requires dnspython and (for
|
||||
redis backend) redis Python modules.
|
||||
* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from
|
||||
stdin. Used with fuzzers, patch from Jacob Hoffman-Andrews.
|
||||
* unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
|
||||
replacements for unbound-fuzzme.c that gets created after applying
|
||||
the contrib/unbound-fuzzme.patch. They are contributed by
|
||||
Eric Sesterhenn from X41 D-Sec.
|
||||
* drop-tld.diff: adds option drop-tld: yesno that drops 2 label queries,
|
||||
to stop random floods. Apply with patch -p1 < contrib/drop-tld.diff and
|
||||
compile. From Saksham Manchanda (Secure64). Please note that we think
|
||||
this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
|
||||
lookups for downstream clients.
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
# Variables
|
||||
dst_dir="/etc/opt/csw/unbound"
|
||||
work_dir="/tmp"
|
||||
list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
|
||||
list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
|
||||
|
||||
# OS commands
|
||||
CAT=`which cat`
|
||||
ECHO=`which echo`
|
||||
WGET=`which wget`
|
||||
TR=`which tr`
|
||||
|
||||
# Check Wget installed
|
||||
if [ ! -f $WGET ]; then
|
||||
@@ -22,8 +23,10 @@ if [ ! -f $WGET ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# remove special characters with tr to protect unbound.conf
|
||||
$WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \
|
||||
$CAT $work_dir/yoyo_ad_servers | \
|
||||
$TR -d '";$\\' | \
|
||||
while read line ; \
|
||||
do \
|
||||
$ECHO "local-zone: \"$line\" redirect" ;\
|
||||
@@ -36,4 +39,4 @@ echo "Done."
|
||||
# the unbound_ad_servers file:
|
||||
#
|
||||
# include: $dst_dir/unbound_ad_servers
|
||||
#
|
||||
#
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
diff --git a/daemon/worker.c b/daemon/worker.c
|
||||
index 263fcdd..f787b70 100644
|
||||
--- a/daemon/worker.c
|
||||
+++ b/daemon/worker.c
|
||||
@@ -1213,6 +1213,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||
}
|
||||
+
|
||||
+ if(worker->env.cfg->drop_tld) {
|
||||
+ int lab = dname_count_labels(qinfo.qname);
|
||||
+ if (lab == 2) {
|
||||
+ comm_point_drop_reply(repinfo);
|
||||
+ verbose(VERB_ALGO, "Dropping one label query.");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index b3ef930..2791541 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -274,6 +274,8 @@ struct config_file {
|
||||
int prefetch_key;
|
||||
/** deny queries of type ANY with an empty answer */
|
||||
int deny_any;
|
||||
+ /** Drop TLD queries from clients **/
|
||||
+ int drop_tld;
|
||||
|
||||
/** chrootdir, if not "" or chroot will be done */
|
||||
char* chrootdir;
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index a86ddf5..9bbedbb 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -299,6 +299,7 @@ private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
|
||||
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
|
||||
prefetch{COLON} { YDVAR(1, VAR_PREFETCH) }
|
||||
deny-any{COLON} { YDVAR(1, VAR_DENY_ANY) }
|
||||
+drop-tld{COLON} { YDVAR(1, VAR_DROP_TLD) }
|
||||
stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) }
|
||||
name{COLON} { YDVAR(1, VAR_NAME) }
|
||||
stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index 10227a2..567d68e 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -164,6 +164,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
|
||||
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
|
||||
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
|
||||
+%token VAR_DROP_TLD
|
||||
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
|
||||
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
|
||||
%token VAR_TLS_SESSION_TICKET_KEYS
|
||||
@@ -266,6 +267,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
|
||||
server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
|
||||
server_tcp_connection_limit | server_log_servfail | server_deny_any |
|
||||
+ server_drop_tld |
|
||||
server_unknown_server_time_limit | server_log_tag_queryreply |
|
||||
server_stream_wait_size | server_tls_ciphers |
|
||||
server_tls_ciphersuites | server_tls_session_ticket_keys
|
||||
@@ -1466,6 +1468,16 @@ server_deny_any: VAR_DENY_ANY STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
+
|
||||
+server_drop_tld: VAR_DROP_TLD STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_drop_tld:%s)\n", $2));
|
||||
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
+ yyerror("expected yes or no.");
|
||||
+ else cfg_parser->cfg->drop_tld = (strcmp($2, "yes")==0);
|
||||
+ free($2);
|
||||
+ }
|
||||
+ ;
|
||||
server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
|
||||
+187
-193
@@ -1,14 +1,10 @@
|
||||
Description: based on the included patch contrib/fastrpz.patch
|
||||
Author: fastrpz@farsightsecurity.com
|
||||
---
|
||||
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
|
||||
===================================================================
|
||||
RCS file: ./RCS/Makefile.in,v
|
||||
retrieving revision 1.1
|
||||
Index: unbound-1.7.0~rc1/Makefile.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/Makefile.in
|
||||
+++ unbound-1.7.0~rc1/Makefile.in
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 721c01b6..56bfb560 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
|
||||
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
|
||||
DNSTAP_SRC=@DNSTAP_SRC@
|
||||
@@ -18,25 +14,25 @@ Index: unbound-1.7.0~rc1/Makefile.in
|
||||
DNSCRYPT_SRC=@DNSCRYPT_SRC@
|
||||
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
|
||||
@@ -126,7 +128,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
|
||||
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
@@ -137,7 +139,7 @@ slabhash.lo timehist.lo tube.lo winsock_
|
||||
@@ -139,7 +141,7 @@ autotrust.lo val_anchor.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
-$(IPSECMOD_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) respip.lo
|
||||
-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
outside_network.lo
|
||||
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
|
||||
@@ -400,6 +402,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscry
|
||||
@@ -409,6 +411,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h
|
||||
|
||||
@@ -48,11 +44,11 @@ Index: unbound-1.7.0~rc1/Makefile.in
|
||||
# Python Module
|
||||
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
|
||||
pythonmod/interface.h \
|
||||
Index: unbound-1.7.0~rc1/config.h.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/config.h.in
|
||||
+++ unbound-1.7.0~rc1/config.h.in
|
||||
@@ -1228,4 +1228,11 @@ void *unbound_stat_realloc_log(void *ptr
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 8c2aa3b9..efaf6450 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -1325,4 +1325,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
@@ -65,10 +61,10 @@ Index: unbound-1.7.0~rc1/config.h.in
|
||||
+#undef FASTRPZ_LIB_OPEN
|
||||
+/** turn on fastrpz response policy zones */
|
||||
+#undef ENABLE_FASTRPZ
|
||||
Index: unbound-1.7.0~rc1/configure.ac
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/configure.ac
|
||||
+++ unbound-1.7.0~rc1/configure.ac
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5276d441..9d74592e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
@@ -77,7 +73,7 @@ Index: unbound-1.7.0~rc1/configure.ac
|
||||
sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
@@ -1453,6 +1454,9 @@ case "$enable_ipsecmod" in
|
||||
@@ -1726,6 +1727,9 @@ case "$enable_ipset" in
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -87,11 +83,11 @@ Index: unbound-1.7.0~rc1/configure.ac
|
||||
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
|
||||
Index: unbound-1.7.0~rc1/daemon/daemon.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/daemon/daemon.c
|
||||
+++ unbound-1.7.0~rc1/daemon/daemon.c
|
||||
@@ -90,6 +90,9 @@
|
||||
diff --git a/daemon/daemon.c b/daemon/daemon.c
|
||||
index 0b1200a2..5857c18b 100644
|
||||
--- a/daemon/daemon.c
|
||||
+++ b/daemon/daemon.c
|
||||
@@ -91,6 +91,9 @@
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include <signal.h>
|
||||
@@ -101,36 +97,36 @@ Index: unbound-1.7.0~rc1/daemon/daemon.c
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
@@ -461,6 +464,14 @@ daemon_create_workers(struct daemon* dae
|
||||
@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
|
||||
dt_apply_cfg(daemon->dtenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
}
|
||||
+#endif
|
||||
+ }
|
||||
+ if(daemon->cfg->rpz_enable) {
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
|
||||
+#else
|
||||
+ fatal_exit("fastrpz enabled in config"
|
||||
+ " but not built with fastrpz");
|
||||
+#endif
|
||||
+ }
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
@@ -710,6 +721,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
@@ -724,6 +735,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
#endif
|
||||
daemon->dnscenv = NULL;
|
||||
+#endif
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
|
||||
+#endif
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
Index: unbound-1.7.0~rc1/daemon/daemon.h
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/daemon/daemon.h
|
||||
+++ unbound-1.7.0~rc1/daemon/daemon.h
|
||||
@@ -134,6 +134,11 @@ struct daemon {
|
||||
diff --git a/daemon/daemon.h b/daemon/daemon.h
|
||||
index 5749dbef..64ce230f 100644
|
||||
--- a/daemon/daemon.h
|
||||
+++ b/daemon/daemon.h
|
||||
@@ -136,6 +136,11 @@ struct daemon {
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
#endif
|
||||
@@ -142,11 +138,11 @@ Index: unbound-1.7.0~rc1/daemon/daemon.h
|
||||
};
|
||||
|
||||
/**
|
||||
Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/daemon/worker.c
|
||||
+++ unbound-1.7.0~rc1/daemon/worker.c
|
||||
@@ -74,6 +74,9 @@
|
||||
diff --git a/daemon/worker.c b/daemon/worker.c
|
||||
index e2ce0e87..f031c656 100644
|
||||
--- a/daemon/worker.c
|
||||
+++ b/daemon/worker.c
|
||||
@@ -75,6 +75,9 @@
|
||||
#include "libunbound/context.h"
|
||||
#include "libunbound/libworker.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
@@ -156,7 +152,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
@@ -527,8 +530,27 @@ answer_norec_from_cache(struct worker* w
|
||||
@@ -533,8 +536,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
/* not secure */
|
||||
secure = 0;
|
||||
break;
|
||||
@@ -182,9 +178,9 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
+ }
|
||||
+#endif
|
||||
/* return this delegation from the cache */
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -689,6 +711,23 @@ answer_from_cache(struct worker* worker,
|
||||
@@ -699,6 +721,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
secure = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
@@ -206,9 +202,9 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -1291,6 +1330,15 @@ worker_handle_request(struct comm_point*
|
||||
@@ -1410,6 +1449,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
@@ -224,7 +220,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
}
|
||||
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
@@ -1339,12 +1387,21 @@ lookup_cache:
|
||||
@@ -1458,12 +1506,21 @@ lookup_cache:
|
||||
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
@@ -248,7 +244,7 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
@@ -1398,11 +1455,19 @@ lookup_cache:
|
||||
@@ -1518,11 +1575,19 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
@@ -270,11 +266,11 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/doc/unbound.conf.5.in
|
||||
+++ unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
@@ -1705,6 +1705,81 @@ It must be /96 or shorter. The default
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index 4bdfcd56..69e70627 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -1801,6 +1801,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
@@ -356,10 +352,11 @@ Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
Index: unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
===================================================================
|
||||
diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
|
||||
new file mode 100644
|
||||
index 00000000..645279d1
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
+++ b/fastrpz/librpz.h
|
||||
@@ -0,0 +1,957 @@
|
||||
+/*
|
||||
+ * Define the interface from a DNS resolver to the Response Policy Zone
|
||||
@@ -1318,11 +1315,12 @@ Index: unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
+#endif /* LIBRPZ_LIB_OPEN */
|
||||
+
|
||||
+#endif /* LIBRPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
|
||||
new file mode 100644
|
||||
index 00000000..c5ab7801
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
@@ -0,0 +1,1357 @@
|
||||
+++ b/fastrpz/rpz.c
|
||||
@@ -0,0 +1,1352 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
|
||||
+ *
|
||||
@@ -1438,8 +1436,6 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+static void
|
||||
+log_fnc(librpz_log_level_t level, void* ATTR_UNUSED(ctx), const char* buf)
|
||||
+{
|
||||
+ char label_buf[sizeof("rpz ")+8];
|
||||
+
|
||||
+ /* Setting librpz_log_level overrides the unbound "verbose" level. */
|
||||
+ if(level > LIBRPZ_LOG_TRACE1 &&
|
||||
+ level <= librpz->log_level_val(LIBRPZ_LOG_INVALID))
|
||||
@@ -1949,12 +1945,9 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+ case st_ck_ns:
|
||||
+ /* An NSDNAME or NSIP check failed for lack of cached data. */
|
||||
+ return false;
|
||||
+#pragma clang diagnostic push
|
||||
+#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
+ default:
|
||||
+ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
|
||||
+ rpz->st);
|
||||
+#pragma clang diagnostic pop
|
||||
+ }
|
||||
+
|
||||
+ /* Wait for a trigger. */
|
||||
@@ -2680,10 +2673,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+}
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
|
||||
new file mode 100644
|
||||
index 00000000..5d7e31c5
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
+++ b/fastrpz/rpz.h
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
|
||||
@@ -2823,10 +2817,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
+#endif /* UNBOUND_FASTRPZ_RPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
|
||||
new file mode 100644
|
||||
index 00000000..21235355
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
+++ b/fastrpz/rpz.m4
|
||||
@@ -0,0 +1,64 @@
|
||||
+# fastrpz/rpz.m4
|
||||
+
|
||||
@@ -2892,10 +2887,10 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
|
||||
+ fi
|
||||
+])
|
||||
Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/iterator/iterator.c
|
||||
+++ unbound-1.7.0~rc1/iterator/iterator.c
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 1e0113a8..2fcbf547 100644
|
||||
--- a/iterator/iterator.c
|
||||
+++ b/iterator/iterator.c
|
||||
@@ -68,6 +68,9 @@
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/parseutil.h"
|
||||
@@ -2904,9 +2899,9 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
+#include "fastrpz/rpz.h"
|
||||
+#endif
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
@@ -511,6 +514,23 @@ handle_cname_response(struct module_qsta
|
||||
/* in msec */
|
||||
int UNKNOWN_SERVER_NICENESS = 376;
|
||||
@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
|
||||
query_dname_compare(*mname, r->rk.dname) == 0 &&
|
||||
!iter_find_rrset_in_prepend_answer(iq, r)) {
|
||||
@@ -2930,7 +2925,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
/* Add this relevant CNAME rrset to the prepend list.*/
|
||||
if(!iter_add_prepend_answer(qstate, iq, r))
|
||||
return 0;
|
||||
@@ -519,6 +539,9 @@ handle_cname_response(struct module_qsta
|
||||
@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* Other rrsets in the section are ignored. */
|
||||
}
|
||||
@@ -2940,7 +2935,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
|
||||
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
|
||||
msg->rep->ns_numrrsets; i++) {
|
||||
@@ -1148,6 +1171,7 @@ processInitRequest(struct module_qstate*
|
||||
@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
uint8_t* delname;
|
||||
size_t delnamelen;
|
||||
struct dns_msg* msg = NULL;
|
||||
@@ -2948,7 +2943,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
|
||||
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
|
||||
/* check effort */
|
||||
@@ -1223,8 +1247,7 @@ processInitRequest(struct module_qstate*
|
||||
@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
@@ -2958,7 +2953,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_dns_msg("msg from cache lookup", &msg->qinfo,
|
||||
msg->rep);
|
||||
@@ -1232,7 +1255,22 @@ processInitRequest(struct module_qstate*
|
||||
@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
(int)msg->rep->ttl,
|
||||
(int)msg->rep->prefetch_ttl);
|
||||
}
|
||||
@@ -2981,7 +2976,7 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
if(type == RESPONSE_TYPE_CNAME) {
|
||||
uint8_t* sname = 0;
|
||||
size_t slen = 0;
|
||||
@@ -2552,6 +2590,62 @@ processQueryResponse(struct module_qstat
|
||||
@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
@@ -3041,10 +3036,10 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
@@ -3273,12 +3367,44 @@ processFinished(struct module_qstate* qs
|
||||
@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* but only if we did recursion. The nonrecursion referral
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
|
||||
@@ -3089,11 +3084,11 @@ Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = iq->response;
|
||||
return 0;
|
||||
Index: unbound-1.7.0~rc1/iterator/iterator.h
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/iterator/iterator.h
|
||||
+++ unbound-1.7.0~rc1/iterator/iterator.h
|
||||
@@ -383,6 +383,16 @@ struct iter_qstate {
|
||||
diff --git a/iterator/iterator.h b/iterator/iterator.h
|
||||
index a2f1b570..e1e4a738 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -386,6 +386,16 @@ struct iter_qstate {
|
||||
*/
|
||||
int minimise_count;
|
||||
|
||||
@@ -3110,11 +3105,11 @@ Index: unbound-1.7.0~rc1/iterator/iterator.h
|
||||
/**
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
Index: unbound-1.7.0~rc1/services/cache/dns.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/services/cache/dns.c
|
||||
+++ unbound-1.7.0~rc1/services/cache/dns.c
|
||||
@@ -876,6 +876,14 @@ dns_cache_store(struct module_env* env,
|
||||
diff --git a/services/cache/dns.c b/services/cache/dns.c
|
||||
index aa4efec7..5dd3412e 100644
|
||||
--- a/services/cache/dns.c
|
||||
+++ b/services/cache/dns.c
|
||||
@@ -945,6 +945,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct regional* region, uint32_t flags)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
@@ -3129,11 +3124,11 @@ Index: unbound-1.7.0~rc1/services/cache/dns.c
|
||||
/* alloc, malloc properly (not in region, like msg is) */
|
||||
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||
if(!rep)
|
||||
Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/services/mesh.c
|
||||
+++ unbound-1.7.0~rc1/services/mesh.c
|
||||
@@ -59,6 +59,9 @@
|
||||
diff --git a/services/mesh.c b/services/mesh.c
|
||||
index d4f814d5..624a9d95 100644
|
||||
--- a/services/mesh.c
|
||||
+++ b/services/mesh.c
|
||||
@@ -60,6 +60,9 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -3141,9 +3136,9 @@ Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
+#include "fastrpz/rpz.h"
|
||||
+#endif
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
@@ -1050,6 +1053,13 @@ mesh_send_reply(struct mesh_state* m, in
|
||||
@@ -1076,6 +1079,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
@@ -3157,7 +3152,7 @@ Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
/* send the reply */
|
||||
/* We don't reuse the encoded answer if either the previous or current
|
||||
* response has a local alias. We could compare the alias records
|
||||
@@ -1199,6 +1209,7 @@ struct mesh_state* mesh_area_find(struct
|
||||
@@ -1255,6 +1265,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
key.s.is_valrec = valrec;
|
||||
key.s.qinfo = *qinfo;
|
||||
key.s.query_flags = qflags;
|
||||
@@ -3165,7 +3160,7 @@ Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
/* We are searching for a similar mesh state when we DO want to
|
||||
* aggregate the state. Thus unique is set to NULL. (default when we
|
||||
* desire aggregation).*/
|
||||
@@ -1245,6 +1256,10 @@ int mesh_state_add_reply(struct mesh_sta
|
||||
@@ -1301,6 +1312,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
if(!r)
|
||||
return 0;
|
||||
r->query_reply = *rep;
|
||||
@@ -3176,11 +3171,11 @@ Index: unbound-1.7.0~rc1/services/mesh.c
|
||||
r->edns = *edns;
|
||||
if(edns->opt_list) {
|
||||
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
|
||||
Index: unbound-1.7.0~rc1/util/config_file.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/config_file.c
|
||||
+++ unbound-1.7.0~rc1/util/config_file.c
|
||||
@@ -1323,6 +1323,8 @@ config_delete(struct config_file* cfg)
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 119b2223..ce43a234 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1434,6 +1434,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_socket_path);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
@@ -3188,12 +3183,12 @@ Index: unbound-1.7.0~rc1/util/config_file.c
|
||||
+ free(cfg->rpz_cstr);
|
||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
#ifdef USE_IPSECMOD
|
||||
Index: unbound-1.7.0~rc1/util/config_file.h
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/config_file.h
|
||||
+++ unbound-1.7.0~rc1/util/config_file.h
|
||||
@@ -431,6 +431,11 @@ struct config_file {
|
||||
config_delstrlist(cfg->python_script);
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index b3ef930a..56173b80 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -494,6 +494,11 @@ struct config_file {
|
||||
/** true to disable DNSSEC lameness check in iterator */
|
||||
int disable_dnssec_lame_check;
|
||||
|
||||
@@ -3205,11 +3200,11 @@ Index: unbound-1.7.0~rc1/util/config_file.h
|
||||
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
|
||||
int ip_ratelimit;
|
||||
/** number of slabs for ip_ratelimit cache */
|
||||
Index: unbound-1.7.0~rc1/util/configlexer.lex
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/configlexer.lex
|
||||
+++ unbound-1.7.0~rc1/util/configlexer.lex
|
||||
@@ -412,6 +412,10 @@ dnstap-log-forwarder-query-messages{COLO
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index a86ddf55..b56bcfb4 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -438,6 +438,10 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
@@ -3220,11 +3215,11 @@ Index: unbound-1.7.0~rc1/util/configlexer.lex
|
||||
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
|
||||
Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/configparser.y
|
||||
+++ unbound-1.7.0~rc1/util/configparser.y
|
||||
@@ -124,6 +124,7 @@ extern struct config_parser_state* cfg_p
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index 10227a2f..cdbcf7cd 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
@@ -3232,7 +3227,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%token VAR_DISABLE_DNSSEC_LAME_CHECK
|
||||
@@ -158,7 +159,7 @@ extern struct config_parser_state* cfg_p
|
||||
@@ -171,7 +172,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -3241,8 +3236,8 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
|
||||
dnscstart contents_dnsc | cachedbstart contents_cachedb |
|
||||
@@ -2384,6 +2385,50 @@ dt_dnstap_log_forwarder_response_message
|
||||
(strcmp($2, "yes")==0);
|
||||
@@ -2726,6 +2727,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
+rpzstart: VAR_RPZ
|
||||
@@ -3269,8 +3264,8 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
+
|
||||
+ OUTYY(("P(rpz_zone:%s)\n", $2));
|
||||
+ old_cstr = cfg_parser->cfg->rpz_cstr;
|
||||
+ asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
|
||||
+ if(!new_cstr)
|
||||
+ if(asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
|
||||
+ else if(!new_cstr)
|
||||
+ yyerror("out of memory");
|
||||
+ free(old_cstr);
|
||||
+ cfg_parser->cfg->rpz_cstr = new_cstr;
|
||||
@@ -3282,8 +3277,8 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
+
|
||||
+ OUTYY(("P(rpz_option:%s)\n", $2));
|
||||
+ old_cstr = cfg_parser->cfg->rpz_cstr;
|
||||
+ asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
|
||||
+ if(!new_cstr)
|
||||
+ if(asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
|
||||
+ else if(!new_cstr)
|
||||
+ yyerror("out of memory");
|
||||
+ free(old_cstr);
|
||||
+ cfg_parser->cfg->rpz_cstr = new_cstr;
|
||||
@@ -3292,11 +3287,11 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
pythonstart: VAR_PYTHON
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
Index: unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/data/msgencode.c
|
||||
+++ unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
@@ -585,6 +585,35 @@ insert_section(struct reply_info* rep, s
|
||||
diff --git a/util/data/msgencode.c b/util/data/msgencode.c
|
||||
index a51a4b9b..475dfce9 100644
|
||||
--- a/util/data/msgencode.c
|
||||
+++ b/util/data/msgencode.c
|
||||
@@ -590,6 +590,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
return RETVAL_OK;
|
||||
}
|
||||
|
||||
@@ -3332,10 +3327,10 @@ Index: unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
/** store query section in wireformat buffer, return RETVAL */
|
||||
static int
|
||||
insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
|
||||
@@ -750,6 +779,19 @@ reply_info_encode(struct query_info* qin
|
||||
return 0;
|
||||
@@ -777,6 +806,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
}
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
}
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ } else if(rep->security == sec_status_rpz_rewritten) {
|
||||
+ /* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */
|
||||
@@ -3352,13 +3347,13 @@ Index: unbound-1.7.0~rc1/util/data/msgencode.c
|
||||
}
|
||||
sldns_buffer_flip(buffer);
|
||||
return 1;
|
||||
Index: unbound-1.7.0~rc1/util/data/packed_rrset.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.c
|
||||
+++ unbound-1.7.0~rc1/util/data/packed_rrset.c
|
||||
@@ -254,6 +254,10 @@ sec_status_to_string(enum sec_status s)
|
||||
case sec_status_indeterminate: return "sec_status_indeterminate";
|
||||
diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
|
||||
index 7b9d5494..e44b2ce5 100644
|
||||
--- a/util/data/packed_rrset.c
|
||||
+++ b/util/data/packed_rrset.c
|
||||
@@ -255,6 +255,10 @@ sec_status_to_string(enum sec_status s)
|
||||
case sec_status_insecure: return "sec_status_insecure";
|
||||
case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
|
||||
case sec_status_secure: return "sec_status_secure";
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ case sec_status_rpz_rewritten: return "sec_status_rpz_rewritten";
|
||||
@@ -3367,12 +3362,12 @@ Index: unbound-1.7.0~rc1/util/data/packed_rrset.c
|
||||
}
|
||||
return "unknown_sec_status_value";
|
||||
}
|
||||
Index: unbound-1.7.0~rc1/util/data/packed_rrset.h
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/data/packed_rrset.h
|
||||
+++ unbound-1.7.0~rc1/util/data/packed_rrset.h
|
||||
@@ -189,7 +189,15 @@ enum sec_status {
|
||||
sec_status_insecure,
|
||||
diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
|
||||
index 3a5335dd..20113217 100644
|
||||
--- a/util/data/packed_rrset.h
|
||||
+++ b/util/data/packed_rrset.h
|
||||
@@ -193,7 +193,15 @@ enum sec_status {
|
||||
sec_status_secure_sentinel_fail,
|
||||
/** SECURE means that the object (RRset or message) validated
|
||||
* according to local policy. */
|
||||
- sec_status_secure
|
||||
@@ -3388,11 +3383,11 @@ Index: unbound-1.7.0~rc1/util/data/packed_rrset.h
|
||||
};
|
||||
|
||||
/**
|
||||
Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/netevent.c
|
||||
+++ unbound-1.7.0~rc1/util/netevent.c
|
||||
@@ -54,6 +54,9 @@
|
||||
diff --git a/util/netevent.c b/util/netevent.c
|
||||
index 980bb8be..d537d288 100644
|
||||
--- a/util/netevent.c
|
||||
+++ b/util/netevent.c
|
||||
@@ -57,6 +57,9 @@
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
@@ -3402,7 +3397,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
|
||||
/* -------- Start of local definitions -------- */
|
||||
/** if CMSG_ALIGN is not defined on this platform, a workaround */
|
||||
@@ -585,6 +588,9 @@ comm_point_udp_ancil_callback(int fd, sh
|
||||
@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
||||
struct cmsghdr* cmsg;
|
||||
#endif /* S_SPLINT_S */
|
||||
|
||||
@@ -3412,7 +3407,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -674,6 +680,9 @@ comm_point_udp_callback(int fd, short ev
|
||||
@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
int i;
|
||||
struct sldns_buffer *buffer;
|
||||
|
||||
@@ -3422,7 +3417,7 @@ Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -717,6 +726,9 @@ comm_point_udp_callback(int fd, short ev
|
||||
@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
(void)comm_point_send_udp_msg(rep.c, buffer,
|
||||
(struct sockaddr*)&rep.addr, rep.addrlen);
|
||||
}
|
||||
@@ -3432,9 +3427,9 @@ Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
|
||||
another UDP port. Note rep.c cannot be reused with TCP fd. */
|
||||
break;
|
||||
@@ -2956,6 +2968,9 @@ comm_point_send_reply(struct comm_reply
|
||||
comm_point_start_listening(repinfo->c, -1,
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
@@ -3184,6 +3196,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
}
|
||||
}
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_end(repinfo);
|
||||
@@ -3442,31 +3437,31 @@ Index: unbound-1.7.0~rc1/util/netevent.c
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2965,6 +2980,9 @@ comm_point_drop_reply(struct comm_reply*
|
||||
@@ -3193,6 +3208,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
||||
return;
|
||||
log_assert(repinfo && repinfo->c);
|
||||
log_assert(repinfo->c);
|
||||
log_assert(repinfo->c->type != comm_tcp_accept);
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_end(repinfo);
|
||||
+#endif
|
||||
if(repinfo->c->type == comm_udp)
|
||||
return;
|
||||
reclaim_tcp_handler(repinfo->c);
|
||||
@@ -2984,6 +3002,9 @@ comm_point_start_listening(struct comm_p
|
||||
if(repinfo->c->tcp_req_info)
|
||||
@@ -3214,6 +3232,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
|
||||
{
|
||||
verbose(VERB_ALGO, "comm point start listening %d",
|
||||
c->fd==-1?newfd:c->fd);
|
||||
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
|
||||
c->fd==-1?newfd:c->fd, msec);
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ rpz_end(&c->repinfo);
|
||||
+#endif
|
||||
if(c->type == comm_tcp_accept && !c->tcp_free) {
|
||||
/* no use to start listening no free slots. */
|
||||
return;
|
||||
Index: unbound-1.7.0~rc1/util/netevent.h
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/util/netevent.h
|
||||
+++ unbound-1.7.0~rc1/util/netevent.h
|
||||
@@ -119,6 +119,10 @@ struct comm_reply {
|
||||
diff --git a/util/netevent.h b/util/netevent.h
|
||||
index d80c72b3..0233292f 100644
|
||||
--- a/util/netevent.h
|
||||
+++ b/util/netevent.h
|
||||
@@ -120,6 +120,10 @@ struct comm_reply {
|
||||
/** return type 0 (none), 4(IP4), 6(IP6) */
|
||||
int srctype;
|
||||
/* DnsCrypt context */
|
||||
@@ -3477,11 +3472,11 @@ Index: unbound-1.7.0~rc1/util/netevent.h
|
||||
#ifdef USE_DNSCRYPT
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES];
|
||||
Index: unbound-1.7.0~rc1/validator/validator.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/validator/validator.c
|
||||
+++ unbound-1.7.0~rc1/validator/validator.c
|
||||
@@ -2688,6 +2688,12 @@ ds_response_to_ke(struct module_qstate*
|
||||
diff --git a/validator/validator.c b/validator/validator.c
|
||||
index 4c560a8e..71de3760 100644
|
||||
--- a/validator/validator.c
|
||||
+++ b/validator/validator.c
|
||||
@@ -2755,6 +2755,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
default:
|
||||
/* NSEC proof did not work, try next */
|
||||
break;
|
||||
@@ -3494,7 +3489,7 @@ Index: unbound-1.7.0~rc1/validator/validator.c
|
||||
}
|
||||
|
||||
sec = nsec3_prove_nods(qstate->env, ve,
|
||||
@@ -2721,6 +2727,12 @@ ds_response_to_ke(struct module_qstate*
|
||||
@@ -2788,6 +2794,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
default:
|
||||
/* NSEC3 proof did not work */
|
||||
break;
|
||||
@@ -3507,4 +3502,3 @@ Index: unbound-1.7.0~rc1/validator/validator.c
|
||||
}
|
||||
|
||||
/* Apparently, no available NSEC/NSEC3 proved NODATA, so
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ int ub_ctx_set_option(ub_ctx*, string, string);
|
||||
int ub_ctx_get_option(ub_ctx*, string, +string*);
|
||||
int ub_ctx_config(ub_ctx*, string);
|
||||
int ub_ctx_set_fwd(ub_ctx*, string);
|
||||
int ub_ctx_set_tls(ub_ctx*, bool(int));
|
||||
int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
|
||||
int ub_ctx_resolvconf(ub_ctx*, string);
|
||||
int ub_ctx_hosts(ub_ctx*, string);
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,148 @@
|
||||
>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
|
||||
Date: Wed, 2 Jan 2019 22:52:51 -0800
|
||||
Subject: [PATCH] Add unbound-fuzzme.
|
||||
|
||||
This is a small program that simply parses a packet provided on stdout,
|
||||
for the purposes of fuzzing.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile.in | 22 ++++++++++++++++++++--
|
||||
smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 59 insertions(+), 2 deletions(-)
|
||||
create mode 100644 smallapp/unbound-fuzzme.c
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index f4527fd8..6163f905 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -24,6 +24,7 @@
|
||||
/unbound-checkconf
|
||||
/unbound-control
|
||||
/unbound-control-setup
|
||||
+/unbound-fuzzme
|
||||
/unbound-host
|
||||
/unbound.h
|
||||
/asynclook
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index af5b10f6..dacf1ab5 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \
|
||||
worker.lo @WIN_DAEMON_OBJ@
|
||||
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
|
||||
+FUZZME_SRC=smallapp/unbound-fuzzme.c
|
||||
+FUZZME_OBJ=unbound-fuzzme.lo
|
||||
+FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
+$(COMPAT_OBJ)
|
||||
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
|
||||
CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
|
||||
CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
|
||||
rsrc_unbound_checkconf.o
|
||||
|
||||
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
+ $(FUZZME_SRC) \
|
||||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
|
||||
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
||||
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
|
||||
@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
|
||||
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
|
||||
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
|
||||
+ $(FUZZME_OBJ) \
|
||||
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
|
||||
$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
|
||||
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
|
||||
@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL
|
||||
|
||||
all: $(COMMON_OBJ) $(ALLTARGET)
|
||||
|
||||
-alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET)
|
||||
+alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET)
|
||||
|
||||
# compat with BSD make, register suffix, and an implicit rule to actualise it.
|
||||
.SUFFIXES: .lo
|
||||
@@ -325,6 +331,9 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
+unbound-fuzzme$(EXEEXT): $(FUZZME_OBJ_LINK) libunbound.la
|
||||
+ $(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
+
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
- rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
|
||||
+ rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
|
||||
rm -f $(ALL_SRC:.c=.lint)
|
||||
rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
+unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \
|
||||
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
|
||||
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
|
||||
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
|
||||
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
|
||||
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c
|
||||
new file mode 100644
|
||||
index 00000000..74ae5204
|
||||
--- /dev/null
|
||||
+++ b/smallapp/unbound-fuzzme.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/*
|
||||
+ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing).
|
||||
+ *
|
||||
+ */
|
||||
+#include "config.h"
|
||||
+#include "util/regional.h"
|
||||
+#include "util/fptr_wlist.h"
|
||||
+#include "sldns/sbuffer.h"
|
||||
+
|
||||
+#define SZ 10000
|
||||
+
|
||||
+int main() {
|
||||
+ char buffer[SZ];
|
||||
+ size_t n_read = fread(buffer, 1, SZ, stdin);
|
||||
+ if (n_read == SZ) {
|
||||
+ printf("input too big\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ sldns_buffer *pkt = sldns_buffer_new(n_read);
|
||||
+ sldns_buffer_init_frm_data(pkt, buffer, n_read);
|
||||
+
|
||||
+ struct regional *region = regional_create();
|
||||
+
|
||||
+ struct msg_parse* prs;
|
||||
+ struct edns_data edns;
|
||||
+ prs = (struct msg_parse*)malloc(sizeof(struct msg_parse));
|
||||
+ if(!prs) {
|
||||
+ printf("out of memory on incoming message\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ memset(prs, 0, sizeof(*prs));
|
||||
+ memset(&edns, 0, sizeof(edns));
|
||||
+ sldns_buffer_set_position(pkt, 0);
|
||||
+ if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) {
|
||||
+ printf("parse error\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -39,13 +39,13 @@ start() {
|
||||
# setup root jail
|
||||
if [ -s /etc/localtime ]; then
|
||||
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
|
||||
if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
|
||||
if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
|
||||
cp -fp /etc/localtime ${rootdir}/etc/localtime
|
||||
fi;
|
||||
fi;
|
||||
if [ -s /etc/resolv.conf ]; then
|
||||
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
|
||||
if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
|
||||
if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
|
||||
cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
|
||||
fi;
|
||||
fi;
|
||||
@@ -54,10 +54,10 @@ start() {
|
||||
[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
|
||||
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
|
||||
fi;
|
||||
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
|
||||
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
|
||||
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
|
||||
[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
|
||||
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
|
||||
[ -e ${rootdir}/dev/urandom ] || touch ${rootdir}/dev/urandom
|
||||
mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
|
||||
fi;
|
||||
|
||||
# if not running, start it up here
|
||||
@@ -78,8 +78,8 @@ stop() {
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
|
||||
umount ${rootdir}/dev/log >/dev/null 2>&1
|
||||
fi;
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
|
||||
umount ${rootdir}/dev/random >/dev/null 2>&1
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
|
||||
umount ${rootdir}/dev/urandom >/dev/null 2>&1
|
||||
fi;
|
||||
return $retval
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ start() {
|
||||
cp -fp /etc/localtime ${rootdir}/etc/localtime
|
||||
fi;
|
||||
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
|
||||
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
|
||||
mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
|
||||
mount --bind -n /var/run/unbound ${rootdir}/var/run/unbound >/dev/null 2>&1;
|
||||
|
||||
# if not running, start it up here
|
||||
@@ -58,7 +58,7 @@ stop() {
|
||||
killproc -p $pidfile unbound
|
||||
retval=$?
|
||||
[ $retval -eq 0 ] && rm -f $lockfile
|
||||
for mountfile in /dev/log /dev/random /etc/localtime /etc/resolv.conf /var/run/unbound
|
||||
for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound
|
||||
do
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then
|
||||
umount ${rootdir}$mountfile >/dev/null 2>&1
|
||||
|
||||
@@ -9,11 +9,11 @@ Wants=nss-lookup.target
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound
|
||||
ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
@@ -21,11 +21,18 @@ PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
|
||||
ReadWritePaths=/run @UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
|
||||
BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
|
||||
BindPaths=-@UNBOUND_PIDFILE@:@UNBOUND_CHROOT_DIR@@UNBOUND_PIDFILE@
|
||||
BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
|
||||
BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
|
||||
RestrictNamespaces=yes
|
||||
LockPersonality=yes
|
||||
RestrictSUIDSGID=yes
|
||||
|
||||
+18
-14
@@ -221,7 +221,9 @@ daemon_init(void)
|
||||
(void)sldns_key_EVP_load_gost_id();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
# ifndef S_SPLINT_S
|
||||
OpenSSL_add_all_algorithms();
|
||||
# endif
|
||||
# else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
@@ -248,8 +250,6 @@ daemon_init(void)
|
||||
/* init timezone info while we are not chrooted yet */
|
||||
tzset();
|
||||
#endif
|
||||
/* open /dev/random if needed */
|
||||
ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67);
|
||||
daemon->need_to_exit = 0;
|
||||
modstack_init(&daemon->mods);
|
||||
if(!(daemon->env = (struct module_env*)calloc(1,
|
||||
@@ -427,9 +427,7 @@ daemon_create_workers(struct daemon* daemon)
|
||||
int* shufport;
|
||||
log_assert(daemon && daemon->cfg);
|
||||
if(!daemon->rand) {
|
||||
unsigned int seed = (unsigned int)time(NULL) ^
|
||||
(unsigned int)getpid() ^ 0x438;
|
||||
daemon->rand = ub_initstate(seed, NULL);
|
||||
daemon->rand = ub_initstate(NULL);
|
||||
if(!daemon->rand)
|
||||
fatal_exit("could not init random generator");
|
||||
hash_set_raninit((uint32_t)ub_random(daemon->rand));
|
||||
@@ -575,6 +573,9 @@ void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
log_assert(daemon);
|
||||
if(!(daemon->views = views_create()))
|
||||
@@ -660,18 +661,20 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if(daemon->cfg->use_systemd)
|
||||
sd_notify(0, "READY=1");
|
||||
ret = sd_notify(0, "READY=1");
|
||||
if(ret <= 0 && getenv("NOTIFY_SOCKET"))
|
||||
fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
|
||||
"access/permission to use the socket presented by systemd.",
|
||||
getenv("NOTIFY_SOCKET"),
|
||||
(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if(daemon->cfg->use_systemd) {
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
}
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
@@ -752,6 +755,7 @@ daemon_delete(struct daemon* daemon)
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
#ifdef HAVE_SSL
|
||||
listen_sslctx_delete_ticket_keys();
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
|
||||
#endif
|
||||
@@ -772,7 +776,7 @@ daemon_delete(struct daemon* daemon)
|
||||
# endif
|
||||
# ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE)
|
||||
ENGINE_cleanup();
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
|
||||
+53
-21
@@ -275,12 +275,13 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* res;
|
||||
struct listen_port* n;
|
||||
int noproto;
|
||||
int noproto = 0;
|
||||
int fd, r;
|
||||
char port[15];
|
||||
snprintf(port, sizeof(port), "%d", nr);
|
||||
port[sizeof(port)-1]=0;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
log_assert(ip);
|
||||
|
||||
if(ip[0] == '/') {
|
||||
/* This looks like a local socket */
|
||||
@@ -498,7 +499,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
goto close_exit;
|
||||
}
|
||||
SSL_set_accept_state(n->ssl);
|
||||
(void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
|
||||
(void)SSL_set_mode(n->ssl, (long)SSL_MODE_AUTO_RETRY);
|
||||
if(!SSL_set_fd(n->ssl, newfd)) {
|
||||
log_crypto_err("could not SSL_set_fd");
|
||||
SSL_free(n->ssl);
|
||||
@@ -673,19 +674,19 @@ static void send_ok(RES* ssl)
|
||||
|
||||
/** do the stop command */
|
||||
static void
|
||||
do_stop(RES* ssl, struct daemon_remote* rc)
|
||||
do_stop(RES* ssl, struct worker* worker)
|
||||
{
|
||||
rc->worker->need_to_exit = 1;
|
||||
comm_base_exit(rc->worker->base);
|
||||
worker->need_to_exit = 1;
|
||||
comm_base_exit(worker->base);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** do the reload command */
|
||||
static void
|
||||
do_reload(RES* ssl, struct daemon_remote* rc)
|
||||
do_reload(RES* ssl, struct worker* worker)
|
||||
{
|
||||
rc->worker->need_to_exit = 0;
|
||||
comm_base_exit(rc->worker->base);
|
||||
worker->need_to_exit = 0;
|
||||
comm_base_exit(worker->base);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
@@ -788,7 +789,8 @@ print_longnum(RES* ssl, const char* desc, size_t x)
|
||||
|
||||
/** print mem stats */
|
||||
static int
|
||||
print_mem(RES* ssl, struct worker* worker, struct daemon* daemon)
|
||||
print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||
struct ub_stats_info* s)
|
||||
{
|
||||
size_t msg, rrset, val, iter, respip;
|
||||
#ifdef CLIENT_SUBNET
|
||||
@@ -846,6 +848,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon)
|
||||
dnscrypt_nonce))
|
||||
return 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(!print_longnum(ssl, "mem.streamwait"SQ,
|
||||
(size_t)s->svr.mem_stream_wait))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -968,6 +973,8 @@ print_ext(RES* ssl, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.qtcp_outgoing)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.tls"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qtls)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.tls.resume"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qtls_resume)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qipv6)) return 0;
|
||||
/* flags */
|
||||
@@ -1063,16 +1070,17 @@ print_ext(RES* ssl, struct ub_stats_info* s)
|
||||
|
||||
/** do the stats command */
|
||||
static void
|
||||
do_stats(RES* ssl, struct daemon_remote* rc, int reset)
|
||||
do_stats(RES* ssl, struct worker* worker, int reset)
|
||||
{
|
||||
struct daemon* daemon = rc->worker->daemon;
|
||||
struct daemon* daemon = worker->daemon;
|
||||
struct ub_stats_info total;
|
||||
struct ub_stats_info s;
|
||||
int i;
|
||||
memset(&total, 0, sizeof(total));
|
||||
log_assert(daemon->num > 0);
|
||||
/* gather all thread statistics in one place */
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
server_stats_obtain(rc->worker, daemon->workers[i], &s, reset);
|
||||
server_stats_obtain(worker, daemon->workers[i], &s, reset);
|
||||
if(!print_thread_stats(ssl, i, &s))
|
||||
return;
|
||||
if(i == 0)
|
||||
@@ -1083,10 +1091,10 @@ do_stats(RES* ssl, struct daemon_remote* rc, int reset)
|
||||
total.mesh_time_median /= (double)daemon->num;
|
||||
if(!print_stats(ssl, "total", &total))
|
||||
return;
|
||||
if(!print_uptime(ssl, rc->worker, reset))
|
||||
if(!print_uptime(ssl, worker, reset))
|
||||
return;
|
||||
if(daemon->cfg->stat_extended) {
|
||||
if(!print_mem(ssl, rc->worker, daemon))
|
||||
if(!print_mem(ssl, worker, daemon, &total))
|
||||
return;
|
||||
if(!print_hist(ssl, &total))
|
||||
return;
|
||||
@@ -1426,6 +1434,28 @@ do_view_data_add(RES* ssl, struct worker* worker, char* arg)
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Add new RR data from stdin to view */
|
||||
static void
|
||||
do_view_datas_add(RES* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct view* v;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
if(!v->local_zones) {
|
||||
if(!(v->local_zones = local_zones_create())){
|
||||
lock_rw_unlock(&v->lock);
|
||||
ssl_printf(ssl,"error out of memory\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
do_datas_add(ssl, v->local_zones);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Remove RR data from view */
|
||||
static void
|
||||
do_view_data_remove(RES* ssl, struct worker* worker, char* arg)
|
||||
@@ -1957,7 +1987,7 @@ parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names)
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
#ifndef HAVE_SSL_SET1_HOST
|
||||
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
if(auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
"ssl library, ignored name for %s", todo);
|
||||
@@ -2454,7 +2484,7 @@ do_auth_zone_reload(RES* ssl, struct worker* worker, char* arg)
|
||||
(void)ssl_printf(ssl, "error no auth-zone %s\n", arg);
|
||||
return;
|
||||
}
|
||||
if(!auth_zone_read_zonefile(z)) {
|
||||
if(!auth_zone_read_zonefile(z, worker->env.cfg)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
(void)ssl_printf(ssl, "error failed to read %s\n", arg);
|
||||
return;
|
||||
@@ -2821,16 +2851,16 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
char* p = skipwhite(cmd);
|
||||
/* compare command */
|
||||
if(cmdcmp(p, "stop", 4)) {
|
||||
do_stop(ssl, rc);
|
||||
do_stop(ssl, worker);
|
||||
return;
|
||||
} else if(cmdcmp(p, "reload", 6)) {
|
||||
do_reload(ssl, rc);
|
||||
do_reload(ssl, worker);
|
||||
return;
|
||||
} else if(cmdcmp(p, "stats_noreset", 13)) {
|
||||
do_stats(ssl, rc, 0);
|
||||
do_stats(ssl, worker, 0);
|
||||
return;
|
||||
} else if(cmdcmp(p, "stats", 5)) {
|
||||
do_stats(ssl, rc, 1);
|
||||
do_stats(ssl, worker, 1);
|
||||
return;
|
||||
} else if(cmdcmp(p, "status", 6)) {
|
||||
do_status(ssl, worker);
|
||||
@@ -2961,6 +2991,8 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
do_view_data_remove(ssl, worker, skipwhite(p+22));
|
||||
} else if(cmdcmp(p, "view_local_data", 15)) {
|
||||
do_view_data_add(ssl, worker, skipwhite(p+15));
|
||||
} else if(cmdcmp(p, "view_local_datas", 16)) {
|
||||
do_view_datas_add(ssl, worker, skipwhite(p+16));
|
||||
} else if(cmdcmp(p, "flush_zone", 10)) {
|
||||
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "flush_type", 10)) {
|
||||
@@ -3093,7 +3125,7 @@ remote_handshake_later(struct daemon_remote* rc, struct rc_state* s,
|
||||
} else {
|
||||
if(r == 0)
|
||||
log_err("remote control connection closed prematurely");
|
||||
log_addr(1, "failed connection from",
|
||||
log_addr(VERB_OPS, "failed connection from",
|
||||
&s->c->repinfo.addr, s->c->repinfo.addrlen);
|
||||
log_crypto_err("remote control failed ssl");
|
||||
clean_point(rc, s);
|
||||
|
||||
+13
-2
@@ -66,6 +66,9 @@
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -74,7 +77,7 @@ stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long l
|
||||
#ifndef S_SPLINT_S
|
||||
(*d_sec) += add_sec;
|
||||
(*d_usec) += add_usec;
|
||||
if((*d_usec) > 1000000) {
|
||||
if((*d_usec) >= 1000000) {
|
||||
(*d_usec) -= 1000000;
|
||||
(*d_sec)++;
|
||||
}
|
||||
@@ -328,6 +331,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
}
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.mem_stream_wait =
|
||||
(long long)tcp_req_info_get_stream_buffer_size();
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
@@ -412,6 +417,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
|
||||
total->svr.qtls += a->svr.qtls;
|
||||
total->svr.qtls_resume += a->svr.qtls_resume;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
@@ -468,8 +474,13 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp) {
|
||||
stats->qtcp++;
|
||||
if(c->ssl != NULL)
|
||||
if(c->ssl != NULL) {
|
||||
stats->qtls++;
|
||||
#ifdef HAVE_SSL
|
||||
if(SSL_session_reused(c->ssl))
|
||||
stats->qtls_resume++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
stats->qipv6++;
|
||||
|
||||
+59
-22
@@ -67,6 +67,7 @@
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifndef S_SPLINT_S
|
||||
/* splint chokes on this system header file */
|
||||
@@ -87,31 +88,20 @@
|
||||
# include "nss.h"
|
||||
#endif
|
||||
|
||||
/** print usage. */
|
||||
static void usage(void)
|
||||
/** print build options. */
|
||||
static void
|
||||
print_build_options(void)
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
time_t t;
|
||||
struct timeval now;
|
||||
struct ub_event_base* base;
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
printf("-c file config file to read instead of %s\n", CONFIGFILE);
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-p do not create a pidfile.\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
printf(" install, remove - manage the services entry\n");
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("Version %s\n\n", PACKAGE_VERSION);
|
||||
printf("Configure line: %s\n", CONFCMDLINE);
|
||||
base = ub_default_event_base(0,&t,&now);
|
||||
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
printf("Linked libs: %s %s (it uses %s), %s\n",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef SSLEAY_VERSION
|
||||
@@ -125,16 +115,42 @@ static void usage(void)
|
||||
"nettle"
|
||||
#endif
|
||||
);
|
||||
printf("linked modules:");
|
||||
printf("Linked modules:");
|
||||
for(m = module_list_avail(); *m; m++)
|
||||
printf(" %s", *m);
|
||||
printf("\n");
|
||||
#ifdef USE_DNSCRYPT
|
||||
printf("DNSCrypt feature available\n");
|
||||
#endif
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
printf("TCP Fastopen feature available\n");
|
||||
#endif
|
||||
ub_event_base_free(base);
|
||||
printf("\nBSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
}
|
||||
|
||||
/** print usage. */
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help.\n");
|
||||
printf("-c file config file to read instead of %s\n", CONFIGFILE);
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-p do not create a pidfile.\n");
|
||||
printf("-v verbose (more times to increase verbosity).\n");
|
||||
printf("-V show version number and build options.\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
printf(" install, remove - manage the services entry\n");
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("\nVersion %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
ub_event_base_free(base);
|
||||
}
|
||||
|
||||
#ifndef unbound_testbound
|
||||
@@ -430,6 +446,24 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
if(!(daemon->listen_sslctx = listen_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
|
||||
if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
|
||||
fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
|
||||
if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
|
||||
fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0) {
|
||||
if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
|
||||
fatal_exit("could not set session ticket SSL_CTX");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert)))
|
||||
@@ -701,7 +735,7 @@ main(int argc, char* argv[])
|
||||
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
|
||||
log_ident_set(log_ident_default);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
cfgfile = optarg;
|
||||
@@ -722,6 +756,9 @@ main(int argc, char* argv[])
|
||||
case 'w':
|
||||
winopt = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
print_build_options();
|
||||
return 0;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
@@ -730,7 +767,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
@@ -750,7 +787,7 @@ main(int argc, char* argv[])
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
#ifndef unbound_testbound
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
+38
-31
@@ -660,10 +660,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!reply_check_cname_chain(qinfo, rep)) {
|
||||
/* cname chain invalid, redo iterator steps */
|
||||
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
||||
bail_out:
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
return 0;
|
||||
goto bail_out;
|
||||
}
|
||||
}
|
||||
/* check security status of the cached answer */
|
||||
@@ -724,8 +721,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(encode_rep != rep)
|
||||
secure = 0; /* if rewritten, it can't be considered "secure" */
|
||||
if(!encode_rep || *alias_rrset) {
|
||||
sldns_buffer_clear(repinfo->c->buffer);
|
||||
sldns_buffer_flip(repinfo->c->buffer);
|
||||
if(!encode_rep)
|
||||
*need_drop = 1;
|
||||
else {
|
||||
@@ -758,20 +753,28 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
/* go and return this buffer to the client */
|
||||
return 1;
|
||||
|
||||
bail_out:
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Reply to client and perform prefetch to keep cache up to date.
|
||||
* If the buffer for the reply is empty, it indicates that only prefetch is
|
||||
* necessary and the reply should be suppressed (because it's dropped or
|
||||
* being deferred). */
|
||||
/** Reply to client and perform prefetch to keep cache up to date. */
|
||||
static void
|
||||
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway)
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
|
||||
{
|
||||
/* first send answer to client to keep its latency
|
||||
* as small as a cachereply */
|
||||
if(sldns_buffer_limit(repinfo->c->buffer) != 0)
|
||||
if(!noreply) {
|
||||
if(repinfo->c->tcp_req_info) {
|
||||
sldns_buffer_copy(
|
||||
repinfo->c->tcp_req_info->spool_buffer,
|
||||
repinfo->c->buffer);
|
||||
}
|
||||
comm_point_send_reply(repinfo);
|
||||
}
|
||||
server_stats_prefetch(&worker->stats, worker);
|
||||
|
||||
/* create the prefetch in the mesh as a normal lookup without
|
||||
@@ -1088,11 +1091,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct ub_packed_rrset_key* alias_rrset = NULL;
|
||||
struct reply_info* partial_rep = NULL;
|
||||
struct query_info* lookup_qinfo = &qinfo;
|
||||
struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
|
||||
struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */
|
||||
struct respip_client_info* cinfo = NULL, cinfo_tmp;
|
||||
memset(&qinfo, 0, sizeof(qinfo));
|
||||
|
||||
if(error != NETEVENT_NOERROR) {
|
||||
if(error != NETEVENT_NOERROR || !repinfo) {
|
||||
/* some bad tcp query DNS formats give these error calls */
|
||||
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
||||
return 0;
|
||||
@@ -1171,16 +1174,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
|
||||
/* check if this query should be dropped based on source ip rate limiting */
|
||||
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
|
||||
*worker->env.now)) {
|
||||
*worker->env.now, c->buffer)) {
|
||||
/* See if we are passed through with slip factor */
|
||||
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
|
||||
ub_random_max(worker->env.rnd,
|
||||
worker->env.cfg->ip_ratelimit_factor) == 1) {
|
||||
worker->env.cfg->ip_ratelimit_factor) == 0) {
|
||||
|
||||
char addrbuf[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen,
|
||||
addrbuf, sizeof(addrbuf));
|
||||
verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
|
||||
verbose(VERB_QUERY, "ip_ratelimit allowed through for ip address %s because of slip in ip_ratelimit_factor",
|
||||
addrbuf);
|
||||
} else {
|
||||
worker->stats.num_queries_ip_ratelimited++;
|
||||
@@ -1208,7 +1211,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(worker->env.cfg->log_queries) {
|
||||
char ip[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||
}
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||
@@ -1476,7 +1479,8 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway);
|
||||
repinfo, leeway,
|
||||
(partial_rep || need_drop));
|
||||
if(!partial_rep) {
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
@@ -1558,9 +1562,19 @@ send_reply_rc:
|
||||
#endif
|
||||
if(worker->env.cfg->log_replies)
|
||||
{
|
||||
struct timeval tv = {0, 0};
|
||||
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
|
||||
tv, 1, c->buffer);
|
||||
struct timeval tv;
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
if(qinfo.local_alias && qinfo.local_alias->rrset &&
|
||||
qinfo.local_alias->rrset->rk.dname) {
|
||||
/* log original qname, before the local alias was
|
||||
* used to resolve that CNAME to something else */
|
||||
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
|
||||
log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
|
||||
tv, 1, c->buffer);
|
||||
} else {
|
||||
log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
|
||||
tv, 1, c->buffer);
|
||||
}
|
||||
}
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(!dnsc_handle_uncurved_request(repinfo)) {
|
||||
@@ -1667,18 +1681,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
return NULL;
|
||||
}
|
||||
/* create random state here to avoid locking trouble in RAND_bytes */
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((unsigned int)worker->thread_num)<<17);
|
||||
/* shift thread_num so it does not match out pid bits */
|
||||
if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
|
||||
seed = 0;
|
||||
if(!(worker->rndstate = ub_initstate(daemon->rand))) {
|
||||
log_err("could not init random numbers.");
|
||||
tube_delete(worker->cmd);
|
||||
free(worker->ports);
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
#ifdef USE_DNSTAP
|
||||
if(daemon->cfg->dnstap) {
|
||||
log_assert(daemon->dtenv != NULL);
|
||||
@@ -1802,8 +1812,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
|
||||
worker->env = *worker->daemon->env;
|
||||
comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
|
||||
if(worker->thread_num == 0)
|
||||
log_set_time(worker->env.now);
|
||||
worker->env.worker = worker;
|
||||
worker->env.worker_base = worker->base;
|
||||
worker->env.send_query = &worker_send_query;
|
||||
@@ -1909,7 +1917,6 @@ worker_delete(struct worker* worker)
|
||||
comm_timer_delete(worker->env.probe_timer);
|
||||
free(worker->ports);
|
||||
if(worker->thread_num == 0) {
|
||||
log_set_time(NULL);
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_desetup_worker(worker);
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
+96
-33
@@ -70,12 +70,9 @@ static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
|
||||
#define MAX_PTR_QNAME_IPV4 30
|
||||
|
||||
/**
|
||||
* Per-query module-specific state. This is usually a dynamically-allocated
|
||||
* structure, but in our case we only need to store one variable describing the
|
||||
* state the query is in. So we repurpose the minfo pointer by storing an
|
||||
* integer in there.
|
||||
* State of DNS64 processing for a query.
|
||||
*/
|
||||
enum dns64_qstate {
|
||||
enum dns64_state {
|
||||
DNS64_INTERNAL_QUERY, /**< Internally-generated query, no DNS64
|
||||
processing. */
|
||||
DNS64_NEW_QUERY, /**< Query for which we're the first module in
|
||||
@@ -84,6 +81,19 @@ enum dns64_qstate {
|
||||
for which this sub-query is finished. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Per-query module-specific state. For the DNS64 module.
|
||||
*/
|
||||
struct dns64_qstate {
|
||||
/** State of the DNS64 module. */
|
||||
enum dns64_state state;
|
||||
/** If the dns64 module started with no_cache bool set in the qstate,
|
||||
* a message to tell it to not modify the cache contents, then this
|
||||
* is true. The dns64 module is then free to modify that flag for
|
||||
* its own purposes.
|
||||
* Otherwise, it is false, the dns64 module was not told to no_cache */
|
||||
int started_no_cache_store;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
@@ -181,16 +191,19 @@ uitoa(unsigned n, char* s)
|
||||
*
|
||||
* \param ipv6 IPv6 address represented as a 128-bit array in big-endian
|
||||
* order.
|
||||
* \param ipv6_len length of the ipv6 byte array.
|
||||
* \param offset Index of the MSB of the IPv4 address embedded in the IPv6
|
||||
* address.
|
||||
*/
|
||||
static uint32_t
|
||||
extract_ipv4(const uint8_t ipv6[16], const int offset)
|
||||
extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
|
||||
{
|
||||
uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
|
||||
uint32_t ipv4;
|
||||
log_assert(ipv6_len == 16); (void)ipv6_len;
|
||||
ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
|
||||
if (offset/8+4 < 16)
|
||||
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
|
||||
return ipv4;
|
||||
@@ -204,22 +217,26 @@ extract_ipv4(const uint8_t ipv6[16], const int offset)
|
||||
* \param ipv4 IPv4 address represented as an unsigned 32-bit number.
|
||||
* \param ptr The result will be written here. Must be large enough, be
|
||||
* careful!
|
||||
* \param nm_len length of the ptr buffer.
|
||||
*
|
||||
* \return The number of characters written.
|
||||
*/
|
||||
static size_t
|
||||
ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
|
||||
ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
|
||||
{
|
||||
static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
|
||||
int i;
|
||||
char* c = ptr;
|
||||
log_assert(nm_len == MAX_PTR_QNAME_IPV4);
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
*c = uitoa((unsigned int)(ipv4 % 256), c + 1);
|
||||
c += *c + 1;
|
||||
log_assert(c < ptr+nm_len);
|
||||
ipv4 /= 256;
|
||||
}
|
||||
|
||||
log_assert(c + sizeof(IPV4_PTR_SUFFIX) <= ptr+nm_len);
|
||||
memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX));
|
||||
|
||||
return c + sizeof(IPV4_PTR_SUFFIX) - ptr;
|
||||
@@ -231,13 +248,15 @@ ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
|
||||
*
|
||||
* \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
|
||||
* \param ipv6 The result will be written here, in network byte order.
|
||||
* \param ipv6_len length of the ipv6 byte array.
|
||||
*
|
||||
* \return 1 on success, 0 on failure.
|
||||
*/
|
||||
static int
|
||||
ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
|
||||
ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len)
|
||||
{
|
||||
int i;
|
||||
log_assert(ipv6_len == 16); (void)ipv6_len;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int x;
|
||||
@@ -265,14 +284,20 @@ ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
|
||||
* Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
|
||||
*
|
||||
* \param prefix_addr DNS64 prefix address.
|
||||
* \param prefix_addr_len length of the prefix_addr buffer.
|
||||
* \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96.
|
||||
* \param a IPv4 address.
|
||||
* \param a_len length of the a buffer.
|
||||
* \param aaaa IPv6 address. The result will be written here.
|
||||
* \param aaaa_len length of the aaaa buffer.
|
||||
*/
|
||||
static void
|
||||
synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
const uint8_t a[4], uint8_t aaaa[16])
|
||||
synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len,
|
||||
int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[],
|
||||
size_t aaaa_len)
|
||||
{
|
||||
log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
|
||||
(void)prefix_addr_len; (void)a_len; (void)aaaa_len;
|
||||
memcpy(aaaa, prefix_addr, 16);
|
||||
aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
|
||||
@@ -437,7 +462,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
/* Convert the PTR query string to an IPv6 address. */
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
|
||||
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr,
|
||||
sizeof(sin6.sin6_addr.s6_addr)))
|
||||
return module_wait_module; /* Let other module handle this. */
|
||||
|
||||
/*
|
||||
@@ -460,7 +486,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
|
||||
return module_error;
|
||||
qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
|
||||
dns64_env->prefix_net), (char*)qinfo.qname);
|
||||
sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net),
|
||||
(char*)qinfo.qname, MAX_PTR_QNAME_IPV4);
|
||||
|
||||
/* Create the new sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
@@ -470,7 +497,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
if (subq) {
|
||||
subq->curmod = id;
|
||||
subq->ext_state[id] = module_state_initial;
|
||||
subq->minfo[id] = NULL;
|
||||
subq->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
return module_wait_subquery;
|
||||
@@ -540,7 +567,8 @@ dns64_always_synth_for_qname(struct module_qstate* qstate, int id)
|
||||
static enum module_ext_state
|
||||
handle_event_pass(struct module_qstate* qstate, int id)
|
||||
{
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
if (iq && iq->state == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
|
||||
&& qstate->qinfo.qname_len == 74
|
||||
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
|
||||
@@ -548,12 +576,12 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
return handle_ipv6_ptr(qstate, id);
|
||||
|
||||
if (qstate->env->cfg->dns64_synthall &&
|
||||
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
iq && iq->state == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
if(dns64_always_synth_for_qname(qstate, id) &&
|
||||
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
iq && iq->state == DNS64_NEW_QUERY
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
|
||||
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
|
||||
@@ -561,7 +589,7 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
}
|
||||
|
||||
/* We are finished when our sub-query is finished. */
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
|
||||
if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
|
||||
return module_finished;
|
||||
|
||||
/* Otherwise, pass request to next module. */
|
||||
@@ -582,6 +610,7 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
static enum module_ext_state
|
||||
handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
/*
|
||||
* In many cases we have nothing special to do. From most to least common:
|
||||
*
|
||||
@@ -593,7 +622,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
* synthesize in (sec 5.1.2 of RFC6147).
|
||||
* - A successful AAAA query with an answer.
|
||||
*/
|
||||
if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
|
||||
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& !(qstate->return_msg &&
|
||||
@@ -604,7 +633,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
|
||||
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& dns64_always_synth_for_qname(qstate, id)) {
|
||||
@@ -614,6 +643,13 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/* Store the response in cache. */
|
||||
if ( (!iq || !iq->started_no_cache_store) &&
|
||||
qstate->return_msg && qstate->return_msg->rep &&
|
||||
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
|
||||
0, 0, 0, NULL, qstate->query_flags))
|
||||
log_err("out of memory");
|
||||
|
||||
/* do nothing */
|
||||
return module_finished;
|
||||
}
|
||||
@@ -634,6 +670,7 @@ void
|
||||
dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
struct dns64_qstate* iq;
|
||||
(void)outbound;
|
||||
verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]),
|
||||
@@ -643,7 +680,12 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
switch(event) {
|
||||
case module_event_new:
|
||||
/* Tag this query as being new and fall through. */
|
||||
qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
|
||||
iq = (struct dns64_qstate*)regional_alloc(
|
||||
qstate->region, sizeof(*iq));
|
||||
qstate->minfo[id] = iq;
|
||||
iq->state = DNS64_NEW_QUERY;
|
||||
iq->started_no_cache_store = qstate->no_cache_store;
|
||||
qstate->no_cache_store = 1;
|
||||
/* fallthrough */
|
||||
case module_event_pass:
|
||||
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
||||
@@ -655,6 +697,11 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
qstate->ext_state[id] = module_finished;
|
||||
break;
|
||||
}
|
||||
if(qstate->ext_state[id] == module_finished) {
|
||||
iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
if(iq && iq->state != DNS64_INTERNAL_QUERY)
|
||||
qstate->no_cache_store = iq->started_no_cache_store;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -710,8 +757,10 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
|
||||
dd->rr_data[i][1] = 16;
|
||||
synthesize_aaaa(
|
||||
((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
|
||||
sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
|
||||
dns64_env->prefix_net, &fd->rr_data[i][2],
|
||||
&dd->rr_data[i][2] );
|
||||
fd->rr_len[i]-2, &dd->rr_data[i][2],
|
||||
dd->rr_len[i]-2);
|
||||
dd->rr_ttl[i] = fd->rr_ttl[i];
|
||||
}
|
||||
|
||||
@@ -867,9 +916,10 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
|
||||
* initial query's domain name.
|
||||
*/
|
||||
answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
|
||||
log_assert(answer);
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
if(answer) {
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -885,6 +935,7 @@ void
|
||||
dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super)
|
||||
{
|
||||
struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id];
|
||||
log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
|
||||
&qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "super is", &super->qinfo);
|
||||
@@ -893,15 +944,27 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
* Signal that the sub-query is finished, no matter whether we are
|
||||
* successful or not. This lets the state machine terminate.
|
||||
*/
|
||||
super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED;
|
||||
if(!super_dq) {
|
||||
super_dq = (struct dns64_qstate*)regional_alloc(super->region,
|
||||
sizeof(*super_dq));
|
||||
if(!super_dq) {
|
||||
log_err("out of memory");
|
||||
super->return_rcode = LDNS_RCODE_SERVFAIL;
|
||||
super->return_msg = NULL;
|
||||
return;
|
||||
}
|
||||
super->minfo[id] = super_dq;
|
||||
memset(super_dq, 0, sizeof(*super_dq));
|
||||
super_dq->started_no_cache_store = super->no_cache_store;
|
||||
}
|
||||
super_dq->state = DNS64_SUBQUERY_FINISHED;
|
||||
|
||||
/* If there is no successful answer, we're done. */
|
||||
if (qstate->return_rcode != LDNS_RCODE_NOERROR
|
||||
|| !qstate->return_msg
|
||||
|| !qstate->return_msg->rep
|
||||
|| !reply_find_answer_rrset(&qstate->qinfo,
|
||||
qstate->return_msg->rep))
|
||||
|| !qstate->return_msg->rep) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Use return code from A query in response to client. */
|
||||
if (super->return_rcode != LDNS_RCODE_NOERROR)
|
||||
@@ -916,7 +979,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
}
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if (!super->no_cache_store &&
|
||||
if ( (!super_dq || !super_dq->started_no_cache_store) &&
|
||||
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
log_err("out of memory");
|
||||
|
||||
+21
-28
@@ -316,15 +316,15 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
} else {
|
||||
if (crypto_box_beforenm(nmkey,
|
||||
query_header->publickey,
|
||||
cert->keypair->crypt_secretkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Cache the shared secret we just computed.
|
||||
dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
|
||||
} else {
|
||||
if (crypto_box_beforenm(nmkey,
|
||||
query_header->publickey,
|
||||
cert->keypair->crypt_secretkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Cache the shared secret we just computed.
|
||||
dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
|
||||
key,
|
||||
hash,
|
||||
nmkey);
|
||||
@@ -442,20 +442,7 @@ dnscrypt_hrtime(void)
|
||||
static void
|
||||
add_server_nonce(uint8_t *nonce)
|
||||
{
|
||||
uint64_t ts;
|
||||
uint64_t tsn;
|
||||
uint32_t suffix;
|
||||
ts = dnscrypt_hrtime();
|
||||
// TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
|
||||
// unclear if we really need it, so skipping it for now.
|
||||
tsn = (ts << 10) | (randombytes_random() & 0x3ff);
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
tsn =
|
||||
(((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
|
||||
#endif
|
||||
memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
|
||||
suffix = randombytes_random();
|
||||
memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
|
||||
randombytes_buf(nonce + crypto_box_HALF_NONCEBYTES, 8/*tsn*/+4/*suffix*/);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -732,6 +719,11 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) {
|
||||
/* guard against integer overflow in rrlen calculation */
|
||||
verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial);
|
||||
continue;
|
||||
}
|
||||
rrlen = strlen(dnscenv->provider_name) +
|
||||
strlen(ttl_class_type) +
|
||||
4 * sizeof(struct SignedCert) + // worst case scenario
|
||||
@@ -746,9 +738,9 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
|
||||
for(j=0; j<sizeof(struct SignedCert); j++) {
|
||||
int c = (int)*((const uint8_t *) cert + j);
|
||||
if (isprint(c) && c != '"' && c != '\\') {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
|
||||
snprintf(rr + strlen(rr), rrlen - strlen(rr), "%c", c);
|
||||
} else {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
|
||||
snprintf(rr + strlen(rr), rrlen - strlen(rr), "\\%03d", c);
|
||||
}
|
||||
}
|
||||
verbose(VERB_OPS,
|
||||
@@ -757,7 +749,7 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
|
||||
" to local-data to config: %s",
|
||||
serial, rr
|
||||
);
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
|
||||
snprintf(rr + strlen(rr), rrlen - strlen(rr), "\"");
|
||||
cfg_strlist_insert(&cfg->local_data, strdup(rr));
|
||||
free(rr);
|
||||
}
|
||||
@@ -772,12 +764,13 @@ key_get_es_version(uint8_t version[2])
|
||||
const char *name;
|
||||
};
|
||||
|
||||
const int num_versions = 2;
|
||||
struct es_version es_versions[] = {
|
||||
{{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
|
||||
{{0x00, 0x02}, "X25519-XChacha20Poly1305"},
|
||||
};
|
||||
int i;
|
||||
for(i=0; i < (int)sizeof(es_versions); i++){
|
||||
for(i=0; i < num_versions; i++){
|
||||
if(es_versions[i].es_version[0] == version[0] &&
|
||||
es_versions[i].es_version[1] == version[1]){
|
||||
return es_versions[i].name;
|
||||
@@ -876,7 +869,7 @@ sodium_misuse_handler(void)
|
||||
fatal_exit(
|
||||
"dnscrypt: libsodium could not be initialized, this typically"
|
||||
" happens when no good source of entropy is found. If you run"
|
||||
" unbound in a chroot, make sure /dev/random is available. See"
|
||||
" unbound in a chroot, make sure /dev/urandom is available. See"
|
||||
" https://www.unbound.net/documentation/unbound.conf.html");
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
@@ -118,6 +122,18 @@ dt_msg_init(const struct dt_env *env,
|
||||
}
|
||||
}
|
||||
|
||||
/* check that the socket file can be opened and exists, print error if not */
|
||||
static void
|
||||
check_socket_file(const char* socket_path)
|
||||
{
|
||||
struct stat statbuf;
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
if(stat(socket_path, &statbuf) < 0) {
|
||||
log_warn("could not open dnstap-socket-path: %s, %s",
|
||||
socket_path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
{
|
||||
@@ -134,6 +150,7 @@ dt_create(const char *socket_path, unsigned num_workers)
|
||||
socket_path);
|
||||
log_assert(socket_path != NULL);
|
||||
log_assert(num_workers > 0);
|
||||
check_socket_file(socket_path);
|
||||
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
|
||||
+942
-2
@@ -1,5 +1,945 @@
|
||||
6 December 2019: Wouter
|
||||
- Fix ipsecmod compile.
|
||||
- Fix Makefile.in for ipset module compile, from Adi Prasaja.
|
||||
|
||||
5 December 2019: Wouter
|
||||
- unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
|
||||
replacements for unbound-fuzzme.c that gets created after applying
|
||||
the contrib/unbound-fuzzme.patch. They are contributed by
|
||||
Eric Sesterhenn from X41 D-Sec.
|
||||
- tag for 1.9.6rc1.
|
||||
|
||||
4 December 2019: Wouter
|
||||
- Fix lock type for memory purify log lock deletion.
|
||||
- Fix testbound for alloccheck runs, memory purify and lock checks.
|
||||
- update contrib/fastrpz.patch to apply more cleanly.
|
||||
- Fix Make Test Fails when Configured With --enable-alloc-nonregional,
|
||||
reported by X41 D-Sec.
|
||||
|
||||
3 December 2019: Wouter
|
||||
- Merge pull request #124 from rmetrich: Changed log lock
|
||||
from 'quick' to 'basic' because this is an I/O lock.
|
||||
- Fix text around serial arithmatic used for RRSIG times to refer
|
||||
to correct RFC number.
|
||||
- Fix Assert Causing DoS in synth_cname(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix similar code in auth_zone synth cname to add the extra checks.
|
||||
- Fix Assert Causing DoS in dname_pkt_copy(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix OOB Read in sldns_wire2str_dname_scan(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Out of Bounds Write in sldns_str2wire_str_buf(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Out of Bounds Write in sldns_b64_pton(),
|
||||
fixed by check in sldns_str2wire_int16_data_buf(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Insufficient Handling of Compressed Names in dname_pkt_copy(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Out of Bound Write Compressed Names in rdata_copy(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Hang in sldns_wire2str_pkt_scan(),
|
||||
reported by X41 D-Sec.
|
||||
This further lowers the max to 256.
|
||||
- Fix snprintf() supports the n-specifier,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Bad Indentation, in dnscrypt.c,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Client NONCE Generation used for Server NONCE,
|
||||
reported by X41 D-Sec.
|
||||
- Fix compile error in dnscrypt.
|
||||
- Fix _vfixed not Used, removed from sbuffer code,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Hardcoded Constant, reported by X41 D-Sec.
|
||||
- make depend
|
||||
|
||||
2 December 2019: Wouter
|
||||
- Merge pull request #122 from he32: In tcp_callback_writer(),
|
||||
don't disable time-out when changing to read.
|
||||
|
||||
22 November 2019: George
|
||||
- Fix compiler warnings.
|
||||
|
||||
22 November 2019: Wouter
|
||||
- Fix dname loop maximum, reported by Eric Sesterhenn from X41 D-Sec.
|
||||
- Add make distclean that removes everything configure produced,
|
||||
and make maintainer-clean that removes bison and flex output.
|
||||
|
||||
20 November 2019: Wouter
|
||||
- Fix Out of Bounds Read in rrinternal_get_owner(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Race Condition in autr_tp_create(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Shared Memory World Writeable,
|
||||
reported by X41 D-Sec.
|
||||
- Adjust unbound-control to make stats_shm a read only operation.
|
||||
- Fix Weak Entropy Used For Nettle,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Randomness Error not Handled Properly,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Out-of-Bounds Read in dname_valid(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Config Injection in create_unbound_ad_servers.sh,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Local Memory Leak in cachedb_init(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Integer Underflow in Regional Allocator,
|
||||
reported by X41 D-Sec.
|
||||
- Upgrade compat/getentropy_linux.c to version 1.46 from OpenBSD.
|
||||
- Synchronize compat/getentropy_win.c with version 1.5 from
|
||||
OpenBSD, no changes but makes the file, comments, identical.
|
||||
- Upgrade compat/getentropy_solaris.c to version 1.13 from OpenBSD.
|
||||
- Upgrade compat/getentropy_osx.c to version 1.12 from OpenBSD.
|
||||
- Changes to compat/getentropy files for,
|
||||
no link to openssl if using nettle, and hence config.h for
|
||||
HAVE_NETTLE variable.
|
||||
compat definition of MAP_ANON, for older systems.
|
||||
ifdef stdint.h inclusion for older systems.
|
||||
ifdef sha2.h inclusion for older systems.
|
||||
- Fixed Compat Code Diverging from Upstream, reported by X41 D-Sec.
|
||||
- Fix compile with --enable-alloc-checks, reported by X41 D-Sec.
|
||||
- Fix Terminating Quotes not Written, reported by X41 D-Sec.
|
||||
- Fix Useless memset() in validator, reported by X41 D-Sec.
|
||||
- Fix Unrequired Checks, reported by X41 D-Sec.
|
||||
- Fix Enum Name not Used, reported by X41 D-Sec.
|
||||
- Fix NULL Pointer Dereference via Control Port,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Bad Randomness in Seed, reported by X41 D-Sec.
|
||||
- Fix python examples/calc.py for eval, reported by X41 D-Sec.
|
||||
- Fix comments for doxygen in dns64.
|
||||
|
||||
19 November 2019: Wouter
|
||||
- Fix CVE-2019-18934, shell execution in ipsecmod.
|
||||
- 1.9.5 is 1.9.4 with bugfix, trunk is 1.9.6 in development.
|
||||
- Fix authzone printout buffer length check.
|
||||
- Fixes to please lint checks.
|
||||
- Fix Integer Overflow in Regional Allocator,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Unchecked NULL Pointer in dns64_inform_super()
|
||||
and ipsecmod_new(), reported by X41 D-Sec.
|
||||
- Fix Out-of-bounds Read in rr_comment_dnskey(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Integer Overflows in Size Calculations,
|
||||
reported by X41 D-Sec.
|
||||
- Fix Integer Overflow to Buffer Overflow in
|
||||
sldns_str2wire_dname_buf_origin(), reported by X41 D-Sec.
|
||||
- Fix Out of Bounds Read in sldns_str2wire_dname(),
|
||||
reported by X41 D-Sec.
|
||||
- Fix Out of Bounds Write in sldns_bget_token_par(),
|
||||
reported by X41 D-Sec.
|
||||
|
||||
18 November 2019: Wouter
|
||||
- In unbound-host use separate variable for get_option to please
|
||||
code checkers.
|
||||
- update to bison output of 3.4.1 in code repository.
|
||||
- Provide a prototype for compat malloc to remove compile warning.
|
||||
- Portable grep usage for reuseport configure test.
|
||||
- Check return type of HMAC_Init_ex for openssl 0.9.8.
|
||||
- gitignore .source tempfile used for compatible make.
|
||||
|
||||
13 November 2019: Wouter
|
||||
- iana portlist updated.
|
||||
- contrib/fastrpz.patch updated to apply for current code.
|
||||
- fixes for splint cleanliness, long vs int in SSL set_mode.
|
||||
|
||||
11 November 2019: Wouter
|
||||
- Fix #109: check number of arguments for stdin-pipes in
|
||||
unbound-control and fail if too many arguments.
|
||||
- Merge #102 from jrtc27: Add getentropy emulation for FreeBSD.
|
||||
|
||||
24 October 2019: Wouter
|
||||
- Fix #99: Memory leak in ub_ctx (event_base will never be freed).
|
||||
|
||||
23 October 2019: George
|
||||
- Add new configure option `--enable-fully-static` to enable full static
|
||||
build if requested; in relation to #91.
|
||||
|
||||
23 October 2019: Wouter
|
||||
- Merge #97: manpage: Add missing word on unbound.conf,
|
||||
from Erethon.
|
||||
|
||||
22 October 2019: Wouter
|
||||
- drop-tld.diff: adds option drop-tld: yesno that drops 2 label
|
||||
queries, to stop random floods. Apply with
|
||||
patch -p1 < contrib/drop-tld.diff and compile.
|
||||
From Saksham Manchanda (Secure64). Please note that we think this
|
||||
will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
|
||||
lookups for downstream clients.
|
||||
|
||||
7 October 2019: Wouter
|
||||
- Add doxygen comments to unbound-anchor source address code, in #86.
|
||||
|
||||
3 October 2019: Wouter
|
||||
- Merge #90 from vcunat: fix build with nettle-3.5.
|
||||
- Merge 1.9.4 release with fix for vulnerability CVE-2019-16866.
|
||||
- Continue with development of 1.9.5.
|
||||
- Merge #86 from psquarejho: Added -b source address option to
|
||||
smallapp/unbound-anchor.c, from Lukas Wunner.
|
||||
|
||||
26 September 2019: Wouter
|
||||
- Merge #87 from hardfalcon: Fix contrib/unbound.service.in,
|
||||
Drop CAP_KILL, use + prefix for ExecReload= instead.
|
||||
|
||||
25 September 2019: Wouter
|
||||
- The unbound.conf includes are sorted ascending, for include
|
||||
statements with a '*' from glob.
|
||||
|
||||
23 September 2019: Wouter
|
||||
- Merge #85 for #84 from sam-lunt: Add kill capability to systemd
|
||||
service file to fix that systemctl reload fails.
|
||||
|
||||
20 September 2019: Wouter
|
||||
- Merge #82 from hardfalcon: Downgrade CAP_NET_ADMIN to CAP_NET_RAW
|
||||
in unbound.service.
|
||||
- Merge #81 from Maryse47: Consistently use /dev/urandom instead
|
||||
of /dev/random in scripts and docs.
|
||||
- Merge #83 from Maryse47: contrib/unbound.service.in: do not fork
|
||||
into the background.
|
||||
|
||||
19 September 2019: Wouter
|
||||
- Fix #78: Memory leak in outside_network.c.
|
||||
- Merge pull request #76 from Maryse47: Improvements and fixes for
|
||||
systemd unbound.service.
|
||||
- oss-fuzz badge on README.md.
|
||||
- Fix fix for #78 to also free service callback struct.
|
||||
- Fix for oss-fuzz build warning.
|
||||
- Fix wrong response ttl for prepended short CNAME ttls, this would
|
||||
create a wrong zero_ttl response count with serve-expired enabled.
|
||||
- Merge #80 from stasic: Improve wording in man page.
|
||||
|
||||
11 September 2019: Wouter
|
||||
- Use explicit bzero for wiping clear buffer of hash in cachedb,
|
||||
reported by Eric Sesterhenn from X41 D-Sec.
|
||||
|
||||
9 September 2019: Wouter
|
||||
- Fix #72: configure --with-syslog-facility=LOCAL0-7 with default
|
||||
LOG_DAEMON (as before) can set the syslog facility that the server
|
||||
uses to log messages.
|
||||
|
||||
4 September 2019: Wouter
|
||||
- Fix #71: fix openssl error squelch commit compilation error.
|
||||
|
||||
3 September 2019: Wouter
|
||||
- squelch DNS over TLS errors 'ssl handshake failed crypto error'
|
||||
on low verbosity, they show on verbosity 3 (query details), because
|
||||
there is a high volume and the operator cannot do anything for the
|
||||
remote failure. Specifically filters the high volume errors.
|
||||
|
||||
2 September 2019: Wouter
|
||||
- ipset module #28: log that an address is added, when verbosity high.
|
||||
- ipset: refactor long routine into three smaller ones.
|
||||
- updated Makefile dependencies.
|
||||
|
||||
23 August 2019: Wouter
|
||||
- Fix contrib/fastrpz.patch asprintf return value checks.
|
||||
|
||||
22 August 2019: Wouter
|
||||
- Fix that pkg-config is setup before --enable-systemd needs it.
|
||||
- 1.9.3rc2 release candidate tag. And this became the 1.9.3 release.
|
||||
Master is 1.9.4 in development.
|
||||
|
||||
21 August 2019: Wouter
|
||||
- Fix log_dns_msg to log irrespective of minimal responses config.
|
||||
|
||||
19 August 2019: Ralph
|
||||
- Document limitation of pidfile removal outside of chroot directory.
|
||||
|
||||
16 August 2019: Wouter
|
||||
- Fix unittest valgrind false positive uninitialised value report,
|
||||
where if gcc 9.1.1 uses -O2 (but not -O1) then valgrind 3.15.0
|
||||
issues an uninitialised value for the token buffer at the str2wire.c
|
||||
rrinternal_get_owner() strcmp with the '@' value. Rewritten to use
|
||||
straight character comparisons removes the false positive. Also
|
||||
valgrinds --expensive-definedness-checks=yes can stop this false
|
||||
positive.
|
||||
- Please doxygen's parser for "@" occurrence in doxygen comment.
|
||||
- Fixup contrib/fastrpz.patch
|
||||
- Remove warning about unknown cast-function-type warning pragma.
|
||||
|
||||
15 August 2019: Wouter
|
||||
- iana portlist updated.
|
||||
- Fix autotrust temp file uniqueness windows compile.
|
||||
- avoid warning about upcast on 32bit systems for autotrust.
|
||||
- escape commandline contents for -V.
|
||||
- Fix character buffer size in ub_ctx_hosts.
|
||||
- 1.9.3rc1 release candidate tag.
|
||||
- Option -V prints if TCP fastopen is available.
|
||||
|
||||
14 August 2019: George
|
||||
- Fix #59, when compiled with systemd support check that we can properly
|
||||
communicate with systemd through the `NOTIFY_SOCKET`.
|
||||
|
||||
14 August 2019: Wouter
|
||||
- Generate configlexer with newer flex.
|
||||
- Fix warning for unused variable for compilation without systemd.
|
||||
|
||||
12 August 2019: George
|
||||
- Introduce `-V` option to print the version number and build options.
|
||||
Previously reported build options like linked libs and linked modules
|
||||
are now moved from `-h` to `-V` as well for consistency.
|
||||
- PACKAGE_BUGREPORT now also includes link to GitHub issues.
|
||||
|
||||
1 August 2019: Wouter
|
||||
- For #52 #53, second context does not close logfile override.
|
||||
- Fix #52 #53, fix for example fail program.
|
||||
- Fix to return after failed auth zone http chunk write.
|
||||
- Fix to remove unused test for task_probe existance.
|
||||
- Fix to timeval_add for remaining second in microseconds.
|
||||
- Check repinfo in worker_handle_request, if null, drop it.
|
||||
|
||||
29 July 2019: Wouter
|
||||
- Add verbose log message when auth zone file is written, at level 4.
|
||||
- Add hex print of trust anchor pointer to trust anchor file temp
|
||||
name to make it unique, for libunbound created multiple contexts.
|
||||
|
||||
23 July 2019: Wouter
|
||||
- Fix question section mismatch in local zone redirect.
|
||||
|
||||
19 July 2019: Wouter
|
||||
- Fix #49: Set no renegotiation on the SSL context to stop client
|
||||
session renegotiation.
|
||||
|
||||
12 July 2019: Wouter
|
||||
- Fix #48: Unbound returns additional records on NODATA response,
|
||||
if minimal-responses is enabled, also the additional for negative
|
||||
responses is removed.
|
||||
|
||||
9 July 2019: Ralph
|
||||
- Fix in respip addrtree selection. Absence of addr_tree_init_parents()
|
||||
call made it impossible to go up the tree when the matching netmask is
|
||||
too specific.
|
||||
|
||||
5 July 2019: Ralph
|
||||
- Fix for possible assertion failure when answering respip CNAME from
|
||||
cache.
|
||||
|
||||
25 June 2019: Wouter
|
||||
- For #45, check that 127.0.0.1 and ::1 are not used in unbound.conf
|
||||
when do-not-query-localhost is turned on, or at default on,
|
||||
unbound-checkconf prints a warning if it is found in forward-addr or
|
||||
stub-addr statements.
|
||||
|
||||
24 June 2019: Wouter
|
||||
- Fix memleak in unit test, reported from the clang 8.0 static analyzer.
|
||||
|
||||
18 June 2019: Wouter
|
||||
- PR #28: IPSet module, by Kevin Chou. Created a module to support
|
||||
the ipset that could add the domain's ip to a list easily.
|
||||
Needs libmnl, and --enable-ipset and config it, doc/README.ipset.md.
|
||||
- Fix to omit RRSIGs from addition to the ipset.
|
||||
- Fix to make unbound-control with ipset, remove unused variable,
|
||||
use unsigned type because of comparison, and assign null instead
|
||||
of compare with it. Remade lex and yacc output.
|
||||
- make depend
|
||||
- Added documentation to the ipset files (for doxygen output).
|
||||
- Merge PR #6: Python module: support multiple instances
|
||||
- Merge PR #5: Python module: define constant MODULE_RESTART_NEXT
|
||||
- Merge PR #4: Python module: assign something useful to the
|
||||
per-query data store 'qdata'
|
||||
- Fix python dict reference and double free in config.
|
||||
|
||||
17 June 2019: Wouter
|
||||
- Master contains version 1.9.3 in development.
|
||||
- Fix #39: In libunbound, leftover logfile is close()d unpredictably.
|
||||
- Fix for #24: Fix abort due to scan of auth zone masters using old
|
||||
address from previous scan.
|
||||
|
||||
12 June 2019: Wouter
|
||||
- Fix another spoolbuf storage code point, in prefetch.
|
||||
- 1.9.2rc3 release candidate tag. Which became the 1.9.2 release
|
||||
on 17 June 2019.
|
||||
|
||||
11 June 2019: Wouter
|
||||
- Fix that fixes the Fix that spoolbuf is not used to store tcp
|
||||
pipelined response between mesh send and callback end, this fixes
|
||||
error cases that did not use the correct spoolbuf.
|
||||
- 1.9.2rc2 release candidate tag.
|
||||
|
||||
6 June 2019: Wouter
|
||||
- 1.9.2rc1 release candidate tag.
|
||||
|
||||
4 June 2019: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
29 May 2019: Wouter
|
||||
- Fix to guard _OPENBSD_SOURCE from redefinition.
|
||||
|
||||
28 May 2019: Wouter
|
||||
- Fix to define _OPENBSD_SOURCE to get reallocarray on NetBSD.
|
||||
- gitignore config.h.in~.
|
||||
|
||||
27 May 2019: Wouter
|
||||
- Fix double file close in tcp pipelined response code.
|
||||
|
||||
24 May 2019: Wouter
|
||||
- Fix that spoolbuf is not used to store tcp pipelined response
|
||||
between mesh send and callback end.
|
||||
|
||||
20 May 2019: Wouter
|
||||
- Note that so-reuseport at extreme load is better turned off,
|
||||
otherwise queries are not distributed evenly, on Linux 4.4.x.
|
||||
|
||||
16 May 2019: Wouter
|
||||
- Fix #31: swig 4.0 and python module.
|
||||
|
||||
13 May 2019: Wouter
|
||||
- Squelch log messages from tcp send about connection reset by peer.
|
||||
They can be enabled with verbosity at higher values for diagnosing
|
||||
network connectivity issues.
|
||||
- Attempt to fix malformed tcp response.
|
||||
|
||||
9 May 2019: Wouter
|
||||
- Revert fix for oss-fuzz, error is in that build script that
|
||||
unconditionally includes .o files detected by configure, also
|
||||
when the machine architecture uses different LIBOBJS files.
|
||||
|
||||
8 May 2019: Wouter
|
||||
- Attempt to fix build failure in oss-fuzz because of reallocarray.
|
||||
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14648.
|
||||
Does not omit compile flags from commandline.
|
||||
|
||||
7 May 2019: Wouter
|
||||
- Fix edns-subnet locks, in error cases the lock was not unlocked.
|
||||
- Fix doxygen output error on readme markdown vignettes.
|
||||
|
||||
6 May 2019: Wouter
|
||||
- Fix #29: Solaris 11.3 and missing symbols be64toh, htobe64.
|
||||
- Fix #30: AddressSanitizer finding in lookup3.c. This sets the
|
||||
hash function to use a slower but better auditable code that does
|
||||
not read beyond array boundaries. This makes code better security
|
||||
checkable, and is better for security. It is fixed to be slower,
|
||||
but not read outside of the array.
|
||||
|
||||
2 May 2019: Wouter
|
||||
- contrib/fastrpz.patch updated for code changes, and with git diff.
|
||||
- Fix .gitignore, add pythonmod and dnstap generated files.
|
||||
And unit test generated files, and generated doc files.
|
||||
|
||||
1 May 2019: Wouter
|
||||
- Update makedist for git.
|
||||
- Nicer travis output for clang analysis.
|
||||
- PR #16: XoT support, AXFR over TLS, turn it on with
|
||||
master: <ip>#<authname> in unbound.conf. This uses TLS to
|
||||
download the AXFR (or IXFR).
|
||||
|
||||
25 April 2019: Wouter
|
||||
- Fix wrong query name in local zone redirect answers with a CNAME,
|
||||
the copy of the local alias is in unpacked form.
|
||||
|
||||
18 April 2019: Ralph
|
||||
- Scrub RRs from answer section when reusing NXDOMAIN message for
|
||||
subdomain answers.
|
||||
- For harden-below-nxdomain: do not consider a name to be non-exitent
|
||||
when message contains a CNAME record.
|
||||
|
||||
18 April 2019: Wouter
|
||||
- travis build file.
|
||||
|
||||
16 April 2019: Wouter
|
||||
- Better braces in if statement in TCP fastopen code.
|
||||
- iana portlist updated.
|
||||
|
||||
15 April 2019: Wouter
|
||||
- Fix tls write event for read state change to re-call SSL_write and
|
||||
not resume the TLS handshake.
|
||||
|
||||
11 April 2019: George
|
||||
- Update python documentation for init_standard().
|
||||
- Typos.
|
||||
|
||||
11 April 2019: Wouter
|
||||
- Fix that auth zone uses correct network type for sockets for
|
||||
SOA serial probes. This fixes that probes fail because earlier
|
||||
probe addresses are unreachable.
|
||||
- Fix that auth zone fails over to next master for timeout in tcp.
|
||||
- Squelch SSL read and write connection reset by peer and broken pipe
|
||||
messages. Verbosity 2 and higher enables them.
|
||||
|
||||
8 April 2019: Wouter
|
||||
- Fix to use event_assign with libevent for thread-safety.
|
||||
- verbose information about auth zone lookup process, also lookup
|
||||
start, timeout and fail.
|
||||
- Fix #17: Add python module example from Jan Janak, that is a
|
||||
plugin for the Unbound DNS resolver to resolve DNS records in
|
||||
multicast DNS [RFC 6762] via Avahi. The plugin communicates
|
||||
with Avahi via DBus. The comment section at the beginning of
|
||||
the file contains detailed documentation.
|
||||
- Fix to wipe ssl ticket keys from memory with explicit_bzero,
|
||||
if available.
|
||||
|
||||
5 April 2019: Wouter
|
||||
- Fix to reinit event structure for accepted TCP (and TLS) sockets.
|
||||
|
||||
4 April 2019: Wouter
|
||||
- Fix spelling error in log output for event method.
|
||||
|
||||
3 April 2019: Wouter
|
||||
- Move goto label in answer_from_cache to the end of the function
|
||||
where it is more visible.
|
||||
- Fix auth-zone NSEC3 response for wildcard nodata answers,
|
||||
include the closest encloser in the answer.
|
||||
|
||||
2 April 2019: Wouter
|
||||
- Fix auth-zone NSEC3 response for empty nonterminals with exact
|
||||
match nsec3 records.
|
||||
- Fix for out of bounds integers, thanks to OSTIF audit. It is in
|
||||
allocation debug code.
|
||||
- Fix for auth zone nsec3 ent fix for wildcard nodata.
|
||||
|
||||
25 March 2019: Wouter
|
||||
- Fix that tls-session-ticket-keys: "" on its own in unbound.conf
|
||||
disables the tls session ticker key calls into the OpenSSL API.
|
||||
- Fix crash if tls-servic-pem not filled in when necessary.
|
||||
|
||||
21 March 2019: Wouter
|
||||
- Fix #4240: Fix whitespace cleanup in example.conf.
|
||||
|
||||
19 March 2019: Wouter
|
||||
- add type CAA to libpyunbound (accessing libunbound from python).
|
||||
|
||||
18 March 2019: Wouter
|
||||
- Add log message, at verbosity 4, that says the query is encrypted
|
||||
with TLS, if that is enabled for the query.
|
||||
- Fix #4239: set NOTIMPL when deny-any is enabled, for RFC8482.
|
||||
|
||||
7 March 2019: Wouter
|
||||
- Fix for #4233: guard use of NDEBUG, so that it can be passed in
|
||||
CFLAGS into configure.
|
||||
|
||||
5 March 2019: Wouter
|
||||
- Tag release 1.9.1rc1. Which became 1.9.1 on 12 March 2019. Trunk
|
||||
has 1.9.2 in development.
|
||||
|
||||
1 March 2019: Wouter
|
||||
- output forwarder log in ssl_req_order test.
|
||||
|
||||
28 February 2019: Wouter
|
||||
- Remove memory leak on pythonmod python2 script file init.
|
||||
- Remove swig gcc8 python function cast warnings, they are ignored.
|
||||
- Print correct module that failed when module-config is wrong.
|
||||
|
||||
27 February 2019: Wouter
|
||||
- Fix #4229: Unbound man pages lack information, about access-control
|
||||
order and local zone tags, and elements in views.
|
||||
- Fix #14: contrib/unbound.init: Fix wrong comparison judgment
|
||||
before copying.
|
||||
- Fix for python module on Windows, fix fopen.
|
||||
|
||||
25 February 2019: Wouter
|
||||
- Fix #4227: pair event del and add for libevent for tcp_req_info.
|
||||
|
||||
21 February 2019: Wouter
|
||||
- Fix the error for unknown module in module-config is understandable,
|
||||
and explains it was not compiled in and where to see the list.
|
||||
- In example.conf explain where to put cachedb module in module-config.
|
||||
- In man page and example config explain that most modules have to
|
||||
be listed at the start of module-config.
|
||||
|
||||
20 February 2019: Wouter
|
||||
- Fix pythonmod include and sockaddr_un ifdefs for compile on
|
||||
Windows, and for libunbound.
|
||||
|
||||
18 February 2019: Wouter
|
||||
- Print query name with ip_ratelimit exceeded log lines.
|
||||
- Spaces instead of tabs in that log message.
|
||||
- Print query name and IP address when domain rate limit exceeded.
|
||||
|
||||
14 February 2019: Wouter
|
||||
- Fix capsforid canonical sort qsort callback.
|
||||
|
||||
11 February 2019: Wouter
|
||||
- Note default for module-config in man page.
|
||||
- Fix recursion lame test for qname minimisation asked queries,
|
||||
that were not present in the set of prepared answers.
|
||||
- Fix #13: Remove left-over requirements on OpenSSL >= 1.1.0 for
|
||||
cert name matching, from man page.
|
||||
- make depend, with newer gcc, nicer layout.
|
||||
|
||||
7 February 2019: Wouter
|
||||
- Fix #4206: OpenSSL 1.0.2 hostname verification for FreeBSD 11.2.
|
||||
- Fix that qname minimisation does not skip a label when missing
|
||||
nameserver targets need to be fetched.
|
||||
- Fix #4225: clients seem to erroneously receive no answer with
|
||||
DNS-over-TLS and qname-minimisation.
|
||||
|
||||
4 February 2019: Wouter
|
||||
- Fix that log-replies prints the correct name for local-alias
|
||||
names, for names that have a CNAME in local-data configuration.
|
||||
It logs the original query name, not the target of the CNAME.
|
||||
- Add local-zone type inform_redirect, which logs like type inform,
|
||||
and redirects like type redirect.
|
||||
- Perform canonical sort for 0x20 capsforid compare of replies,
|
||||
this sorts rrsets in the authority and additional section before
|
||||
comparison, so that out of order rrsets do not cause failure.
|
||||
|
||||
31 January 2019: Wouter
|
||||
- Set ub_ctx_set_tls call signature in ltrace config file for
|
||||
libunbound in contrib/libunbound.so.conf.
|
||||
- improve documentation for tls-service-key and forward-first.
|
||||
- #10: fixed pkg-config operations, PKG_PROG_PKG_CONFIG moved out of
|
||||
conditional section, fixes systemd builds, from Enrico Scholz.
|
||||
- #9: For openssl 1.0.2 use the CRYPTO_THREADID locking callbacks,
|
||||
still supports the set_id_callback previous API. And for 1.1.0
|
||||
no locking callbacks are needed.
|
||||
- #8: Fix OpenSSL without ENGINE support compilation.
|
||||
- Wipe TLS session key data from memory on exit.
|
||||
|
||||
30 January 2019: Ralph
|
||||
- Fix case in which query timeout can result in marking delegation
|
||||
as edns_lame_known.
|
||||
|
||||
29 January 2019: Wouter
|
||||
- Fix spelling of tls-ciphers in example.conf.in.
|
||||
- Fix #4224: auth_xfr_notify.rpl test broken due to typo
|
||||
- Fix locking for libunbound context setup with broken port config.
|
||||
|
||||
28 January 2019: Wouter
|
||||
- ub_ctx_set_tls call for libunbound that enables DoT for the machines
|
||||
set with ub_ctx_set_fwd. Patch from Florian Obser.
|
||||
- Set build system for added call in the libunbound API.
|
||||
- List example config for root zone copy locally hosted with auth-zone
|
||||
as suggested from draft-ietf-dnsop-7706-bis-02. But with updated
|
||||
B root address.
|
||||
- set version to 1.9.0 for release. And this was released with the
|
||||
spelling for tls-ciphers fix as 1.9.0 on Feb 5. Trunk has 1.9.1 in
|
||||
development.
|
||||
|
||||
25 January 2019: Wouter
|
||||
- Fix that tcp for auth zone and outgoing does not remove and
|
||||
then gets the ssl read again applied to the deleted commpoint.
|
||||
- updated contrib/fastrpz.patch to cleanly diff.
|
||||
- no lock when threads disabled in tcp request buffer count.
|
||||
- remove compile warnings from libnettle compile.
|
||||
- output of newer lex 2.6.1 and bison 3.0.5.
|
||||
|
||||
24 January 2019: Wouter
|
||||
- Newer aclocal and libtoolize used for generating configure scripts,
|
||||
aclocal 1.16.1 and libtoolize 2.4.6.
|
||||
- Fix unit test for python 3.7 new keyword 'async'.
|
||||
- clang analysis fixes, assert arc4random buffer in init,
|
||||
no check for already checked delegation pointer in iterator,
|
||||
in testcode check for NULL packet matches, in perf do not copy
|
||||
from NULL start list when growing capacity. Adjust host and file
|
||||
only when present in test header read to please checker. In
|
||||
testcode for unknown macro operand give zero result. Initialise the
|
||||
passed argv array in test code. In test code add EDNS data
|
||||
segment copy only when nonempty.
|
||||
- Patch from Florian Obser fixes some compiler warnings:
|
||||
include mini_event.h to have a prototype for mini_ev_cmp
|
||||
include edns.h to have a prototype for apply_edns_options
|
||||
sldns_wire2str_edns_keepalive_print is only called in the wire2str,
|
||||
module declare it static to get rid of compiler warning:
|
||||
no previous prototype for function
|
||||
infra_find_ip_ratedata() is only called in the infra module,
|
||||
declare it static to get rid of compiler warning:
|
||||
no previous prototype for function
|
||||
do not shadow local variable buf in authzone
|
||||
auth_chunks_delete and az_nsec3_findnode are only called in the
|
||||
authzone module, declare them static to get rid of compiler warning:
|
||||
no previous prototype for function...
|
||||
copy_rrset() is only called in the respip module, declare it
|
||||
static to get rid of compiler warning:
|
||||
no previous prototype for function 'copy_rrset'
|
||||
no need for another variable "r"; gets rid of compiler warning:
|
||||
declaration shadows a local variable in libunbound.c
|
||||
no need for another variable "ns"; gets rid of compiler warning:
|
||||
declaration shadows a local variable in iterator.c
|
||||
- Moved includes and make depend.
|
||||
|
||||
23 January 2019: Wouter
|
||||
- Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
|
||||
options for unbound.conf.
|
||||
- Fixes for the patch, and man page entry.
|
||||
- Fix configure to detect SSL_CTX_set_ciphersuites, for better
|
||||
library compatibility when compiling.
|
||||
- Patch for TLS session resumption from Manabu Sonoda,
|
||||
enable with tls-session-ticket-keys in unbound.conf.
|
||||
- Fixes for patch (includes, declarations, warnings). Free at end
|
||||
and keep config options in order read from file to keep the first
|
||||
one as the first one.
|
||||
- Fix for IXFR fallback to reset counter when IXFR does not timeout.
|
||||
|
||||
22 January 2019: Wouter
|
||||
- Fix space calculation for tcp req buffer size.
|
||||
- Doc for stream-wait-size and unit test.
|
||||
- unbound-control stats has mem.streamwait that counts TCP and TLS
|
||||
waiting result buffers.
|
||||
- Fix for #4219: secondaries not updated after serial change, unbound
|
||||
falls back to AXFR after IXFR gives several timeout failures.
|
||||
- Fix that auth zone after IXFR fallback tries the same master.
|
||||
|
||||
21 January 2019: Wouter
|
||||
- Fix tcp idle timeout test, for difference in the tcp reply code.
|
||||
- Unit test for tcp request reorder and timeouts.
|
||||
- Unit tests for ssl out of order processing.
|
||||
- Fix that multiple dns fragments can be carried in one TLS frame.
|
||||
- Add stream-wait-size: 4m config option to limit the maximum
|
||||
memory used by waiting tcp and tls stream replies. This avoids
|
||||
a denial of service where these replies use up all of the memory.
|
||||
|
||||
17 January 2019: Wouter
|
||||
- For caps-for-id fallback, use the whitelist to avoid timeout
|
||||
starting a fallback sequence for it.
|
||||
- increase mesh max activation count for capsforid long fetches.
|
||||
|
||||
16 January 2019: Ralph
|
||||
- Get ready for the DNS flag day: remove EDNS lame procedure, do not
|
||||
re-query without EDNS after timeout.
|
||||
|
||||
15 January 2019: Wouter
|
||||
- In the out of order processing, reset byte count for (potential)
|
||||
partial read.
|
||||
- Review fixes in out of order processing.
|
||||
|
||||
14 January 2019: Wouter
|
||||
- streamtcp option -a send queries consecutively and prints answers
|
||||
as they arrive.
|
||||
- Fix for out of order processing administration quit cleanup.
|
||||
- unit test for tcp out of order processing.
|
||||
|
||||
11 January 2019: Wouter
|
||||
- Initial commit for out-of-order processing for TCP and TLS.
|
||||
|
||||
9 January 2019: Wouter
|
||||
- Log query name for looping module errors.
|
||||
|
||||
8 January 2019: Wouter
|
||||
- Fix syntax in comment of local alias processing.
|
||||
- Fix NSEC3 record that is returned in wildcard replies from
|
||||
auth-zone zones with NSEC3 and wildcards.
|
||||
|
||||
7 January 2019: Wouter
|
||||
- On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
|
||||
and server tcp fastopen is enabled at compile time.
|
||||
- Document interaction between the tls-upstream option in the server
|
||||
section and forward-tls-upstream option in the forward-zone sections.
|
||||
- Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
|
||||
the patch adds a program used for fuzzing.
|
||||
|
||||
12 December 2018: Wouter
|
||||
- Fix for crash in dns64 module if response is null.
|
||||
|
||||
10 December 2018: Wouter
|
||||
- Fix config parser memory leaks.
|
||||
- ip-ratelimit-factor of 1 allows all traffic through, instead of the
|
||||
previous blocking everything.
|
||||
- Fix for FreeBSD port make with dnscrypt and dnstap enabled.
|
||||
- Fix #4206: support openssl 1.0.2 for TLS hostname verification,
|
||||
alongside the 1.1.0 and later support that is already there.
|
||||
- Fixup openssl 1.0.2 compile
|
||||
|
||||
6 December 2018: Wouter
|
||||
- Fix dns64 allocation in wrong region for returned internal queries.
|
||||
|
||||
3 December 2018: Wouter
|
||||
- Fix icon, no ragged edges and nicer resolutions available, for eg.
|
||||
Win 7 and Windows 10 display.
|
||||
- cache-max-ttl also defines upperbound of initial TTL in response.
|
||||
|
||||
30 November 2018: Wouter
|
||||
- Patch for typo in unbound.conf man page.
|
||||
- log-tag-queryreply: yes in unbound.conf tags the log-queries and
|
||||
log-replies in the log file for easier log filter maintenance.
|
||||
|
||||
29 November 2018: Wouter
|
||||
- iana portlist updated.
|
||||
- Fix chroot auth-zone fix to remove chroot prefix.
|
||||
- tag for 1.8.2rc1, which became 1.8.2 on 4 dec 2018, with icon
|
||||
updated. Trunk contains 1.8.3 in development.
|
||||
Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec.
|
||||
Trunk then became 1.8.4 in development.
|
||||
- Fix that unbound-checkconf does not complains if the config file
|
||||
is not placed inside the chroot.
|
||||
- Refuse to start with no ports.
|
||||
- Remove clang analysis warnings.
|
||||
|
||||
28 November 2018: Wouter
|
||||
- Fix leak in chroot fix for auth-zone.
|
||||
- Fix clang analysis for outside directory build test.
|
||||
|
||||
27 November 2018: Wouter
|
||||
- Fix DNS64 to not store intermediate results in cache, this avoids
|
||||
other threads from picking up the wrong data. The module restores
|
||||
the previous no_cache_store setting when the the module is finished.
|
||||
- Fix #4208: 'stub-no-cache' and 'forward-no-cache' not work.
|
||||
- New and better fix for Fix #4193: Fix that prefetch failure does
|
||||
not overwrite valid cache entry with SERVFAIL.
|
||||
- auth-zone give SERVFAIL when expired, fallback activates when
|
||||
expired, and this is documented in the man page.
|
||||
- stat count SERVFAIL downstream auth-zone queries for expired zones.
|
||||
- Put new logos into windows installer.
|
||||
- Fix windows compile for new rrset roundrobin fix.
|
||||
- Update contrib fastrpz patch for latest release.
|
||||
|
||||
26 November 2018: Wouter
|
||||
- Fix to not set GLOB_NOSORT so the unbound.conf include: files are
|
||||
sorted and in a predictable order.
|
||||
- Fix #4193: Fix that prefetch failure does not overwrite valid cache
|
||||
entry with SERVFAIL.
|
||||
- Add unbound-control view_local_datas command, like local_datas.
|
||||
- Fix that unbound-control can send file for view_local_datas.
|
||||
|
||||
22 November 2018: Wouter
|
||||
- With ./configure --with-pyunbound --with-pythonmodule
|
||||
PYTHON_VERSION=3.6 or with 2.7 unbound can compile and unit tests
|
||||
succeed for the python module.
|
||||
- pythonmod logs the python error and traceback on failure.
|
||||
- ignore debug python module for test in doxygen output.
|
||||
- review fixes for python module.
|
||||
- Fix #4209: Crash in libunbound when called from getdns.
|
||||
- auth zone zonefiles can be in a chroot, the chroot directory
|
||||
components are removed before use.
|
||||
- Fix that empty zonefile means the zonefile is not set and not used.
|
||||
- make depend.
|
||||
|
||||
21 November 2018: Wouter
|
||||
- Scrub NS records from NODATA responses as well.
|
||||
|
||||
20 November 2018: Wouter
|
||||
- Scrub NS records from NXDOMAIN responses to stop fragmentation
|
||||
poisoning of the cache.
|
||||
- Add patch from Jan Vcelak for pythonmod,
|
||||
add sockaddr_storage getters, add support for query callbacks,
|
||||
allow raw address access via comm_reply and update API documentation.
|
||||
- Removed compile warnings in pythonmod sockaddr routines.
|
||||
|
||||
19 November 2018: Wouter
|
||||
- Support SO_REUSEPORT_LB in FreeBSD 12 with the so-reuseport: yes
|
||||
option in unbound.conf.
|
||||
|
||||
6 November 2018: Ralph
|
||||
- Bugfix min-client-subnet-ipv6
|
||||
|
||||
25 October 2018: Ralph
|
||||
- Add min-client-subnet-ipv6 and min-client-subnet-ipv4 options.
|
||||
|
||||
25 October 2018: Wouter
|
||||
- Fix #4191: NXDOMAIN vs SERVFAIL during dns64 PTR query.
|
||||
- Fix #4190: Please create a "ANY" deny option, adds the option
|
||||
deny-any: yes in unbound.conf. This responds with an empty message
|
||||
to queries of type ANY.
|
||||
- Fix #4141: More randomness to rrset-roundrobin.
|
||||
- Fix #4132: Openness/closeness of RANGE intervals in rpl files.
|
||||
- Fix #4126: RTT_band too low on VSAT links with 600+ms latency,
|
||||
adds the option unknown-server-time-limit to unbound.conf that
|
||||
can be increased to avoid the problem.
|
||||
- remade makefile dependencies.
|
||||
- Fix #4152: Logs shows wrong time when using log-time-ascii: yes.
|
||||
|
||||
24 October 2018: Ralph
|
||||
- Add markdel function to ECS slabhash.
|
||||
- Limit ECS scope returned to client to the scope used for caching.
|
||||
- Make lint like previous #4154 fix.
|
||||
|
||||
22 October 2018: Wouter
|
||||
- Fix #4192: unbound-control-setup generates keys not readable by
|
||||
group.
|
||||
- check that the dnstap socket file can be opened and exists, print
|
||||
error if not.
|
||||
- Fix #4154: make ECS_MAX_TREESIZE configurable, with
|
||||
the max-ecs-tree-size-ipv4 and max-ecs-tree-size-ipv6 options.
|
||||
|
||||
22 October 2018: Ralph
|
||||
- Change fast-server-num default to 3.
|
||||
|
||||
8 October 2018: Ralph
|
||||
- Add fast-server-permil and fast-server-num options.
|
||||
- Deprecate low-rtt and low-rtt-permil options.
|
||||
|
||||
8 October 2018: Wouter
|
||||
- Squelch log of failed to tcp initiate after TCP Fastopen failure.
|
||||
|
||||
5 October 2018: Wouter
|
||||
- Squelch EADDRNOTAVAIL errors when the interface goes away,
|
||||
this omits 'can't assign requested address' errors unless
|
||||
verbosity is set to a high value.
|
||||
- Set default for so-reuseport to no for FreeBSD. It is enabled
|
||||
by default for Linux and DragonFlyBSD. The setting can
|
||||
be configured in unbound.conf to override the default.
|
||||
- iana port update.
|
||||
|
||||
2 October 2018: Wouter
|
||||
- updated contrib/fastrpz.patch to apply for this version
|
||||
- dnscrypt.c removed sizeof to get array bounds.
|
||||
- Fix testlock code to set noreturn on error routine.
|
||||
- Remove unused variable from contrib fastrpz/rpz.c and
|
||||
remove unused diagnostic pragmas that themselves generate warnings
|
||||
- clang analyze test is used only when assertions are enabled.
|
||||
|
||||
1 October 2018: Wouter
|
||||
- tag for release 1.8.1rc1. Became release 1.8.1 on 8 oct, with
|
||||
fastrpz.patch fix included. Trunk has 1.8.2 in development.
|
||||
|
||||
27 September 2018: Wouter
|
||||
- Fix #4188: IPv6 forwarders without ipv6 result in SERVFAIL, fixes
|
||||
qname minimisation with a forwarder when connectivity has issues
|
||||
from rejecting responses.
|
||||
|
||||
25 September 2018: Wouter
|
||||
- Perform TLS SNI indication of the host that is being contacted
|
||||
for DNS over TLS service. It sets the configured tls auth name.
|
||||
This is useful for hosts that apart from the DNS over TLS services
|
||||
also provide other (web) services.
|
||||
- Fix #4149: Add SSL cleanup for tcp timeout.
|
||||
|
||||
17 September 2018: Wouter
|
||||
- Fix compile on Mac for unbound, provide explicit_bzero when libc
|
||||
does not have it.
|
||||
- Fix unbound for openssl in FIPS mode, it uses the digests with
|
||||
the EVP call contexts.
|
||||
- Fix that with harden-below-nxdomain and qname minisation enabled
|
||||
some iterator states for nonresponsive domains can get into a
|
||||
state where they waited for an empty list.
|
||||
- Stop UDP to TCP failover after timeouts that causes the ping count
|
||||
to be reset by the TCP time measurement (that exists for TLS),
|
||||
because that causes the UDP part to not be measured as timeout.
|
||||
- Fix #4156: Fix systemd service manager state change notification.
|
||||
|
||||
13 September 2018: Wouter
|
||||
- Fix seed for random backup code to use explicit zero when wiped.
|
||||
- exit log routine is annotated as noreturn function.
|
||||
- free memory leaks in config strlist and str2list insert functions.
|
||||
- do not move unused argv variable after getopt.
|
||||
- Remove unused if clause in testcode.
|
||||
- in testcode, free async ids, initialise array, and check for null
|
||||
pointer during test of the test. And use exit for return to note
|
||||
irregular program stop.
|
||||
- Free memory leak in config strlist append.
|
||||
- make sure nsec3 comparison salt is initialized.
|
||||
- unit test has clang analysis.
|
||||
- remove unused variable assignment from iterator scrub routine.
|
||||
- check for null in delegation point during iterator refetch
|
||||
in forward zone.
|
||||
- neater pointer cast in libunbound context quit routine.
|
||||
- initialize statistics totals for printout.
|
||||
- in authzone check that node exists before adding rrset.
|
||||
- in unbound-anchor, use readwrite memory BIO.
|
||||
- assertion in autotrust that packed rrset is formed correctly.
|
||||
- Fix memory leak when message parse fails partway through copy.
|
||||
- remove unused udpsize assignment in message encode.
|
||||
- nicer bio free code in unbound-anchor.
|
||||
- annotate exit functions with noreturn in unbound-control.
|
||||
|
||||
11 September 2018: Wouter
|
||||
- Fixed unused return value warnings in contrib/fastrpz.patch for
|
||||
asprintf.
|
||||
- Fix to squelch respip warning in unit test, it is printed at
|
||||
higher verbosity settings.
|
||||
- Fix spelling errors.
|
||||
- Fix initialisation in remote.c
|
||||
|
||||
10 September 2018: Wouter
|
||||
- 1.8.1 in svn trunk. (changes from 4,5,.. sep apply).
|
||||
- iana port update.
|
||||
|
||||
5 September 2018: Wouter
|
||||
- Fix spelling error in header, from getdns commit by Andreas Gelmini.
|
||||
|
||||
4 September 2018: Ralph
|
||||
- More explicitly mention the type of ratelimit when applying
|
||||
ip-ratelimit.
|
||||
|
||||
4 September 2018: Wouter
|
||||
- Tag for 1.8.0rc1 release.
|
||||
- Tag for 1.8.0rc1 release, became 1.8.0 release on 10 Sep 2018.
|
||||
|
||||
31 August 2018: Wouter
|
||||
- Disable minimal-responses in subnet unit tests.
|
||||
@@ -1856,7 +2796,7 @@
|
||||
compatibility with cisco dns guard. This lowers false positives.
|
||||
|
||||
18 April 2016: Wouter
|
||||
- Fix some malformed reponses to edns queries get fallback to nonedns.
|
||||
- Fix some malformed responses to edns queries get fallback to nonedns.
|
||||
|
||||
15 April 2016: Wouter
|
||||
- cachedb module event handling design.
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ o If you are not receiving the correct source IP address on replies (e.g.
|
||||
the config file is an alternative. The interface-automatic option uses
|
||||
non portable socket options, Linux and FreeBSD should work fine.
|
||||
o The warning 'openssl has no entropy, seeding with time', with chroot
|
||||
enabled, may be solved with a symbolic link to /dev/random from <chrootdir>.
|
||||
enabled, may be solved with a symbolic link to /dev/urandom from <chrootdir>.
|
||||
o On Solaris 5.10 some libtool packages from repositories do not work with
|
||||
gcc, showing errors gcc: unrecognized option `-KPIC'
|
||||
To solve this do ./configure libtool=./libtool [your options...].
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
## Created a module to support the ipset that could add the domain's ip to a list easily.
|
||||
|
||||
### Purposes:
|
||||
* In my case, I can't access the facebook, twitter, youtube and thousands web site for some reason. VPN is a solution. But the internet too slow whether all traffics pass through the vpn.
|
||||
So, I set up a transparent proxy to proxy the traffic which has been blocked only.
|
||||
At the final step, I need to install a dns service which would work with ipset well to launch the system.
|
||||
I did some research for this. Unfortunately, Unbound, My favorite dns service doesn't support ipset yet. So, I decided to implement it by my self and contribute the patch. It's good for me and the community.
|
||||
```
|
||||
# unbound.conf
|
||||
server:
|
||||
...
|
||||
local-zone: "facebook.com" ipset
|
||||
local-zone: "twitter.com" ipset
|
||||
local-zone: "instagram.com" ipset
|
||||
more social website
|
||||
|
||||
ipset:
|
||||
name-v4: "gfwlist"
|
||||
```
|
||||
```
|
||||
# iptables
|
||||
iptables -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
|
||||
iptables -A OUTPUT -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-ports 10800
|
||||
```
|
||||
|
||||
* This patch could work with iptables rules to batch block the IPs.
|
||||
```
|
||||
# unbound.conf
|
||||
server:
|
||||
...
|
||||
local-zone: "facebook.com" ipset
|
||||
local-zone: "twitter.com" ipset
|
||||
local-zone: "instagram.com" ipset
|
||||
more social website
|
||||
|
||||
ipset:
|
||||
name-v4: "blacklist"
|
||||
name-v6: "blacklist6"
|
||||
```
|
||||
```
|
||||
# iptables
|
||||
iptables -A INPUT -m set --set blacklist src -j DROP
|
||||
ip6tables -A INPUT -m set --set blacklist6 src -j DROP
|
||||
```
|
||||
|
||||
### Notes:
|
||||
* To enable this module the root privileges is required.
|
||||
* Please create a set with ipset command first. eg. **ipset -N blacklist iphash**
|
||||
|
||||
### How to use:
|
||||
```
|
||||
./configure --enable-ipset
|
||||
make && make install
|
||||
```
|
||||
|
||||
### Configuration:
|
||||
```
|
||||
# unbound.conf
|
||||
server:
|
||||
...
|
||||
local-zone: "example.com" ipset
|
||||
|
||||
ipset:
|
||||
name-v4: "blacklist"
|
||||
```
|
||||
@@ -29,7 +29,7 @@ o support OPT record placement on recv anywhere in the additional section.
|
||||
o add local-file: config with authority features.
|
||||
o (option) to make local-data answers be secure for libunbound (default=no)
|
||||
o (option) to make chroot: copy all needed files into jail (or make jail)
|
||||
perhaps also print reminder to link /dev/random and sysloghack.
|
||||
perhaps also print reminder to link /dev/urandom and sysloghack.
|
||||
o overhaul outside-network servicedquery to merge with udpwait and tcpwait,
|
||||
to make timers in servicedquery independent of udpwait queues.
|
||||
o check into rebinding ports for efficiency, configure time test.
|
||||
|
||||
+73
-15
@@ -103,6 +103,7 @@ server:
|
||||
# so-sndbuf: 0
|
||||
|
||||
# use SO_REUSEPORT to distribute queries over threads.
|
||||
# at extreme load it could be better to turn it off to distribute even.
|
||||
# so-reuseport: yes
|
||||
|
||||
# use IP_TRANSPARENT so the interface: addresses can be non-local
|
||||
@@ -123,6 +124,9 @@ server:
|
||||
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
|
||||
# max-udp-size: 4096
|
||||
|
||||
# max memory to use for stream(tcp and tls) waiting result buffers.
|
||||
# stream-wait-size: 4m
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
@@ -145,6 +149,10 @@ server:
|
||||
# msec to wait before close of port on timeout UDP. 0 disables.
|
||||
# delay-close: 0
|
||||
|
||||
# msec for waiting for an unknown server to reply. Increase if you
|
||||
# are behind a slow satellite link, to eg. 1128.
|
||||
# unknown-server-time-limit: 376
|
||||
|
||||
# the amount of memory to use for the RRset cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
# rrset-cache-size: 4m
|
||||
@@ -278,7 +286,7 @@ server:
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy).
|
||||
# Additionally, unbound may need to access /dev/urandom (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
@@ -318,6 +326,10 @@ server:
|
||||
# timetoresolve, fromcache and responsesize.
|
||||
# log-replies: no
|
||||
|
||||
# log with tag 'query' and 'reply' instead of 'info' for
|
||||
# filtering log-queries and log-replies from the log.
|
||||
# log-tag-queryreply: no
|
||||
|
||||
# log the local-zone actions, like local-zone type inform is enabled
|
||||
# also for the other local zone types.
|
||||
# log-local-actions: no
|
||||
@@ -449,6 +461,9 @@ server:
|
||||
# if yes, perform key lookups adjacent to normal lookups.
|
||||
# prefetch-key: no
|
||||
|
||||
# deny queries of type ANY with an empty response.
|
||||
# deny-any: no
|
||||
|
||||
# if yes, Unbound rotates RRSet order in response.
|
||||
# rrset-roundrobin: no
|
||||
|
||||
@@ -461,6 +476,9 @@ server:
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. Syntax: "[dns64] [validator] iterator"
|
||||
# most modules have to be listed at the beginning of the line,
|
||||
# except cachedb(just before iterator), and python (at the beginning,
|
||||
# or, just before the iterator).
|
||||
# module-config: "validator iterator"
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
@@ -475,7 +493,7 @@ server:
|
||||
|
||||
# trust anchor signaling sends a RFC8145 key tag query after priming.
|
||||
# trust-anchor-signaling: yes
|
||||
|
||||
|
||||
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
|
||||
# root-key-sentinel: yes
|
||||
|
||||
@@ -636,6 +654,9 @@ server:
|
||||
# local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
|
||||
# And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
|
||||
|
||||
# Add example.com into ipset
|
||||
# local-zone: "example.com" ipset
|
||||
|
||||
# If unbound is running service for the local host then it is useful
|
||||
# to perform lan-wide lookups to the upstream, and unblock the
|
||||
# long list of local-zones above. If this unbound is a dns server
|
||||
@@ -659,6 +680,7 @@ server:
|
||||
# o typetransparent resolves normally for other types and other names
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o inform_redirect redirects queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
@@ -701,6 +723,19 @@ server:
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
|
||||
# cipher setting for TLSv1.2
|
||||
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
|
||||
# cipher setting for TLSv1.3
|
||||
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
|
||||
|
||||
# Add the secret file for TLS Session Ticket.
|
||||
# Secret file must be 80 bytes of random data.
|
||||
# First key use to encrypt and decrypt TLS session tickets.
|
||||
# Other keys use to decrypt only.
|
||||
# requires restart to take effect.
|
||||
# tls-session-ticket-keys: "path/to/secret_file1"
|
||||
# tls-session-ticket-keys: "path/to/secret_file2"
|
||||
|
||||
# request upstream over TLS (with plain DNS inside the TLS stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# tls-upstream: no
|
||||
@@ -757,11 +792,11 @@ server:
|
||||
# Limit the number of connections simultaneous from a netblock
|
||||
# tcp-connection-limit: 192.0.2.0/24 12
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-permil: 0
|
||||
# select from the fastest servers this many times out of 1000. 0 means
|
||||
# the fast server select is disabled. prefetches are not sped up.
|
||||
# fast-server-permil: 0
|
||||
# the number of servers that will be used in the fast server selection.
|
||||
# fast-server-num: 3
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
@@ -795,6 +830,8 @@ server:
|
||||
# Python config section. To enable:
|
||||
# o use --with-pythonmodule to configure before compiling.
|
||||
# o list python in the module-config string (above) to enable.
|
||||
# It can be at the start, it gets validated results, or just before
|
||||
# the iterator and process before DNSSEC validation.
|
||||
# o and give a python-script to run.
|
||||
python:
|
||||
# Script file to load
|
||||
@@ -879,15 +916,25 @@ remote-control:
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# master: 199.9.14.201 # b.root-servers.net
|
||||
# master: 192.33.4.12 # c.root-servers.net
|
||||
# master: 199.7.91.13 # d.root-servers.net
|
||||
# master: 192.5.5.241 # f.root-servers.net
|
||||
# master: 192.112.36.4 # g.root-servers.net
|
||||
# master: 193.0.14.129 # k.root-servers.net
|
||||
# master: 192.0.47.132 # xfr.cjr.dns.icann.org
|
||||
# master: 192.0.32.132 # xfr.lax.dns.icann.org
|
||||
# master: 2001:500:200::b # b.root-servers.net
|
||||
# master: 2001:500:2::c # c.root-servers.net
|
||||
# master: 2001:500:2d::d # d.root-servers.net
|
||||
# master: 2001:500:2f::f # f.root-servers.net
|
||||
# master: 2001:500:12::d0d # g.root-servers.net
|
||||
# master: 2001:7fd::1 # k.root-servers.net
|
||||
# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
|
||||
# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
|
||||
# fallback-enabled: yes
|
||||
# for-downstream: no
|
||||
# for-upstream: yes
|
||||
# fallback-enabled: yes
|
||||
# master: b.root-servers.net
|
||||
# master: c.root-servers.net
|
||||
# master: e.root-servers.net
|
||||
# master: f.root-servers.net
|
||||
# master: g.root-servers.net
|
||||
# master: k.root-servers.net
|
||||
# auth-zone:
|
||||
# name: "example.org"
|
||||
# for-downstream: yes
|
||||
@@ -935,7 +982,7 @@ remote-control:
|
||||
# Enable external backend DB as auxiliary cache. Specify the backend name
|
||||
# (default is "testframe", which has no use other than for debugging and
|
||||
# testing) and backend-specific options. The 'cachedb' module must be
|
||||
# included in module-config.
|
||||
# included in module-config, just before the iterator module.
|
||||
# cachedb:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
@@ -948,3 +995,14 @@ remote-control:
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
|
||||
# IPSet
|
||||
# Add specify domain into set via ipset.
|
||||
# Note: To enable ipset needs run unbound as root user.
|
||||
# ipset:
|
||||
# # set name for ip v4 addresses
|
||||
# name-v4: "list-v4"
|
||||
# # set name for ip v6 addresses
|
||||
# name-v6: "list-v6"
|
||||
#
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
.B ub_ctx_config,
|
||||
.B ub_ctx_set_fwd,
|
||||
.B ub_ctx_set_stub,
|
||||
.B ub_ctx_set_tls,
|
||||
.B ub_ctx_resolvconf,
|
||||
.B ub_ctx_hosts,
|
||||
.B ub_ctx_add_ta,
|
||||
@@ -72,6 +73,9 @@
|
||||
\fIint\fR isprime);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
|
||||
.LP
|
||||
\fIint\fR
|
||||
@@ -227,6 +231,12 @@ for different zones, or to add multiple addresses for a particular zone.
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_set_tls
|
||||
Enable DNS over TLS (DoT) for machines set with
|
||||
.B ub_ctx_set_fwd.
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_resolvconf
|
||||
By default the root servers are queried and full resolver mode is used, but
|
||||
you can use this call to read the list of nameservers to use from the
|
||||
|
||||
@@ -69,6 +69,10 @@ The server name, it connects to https://name. Specify without https:// prefix.
|
||||
The default is "data.iana.org". It connects to the port specified with \-P.
|
||||
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
|
||||
.TP
|
||||
.B \-b \fIaddress
|
||||
The source address to bind to for domain resolution and contacting the server
|
||||
on https. May be either an IPv4 address or IPv6 address (no brackets).
|
||||
.TP
|
||||
.B \-x \fIpath
|
||||
The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
|
||||
The default is /root\-anchors/root\-anchors.xml.
|
||||
|
||||
@@ -301,7 +301,7 @@ you set unbound to validate with for-upstream yes and that can be cleared
|
||||
with \fBflush_zone\fR \fIzone\fR.
|
||||
.TP
|
||||
.B auth_zone_transfer \fIzone\fR
|
||||
Tranfer the auth zone from master. The auth zone probe sequence is started,
|
||||
Transfer the auth zone from master. The auth zone probe sequence is started,
|
||||
where the masters are probed to see if they have an updated zone (with the SOA
|
||||
serial check). And then the zone is transferred for a newer zone version.
|
||||
.TP
|
||||
@@ -322,6 +322,9 @@ serial check). And then the zone is transferred for a newer zone version.
|
||||
.TP
|
||||
.B view_local_data_remove \fIview\fR \fIname
|
||||
\fIlocal_data_remove\fR for given view.
|
||||
.TP
|
||||
.B view_local_datas \fIview\fR
|
||||
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
@@ -496,6 +499,10 @@ Memory in bytes in use by the iterator module.
|
||||
Memory in bytes in use by the validator module. Includes the key cache and
|
||||
negative cache.
|
||||
.TP
|
||||
.I mem.streamwait
|
||||
Memory in bytes in used by the TCP and TLS stream wait buffers. These are
|
||||
answers waiting to be written back to the clients.
|
||||
.TP
|
||||
.I histogram.<sec>.<usec>.to.<sec>.<usec>
|
||||
Shows a histogram, summed over all threads. Every element counts the
|
||||
recursive queries whose reply time fit between the lower and upper bound.
|
||||
@@ -531,6 +538,10 @@ other servers.
|
||||
Number of queries that were made using TLS towards the unbound server.
|
||||
These are also counted in num.query.tcp, because TLS uses TCP.
|
||||
.TP
|
||||
.I num.query.tls.resume
|
||||
Number of TLS session resumptions, these are queries over TLS towards
|
||||
the unbound server where the client negotiated a TLS session resumption key.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the unbound server.
|
||||
.TP
|
||||
|
||||
+4
-1
@@ -54,7 +54,7 @@ resolvers are using the same port number (53).
|
||||
The available options are:
|
||||
.TP
|
||||
.B \-h
|
||||
Show the version and commandline option help.
|
||||
Show the version number and commandline option help, and exit.
|
||||
.TP
|
||||
.B \-c\fI cfgfile
|
||||
Set the config file with settings for unbound to read instead of reading the
|
||||
@@ -76,6 +76,9 @@ concurrently.
|
||||
.B \-v
|
||||
Increase verbosity. If given multiple times, more information is logged.
|
||||
This is in addition to the verbosity (if any) from the config file.
|
||||
.TP
|
||||
.B \-V
|
||||
Show the version number and build options, and exit.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\-checkconf\fR(8),
|
||||
|
||||
+141
-50
@@ -50,7 +50,7 @@ server:
|
||||
username: unbound
|
||||
# make sure unbound can access entropy from inside the chroot.
|
||||
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
|
||||
# mount \-\-bind \-n /dev/random /etc/unbound/dev/random
|
||||
# mount \-\-bind \-n /dev/urandom /etc/unbound/dev/urandom
|
||||
# and mount \-\-bind \-n /dev/log /etc/unbound/dev/log
|
||||
chroot: "/etc/unbound"
|
||||
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
|
||||
@@ -207,6 +207,16 @@ Maximum UDP response size (not applied to TCP response). 65536 disables the
|
||||
udp response size maximum, and uses the choice from the client, always.
|
||||
Suggested values are 512 to 4096. Default is 4096.
|
||||
.TP
|
||||
.B stream\-wait\-size: \fI<number>
|
||||
Number of bytes size maximum to use for waiting stream buffers. Default is
|
||||
4 megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
|
||||
megabytes or gigabytes (1024*1024 bytes in a megabyte). As TCP and TLS streams
|
||||
queue up multiple results, the amount of memory used for these buffers does
|
||||
not exceed this number, otherwise the responses are dropped. This manages
|
||||
the total memory usage of the server (under heavy use), the number of requests
|
||||
that can be queued up per connection is also limited, with further requests
|
||||
waiting in TCP buffers.
|
||||
.TP
|
||||
.B msg\-buffer\-size: \fI<number>
|
||||
Number of bytes size of the message buffers. Default is 65552 bytes, enough
|
||||
for 64 Kb packets, the maximum DNS message size. No message larger than this
|
||||
@@ -253,6 +263,12 @@ eg. 1500 msec. When timeouts happen you need extra sockets, it checks
|
||||
the ID and remote IP of packets, and unwanted packets are added to the
|
||||
unwanted packet counter.
|
||||
.TP
|
||||
.B unknown\-server\-time\-limit: \fI<msec>
|
||||
The wait time in msec for waiting for an unknown server to reply.
|
||||
Increase this if you are behind a slow satellite link, to eg. 1128.
|
||||
That would then avoid re\-querying every initial query because it times out.
|
||||
Default is 376 msec.
|
||||
.TP
|
||||
.B so\-rcvbuf: \fI<number>
|
||||
If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
space on UDP port 53 incoming queries. So that short spikes on busy
|
||||
@@ -284,6 +300,8 @@ it may also work. You can enable it (on any platform and kernel),
|
||||
it then attempts to open the port and passes the option if it was available
|
||||
at compile time, if that works it is used, if it fails, it continues
|
||||
silently (unless verbosity 3) without the option.
|
||||
At extreme load it could be better to turn it off to distribute the queries
|
||||
evenly, reported for Linux systems (4.4.x).
|
||||
.TP
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
@@ -314,11 +332,9 @@ Must be set to a power of 2.
|
||||
.TP
|
||||
.B cache\-max\-ttl: \fI<seconds>
|
||||
Time to live maximum for RRsets and messages in the cache. Default is
|
||||
86400 seconds (1 day). If the maximum kicks in, responses to clients
|
||||
still get decrementing TTLs based on the original (larger) values.
|
||||
When the internal TTL expires, the cache item has expired.
|
||||
86400 seconds (1 day). When the TTL expires, the cache item has expired.
|
||||
Can be set lower to force the resolver to query for data often, and not
|
||||
trust (very large) TTL values.
|
||||
trust (very large) TTL values. Downstream clients also see the lower TTL.
|
||||
.TP
|
||||
.B cache\-min\-ttl: \fI<seconds>
|
||||
Time to live minimum for RRsets and messages in the cache. Default is 0.
|
||||
@@ -436,20 +452,23 @@ TCP wireformat. The other server must support this (see
|
||||
\fBtls\-service\-key\fR).
|
||||
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
|
||||
load CA certs, otherwise the connections cannot be authenticated.
|
||||
This option enables TLS for all of them, but if you do not set this you can
|
||||
configure TLS specifically for some forward zones with forward\-tls\-upstream. And also with stub\-tls\-upstream.
|
||||
.TP
|
||||
.B ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provider TLS service on its TCP sockets. The clients
|
||||
have to use tls\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the tls\-service\-pem file. Default
|
||||
is "", turned off. Requires a restart (a reload is not enough) if changed,
|
||||
because the private key is read while root permissions are held and before
|
||||
chroot (if any). Normal DNS TCP service is not provided and gives errors,
|
||||
this service is best run with a different \fBport:\fR config or \fI@port\fR
|
||||
suffixes in the \fBinterface\fR config.
|
||||
If enabled, the server provides TLS service on the TCP ports marked
|
||||
implicitly or explicitly for TLS service with tls\-port. The file must
|
||||
contain the private key for the TLS session, the public certificate is in
|
||||
the tls\-service\-pem file and it must also be specified if tls\-service\-key
|
||||
is specified. The default is "", turned off. Enabling or disabling
|
||||
this service requires a restart (a reload is not enough), because the
|
||||
key is read while root permissions are held and before chroot (if any).
|
||||
The ports enabled implicitly or explicitly via \fBtls\-port:\fR do not provide
|
||||
normal DNS TCP service.
|
||||
.TP
|
||||
.B ssl\-service\-key: \fI<file>
|
||||
Alternate syntax for \fBtls\-service\-key\fR.
|
||||
@@ -488,6 +507,27 @@ List portnumbers as tls\-additional\-port, and when interfaces are defined,
|
||||
eg. with the @port suffix, as this port number, they provide dns over TLS
|
||||
service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B tls-session-ticket-keys: \fI<file>
|
||||
If not "", lists files with 80 bytes of random contents that are used to
|
||||
perform TLS session resumption for clients using the unbound server.
|
||||
These files contain the secret key for the TLS session tickets.
|
||||
First key use to encrypt and decrypt TLS session tickets.
|
||||
Other keys use to decrypt only. With this you can roll over to new keys,
|
||||
by generating a new first file and allowing decrypt of the old file by
|
||||
listing it after the first file for some time, after the wait clients are not
|
||||
using the old key any more and the old key can be removed.
|
||||
One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat
|
||||
The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key. Then there is 32 bytes random
|
||||
data for an AES key and then 32 bytes random data for the HMAC key.
|
||||
.TP
|
||||
.B tls\-ciphers: \fI<string with cipher list>
|
||||
Set the list of ciphers to allow when serving TLS. Use "" for defaults,
|
||||
and that is the default.
|
||||
.TP
|
||||
.B tls\-ciphersuites: \fI<string with ciphersuites list>
|
||||
Set the list of ciphersuites to allow when serving TLS. This is for newer
|
||||
TLS 1.3 connections. Use "" for defaults, and that is the default.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@@ -498,7 +538,7 @@ a daemon. Set the value to \fIno\fR when unbound runs as systemd service.
|
||||
Default is yes.
|
||||
.TP
|
||||
.B tcp\-connection\-limit: \fI<IP netblock> <limit>
|
||||
Allow up to \fIlimit\R simultaneous TCP connections from the given netblock.
|
||||
Allow up to \fIlimit\fR simultaneous TCP connections from the given netblock.
|
||||
When at the limit, further connections are accepted but closed immediately.
|
||||
This option is experimental at this time.
|
||||
.TP
|
||||
@@ -508,6 +548,7 @@ classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
|
||||
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
|
||||
\fIrefuse_non_local\fR.
|
||||
The most specific netblock match is used, if none match \fIdeny\fR is used.
|
||||
The order of the access\-control statements therefore does not matter.
|
||||
.IP
|
||||
The action \fIdeny\fR stops queries from hosts from that netblock.
|
||||
.IP
|
||||
@@ -588,9 +629,11 @@ In the last case the path is adjusted to remove the unused portion.
|
||||
The pidfile can be either a relative path to the working directory, or
|
||||
an absolute path relative to the original root. It is written just prior
|
||||
to chroot and dropping permissions. This allows the pidfile to be
|
||||
/var/run/unbound.pid and the chroot to be /var/unbound, for example.
|
||||
/var/run/unbound.pid and the chroot to be /var/unbound, for example. Note that
|
||||
Unbound is not able to remove the pidfile after termination when it is located
|
||||
outside of the chroot directory.
|
||||
.IP
|
||||
Additionally, unbound may need to access /dev/random (for entropy)
|
||||
Additionally, unbound may need to access /dev/urandom (for entropy)
|
||||
from inside the chroot.
|
||||
.IP
|
||||
If given a chroot is done to the given directory. By default chroot is
|
||||
@@ -655,6 +698,11 @@ Default is no. Note that it takes time to print these
|
||||
lines which makes the server (significantly) slower. Odd (nonprintable)
|
||||
characters in names are printed as '?'.
|
||||
.TP
|
||||
.B log\-tag\-queryreply: \fI<yes or no>
|
||||
Prints the word 'query' and 'reply' with log\-queries and log\-replies.
|
||||
This makes filtering logs easier. The default is off (for backwards
|
||||
compatibility).
|
||||
.TP
|
||||
.B log\-local\-actions: \fI<yes or no>
|
||||
Print log lines to inform about local zone actions. These lines are like the
|
||||
local\-zone type inform prints out, but they are also printed for the other
|
||||
@@ -727,7 +775,7 @@ wise to send these, and could be necessary for operation if TSIG or EDNS
|
||||
payload is very large.
|
||||
.TP
|
||||
.B harden\-glue: \fI<yes or no>
|
||||
Will trust glue only if it is within the servers authority. Default is on.
|
||||
Will trust glue only if it is within the servers authority. Default is yes.
|
||||
.TP
|
||||
.B harden\-dnssec\-stripped: \fI<yes or no>
|
||||
Require DNSSEC data for trust\-anchored zones, if such data is absent,
|
||||
@@ -737,7 +785,7 @@ 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.
|
||||
downgrade attack that disables security for a zone. Default is yes.
|
||||
.TP
|
||||
.B harden\-below\-nxdomain: \fI<yes or no>
|
||||
From RFC 8020 (with title "NXDOMAIN: There Really Is Nothing Underneath"),
|
||||
@@ -747,7 +795,7 @@ noerror for empty nonterminals, hence this is possible. Very old software
|
||||
might return nxdomain for empty nonterminals (that usually happen for reverse
|
||||
IP address lookups), and thus may be incompatible with this. To try to avoid
|
||||
this only DNSSEC-secure nxdomains are used, because the old software does not
|
||||
have DNSSEC. Default is on.
|
||||
have DNSSEC. Default is yes.
|
||||
The nxdomain must be secure, this means nsec3 with optout is insufficient.
|
||||
.TP
|
||||
.B harden\-referral\-path: \fI<yes or no>
|
||||
@@ -784,7 +832,7 @@ Can be given multiple times, for different domains.
|
||||
.TP
|
||||
.B qname\-minimisation: \fI<yes or no>
|
||||
Send minimum amount of information to upstream servers to enhance privacy.
|
||||
Only sent minimum required labels of the QNAME and set QTYPE to A when
|
||||
Only send minimum required labels of the QNAME and set QTYPE to A when
|
||||
possible. Best effort approach; full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR, except when receiving
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is yes.
|
||||
@@ -848,12 +896,18 @@ keep the cache up to date. Default is no. Turning it on gives about
|
||||
10 percent more traffic and load on the machine, but popular items do
|
||||
not expire from the cache.
|
||||
.TP
|
||||
.B prefetch-key: \fI<yes or no>
|
||||
.B prefetch\-key: \fI<yes or no>
|
||||
If yes, fetch the DNSKEYs earlier in the validation process, when a DS
|
||||
record is encountered. This lowers the latency of requests. It does use
|
||||
a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
|
||||
.TP
|
||||
.B rrset-roundrobin: \fI<yes or no>
|
||||
.B deny\-any: \fI<yes or no>
|
||||
If yes, deny queries of type ANY with an empty response. Default is no.
|
||||
If disabled, unbound responds with a short list of resource records if some
|
||||
can be found in the cache and makes the upstream type ANY query if there
|
||||
are none.
|
||||
.TP
|
||||
.B rrset\-roundrobin: \fI<yes or no>
|
||||
If yes, Unbound rotates RRSet order in response (the random number is taken
|
||||
from the query ID, for speed and thread safety). Default is no.
|
||||
.TP
|
||||
@@ -881,6 +935,12 @@ Setting this to "iterator" will result in a non\-validating server.
|
||||
Setting this to "validator iterator" will turn on DNSSEC validation.
|
||||
The ordering of the modules is important.
|
||||
You must also set trust\-anchors for validation to be useful.
|
||||
The default is "validator iterator". When the server is built with
|
||||
EDNS client subnet support the default is "subnetcache validator iterator".
|
||||
Most modules that need to be listed here have to be listed at the beginning
|
||||
of the line. The cachedb module has to be listed just before the iterator.
|
||||
The python module can be listed in different places, it then processes the
|
||||
output of the module it is just before.
|
||||
.TP
|
||||
.B trust\-anchor\-file: \fI<filename>
|
||||
File with trusted keys for validation. Both DS and DNSKEY entries can appear
|
||||
@@ -889,7 +949,7 @@ Default is "", or no trust anchor file.
|
||||
.TP
|
||||
.B auto\-trust\-anchor\-file: \fI<filename>
|
||||
File with trust anchor for one zone, which is tracked with RFC5011 probes.
|
||||
The probes are several times per month, thus the machine must be online
|
||||
The probes are run several times per month, thus the machine must be online
|
||||
frequently. The initial file can be one with contents as described in
|
||||
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
|
||||
so the unbound user must have write permission. Write permission to the file,
|
||||
@@ -914,10 +974,10 @@ It is possible to use wildcards with this statement, the wildcard is
|
||||
expanded on start and on reload.
|
||||
.TP
|
||||
.B trust\-anchor\-signaling: \fI<yes or no>
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is on.
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is yes.
|
||||
.TP
|
||||
.B root\-key\-sentinel: \fI<yes or no>
|
||||
Root key trust anchor sentinel. Default is on.
|
||||
Root key trust anchor sentinel. Default is yes.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
This option was used during early days DNSSEC deployment when no parent-side
|
||||
@@ -1092,7 +1152,7 @@ address space are not validated. This is usually required whenever
|
||||
Configure a local zone. The type determines the answer to give if
|
||||
there is no match from local\-data. The types are deny, refuse, static,
|
||||
transparent, redirect, nodefault, typetransparent, inform, inform_deny,
|
||||
always_transparent, always_refuse, always_nxdomain, noview,
|
||||
inform_redirect, always_transparent, always_refuse, always_nxdomain, noview,
|
||||
and are explained below. After that the default settings are listed. Use
|
||||
local\-data: to enter data into the local zone. Answers for local zones
|
||||
are authoritative DNS answers. By default the zones are class IN.
|
||||
@@ -1153,6 +1213,10 @@ looking up infected names are logged, eg. to run antivirus on them.
|
||||
The query is dropped, like 'deny', and logged, like 'inform'. Ie. find
|
||||
infected machines without answering the queries.
|
||||
.TP 10
|
||||
\h'5'\fIinform_redirect\fR
|
||||
The query is redirected, like 'redirect', and logged, like 'inform'.
|
||||
Ie. answer queries with fixed data and also log the machines that ask.
|
||||
.TP 10
|
||||
\h'5'\fIalways_transparent\fR
|
||||
Like transparent, but ignores local data and resolves normally.
|
||||
.TP 10
|
||||
@@ -1308,7 +1372,8 @@ TTL can be inserted like this: "2001:DB8::4 7200 www.example.com"
|
||||
Assign tags to localzones. Tagged localzones will only be applied when the
|
||||
used access-control element has a matching tag. Tags must be defined in
|
||||
\fIdefine\-tags\fR. Enclose list of tags in quotes ("") and put spaces between
|
||||
tags.
|
||||
tags. When there are multiple tags it checks if the intersection of the
|
||||
list of tags for the query and local\-zone\-tag is non-empty.
|
||||
.TP 5
|
||||
.B local\-zone\-override: \fI<zone> <IP netblock> <type>
|
||||
Override the localzone type for queries from addresses matching netblock.
|
||||
@@ -1391,22 +1456,20 @@ This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B low\-rtt: \fI<msec time>
|
||||
Set the time in millisecond that is considere a low ping time for fast
|
||||
server selection with the low\-rtt\-permil option, that turns this on or off.
|
||||
The default is 45 msec, a number from IPv6 quick response documents.
|
||||
.B fast\-server\-permil: \fI<number>
|
||||
Specify how many times out of 1000 to pick from the set of fastest servers.
|
||||
0 turns the feature off. A value of 900 would pick from the fastest
|
||||
servers 90 percent of the time, and would perform normal exploration of random
|
||||
servers for the remaining time. When prefetch is enabled (or serve\-expired),
|
||||
such prefetches are not sped up, because there is no one waiting for it, and it
|
||||
presents a good moment to perform server exploration. The
|
||||
\fBfast\-server\-num\fR option can be used to specify the size of the fastest
|
||||
servers set. The default for fast\-server\-permil is 0.
|
||||
.TP 5
|
||||
.B low\-rtt\-permil: \fI<number>
|
||||
Specify how many times out of 1000 to pick the fast server from the low
|
||||
rtt band. 0 turns the feature off. A value of 900 would pick the fast
|
||||
server when such fast servers are available 90 percent of the time, and
|
||||
the remaining time perform normal exploration of random servers.
|
||||
When prefetch is enabled (or serve\-expired), such prefetches are not
|
||||
sped up, because there is no one waiting for it, and it presents a good
|
||||
moment to perform server exploration. The low\-rtt option can be used
|
||||
to specify which servers are picked for fast server selection, servers
|
||||
with a ping roundtrip time below that value are considered.
|
||||
The default for low\-rtt\-permil is 0.
|
||||
.B fast\-server\-num: \fI<number>
|
||||
Set the number of servers that should be used for fast server selection. Only
|
||||
use the fastest specified number of servers with the fast\-server\-permil
|
||||
option, that turns this on or off. The default is to use the fastest 3 servers.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
@@ -1568,13 +1631,11 @@ the '@' and '#', the '@' comes first.
|
||||
At high verbosity it logs the TLS certificate, with TLS enabled.
|
||||
If you leave out the '#' and auth name from the forward\-addr, any
|
||||
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
The cert name match code needs OpenSSL 1.1.0 or later to be enabled.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If enabled, a query is attempted without the forward clause if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because
|
||||
the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified. The default is "no".
|
||||
.TP
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use TLS for transport.
|
||||
@@ -1604,6 +1665,13 @@ lookups of that data.
|
||||
Authority zones can be read from zonefile. And can be kept updated via
|
||||
AXFR and IXFR. After update the zonefile is rewritten. The update mechanism
|
||||
uses the SOA timer values and performs SOA UDP queries to detect zone changes.
|
||||
.LP
|
||||
If the update fetch fails, the timers in the SOA record are used to time
|
||||
another fetch attempt. Until the SOA expiry timer is reached. Then the
|
||||
zone is expired. When a zone is expired, queries are SERVFAIL, and
|
||||
any new serial number is accepted from the master (even if older), and if
|
||||
fallback is enabled, the fallback activates to fetch from the upstream instead
|
||||
of the SERVFAIL.
|
||||
.TP
|
||||
.B name: \fI<zone name>
|
||||
Name of the authority zone.
|
||||
@@ -1611,6 +1679,7 @@ Name of the authority zone.
|
||||
.B master: \fI<IP address or host name>
|
||||
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
|
||||
masters can be specified. They are all tried if one fails.
|
||||
With the "ip#name" notation a AXFR over TLS can be used.
|
||||
.TP
|
||||
.B url: \fI<url to zonefile>
|
||||
Where to download a zonefile for the zone. With http or https. An example
|
||||
@@ -1662,7 +1731,9 @@ data (eg. from the master servers).
|
||||
There may be multiple
|
||||
.B view:
|
||||
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
|
||||
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the
|
||||
\fBlocal\-data\fR elements. Views can also contain view\-first,
|
||||
response\-ip, response\-ip\-data and local\-data\-ptr elements.
|
||||
View can be mapped to requests by specifying the
|
||||
view name in an \fBaccess\-control\-view\fR element. Options from matching
|
||||
views will override global options. Global options will be used if no matching
|
||||
view is found, or when the matching view does not have the option specified.
|
||||
@@ -1699,7 +1770,8 @@ clause gives the settings for the \fIpython\fR(1) script module. This module
|
||||
acts like the iterator and validator modules do, on queries and answers.
|
||||
To enable the script module it has to be compiled into the daemon,
|
||||
and the word "python" has to be put in the \fBmodule\-config:\fR option
|
||||
(usually first, or between the validator and iterator).
|
||||
(usually first, or between the validator and iterator). Multiple instances of
|
||||
the python module are supported by adding the word "python" more than once.
|
||||
.LP
|
||||
If the \fBchroot:\fR option is enabled, you should make sure Python's
|
||||
library directory structure is bind mounted in the new root environment, see
|
||||
@@ -1708,7 +1780,8 @@ absolute path relative to the new root, or as a relative path to the working
|
||||
directory.
|
||||
.TP
|
||||
.B python\-script: \fI<python file>\fR
|
||||
The script file to load.
|
||||
The script file to load. Repeat this option for every python module instance
|
||||
added to the \fBmodule\-config:\fR option.
|
||||
.SS "DNS64 Module Options"
|
||||
.LP
|
||||
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
||||
@@ -1843,6 +1916,24 @@ to expose to third parties for IPv6. Defaults to 56.
|
||||
.B max\-client\-subnet\-ipv4: \fI<number>\fR
|
||||
Specifies the maximum prefix length of the client source address we are willing
|
||||
to expose to third parties for IPv4. Defaults to 24.
|
||||
.TP
|
||||
.B min\-client\-subnet\-ipv6: \fI<number>\fR
|
||||
Specifies the minimum prefix length of the IPv6 source mask we are willing to
|
||||
accept in queries. Shorter source masks result in REFUSED answers. Source mask
|
||||
of 0 is always accepted. Default is 0.
|
||||
.TP
|
||||
.B min\-client\-subnet\-ipv4: \fI<number>\fR
|
||||
Specifies the minimum prefix length of the IPv4 source mask we are willing to
|
||||
accept in queries. Shorter source masks result in REFUSED answers. Source mask
|
||||
of 0 is always accepted. Default is 0.
|
||||
.TP
|
||||
.B max\-ecs\-tree\-size\-ipv4: \fI<number>\fR
|
||||
Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
|
||||
This number applies for each qname/qclass/qtype tuple. Defaults to 100.
|
||||
.TP
|
||||
.B max\-ecs\-tree\-size\-ipv6: \fI<number>\fR
|
||||
Specifies the maximum number of subnets ECS answers kept in the ECS radix tree.
|
||||
This number applies for each qname/qclass/qtype tuple. Defaults to 100.
|
||||
.SS "Opportunistic IPsec Support Module Options"
|
||||
.LP
|
||||
The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
|
||||
|
||||
+9
-3
@@ -612,18 +612,24 @@ RECURSIVE = YES
|
||||
|
||||
EXCLUDE = ./build \
|
||||
./compat \
|
||||
./contrib \
|
||||
util/configparser.c \
|
||||
util/configparser.h \
|
||||
util/configlexer.c \
|
||||
util/locks.h \
|
||||
pythonmod/doc \
|
||||
pythonmod/examples \
|
||||
pythonmod/unboundmodule.py \
|
||||
pythonmod/interface.h \
|
||||
pythonmod/examples/resgen.py \
|
||||
pythonmod/examples/resmod.py \
|
||||
pythonmod/examples/resip.py \
|
||||
pythonmod/ubmodule-msg.py \
|
||||
pythonmod/ubmodule-tst.py \
|
||||
unboundmodule.py \
|
||||
libunbound/python/unbound.py \
|
||||
libunbound/python/libunbound_wrap.c \
|
||||
libunbound/python/doc \
|
||||
libunbound/python/examples \
|
||||
./ldns-src \
|
||||
README.md \
|
||||
doc/control_proto_spec.txt \
|
||||
doc/requirements.txt
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ node_size(const struct addrtree *tree, const struct addrnode *n)
|
||||
|
||||
struct addrtree *
|
||||
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
|
||||
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count)
|
||||
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count)
|
||||
{
|
||||
struct addrtree *tree;
|
||||
log_assert(delfunc != NULL);
|
||||
|
||||
@@ -66,10 +66,10 @@ struct addrtree {
|
||||
struct addrnode *root;
|
||||
/** Number of elements in the tree (not always equal to number of
|
||||
* nodes) */
|
||||
unsigned int node_count;
|
||||
uint32_t node_count;
|
||||
/** Maximum number of allowed nodes, will be enforced by LRU list.
|
||||
* Excluding the root node, 0 for unlimited */
|
||||
unsigned int max_node_count;
|
||||
uint32_t max_node_count;
|
||||
/** Size of tree in bytes */
|
||||
size_t size_bytes;
|
||||
/** Maximum prefix length we are willing to cache. */
|
||||
@@ -137,7 +137,7 @@ size_t addrtree_size(const struct addrtree *tree);
|
||||
*/
|
||||
struct addrtree *
|
||||
addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *),
|
||||
size_t (*sizefunc)(void *), void *env, unsigned int max_node_count);
|
||||
size_t (*sizefunc)(void *), void *env, uint32_t max_node_count);
|
||||
|
||||
/**
|
||||
* Free tree and all nodes below.
|
||||
|
||||
+66
-23
@@ -55,8 +55,7 @@
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#define ECS_MAX_TREESIZE 100
|
||||
#include "iterator/iter_utils.h"
|
||||
|
||||
/** externally called */
|
||||
void
|
||||
@@ -93,6 +92,7 @@ subnet_new_qstate(struct module_qstate *qstate, int id)
|
||||
return 0;
|
||||
qstate->minfo[id] = sq;
|
||||
memset(sq, 0, sizeof(*sq));
|
||||
sq->started_no_cache_store = qstate->no_cache_store;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,9 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
||||
|
||||
/* Cache by default, might be disabled after parsing EDNS option
|
||||
* received from nameserver. */
|
||||
qstate->no_cache_store = 0;
|
||||
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo)) {
|
||||
qstate->no_cache_store = 0;
|
||||
}
|
||||
|
||||
if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream &&
|
||||
qstate->env->cfg->client_subnet_always_forward) ||
|
||||
@@ -177,6 +179,14 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
subnet_markdel(void* key)
|
||||
{
|
||||
struct msgreply_entry *e = (struct msgreply_entry*)key;
|
||||
e->key.qtype = 0;
|
||||
e->key.qclass = 0;
|
||||
}
|
||||
|
||||
int
|
||||
subnetmod_init(struct module_env *env, int id)
|
||||
{
|
||||
@@ -193,6 +203,7 @@ subnetmod_init(struct module_env *env, int id)
|
||||
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
|
||||
msg_cache_sizefunc, query_info_compare, query_entry_delete,
|
||||
subnet_data_delete, NULL);
|
||||
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
|
||||
if(!sn_env->subnet_msg_cache) {
|
||||
log_err("subnet: could not create cache");
|
||||
free(sn_env);
|
||||
@@ -291,13 +302,13 @@ get_tree(struct subnet_msg_cache_data *data, struct ecs_data *edns,
|
||||
if (!data->tree4)
|
||||
data->tree4 = addrtree_create(
|
||||
cfg->max_client_subnet_ipv4, &delfunc,
|
||||
&sizefunc, env, ECS_MAX_TREESIZE);
|
||||
&sizefunc, env, cfg->max_ecs_tree_size_ipv4);
|
||||
tree = data->tree4;
|
||||
} else {
|
||||
if (!data->tree6)
|
||||
data->tree6 = addrtree_create(
|
||||
cfg->max_client_subnet_ipv6, &delfunc,
|
||||
&sizefunc, env, ECS_MAX_TREESIZE);
|
||||
&sizefunc, env, cfg->max_ecs_tree_size_ipv6);
|
||||
tree = data->tree6;
|
||||
}
|
||||
return tree;
|
||||
@@ -323,33 +334,37 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
/* Step 1, general qinfo lookup */
|
||||
struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h,
|
||||
&qstate->qinfo, 1);
|
||||
int acquired_lock = (lru_entry != NULL);
|
||||
int need_to_insert = (lru_entry == NULL);
|
||||
if (!lru_entry) {
|
||||
void* data = calloc(1,
|
||||
sizeof(struct subnet_msg_cache_data));
|
||||
if(!data) {
|
||||
log_err("malloc failed");
|
||||
return;
|
||||
}
|
||||
qinf = qstate->qinfo;
|
||||
qinf.qname = memdup(qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len);
|
||||
if(!qinf.qname) {
|
||||
free(data);
|
||||
log_err("memdup failed");
|
||||
return;
|
||||
}
|
||||
mrep_entry = query_info_entrysetup(&qinf, NULL, h);
|
||||
mrep_entry = query_info_entrysetup(&qinf, data, h);
|
||||
free(qinf.qname); /* if qname 'consumed', it is set to NULL */
|
||||
if (!mrep_entry) {
|
||||
free(data);
|
||||
log_err("query_info_entrysetup failed");
|
||||
return;
|
||||
}
|
||||
lru_entry = &mrep_entry->entry;
|
||||
lock_rw_wrlock(&lru_entry->lock);
|
||||
lru_entry->data = calloc(1,
|
||||
sizeof(struct subnet_msg_cache_data));
|
||||
if (!lru_entry->data) {
|
||||
log_err("malloc failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* lru_entry->lock is locked regardless of how we got here,
|
||||
* either from the slabhash_lookup, or above in the new allocated */
|
||||
/* Step 2, find the correct tree */
|
||||
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
|
||||
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
log_err("Subnet cache insertion failed");
|
||||
return;
|
||||
}
|
||||
@@ -357,7 +372,7 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL);
|
||||
lock_quick_unlock(&sne->alloc.lock);
|
||||
if (!rep) {
|
||||
if (acquired_lock) lock_rw_unlock(&lru_entry->lock);
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
log_err("Subnet cache insertion failed");
|
||||
return;
|
||||
}
|
||||
@@ -374,10 +389,9 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
edns->subnet_source_mask,
|
||||
sq->ecs_server_in.subnet_scope_mask, rep,
|
||||
rep->ttl, *qstate->env->now);
|
||||
if (acquired_lock) {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
} else {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
if (need_to_insert) {
|
||||
slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data,
|
||||
NULL);
|
||||
}
|
||||
@@ -487,9 +501,11 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
* is still usefull to put it in the edns subnet cache for
|
||||
* when a client explicitly asks for subnet specific answer. */
|
||||
verbose(VERB_QUERY, "subnet: Authority indicates no support");
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
if(!sq->started_no_cache_store) {
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
}
|
||||
if (sq->subnet_downstream)
|
||||
cp_edns_bad_response(c_out, c_in);
|
||||
return module_finished;
|
||||
@@ -515,7 +531,9 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
if(!sq->started_no_cache_store) {
|
||||
update_cache(qstate, id);
|
||||
}
|
||||
sne->num_msg_nocache++;
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
|
||||
@@ -526,6 +544,19 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
c_out->subnet_source_mask = c_in->subnet_source_mask;
|
||||
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
|
||||
c_out->subnet_scope_mask = s_in->subnet_scope_mask;
|
||||
/* Limit scope returned to client to scope used for caching. */
|
||||
if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
|
||||
if(c_out->subnet_scope_mask >
|
||||
qstate->env->cfg->max_client_subnet_ipv4) {
|
||||
c_out->subnet_scope_mask =
|
||||
qstate->env->cfg->max_client_subnet_ipv4;
|
||||
}
|
||||
}
|
||||
else if(c_out->subnet_scope_mask >
|
||||
qstate->env->cfg->max_client_subnet_ipv6) {
|
||||
c_out->subnet_scope_mask =
|
||||
qstate->env->cfg->max_client_subnet_ipv6;
|
||||
}
|
||||
c_out->subnet_validdata = 1;
|
||||
}
|
||||
return module_finished;
|
||||
@@ -697,6 +728,17 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Limit to minimum allowed source mask */
|
||||
if(sq->ecs_client_in.subnet_source_mask != 0 && (
|
||||
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 &&
|
||||
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv4) ||
|
||||
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 &&
|
||||
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv6))) {
|
||||
qstate->return_rcode = LDNS_RCODE_REFUSED;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
if (lookup_and_reply(qstate, id, sq)) {
|
||||
sne->num_msg_cache++;
|
||||
@@ -753,6 +795,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
ecs_opt_list_append(&sq->ecs_client_out,
|
||||
&qstate->edns_opts_front_out, qstate);
|
||||
}
|
||||
qstate->no_cache_store = sq->started_no_cache_store;
|
||||
return;
|
||||
}
|
||||
if(sq && outbound) {
|
||||
|
||||
@@ -83,6 +83,8 @@ struct subnet_qstate {
|
||||
struct ecs_data ecs_server_out;
|
||||
int subnet_downstream;
|
||||
int subnet_sent;
|
||||
/** has the subnet module been started with no_cache_store? */
|
||||
int started_no_cache_store;
|
||||
};
|
||||
|
||||
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
|
||||
@@ -131,4 +133,7 @@ int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
|
||||
int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
|
||||
int id, void* cbargs);
|
||||
|
||||
/** mark subnet msg to be deleted */
|
||||
void subnet_markdel(void* key);
|
||||
|
||||
#endif /* SUBNETMOD_H */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
+121
-28
@@ -103,11 +103,11 @@ ipsecmod_new(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc(
|
||||
qstate->region, sizeof(struct ipsecmod_qstate));
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
qstate->minfo[id] = iq;
|
||||
if(!iq)
|
||||
return 0;
|
||||
/* Initialise it. */
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
iq->enabled = qstate->env->cfg->ipsecmod_enabled;
|
||||
iq->is_whitelisted = ipsecmod_domain_is_whitelisted(
|
||||
(struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname,
|
||||
@@ -161,6 +161,71 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string passed is a valid domain name with safe characters to
|
||||
* pass to a shell.
|
||||
* This will only allow:
|
||||
* - digits
|
||||
* - alphas
|
||||
* - hyphen (not at the start)
|
||||
* - dot (not at the start, or the only character)
|
||||
* - underscore
|
||||
* @param s: pointer to the string.
|
||||
* @param slen: string's length.
|
||||
* @return true if s only contains safe characters; false otherwise.
|
||||
*/
|
||||
static int
|
||||
domainname_has_safe_characters(char* s, size_t slen) {
|
||||
size_t i;
|
||||
for(i = 0; i < slen; i++) {
|
||||
if(s[i] == '\0') return 1;
|
||||
if((s[i] == '-' && i != 0)
|
||||
|| (s[i] == '.' && (i != 0 || s[1] == '\0'))
|
||||
|| (s[i] == '_') || (s[i] >= '0' && s[i] <= '9')
|
||||
|| (s[i] >= 'A' && s[i] <= 'Z')
|
||||
|| (s[i] >= 'a' && s[i] <= 'z')) {
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the stringified IPSECKEY RDATA contains safe characters to pass to
|
||||
* a shell.
|
||||
* This is only relevant for checking the gateway when the gateway type is 3
|
||||
* (domainname).
|
||||
* @param s: pointer to the string.
|
||||
* @param slen: string's length.
|
||||
* @return true if s contains only safe characters; false otherwise.
|
||||
*/
|
||||
static int
|
||||
ipseckey_has_safe_characters(char* s, size_t slen) {
|
||||
int precedence, gateway_type, algorithm;
|
||||
char* gateway;
|
||||
gateway = (char*)calloc(slen, sizeof(char));
|
||||
if(!gateway) {
|
||||
log_err("ipsecmod: out of memory when calling the hook");
|
||||
return 0;
|
||||
}
|
||||
if(sscanf(s, "%d %d %d %s ",
|
||||
&precedence, &gateway_type, &algorithm, gateway) != 4) {
|
||||
free(gateway);
|
||||
return 0;
|
||||
}
|
||||
if(gateway_type != 3) {
|
||||
free(gateway);
|
||||
return 1;
|
||||
}
|
||||
if(domainname_has_safe_characters(gateway, slen)) {
|
||||
free(gateway);
|
||||
return 1;
|
||||
}
|
||||
free(gateway);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data and call the hook.
|
||||
*
|
||||
@@ -175,7 +240,7 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq,
|
||||
{
|
||||
size_t slen, tempdata_len, tempstring_len, i;
|
||||
char str[65535], *s, *tempstring;
|
||||
int w;
|
||||
int w = 0, w_temp, qtype;
|
||||
struct ub_packed_rrset_key* rrset_key;
|
||||
struct packed_rrset_data* rrset_data;
|
||||
uint8_t *tempdata;
|
||||
@@ -192,9 +257,9 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq,
|
||||
memset(s, 0, slen);
|
||||
|
||||
/* Copy the hook into the buffer. */
|
||||
sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
|
||||
w += sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
/* Copy the qname into the buffer. */
|
||||
tempstring = sldns_wire2str_dname(qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len);
|
||||
@@ -202,68 +267,96 @@ call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq,
|
||||
log_err("ipsecmod: out of memory when calling the hook");
|
||||
return 0;
|
||||
}
|
||||
sldns_str_print(&s, &slen, "\"%s\"", tempstring);
|
||||
if(!domainname_has_safe_characters(tempstring, strlen(tempstring))) {
|
||||
log_err("ipsecmod: qname has unsafe characters");
|
||||
free(tempstring);
|
||||
return 0;
|
||||
}
|
||||
w += sldns_str_print(&s, &slen, "\"%s\"", tempstring);
|
||||
free(tempstring);
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
/* Copy the IPSECKEY TTL into the buffer. */
|
||||
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
|
||||
sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl);
|
||||
w += sldns_str_print(&s, &slen, "\"%ld\"", (long)rrset_data->ttl);
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
/* Copy the A/AAAA record(s) into the buffer. Start and end this section
|
||||
* with a double quote. */
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
/* Double check that the records are indeed A/AAAA.
|
||||
* This should never happen as this function is only executed for A/AAAA
|
||||
* queries but make sure we don't pass anything other than A/AAAA to the
|
||||
* shell. */
|
||||
qtype = ntohs(rrset_key->rk.type);
|
||||
if(qtype != LDNS_RR_TYPE_AAAA && qtype != LDNS_RR_TYPE_A) {
|
||||
log_err("ipsecmod: Answer is not of A or AAAA type");
|
||||
return 0;
|
||||
}
|
||||
rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
|
||||
sldns_str_print(&s, &slen, "\"");
|
||||
/* Copy the A/AAAA record(s) into the buffer. Start and end this section
|
||||
* with a double quote. */
|
||||
w += sldns_str_print(&s, &slen, "\"");
|
||||
for(i=0; i<rrset_data->count; i++) {
|
||||
if(i > 0) {
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
}
|
||||
/* Ignore the first two bytes, they are the rr_data len. */
|
||||
w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
|
||||
w_temp = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
|
||||
rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype);
|
||||
if(w < 0) {
|
||||
if(w_temp < 0) {
|
||||
/* Error in printout. */
|
||||
return -1;
|
||||
} else if((size_t)w >= slen) {
|
||||
log_err("ipsecmod: Error in printing IP address");
|
||||
return 0;
|
||||
} else if((size_t)w_temp >= slen) {
|
||||
s = NULL; /* We do not want str to point outside of buffer. */
|
||||
slen = 0;
|
||||
return -1;
|
||||
log_err("ipsecmod: shell command too long");
|
||||
return 0;
|
||||
} else {
|
||||
s += w;
|
||||
slen -= w;
|
||||
s += w_temp;
|
||||
slen -= w_temp;
|
||||
w += w_temp;
|
||||
}
|
||||
}
|
||||
sldns_str_print(&s, &slen, "\"");
|
||||
w += sldns_str_print(&s, &slen, "\"");
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
/* Copy the IPSECKEY record(s) into the buffer. Start and end this section
|
||||
* with a double quote. */
|
||||
sldns_str_print(&s, &slen, "\"");
|
||||
w += sldns_str_print(&s, &slen, "\"");
|
||||
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
|
||||
for(i=0; i<rrset_data->count; i++) {
|
||||
if(i > 0) {
|
||||
/* Put space into the buffer. */
|
||||
sldns_str_print(&s, &slen, " ");
|
||||
w += sldns_str_print(&s, &slen, " ");
|
||||
}
|
||||
/* Ignore the first two bytes, they are the rr_data len. */
|
||||
tempdata = rrset_data->rr_data[i] + 2;
|
||||
tempdata_len = rrset_data->rr_len[i] - 2;
|
||||
/* Save the buffer pointers. */
|
||||
tempstring = s; tempstring_len = slen;
|
||||
w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen,
|
||||
NULL, 0);
|
||||
w_temp = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s,
|
||||
&slen, NULL, 0, NULL);
|
||||
/* There was an error when parsing the IPSECKEY; reset the buffer
|
||||
* pointers to their previous values. */
|
||||
if(w == -1){
|
||||
if(w_temp == -1) {
|
||||
s = tempstring; slen = tempstring_len;
|
||||
} else if(w_temp > 0) {
|
||||
if(!ipseckey_has_safe_characters(
|
||||
tempstring, tempstring_len - slen)) {
|
||||
log_err("ipsecmod: ipseckey has unsafe characters");
|
||||
return 0;
|
||||
}
|
||||
w += w_temp;
|
||||
}
|
||||
}
|
||||
sldns_str_print(&s, &slen, "\"");
|
||||
verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str);
|
||||
w += sldns_str_print(&s, &slen, "\"");
|
||||
if(w >= (int)sizeof(str)) {
|
||||
log_err("ipsecmod: shell command too long");
|
||||
return 0;
|
||||
}
|
||||
verbose(VERB_ALGO, "ipsecmod: shell command: '%s'", str);
|
||||
/* ipsecmod-hook should return 0 on success. */
|
||||
if(system(str) != 0)
|
||||
return 0;
|
||||
|
||||
Executable
+383
@@ -0,0 +1,383 @@
|
||||
/**
|
||||
* \file
|
||||
* This file implements the ipset module. It can handle packets by putting
|
||||
* the A and AAAA addresses that are configured in unbound.conf as type
|
||||
* ipset (local-zone statements) into a firewall rule IPSet. For firewall
|
||||
* blacklist and whitelist usage.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "ipset/ipset.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
#include "services/cache/dns.h"
|
||||
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/ipset/ip_set.h>
|
||||
|
||||
#define BUFF_LEN 256
|
||||
|
||||
/**
|
||||
* Return an error
|
||||
* @param qstate: our query state
|
||||
* @param id: module id
|
||||
* @param rcode: error code (DNS errcode).
|
||||
* @return: 0 for use by caller, to make notation easy, like:
|
||||
* return error_response(..).
|
||||
*/
|
||||
static int error_response(struct module_qstate* qstate, int id, int rcode) {
|
||||
verbose(VERB_QUERY, "return error response %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??");
|
||||
qstate->return_rcode = rcode;
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mnl_socket * open_mnl_socket() {
|
||||
struct mnl_socket *mnl;
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!mnl) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
return mnl;
|
||||
}
|
||||
|
||||
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfg;
|
||||
struct nlattr *nested[2];
|
||||
static char buffer[BUFF_LEN];
|
||||
|
||||
if (strlen(setname) >= IPSET_MAXNAMELEN) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
if (af != AF_INET && af != AF_INET6) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nlh = mnl_nlmsg_put_header(buffer);
|
||||
nlh->nlmsg_type = IPSET_CMD_ADD | (NFNL_SUBSYS_IPSET << 8);
|
||||
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL;
|
||||
|
||||
nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
|
||||
nfg->nfgen_family = af;
|
||||
nfg->version = NFNETLINK_V0;
|
||||
nfg->res_id = htons(0);
|
||||
|
||||
mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
|
||||
mnl_attr_put(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
|
||||
nested[0] = mnl_attr_nest_start(nlh, IPSET_ATTR_DATA);
|
||||
nested[1] = mnl_attr_nest_start(nlh, IPSET_ATTR_IP);
|
||||
mnl_attr_put(nlh, (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6)
|
||||
| NLA_F_NET_BYTEORDER, (af == AF_INET ? sizeof(struct in_addr) : sizeof(struct in6_addr)), ipaddr);
|
||||
mnl_attr_nest_end(nlh, nested[1]);
|
||||
mnl_attr_nest_end(nlh, nested[0]);
|
||||
|
||||
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
struct packed_rrset_data *d, const char* setname, int af,
|
||||
const char* dname)
|
||||
{
|
||||
int ret;
|
||||
size_t j, rr_len, rd_len;
|
||||
uint8_t *rr_data;
|
||||
|
||||
/* to d->count, not d->rrsig_count, because we do not want to add the RRSIGs, only the addresses */
|
||||
for (j = 0; j < d->count; j++) {
|
||||
rr_len = d->rr_len[j];
|
||||
rr_data = d->rr_data[j];
|
||||
|
||||
rd_len = sldns_read_uint16(rr_data);
|
||||
if(af == AF_INET && rd_len != INET_SIZE)
|
||||
continue;
|
||||
if(af == AF_INET6 && rd_len != INET6_SIZE)
|
||||
continue;
|
||||
if (rr_len - 2 >= rd_len) {
|
||||
if(verbosity >= VERB_QUERY) {
|
||||
char ip[128];
|
||||
if(inet_ntop(af, rr_data+2, ip, (socklen_t)sizeof(ip)) == 0)
|
||||
snprintf(ip, sizeof(ip), "(inet_ntop_error)");
|
||||
verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
|
||||
}
|
||||
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
|
||||
if (ret < 0) {
|
||||
log_err("ipset: could not add %s into %s", dname, setname);
|
||||
|
||||
mnl_socket_close(mnl);
|
||||
ie->mnl = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
|
||||
const char *setname, int af)
|
||||
{
|
||||
static char dname[BUFF_LEN];
|
||||
const char *s;
|
||||
int dlen, plen;
|
||||
|
||||
struct config_strlist *p;
|
||||
struct packed_rrset_data *d;
|
||||
|
||||
dlen = sldns_wire2str_dname_buf(rrset->rk.dname, rrset->rk.dname_len, dname, BUFF_LEN);
|
||||
if (dlen == 0) {
|
||||
log_err("bad domain name");
|
||||
return -1;
|
||||
}
|
||||
if (dname[dlen - 1] == '.') {
|
||||
dlen--;
|
||||
}
|
||||
|
||||
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
|
||||
plen = strlen(p->str);
|
||||
|
||||
if (dlen >= plen) {
|
||||
s = dname + (dlen - plen);
|
||||
|
||||
if (strncasecmp(p->str, s, plen) == 0) {
|
||||
d = (struct packed_rrset_data*)rrset->entry.data;
|
||||
ipset_add_rrset_data(ie, mnl, d, setname,
|
||||
af, dname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipset_update(struct module_env *env, struct dns_msg *return_msg, struct ipset_env *ie) {
|
||||
struct mnl_socket *mnl;
|
||||
|
||||
size_t i;
|
||||
|
||||
const char *setname;
|
||||
|
||||
struct ub_packed_rrset_key *rrset;
|
||||
|
||||
int af;
|
||||
|
||||
|
||||
mnl = (struct mnl_socket *)ie->mnl;
|
||||
if (!mnl) {
|
||||
// retry to create mnl socket
|
||||
mnl = open_mnl_socket();
|
||||
if (!mnl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ie->mnl = mnl;
|
||||
}
|
||||
|
||||
for (i = 0; i < return_msg->rep->rrset_count; ++i) {
|
||||
setname = NULL;
|
||||
|
||||
rrset = return_msg->rep->rrsets[i];
|
||||
|
||||
if (rrset->rk.type == htons(LDNS_RR_TYPE_A)) {
|
||||
af = AF_INET;
|
||||
if ((ie->v4_enabled == 1)) {
|
||||
setname = ie->name_v4;
|
||||
}
|
||||
} else {
|
||||
af = AF_INET6;
|
||||
if ((ie->v6_enabled == 1)) {
|
||||
setname = ie->name_v6;
|
||||
}
|
||||
}
|
||||
|
||||
if (setname) {
|
||||
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
|
||||
setname, af) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
|
||||
if (!ipset_env) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
env->modinfo[id] = (void *)ipset_env;
|
||||
|
||||
ipset_env->mnl = NULL;
|
||||
|
||||
ipset_env->name_v4 = env->cfg->ipset_name_v4;
|
||||
ipset_env->name_v6 = env->cfg->ipset_name_v6;
|
||||
|
||||
ipset_env->v4_enabled = !ipset_env->name_v4 || (strlen(ipset_env->name_v4) == 0) ? 0 : 1;
|
||||
ipset_env->v6_enabled = !ipset_env->name_v6 || (strlen(ipset_env->name_v6) == 0) ? 0 : 1;
|
||||
|
||||
if ((ipset_env->v4_enabled < 1) && (ipset_env->v6_enabled < 1)) {
|
||||
log_err("ipset: set name no configuration?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_deinit(struct module_env *env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipset_env = (struct ipset_env *)env->modinfo[id];
|
||||
|
||||
mnl = (struct mnl_socket *)ipset_env->mnl;
|
||||
if (mnl) {
|
||||
mnl_socket_close(mnl);
|
||||
ipset_env->mnl = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
static int ipset_new(struct module_qstate* qstate, int id) {
|
||||
struct ipset_qstate *iq = (struct ipset_qstate *)regional_alloc(
|
||||
qstate->region, sizeof(struct ipset_qstate));
|
||||
qstate->minfo[id] = iq;
|
||||
if (!iq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
/* initialise it */
|
||||
/* TODO */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
|
||||
struct outbound_entry *outbound) {
|
||||
struct ipset_env *ie = (struct ipset_env *)qstate->env->modinfo[id];
|
||||
struct ipset_qstate *iq = (struct ipset_qstate *)qstate->minfo[id];
|
||||
verbose(VERB_QUERY, "ipset[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
||||
if (iq) {
|
||||
log_query_info(VERB_QUERY, "ipset operate: query", &qstate->qinfo);
|
||||
}
|
||||
|
||||
/* perform ipset state machine */
|
||||
if ((event == module_event_new || event == module_event_pass) && !iq) {
|
||||
if (!ipset_new(qstate, id)) {
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
iq = (struct ipset_qstate*)qstate->minfo[id];
|
||||
}
|
||||
|
||||
if (iq && (event == module_event_pass || event == module_event_new)) {
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
if (iq && (event == module_event_moddone)) {
|
||||
if (qstate->return_msg && qstate->return_msg->rep) {
|
||||
ipset_update(qstate->env, qstate->return_msg, ie);
|
||||
}
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
if (iq && outbound) {
|
||||
/* ipset does not need to process responses at this time
|
||||
* ignore it.
|
||||
ipset_process_response(qstate, iq, ie, id, outbound, event);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == module_event_error) {
|
||||
verbose(VERB_ALGO, "got called with event error, giving up");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iq && (event == module_event_moddone)) {
|
||||
/* during priming, module done but we never started */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
log_err("bad event for ipset");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
void ipset_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
|
||||
int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) {
|
||||
/* ipset does not use subordinate requests at this time */
|
||||
verbose(VERB_ALGO, "ipset inform_super was called");
|
||||
}
|
||||
|
||||
void ipset_clear(struct module_qstate *qstate, int id) {
|
||||
struct cachedb_qstate *iq;
|
||||
if (!qstate) {
|
||||
return;
|
||||
}
|
||||
iq = (struct cachedb_qstate *)qstate->minfo[id];
|
||||
if (iq) {
|
||||
/* free contents of iq */
|
||||
/* TODO */
|
||||
}
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
size_t ipset_get_mem(struct module_env *env, int id) {
|
||||
struct ipset_env *ie = (struct ipset_env *)env->modinfo[id];
|
||||
if (!ie) {
|
||||
return 0;
|
||||
}
|
||||
return sizeof(*ie);
|
||||
}
|
||||
|
||||
/**
|
||||
* The ipset function block
|
||||
*/
|
||||
static struct module_func_block ipset_block = {
|
||||
"ipset",
|
||||
&ipset_init, &ipset_deinit, &ipset_operate,
|
||||
&ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block * ipset_get_funcblock(void) {
|
||||
return &ipset_block;
|
||||
}
|
||||
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* ipset.h
|
||||
*
|
||||
* Author: Kevin Chou
|
||||
* Email: k9982874@gmail.com
|
||||
*/
|
||||
#ifndef IPSET_H
|
||||
#define IPSET_H
|
||||
/** \file
|
||||
*
|
||||
* This file implements the ipset module. It can handle packets by putting
|
||||
* the A and AAAA addresses that are configured in unbound.conf as type
|
||||
* ipset (local-zone statements) into a firewall rule IPSet. For firewall
|
||||
* blacklist and whitelist usage.
|
||||
*
|
||||
* To use the IPset module, install the libmnl-dev (or libmnl-devel) package
|
||||
* and configure with --enable-ipset. And compile. Then enable the ipset
|
||||
* module in unbound.conf with module-config: "ipset validator iterator"
|
||||
* then create it with ipset -N blacklist iphash and then add
|
||||
* local-zone: "example.com." ipset
|
||||
* statements for the zones where you want the addresses of the names
|
||||
* looked up added to the set.
|
||||
*
|
||||
* Set the name of the set with
|
||||
* ipset:
|
||||
* name-v4: "blacklist"
|
||||
* name-v6: "blacklist6"
|
||||
* in unbound.conf. The set can be used in this way:
|
||||
* iptables -A INPUT -m set --set blacklist src -j DROP
|
||||
* ip6tables -A INPUT -m set --set blacklist6 src -j DROP
|
||||
*/
|
||||
|
||||
#include "util/module.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ipset_env {
|
||||
void* mnl;
|
||||
|
||||
int v4_enabled;
|
||||
int v6_enabled;
|
||||
|
||||
const char *name_v4;
|
||||
const char *name_v6;
|
||||
};
|
||||
|
||||
struct ipset_qstate {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/** Init the ipset module */
|
||||
int ipset_init(struct module_env* env, int id);
|
||||
/** Deinit the ipset module */
|
||||
void ipset_deinit(struct module_env* env, int id);
|
||||
/** Operate on an event on a query (in qstate). */
|
||||
void ipset_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound);
|
||||
/** Subordinate query done, inform this super request of its conclusion */
|
||||
void ipset_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
/** clear the ipset query-specific contents out of qstate */
|
||||
void ipset_clear(struct module_qstate* qstate, int id);
|
||||
/** return memory estimate for ipset module */
|
||||
size_t ipset_get_mem(struct module_env* env, int id);
|
||||
|
||||
/**
|
||||
* Get the function block with pointers to the ipset functions
|
||||
* @return the function block for "ipset".
|
||||
*/
|
||||
struct module_func_block* ipset_get_funcblock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* IPSET_H */
|
||||
|
||||
+1
-1
@@ -239,7 +239,7 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
#ifndef HAVE_SSL_SET1_HOST
|
||||
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
if(tls_auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
"ssl library, ignored name for %s", p->str);
|
||||
|
||||
@@ -252,7 +252,7 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
#ifndef HAVE_SSL_SET1_HOST
|
||||
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
if(auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
"ssl library, ignored name for %s", p->str);
|
||||
|
||||
+32
-13
@@ -217,6 +217,10 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
|
||||
size_t dtarglen;
|
||||
if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))
|
||||
return 0;
|
||||
if(qnamelen <= dname_rrset->dname_len)
|
||||
return 0;
|
||||
if(qnamelen == 0)
|
||||
return 0;
|
||||
log_assert(qnamelen > dname_rrset->dname_len);
|
||||
/* DNAME from com. to net. with qname example.com. -> example.net. */
|
||||
/* so: \3com\0 to \3net\0 and qname \7example\3com\0 */
|
||||
@@ -316,6 +320,18 @@ sub_of_pkt(sldns_buffer* pkt, uint8_t* zone, uint8_t* comprname)
|
||||
return dname_subdomain_c(zone, buf);
|
||||
}
|
||||
|
||||
/** Check if there are SOA records in the authority section (negative) */
|
||||
static int
|
||||
soa_in_auth(struct msg_parse* msg)
|
||||
{
|
||||
struct rrset_parse* rrset;
|
||||
for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
|
||||
if(rrset->type == LDNS_RR_TYPE_SOA &&
|
||||
rrset->section == LDNS_SECTION_AUTHORITY)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine normalizes a response. This includes removing "irrelevant"
|
||||
* records from the answer and additional sections and (re)synthesizing
|
||||
@@ -437,7 +453,9 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset->rrset_all_next =
|
||||
nx->rrset_all_next;
|
||||
nx->rrset_all_next = rrset;
|
||||
prev = nx;
|
||||
/* prev = nx; unused, enable if there
|
||||
* is other rrset removal code after
|
||||
* this */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,6 +513,19 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* we don't want NS sets for NXDOMAIN answers,
|
||||
* because they could contain poisonous contents,
|
||||
* from. eg. fragmentation attacks, inserted after
|
||||
* long RRSIGs in the packet get to the packet
|
||||
* border and such */
|
||||
/* also for NODATA answers */
|
||||
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN ||
|
||||
(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR
|
||||
&& soa_in_auth(msg) && msg->an_rrsets == 0)) {
|
||||
remove_rrset("normalize: removing irrelevant "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if(nsset == NULL) {
|
||||
nsset = rrset;
|
||||
} else {
|
||||
@@ -593,18 +624,6 @@ store_rrset(sldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
|
||||
(void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, now);
|
||||
}
|
||||
|
||||
/** Check if there are SOA records in the authority section (negative) */
|
||||
static int
|
||||
soa_in_auth(struct msg_parse* msg)
|
||||
{
|
||||
struct rrset_parse* rrset;
|
||||
for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next)
|
||||
if(rrset->type == LDNS_RR_TYPE_SOA &&
|
||||
rrset->section == LDNS_SECTION_AUTHORITY)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if right hand name in NSEC is within zone
|
||||
* @param rrset: the NSEC rrset
|
||||
|
||||
+182
-14
@@ -282,10 +282,13 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
static int
|
||||
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
|
||||
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
|
||||
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist,
|
||||
size_t* num_suitable_results)
|
||||
{
|
||||
int got_it = 0;
|
||||
struct delegpt_addr* a;
|
||||
*num_suitable_results = 0;
|
||||
|
||||
if(dp->bogus)
|
||||
return 0; /* NS bogus, all bogus, nothing found */
|
||||
for(a=dp->result_list; a; a = a->next_result) {
|
||||
@@ -301,11 +304,58 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
} else if(a->sel_rtt < *best_rtt) {
|
||||
*best_rtt = a->sel_rtt;
|
||||
}
|
||||
(*num_suitable_results)++;
|
||||
}
|
||||
}
|
||||
return got_it;
|
||||
}
|
||||
|
||||
/** compare two rtts, return -1, 0 or 1 */
|
||||
static int
|
||||
rtt_compare(const void* x, const void* y)
|
||||
{
|
||||
if(*(int*)x == *(int*)y)
|
||||
return 0;
|
||||
if(*(int*)x > *(int*)y)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** get RTT for the Nth fastest server */
|
||||
static int
|
||||
nth_rtt(struct delegpt_addr* result_list, size_t num_results, size_t n)
|
||||
{
|
||||
int rtt_band;
|
||||
size_t i;
|
||||
int* rtt_list, *rtt_index;
|
||||
|
||||
if(num_results < 1 || n >= num_results) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtt_list = calloc(num_results, sizeof(int));
|
||||
if(!rtt_list) {
|
||||
log_err("malloc failure: allocating rtt_list");
|
||||
return -1;
|
||||
}
|
||||
rtt_index = rtt_list;
|
||||
|
||||
for(i=0; i<num_results && result_list; i++) {
|
||||
if(result_list->sel_rtt != -1) {
|
||||
*rtt_index = result_list->sel_rtt;
|
||||
rtt_index++;
|
||||
}
|
||||
result_list=result_list->next_result;
|
||||
}
|
||||
qsort(rtt_list, num_results, sizeof(*rtt_list), rtt_compare);
|
||||
|
||||
log_assert(n > 0);
|
||||
rtt_band = rtt_list[n-1];
|
||||
free(rtt_list);
|
||||
|
||||
return rtt_band;
|
||||
}
|
||||
|
||||
/** filter the address list, putting best targets at front,
|
||||
* returns number of best targets (or 0, no suitable targets) */
|
||||
static int
|
||||
@@ -314,12 +364,13 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
struct delegpt* dp, int* selected_rtt, int open_target,
|
||||
struct sock_list* blacklist, time_t prefetch)
|
||||
{
|
||||
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
|
||||
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND, nth;
|
||||
size_t num_results;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
|
||||
&low_rtt, blacklist);
|
||||
&low_rtt, blacklist, &num_results);
|
||||
if(got_num == 0)
|
||||
return 0;
|
||||
if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
|
||||
@@ -329,14 +380,19 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
return 0 to force the caller to fetch more */
|
||||
}
|
||||
|
||||
if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
|
||||
low_rtt < env->cfg->low_rtt &&
|
||||
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
|
||||
if(env->cfg->fast_server_permil != 0 && prefetch == 0 &&
|
||||
num_results > env->cfg->fast_server_num &&
|
||||
ub_random_max(env->rnd, 1000) < env->cfg->fast_server_permil) {
|
||||
/* the query is not prefetch, but for a downstream client,
|
||||
* there is a low_rtt (fast) server. We choose that x% of the
|
||||
* time */
|
||||
/* pick rtt numbers from 0..LOWBAND_RTT */
|
||||
rtt_band = env->cfg->low_rtt - low_rtt;
|
||||
* there are more servers available then the fastest N we want
|
||||
* to choose from. Limit our choice to the fastest servers. */
|
||||
nth = nth_rtt(dp->result_list, num_results,
|
||||
env->cfg->fast_server_num);
|
||||
if(nth > 0) {
|
||||
rtt_band = nth - low_rtt;
|
||||
if(rtt_band > RTT_BAND)
|
||||
rtt_band = RTT_BAND;
|
||||
}
|
||||
}
|
||||
|
||||
got_num = 0;
|
||||
@@ -826,10 +882,35 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** compare rrsets and sort canonically. Compares rrset name, type, class.
|
||||
* return 0 if equal, +1 if x > y, and -1 if x < y.
|
||||
*/
|
||||
static int
|
||||
rrset_canonical_sort_cmp(const void* x, const void* y)
|
||||
{
|
||||
struct ub_packed_rrset_key* rrx = *(struct ub_packed_rrset_key**)x;
|
||||
struct ub_packed_rrset_key* rry = *(struct ub_packed_rrset_key**)y;
|
||||
int r = dname_canonical_compare(rrx->rk.dname, rry->rk.dname);
|
||||
if(r != 0)
|
||||
return r;
|
||||
if(rrx->rk.type != rry->rk.type) {
|
||||
if(ntohs(rrx->rk.type) > ntohs(rry->rk.type))
|
||||
return 1;
|
||||
else return -1;
|
||||
}
|
||||
if(rrx->rk.rrset_class != rry->rk.rrset_class) {
|
||||
if(ntohs(rrx->rk.rrset_class) > ntohs(rry->rk.rrset_class))
|
||||
return 1;
|
||||
else return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key** sorted_p, **sorted_q;
|
||||
if(p->flags != q->flags ||
|
||||
p->qdcount != q->qdcount ||
|
||||
/* do not check TTL, this may differ */
|
||||
@@ -843,16 +924,43 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
|
||||
p->ar_numrrsets != q->ar_numrrsets ||
|
||||
p->rrset_count != q->rrset_count)
|
||||
return 0;
|
||||
/* sort the rrsets in the authority and additional sections before
|
||||
* compare, the query and answer sections are ordered in the sequence
|
||||
* they should have (eg. one after the other for aliases). */
|
||||
sorted_p = (struct ub_packed_rrset_key**)regional_alloc_init(
|
||||
region, p->rrsets, sizeof(*sorted_p)*p->rrset_count);
|
||||
if(!sorted_p) return 0;
|
||||
log_assert(p->an_numrrsets + p->ns_numrrsets + p->ar_numrrsets <=
|
||||
p->rrset_count);
|
||||
qsort(sorted_p + p->an_numrrsets, p->ns_numrrsets,
|
||||
sizeof(*sorted_p), rrset_canonical_sort_cmp);
|
||||
qsort(sorted_p + p->an_numrrsets + p->ns_numrrsets, p->ar_numrrsets,
|
||||
sizeof(*sorted_p), rrset_canonical_sort_cmp);
|
||||
|
||||
sorted_q = (struct ub_packed_rrset_key**)regional_alloc_init(
|
||||
region, q->rrsets, sizeof(*sorted_q)*q->rrset_count);
|
||||
if(!sorted_q) {
|
||||
regional_free_all(region);
|
||||
return 0;
|
||||
}
|
||||
log_assert(q->an_numrrsets + q->ns_numrrsets + q->ar_numrrsets <=
|
||||
q->rrset_count);
|
||||
qsort(sorted_q + q->an_numrrsets, q->ns_numrrsets,
|
||||
sizeof(*sorted_q), rrset_canonical_sort_cmp);
|
||||
qsort(sorted_q + q->an_numrrsets + q->ns_numrrsets, q->ar_numrrsets,
|
||||
sizeof(*sorted_q), rrset_canonical_sort_cmp);
|
||||
|
||||
/* compare the rrsets */
|
||||
for(i=0; i<p->rrset_count; i++) {
|
||||
if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
|
||||
if(!rrset_canonical_equal(region, p->rrsets[i],
|
||||
q->rrsets[i])) {
|
||||
if(!rrset_equal(sorted_p[i], sorted_q[i])) {
|
||||
if(!rrset_canonical_equal(region, sorted_p[i],
|
||||
sorted_q[i])) {
|
||||
regional_free_all(region);
|
||||
return 0;
|
||||
}
|
||||
regional_free_all(region);
|
||||
}
|
||||
}
|
||||
regional_free_all(region);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1103,6 +1211,19 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iter_scrub_nxdomain(struct dns_msg* msg)
|
||||
{
|
||||
if(msg->rep->an_numrrsets == 0)
|
||||
return;
|
||||
|
||||
memmove(msg->rep->rrsets, msg->rep->rrsets+msg->rep->an_numrrsets,
|
||||
sizeof(struct ub_packed_rrset_key*) *
|
||||
(msg->rep->rrset_count-msg->rep->an_numrrsets));
|
||||
msg->rep->rrset_count -= msg->rep->an_numrrsets;
|
||||
msg->rep->an_numrrsets = 0;
|
||||
}
|
||||
|
||||
void iter_dec_attempts(struct delegpt* dp, int d)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
@@ -1210,3 +1331,50 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
|
||||
{
|
||||
struct iter_hints_stub *stub;
|
||||
struct delegpt *dp;
|
||||
|
||||
/* Check for stub. */
|
||||
stub = hints_lookup_stub(qstate->env->hints, qinf->qname,
|
||||
qinf->qclass, NULL);
|
||||
dp = forwards_lookup(qstate->env->fwds, qinf->qname, qinf->qclass);
|
||||
|
||||
/* see if forward or stub is more pertinent */
|
||||
if(stub && stub->dp && dp) {
|
||||
if(dname_strict_subdomain(dp->name, dp->namelabs,
|
||||
stub->dp->name, stub->dp->namelabs)) {
|
||||
stub = NULL; /* ignore stub, forward is lower */
|
||||
} else {
|
||||
dp = NULL; /* ignore forward, stub is lower */
|
||||
}
|
||||
}
|
||||
|
||||
/* check stub */
|
||||
if (stub != NULL && stub->dp != NULL) {
|
||||
if(stub->dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(qinf->qname, qname);
|
||||
dname_str(stub->dp->name, dpname);
|
||||
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (stub->dp->no_cache);
|
||||
}
|
||||
|
||||
/* Check for forward. */
|
||||
if (dp) {
|
||||
if(dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(qinf->qname, qname);
|
||||
dname_str(dp->name, dpname);
|
||||
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (dp->no_cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -334,6 +334,13 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
|
||||
void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
|
||||
uint8_t* z);
|
||||
|
||||
/**
|
||||
* Prepare an NXDOMAIN message to be used for a subdomain answer by removing all
|
||||
* RRs from the ANSWER section.
|
||||
* @param msg: the response to scrub.
|
||||
*/
|
||||
void iter_scrub_nxdomain(struct dns_msg* msg);
|
||||
|
||||
/**
|
||||
* Remove query attempts from all available ips. For 0x20.
|
||||
* @param dp: delegpt.
|
||||
@@ -369,4 +376,13 @@ int iter_ds_toolow(struct dns_msg* msg, struct delegpt* dp);
|
||||
*/
|
||||
int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* Lookup if no_cache is set in stub or fwd.
|
||||
* @param qstate: query state with env with hints and fwds.
|
||||
* @param qinf: query name to lookup for.
|
||||
* @return true if no_cache is set in stub or fwd.
|
||||
*/
|
||||
int iter_stub_fwd_no_cache(struct module_qstate *qstate,
|
||||
struct query_info *qinf);
|
||||
|
||||
#endif /* ITERATOR_ITER_UTILS_H */
|
||||
|
||||
+76
-59
@@ -69,6 +69,9 @@
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
/* in msec */
|
||||
int UNKNOWN_SERVER_NICENESS = 376;
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
{
|
||||
@@ -324,6 +327,29 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
/* serving expired contents, but nothing is cached
|
||||
* at all, so the servfail cache entry is useful
|
||||
* (stops waste of time on this servfail NORR_TTL) */
|
||||
} else {
|
||||
/* don't overwrite existing (non-expired) data in
|
||||
* cache with a servfail */
|
||||
struct msgreply_entry* msg;
|
||||
if((msg=msg_cache_lookup(qstate->env,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
qstate->query_flags, *qstate->env->now, 0))
|
||||
!= NULL) {
|
||||
struct reply_info* rep = (struct reply_info*)
|
||||
msg->entry.data;
|
||||
if(FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_NOERROR ||
|
||||
FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
/* we have a good entry,
|
||||
* don't overwrite */
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
}
|
||||
|
||||
}
|
||||
memset(&err, 0, sizeof(err));
|
||||
err.flags = (uint16_t)(BIT_QR | BIT_RA);
|
||||
@@ -383,6 +409,8 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
|
||||
num_an = 0;
|
||||
for(p = iq->an_prepend_list; p; p = p->next) {
|
||||
sets[num_an++] = p->rrset;
|
||||
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
|
||||
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
|
||||
}
|
||||
memcpy(sets+num_an, msg->rep->rrsets, msg->rep->an_numrrsets *
|
||||
sizeof(struct ub_packed_rrset_key*));
|
||||
@@ -395,6 +423,8 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
|
||||
msg->rep->ns_numrrsets, p->rrset))
|
||||
continue;
|
||||
sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
|
||||
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
|
||||
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
|
||||
}
|
||||
memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns,
|
||||
msg->rep->rrsets + msg->rep->an_numrrsets,
|
||||
@@ -1125,7 +1155,7 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
struct delegpt* dp;
|
||||
uint8_t* delname = iq->qchase.qname;
|
||||
size_t delnamelen = iq->qchase.qname_len;
|
||||
if(iq->refetch_glue) {
|
||||
if(iq->refetch_glue && iq->dp) {
|
||||
delname = iq->dp->name;
|
||||
delnamelen = iq->dp->namelen;
|
||||
}
|
||||
@@ -1144,53 +1174,6 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct iter_qstate *iq)
|
||||
{
|
||||
struct iter_hints_stub *stub;
|
||||
struct delegpt *dp;
|
||||
|
||||
/* Check for stub. */
|
||||
stub = hints_lookup_stub(qstate->env->hints, iq->qchase.qname,
|
||||
iq->qchase.qclass, iq->dp);
|
||||
dp = forwards_lookup(qstate->env->fwds, iq->qchase.qname, iq->qchase.qclass);
|
||||
|
||||
/* see if forward or stub is more pertinent */
|
||||
if(stub && stub->dp && dp) {
|
||||
if(dname_strict_subdomain(dp->name, dp->namelabs,
|
||||
stub->dp->name, stub->dp->namelabs)) {
|
||||
stub = NULL; /* ignore stub, forward is lower */
|
||||
} else {
|
||||
dp = NULL; /* ignore forward, stub is lower */
|
||||
}
|
||||
}
|
||||
|
||||
/* check stub */
|
||||
if (stub != NULL && stub->dp != NULL) {
|
||||
if(stub->dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(iq->qchase.qname, qname);
|
||||
dname_str(stub->dp->name, dpname);
|
||||
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (stub->dp->no_cache);
|
||||
}
|
||||
|
||||
/* Check for forward. */
|
||||
if (dp) {
|
||||
if(dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(iq->qchase.qname, qname);
|
||||
dname_str(dp->name, dpname);
|
||||
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (dp->no_cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the initial part of the request handling. This state roughly
|
||||
* corresponds to resolver algorithms steps 1 (find answer in cache) and 2
|
||||
@@ -1268,7 +1251,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* This either results in a query restart (CNAME cache response), a
|
||||
* terminating response (ANSWER), or a cache miss (null). */
|
||||
|
||||
if (iter_stub_fwd_no_cache(qstate, iq)) {
|
||||
if (iter_stub_fwd_no_cache(qstate, &iq->qchase)) {
|
||||
/* Asked to not query cache. */
|
||||
verbose(VERB_ALGO, "no-cache set, going to the network");
|
||||
qstate->no_cache_lookup = 1;
|
||||
@@ -1469,7 +1452,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* now will also exceed the rate, keeping cache fresh */
|
||||
(void)infra_ratelimit_inc(qstate->env->infra_cache,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
*qstate->env->now);
|
||||
*qstate->env->now, &qstate->qinfo,
|
||||
qstate->reply);
|
||||
/* see if we are passed through with slip factor */
|
||||
if(qstate->env->cfg->ratelimit_factor != 0 &&
|
||||
ub_random_max(qstate->env->rnd,
|
||||
@@ -1903,7 +1887,6 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct delegpt* p = hints_lookup_root(qstate->env->hints,
|
||||
iq->qchase.qclass);
|
||||
if(p) {
|
||||
struct delegpt_ns* ns;
|
||||
struct delegpt_addr* a;
|
||||
iq->chase_flags &= ~BIT_RD; /* go to authorities */
|
||||
for(ns = p->nslist; ns; ns=ns->next) {
|
||||
@@ -2127,6 +2110,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
int auth_fallback = 0;
|
||||
uint8_t* qout_orig = NULL;
|
||||
size_t qout_orig_len = 0;
|
||||
|
||||
/* NOTE: a request will encounter this state for each target it
|
||||
* needs to send a query to. That is, at least one per referral,
|
||||
@@ -2174,7 +2159,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE) {
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
/* (Re)set qinfo_out to (new) delegation point, except when
|
||||
* qinfo_out is already a subdomain of dp. This happens when
|
||||
* increasing by more than one label at once (QNAMEs with more
|
||||
@@ -2199,6 +2185,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int labdiff = qchaselabs -
|
||||
dname_count_labels(iq->qinfo_out.qname);
|
||||
|
||||
qout_orig = iq->qinfo_out.qname;
|
||||
qout_orig_len = iq->qinfo_out.qname_len;
|
||||
iq->qinfo_out.qname = iq->qchase.qname;
|
||||
iq->qinfo_out.qname_len = iq->qchase.qname_len;
|
||||
iq->minimise_count++;
|
||||
@@ -2319,7 +2307,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
errinf(qstate, "auth zone lookup failed, fallback is off");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->dp && iq->dp->auth_dp) {
|
||||
if(iq->dp->auth_dp) {
|
||||
/* we wanted to fallback, but had no delegpt, only the
|
||||
* auth zone generated delegpt, create an actual one */
|
||||
iq->auth_zone_avoid = 1;
|
||||
@@ -2351,6 +2339,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* wait to get all targets, we want to try em */
|
||||
verbose(VERB_ALGO, "wait for all targets for fallback");
|
||||
qstate->ext_state[id] = module_wait_reply;
|
||||
/* undo qname minimise step because we'll get back here
|
||||
* to do it again */
|
||||
if(qout_orig && iq->minimise_count > 0) {
|
||||
iq->minimise_count--;
|
||||
iq->qinfo_out.qname = qout_orig;
|
||||
iq->qinfo_out.qname_len = qout_orig_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* did we do enough fallback queries already? */
|
||||
@@ -2484,13 +2479,21 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->num_current_queries);
|
||||
qstate->ext_state[id] = module_wait_reply;
|
||||
}
|
||||
/* undo qname minimise step because we'll get back here
|
||||
* to do it again */
|
||||
if(qout_orig && iq->minimise_count > 0) {
|
||||
iq->minimise_count--;
|
||||
iq->qinfo_out.qname = qout_orig;
|
||||
iq->qinfo_out.qname_len = qout_orig_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if not forwarding, check ratelimits per delegationpoint name */
|
||||
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
|
||||
if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name,
|
||||
iq->dp->namelen, *qstate->env->now)) {
|
||||
iq->dp->namelen, *qstate->env->now, &qstate->qinfo,
|
||||
qstate->reply)) {
|
||||
lock_basic_lock(&ie->queries_ratelimit_lock);
|
||||
ie->num_queries_ratelimited++;
|
||||
lock_basic_unlock(&ie->queries_ratelimit_lock);
|
||||
@@ -2715,11 +2718,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
if(qstate->env->cfg->qname_minimisation_strict)
|
||||
return final_state(iq);
|
||||
if(qstate->env->cfg->qname_minimisation_strict) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
iter_scrub_nxdomain(iq->response);
|
||||
return final_state(iq);
|
||||
}
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* Best effort qname-minimisation.
|
||||
* Stop minimising and send full query when
|
||||
* RCODE is not NOERROR. */
|
||||
@@ -2752,6 +2763,12 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
verbose(VERB_ALGO,
|
||||
"could not validate NXDOMAIN "
|
||||
"response");
|
||||
outbound_list_clear(&iq->outlist);
|
||||
iq->num_current_queries = 0;
|
||||
fptr_ok(fptr_whitelist_modenv_detach_subs(
|
||||
qstate->env->detach_subs));
|
||||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
}
|
||||
}
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
@@ -2993,7 +3010,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp->name, iq->dp->namelen, qstate->qinfo.qclass)) {
|
||||
verbose(VERB_ALGO, "auth zone response bad, and no"
|
||||
" fallback possible, servfail");
|
||||
errinf_dname(qstate, "reponse is bad, no fallback, "
|
||||
errinf_dname(qstate, "response is bad, no fallback, "
|
||||
"for auth zone", iq->dp->name);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -3584,7 +3601,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(event == module_event_noreply || event == module_event_error) {
|
||||
if(event == module_event_noreply && iq->sent_count >= 3 &&
|
||||
qstate->env->cfg->use_caps_bits_for_id &&
|
||||
!iq->caps_fallback) {
|
||||
!iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
|
||||
/* start fallback */
|
||||
iq->caps_fallback = 1;
|
||||
iq->caps_server = 0;
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ struct rbtree_type;
|
||||
/** how nice is a server without further information, in msec
|
||||
* Equals rtt initial timeout value.
|
||||
*/
|
||||
#define UNKNOWN_SERVER_NICENESS 376
|
||||
extern int UNKNOWN_SERVER_NICENESS;
|
||||
/** maximum timeout before a host is deemed unsuitable, in msec.
|
||||
* After host_ttl this will be timed out and the host will be tried again.
|
||||
* Equals RTT_MAX_TIMEOUT
|
||||
|
||||
+11
-4
@@ -57,9 +57,16 @@ context_finalize(struct ub_ctx* ctx)
|
||||
{
|
||||
struct config_file* cfg = ctx->env->cfg;
|
||||
verbosity = cfg->verbosity;
|
||||
if(ctx->logfile_override)
|
||||
if(ctx_logfile_overridden && !ctx->logfile_override) {
|
||||
log_file(NULL); /* clear that override */
|
||||
ctx_logfile_overridden = 0;
|
||||
}
|
||||
if(ctx->logfile_override) {
|
||||
ctx_logfile_overridden = 1;
|
||||
log_file(ctx->log_out);
|
||||
else log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
} else {
|
||||
log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||
}
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
@@ -392,12 +399,12 @@ struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
|
||||
uint8_t*
|
||||
context_serialize_quit(uint32_t* len)
|
||||
{
|
||||
uint8_t* p = (uint8_t*)malloc(sizeof(uint32_t));
|
||||
uint32_t* p = (uint32_t*)malloc(sizeof(uint32_t));
|
||||
if(!p)
|
||||
return NULL;
|
||||
*len = sizeof(uint32_t);
|
||||
sldns_write_uint32(p, UB_LIBCMD_QUIT);
|
||||
return p;
|
||||
return (uint8_t*)p;
|
||||
}
|
||||
|
||||
enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len)
|
||||
|
||||
@@ -52,6 +52,9 @@ struct tube;
|
||||
struct sldns_buffer;
|
||||
struct ub_event_base;
|
||||
|
||||
/** store that the logfile has a debug override */
|
||||
extern int ctx_logfile_overridden;
|
||||
|
||||
/**
|
||||
* The context structure
|
||||
*
|
||||
@@ -116,6 +119,9 @@ struct ub_ctx {
|
||||
|
||||
/** event base for event oriented interface */
|
||||
struct ub_event_base* event_base;
|
||||
/** true if the event_base is a pluggable base that is malloced
|
||||
* with a user event base inside, if so, clean up the pluggable alloc*/
|
||||
int event_base_malloced;
|
||||
/** libworker for event based interface */
|
||||
struct libworker* event_worker;
|
||||
|
||||
|
||||
+30
-16
@@ -79,18 +79,21 @@
|
||||
#include <iphlpapi.h>
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
/** store that the logfile has a debug override */
|
||||
int ctx_logfile_overridden = 0;
|
||||
|
||||
/** create context functionality, but no pipes */
|
||||
static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
unsigned int seed;
|
||||
#ifdef USE_WINSOCK
|
||||
int r;
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
|
||||
checklock_start();
|
||||
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||
if(!ctx_logfile_overridden)
|
||||
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||
log_ident_set("libunbound");
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
|
||||
@@ -99,7 +102,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
verbosity = 0; /* errors only */
|
||||
verbosity = NO_VERBOSE; /* errors only */
|
||||
checklock_start();
|
||||
ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
|
||||
if(!ctx) {
|
||||
@@ -107,15 +110,12 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
return NULL;
|
||||
}
|
||||
alloc_init(&ctx->superalloc, NULL, 0);
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
|
||||
if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
|
||||
seed = 0;
|
||||
if(!(ctx->seed_rnd = ub_initstate(NULL))) {
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
free(ctx);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
lock_basic_init(&ctx->qqpipe_lock);
|
||||
lock_basic_init(&ctx->rrpipe_lock);
|
||||
lock_basic_init(&ctx->cfglock);
|
||||
@@ -222,6 +222,7 @@ ub_ctx_create_event(struct event_base* eb)
|
||||
ub_ctx_delete(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->event_base_malloced = 1;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -328,6 +329,12 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
alloc_clear(&ctx->superalloc);
|
||||
traverse_postorder(&ctx->queries, delq, NULL);
|
||||
if(ctx_logfile_overridden) {
|
||||
log_file(NULL);
|
||||
ctx_logfile_overridden = 0;
|
||||
}
|
||||
if(ctx->event_base_malloced)
|
||||
free(ctx->event_base);
|
||||
free(ctx);
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
@@ -392,7 +399,6 @@ ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -412,7 +418,6 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -432,7 +437,6 @@ int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
|
||||
dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -452,7 +456,6 @@ ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -473,6 +476,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
log_file((FILE*)out);
|
||||
ctx_logfile_overridden = 1;
|
||||
ctx->logfile_override = 1;
|
||||
ctx->log_out = out;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -728,7 +732,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
*async_id = 0;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!ctx->finalized) {
|
||||
int r = context_finalize(ctx);
|
||||
r = context_finalize(ctx);
|
||||
if(r) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return r;
|
||||
@@ -962,7 +966,6 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
return UB_NOMEM;
|
||||
}
|
||||
if(!cfg_strlist_insert(&s->addrs, dupl)) {
|
||||
free(dupl);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
@@ -971,6 +974,19 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls)
|
||||
{
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
errno=EINVAL;
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
ctx->env->cfg->ssl_upstream = tls;
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
|
||||
int isprime)
|
||||
{
|
||||
@@ -1045,7 +1061,6 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
|
||||
}
|
||||
if(!cfg_strlist_insert(&elem->addrs, a)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(a);
|
||||
errno = ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
@@ -1143,7 +1158,7 @@ int
|
||||
ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
|
||||
{
|
||||
FILE* in;
|
||||
char buf[1024], ldata[1024];
|
||||
char buf[1024], ldata[2048];
|
||||
char* parse, *addr, *name, *ins;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
@@ -1233,7 +1248,6 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
|
||||
ins)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
fclose(in);
|
||||
free(ins);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
|
||||
+6
-13
@@ -122,7 +122,6 @@ libworker_delete_event(struct libworker* w)
|
||||
static struct libworker*
|
||||
libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
{
|
||||
unsigned int seed;
|
||||
struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
|
||||
struct config_file* cfg = ctx->env->cfg;
|
||||
int* ports;
|
||||
@@ -177,17 +176,13 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
}
|
||||
w->env->worker = (struct worker*)w;
|
||||
w->env->probe_timer = NULL;
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((unsigned int)w->thread_num)<<17);
|
||||
seed ^= (unsigned int)w->env->alloc->next_id;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
}
|
||||
if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) {
|
||||
if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) {
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
seed = 0;
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
@@ -207,7 +202,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
hash_set_raninit((uint32_t)ub_random(w->env->rnd));
|
||||
}
|
||||
}
|
||||
seed = 0;
|
||||
|
||||
if(eb)
|
||||
w->base = comm_base_create_event(eb);
|
||||
@@ -222,11 +216,10 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
}
|
||||
numports = cfg_condense_ports(cfg, &ports);
|
||||
if(numports == 0) {
|
||||
int locked = !w->is_bg || w->is_bg_thread;
|
||||
libworker_delete(w);
|
||||
if(locked) {
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->back = outside_network_create(w->base, cfg->msg_buffer_size,
|
||||
@@ -533,7 +526,7 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
|
||||
}
|
||||
|
||||
q->res->rcode = LDNS_RCODE_SERVFAIL;
|
||||
q->msg_security = 0;
|
||||
q->msg_security = sec_status_unchecked;
|
||||
q->msg = memdup(sldns_buffer_begin(buf), sldns_buffer_limit(buf));
|
||||
q->msg_len = sldns_buffer_limit(buf);
|
||||
if(!q->msg) {
|
||||
@@ -657,8 +650,8 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
sec = 1;
|
||||
else if(s == sec_status_secure)
|
||||
sec = 2;
|
||||
(*cb)(cb_arg, rcode, (void*)sldns_buffer_begin(buf),
|
||||
(int)sldns_buffer_limit(buf), sec, why_bogus, was_ratelimited);
|
||||
(*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL),
|
||||
(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,12 +33,26 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
%begin %{
|
||||
/* store state of warning output, restored at later pop */
|
||||
#pragma GCC diagnostic push
|
||||
/* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
%}
|
||||
%module unbound
|
||||
%{
|
||||
/* restore state of warning output, remove the functioncast ignore */
|
||||
#pragma GCC diagnostic pop
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include "libunbound/unbound.h"
|
||||
%}
|
||||
|
||||
@@ -108,7 +122,7 @@
|
||||
|
||||
%inline %{
|
||||
void ub_ctx_free_dbg (struct ub_ctx* c) {
|
||||
printf("******** UB_CTX free 0x%lX ************\n", (long unsigned int)c);
|
||||
printf("******** UB_CTX free 0x%p ************\n", c);
|
||||
ub_ctx_delete(c);
|
||||
}
|
||||
|
||||
@@ -228,6 +242,7 @@
|
||||
RR_TYPE_MAILA = 254,
|
||||
/** any type (wildcard) */
|
||||
RR_TYPE_ANY = 255,
|
||||
RR_TYPE_CAA = 257,
|
||||
|
||||
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
|
||||
RR_TYPE_DLV = 32769,
|
||||
@@ -648,7 +663,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
|
||||
%inline %{
|
||||
void ub_resolve_free_dbg (struct ub_result* r) {
|
||||
printf("******** UB_RESOLVE free 0x%lX ************\n", (long unsigned int)r);
|
||||
printf("******** UB_RESOLVE free 0x%p ************\n", r);
|
||||
ub_resolve_free(r);
|
||||
}
|
||||
%}
|
||||
@@ -809,8 +824,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
"""
|
||||
return self.rcode2str[self.rcode]
|
||||
|
||||
__swig_getmethods__["rcode_str"] = _get_rcode_str
|
||||
if _newclass:rcode_str = _swig_property(_get_rcode_str)
|
||||
rcode_str = property(_get_rcode_str)
|
||||
|
||||
def _get_raw_data(self):
|
||||
"""Result data, a list of network order DNS rdata items.
|
||||
@@ -819,15 +833,13 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
"""
|
||||
return self._ub_result_data(self)
|
||||
|
||||
__swig_getmethods__["rawdata"] = _get_raw_data
|
||||
rawdata = property(_get_raw_data, doc="Returns raw data, a list of rdata items. To decode RAW data use the :attr:`data` attribute which returns an instance of :class:`ub_data` containing the conversion functions.")
|
||||
|
||||
def _get_data(self):
|
||||
if not self.havedata: return None
|
||||
return ub_data(self._ub_result_data(self))
|
||||
|
||||
__swig_getmethods__["data"] = _get_data
|
||||
__swig_getmethods__["packet"] = _packet
|
||||
packet = property(_packet)
|
||||
data = property(_get_data, doc="Returns :class:`ub_data` instance containing various decoding functions or None")
|
||||
|
||||
%}
|
||||
|
||||
@@ -20,6 +20,7 @@ ub_ctx_set_event
|
||||
ub_ctx_set_fwd
|
||||
ub_ctx_set_option
|
||||
ub_ctx_set_stub
|
||||
ub_ctx_set_tls
|
||||
ub_ctx_trustedkeys
|
||||
ub_ctx_zone_add
|
||||
ub_ctx_zone_remove
|
||||
|
||||
@@ -309,6 +309,17 @@ int ub_ctx_config(struct ub_ctx* ctx, const char* fname);
|
||||
*/
|
||||
int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
|
||||
|
||||
/**
|
||||
* Use DNS over TLS to send queries to machines set with ub_ctx_set_fwd().
|
||||
*
|
||||
* @param ctx: context.
|
||||
* At this time it is only possible to set configuration before the
|
||||
* first resolve is done.
|
||||
* @param tls: enable or disable DNS over TLS
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
|
||||
|
||||
/**
|
||||
* Add a stub zone, with given address to send to. This is for custom
|
||||
* root hints or pointing to a local authoritative dns server.
|
||||
@@ -770,6 +781,10 @@ struct ub_server_stats {
|
||||
/** number of queries answered from edns-subnet specific data, and
|
||||
* the answer was from the edns-subnet cache. */
|
||||
long long num_query_subnet_cache;
|
||||
/** number of bytes in the stream wait buffers */
|
||||
long long mem_stream_wait;
|
||||
/** number of TLS connection resume */
|
||||
long long qtls_resume;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2124,7 +2124,7 @@ fi
|
||||
# a configuration failure hint, and exit.
|
||||
func_fatal_configuration ()
|
||||
{
|
||||
func__fatal_error ${1+"$@"} \
|
||||
func_fatal_error ${1+"$@"} \
|
||||
"See the $PACKAGE documentation for more information." \
|
||||
"Fatal configuration error."
|
||||
}
|
||||
@@ -7272,10 +7272,12 @@ func_mode_link ()
|
||||
# -tp=* Portland pgcc target processor selection
|
||||
# --sysroot=* for sysroot support
|
||||
# -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
|
||||
# -specs=* GCC specs files
|
||||
# -stdlib=* select c++ std lib with clang
|
||||
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
|
||||
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
|
||||
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
|
||||
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
|
||||
-specs=*)
|
||||
func_quote_for_eval "$arg"
|
||||
arg=$func_quote_for_eval_result
|
||||
func_append compile_command " $arg"
|
||||
|
||||
+43
-26
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Build unbound distribution tar from the SVN repository.
|
||||
# Build unbound distribution tar from the git repository.
|
||||
#
|
||||
# Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
#
|
||||
@@ -42,7 +42,7 @@ cwd=`pwd`
|
||||
# Utility functions.
|
||||
usage () {
|
||||
cat >&2 <<EOF
|
||||
Usage $0: [-h] [-s] [-d SVN_root] [-w ...args...]
|
||||
Usage $0: [-h] [-s] [-u git_url] [-b git_branch] [-w ...args...]
|
||||
Generate a distribution tar file for unbound.
|
||||
|
||||
-h This usage information.
|
||||
@@ -51,8 +51,10 @@ Generate a distribution tar file for unbound.
|
||||
-rc <nr> Build a release candidate, the given string will be added
|
||||
to the version number
|
||||
(which will then be unbound-<version>rc<number>)
|
||||
-d SVN_root Retrieve the unbound source from the specified repository.
|
||||
Detected from svn working copy if not specified.
|
||||
-u git_url Retrieve the source from the specified repository url.
|
||||
Detected from the working copy if not specified.
|
||||
-b git_branch Retrieve the the specified branch or tag.
|
||||
Detected from the working copy if not specified.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
-w32 32bit windows compile.
|
||||
@@ -115,16 +117,20 @@ replace_version () {
|
||||
replace_text "$1" "VERSION_MICRO\],\[$v1" "VERSION_MICRO\],\[$v2"
|
||||
}
|
||||
|
||||
check_svn_root () {
|
||||
# Check if SVNROOT is specified.
|
||||
if [ -z "$SVNROOT" ]; then
|
||||
if svn info 2>&1 | grep "not a working copy" >/dev/null; then
|
||||
if test -z "$SVNROOT"; then
|
||||
error "SVNROOT must be specified (using -d)"
|
||||
fi
|
||||
check_git_repo () {
|
||||
# Check if git repo and branch are specified.
|
||||
if [ -z "$GITREPO" ]; then
|
||||
if git status 2>&1 | grep "not a git repository" >/dev/null; then
|
||||
error "specify repo (using -u) or use settings detected by starting from working copy directory"
|
||||
else
|
||||
eval `svn info | grep 'URL:' | sed -e 's/URL: /url=/' | head -1`
|
||||
SVNROOT="$url"
|
||||
GITREPO="`git config --get remote.origin.url`"
|
||||
fi
|
||||
fi
|
||||
if [ -z "$GITBRANCH" ]; then
|
||||
if git status 2>&1 | grep "not a git repository" >/dev/null; then
|
||||
error "specify branch (using -b) or use settings detected by starting from working copy directory"
|
||||
else
|
||||
GITBRANCH="`git branch | grep '^\*' | sed -e 's/^\* //'`"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -189,8 +195,12 @@ while [ "$1" ]; do
|
||||
"-h")
|
||||
usage
|
||||
;;
|
||||
"-d")
|
||||
SVNROOT="$2"
|
||||
"-u")
|
||||
GITREPO="$2"
|
||||
shift
|
||||
;;
|
||||
"-b")
|
||||
GITBRANCH="$2"
|
||||
shift
|
||||
;;
|
||||
"-s")
|
||||
@@ -242,7 +252,7 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
cross_flag=""
|
||||
shared_cross_flag=""
|
||||
|
||||
check_svn_root
|
||||
check_git_repo
|
||||
create_temp_dir
|
||||
|
||||
# crosscompile openssl for windows.
|
||||
@@ -301,10 +311,13 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
info "SVNROOT is $SVNROOT"
|
||||
info "Exporting source from SVN."
|
||||
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
|
||||
info "GITREPO is $GITREPO"
|
||||
info "GITBRANCH is $GITBRANCH"
|
||||
info "Exporting source from git."
|
||||
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
|
||||
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from git"
|
||||
rm -rf .git || error_cleanup "Failed to remove .git tracking information"
|
||||
|
||||
# on a re-configure the cache may no longer be valid...
|
||||
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
|
||||
@@ -429,20 +442,24 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_svn_root
|
||||
check_git_repo
|
||||
|
||||
# Start the packaging process.
|
||||
info "SVNROOT is $SVNROOT"
|
||||
info "SNAPSHOT is $SNAPSHOT"
|
||||
info "GITREPO is $GITREPO"
|
||||
info "GITBRANCH is $GITBRANCH"
|
||||
info "SNAPSHOT is $SNAPSHOT"
|
||||
|
||||
#question "Do you wish to continue with these settings?" || error "User abort."
|
||||
|
||||
create_temp_dir
|
||||
|
||||
info "Exporting source from SVN."
|
||||
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
info "Exporting source from git."
|
||||
# --depth=1 and --no-tags reduce the download size.
|
||||
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
|
||||
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
|
||||
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from git"
|
||||
rm -rf .git || error_cleanup "Failed to remove .git tracking information"
|
||||
|
||||
info "Adding libtool utils (libtoolize)."
|
||||
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def init_standard(id, env):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, env.cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
@@ -54,6 +54,25 @@ Script file must contain four compulsory functions:
|
||||
return True
|
||||
|
||||
|
||||
.. function:: init_standard(id, env)
|
||||
|
||||
Initialize module internals, like database etc.
|
||||
Called just once on module load.
|
||||
|
||||
*Preferred* over the init() function above as this function's signature is the
|
||||
same as the C counterpart and allows for extra functionality during init.
|
||||
The previously accessible configuration options can now be found in env.cfg.
|
||||
|
||||
:param id: module identifier (integer)
|
||||
:param env: :class:`module_env` module environment
|
||||
|
||||
::
|
||||
|
||||
def init_standard(id, env):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, env.cfg.python_script))
|
||||
return True
|
||||
|
||||
|
||||
.. function:: deinit(id)
|
||||
|
||||
Deinitialize module internals.
|
||||
|
||||
@@ -103,42 +103,67 @@ Inplace callbacks
|
||||
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
|
||||
:param region: :class:`regional`
|
||||
|
||||
.. function:: register_inplace_cb_reply(py_cb, env)
|
||||
.. function:: inplace_cb_query(qinfo, flags, qstate, addr, zone, region)
|
||||
|
||||
Function prototype for callback functions used in
|
||||
`register_inplace_cb_query`_.
|
||||
|
||||
:param qinfo: :class:`query_info`
|
||||
:param flags: query flags (integer)
|
||||
:param qstate: :class:`module_qstate`
|
||||
:param addr: :class:`sockaddr_storage`
|
||||
:param zone: zone name in wire format (bytes)
|
||||
:param region: :class:`regional`
|
||||
|
||||
.. function:: register_inplace_cb_reply(py_cb, env, id)
|
||||
|
||||
Register py_cb as an inplace reply callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:param id: Module ID.
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_cache(py_cb, env)
|
||||
.. function:: register_inplace_cb_reply_cache(py_cb, env, id)
|
||||
|
||||
Register py_cb as an inplace reply_cache callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:param id: Module ID.
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_local(py_cb, env)
|
||||
.. function:: register_inplace_cb_reply_local(py_cb, env, id)
|
||||
|
||||
Register py_cb as an inplace reply_local callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:param id: Module ID.
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_servfail(py_cb, env)
|
||||
.. function:: register_inplace_cb_reply_servfail(py_cb, env, id)
|
||||
|
||||
Register py_cb as an inplace reply_servfail callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:param id: Module ID.
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_query(py_cb, env, id)
|
||||
|
||||
Register py_cb as an inplace query callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_query`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:param id: Module ID.
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
Logging
|
||||
-------
|
||||
|
||||
@@ -514,3 +514,33 @@ pythonmod_qstate
|
||||
|
||||
Here you can keep your own private data (each thread has own data object).
|
||||
|
||||
sockaddr_storage
|
||||
-------------------------
|
||||
|
||||
.. class:: sockaddr_storage
|
||||
|
||||
The :class:`sockaddr_storage` provides these data attributes:
|
||||
|
||||
.. attribute:: family
|
||||
|
||||
Address family name as a string. Possible values are `ip4`, `ip6`, and `unix`.
|
||||
|
||||
.. attribute:: addr
|
||||
|
||||
Address in presentation format.
|
||||
|
||||
.. attribute:: raw_addr
|
||||
|
||||
Address in network wire format.
|
||||
|
||||
.. attribute:: port
|
||||
|
||||
Port number. Invalid for Unix address.
|
||||
|
||||
.. attribute:: flowinfo
|
||||
|
||||
Flow info value. Valid only for IPv6 address.
|
||||
|
||||
.. attribute:: scope_id
|
||||
|
||||
Scope ID value. Valid only for IPv6 address.
|
||||
|
||||
@@ -0,0 +1,567 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# A plugin for the Unbound DNS resolver to resolve DNS records in
|
||||
# multicast DNS [RFC 6762] via Avahi.
|
||||
#
|
||||
# Copyright (C) 2018-2019 Internet Real-Time Lab, Columbia University
|
||||
# http://www.cs.columbia.edu/irt/
|
||||
#
|
||||
# Written by Jan Janak <janakj@cs.columbia.edu>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
#
|
||||
# Dependendies:
|
||||
# Unbound with pythonmodule configured for Python 3
|
||||
# dnspython [http://www.dnspython.org]
|
||||
# pydbus [https://github.com/LEW21/pydbus]
|
||||
#
|
||||
# To enable Python 3 support, configure Unbound as follows:
|
||||
# PYTHON_VERSION=3 ./configure --with-pythonmodule
|
||||
#
|
||||
# The plugin in meant to be used as a fallback resolver that resolves
|
||||
# records in multicast DNS if the upstream server cannot be reached or
|
||||
# provides no answer (NXDOMAIN).
|
||||
#
|
||||
# mDNS requests for negative records, i.e., records for which Avahi
|
||||
# returns no answer (NXDOMAIN), are expensive. Since there is no
|
||||
# single authoritative server in mDNS, such requests terminate only
|
||||
# via a timeout. The timeout is about a second (if MDNS_TIMEOUT is not
|
||||
# configured), or the value configured via MDNS_TIMEOUT. The
|
||||
# corresponding Unbound thread will be blocked for this amount of
|
||||
# time. For this reason, it is important to configure an appropriate
|
||||
# number of threads in unbound.conf and limit the RR types and names
|
||||
# that will be resolved via Avahi via the environment variables
|
||||
# described later.
|
||||
#
|
||||
# An example unbound.conf with the plugin enabled:
|
||||
#
|
||||
# | server:
|
||||
# | module-config: "validator python iterator"
|
||||
# | num-threads: 32
|
||||
# | cache-max-negative-ttl: 60
|
||||
# | cache-max-ttl: 60
|
||||
#
|
||||
#
|
||||
# The plugin can also be run interactively. Provide the name and
|
||||
# record type to be resolved as command line arguments and the
|
||||
# resolved record will be printed to standard output:
|
||||
#
|
||||
# $ ./avahi-resolver.py voip-phx4.phxnet.org A
|
||||
# voip-phx4.phxnet.org. 120 IN A 10.4.3.2
|
||||
#
|
||||
#
|
||||
# The behavior of the plugin can be controlled via the following
|
||||
# environment variables:
|
||||
#
|
||||
# DBUS_SYSTEM_BUS_ADDRESS
|
||||
#
|
||||
# The address of the system DBus bus, in the format expected by DBus,
|
||||
# e.g., unix:path=/run/avahi/system-bus.sock
|
||||
#
|
||||
#
|
||||
# DEBUG
|
||||
#
|
||||
# Set this environment variable to "yes", "true", "on", or "1" to
|
||||
# enable debugging. In debugging mode, the plugin will output a lot
|
||||
# more information about what it is doing either to the standard
|
||||
# output (when run interactively) or to Unbound via log_info and
|
||||
# log_error.
|
||||
#
|
||||
# By default debugging is disabled.
|
||||
#
|
||||
#
|
||||
# MDNS_TTL
|
||||
#
|
||||
# Avahi does not provide the TTL value for the records it returns.
|
||||
# This environment variable can be used to configure the TTL value for
|
||||
# such records.
|
||||
#
|
||||
# The default value is 120 seconds.
|
||||
#
|
||||
#
|
||||
# MDNS_TIMEOUT
|
||||
#
|
||||
# The maximum amount of time (in milliseconds) an Avahi request is
|
||||
# allowed to run. This value sets the time it takes to resolve
|
||||
# negative (non-existent) records in Avahi. If unset, the request
|
||||
# terminates when Avahi sends the "AllForNow" signal, telling the
|
||||
# client that more records are unlikely to arrive. This takes roughly
|
||||
# about one second. You may need to configure a longer value here on
|
||||
# slower networks, e.g., networks that relay mDNS packets such as
|
||||
# MANETs.
|
||||
#
|
||||
#
|
||||
# MDNS_GETONE
|
||||
#
|
||||
# If set to "true", "1", or "on", an Avahi request will terminate as
|
||||
# soon as at least one record has been found. If there are multiple
|
||||
# nodes in the mDNS network publishing the same record, only one (or
|
||||
# subset) will be returned.
|
||||
#
|
||||
# If set to "false", "0", or "off", the plugin will gather records for
|
||||
# MDNS_TIMEOUT and return all records found. This is only useful in
|
||||
# networks where multiple nodes are known to publish different records
|
||||
# under the same name and the client needs to be able to obtain them
|
||||
# all. When configured this way, all Avahi requests will always take
|
||||
# MDNS_TIMEOUT to complete!
|
||||
#
|
||||
# This option is set to true by default.
|
||||
#
|
||||
#
|
||||
# MDNS_REJECT_TYPES
|
||||
#
|
||||
# A comma-separated list of record types that will NOT be resolved in
|
||||
# mDNS via Avahi. Use this environment variable to prevent specific
|
||||
# record types from being resolved via Avahi. For example, if your
|
||||
# network does not support IPv6, you can put AAAA on this list.
|
||||
#
|
||||
# The default value is an empty list.
|
||||
#
|
||||
# Example: MDNS_REJECT_TYPES=aaaa,mx,soa
|
||||
#
|
||||
#
|
||||
# MDNS_ACCEPT_TYPES
|
||||
#
|
||||
# If set, a record type will be resolved via Avahi if and only if it
|
||||
# is present on this comma-separated list. In other words, this is a
|
||||
# whitelist.
|
||||
#
|
||||
# The default value is an empty list which means all record types will
|
||||
# be resolved via Avahi.
|
||||
#
|
||||
# Example: MDNS_ACCEPT_TYPES=a,ptr,txt,srv,aaaa,cname
|
||||
#
|
||||
#
|
||||
# MDNS_REJECT_NAMES
|
||||
#
|
||||
# If the name being resolved matches the regular expression in this
|
||||
# environment variable, the name will NOT be resolved via Avahi. In
|
||||
# other words, this environment variable provides a blacklist.
|
||||
#
|
||||
# The default value is empty--no names will be reject.
|
||||
#
|
||||
# Example: MDNS_REJECT_NAMES=(^|\.)example\.com\.$
|
||||
#
|
||||
#
|
||||
# MDNS_ACCEPT_NAMES
|
||||
#
|
||||
# If set to a regular expression, a name will be resolved via Avahi if
|
||||
# and only if it matches the regular expression. In other words, this
|
||||
# variable provides a whitelist.
|
||||
#
|
||||
# The default value is empty--all names will be resolved via Avahi.
|
||||
#
|
||||
# Example: MDNS_ACCEPT_NAMES=^.*\.example\.com\.$
|
||||
#
|
||||
|
||||
import os
|
||||
import re
|
||||
import array
|
||||
import threading
|
||||
import traceback
|
||||
import dns.rdata
|
||||
import dns.rdatatype
|
||||
import dns.rdataclass
|
||||
from queue import Queue
|
||||
from gi.repository import GLib
|
||||
from pydbus import SystemBus
|
||||
|
||||
|
||||
IF_UNSPEC = -1
|
||||
PROTO_UNSPEC = -1
|
||||
|
||||
sysbus = None
|
||||
avahi = None
|
||||
trampoline = dict()
|
||||
thread_local = threading.local()
|
||||
dbus_thread = None
|
||||
dbus_loop = None
|
||||
|
||||
|
||||
def str2bool(v):
|
||||
if v.lower() in ['false', 'no', '0', 'off', '']:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def dbg(msg):
|
||||
if DEBUG != False:
|
||||
log_info('avahi-resolver: %s' % msg)
|
||||
|
||||
|
||||
#
|
||||
# Although pydbus has an internal facility for handling signals, we
|
||||
# cannot use that with Avahi. When responding from an internal cache,
|
||||
# Avahi sends the first signal very quickly, before pydbus has had a
|
||||
# chance to subscribe for the signal. This will result in lost signal
|
||||
# and missed data:
|
||||
#
|
||||
# https://github.com/LEW21/pydbus/issues/87
|
||||
#
|
||||
# As a workaround, we subscribe to all signals before creating a
|
||||
# record browser and do our own signal matching and dispatching via
|
||||
# the following function.
|
||||
#
|
||||
def signal_dispatcher(connection, sender, path, interface, name, args):
|
||||
o = trampoline.get(path, None)
|
||||
if o is None:
|
||||
return
|
||||
|
||||
if name == 'ItemNew': o.itemNew(*args)
|
||||
elif name == 'ItemRemove': o.itemRemove(*args)
|
||||
elif name == 'AllForNow': o.allForNow(*args)
|
||||
elif name == 'Failure': o.failure(*args)
|
||||
|
||||
|
||||
class RecordBrowser:
|
||||
def __init__(self, callback, name, type_, timeout=None, getone=True):
|
||||
self.callback = callback
|
||||
self.records = []
|
||||
self.error = None
|
||||
self.getone = getone
|
||||
|
||||
self.timer = None if timeout is None else GLib.timeout_add(timeout, self.timedOut)
|
||||
|
||||
self.browser_path = avahi.RecordBrowserNew(IF_UNSPEC, PROTO_UNSPEC, name, dns.rdataclass.IN, type_, 0)
|
||||
trampoline[self.browser_path] = self
|
||||
self.browser = sysbus.get('.Avahi', self.browser_path)
|
||||
self.dbg('Created RecordBrowser(name=%s, type=%s, getone=%s, timeout=%s)'
|
||||
% (name, dns.rdatatype.to_text(type_), getone, timeout))
|
||||
|
||||
def dbg(self, msg):
|
||||
dbg('[%s] %s' % (self.browser_path, msg))
|
||||
|
||||
def _done(self):
|
||||
del trampoline[self.browser_path]
|
||||
self.dbg('Freeing')
|
||||
self.browser.Free()
|
||||
|
||||
if self.timer is not None:
|
||||
self.dbg('Removing timer')
|
||||
GLib.source_remove(self.timer)
|
||||
|
||||
self.callback(self.records, self.error)
|
||||
|
||||
def itemNew(self, interface, protocol, name, class_, type_, rdata, flags):
|
||||
self.dbg('Got signal ItemNew')
|
||||
self.records.append((name, class_, type_, rdata))
|
||||
if self.getone:
|
||||
self._done()
|
||||
|
||||
def itemRemove(self, interface, protocol, name, class_, type_, rdata, flags):
|
||||
self.dbg('Got signal ItemRemove')
|
||||
self.records.remove((name, class_, type_, rdata))
|
||||
|
||||
def failure(self, error):
|
||||
self.dbg('Got signal Failure')
|
||||
self.error = Exception(error)
|
||||
self._done()
|
||||
|
||||
def allForNow(self):
|
||||
self.dbg('Got signal AllForNow')
|
||||
if self.timer is None:
|
||||
self._done()
|
||||
|
||||
def timedOut(self):
|
||||
self.dbg('Timed out')
|
||||
self._done()
|
||||
return False
|
||||
|
||||
|
||||
#
|
||||
# This function runs the main event loop for DBus (GLib). This
|
||||
# function must be run in a dedicated worker thread.
|
||||
#
|
||||
def dbus_main():
|
||||
global sysbus, avahi, dbus_loop
|
||||
|
||||
dbg('Connecting to system DBus')
|
||||
sysbus = SystemBus()
|
||||
|
||||
dbg('Subscribing to .Avahi.RecordBrowser signals')
|
||||
sysbus.con.signal_subscribe('org.freedesktop.Avahi',
|
||||
'org.freedesktop.Avahi.RecordBrowser',
|
||||
None, None, None, 0, signal_dispatcher)
|
||||
|
||||
avahi = sysbus.get('.Avahi', '/')
|
||||
|
||||
dbg("Connected to Avahi Daemon: %s (API %s) [%s]"
|
||||
% (avahi.GetVersionString(), avahi.GetAPIVersion(), avahi.GetHostNameFqdn()))
|
||||
|
||||
dbg('Starting DBus main loop')
|
||||
dbus_loop = GLib.MainLoop()
|
||||
dbus_loop.run()
|
||||
|
||||
|
||||
#
|
||||
# This function must be run in the DBus worker thread. It creates a
|
||||
# new RecordBrowser instance and once it has finished doing it thing,
|
||||
# it will send the result back to the original thread via the queue.
|
||||
#
|
||||
def start_resolver(queue, *args, **kwargs):
|
||||
try:
|
||||
RecordBrowser(lambda *v: queue.put_nowait(v), *args, **kwargs)
|
||||
except Exception as e:
|
||||
queue.put_nowait((None, e))
|
||||
|
||||
return False
|
||||
|
||||
|
||||
#
|
||||
# To resolve a request, we setup a queue, post a task to the DBus
|
||||
# worker thread, and wait for the result (or error) to arrive over the
|
||||
# queue. If the worker thread reports an error, raise the error as an
|
||||
# exception.
|
||||
#
|
||||
def resolve(*args, **kwargs):
|
||||
try:
|
||||
queue = thread_local.queue
|
||||
except AttributeError:
|
||||
dbg('Creating new per-thread queue')
|
||||
queue = Queue()
|
||||
thread_local.queue = queue
|
||||
|
||||
GLib.idle_add(lambda: start_resolver(queue, *args, **kwargs))
|
||||
|
||||
records, error = queue.get()
|
||||
queue.task_done()
|
||||
|
||||
if error is not None:
|
||||
raise error
|
||||
|
||||
return records
|
||||
|
||||
|
||||
def parse_type_list(lst):
|
||||
return list(map(dns.rdatatype.from_text, [v.strip() for v in lst.split(',') if len(v)]))
|
||||
|
||||
|
||||
def init(*args, **kwargs):
|
||||
global dbus_thread, DEBUG
|
||||
global MDNS_TTL, MDNS_GETONE, MDNS_TIMEOUT
|
||||
global MDNS_REJECT_TYPES, MDNS_ACCEPT_TYPES
|
||||
global MDNS_REJECT_NAMES, MDNS_ACCEPT_NAMES
|
||||
|
||||
DEBUG = str2bool(os.environ.get('DEBUG', str(False)))
|
||||
|
||||
MDNS_TTL = int(os.environ.get('MDNS_TTL', 120))
|
||||
dbg("TTL for records from Avahi: %d" % MDNS_TTL)
|
||||
|
||||
MDNS_REJECT_TYPES = parse_type_list(os.environ.get('MDNS_REJECT_TYPES', ''))
|
||||
if MDNS_REJECT_TYPES:
|
||||
dbg('Types NOT resolved via Avahi: %s' % MDNS_REJECT_TYPES)
|
||||
|
||||
MDNS_ACCEPT_TYPES = parse_type_list(os.environ.get('MDNS_ACCEPT_TYPES', ''))
|
||||
if MDNS_ACCEPT_TYPES:
|
||||
dbg('ONLY resolving the following types via Avahi: %s' % MDNS_ACCEPT_TYPES)
|
||||
|
||||
v = os.environ.get('MDNS_REJECT_NAMES', None)
|
||||
MDNS_REJECT_NAMES = re.compile(v, flags=re.I | re.S) if v is not None else None
|
||||
if MDNS_REJECT_NAMES is not None:
|
||||
dbg('Names NOT resolved via Avahi: %s' % MDNS_REJECT_NAMES.pattern)
|
||||
|
||||
v = os.environ.get('MDNS_ACCEPT_NAMES', None)
|
||||
MDNS_ACCEPT_NAMES = re.compile(v, flags=re.I | re.S) if v is not None else None
|
||||
if MDNS_ACCEPT_NAMES is not None:
|
||||
dbg('ONLY resolving the following names via Avahi: %s' % MDNS_ACCEPT_NAMES.pattern)
|
||||
|
||||
v = os.environ.get('MDNS_TIMEOUT', None)
|
||||
MDNS_TIMEOUT = int(v) if v is not None else None
|
||||
if MDNS_TIMEOUT is not None:
|
||||
dbg('Avahi request timeout: %s' % MDNS_TIMEOUT)
|
||||
|
||||
MDNS_GETONE = str2bool(os.environ.get('MDNS_GETONE', str(True)))
|
||||
dbg('Terminate Avahi requests on first record: %s' % MDNS_GETONE)
|
||||
|
||||
dbus_thread = threading.Thread(target=dbus_main)
|
||||
dbus_thread.daemon = True
|
||||
dbus_thread.start()
|
||||
|
||||
|
||||
def deinit(*args, **kwargs):
|
||||
dbus_loop.quit()
|
||||
dbus_thread.join()
|
||||
return True
|
||||
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
|
||||
def get_rcode(msg):
|
||||
if not msg:
|
||||
return RCODE_SERVFAIL
|
||||
|
||||
return msg.rep.flags & 0xf
|
||||
|
||||
|
||||
def rr2text(rec, ttl):
|
||||
name, class_, type_, rdata = rec
|
||||
wire = array.array('B', rdata).tostring()
|
||||
return '%s. %d %s %s %s' % (
|
||||
name,
|
||||
ttl,
|
||||
dns.rdataclass.to_text(class_),
|
||||
dns.rdatatype.to_text(type_),
|
||||
dns.rdata.from_wire(class_, type_, wire, 0, len(wire), None))
|
||||
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
qi = qstate.qinfo
|
||||
name = qi.qname_str
|
||||
type_ = qi.qtype
|
||||
type_str = dns.rdatatype.to_text(type_)
|
||||
class_ = qi.qclass
|
||||
class_str = dns.rdataclass.to_text(class_)
|
||||
rc = get_rcode(qstate.return_msg)
|
||||
|
||||
if event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event != MODULE_EVENT_MODDONE:
|
||||
log_err("avahi-resolver: Unexpected event %d" % event)
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
|
||||
# Only resolve via Avahi if we got NXDOMAIn from the upstream DNS
|
||||
# server, or if we could not reach the upstream DNS server. If we
|
||||
# got some records for the name from the upstream DNS server
|
||||
# already, do not resolve the record in Avahi.
|
||||
if rc != RCODE_NXDOMAIN and rc != RCODE_SERVFAIL:
|
||||
return True
|
||||
|
||||
dbg("Got request for '%s %s %s'" % (name, class_str, type_str))
|
||||
|
||||
# Avahi only supports the IN class
|
||||
if class_ != RR_CLASS_IN:
|
||||
dbg('Rejected, Avahi only supports the IN class')
|
||||
return True
|
||||
|
||||
# Avahi does not support meta queries (e.g., ANY)
|
||||
if dns.rdatatype.is_metatype(type_):
|
||||
dbg('Rejected, Avahi does not support the type %s' % type_str)
|
||||
return True
|
||||
|
||||
# If we have a type blacklist and the requested type is on the
|
||||
# list, reject it.
|
||||
if MDNS_REJECT_TYPES and type_ in MDNS_REJECT_TYPES:
|
||||
dbg('Rejected, type %s is on the blacklist' % type_str)
|
||||
return True
|
||||
|
||||
# If we have a type whitelist and if the requested type is not on
|
||||
# the list, reject it.
|
||||
if MDNS_ACCEPT_TYPES and type_ not in MDNS_ACCEPT_TYPES:
|
||||
dbg('Rejected, type %s is not on the whitelist' % type_str)
|
||||
return True
|
||||
|
||||
# If we have a name blacklist and if the requested name matches
|
||||
# the blacklist, reject it.
|
||||
if MDNS_REJECT_NAMES is not None:
|
||||
if MDNS_REJECT_NAMES.search(name):
|
||||
dbg('Rejected, name %s is on the blacklist' % name)
|
||||
return True
|
||||
|
||||
# If we have a name whitelist and if the requested name does not
|
||||
# match the whitelist, reject it.
|
||||
if MDNS_ACCEPT_NAMES is not None:
|
||||
if not MDNS_ACCEPT_NAMES.search(name):
|
||||
dbg('Rejected, name %s is not on the whitelist' % name)
|
||||
return True
|
||||
|
||||
dbg("Resolving '%s %s %s' via Avahi" % (name, class_str, type_str))
|
||||
|
||||
recs = resolve(name, type_, getone=MDNS_GETONE, timeout=MDNS_TIMEOUT)
|
||||
|
||||
if not recs:
|
||||
dbg('Result: Not found (NXDOMAIN)')
|
||||
qstate.return_rcode = RCODE_NXDOMAIN
|
||||
return True
|
||||
|
||||
m = DNSMessage(name, type_, class_, PKT_QR | PKT_RD | PKT_RA)
|
||||
for r in recs:
|
||||
s = rr2text(r, MDNS_TTL)
|
||||
dbg('Result: %s' % s)
|
||||
m.answer.append(s)
|
||||
|
||||
if not m.set_return_msg(qstate):
|
||||
raise Exception("Error in set_return_msg")
|
||||
|
||||
if not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0):
|
||||
raise Exception("Error in storeQueryInCache")
|
||||
|
||||
qstate.return_msg.rep.security = 2
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
return True
|
||||
|
||||
|
||||
#
|
||||
# It does not appear to be sufficient to check __name__ to determine
|
||||
# whether we are being run in interactive mode. As a workaround, try
|
||||
# to import module unboundmodule and if that fails, assume we're being
|
||||
# run in interactive mode.
|
||||
#
|
||||
try:
|
||||
import unboundmodule
|
||||
embedded = True
|
||||
except ImportError:
|
||||
embedded = False
|
||||
|
||||
if __name__ == '__main__' and not embedded:
|
||||
import sys
|
||||
|
||||
def log_info(msg):
|
||||
print(msg)
|
||||
|
||||
def log_err(msg):
|
||||
print('ERROR: %s' % msg, file=sys.stderr)
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print('Usage: %s <name> <rr_type>' % sys.argv[0])
|
||||
sys.exit(2)
|
||||
|
||||
name = sys.argv[1]
|
||||
type_str = sys.argv[2]
|
||||
|
||||
try:
|
||||
type_ = dns.rdatatype.from_text(type_str)
|
||||
except dns.rdatatype.UnknownRdatatype:
|
||||
log_err('Unsupported DNS record type "%s"' % type_str)
|
||||
sys.exit(2)
|
||||
|
||||
if dns.rdatatype.is_metatype(type_):
|
||||
log_err('Meta record type "%s" cannot be resolved via Avahi' % type_str)
|
||||
sys.exit(2)
|
||||
|
||||
init()
|
||||
try:
|
||||
recs = resolve(name, type_, getone=MDNS_GETONE, timeout=MDNS_TIMEOUT)
|
||||
if not len(recs):
|
||||
print('%s not found (NXDOMAIN)' % name)
|
||||
sys.exit(1)
|
||||
|
||||
for r in recs:
|
||||
print(rr2text(r, MDNS_TTL))
|
||||
finally:
|
||||
deinit()
|
||||
@@ -45,9 +45,13 @@ def operate(id, event, qstate, qdata):
|
||||
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
|
||||
if qstate.qinfo.qname_str.endswith("._calc_.cz."):
|
||||
if qstate.qinfo.qname_str.endswith("._calc_.cz.") and not ("__" in qstate.qinfo.qname_str):
|
||||
try:
|
||||
res = eval(''.join(qstate.qinfo.qname_list[0:-3]))
|
||||
# the second and third argument to eval attempt to restrict
|
||||
# functions and variables available to stop code execution
|
||||
# but it may not be safe either. This is why __ substrings
|
||||
# are excluded from evaluation.
|
||||
res = eval(''.join(qstate.qinfo.qname_list[0:-3]),{"__builtins__":None},{})
|
||||
except:
|
||||
res = "exception"
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ def init_standard(id, env):
|
||||
extra functionality during init.
|
||||
..note:: This function is preferred by unbound over the old init function.
|
||||
..note:: The previously accessible configuration options can now be found in
|
||||
env.cgf.
|
||||
env.cfg.
|
||||
"""
|
||||
log_info("python: inited script {}".format(env.cfg.python_script))
|
||||
|
||||
|
||||
@@ -247,6 +247,25 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
return True
|
||||
|
||||
|
||||
def inplace_query_callback(qinfo, flags, qstate, addr, zone, region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called before sending a query to a backend server.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param flags: flags of the query;
|
||||
:param qstate: module qstate. opt_lists are available here;
|
||||
:param addr: struct sockaddr_storage. Address of the backend server;
|
||||
:param zone: zone name in binary;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_lists.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release.
|
||||
"""
|
||||
log_info("python: outgoing query to {}@{}".format(addr.addr, addr.port))
|
||||
return True
|
||||
|
||||
|
||||
def init_standard(id, env):
|
||||
"""
|
||||
New version of the init function.
|
||||
@@ -256,7 +275,7 @@ def init_standard(id, env):
|
||||
|
||||
..note:: This function is preferred by unbound over the old init function.
|
||||
..note:: The previously accessible configuration options can now be found in
|
||||
env.cgf.
|
||||
env.cfg.
|
||||
|
||||
"""
|
||||
log_info("python: inited script {}".format(env.cfg.python_script))
|
||||
@@ -281,6 +300,11 @@ def init_standard(id, env):
|
||||
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env, id):
|
||||
return False
|
||||
|
||||
# Register the inplace_query_callback function as an inplace callback
|
||||
# before sending a query to a backend server.
|
||||
if not register_inplace_cb_query(inplace_query_callback, env, id):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
+309
-123
@@ -1,17 +1,40 @@
|
||||
/*
|
||||
* interface.i: unbound python module
|
||||
*/
|
||||
%begin %{
|
||||
/* store state of warning output, restored at later pop */
|
||||
#pragma GCC diagnostic push
|
||||
/* ignore warnings for pragma below, where for older GCC it can produce a
|
||||
warning if the cast-function-type warning is absent. */
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
/* ignore gcc8 METH_NOARGS function cast warnings for swig function pointers */
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
%}
|
||||
%module unboundmodule
|
||||
%{
|
||||
/* restore state of warning output, remove the functioncast ignore */
|
||||
#pragma GCC diagnostic pop
|
||||
/**
|
||||
* \file
|
||||
* This is the interface between the unbound server and a python module
|
||||
* called to perform operations on queries.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
@@ -43,15 +66,21 @@
|
||||
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
i += name[i] + 1;
|
||||
i += ((unsigned int)name[i]) + 1;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
list = PyList_New(cnt);
|
||||
i = 0; cnt = 0;
|
||||
while (i < len) {
|
||||
PyList_SetItem(list, cnt, PyBytes_FromStringAndSize(name + i + 1, name[i]));
|
||||
i += name[i] + 1;
|
||||
char buf[LDNS_MAX_LABELLEN+1];
|
||||
if(((unsigned int)name[i])+1 <= (unsigned int)sizeof(buf) &&
|
||||
i+(int)((unsigned int)name[i]) < len) {
|
||||
memmove(buf, name + i + 1, (unsigned int)name[i]);
|
||||
buf[(unsigned int)name[i]] = 0;
|
||||
PyList_SetItem(list, cnt, PyString_FromString(buf));
|
||||
}
|
||||
i += ((unsigned int)name[i]) + 1;
|
||||
cnt++;
|
||||
}
|
||||
return list;
|
||||
@@ -159,33 +188,28 @@ struct query_info {
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
PyObject* dnameAsStr(const char* dname) {
|
||||
PyObject* dnameAsStr(PyObject* dname) {
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
buf[0] = '\0';
|
||||
dname_str((uint8_t*)dname, buf);
|
||||
return PyBytes_FromString(buf);
|
||||
dname_str((uint8_t*)PyBytes_AsString(dname), buf);
|
||||
return PyString_FromString(buf);
|
||||
}
|
||||
%}
|
||||
|
||||
%extend query_info {
|
||||
%pythoncode %{
|
||||
def _get_qtype_str(self): return sldns_wire2str_type(self.qtype)
|
||||
__swig_getmethods__["qtype_str"] = _get_qtype_str
|
||||
if _newclass:qtype_str = _swig_property(_get_qtype_str)
|
||||
qtype_str = property(_get_qtype_str)
|
||||
|
||||
def _get_qclass_str(self): return sldns_wire2str_class(self.qclass)
|
||||
__swig_getmethods__["qclass_str"] = _get_qclass_str
|
||||
if _newclass:qclass_str = _swig_property(_get_qclass_str)
|
||||
qclass_str = property(_get_qclass_str)
|
||||
|
||||
__swig_getmethods__["qname"] = _unboundmodule._get_qname
|
||||
if _newclass:qname = _swig_property(_unboundmodule._get_qname)
|
||||
qname = property(_unboundmodule._get_qname)
|
||||
|
||||
__swig_getmethods__["qname_list"] = _unboundmodule._get_qname_components
|
||||
if _newclass:qname_list = _swig_property(_unboundmodule._get_qname_components)
|
||||
qname_list = property(_unboundmodule._get_qname_components)
|
||||
|
||||
def _get_qname_str(self): return dnameAsStr(self.qname)
|
||||
__swig_getmethods__["qname_str"] = _get_qname_str
|
||||
if _newclass:qname_str = _swig_property(_get_qname_str)
|
||||
qname_str = property(_get_qname_str)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -225,22 +249,17 @@ uint16_t ntohs(uint16_t netshort);
|
||||
%extend packed_rrset_key {
|
||||
%pythoncode %{
|
||||
def _get_type_str(self): return sldns_wire2str_type(_unboundmodule.ntohs(self.type))
|
||||
__swig_getmethods__["type_str"] = _get_type_str
|
||||
if _newclass:type_str = _swig_property(_get_type_str)
|
||||
type_str = property(_get_type_str)
|
||||
|
||||
def _get_class_str(self): return sldns_wire2str_class(_unboundmodule.ntohs(self.rrset_class))
|
||||
__swig_getmethods__["rrset_class_str"] = _get_class_str
|
||||
if _newclass:rrset_class_str = _swig_property(_get_class_str)
|
||||
rrset_class_str = property(_get_class_str)
|
||||
|
||||
__swig_getmethods__["dname"] = _unboundmodule._get_dname
|
||||
if _newclass:dname = _swig_property(_unboundmodule._get_dname)
|
||||
dname = property(_unboundmodule._get_dname)
|
||||
|
||||
__swig_getmethods__["dname_list"] = _unboundmodule._get_dname_components
|
||||
if _newclass:dname_list = _swig_property(_unboundmodule._get_dname_components)
|
||||
dname_list = property(_unboundmodule._get_dname_components)
|
||||
|
||||
def _get_dname_str(self): return dnameAsStr(self.dname)
|
||||
__swig_getmethods__["dname_str"] = _get_dname_str
|
||||
if _newclass:dname_str = _swig_property(_get_dname_str)
|
||||
dname_str = property(_get_dname_str)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -338,14 +357,11 @@ struct packed_rrset_data {
|
||||
%extend packed_rrset_data {
|
||||
%pythoncode %{
|
||||
def _get_data_rr_len(self): return RRSetData_RRLen(self)
|
||||
__swig_getmethods__["rr_len"] = _get_data_rr_len
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_len)
|
||||
rr_len = property(_get_data_rr_len)
|
||||
def _get_data_rr_ttl(self): return RRSetData_RRTTL(self)
|
||||
__swig_getmethods__["rr_ttl"] =_get_data_rr_ttl
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_ttl)
|
||||
rr_ttl = property(_get_data_rr_ttl)
|
||||
def _get_data_rr_data(self): return RRSetData_RRData(self)
|
||||
__swig_getmethods__["rr_data"] = _get_data_rr_data
|
||||
if _newclass:rr_len = _swig_property(_get_data_rr_data)
|
||||
rr_data = property(_get_data_rr_data)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -417,12 +433,166 @@ struct dns_msg {
|
||||
%extend reply_info {
|
||||
%pythoncode %{
|
||||
def _rrset_ref_get(self): return ReplyInfo_Ref(self)
|
||||
__swig_getmethods__["ref"] = _rrset_ref_get
|
||||
if _newclass:ref = _swig_property(_rrset_ref_get)
|
||||
ref = property(_rrset_ref_get)
|
||||
|
||||
def _rrset_rrsets_get(self): return ReplyInfo_RRSet(self)
|
||||
__swig_getmethods__["rrsets"] = _rrset_rrsets_get
|
||||
if _newclass:rrsets = _swig_property(_rrset_rrsets_get)
|
||||
rrsets = property(_rrset_rrsets_get)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure sockaddr_storage
|
||||
* ************************************************************************************ */
|
||||
|
||||
struct sockaddr_storage {};
|
||||
|
||||
%inline %{
|
||||
static size_t _sockaddr_storage_len(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (ss->ss_family) {
|
||||
case AF_INET: return sizeof(struct sockaddr_in);
|
||||
case AF_INET6: return sizeof(struct sockaddr_in6);
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
case AF_UNIX: return sizeof(struct sockaddr_un);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_family(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
switch (ss->ss_family) {
|
||||
case AF_INET: return PyUnicode_FromString("ip4");
|
||||
case AF_INET6: return PyUnicode_FromString("ip6");
|
||||
case AF_UNIX: return PyUnicode_FromString("unix");
|
||||
default:
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_addr(const struct sockaddr_storage *ss) {
|
||||
const struct sockaddr *sa;
|
||||
size_t sa_len;
|
||||
char name[NI_MAXHOST] = {0};
|
||||
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
sa = (struct sockaddr *)ss;
|
||||
sa_len = _sockaddr_storage_len(ss);
|
||||
if (sa_len == 0) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
if (getnameinfo(sa, sa_len, name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
return PyUnicode_FromString(name);
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_raw_addr(const struct sockaddr_storage *ss) {
|
||||
size_t sa_len;
|
||||
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
sa_len = _sockaddr_storage_len(ss);
|
||||
if (sa_len == 0) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
if (ss->ss_family == AF_INET) {
|
||||
const struct sockaddr_in *sa = (struct sockaddr_in *)ss;
|
||||
const struct in_addr *raw = (struct in_addr *)&sa->sin_addr;
|
||||
return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
|
||||
}
|
||||
|
||||
if (ss->ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
|
||||
const struct in6_addr *raw = (struct in6_addr *)&sa->sin6_addr;
|
||||
return PyBytes_FromStringAndSize((const char *)raw, sizeof(*raw));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
if (ss->ss_family == AF_UNIX) {
|
||||
const struct sockaddr_un *sa = (struct sockaddr_un *)ss;
|
||||
return PyBytes_FromString(sa->sun_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_port(const struct sockaddr_storage *ss) {
|
||||
if (ss == NULL) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
if (ss->ss_family == AF_INET) {
|
||||
const struct sockaddr_in *sa4 = (struct sockaddr_in *)ss;
|
||||
return PyInt_FromLong(ntohs(sa4->sin_port));
|
||||
}
|
||||
|
||||
if (ss->ss_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss;
|
||||
return PyInt_FromLong(ntohs(sa6->sin6_port));
|
||||
}
|
||||
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_flowinfo(const struct sockaddr_storage *ss) {
|
||||
const struct sockaddr_in6 *sa6;
|
||||
|
||||
if (ss == NULL || ss->ss_family != AF_INET6) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
sa6 = (struct sockaddr_in6 *)ss;
|
||||
return PyInt_FromLong(ntohl(sa6->sin6_flowinfo));
|
||||
}
|
||||
|
||||
PyObject *_sockaddr_storage_scope_id(const struct sockaddr_storage *ss) {
|
||||
const struct sockaddr_in6 *sa6;
|
||||
|
||||
if (ss == NULL || ss->ss_family != AF_INET6) {
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
sa6 = (struct sockaddr_in6 *)ss;
|
||||
return PyInt_FromLong(ntohl(sa6->sin6_scope_id));
|
||||
}
|
||||
%}
|
||||
|
||||
%extend sockaddr_storage {
|
||||
%pythoncode %{
|
||||
def _family_get(self): return _sockaddr_storage_family(self)
|
||||
family = property(_family_get)
|
||||
|
||||
def _addr_get(self): return _sockaddr_storage_addr(self)
|
||||
addr = property(_addr_get)
|
||||
|
||||
def _raw_addr_get(self): return _sockaddr_storage_raw_addr(self)
|
||||
raw_addr = property(_raw_addr_get)
|
||||
|
||||
def _port_get(self): return _sockaddr_storage_port(self)
|
||||
port = property(_port_get)
|
||||
|
||||
def _flowinfo_get(self): return _sockaddr_storage_flowinfo(self)
|
||||
flowinfo = property(_flowinfo_get)
|
||||
|
||||
def _scope_id_get(self): return _sockaddr_storage_scope_id(self)
|
||||
scope_id = property(_scope_id_get)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -438,54 +608,21 @@ struct mesh_reply {
|
||||
struct comm_reply query_reply;
|
||||
};
|
||||
|
||||
%rename(_addr) comm_reply::addr;
|
||||
struct comm_reply {
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
};
|
||||
|
||||
%inline %{
|
||||
|
||||
PyObject* _comm_reply_addr_get(struct comm_reply* reply) {
|
||||
char dest[64];
|
||||
reply_addr2str(reply, dest, 64);
|
||||
if (dest[0] == 0)
|
||||
return Py_None;
|
||||
return PyBytes_FromString(dest);
|
||||
}
|
||||
|
||||
PyObject* _comm_reply_family_get(struct comm_reply* reply) {
|
||||
|
||||
int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
|
||||
|
||||
switch(af) {
|
||||
case AF_INET: return PyBytes_FromString("ip4");
|
||||
case AF_INET6: return PyBytes_FromString("ip6");
|
||||
case AF_UNIX: return PyBytes_FromString("unix");
|
||||
}
|
||||
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject* _comm_reply_port_get(struct comm_reply* reply) {
|
||||
uint16_t port;
|
||||
port = ntohs(((struct sockaddr_in*)&(reply->addr))->sin_port);
|
||||
return PyInt_FromLong(port);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%extend comm_reply {
|
||||
%pythoncode %{
|
||||
def _addr_get(self): return _comm_reply_addr_get(self)
|
||||
__swig_getmethods__["addr"] = _addr_get
|
||||
if _newclass:addr = _swig_property(_addr_get)
|
||||
def _addr_get(self): return _sockaddr_storage_addr(self._addr)
|
||||
addr = property(_addr_get)
|
||||
|
||||
def _port_get(self): return _comm_reply_port_get(self)
|
||||
__swig_getmethods__["port"] = _port_get
|
||||
if _newclass:port = _swig_property(_port_get)
|
||||
def _port_get(self): return _sockaddr_storage_port(self._addr)
|
||||
port = property(_port_get)
|
||||
|
||||
def _family_get(self): return _comm_reply_family_get(self)
|
||||
__swig_getmethods__["family"] = _family_get
|
||||
if _newclass:family = _swig_property(_family_get)
|
||||
def _family_get(self): return _sockaddr_storage_family(self._addr)
|
||||
family = property(_family_get)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -520,12 +657,10 @@ struct edns_option {
|
||||
%extend edns_option {
|
||||
%pythoncode %{
|
||||
def _opt_code_get(self): return _edns_option_opt_code_get(self)
|
||||
__swig_getmethods__["code"] = _opt_code_get
|
||||
if _newclass: opt_code = _swig_property(_opt_code_get)
|
||||
code = property(_opt_code_get)
|
||||
|
||||
def _opt_data_get(self): return _edns_option_opt_data_get(self)
|
||||
__swig_getmethods__["data"] = _opt_data_get
|
||||
if _newclass: opt_data = _swig_property(_opt_data_get)
|
||||
data = property(_opt_data_get)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -552,11 +687,9 @@ struct edns_data {
|
||||
%extend edns_data {
|
||||
%pythoncode %{
|
||||
def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
|
||||
__swig_getmethods__["opt_list_iter"] = _opt_list_iter
|
||||
if _newclass:opt_list_iter = _swig_property(_opt_list_iter)
|
||||
opt_list_iter = property(_opt_list_iter)
|
||||
def _opt_list(self): return _edns_data_opt_list_get(self)
|
||||
__swig_getmethods__["opt_list"] = _opt_list
|
||||
if _newclass:opt_list = _swig_property(_opt_list)
|
||||
opt_list = property(_opt_list)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -757,34 +890,25 @@ struct module_qstate {
|
||||
_unboundmodule._ext_state_set(self, id, state)
|
||||
|
||||
def __ext_state_get(self): return ExtState(self)
|
||||
__swig_getmethods__["ext_state"] = __ext_state_get
|
||||
if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
|
||||
ext_state = property(__ext_state_get) #, __ext_state_set
|
||||
|
||||
def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
|
||||
__swig_getmethods__["edns_opts_front_in_iter"] = _edns_opts_front_in_iter
|
||||
if _newclass:edns_opts_front_in_iter = _swig_property(_edns_opts_front_in_iter)
|
||||
edns_opts_front_in_iter = property(_edns_opts_front_in_iter)
|
||||
def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
|
||||
__swig_getmethods__["edns_opts_back_out_iter"] = _edns_opts_back_out_iter
|
||||
if _newclass:edns_opts_back_out_iter = _swig_property(_edns_opts_back_out_iter)
|
||||
edns_opts_back_out_iter = property(_edns_opts_back_out_iter)
|
||||
def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
|
||||
__swig_getmethods__["edns_opts_back_in_iter"] = _edns_opts_back_in_iter
|
||||
if _newclass:edns_opts_back_in_iter = _swig_property(_edns_opts_back_in_iter)
|
||||
edns_opts_back_in_iter = property(_edns_opts_back_in_iter)
|
||||
def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
|
||||
__swig_getmethods__["edns_opts_front_out_iter"] = _edns_opts_front_out_iter
|
||||
if _newclass:edns_opts_front_out_iter = _swig_property(_edns_opts_front_out_iter)
|
||||
edns_opts_front_out_iter = property(_edns_opts_front_out_iter)
|
||||
|
||||
def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
|
||||
__swig_getmethods__["edns_opts_front_in"] = _edns_opts_front_in
|
||||
if _newclass:edns_opts_front_in = _swig_property(_edns_opts_front_in)
|
||||
edns_opts_front_in = property(_edns_opts_front_in)
|
||||
def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
|
||||
__swig_getmethods__["edns_opts_back_out"] = _edns_opts_back_out
|
||||
if _newclass:edns_opts_back_out = _swig_property(_edns_opts_back_out)
|
||||
edns_opts_back_out = property(_edns_opts_back_out)
|
||||
def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
|
||||
__swig_getmethods__["edns_opts_back_in"] = _edns_opts_back_in
|
||||
if _newclass:edns_opts_back_in = _swig_property(_edns_opts_back_in)
|
||||
edns_opts_back_in = property(_edns_opts_back_in)
|
||||
def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
|
||||
__swig_getmethods__["edns_opts_front_out"] = _edns_opts_front_out
|
||||
if _newclass:edns_opts_front_out = _swig_property(_edns_opts_front_out)
|
||||
edns_opts_front_out = property(_edns_opts_front_out)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -890,7 +1014,7 @@ struct config_file {
|
||||
char* control_key_file;
|
||||
char* control_cert_file;
|
||||
int do_daemonize;
|
||||
char* python_script;
|
||||
struct config_strlist* python_script;
|
||||
};
|
||||
|
||||
/* ************************************************************************************ *
|
||||
@@ -954,35 +1078,28 @@ struct delegpt {
|
||||
|
||||
%extend delegpt {
|
||||
%pythoncode %{
|
||||
__swig_getmethods__["dname"] = _unboundmodule._get_dp_dname
|
||||
if _newclass:dname = _swig_property(_unboundmodule._get_dp_dname)
|
||||
dname = property(_unboundmodule._get_dp_dname)
|
||||
|
||||
__swig_getmethods__["dname_list"] = _unboundmodule._get_dp_dname_components
|
||||
if _newclass:dname_list = _swig_property(_unboundmodule._get_dp_dname_components)
|
||||
dname_list = property(_unboundmodule._get_dp_dname_components)
|
||||
|
||||
def _get_dname_str(self): return dnameAsStr(self.dname)
|
||||
__swig_getmethods__["dname_str"] = _get_dname_str
|
||||
if _newclass:dname_str = _swig_property(_get_dname_str)
|
||||
dname_str = property(_get_dname_str)
|
||||
%}
|
||||
}
|
||||
%extend delegpt_ns {
|
||||
%pythoncode %{
|
||||
__swig_getmethods__["dname"] = _unboundmodule._get_dpns_dname
|
||||
if _newclass:dname = _swig_property(_unboundmodule._get_dpns_dname)
|
||||
dname = property(_unboundmodule._get_dpns_dname)
|
||||
|
||||
__swig_getmethods__["dname_list"] = _unboundmodule._get_dpns_dname_components
|
||||
if _newclass:dname_list = _swig_property(_unboundmodule._get_dpns_dname_components)
|
||||
dname_list = property(_unboundmodule._get_dpns_dname_components)
|
||||
|
||||
def _get_dname_str(self): return dnameAsStr(self.dname)
|
||||
__swig_getmethods__["dname_str"] = _get_dname_str
|
||||
if _newclass:dname_str = _swig_property(_get_dname_str)
|
||||
dname_str = property(_get_dname_str)
|
||||
%}
|
||||
}
|
||||
%extend delegpt_addr {
|
||||
%pythoncode %{
|
||||
def _addr_get(self): return _delegpt_addr_addr_get(self)
|
||||
__swig_getmethods__["addr"] = _addr_get
|
||||
if _newclass:addr = _swig_property(_addr_get)
|
||||
addr = property(_addr_get)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -992,6 +1109,7 @@ struct delegpt {
|
||||
%rename ("MODULE_STATE_INITIAL") "module_state_initial";
|
||||
%rename ("MODULE_WAIT_REPLY") "module_wait_reply";
|
||||
%rename ("MODULE_WAIT_MODULE") "module_wait_module";
|
||||
%rename ("MODULE_RESTART_NEXT") "module_restart_next";
|
||||
%rename ("MODULE_WAIT_SUBQUERY") "module_wait_subquery";
|
||||
%rename ("MODULE_ERROR") "module_error";
|
||||
%rename ("MODULE_FINISHED") "module_finished";
|
||||
@@ -1000,6 +1118,7 @@ enum module_ext_state {
|
||||
module_state_initial = 0,
|
||||
module_wait_reply,
|
||||
module_wait_module,
|
||||
module_restart_next,
|
||||
module_wait_subquery,
|
||||
module_error,
|
||||
module_finished
|
||||
@@ -1081,7 +1200,7 @@ int checkList(PyObject *l)
|
||||
for (i=0; i < PyList_Size(l); i++)
|
||||
{
|
||||
item = PyList_GetItem(l, i);
|
||||
if (!PyBytes_Check(item))
|
||||
if (!PyBytes_Check(item) && !PyUnicode_Check(item))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -1096,23 +1215,40 @@ int pushRRList(sldns_buffer* qb, PyObject *l, uint32_t default_ttl, int qsec,
|
||||
PyObject* item;
|
||||
int i;
|
||||
size_t len;
|
||||
char* s;
|
||||
PyObject* ascstr;
|
||||
|
||||
for (i=0; i < PyList_Size(l); i++)
|
||||
{
|
||||
ascstr = NULL;
|
||||
item = PyList_GetItem(l, i);
|
||||
if(PyObject_TypeCheck(item, &PyBytes_Type)) {
|
||||
s = PyBytes_AsString(item);
|
||||
} else {
|
||||
ascstr = PyUnicode_AsASCIIString(item);
|
||||
s = PyBytes_AsString(ascstr);
|
||||
}
|
||||
|
||||
len = sldns_buffer_remaining(qb);
|
||||
if(qsec) {
|
||||
if(sldns_str2wire_rr_question_buf(PyBytes_AsString(item),
|
||||
if(sldns_str2wire_rr_question_buf(s,
|
||||
sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)
|
||||
!= 0)
|
||||
!= 0) {
|
||||
if(ascstr)
|
||||
Py_DECREF(ascstr);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(sldns_str2wire_rr_buf(PyBytes_AsString(item),
|
||||
if(sldns_str2wire_rr_buf(s,
|
||||
sldns_buffer_current(qb), &len, NULL, default_ttl,
|
||||
NULL, 0, NULL, 0) != 0)
|
||||
NULL, 0, NULL, 0) != 0) {
|
||||
if(ascstr)
|
||||
Py_DECREF(ascstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(ascstr)
|
||||
Py_DECREF(ascstr);
|
||||
sldns_buffer_skip(qb, len);
|
||||
|
||||
sldns_buffer_write_u16_at(qb, count_offset,
|
||||
@@ -1437,6 +1573,54 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
return python_inplace_cb_register(inplace_cb_reply_servfail,
|
||||
py_cb, env, id);
|
||||
}
|
||||
|
||||
int python_inplace_cb_query_generic(
|
||||
struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct regional* region, int id,
|
||||
void* python_callback)
|
||||
{
|
||||
int res = 0;
|
||||
PyObject *func = python_callback;
|
||||
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
|
||||
PyObject *py_qstate = SWIG_NewPointerObj((void*) qstate, SWIGTYPE_p_module_qstate, 0);
|
||||
PyObject *py_addr = SWIG_NewPointerObj((void *) addr, SWIGTYPE_p_sockaddr_storage, 0);
|
||||
PyObject *py_zone = PyBytes_FromStringAndSize((const char *)zone, zonelen);
|
||||
PyObject *py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
|
||||
|
||||
PyObject *py_args = Py_BuildValue("(OiOOOO)", py_qinfo, flags, py_qstate, py_addr, py_zone, py_region);
|
||||
PyObject *py_kwargs = Py_BuildValue("{}");
|
||||
PyObject *result = PyObject_Call(func, py_args, py_kwargs);
|
||||
if (result) {
|
||||
res = PyInt_AsLong(result);
|
||||
}
|
||||
|
||||
Py_XDECREF(py_qinfo);
|
||||
Py_XDECREF(py_qstate);
|
||||
Py_XDECREF(py_addr);
|
||||
Py_XDECREF(py_zone);
|
||||
Py_XDECREF(py_region);
|
||||
|
||||
Py_XDECREF(py_args);
|
||||
Py_XDECREF(py_kwargs);
|
||||
Py_XDECREF(result);
|
||||
|
||||
PyGILState_Release(gstate);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int register_inplace_cb_query(PyObject* py_cb,
|
||||
struct module_env* env, int id)
|
||||
{
|
||||
int ret = inplace_cb_register(python_inplace_cb_query_generic,
|
||||
inplace_cb_query, (void*) py_cb, env, id);
|
||||
if (ret) Py_INCREF(py_cb);
|
||||
return ret;
|
||||
}
|
||||
%}
|
||||
/* C declarations */
|
||||
int inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
@@ -1451,3 +1635,5 @@ static int register_inplace_cb_reply_local(PyObject* py_cb,
|
||||
struct module_env* env, int id);
|
||||
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
|
||||
struct module_env* env, int id);
|
||||
static int register_inplace_cb_query(PyObject *py_cb,
|
||||
struct module_env* env, int id);
|
||||
|
||||
+221
-44
@@ -64,6 +64,15 @@ typedef struct PyThreadState PyThreadState;
|
||||
typedef void* PyGILState_STATE;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* counter for python module instances
|
||||
* incremented by pythonmod_init(...)
|
||||
*/
|
||||
int py_mod_count = 0;
|
||||
|
||||
/** Python main thread */
|
||||
PyThreadState* mainthr;
|
||||
|
||||
/**
|
||||
* Global state for the module.
|
||||
*/
|
||||
@@ -72,8 +81,6 @@ struct pythonmod_env {
|
||||
/** Python script filename. */
|
||||
const char* fname;
|
||||
|
||||
/** Python main thread */
|
||||
PyThreadState* mainthr;
|
||||
/** Python module. */
|
||||
PyObject* module;
|
||||
|
||||
@@ -110,13 +117,149 @@ struct pythonmod_qstate {
|
||||
#include "pythonmod/interface.h"
|
||||
#endif
|
||||
|
||||
/** log python error */
|
||||
static void
|
||||
log_py_err(void)
|
||||
{
|
||||
char *result = NULL;
|
||||
const char* iomod = "cStringIO";
|
||||
PyObject *modStringIO = NULL;
|
||||
PyObject *modTB = NULL;
|
||||
PyObject *obFuncStringIO = NULL;
|
||||
PyObject *obStringIO = NULL;
|
||||
PyObject *obFuncTB = NULL;
|
||||
PyObject *argsTB = NULL;
|
||||
PyObject *obResult = NULL;
|
||||
PyObject *ascstr = NULL;
|
||||
PyObject *exc_typ, *exc_val, *exc_tb;
|
||||
|
||||
/* Fetch the error state now before we cruch it */
|
||||
/* exc val contains the error message
|
||||
* exc tb contains stack traceback and other info. */
|
||||
PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
|
||||
PyErr_NormalizeException(&exc_typ, &exc_val, &exc_tb);
|
||||
|
||||
/* Import the modules we need - cStringIO and traceback */
|
||||
modStringIO = PyImport_ImportModule("cStringIO");
|
||||
if (modStringIO==NULL) {
|
||||
/* python 1.4 and before */
|
||||
modStringIO = PyImport_ImportModule("StringIO");
|
||||
iomod = "StringIO";
|
||||
}
|
||||
if (modStringIO==NULL) {
|
||||
/* python 3 */
|
||||
modStringIO = PyImport_ImportModule("io");
|
||||
iomod = "io";
|
||||
}
|
||||
if (modStringIO==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot ImportModule cStringIO or StringIO or io");
|
||||
goto cleanup;
|
||||
}
|
||||
modTB = PyImport_ImportModule("traceback");
|
||||
if (modTB==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot ImportModule traceback");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Construct a cStringIO object */
|
||||
obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
|
||||
if (obFuncStringIO==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot GetAttrString %s.StringIO", iomod);
|
||||
goto cleanup;
|
||||
}
|
||||
obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
|
||||
if (obStringIO==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot call %s.StringIO()", iomod);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get the traceback.print_exception function, and call it. */
|
||||
obFuncTB = PyObject_GetAttrString(modTB, "print_exception");
|
||||
if (obFuncTB==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot GetAttrString traceback.print_exception");
|
||||
goto cleanup;
|
||||
}
|
||||
argsTB = Py_BuildValue("OOOOO", (exc_typ ? exc_typ : Py_None),
|
||||
(exc_val ? exc_val : Py_None), (exc_tb ? exc_tb : Py_None),
|
||||
Py_None, obStringIO);
|
||||
if (argsTB==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot BuildValue for print_exception");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
obResult = PyObject_CallObject(obFuncTB, argsTB);
|
||||
if (obResult==NULL) {
|
||||
PyErr_Print();
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"call traceback.print_exception() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Now call the getvalue() method in the StringIO instance */
|
||||
Py_DECREF(obFuncStringIO);
|
||||
obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
|
||||
if (obFuncStringIO==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"cannot GetAttrString StringIO.getvalue");
|
||||
goto cleanup;
|
||||
}
|
||||
Py_DECREF(obResult);
|
||||
obResult = PyObject_CallObject(obFuncStringIO, NULL);
|
||||
if (obResult==NULL) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"call StringIO.getvalue() failed");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* And it should be a string all ready to go - duplicate it. */
|
||||
if (!PyString_Check(obResult) && !PyUnicode_Check(obResult)) {
|
||||
log_err("pythonmod: cannot print exception, "
|
||||
"StringIO.getvalue() result did not String_Check"
|
||||
" or Unicode_Check");
|
||||
goto cleanup;
|
||||
}
|
||||
if(PyString_Check(obResult)) {
|
||||
result = PyString_AsString(obResult);
|
||||
} else {
|
||||
ascstr = PyUnicode_AsASCIIString(obResult);
|
||||
result = PyBytes_AsString(ascstr);
|
||||
}
|
||||
log_err("pythonmod: python error: %s", result);
|
||||
|
||||
cleanup:
|
||||
Py_XDECREF(modStringIO);
|
||||
Py_XDECREF(modTB);
|
||||
Py_XDECREF(obFuncStringIO);
|
||||
Py_XDECREF(obStringIO);
|
||||
Py_XDECREF(obFuncTB);
|
||||
Py_XDECREF(argsTB);
|
||||
Py_XDECREF(obResult);
|
||||
Py_XDECREF(ascstr);
|
||||
|
||||
/* clear the exception, by not restoring it */
|
||||
/* Restore the exception state */
|
||||
/* PyErr_Restore(exc_typ, exc_val, exc_tb); */
|
||||
}
|
||||
|
||||
int pythonmod_init(struct module_env* env, int id)
|
||||
{
|
||||
int py_mod_idx = py_mod_count++;
|
||||
|
||||
/* Initialize module */
|
||||
FILE* script_py = NULL;
|
||||
PyObject* py_init_arg, *res;
|
||||
PyGILState_STATE gil;
|
||||
int init_standard = 1;
|
||||
int init_standard = 1, i = 0;
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyObject* PyFileObject = NULL;
|
||||
#endif
|
||||
struct config_strlist* cfg_item = env->cfg->python_script;
|
||||
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
|
||||
if (!pe)
|
||||
@@ -128,14 +271,21 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
env->modinfo[id] = (void*) pe;
|
||||
|
||||
/* Initialize module */
|
||||
pe->fname = env->cfg->python_script;
|
||||
pe->fname=NULL; i = 0;
|
||||
while (cfg_item!=NULL) {
|
||||
if (py_mod_idx==i++) {
|
||||
pe->fname=cfg_item->str;
|
||||
break;
|
||||
}
|
||||
cfg_item = cfg_item->next;
|
||||
}
|
||||
if(pe->fname==NULL || pe->fname[0]==0) {
|
||||
log_err("pythonmod: no script given.");
|
||||
log_err("pythonmod[%d]: no script given.", py_mod_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize Python libraries */
|
||||
if (!Py_IsInitialized())
|
||||
if (py_mod_count==1 && !Py_IsInitialized())
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
wchar_t progname[8];
|
||||
@@ -151,33 +301,43 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
SWIG_init();
|
||||
pe->mainthr = PyEval_SaveThread();
|
||||
mainthr = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
gil = PyGILState_Ensure();
|
||||
|
||||
/* Initialize Python */
|
||||
PyRun_SimpleString("import sys \n");
|
||||
PyRun_SimpleString("sys.path.append('.') \n");
|
||||
if(env->cfg->directory && env->cfg->directory[0]) {
|
||||
char wdir[1524];
|
||||
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
|
||||
env->cfg->directory);
|
||||
PyRun_SimpleString(wdir);
|
||||
}
|
||||
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
|
||||
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
|
||||
PyRun_SimpleString("import distutils.sysconfig \n");
|
||||
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
|
||||
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
|
||||
{
|
||||
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||
PyGILState_Release(gil);
|
||||
return 0;
|
||||
if (py_mod_count==1) {
|
||||
/* Initialize Python */
|
||||
PyRun_SimpleString("import sys \n");
|
||||
PyRun_SimpleString("sys.path.append('.') \n");
|
||||
if(env->cfg->directory && env->cfg->directory[0]) {
|
||||
char wdir[1524];
|
||||
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
|
||||
env->cfg->directory);
|
||||
PyRun_SimpleString(wdir);
|
||||
}
|
||||
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
|
||||
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
|
||||
PyRun_SimpleString("import distutils.sysconfig \n");
|
||||
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
|
||||
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
|
||||
{
|
||||
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
|
||||
PyGILState_Release(gil);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Python file load */
|
||||
if ((script_py = fopen(pe->fname, "r")) == NULL)
|
||||
/* uses python to open the file, this works on other platforms,
|
||||
* eg. Windows, to open the file in the correct mode for python */
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyFileObject = PyFile_FromString((char*)pe->fname, "r");
|
||||
script_py = PyFile_AsFile(PyFileObject);
|
||||
#else
|
||||
script_py = _Py_fopen(pe->fname, "r");
|
||||
#endif
|
||||
if (script_py == NULL)
|
||||
{
|
||||
log_err("pythonmod: can't open file %s for reading", pe->fname);
|
||||
PyGILState_Release(gil);
|
||||
@@ -187,20 +347,38 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
/* Load file */
|
||||
pe->module = PyImport_AddModule("__main__");
|
||||
pe->dict = PyModule_GetDict(pe->module);
|
||||
pe->data = Py_None;
|
||||
Py_INCREF(pe->data);
|
||||
pe->data = PyDict_New();
|
||||
Py_XINCREF(pe->data);
|
||||
PyModule_AddObject(pe->module, "mod_env", pe->data);
|
||||
|
||||
/* TODO: deallocation of pe->... if an error occurs */
|
||||
|
||||
if (PyRun_SimpleFile(script_py, pe->fname) < 0)
|
||||
{
|
||||
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
|
||||
log_err("pythonmod: can't parse Python script %s", pe->fname);
|
||||
/* print the error to logs too, run it again */
|
||||
fseek(script_py, 0, SEEK_SET);
|
||||
/* we don't run the file, like this, because then side-effects
|
||||
* s = PyRun_File(script_py, pe->fname, Py_file_input,
|
||||
* PyModule_GetDict(PyImport_AddModule("__main__")), pe->dict);
|
||||
* could happen (again). Instead we parse the file again to get
|
||||
* the error string in the logs, for when the daemon has stderr
|
||||
* removed. SimpleFile run already printed to stderr, for then
|
||||
* this is called from unbound-checkconf or unbound -dd the user
|
||||
* has a nice formatted error.
|
||||
*/
|
||||
/* ignore the NULL return of _node, it is NULL due to the parse failure
|
||||
* that we are expecting */
|
||||
(void)PyParser_SimpleParseFile(script_py, pe->fname, Py_file_input);
|
||||
log_py_err();
|
||||
PyGILState_Release(gil);
|
||||
fclose(script_py);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_XDECREF(PyFileObject);
|
||||
#else
|
||||
fclose(script_py);
|
||||
#endif
|
||||
|
||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL)
|
||||
{
|
||||
@@ -244,7 +422,7 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function init");
|
||||
PyErr_Print();
|
||||
log_py_err();
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_init_arg);
|
||||
PyGILState_Release(gil);
|
||||
@@ -274,7 +452,7 @@ void pythonmod_deinit(struct module_env* env, int id)
|
||||
res = PyObject_CallFunction(pe->func_deinit, "i", id);
|
||||
if (PyErr_Occurred()) {
|
||||
log_err("pythonmod: Exception occurred in function deinit");
|
||||
PyErr_Print();
|
||||
log_py_err();
|
||||
}
|
||||
/* Free result if any */
|
||||
Py_XDECREF(res);
|
||||
@@ -282,9 +460,11 @@ void pythonmod_deinit(struct module_env* env, int id)
|
||||
Py_XDECREF(pe->data);
|
||||
PyGILState_Release(gil);
|
||||
|
||||
PyEval_RestoreThread(pe->mainthr);
|
||||
Py_Finalize();
|
||||
pe->mainthr = NULL;
|
||||
if(--py_mod_count==0) {
|
||||
PyEval_RestoreThread(mainthr);
|
||||
Py_Finalize();
|
||||
mainthr = NULL;
|
||||
}
|
||||
}
|
||||
pe->fname = NULL;
|
||||
free(pe);
|
||||
@@ -312,7 +492,7 @@ void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function inform_super");
|
||||
PyErr_Print();
|
||||
log_py_err();
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
else if ((res == NULL) || (!PyObject_IsTrue(res)))
|
||||
@@ -342,8 +522,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
pq = qstate->minfo[id] = malloc(sizeof(struct pythonmod_qstate));
|
||||
|
||||
/* Initialize per query data */
|
||||
pq->data = Py_None;
|
||||
Py_INCREF(pq->data);
|
||||
pq->data = PyDict_New();
|
||||
}
|
||||
|
||||
/* Call operate */
|
||||
@@ -353,7 +532,7 @@ void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function operate, event: %s", strmodulevent(event));
|
||||
PyErr_Print();
|
||||
log_py_err();
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
else if ((res == NULL) || (!PyObject_IsTrue(res)))
|
||||
@@ -374,8 +553,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
|
||||
return;
|
||||
|
||||
pq = (struct pythonmod_qstate*)qstate->minfo[id];
|
||||
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%lX", id,
|
||||
(unsigned long int)pq);
|
||||
verbose(VERB_ALGO, "pythonmod: clear, id: %d, pq:%p", id, pq);
|
||||
if(pq != NULL)
|
||||
{
|
||||
PyGILState_STATE gil = PyGILState_Ensure();
|
||||
@@ -391,8 +569,7 @@ void pythonmod_clear(struct module_qstate* qstate, int id)
|
||||
size_t pythonmod_get_mem(struct module_env* env, int id)
|
||||
{
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)env->modinfo[id];
|
||||
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%lX", id,
|
||||
(unsigned long int)pe);
|
||||
verbose(VERB_ALGO, "pythonmod: get_mem, id: %d, pe:%p", id, pe);
|
||||
if(!pe)
|
||||
return 0;
|
||||
return sizeof(*pe);
|
||||
|
||||
@@ -74,4 +74,12 @@ int python_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* python_callback);
|
||||
|
||||
/** Declared here for fptr_wlist access. The definition is in interface.i. */
|
||||
int python_inplace_cb_query_generic(
|
||||
struct query_info* qinfo, uint16_t flags, struct module_qstate* qstate,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct regional* region, int id,
|
||||
void* python_callback);
|
||||
|
||||
#endif /* PYTHONMOD_H */
|
||||
|
||||
+17
-6
@@ -172,7 +172,7 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
|
||||
if(!(node=respip_find_or_create(set, ipstr, 1)))
|
||||
return 0;
|
||||
if(node->action != respip_none) {
|
||||
log_warn("duplicate response-ip action for '%s', overridden.",
|
||||
verbose(VERB_QUERY, "duplicate response-ip action for '%s', overridden.",
|
||||
ipstr);
|
||||
}
|
||||
if(strcmp(actnstr, "deny") == 0)
|
||||
@@ -183,6 +183,8 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
|
||||
action = respip_inform;
|
||||
else if(strcmp(actnstr, "inform_deny") == 0)
|
||||
action = respip_inform_deny;
|
||||
else if(strcmp(actnstr, "inform_redirect") == 0)
|
||||
action = respip_inform_redirect;
|
||||
else if(strcmp(actnstr, "always_transparent") == 0)
|
||||
action = respip_always_transparent;
|
||||
else if(strcmp(actnstr, "always_refuse") == 0)
|
||||
@@ -245,7 +247,8 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
struct packed_rrset_data* pd;
|
||||
struct sockaddr* sa;
|
||||
int ret;
|
||||
if(raddr->action != respip_redirect) {
|
||||
if(raddr->action != respip_redirect
|
||||
&& raddr->action != respip_inform_redirect) {
|
||||
log_err("cannot parse response-ip-data %s: response-ip "
|
||||
"action for %s is not redirect", rrstr, netblock);
|
||||
return 0;
|
||||
@@ -358,6 +361,7 @@ respip_set_apply_cfg(struct respip_set* set, char* const* tagname, int num_tags,
|
||||
free(pd);
|
||||
pd = np;
|
||||
}
|
||||
addr_tree_init_parents(&set->ip_tree);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -451,7 +455,7 @@ respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
|
||||
* This function returns the copied rrset key on success, and NULL on memory
|
||||
* allocation failure.
|
||||
*/
|
||||
struct ub_packed_rrset_key*
|
||||
static struct ub_packed_rrset_key*
|
||||
copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
|
||||
{
|
||||
struct ub_packed_rrset_key* ck = regional_alloc(region,
|
||||
@@ -475,10 +479,16 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
|
||||
if(!ck->rk.dname)
|
||||
return NULL;
|
||||
|
||||
if((unsigned)data->count >= 0xffff00U)
|
||||
return NULL; /* guard against integer overflow in dsize */
|
||||
dsize = sizeof(struct packed_rrset_data) + data->count *
|
||||
(sizeof(size_t)+sizeof(uint8_t*)+sizeof(time_t));
|
||||
for(i=0; i<data->count; i++)
|
||||
for(i=0; i<data->count; i++) {
|
||||
if((unsigned)dsize >= 0x0fffffffU ||
|
||||
(unsigned)data->rr_len[i] >= 0x0fffffffU)
|
||||
return NULL; /* guard against integer overflow */
|
||||
dsize += data->rr_len[i];
|
||||
}
|
||||
d = regional_alloc(region, dsize);
|
||||
if(!d)
|
||||
return NULL;
|
||||
@@ -750,7 +760,8 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action,
|
||||
*new_repp = new_rep;
|
||||
return 1;
|
||||
} else if(action == respip_static || action == respip_redirect ||
|
||||
action == respip_always_nxdomain) {
|
||||
action == respip_always_nxdomain ||
|
||||
action == respip_inform_redirect) {
|
||||
/* Since we don't know about other types of the owner name,
|
||||
* we generally return NOERROR/NODATA unless an NXDOMAIN action
|
||||
* is explicitly specified. */
|
||||
@@ -1177,5 +1188,5 @@ respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
|
||||
respip, sizeof(respip));
|
||||
snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip,
|
||||
respip_addr->net, srcip, port);
|
||||
log_nametypeclass(0, txt, qname, qtype, qclass);
|
||||
log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass);
|
||||
}
|
||||
|
||||
+352
-65
@@ -88,6 +88,9 @@
|
||||
#define AUTH_HTTPS_PORT 443
|
||||
/* max depth for nested $INCLUDEs */
|
||||
#define MAX_INCLUDE_DEPTH 10
|
||||
/** number of timeouts before we fallback from IXFR to AXFR,
|
||||
* because some versions of servers (eg. dnsmasq) drop IXFR packets. */
|
||||
#define NUM_TIMEOUTS_FALLBACK_IXFR 3
|
||||
|
||||
/** pick up nextprobe task to start waiting to perform transfer actions */
|
||||
static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
@@ -218,7 +221,7 @@ msg_add_rrset_an(struct auth_zone* z, struct regional* region,
|
||||
{
|
||||
log_assert(msg->rep->ns_numrrsets == 0);
|
||||
log_assert(msg->rep->ar_numrrsets == 0);
|
||||
if(!rrset)
|
||||
if(!rrset || !node)
|
||||
return 1;
|
||||
if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type,
|
||||
z->dclass))
|
||||
@@ -242,7 +245,7 @@ msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
log_assert(msg->rep->ar_numrrsets == 0);
|
||||
if(!rrset)
|
||||
if(!rrset || !node)
|
||||
return 1;
|
||||
if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type,
|
||||
z->dclass))
|
||||
@@ -265,7 +268,7 @@ static int
|
||||
msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, struct auth_data* node, struct auth_rrset* rrset)
|
||||
{
|
||||
if(!rrset)
|
||||
if(!rrset || !node)
|
||||
return 1;
|
||||
if(msg_rrset_duplicate(msg, node->name, node->namelen, rrset->type,
|
||||
z->dclass))
|
||||
@@ -1450,11 +1453,13 @@ az_remove_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen,
|
||||
* The lineno is set at 1 and then increased by the function.
|
||||
* @param fname: file name.
|
||||
* @param depth: recursion depth for includes
|
||||
* @param cfg: config for chroot.
|
||||
* returns false on failure, has printed an error message
|
||||
*/
|
||||
static int
|
||||
az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
struct sldns_file_parse_state* state, char* fname, int depth)
|
||||
struct sldns_file_parse_state* state, char* fname, int depth,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
size_t rr_len, dname_len;
|
||||
int status;
|
||||
@@ -1480,6 +1485,11 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
/* skip spaces */
|
||||
while(*incfile == ' ' || *incfile == '\t')
|
||||
incfile++;
|
||||
/* adjust for chroot on include file */
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(incfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir)) == 0)
|
||||
incfile += strlen(cfg->chrootdir);
|
||||
incfile = strdup(incfile);
|
||||
if(!incfile) {
|
||||
log_err("malloc failure");
|
||||
@@ -1490,7 +1500,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
inc = fopen(incfile, "r");
|
||||
if(!inc) {
|
||||
log_err("%s:%d cannot open include "
|
||||
"file %s: %s", z->zonefile,
|
||||
"file %s: %s", fname,
|
||||
lineno_orig, incfile,
|
||||
strerror(errno));
|
||||
free(incfile);
|
||||
@@ -1498,7 +1508,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
}
|
||||
/* recurse read that file now */
|
||||
if(!az_parse_file(z, inc, rr, rrbuflen,
|
||||
state, incfile, depth+1)) {
|
||||
state, incfile, depth+1, cfg)) {
|
||||
log_err("%s:%d cannot parse include "
|
||||
"file %s", fname,
|
||||
lineno_orig, incfile);
|
||||
@@ -1538,30 +1548,36 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
}
|
||||
|
||||
int
|
||||
auth_zone_read_zonefile(struct auth_zone* z)
|
||||
auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
{
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
struct sldns_file_parse_state state;
|
||||
char* zfilename;
|
||||
FILE* in;
|
||||
if(!z || !z->zonefile || z->zonefile[0]==0)
|
||||
return 1; /* no file, or "", nothing to read */
|
||||
|
||||
zfilename = z->zonefile;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename,
|
||||
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
|
||||
zfilename += strlen(cfg->chrootdir);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char nm[255+1];
|
||||
dname_str(z->name, nm);
|
||||
verbose(VERB_ALGO, "read zonefile %s for %s", z->zonefile, nm);
|
||||
verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm);
|
||||
}
|
||||
in = fopen(z->zonefile, "r");
|
||||
in = fopen(zfilename, "r");
|
||||
if(!in) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
if(z->zone_is_slave && errno == ENOENT) {
|
||||
/* we fetch the zone contents later, no file yet */
|
||||
verbose(VERB_ALGO, "no zonefile %s for %s",
|
||||
z->zonefile, n?n:"error");
|
||||
zfilename, n?n:"error");
|
||||
free(n);
|
||||
return 1;
|
||||
}
|
||||
log_err("cannot open zonefile %s for %s: %s",
|
||||
z->zonefile, n?n:"error", strerror(errno));
|
||||
zfilename, n?n:"error", strerror(errno));
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1579,10 +1595,10 @@ auth_zone_read_zonefile(struct auth_zone* z)
|
||||
state.origin_len = z->namelen;
|
||||
}
|
||||
/* parse the (toplevel) file */
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state, z->zonefile, 0)) {
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("error parsing zonefile %s for %s",
|
||||
z->zonefile, n?n:"error");
|
||||
zfilename, n?n:"error");
|
||||
free(n);
|
||||
fclose(in);
|
||||
return 0;
|
||||
@@ -1620,7 +1636,7 @@ auth_rr_to_string(uint8_t* nm, size_t nmlen, uint16_t tp, uint16_t cl,
|
||||
if(i >= data->count) tp = LDNS_RR_TYPE_RRSIG;
|
||||
dat = nm;
|
||||
datlen = nmlen;
|
||||
w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0);
|
||||
w += sldns_wire2str_dname_scan(&dat, &datlen, &s, &slen, NULL, 0, NULL);
|
||||
w += sldns_str_print(&s, &slen, "\t");
|
||||
w += sldns_str_print(&s, &slen, "%lu\t", (unsigned long)data->rr_ttl[i]);
|
||||
w += sldns_wire2str_class_print(&s, &slen, cl);
|
||||
@@ -1629,7 +1645,7 @@ auth_rr_to_string(uint8_t* nm, size_t nmlen, uint16_t tp, uint16_t cl,
|
||||
w += sldns_str_print(&s, &slen, "\t");
|
||||
datlen = data->rr_len[i]-2;
|
||||
dat = data->rr_data[i]+2;
|
||||
w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0);
|
||||
w += sldns_wire2str_rdata_scan(&dat, &datlen, &s, &slen, tp, NULL, 0, NULL);
|
||||
|
||||
if(tp == LDNS_RR_TYPE_DNSKEY) {
|
||||
w += sldns_str_print(&s, &slen, " ;{id = %u}",
|
||||
@@ -1638,8 +1654,8 @@ auth_rr_to_string(uint8_t* nm, size_t nmlen, uint16_t tp, uint16_t cl,
|
||||
}
|
||||
w += sldns_str_print(&s, &slen, "\n");
|
||||
|
||||
if(w > (int)buflen) {
|
||||
log_nametypeclass(0, "RR too long to print", nm, tp, cl);
|
||||
if(w >= (int)buflen) {
|
||||
log_nametypeclass(NO_VERBOSE, "RR too long to print", nm, tp, cl);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -1710,13 +1726,13 @@ int auth_zone_write_file(struct auth_zone* z, const char* fname)
|
||||
|
||||
/** read all auth zones from file (if they have) */
|
||||
static int
|
||||
auth_zones_read_zones(struct auth_zones* az)
|
||||
auth_zones_read_zones(struct auth_zones* az, struct config_file* cfg)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
lock_rw_wrlock(&az->lock);
|
||||
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
if(!auth_zone_read_zonefile(z)) {
|
||||
if(!auth_zone_read_zonefile(z, cfg)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_rw_unlock(&az->lock);
|
||||
return 0;
|
||||
@@ -1953,7 +1969,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
}
|
||||
}
|
||||
az_delete_deleted_zones(az);
|
||||
if(!auth_zones_read_zones(az))
|
||||
if(!auth_zones_read_zones(az, cfg))
|
||||
return 0;
|
||||
if(setup) {
|
||||
if(!auth_zones_setup_zones(az))
|
||||
@@ -1966,7 +1982,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
* @param at: transfer structure with chunks list. The chunks and their
|
||||
* data are freed.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
auth_chunks_delete(struct auth_transfer* at)
|
||||
{
|
||||
if(at->chunks_first) {
|
||||
@@ -2026,11 +2042,13 @@ auth_xfer_delete(struct auth_xfer* xfr)
|
||||
if(xfr->task_probe) {
|
||||
auth_free_masters(xfr->task_probe->masters);
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
comm_timer_delete(xfr->task_probe->timer);
|
||||
free(xfr->task_probe);
|
||||
}
|
||||
if(xfr->task_transfer) {
|
||||
auth_free_masters(xfr->task_transfer->masters);
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
comm_timer_delete(xfr->task_transfer->timer);
|
||||
if(xfr->task_transfer->chunks_first) {
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
}
|
||||
@@ -2362,6 +2380,10 @@ create_synth_cname(uint8_t* qname, size_t qname_len, struct regional* region,
|
||||
return 0; /* rdatalen in DNAME rdata is malformed */
|
||||
if(dname_valid(dtarg, dtarglen) != dtarglen)
|
||||
return 0; /* DNAME RR has malformed rdata */
|
||||
if(qname_len == 0)
|
||||
return 0; /* too short */
|
||||
if(qname_len <= node->namelen)
|
||||
return 0; /* qname too short for dname removal */
|
||||
|
||||
/* synthesize a CNAME */
|
||||
newlen = synth_cname_buf(qname, qname_len, node->namelen,
|
||||
@@ -2605,7 +2627,7 @@ az_nsec3_hashname(struct auth_zone* z, uint8_t* hashname, size_t* hashnmlen,
|
||||
}
|
||||
|
||||
/** Find the datanode that covers the nsec3hash-name */
|
||||
struct auth_data*
|
||||
static struct auth_data*
|
||||
az_nsec3_findnode(struct auth_zone* z, uint8_t* hashnm, size_t hashnmlen)
|
||||
{
|
||||
struct query_info qinfo;
|
||||
@@ -2730,13 +2752,16 @@ az_nsec3_insert(struct auth_zone* z, struct regional* region,
|
||||
* that is an exact match that should exist for it.
|
||||
* If that does not exist, a higher exact match + nxproof is enabled
|
||||
* (for some sort of opt-out empty nonterminal cases).
|
||||
* nodataproof: search for exact match and include that instead.
|
||||
* ceproof: include ce proof NSEC3 (omitted for wildcard replies).
|
||||
* nxproof: include denial of the qname.
|
||||
* wcproof: include denial of wildcard (wildcard.ce).
|
||||
*/
|
||||
static int
|
||||
az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
struct dns_msg* msg, uint8_t* cenm, size_t cenmlen, uint8_t* qname,
|
||||
size_t qname_len, int nxproof, int wcproof)
|
||||
size_t qname_len, int nodataproof, int ceproof, int nxproof,
|
||||
int wcproof)
|
||||
{
|
||||
int algo;
|
||||
size_t iter, saltlen;
|
||||
@@ -2747,12 +2772,27 @@ az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
|
||||
/* find parameters of nsec3 proof */
|
||||
if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen))
|
||||
return 1; /* no nsec3 */
|
||||
if(nodataproof) {
|
||||
/* see if the node has a hash of itself for the nodata
|
||||
* proof nsec3, this has to be an exact match nsec3. */
|
||||
struct auth_data* match;
|
||||
match = az_nsec3_find_exact(z, qname, qname_len, algo,
|
||||
iter, salt, saltlen);
|
||||
if(match) {
|
||||
if(!az_nsec3_insert(z, region, msg, match))
|
||||
return 0;
|
||||
/* only nodata NSEC3 needed, no CE or others. */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* find ce that has an NSEC3 */
|
||||
node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
|
||||
algo, iter, salt, saltlen);
|
||||
if(no_exact_ce) nxproof = 1;
|
||||
if(!az_nsec3_insert(z, region, msg, node))
|
||||
return 0;
|
||||
if(ceproof) {
|
||||
node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
|
||||
algo, iter, salt, saltlen);
|
||||
if(no_exact_ce) nxproof = 1;
|
||||
if(!az_nsec3_insert(z, region, msg, node))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(nxproof) {
|
||||
uint8_t* nx;
|
||||
@@ -2828,7 +2868,7 @@ az_generate_any_answer(struct auth_zone* z, struct regional* region,
|
||||
if(!msg_add_rrset_an(z, region, msg, node, rrset)) return 0;
|
||||
added++;
|
||||
}
|
||||
if(added == 0 && node->rrsets) {
|
||||
if(added == 0 && node && node->rrsets) {
|
||||
if(!msg_add_rrset_an(z, region, msg, node,
|
||||
node->rrsets)) return 0;
|
||||
}
|
||||
@@ -2897,7 +2937,7 @@ az_generate_notype_answer(struct auth_zone* z, struct regional* region,
|
||||
/* DNSSEC denial NSEC3 */
|
||||
if(!az_add_nsec3_proof(z, region, msg, node->name,
|
||||
node->namelen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 0, 0))
|
||||
msg->qinfo.qname_len, 1, 1, 0, 0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -2924,7 +2964,7 @@ az_generate_referral_answer(struct auth_zone* z, struct regional* region,
|
||||
} else {
|
||||
if(!az_add_nsec3_proof(z, region, msg, ce->name,
|
||||
ce->namelen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 0, 0))
|
||||
msg->qinfo.qname_len, 1, 1, 0, 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2963,6 +3003,7 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
struct auth_data* wildcard, struct auth_data* node)
|
||||
{
|
||||
struct auth_rrset* rrset, *nsec;
|
||||
int insert_ce = 0;
|
||||
if((rrset=az_domain_rrset(wildcard, qinfo->qtype)) != NULL) {
|
||||
/* wildcard has type, add it */
|
||||
if(!msg_add_rrset_an(z, region, msg, wildcard, rrset))
|
||||
@@ -2989,15 +3030,22 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
|
||||
/* call other notype routine for dnssec notype denials */
|
||||
if(!az_generate_notype_answer(z, region, msg, wildcard))
|
||||
return 0;
|
||||
/* because the notype, there is no positive data with an
|
||||
* RRSIG that indicates the wildcard position. Thus the
|
||||
* wildcard qname denial needs to have a CE nsec3. */
|
||||
insert_ce = 1;
|
||||
}
|
||||
|
||||
/* ce and node for dnssec denial of wildcard original name */
|
||||
if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
|
||||
if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
|
||||
} else if(ce) {
|
||||
if(!az_add_nsec3_proof(z, region, msg, ce->name,
|
||||
ce->namelen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 1, 0))
|
||||
uint8_t* wildup = wildcard->name;
|
||||
size_t wilduplen= wildcard->namelen;
|
||||
dname_remove_label(&wildup, &wilduplen);
|
||||
if(!az_add_nsec3_proof(z, region, msg, wildup,
|
||||
wilduplen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 0, insert_ce, 1, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3023,7 +3071,7 @@ az_generate_nxdomain_answer(struct auth_zone* z, struct regional* region,
|
||||
} else if(ce) {
|
||||
if(!az_add_nsec3_proof(z, region, msg, ce->name,
|
||||
ce->namelen, msg->qinfo.qname,
|
||||
msg->qinfo.qname_len, 1, 1))
|
||||
msg->qinfo.qname_len, 0, 1, 1, 1))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -3163,6 +3211,11 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
|
||||
*fallback = 1;
|
||||
return 0;
|
||||
}
|
||||
if(z->zone_expired) {
|
||||
*fallback = z->fallback_enabled;
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
/* see what answer that zone would generate */
|
||||
r = auth_zone_generate_answer(z, qinfo, region, msg, fallback);
|
||||
lock_rw_unlock(&z->lock);
|
||||
@@ -3250,6 +3303,19 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
if(z->zone_expired) {
|
||||
if(z->fallback_enabled) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_rw_wrlock(&az->lock);
|
||||
az->num_query_down++;
|
||||
lock_rw_unlock(&az->lock);
|
||||
auth_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* answer it from zone z */
|
||||
r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
|
||||
@@ -3636,6 +3702,7 @@ static void
|
||||
xfr_transfer_start_lookups(struct auth_xfer* xfr)
|
||||
{
|
||||
/* delete all the looked up addresses in the list */
|
||||
xfr->task_transfer->scan_addr = NULL;
|
||||
xfr_masterlist_free_addrs(xfr->task_transfer->masters);
|
||||
|
||||
/* start lookup at the first master */
|
||||
@@ -3666,6 +3733,7 @@ static void
|
||||
xfr_probe_start_lookups(struct auth_xfer* xfr)
|
||||
{
|
||||
/* delete all the looked up addresses in the list */
|
||||
xfr->task_probe->scan_addr = NULL;
|
||||
xfr_masterlist_free_addrs(xfr->task_probe->masters);
|
||||
|
||||
/* start lookup at the first master */
|
||||
@@ -4773,8 +4841,10 @@ auth_zone_write_chunks(struct auth_xfer* xfr, const char* fname)
|
||||
static void
|
||||
xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
|
||||
{
|
||||
struct config_file* cfg = env->cfg;
|
||||
struct auth_zone* z;
|
||||
char tmpfile[1024];
|
||||
char* zfilename;
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
|
||||
/* get lock again, so it is a readlock and concurrently queries
|
||||
@@ -4792,34 +4862,44 @@ xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
|
||||
lock_basic_lock(&xfr->lock);
|
||||
lock_rw_unlock(&env->auth_zones->lock);
|
||||
|
||||
if(z->zonefile == NULL) {
|
||||
if(z->zonefile == NULL || z->zonefile[0] == 0) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
/* no write needed, no zonefile set */
|
||||
return;
|
||||
}
|
||||
zfilename = z->zonefile;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(zfilename,
|
||||
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
|
||||
zfilename += strlen(cfg->chrootdir);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char nm[255+1];
|
||||
dname_str(z->name, nm);
|
||||
verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm);
|
||||
}
|
||||
|
||||
/* write to tempfile first */
|
||||
if((size_t)strlen(z->zonefile) + 16 > sizeof(tmpfile)) {
|
||||
if((size_t)strlen(zfilename) + 16 > sizeof(tmpfile)) {
|
||||
verbose(VERB_ALGO, "tmpfilename too long, cannot update "
|
||||
" zonefile %s", z->zonefile);
|
||||
" zonefile %s", zfilename);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return;
|
||||
}
|
||||
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", z->zonefile,
|
||||
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", zfilename,
|
||||
(unsigned)getpid());
|
||||
if(xfr->task_transfer->master->http) {
|
||||
/* use the stored chunk list to write them */
|
||||
if(!auth_zone_write_chunks(xfr, tmpfile)) {
|
||||
unlink(tmpfile);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return;
|
||||
}
|
||||
} else if(!auth_zone_write_file(z, tmpfile)) {
|
||||
unlink(tmpfile);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return;
|
||||
}
|
||||
if(rename(tmpfile, z->zonefile) < 0) {
|
||||
log_err("could not rename(%s, %s): %s", tmpfile, z->zonefile,
|
||||
if(rename(tmpfile, zfilename) < 0) {
|
||||
log_err("could not rename(%s, %s): %s", tmpfile, zfilename,
|
||||
strerror(errno));
|
||||
unlink(tmpfile);
|
||||
lock_rw_unlock(&z->lock);
|
||||
@@ -4907,6 +4987,9 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
|
||||
static void
|
||||
xfr_transfer_disown(struct auth_xfer* xfr)
|
||||
{
|
||||
/* remove timer (from this worker's event base) */
|
||||
comm_timer_delete(xfr->task_transfer->timer);
|
||||
xfr->task_transfer->timer = NULL;
|
||||
/* remove the commpoint */
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
xfr->task_transfer->cp = NULL;
|
||||
@@ -4951,12 +5034,12 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
qinfo.qtype = LDNS_RR_TYPE_AAAA;
|
||||
qinfo.local_alias = NULL;
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[512];
|
||||
char buf1[512];
|
||||
char buf2[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_str(xfr->name, buf2);
|
||||
snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
|
||||
snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
|
||||
" for task_transfer", buf2);
|
||||
log_query_info(VERB_ALGO, buf, &qinfo);
|
||||
log_query_info(VERB_ALGO, buf1, &qinfo);
|
||||
}
|
||||
edns.edns_present = 1;
|
||||
edns.ext_rcode = 0;
|
||||
@@ -4988,6 +5071,9 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = 0;
|
||||
struct auth_master* master = xfr->task_transfer->master;
|
||||
char *auth_name = NULL;
|
||||
struct timeval t;
|
||||
int timeout;
|
||||
if(!master) return 0;
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
|
||||
@@ -4996,7 +5082,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
addrlen = xfr->task_transfer->scan_addr->addrlen;
|
||||
memmove(&addr, &xfr->task_transfer->scan_addr->addr, addrlen);
|
||||
} else {
|
||||
if(!extstrtoaddr(master->host, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) {
|
||||
/* the ones that are not in addr format are supposed
|
||||
* to be looked up. The lookup has failed however,
|
||||
* so skip them */
|
||||
@@ -5013,25 +5099,46 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
xfr->task_transfer->cp = NULL;
|
||||
}
|
||||
if(!xfr->task_transfer->timer) {
|
||||
xfr->task_transfer->timer = comm_timer_create(env->worker_base,
|
||||
auth_xfer_transfer_timer_callback, xfr);
|
||||
if(!xfr->task_transfer->timer) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
timeout = AUTH_TRANSFER_TIMEOUT;
|
||||
#ifndef S_SPLINT_S
|
||||
t.tv_sec = timeout/1000;
|
||||
t.tv_usec = (timeout%1000)*1000;
|
||||
#endif
|
||||
|
||||
if(master->http) {
|
||||
/* perform http fetch */
|
||||
/* store http port number into sockaddr,
|
||||
* unless someone used unbound's host@port notation */
|
||||
xfr->task_transfer->on_ixfr = 0;
|
||||
if(strchr(master->host, '@') == NULL)
|
||||
sockaddr_store_port(&addr, addrlen, master->port);
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_http(
|
||||
env->outnet, auth_xfer_transfer_http_callback, xfr,
|
||||
&addr, addrlen, AUTH_TRANSFER_TIMEOUT, master->ssl,
|
||||
master->host, master->file);
|
||||
&addr, addrlen, -1, master->ssl, master->host,
|
||||
master->file);
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1];
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create http cp "
|
||||
"connection for %s to %s", zname,
|
||||
master->host);
|
||||
"connection for %s to %s", zname, as);
|
||||
return 0;
|
||||
}
|
||||
comm_timer_set(xfr->task_transfer->timer, &t);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5045,14 +5152,24 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* connect on fd */
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
|
||||
auth_xfer_transfer_tcp_callback, xfr, &addr, addrlen,
|
||||
env->scratch_buffer, AUTH_TRANSFER_TIMEOUT);
|
||||
env->scratch_buffer, -1,
|
||||
auth_name != NULL, auth_name);
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create tcp cp connection for "
|
||||
"xfr %s to %s", zname, master->host);
|
||||
"xfr %s to %s", zname, as);
|
||||
return 0;
|
||||
}
|
||||
comm_timer_set(xfr->task_transfer->timer, &t);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
|
||||
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5070,6 +5187,11 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
* and we may then get an instant cache response,
|
||||
* and that calls the callback just like a full
|
||||
* lookup and lookup failures also call callback */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname);
|
||||
}
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
@@ -5088,6 +5210,11 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* failed to fetch, next master */
|
||||
xfr_transfer_nextmaster(xfr);
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname);
|
||||
}
|
||||
|
||||
/* we failed to fetch the zone, move to wait task
|
||||
* use the shorter retry timeout */
|
||||
@@ -5185,7 +5312,25 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(answer) {
|
||||
xfr_master_add_addrs(xfr->task_transfer->
|
||||
lookup_target, answer, wanted_qtype);
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
if(xfr->task_transfer->lookup_target->list &&
|
||||
@@ -5570,6 +5715,46 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
|
||||
xfr_transfer_nexttarget_or_end(xfr, env);
|
||||
}
|
||||
|
||||
/** callback for the task_transfer timer */
|
||||
void
|
||||
auth_xfer_transfer_timer_callback(void* arg)
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
int gonextonfail = 1;
|
||||
log_assert(xfr->task_transfer);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_transfer->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
|
||||
verbose(VERB_ALGO, "xfr stopped, connection timeout to %s",
|
||||
xfr->task_transfer->master->host);
|
||||
|
||||
/* see if IXFR caused the failure, if so, try AXFR */
|
||||
if(xfr->task_transfer->on_ixfr) {
|
||||
xfr->task_transfer->ixfr_possible_timeout_count++;
|
||||
if(xfr->task_transfer->ixfr_possible_timeout_count >=
|
||||
NUM_TIMEOUTS_FALLBACK_IXFR) {
|
||||
verbose(VERB_ALGO, "xfr to %s, fallback "
|
||||
"from IXFR to AXFR (because of timeouts)",
|
||||
xfr->task_transfer->master->host);
|
||||
xfr->task_transfer->ixfr_fail = 1;
|
||||
gonextonfail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* delete transferred data from list */
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
xfr->task_transfer->cp = NULL;
|
||||
if(gonextonfail)
|
||||
xfr_transfer_nextmaster(xfr);
|
||||
xfr_transfer_nexttarget_or_end(xfr, env);
|
||||
}
|
||||
|
||||
/** callback for task_transfer tcp connections */
|
||||
int
|
||||
auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
@@ -5586,6 +5771,8 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
/* stop the timer */
|
||||
comm_timer_disable(xfr->task_transfer->timer);
|
||||
|
||||
if(err != NETEVENT_NOERROR) {
|
||||
/* connection failed, closed, or timeout */
|
||||
@@ -5593,15 +5780,33 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
* and continue task_transfer*/
|
||||
verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
|
||||
xfr->task_transfer->master->host);
|
||||
|
||||
/* see if IXFR caused the failure, if so, try AXFR */
|
||||
if(xfr->task_transfer->on_ixfr) {
|
||||
xfr->task_transfer->ixfr_possible_timeout_count++;
|
||||
if(xfr->task_transfer->ixfr_possible_timeout_count >=
|
||||
NUM_TIMEOUTS_FALLBACK_IXFR) {
|
||||
verbose(VERB_ALGO, "xfr to %s, fallback "
|
||||
"from IXFR to AXFR (because of timeouts)",
|
||||
xfr->task_transfer->master->host);
|
||||
xfr->task_transfer->ixfr_fail = 1;
|
||||
gonextonfail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
/* delete transferred data from list */
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
xfr->task_transfer->cp = NULL;
|
||||
xfr_transfer_nextmaster(xfr);
|
||||
if(gonextonfail)
|
||||
xfr_transfer_nextmaster(xfr);
|
||||
xfr_transfer_nexttarget_or_end(xfr, env);
|
||||
return 0;
|
||||
}
|
||||
/* note that IXFR worked without timeout */
|
||||
if(xfr->task_transfer->on_ixfr)
|
||||
xfr->task_transfer->ixfr_possible_timeout_count = 0;
|
||||
|
||||
/* handle returned packet */
|
||||
/* if it fails, cleanup and end this transfer */
|
||||
@@ -5648,6 +5853,8 @@ auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
verbose(VERB_ALGO, "auth zone transfer http callback");
|
||||
/* stop the timer */
|
||||
comm_timer_disable(xfr->task_transfer->timer);
|
||||
|
||||
if(err != NETEVENT_NOERROR && err != NETEVENT_DONE) {
|
||||
/* connection failed, closed, or timeout */
|
||||
@@ -5745,6 +5952,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
struct timeval t;
|
||||
/* pick master */
|
||||
struct auth_master* master = xfr_probe_current_master(xfr);
|
||||
char *auth_name = NULL;
|
||||
if(!master) return 0;
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
if(master->http) return 0; /* only masters get SOA UDP probe,
|
||||
@@ -5755,7 +5963,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
addrlen = xfr->task_probe->scan_addr->addrlen;
|
||||
memmove(&addr, &xfr->task_probe->scan_addr->addr, addrlen);
|
||||
} else {
|
||||
if(!extstrtoaddr(master->host, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(master->host, &addr, &addrlen, &auth_name)) {
|
||||
/* the ones that are not in addr format are supposed
|
||||
* to be looked up. The lookup has failed however,
|
||||
* so skip them */
|
||||
@@ -5765,6 +5973,18 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
zname, master->host);
|
||||
return 0;
|
||||
}
|
||||
if (auth_name != NULL) {
|
||||
if (addr.ss_family == AF_INET
|
||||
&& (int)ntohs(((struct sockaddr_in *)&addr)->sin_port)
|
||||
== env->cfg->ssl_port)
|
||||
((struct sockaddr_in *)&addr)->sin_port
|
||||
= htons((uint16_t)env->cfg->port);
|
||||
else if (addr.ss_family == AF_INET6
|
||||
&& (int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port)
|
||||
== env->cfg->ssl_port)
|
||||
((struct sockaddr_in6 *)&addr)->sin6_port
|
||||
= htons((uint16_t)env->cfg->port);
|
||||
}
|
||||
}
|
||||
|
||||
/* create packet */
|
||||
@@ -5774,14 +5994,26 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
xfr->task_probe->id = (uint16_t)(ub_random(env->rnd)&0xffff);
|
||||
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_probe->id);
|
||||
/* we need to remove the cp if we have a different ip4/ip6 type now */
|
||||
if(xfr->task_probe->cp &&
|
||||
((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
|
||||
(!xfr->task_probe->cp_is_ip6 && addr_is_ip6(&addr, addrlen)))
|
||||
) {
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
xfr->task_probe->cp = NULL;
|
||||
}
|
||||
if(!xfr->task_probe->cp) {
|
||||
if(addr_is_ip6(&addr, addrlen))
|
||||
xfr->task_probe->cp_is_ip6 = 1;
|
||||
else xfr->task_probe->cp_is_ip6 = 0;
|
||||
xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
|
||||
auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
|
||||
if(!xfr->task_probe->cp) {
|
||||
char zname[255+1];
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create udp cp for "
|
||||
"probe %s to %s", zname, master->host);
|
||||
"probe %s to %s", zname, as);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -5797,12 +6029,20 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
/* send udp packet */
|
||||
if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
|
||||
(struct sockaddr*)&addr, addrlen)) {
|
||||
char zname[255+1];
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "failed to send soa probe for %s to %s",
|
||||
zname, master->host);
|
||||
zname, as);
|
||||
return 0;
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
|
||||
as);
|
||||
}
|
||||
xfr->task_probe->timeout = timeout;
|
||||
#ifndef S_SPLINT_S
|
||||
t.tv_sec = timeout/1000;
|
||||
@@ -5827,6 +6067,11 @@ auth_xfer_probe_timer_callback(void* arg)
|
||||
return; /* stop on quit */
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname);
|
||||
}
|
||||
if(xfr->task_probe->timeout <= AUTH_PROBE_TIMEOUT_STOP) {
|
||||
/* try again with bigger timeout */
|
||||
if(xfr_probe_send_probe(xfr, env, xfr->task_probe->timeout*2)) {
|
||||
@@ -5973,12 +6218,12 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
qinfo.qtype = LDNS_RR_TYPE_AAAA;
|
||||
qinfo.local_alias = NULL;
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[512];
|
||||
char buf1[512];
|
||||
char buf2[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_str(xfr->name, buf2);
|
||||
snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
|
||||
snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
|
||||
" for task_probe", buf2);
|
||||
log_query_info(VERB_ALGO, buf, &qinfo);
|
||||
log_query_info(VERB_ALGO, buf1, &qinfo);
|
||||
}
|
||||
edns.edns_present = 1;
|
||||
edns.ext_rcode = 0;
|
||||
@@ -6014,6 +6259,11 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
* and we may then get an instant cache response,
|
||||
* and that calls the callback just like a full
|
||||
* lookup and lookup failures also call callback */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname);
|
||||
}
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
@@ -6022,9 +6272,19 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* probe of list has ended. Create or refresh the list of of
|
||||
* allow_notify addrs */
|
||||
probe_copy_masters_for_allow_notify(xfr);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname);
|
||||
}
|
||||
if(xfr->task_probe->only_lookup) {
|
||||
/* only wanted lookups for copy, stop probe and start wait */
|
||||
xfr->task_probe->only_lookup = 0;
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
|
||||
}
|
||||
xfr_probe_disown(xfr);
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
@@ -6046,13 +6306,22 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* done with probe sequence, wait */
|
||||
if(xfr->task_probe->have_new_lease) {
|
||||
/* if zone not updated, start the wait timer again */
|
||||
verbose(VERB_ALGO, "auth_zone unchanged, new lease, wait");
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname);
|
||||
}
|
||||
xfr_probe_disown(xfr);
|
||||
if(xfr->have_zone)
|
||||
xfr->lease_time = *env->now;
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname);
|
||||
}
|
||||
/* we failed to send this as well, move to the wait task,
|
||||
* use the shorter retry timeout */
|
||||
xfr_probe_disown(xfr);
|
||||
@@ -6097,7 +6366,25 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(answer) {
|
||||
xfr_master_add_addrs(xfr->task_probe->
|
||||
lookup_target, answer, wanted_qtype);
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
|
||||
}
|
||||
}
|
||||
if(xfr->task_probe->lookup_target->list &&
|
||||
@@ -6286,7 +6573,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
/* don't lookup_only, if lookup timeout is 0 anyway,
|
||||
* or if we don't have masters to lookup */
|
||||
tv.tv_sec = 0;
|
||||
if(xfr->task_probe && xfr->task_probe->worker == NULL)
|
||||
if(xfr->task_probe->worker == NULL)
|
||||
xfr->task_probe->only_lookup = 1;
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
|
||||
+10
-1
@@ -327,6 +327,8 @@ struct auth_probe {
|
||||
/** the SOA probe udp event.
|
||||
* on the workers event base. */
|
||||
struct comm_point* cp;
|
||||
/** is the cp for ip6 or ip4 */
|
||||
int cp_is_ip6;
|
||||
/** timeout for packets.
|
||||
* on the workers event base. */
|
||||
struct comm_timer* timer;
|
||||
@@ -378,6 +380,8 @@ struct auth_transfer {
|
||||
* data or add of duplicate data). Flag is cleared once the retry
|
||||
* with axfr is done. */
|
||||
int ixfr_fail;
|
||||
/** we saw an ixfr-indicating timeout, count of them */
|
||||
int ixfr_possible_timeout_count;
|
||||
/** we are doing IXFR right now */
|
||||
int on_ixfr;
|
||||
/** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
|
||||
@@ -396,6 +400,9 @@ struct auth_transfer {
|
||||
/** the transfer (TCP) to the master.
|
||||
* on the workers event base. */
|
||||
struct comm_point* cp;
|
||||
/** timeout for the transfer.
|
||||
* on the workers event base. */
|
||||
struct comm_timer* timer;
|
||||
};
|
||||
|
||||
/** list of addresses */
|
||||
@@ -599,7 +606,7 @@ int auth_zones_startprobesequence(struct auth_zones* az,
|
||||
struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass);
|
||||
|
||||
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
||||
int auth_zone_read_zonefile(struct auth_zone* z);
|
||||
int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg);
|
||||
|
||||
/** find serial number of zone or false if none (no SOA record) */
|
||||
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
|
||||
@@ -645,6 +652,8 @@ int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
struct comm_reply* repinfo);
|
||||
/** xfer probe timeout callback, part of task_probe */
|
||||
void auth_xfer_probe_timer_callback(void* arg);
|
||||
/** xfer transfer timeout callback, part of task_transfer */
|
||||
void auth_xfer_transfer_timer_callback(void* arg);
|
||||
/** mesh callback for task_probe on lookup of host names */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
|
||||
|
||||
Vendored
+17
@@ -40,6 +40,7 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "validator/val_nsec.h"
|
||||
#include "validator/val_utils.h"
|
||||
#include "services/cache/dns.h"
|
||||
@@ -721,6 +722,19 @@ fill_any(struct module_env* env,
|
||||
int i, num=6; /* number of RR types to look up */
|
||||
log_assert(lookup[num] == 0);
|
||||
|
||||
if(env->cfg->deny_any) {
|
||||
/* return empty message */
|
||||
msg = dns_msg_create(qname, qnamelen, qtype, qclass,
|
||||
region, 0);
|
||||
if(!msg) {
|
||||
return NULL;
|
||||
}
|
||||
/* set NOTIMPL for RFC 8482 */
|
||||
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
|
||||
msg->rep->security = sec_status_indeterminate;
|
||||
return msg;
|
||||
}
|
||||
|
||||
for(i=0; i<num; i++) {
|
||||
/* look up this RR for inclusion in type ANY response */
|
||||
struct ub_packed_rrset_key* rrset = rrset_cache_lookup(
|
||||
@@ -901,12 +915,15 @@ dns_cache_lookup(struct module_env* env,
|
||||
struct dns_msg* msg;
|
||||
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
|
||||
&& data->security == sec_status_secure
|
||||
&& (data->an_numrrsets == 0 ||
|
||||
ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
|
||||
&& (msg=tomsg(env, &k, data, region, now, scratch))){
|
||||
lock_rw_unlock(&e->lock);
|
||||
msg->qinfo.qname=qname;
|
||||
msg->qinfo.qname_len=qnamelen;
|
||||
/* check that DNSSEC really works out */
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
iter_scrub_nxdomain(msg);
|
||||
return msg;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
Vendored
+38
-8
@@ -41,6 +41,8 @@
|
||||
#include "config.h"
|
||||
#include "sldns/rrdef.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
@@ -808,7 +810,7 @@ static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
|
||||
}
|
||||
|
||||
/** find data item in array for ip addresses */
|
||||
struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
|
||||
static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, int wr)
|
||||
{
|
||||
struct ip_rate_key key;
|
||||
@@ -907,7 +909,8 @@ int infra_rate_max(void* data, time_t now)
|
||||
}
|
||||
|
||||
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
|
||||
size_t namelen, time_t timenow)
|
||||
size_t namelen, time_t timenow, struct query_info* qinfo,
|
||||
struct comm_reply* replylist)
|
||||
{
|
||||
int lim, max;
|
||||
struct lruhash_entry* entry;
|
||||
@@ -930,9 +933,19 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
|
||||
lock_rw_unlock(&entry->lock);
|
||||
|
||||
if(premax < lim && max >= lim) {
|
||||
char buf[257];
|
||||
char buf[257], qnm[257], ts[12], cs[12], ip[128];
|
||||
dname_str(name, buf);
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim);
|
||||
dname_str(qinfo->qname, qnm);
|
||||
sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
|
||||
sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
|
||||
ip[0]=0;
|
||||
if(replylist) {
|
||||
addr_to_str((struct sockaddr_storage *)&replylist->addr,
|
||||
replylist->addrlen, ip, sizeof(ip));
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
|
||||
} else {
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
|
||||
}
|
||||
}
|
||||
return (max < lim);
|
||||
}
|
||||
@@ -991,7 +1004,7 @@ infra_get_mem(struct infra_cache* infra)
|
||||
}
|
||||
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, time_t timenow)
|
||||
struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer)
|
||||
{
|
||||
int max;
|
||||
struct lruhash_entry* entry;
|
||||
@@ -1010,11 +1023,28 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
lock_rw_unlock(&entry->lock);
|
||||
|
||||
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
|
||||
char client_ip[128];
|
||||
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
|
||||
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
|
||||
repinfo->addrlen, client_ip, sizeof(client_ip));
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip,
|
||||
infra_ip_ratelimit);
|
||||
qnm[0]=0;
|
||||
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
|
||||
(void)sldns_wire2str_rrquestion_buf(
|
||||
sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
|
||||
sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
|
||||
qnm, sizeof(qnm));
|
||||
if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
|
||||
qnm[strlen(qnm)-1] = 0; /*remove newline*/
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
if(strchr(qnm, '\t'))
|
||||
*strchr(qnm, '\t') = ' ';
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s",
|
||||
client_ip, infra_ip_ratelimit, qnm);
|
||||
} else {
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)",
|
||||
client_ip, infra_ip_ratelimit);
|
||||
}
|
||||
}
|
||||
return (max <= infra_ip_ratelimit);
|
||||
}
|
||||
|
||||
Vendored
+7
-2
@@ -366,12 +366,15 @@ long long infra_get_host_rto(struct infra_cache* infra,
|
||||
* @param name: zone name
|
||||
* @param namelen: zone name length
|
||||
* @param timenow: what time it is now.
|
||||
* @param qinfo: for logging, query name.
|
||||
* @param replylist: for logging, querier's address (if any).
|
||||
* @return 1 if it could be incremented. 0 if the increment overshot the
|
||||
* ratelimit or if in the previous second the ratelimit was exceeded.
|
||||
* Failures like alloc failures are not returned (probably as 1).
|
||||
*/
|
||||
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
|
||||
size_t namelen, time_t timenow);
|
||||
size_t namelen, time_t timenow, struct query_info* qinfo,
|
||||
struct comm_reply* replylist);
|
||||
|
||||
/**
|
||||
* Decrement the query rate counter for a delegation point.
|
||||
@@ -410,10 +413,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
|
||||
* @param infra: infra cache
|
||||
* @param repinfo: information about client
|
||||
* @param timenow: what time it is now.
|
||||
* @param buffer: with query for logging.
|
||||
* @return 1 if it could be incremented. 0 if the increment overshot the
|
||||
* ratelimit and the query should be dropped. */
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, time_t timenow);
|
||||
struct comm_reply* repinfo, time_t timenow,
|
||||
struct sldns_buffer* buffer);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
|
||||
+432
-5
@@ -53,6 +53,9 @@
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/mesh.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
@@ -70,6 +73,18 @@
|
||||
/** number of queued TCP connections for listen() */
|
||||
#define TCP_BACKLOG 256
|
||||
|
||||
/** number of simultaneous requests a client can have */
|
||||
#define TCP_MAX_REQ_SIMULTANEOUS 32
|
||||
|
||||
#ifndef THREADS_DISABLED
|
||||
/** lock on the counter of stream buffer memory */
|
||||
static lock_basic_type stream_wait_count_lock;
|
||||
#endif
|
||||
/** size (in bytes) of stream wait buffers */
|
||||
static size_t stream_wait_count = 0;
|
||||
/** is the lock initialised for stream wait buffers */
|
||||
static int stream_wait_lock_inited = 0;
|
||||
|
||||
/**
|
||||
* Debug print of the getaddrinfo returned address.
|
||||
* @param addr: the address returned.
|
||||
@@ -247,6 +262,26 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
}
|
||||
#endif /* SO_REUSEADDR */
|
||||
#ifdef SO_REUSEPORT
|
||||
# ifdef SO_REUSEPORT_LB
|
||||
/* on FreeBSD 12 we have SO_REUSEPORT_LB that does loadbalance
|
||||
* like SO_REUSEPORT on Linux. This is what the users want
|
||||
* with the config option in unbound.conf; if we actually
|
||||
* need local address and port reuse they'll also need to
|
||||
* have SO_REUSEPORT set for them, assume it was _LB they want.
|
||||
*/
|
||||
if (reuseport && *reuseport &&
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEPORT_LB, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
#ifdef ENOPROTOOPT
|
||||
if(errno != ENOPROTOOPT || verbosity >= 3)
|
||||
log_warn("setsockopt(.. SO_REUSEPORT_LB ..) failed: %s",
|
||||
strerror(errno));
|
||||
#endif
|
||||
/* this option is not essential, we can continue */
|
||||
*reuseport = 0;
|
||||
}
|
||||
# else /* no SO_REUSEPORT_LB */
|
||||
|
||||
/* try to set SO_REUSEPORT so that incoming
|
||||
* queries are distributed evenly among the receiving threads.
|
||||
* Each thread must have its own socket bound to the same port,
|
||||
@@ -263,6 +298,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
/* this option is not essential, we can continue */
|
||||
*reuseport = 0;
|
||||
}
|
||||
# endif /* SO_REUSEPORT_LB */
|
||||
#else
|
||||
(void)reuseport;
|
||||
#endif /* defined(SO_REUSEPORT) */
|
||||
@@ -565,7 +601,11 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
if(family==AF_INET6 && errno==EINVAL)
|
||||
*noproto = 1;
|
||||
else if(errno != EADDRINUSE &&
|
||||
!(errno == EACCES && verbosity < 4 && !listen)) {
|
||||
!(errno == EACCES && verbosity < 4 && !listen)
|
||||
#ifdef EADDRNOTAVAIL
|
||||
&& !(errno == EADDRNOTAVAIL && verbosity < 4 && !listen)
|
||||
#endif
|
||||
) {
|
||||
log_err_addr("can't bind socket", strerror(errno),
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
}
|
||||
@@ -811,9 +851,16 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
#ifdef ENOPROTOOPT
|
||||
/* squelch ENOPROTOOPT: freebsd server mode with kernel support
|
||||
disabled, except when verbosity enabled for debugging */
|
||||
if(errno != ENOPROTOOPT || verbosity >= 3)
|
||||
if(errno != ENOPROTOOPT || verbosity >= 3) {
|
||||
#endif
|
||||
if(errno == EPERM) {
|
||||
log_warn("Setting TCP Fast Open as server failed: %s ; this could likely be because sysctl net.inet.tcp.fastopen.enabled, net.inet.tcp.fastopen.server_enable, or net.ipv4.tcp_fastopen is disabled", strerror(errno));
|
||||
} else {
|
||||
log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
|
||||
}
|
||||
#ifdef ENOPROTOOPT
|
||||
}
|
||||
#endif
|
||||
log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
return s;
|
||||
@@ -1235,6 +1282,10 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
free(front);
|
||||
return NULL;
|
||||
}
|
||||
if(!stream_wait_lock_inited) {
|
||||
lock_basic_init(&stream_wait_count_lock);
|
||||
stream_wait_lock_inited = 1;
|
||||
}
|
||||
|
||||
/* create comm points as needed */
|
||||
while(ports) {
|
||||
@@ -1247,11 +1298,13 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
ports->ftype == listen_type_tcp_dnscrypt)
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
tcp_conn_limit, bufsize, cb, cb_arg);
|
||||
tcp_conn_limit, bufsize, front->udp_buff,
|
||||
cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_ssl) {
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
tcp_conn_limit, bufsize, cb, cb_arg);
|
||||
tcp_conn_limit, bufsize, front->udp_buff,
|
||||
cb, cb_arg);
|
||||
cp->ssl = sslctx;
|
||||
} else if(ports->ftype == listen_type_udpancil ||
|
||||
ports->ftype == listen_type_udpancil_dnscrypt)
|
||||
@@ -1322,6 +1375,10 @@ listen_delete(struct listen_dnsport* front)
|
||||
#endif
|
||||
sldns_buffer_free(front->udp_buff);
|
||||
free(front);
|
||||
if(stream_wait_lock_inited) {
|
||||
stream_wait_lock_inited = 0;
|
||||
lock_basic_destroy(&stream_wait_count_lock);
|
||||
}
|
||||
}
|
||||
|
||||
struct listen_port*
|
||||
@@ -1479,3 +1536,373 @@ void listen_start_accept(struct listen_dnsport* listen)
|
||||
}
|
||||
}
|
||||
|
||||
struct tcp_req_info*
|
||||
tcp_req_info_create(struct sldns_buffer* spoolbuf)
|
||||
{
|
||||
struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req));
|
||||
if(!req) {
|
||||
log_err("malloc failure for new stream outoforder processing structure");
|
||||
return NULL;
|
||||
}
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->spool_buffer = spoolbuf;
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
tcp_req_info_delete(struct tcp_req_info* req)
|
||||
{
|
||||
if(!req) return;
|
||||
tcp_req_info_clear(req);
|
||||
/* cp is pointer back to commpoint that owns this struct and
|
||||
* called delete on us */
|
||||
/* spool_buffer is shared udp buffer, not deleted here */
|
||||
free(req);
|
||||
}
|
||||
|
||||
void tcp_req_info_clear(struct tcp_req_info* req)
|
||||
{
|
||||
struct tcp_req_open_item* open, *nopen;
|
||||
struct tcp_req_done_item* item, *nitem;
|
||||
if(!req) return;
|
||||
|
||||
/* free outstanding request mesh reply entries */
|
||||
open = req->open_req_list;
|
||||
while(open) {
|
||||
nopen = open->next;
|
||||
mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp);
|
||||
free(open);
|
||||
open = nopen;
|
||||
}
|
||||
req->open_req_list = NULL;
|
||||
req->num_open_req = 0;
|
||||
|
||||
/* free pending writable result packets */
|
||||
item = req->done_req_list;
|
||||
while(item) {
|
||||
nitem = item->next;
|
||||
lock_basic_lock(&stream_wait_count_lock);
|
||||
stream_wait_count -= (sizeof(struct tcp_req_done_item)
|
||||
+item->len);
|
||||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
free(item->buf);
|
||||
free(item);
|
||||
item = nitem;
|
||||
}
|
||||
req->done_req_list = NULL;
|
||||
req->num_done_req = 0;
|
||||
req->read_is_closed = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tcp_req_info_remove_mesh_state(struct tcp_req_info* req, struct mesh_state* m)
|
||||
{
|
||||
struct tcp_req_open_item* open, *prev = NULL;
|
||||
if(!req || !m) return;
|
||||
open = req->open_req_list;
|
||||
while(open) {
|
||||
if(open->mesh_state == m) {
|
||||
struct tcp_req_open_item* next;
|
||||
if(prev) prev->next = open->next;
|
||||
else req->open_req_list = open->next;
|
||||
/* caller has to manage the mesh state reply entry */
|
||||
next = open->next;
|
||||
free(open);
|
||||
req->num_open_req --;
|
||||
|
||||
/* prev = prev; */
|
||||
open = next;
|
||||
continue;
|
||||
}
|
||||
prev = open;
|
||||
open = open->next;
|
||||
}
|
||||
}
|
||||
|
||||
/** setup listening for read or write */
|
||||
static void
|
||||
tcp_req_info_setup_listen(struct tcp_req_info* req)
|
||||
{
|
||||
int wr = 0;
|
||||
int rd = 0;
|
||||
|
||||
if(req->cp->tcp_byte_count != 0) {
|
||||
/* cannot change, halfway through */
|
||||
return;
|
||||
}
|
||||
|
||||
if(!req->cp->tcp_is_reading)
|
||||
wr = 1;
|
||||
if(req->num_open_req + req->num_done_req < TCP_MAX_REQ_SIMULTANEOUS &&
|
||||
!req->read_is_closed)
|
||||
rd = 1;
|
||||
|
||||
if(wr) {
|
||||
req->cp->tcp_is_reading = 0;
|
||||
comm_point_stop_listening(req->cp);
|
||||
comm_point_start_listening(req->cp, -1,
|
||||
req->cp->tcp_timeout_msec);
|
||||
} else if(rd) {
|
||||
req->cp->tcp_is_reading = 1;
|
||||
comm_point_stop_listening(req->cp);
|
||||
comm_point_start_listening(req->cp, -1,
|
||||
req->cp->tcp_timeout_msec);
|
||||
/* and also read it (from SSL stack buffers), so
|
||||
* no event read event is expected since the remainder of
|
||||
* the TLS frame is sitting in the buffers. */
|
||||
req->read_again = 1;
|
||||
} else {
|
||||
comm_point_stop_listening(req->cp);
|
||||
comm_point_start_listening(req->cp, -1,
|
||||
req->cp->tcp_timeout_msec);
|
||||
comm_point_listen_for_rw(req->cp, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/** remove first item from list of pending results */
|
||||
static struct tcp_req_done_item*
|
||||
tcp_req_info_pop_done(struct tcp_req_info* req)
|
||||
{
|
||||
struct tcp_req_done_item* item;
|
||||
log_assert(req->num_done_req > 0 && req->done_req_list);
|
||||
item = req->done_req_list;
|
||||
lock_basic_lock(&stream_wait_count_lock);
|
||||
stream_wait_count -= (sizeof(struct tcp_req_done_item)+item->len);
|
||||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
req->done_req_list = req->done_req_list->next;
|
||||
req->num_done_req --;
|
||||
return item;
|
||||
}
|
||||
|
||||
/** Send given buffer and setup to write */
|
||||
static void
|
||||
tcp_req_info_start_write_buf(struct tcp_req_info* req, uint8_t* buf,
|
||||
size_t len)
|
||||
{
|
||||
sldns_buffer_clear(req->cp->buffer);
|
||||
sldns_buffer_write(req->cp->buffer, buf, len);
|
||||
sldns_buffer_flip(req->cp->buffer);
|
||||
|
||||
req->cp->tcp_is_reading = 0; /* we are now writing */
|
||||
}
|
||||
|
||||
/** pick up the next result and start writing it to the channel */
|
||||
static void
|
||||
tcp_req_pickup_next_result(struct tcp_req_info* req)
|
||||
{
|
||||
if(req->num_done_req > 0) {
|
||||
/* unlist the done item from the list of pending results */
|
||||
struct tcp_req_done_item* item = tcp_req_info_pop_done(req);
|
||||
tcp_req_info_start_write_buf(req, item->buf, item->len);
|
||||
free(item->buf);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
/** the read channel has closed */
|
||||
int
|
||||
tcp_req_info_handle_read_close(struct tcp_req_info* req)
|
||||
{
|
||||
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
|
||||
/* reset byte count for (potential) partial read */
|
||||
req->cp->tcp_byte_count = 0;
|
||||
/* if we still have results to write, pick up next and write it */
|
||||
if(req->num_done_req != 0) {
|
||||
tcp_req_pickup_next_result(req);
|
||||
tcp_req_info_setup_listen(req);
|
||||
return 1;
|
||||
}
|
||||
/* if nothing to do, this closes the connection */
|
||||
if(req->num_open_req == 0 && req->num_done_req == 0)
|
||||
return 0;
|
||||
/* otherwise, we must be waiting for dns resolve, wait with timeout */
|
||||
req->read_is_closed = 1;
|
||||
tcp_req_info_setup_listen(req);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tcp_req_info_handle_writedone(struct tcp_req_info* req)
|
||||
{
|
||||
/* back to reading state, we finished this write event */
|
||||
sldns_buffer_clear(req->cp->buffer);
|
||||
if(req->num_done_req == 0 && req->read_is_closed) {
|
||||
/* no more to write and nothing to read, close it */
|
||||
comm_point_drop_reply(&req->cp->repinfo);
|
||||
return;
|
||||
}
|
||||
req->cp->tcp_is_reading = 1;
|
||||
/* see if another result needs writing */
|
||||
tcp_req_pickup_next_result(req);
|
||||
|
||||
/* see if there is more to write, if not stop_listening for writing */
|
||||
/* see if new requests are allowed, if so, start_listening
|
||||
* for reading */
|
||||
tcp_req_info_setup_listen(req);
|
||||
}
|
||||
|
||||
void
|
||||
tcp_req_info_handle_readdone(struct tcp_req_info* req)
|
||||
{
|
||||
struct comm_point* c = req->cp;
|
||||
|
||||
/* we want to read up several requests, unless there are
|
||||
* pending answers */
|
||||
|
||||
req->is_drop = 0;
|
||||
req->is_reply = 0;
|
||||
req->in_worker_handle = 1;
|
||||
sldns_buffer_set_limit(req->spool_buffer, 0);
|
||||
/* handle the current request */
|
||||
/* this calls the worker handle request routine that could give
|
||||
* a cache response, or localdata response, or drop the reply,
|
||||
* or schedule a mesh entry for later */
|
||||
fptr_ok(fptr_whitelist_comm_point(c->callback));
|
||||
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
|
||||
req->in_worker_handle = 0;
|
||||
/* there is an answer, put it up. It is already in the
|
||||
* c->buffer, just send it. */
|
||||
/* since we were just reading a query, the channel is
|
||||
* clear to write to */
|
||||
send_it:
|
||||
c->tcp_is_reading = 0;
|
||||
comm_point_stop_listening(c);
|
||||
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
|
||||
return;
|
||||
}
|
||||
req->in_worker_handle = 0;
|
||||
/* it should be waiting in the mesh for recursion.
|
||||
* If mesh failed to add a new entry and called commpoint_drop_reply.
|
||||
* Then the mesh state has been cleared. */
|
||||
if(req->is_drop) {
|
||||
/* the reply has been dropped, stream has been closed. */
|
||||
return;
|
||||
}
|
||||
/* If mesh failed(mallocfail) and called commpoint_send_reply with
|
||||
* something like servfail then we pick up that reply below. */
|
||||
if(req->is_reply) {
|
||||
goto send_it;
|
||||
}
|
||||
|
||||
sldns_buffer_clear(c->buffer);
|
||||
/* if pending answers, pick up an answer and start sending it */
|
||||
tcp_req_pickup_next_result(req);
|
||||
|
||||
/* if answers pending, start sending answers */
|
||||
/* read more requests if we can have more requests */
|
||||
tcp_req_info_setup_listen(req);
|
||||
}
|
||||
|
||||
int
|
||||
tcp_req_info_add_meshstate(struct tcp_req_info* req,
|
||||
struct mesh_area* mesh, struct mesh_state* m)
|
||||
{
|
||||
struct tcp_req_open_item* item;
|
||||
log_assert(req && mesh && m);
|
||||
item = (struct tcp_req_open_item*)malloc(sizeof(*item));
|
||||
if(!item) return 0;
|
||||
item->next = req->open_req_list;
|
||||
item->mesh = mesh;
|
||||
item->mesh_state = m;
|
||||
req->open_req_list = item;
|
||||
req->num_open_req++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Add a result to the result list. At the end. */
|
||||
static int
|
||||
tcp_req_info_add_result(struct tcp_req_info* req, uint8_t* buf, size_t len)
|
||||
{
|
||||
struct tcp_req_done_item* last = NULL;
|
||||
struct tcp_req_done_item* item;
|
||||
size_t space;
|
||||
|
||||
/* see if we have space */
|
||||
space = sizeof(struct tcp_req_done_item) + len;
|
||||
lock_basic_lock(&stream_wait_count_lock);
|
||||
if(stream_wait_count + space > stream_wait_max) {
|
||||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
verbose(VERB_ALGO, "drop stream reply, no space left, in stream-wait-size");
|
||||
return 0;
|
||||
}
|
||||
stream_wait_count += space;
|
||||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
|
||||
/* find last element */
|
||||
last = req->done_req_list;
|
||||
while(last && last->next)
|
||||
last = last->next;
|
||||
|
||||
/* create new element */
|
||||
item = (struct tcp_req_done_item*)malloc(sizeof(*item));
|
||||
if(!item) {
|
||||
log_err("malloc failure, for stream result list");
|
||||
return 0;
|
||||
}
|
||||
item->next = NULL;
|
||||
item->len = len;
|
||||
item->buf = memdup(buf, len);
|
||||
if(!item->buf) {
|
||||
free(item);
|
||||
log_err("malloc failure, adding reply to stream result list");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* link in */
|
||||
if(last) last->next = item;
|
||||
else req->done_req_list = item;
|
||||
req->num_done_req++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tcp_req_info_send_reply(struct tcp_req_info* req)
|
||||
{
|
||||
if(req->in_worker_handle) {
|
||||
/* reply from mesh is in the spool_buffer */
|
||||
/* copy now, so that the spool buffer is free for other tasks
|
||||
* before the callback is done */
|
||||
sldns_buffer_clear(req->cp->buffer);
|
||||
sldns_buffer_write(req->cp->buffer,
|
||||
sldns_buffer_begin(req->spool_buffer),
|
||||
sldns_buffer_limit(req->spool_buffer));
|
||||
sldns_buffer_flip(req->cp->buffer);
|
||||
req->is_reply = 1;
|
||||
return;
|
||||
}
|
||||
/* now that the query has been handled, that mesh_reply entry
|
||||
* should be removed, from the tcp_req_info list,
|
||||
* the mesh state cleanup removes then with region_cleanup and
|
||||
* replies_sent true. */
|
||||
/* see if we can send it straight away (we are not doing
|
||||
* anything else). If so, copy to buffer and start */
|
||||
if(req->cp->tcp_is_reading && req->cp->tcp_byte_count == 0) {
|
||||
/* buffer is free, and was ready to read new query into,
|
||||
* but we are now going to use it to send this answer */
|
||||
tcp_req_info_start_write_buf(req,
|
||||
sldns_buffer_begin(req->spool_buffer),
|
||||
sldns_buffer_limit(req->spool_buffer));
|
||||
/* switch to listen to write events */
|
||||
comm_point_stop_listening(req->cp);
|
||||
comm_point_start_listening(req->cp, -1,
|
||||
req->cp->tcp_timeout_msec);
|
||||
return;
|
||||
}
|
||||
/* queue up the answer behind the others already pending */
|
||||
if(!tcp_req_info_add_result(req, sldns_buffer_begin(req->spool_buffer),
|
||||
sldns_buffer_limit(req->spool_buffer))) {
|
||||
/* drop the connection, we are out of resources */
|
||||
comm_point_drop_reply(&req->cp->repinfo);
|
||||
}
|
||||
}
|
||||
|
||||
size_t tcp_req_info_get_stream_buffer_size(void)
|
||||
{
|
||||
size_t s;
|
||||
if(!stream_wait_lock_inited)
|
||||
return stream_wait_count;
|
||||
lock_basic_lock(&stream_wait_count_lock);
|
||||
s = stream_wait_count;
|
||||
lock_basic_unlock(&stream_wait_count_lock);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -237,4 +237,134 @@ int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
*/
|
||||
int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
|
||||
|
||||
/**
|
||||
* TCP request info. List of requests outstanding on the channel, that
|
||||
* are asked for but not yet answered back.
|
||||
*/
|
||||
struct tcp_req_info {
|
||||
/** the TCP comm point for this. Its buffer is used for read/write */
|
||||
struct comm_point* cp;
|
||||
/** the buffer to use to spool reply from mesh into,
|
||||
* it can then be copied to the result list and written.
|
||||
* it is a pointer to the shared udp buffer. */
|
||||
struct sldns_buffer* spool_buffer;
|
||||
/** are we in worker_handle function call (for recursion callback)*/
|
||||
int in_worker_handle;
|
||||
/** is the comm point dropped (by worker handle).
|
||||
* That means we have to disconnect the channel. */
|
||||
int is_drop;
|
||||
/** is the comm point set to send_reply (by mesh new client in worker
|
||||
* handle), if so answer is available in c.buffer */
|
||||
int is_reply;
|
||||
/** read channel has closed, just write pending results */
|
||||
int read_is_closed;
|
||||
/** read again */
|
||||
int read_again;
|
||||
/** number of outstanding requests */
|
||||
int num_open_req;
|
||||
/** list of outstanding requests */
|
||||
struct tcp_req_open_item* open_req_list;
|
||||
/** number of pending writeable results */
|
||||
int num_done_req;
|
||||
/** list of pending writable result packets, malloced one at a time */
|
||||
struct tcp_req_done_item* done_req_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* List of open items in TCP channel
|
||||
*/
|
||||
struct tcp_req_open_item {
|
||||
/** next in list */
|
||||
struct tcp_req_open_item* next;
|
||||
/** the mesh area of the mesh_state */
|
||||
struct mesh_area* mesh;
|
||||
/** the mesh state */
|
||||
struct mesh_state* mesh_state;
|
||||
};
|
||||
|
||||
/**
|
||||
* List of done items in TCP channel
|
||||
*/
|
||||
struct tcp_req_done_item {
|
||||
/** next in list */
|
||||
struct tcp_req_done_item* next;
|
||||
/** the buffer with packet contents */
|
||||
uint8_t* buf;
|
||||
/** length of the buffer */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create tcp request info structure that keeps track of open
|
||||
* requests on the TCP channel that are resolved at the same time,
|
||||
* and the pending results that have to get written back to that client.
|
||||
* @param spoolbuf: shared buffer
|
||||
* @return new structure or NULL on alloc failure.
|
||||
*/
|
||||
struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf);
|
||||
|
||||
/**
|
||||
* Delete tcp request structure. Called by owning commpoint.
|
||||
* Removes mesh entry references and stored results from the lists.
|
||||
* @param req: the tcp request info
|
||||
*/
|
||||
void tcp_req_info_delete(struct tcp_req_info* req);
|
||||
|
||||
/**
|
||||
* Clear tcp request structure. Removes list entries, sets it up ready
|
||||
* for the next connection.
|
||||
* @param req: tcp request info structure.
|
||||
*/
|
||||
void tcp_req_info_clear(struct tcp_req_info* req);
|
||||
|
||||
/**
|
||||
* Remove mesh state entry from list in tcp_req_info.
|
||||
* caller has to manage the mesh state reply entry in the mesh state.
|
||||
* @param req: the tcp req info that has the entry removed from the list.
|
||||
* @param m: the state removed from the list.
|
||||
*/
|
||||
void tcp_req_info_remove_mesh_state(struct tcp_req_info* req,
|
||||
struct mesh_state* m);
|
||||
|
||||
/**
|
||||
* Handle write done of the last result packet
|
||||
* @param req: the tcp req info.
|
||||
*/
|
||||
void tcp_req_info_handle_writedone(struct tcp_req_info* req);
|
||||
|
||||
/**
|
||||
* Handle read done of a new request from the client
|
||||
* @param req: the tcp req info.
|
||||
*/
|
||||
void tcp_req_info_handle_readdone(struct tcp_req_info* req);
|
||||
|
||||
/**
|
||||
* Add mesh state to the tcp req list of open requests.
|
||||
* So the comm_reply can be removed off the mesh reply list when
|
||||
* the tcp channel has to be closed (for other reasons then that that
|
||||
* request was done, eg. channel closed by client or some format error).
|
||||
* @param req: tcp req info structure. It keeps track of the simultaneous
|
||||
* requests and results on a tcp (or TLS) channel.
|
||||
* @param mesh: mesh area for the state.
|
||||
* @param m: mesh state to add.
|
||||
* @return 0 on failure (malloc failure).
|
||||
*/
|
||||
int tcp_req_info_add_meshstate(struct tcp_req_info* req,
|
||||
struct mesh_area* mesh, struct mesh_state* m);
|
||||
|
||||
/**
|
||||
* Send reply on tcp simultaneous answer channel. May queue it up.
|
||||
* @param req: request info structure.
|
||||
*/
|
||||
void tcp_req_info_send_reply(struct tcp_req_info* req);
|
||||
|
||||
/** the read channel has closed
|
||||
* @param req: request. remaining queries are looked up and answered.
|
||||
* @return zero if nothing to do, just close the tcp.
|
||||
*/
|
||||
int tcp_req_info_handle_read_close(struct tcp_req_info* req);
|
||||
|
||||
/** get the size of currently used tcp stream wait buffers (in bytes) */
|
||||
size_t tcp_req_info_get_stream_buffer_size(void);
|
||||
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
||||
+22
-10
@@ -464,7 +464,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
return 0;
|
||||
}
|
||||
log_assert(z->dclass == rrclass);
|
||||
if(z->type == local_zone_redirect &&
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) &&
|
||||
query_dname_compare(z->name, nm) != 0) {
|
||||
log_err("local-data in redirect zone must reside at top of zone"
|
||||
", not at %s", rrstr);
|
||||
@@ -481,7 +482,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for a redirect zone. */
|
||||
if(z->type == local_zone_redirect && node->rrsets) {
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) && node->rrsets) {
|
||||
const char* othertype = NULL;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME)
|
||||
othertype = "other";
|
||||
@@ -1119,7 +1121,7 @@ local_zone_out(struct local_zone* z)
|
||||
struct local_rrset* p;
|
||||
RBTREE_FOR(d, struct local_data*, &z->data) {
|
||||
for(p = d->rrsets; p; p = p->next) {
|
||||
log_nametypeclass(0, "rrset", d->name,
|
||||
log_nametypeclass(NO_VERBOSE, "rrset", d->name,
|
||||
ntohs(p->rrset->rk.type),
|
||||
ntohs(p->rrset->rk.rrset_class));
|
||||
}
|
||||
@@ -1136,7 +1138,7 @@ void local_zones_print(struct local_zones* zones)
|
||||
lock_rw_rdlock(&z->lock);
|
||||
snprintf(buf, sizeof(buf), "%s zone",
|
||||
local_zone_type2str(z->type));
|
||||
log_nametypeclass(0, buf, z->name, 0, z->dclass);
|
||||
log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
|
||||
local_zone_out(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
@@ -1323,7 +1325,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
key.name = qinfo->qname;
|
||||
key.namelen = qinfo->qname_len;
|
||||
key.namelabs = labs;
|
||||
if(lz_type == local_zone_redirect) {
|
||||
if(lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect) {
|
||||
key.name = z->name;
|
||||
key.namelen = z->namelen;
|
||||
key.namelabs = z->namelabs;
|
||||
@@ -1355,7 +1358,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
return 0;
|
||||
|
||||
/* Special case for alias matching. See local_data_answer(). */
|
||||
if(lz_type == local_zone_redirect &&
|
||||
if((lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect) &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_CNAME &&
|
||||
lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
qinfo->local_alias =
|
||||
@@ -1370,7 +1374,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
|
||||
return 1;
|
||||
}
|
||||
if(lz_type == local_zone_redirect) {
|
||||
if(lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect) {
|
||||
/* convert rrset name to query name; like a wildcard */
|
||||
struct ub_packed_rrset_key r = *lr->rrset;
|
||||
r.rk.dname = qinfo->qname;
|
||||
@@ -1442,6 +1447,7 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_static ||
|
||||
lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect ||
|
||||
lz_type == local_zone_always_nxdomain) {
|
||||
/* for static, reply nodata or nxdomain
|
||||
* for redirect, reply nodata */
|
||||
@@ -1450,7 +1456,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
* or using closest match for NSEC.
|
||||
* or using closest match for returning delegation downwards
|
||||
*/
|
||||
int rcode = (ld || lz_type == local_zone_redirect)?
|
||||
int rcode = (ld || lz_type == local_zone_redirect ||
|
||||
lz_type == local_zone_inform_redirect)?
|
||||
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
|
||||
if(z->soa)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
@@ -1493,7 +1500,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
|
||||
(unsigned)port);
|
||||
log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
|
||||
log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
|
||||
}
|
||||
|
||||
static enum localzone_type
|
||||
@@ -1624,7 +1631,9 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
}
|
||||
}
|
||||
if((env->cfg->log_local_actions ||
|
||||
lzt == local_zone_inform || lzt == local_zone_inform_deny)
|
||||
lzt == local_zone_inform ||
|
||||
lzt == local_zone_inform_deny ||
|
||||
lzt == local_zone_inform_redirect)
|
||||
&& repinfo)
|
||||
lz_inform_print(z, qinfo, repinfo);
|
||||
|
||||
@@ -1656,6 +1665,7 @@ const char* local_zone_type2str(enum localzone_type t)
|
||||
case local_zone_nodefault: return "nodefault";
|
||||
case local_zone_inform: return "inform";
|
||||
case local_zone_inform_deny: return "inform_deny";
|
||||
case local_zone_inform_redirect: return "inform_redirect";
|
||||
case local_zone_always_transparent: return "always_transparent";
|
||||
case local_zone_always_refuse: return "always_refuse";
|
||||
case local_zone_always_nxdomain: return "always_nxdomain";
|
||||
@@ -1682,6 +1692,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
||||
*t = local_zone_inform;
|
||||
else if(strcmp(type, "inform_deny") == 0)
|
||||
*t = local_zone_inform_deny;
|
||||
else if(strcmp(type, "inform_redirect") == 0)
|
||||
*t = local_zone_inform_redirect;
|
||||
else if(strcmp(type, "always_transparent") == 0)
|
||||
*t = local_zone_always_transparent;
|
||||
else if(strcmp(type, "always_refuse") == 0)
|
||||
|
||||
@@ -83,6 +83,8 @@ enum localzone_type {
|
||||
local_zone_inform,
|
||||
/** log client address, and block (drop) */
|
||||
local_zone_inform_deny,
|
||||
/** log client address, and direct */
|
||||
local_zone_inform_redirect,
|
||||
/** resolve normally, even when there is local data */
|
||||
local_zone_always_transparent,
|
||||
/** answer with error, even when there is local data */
|
||||
@@ -491,6 +493,8 @@ enum respip_action {
|
||||
respip_inform = local_zone_inform,
|
||||
/** log query source and don't answer query */
|
||||
respip_inform_deny = local_zone_inform_deny,
|
||||
/** log query source and redirect */
|
||||
respip_inform_redirect = local_zone_inform_redirect,
|
||||
/** resolve normally, even when there is response-ip data */
|
||||
respip_always_transparent = local_zone_always_transparent,
|
||||
/** answer with 'refused' response */
|
||||
|
||||
+106
-52
@@ -61,6 +61,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
||||
/** subtract timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -84,7 +85,7 @@ timeval_add(struct timeval* d, const struct timeval* add)
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
if(d->tv_usec > 1000000 ) {
|
||||
if(d->tv_usec >= 1000000 ) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
@@ -353,6 +354,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
}
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
/* does this create a new reply state? */
|
||||
@@ -388,7 +393,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
return;
|
||||
@@ -404,7 +409,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
return;
|
||||
@@ -429,16 +434,23 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
/* add reply to s */
|
||||
if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
|
||||
log_err("mesh_new_client: out of memory; SERVFAIL");
|
||||
servfail_mem:
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
return;
|
||||
}
|
||||
if(rep->c->tcp_req_info) {
|
||||
if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
|
||||
log_err("mesh_new_client: out of memory add tcpreqinfo");
|
||||
goto servfail_mem;
|
||||
}
|
||||
}
|
||||
/* update statistics */
|
||||
if(was_detached) {
|
||||
log_assert(mesh->num_detached_states > 0);
|
||||
@@ -732,9 +744,13 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
mesh = mstate->s.env->mesh;
|
||||
/* drop unsent replies */
|
||||
if(!mstate->replies_sent) {
|
||||
struct mesh_reply* rep;
|
||||
struct mesh_reply* rep = mstate->reply_list;
|
||||
struct mesh_cb* cb;
|
||||
for(rep=mstate->reply_list; rep; rep=rep->next) {
|
||||
/* in tcp_req_info, the mstates linked are removed, but
|
||||
* the reply_list is now NULL, so the remove-from-empty-list
|
||||
* takes no time and also it does not do the mesh accounting */
|
||||
mstate->reply_list = NULL;
|
||||
for(; rep; rep=rep->next) {
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
@@ -1031,11 +1047,14 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
* @param rcode: if not 0, error code.
|
||||
* @param rep: reply to send (or NULL if rcode is set).
|
||||
* @param r: reply entry
|
||||
* @param r_buffer: buffer to use for reply entry.
|
||||
* @param prev: previous reply, already has its answer encoded in buffer.
|
||||
* @param prev_buffer: buffer for previous reply.
|
||||
*/
|
||||
static void
|
||||
mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
struct mesh_reply* r, struct mesh_reply* prev)
|
||||
struct mesh_reply* r, struct sldns_buffer* r_buffer,
|
||||
struct mesh_reply* prev, struct sldns_buffer* prev_buffer)
|
||||
{
|
||||
struct timeval end_time;
|
||||
struct timeval duration;
|
||||
@@ -1063,7 +1082,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
* and still reuse the previous answer if they are the same, but that
|
||||
* would be complicated and error prone for the relatively minor case.
|
||||
* So we err on the side of safety. */
|
||||
if(prev && prev->qflags == r->qflags &&
|
||||
if(prev && prev_buffer && prev->qflags == r->qflags &&
|
||||
!prev->local_alias && !r->local_alias &&
|
||||
prev->edns.edns_present == r->edns.edns_present &&
|
||||
prev->edns.bits == r->edns.bits &&
|
||||
@@ -1071,13 +1090,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
|
||||
== 0) {
|
||||
/* if the previous reply is identical to this one, fix ID */
|
||||
if(prev->query_reply.c->buffer != r->query_reply.c->buffer)
|
||||
sldns_buffer_copy(r->query_reply.c->buffer,
|
||||
prev->query_reply.c->buffer);
|
||||
sldns_buffer_write_at(r->query_reply.c->buffer, 0,
|
||||
&r->qid, sizeof(uint16_t));
|
||||
sldns_buffer_write_at(r->query_reply.c->buffer, 12,
|
||||
r->qname, m->s.qinfo.qname_len);
|
||||
if(prev_buffer != r_buffer)
|
||||
sldns_buffer_copy(r_buffer, prev_buffer);
|
||||
sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
|
||||
sldns_buffer_write_at(r_buffer, 12, r->qname,
|
||||
m->s.qinfo.qname_len);
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
} else if(rcode) {
|
||||
m->s.qinfo.qname = r->qname;
|
||||
@@ -1091,8 +1108,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
&r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
}
|
||||
error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
|
||||
r->qid, r->qflags, &r->edns);
|
||||
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
||||
r->qflags, &r->edns);
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
@@ -1108,16 +1125,15 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
m->s.env->cfg, r->query_reply.c,
|
||||
m->s.region) ||
|
||||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
r->qflags, r->query_reply.c->buffer, 0, 1,
|
||||
m->s.env->scratch, udp_size, &r->edns,
|
||||
(int)(r->edns.bits & EDNS_DO), secure))
|
||||
r->qflags, r_buffer, 0, 1, m->s.env->scratch,
|
||||
udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
|
||||
secure))
|
||||
{
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
error_encode(r->query_reply.c->buffer,
|
||||
LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid,
|
||||
r->qflags, &r->edns);
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
&m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||
}
|
||||
r->edns = edns_bak;
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
@@ -1132,19 +1148,17 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
|
||||
timehist_insert(m->s.env->mesh->histogram, &duration);
|
||||
if(m->s.env->cfg->stat_extended) {
|
||||
uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(r->
|
||||
query_reply.c->buffer, 2));
|
||||
uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(
|
||||
r_buffer, 2));
|
||||
if(secure) m->s.env->mesh->ans_secure++;
|
||||
m->s.env->mesh->ans_rcode[ rc ] ++;
|
||||
if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r->
|
||||
query_reply.c->buffer)) == 0)
|
||||
if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r_buffer)) == 0)
|
||||
m->s.env->mesh->ans_nodata++;
|
||||
}
|
||||
/* Log reply sent */
|
||||
if(m->s.env->cfg->log_replies) {
|
||||
log_reply_info(0, &m->s.qinfo, &r->query_reply.addr,
|
||||
r->query_reply.addrlen, duration, 0,
|
||||
r->query_reply.c->buffer);
|
||||
log_reply_info(NO_VERBOSE, &m->s.qinfo, &r->query_reply.addr,
|
||||
r->query_reply.addrlen, duration, 0, r_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1152,6 +1166,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
{
|
||||
struct mesh_reply* r;
|
||||
struct mesh_reply* prev = NULL;
|
||||
struct sldns_buffer* prev_buffer = NULL;
|
||||
struct mesh_cb* c;
|
||||
struct reply_info* rep = (mstate->s.return_msg?
|
||||
mstate->s.return_msg->rep:NULL);
|
||||
@@ -1180,9 +1195,19 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
if(mstate->s.is_drop)
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
else {
|
||||
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
prev_buffer = NULL;
|
||||
}
|
||||
mesh_send_reply(mstate, mstate->s.return_rcode, rep,
|
||||
r, prev);
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
r_buffer = NULL;
|
||||
}
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
@@ -1315,30 +1340,24 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
log_assert(!qinfo->local_alias->next && dsrc->count == 1 &&
|
||||
qinfo->local_alias->rrset->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME));
|
||||
/* Technically, we should make a local copy for the owner
|
||||
* name of the RRset, but in the case of the first (and
|
||||
* currently only) local alias RRset, the owner name should
|
||||
* point to the qname of the corresponding query, which should
|
||||
* be valid throughout the lifetime of this mesh_reply. So
|
||||
* we can skip copying. */
|
||||
log_assert(qinfo->local_alias->rrset->rk.dname ==
|
||||
sldns_buffer_at(rep->c->buffer, LDNS_HEADER_SIZE));
|
||||
/* we should make a local copy for the owner name of
|
||||
* the RRset */
|
||||
r->local_alias->rrset->rk.dname_len =
|
||||
qinfo->local_alias->rrset->rk.dname_len;
|
||||
r->local_alias->rrset->rk.dname = regional_alloc_init(
|
||||
s->s.region, qinfo->local_alias->rrset->rk.dname,
|
||||
qinfo->local_alias->rrset->rk.dname_len);
|
||||
if(!r->local_alias->rrset->rk.dname)
|
||||
return 0;
|
||||
|
||||
d = regional_alloc_init(s->s.region, dsrc,
|
||||
sizeof(struct packed_rrset_data)
|
||||
+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t));
|
||||
/* the rrset is not packed, like in the cache, but it is
|
||||
* individualy allocated with an allocator from localzone. */
|
||||
d = regional_alloc_zero(s->s.region, sizeof(*d));
|
||||
if(!d)
|
||||
return 0;
|
||||
r->local_alias->rrset->entry.data = d;
|
||||
d->rr_len = (size_t*)((uint8_t*)d +
|
||||
sizeof(struct packed_rrset_data));
|
||||
d->rr_data = (uint8_t**)&(d->rr_len[1]);
|
||||
d->rr_ttl = (time_t*)&(d->rr_data[1]);
|
||||
d->rr_len[0] = dsrc->rr_len[0];
|
||||
d->rr_ttl[0] = dsrc->rr_ttl[0];
|
||||
d->rr_data[0] = regional_alloc_init(s->s.region,
|
||||
dsrc->rr_data[0], d->rr_len[0]);
|
||||
if(!d->rr_data[0])
|
||||
if(!rrset_insert_rr(s->s.region, d, dsrc->rr_data[0],
|
||||
dsrc->rr_len[0], dsrc->rr_ttl[0], "CNAME local alias"))
|
||||
return 0;
|
||||
} else
|
||||
r->local_alias = NULL;
|
||||
@@ -1392,7 +1411,7 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
||||
/* module is looping. Stop it. */
|
||||
log_err("internal error: looping module (%s) stopped",
|
||||
mesh->mods.mod[mstate->s.curmod]->name);
|
||||
log_query_info(VERB_QUERY, "pass error for qstate",
|
||||
log_query_info(NO_VERBOSE, "pass error for qstate",
|
||||
&mstate->s.qinfo);
|
||||
s = module_error;
|
||||
}
|
||||
@@ -1613,3 +1632,38 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
|
||||
m->prev->next = m->next;
|
||||
else *fp = m->next;
|
||||
}
|
||||
|
||||
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
struct comm_point* cp)
|
||||
{
|
||||
struct mesh_reply* n, *prev = NULL;
|
||||
n = m->reply_list;
|
||||
/* when in mesh_cleanup, it sets the reply_list to NULL, so that
|
||||
* there is no accounting twice */
|
||||
if(!n) return; /* nothing to remove, also no accounting needed */
|
||||
while(n) {
|
||||
if(n->query_reply.c == cp) {
|
||||
/* unlink it */
|
||||
if(prev) prev->next = n->next;
|
||||
else m->reply_list = n->next;
|
||||
/* delete it, but allocated in m region */
|
||||
mesh->num_reply_addrs--;
|
||||
|
||||
/* prev = prev; */
|
||||
n = n->next;
|
||||
continue;
|
||||
}
|
||||
prev = n;
|
||||
n = n->next;
|
||||
}
|
||||
/* it was not detached (because it had a reply list), could be now */
|
||||
if(!m->reply_list && !m->cb_list
|
||||
&& m->super_set.count == 0) {
|
||||
mesh->num_detached_states++;
|
||||
}
|
||||
/* if not replies any more in mstate, it is no longer a reply_state */
|
||||
if(!m->reply_list && !m->cb_list) {
|
||||
log_assert(mesh->num_reply_states > 0);
|
||||
mesh->num_reply_states--;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -65,7 +65,7 @@ struct respip_client_info;
|
||||
* Maximum number of mesh state activations. Any more is likely an
|
||||
* infinite loop in the module. It is then terminated.
|
||||
*/
|
||||
#define MESH_MAX_ACTIVATION 3000
|
||||
#define MESH_MAX_ACTIVATION 10000
|
||||
|
||||
/**
|
||||
* Max number of references-to-references-to-references.. search size.
|
||||
@@ -633,4 +633,14 @@ void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp,
|
||||
void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
|
||||
struct mesh_state** lp);
|
||||
|
||||
/**
|
||||
* Remove mesh reply entry from the reply entry list. Searches for
|
||||
* the comm_point pointer.
|
||||
* @param mesh: to update the counters.
|
||||
* @param m: the mesh state.
|
||||
* @param cp: the comm_point to remove from the list.
|
||||
*/
|
||||
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
struct comm_point* cp);
|
||||
|
||||
#endif /* SERVICES_MESH_H */
|
||||
|
||||
+17
-2
@@ -60,6 +60,9 @@
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
#ifdef USE_IPSET
|
||||
#include "ipset/ipset.h"
|
||||
#endif
|
||||
|
||||
/** count number of modules (words) in the string */
|
||||
static int
|
||||
@@ -113,8 +116,14 @@ modstack_config(struct module_stack* stack, const char* module_conf)
|
||||
for(i=0; i<stack->num; i++) {
|
||||
stack->mod[i] = module_factory(&module_conf);
|
||||
if(!stack->mod[i]) {
|
||||
log_err("Unknown value for next module: '%s'",
|
||||
module_conf);
|
||||
char md[256];
|
||||
snprintf(md, sizeof(md), "%s", module_conf);
|
||||
if(strchr(md, ' ')) *(strchr(md, ' ')) = 0;
|
||||
if(strchr(md, '\t')) *(strchr(md, '\t')) = 0;
|
||||
log_err("Unknown value in module-config, module: '%s'."
|
||||
" This module is not present (not compiled in),"
|
||||
" See the list of linked modules with unbound -h",
|
||||
md);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -139,6 +148,9 @@ module_list_avail(void)
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
"subnetcache",
|
||||
#endif
|
||||
#ifdef USE_IPSET
|
||||
"ipset",
|
||||
#endif
|
||||
"respip",
|
||||
"validator",
|
||||
@@ -167,6 +179,9 @@ module_funcs_avail(void)
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
&subnetmod_get_funcblock,
|
||||
#endif
|
||||
#ifdef USE_IPSET
|
||||
&ipset_get_funcblock,
|
||||
#endif
|
||||
&respip_get_funcblock,
|
||||
&val_get_funcblock,
|
||||
|
||||
+114
-84
@@ -63,6 +63,9 @@
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
|
||||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
@@ -361,10 +364,17 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
verbose(VERB_ALGO, "the query is using TLS encryption, for %s",
|
||||
(w->tls_auth_name?w->tls_auth_name:"an unauthenticated connection"));
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
if(w->tls_auth_name) {
|
||||
#ifdef HAVE_SSL
|
||||
(void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if(w->tls_auth_name) {
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
@@ -374,10 +384,30 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
/* openssl 1.0.2 has this function that can be used for
|
||||
* set1_host like verification */
|
||||
if(w->tls_auth_name) {
|
||||
X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
|
||||
log_err("X509_VERIFY_PARAM_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
#else
|
||||
verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
w->pkt = NULL;
|
||||
@@ -752,7 +782,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
|
||||
}
|
||||
#endif
|
||||
if(numavailports == 0) {
|
||||
if(numavailports == 0 || num_ports == 0) {
|
||||
log_err("no outgoing ports available");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
@@ -1261,6 +1291,13 @@ outnet_tcptimer(void* arg)
|
||||
} else {
|
||||
/* it was in use */
|
||||
struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting;
|
||||
if(pend->c->ssl) {
|
||||
#ifdef HAVE_SSL
|
||||
SSL_shutdown(pend->c->ssl);
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
#endif
|
||||
}
|
||||
comm_point_close(pend->c);
|
||||
pend->query = NULL;
|
||||
pend->next_free = outnet->tcp_free;
|
||||
@@ -1473,7 +1510,6 @@ serviced_delete(struct serviced_query* sq)
|
||||
/* clear up the pending query */
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP ||
|
||||
sq->status == serviced_query_PROBE_EDNS ||
|
||||
sq->status == serviced_query_UDP_EDNS_FRAG ||
|
||||
sq->status == serviced_query_UDP_EDNS_fallback) {
|
||||
struct pending* p = (struct pending*)sq->pending;
|
||||
@@ -1600,15 +1636,7 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff)
|
||||
sq->last_rtt = rtt;
|
||||
verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
|
||||
if(sq->status == serviced_initial) {
|
||||
if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) {
|
||||
/* perform EDNS lame probe - check if server is
|
||||
* EDNS lame (EDNS queries to it are dropped) */
|
||||
verbose(VERB_ALGO, "serviced query: send probe to see "
|
||||
" if use of EDNS causes timeouts");
|
||||
/* even 700 msec may be too small */
|
||||
rtt = 1000;
|
||||
sq->status = serviced_query_PROBE_EDNS;
|
||||
} else if(vs != -1) {
|
||||
if(vs != -1) {
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
} else {
|
||||
sq->status = serviced_query_UDP;
|
||||
@@ -1862,7 +1890,7 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
|
||||
if(!sq->pending) {
|
||||
/* delete from tree so that a retry by above layer does not
|
||||
* clash with this entry */
|
||||
log_err("serviced_tcp_initiate: failed to send tcp query");
|
||||
verbose(VERB_ALGO, "serviced_tcp_initiate: failed to send tcp query");
|
||||
serviced_callbacks(sq, NETEVENT_CLOSED, NULL, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1940,17 +1968,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
struct serviced_query* sq = (struct serviced_query*)arg;
|
||||
struct outside_network* outnet = sq->outnet;
|
||||
struct timeval now = *sq->outnet->now_tv;
|
||||
int fallback_tcp = 0;
|
||||
|
||||
sq->pending = NULL; /* removed after callback */
|
||||
if(error == NETEVENT_TIMEOUT) {
|
||||
int rto = 0;
|
||||
if(sq->status == serviced_query_PROBE_EDNS) {
|
||||
/* non-EDNS probe failed; we do not know its status,
|
||||
* keep trying with EDNS, timeout may not be caused
|
||||
* by EDNS. */
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
}
|
||||
if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
|
||||
/* fallback to 1480/1280 */
|
||||
sq->status = serviced_query_UDP_EDNS_FRAG;
|
||||
@@ -1978,14 +1999,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(rto >= RTT_MAX_TIMEOUT) {
|
||||
fallback_tcp = 1;
|
||||
/* UDP does not work, fallback to TCP below */
|
||||
} else {
|
||||
serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep);
|
||||
return 0;
|
||||
}
|
||||
} else if(error != NETEVENT_NOERROR) {
|
||||
}
|
||||
if(error != NETEVENT_NOERROR) {
|
||||
/* udp returns error (due to no ID or interface available) */
|
||||
serviced_callbacks(sq, error, c, rep);
|
||||
return 0;
|
||||
@@ -1998,9 +2013,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen,
|
||||
&sq->last_sent_time, sq->outnet->now_tv, c->buffer);
|
||||
#endif
|
||||
if(!fallback_tcp) {
|
||||
if( (sq->status == serviced_query_UDP_EDNS
|
||||
||sq->status == serviced_query_UDP_EDNS_FRAG)
|
||||
if( (sq->status == serviced_query_UDP_EDNS
|
||||
||sq->status == serviced_query_UDP_EDNS_FRAG)
|
||||
&& (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer))
|
||||
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
|
||||
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL
|
||||
@@ -2014,19 +2028,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
|
||||
}
|
||||
return 0;
|
||||
} else if(sq->status == serviced_query_PROBE_EDNS) {
|
||||
/* probe without EDNS succeeds, so we conclude that this
|
||||
* host likely has EDNS packets dropped */
|
||||
log_addr(VERB_DETAIL, "timeouts, concluded that connection to "
|
||||
"host drops EDNS packets", &sq->addr, sq->addrlen);
|
||||
/* only store noEDNS in cache if domain is noDNSSEC */
|
||||
if(!sq->want_dnssec)
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching no edns for host");
|
||||
}
|
||||
sq->status = serviced_query_UDP;
|
||||
} else if(sq->status == serviced_query_UDP_EDNS &&
|
||||
} else if(sq->status == serviced_query_UDP_EDNS &&
|
||||
!sq->edns_lame_known) {
|
||||
/* now we know that edns queries received answers store that */
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS works for",
|
||||
@@ -2036,7 +2038,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_err("Out of memory caching edns works");
|
||||
}
|
||||
sq->edns_lame_known = 1;
|
||||
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
|
||||
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
|
||||
!sq->edns_lame_known && (LDNS_RCODE_WIRE(
|
||||
sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
|
||||
LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||
@@ -2054,12 +2056,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
} else {
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS fails, but "
|
||||
"not stored because need DNSSEC for", &sq->addr,
|
||||
"not stored because need DNSSEC for", &sq->addr,
|
||||
sq->addrlen);
|
||||
}
|
||||
sq->status = serviced_query_UDP;
|
||||
}
|
||||
if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
}
|
||||
if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
(now.tv_sec == sq->last_sent_time.tv_sec &&
|
||||
now.tv_usec > sq->last_sent_time.tv_usec)) {
|
||||
/* convert from microseconds to milliseconds */
|
||||
@@ -2075,11 +2077,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
sq->last_rtt, (time_t)now.tv_sec))
|
||||
log_err("out of memory noting rtt.");
|
||||
}
|
||||
}
|
||||
} /* end of if_!fallback_tcp */
|
||||
}
|
||||
/* perform TC flag check and TCP fallback after updating our
|
||||
* cache entries for EDNS status and RTT times */
|
||||
if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) {
|
||||
if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
/* fallback to TCP */
|
||||
/* this discards partial UDP contents */
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
@@ -2133,18 +2134,14 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(outnet->do_udp && !(tcp_upstream || ssl_upstream)) {
|
||||
if(!serviced_udp_send(sq, buff)) {
|
||||
(void)rbtree_delete(outnet->serviced, sq);
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq);
|
||||
serviced_node_del(&sq->node, NULL);
|
||||
free(cb);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if(!serviced_tcp_send(sq, buff)) {
|
||||
(void)rbtree_delete(outnet->serviced, sq);
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq);
|
||||
serviced_node_del(&sq->node, NULL);
|
||||
free(cb);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2280,11 +2277,60 @@ outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
return cp;
|
||||
}
|
||||
|
||||
/** setup SSL for comm point */
|
||||
static int
|
||||
setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
|
||||
int fd, char* host)
|
||||
{
|
||||
cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
|
||||
if(!cp->ssl) {
|
||||
log_err("cannot create SSL object");
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_tcp_win_bio_cb(cp, cp->ssl);
|
||||
#endif
|
||||
cp->ssl_shake_state = comm_ssl_shake_write;
|
||||
/* https verification */
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
/* because we set SSL_VERIFY_PEER, in netevent in
|
||||
* ssl_handshake, it'll check if the certificate
|
||||
* verification has succeeded */
|
||||
/* SSL_VERIFY_PEER is set on the sslctx */
|
||||
/* and the certificates to verify with are loaded into
|
||||
* it with SSL_load_verify_locations or
|
||||
* SSL_CTX_set_default_verify_paths */
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(cp->ssl, host)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
/* openssl 1.0.2 has this function that can be used for
|
||||
* set1_host like verification */
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
|
||||
log_err("X509_VERIFY_PARAM_set1_host failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)host;
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct comm_point*
|
||||
outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
sldns_buffer* query, int timeout)
|
||||
sldns_buffer* query, int timeout, int ssl, char* host)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
@@ -2304,6 +2350,16 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
}
|
||||
cp->repinfo.addrlen = to_addrlen;
|
||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
||||
|
||||
/* setup for SSL (if needed) */
|
||||
if(ssl) {
|
||||
if(!setup_comm_ssl(cp, outnet, fd, host)) {
|
||||
log_err("cannot setup XoT");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* set timeout on TCP connection */
|
||||
comm_point_start_listening(cp, fd, timeout);
|
||||
/* copy scratch buffer to cp->buffer */
|
||||
@@ -2360,36 +2416,11 @@ outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
|
||||
/* setup for SSL (if needed) */
|
||||
if(ssl) {
|
||||
cp->ssl = outgoing_ssl_fd(outnet->sslctx, fd);
|
||||
if(!cp->ssl) {
|
||||
if(!setup_comm_ssl(cp, outnet, fd, host)) {
|
||||
log_err("cannot setup https");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef USE_WINSOCK
|
||||
comm_point_tcp_win_bio_cb(cp, cp->ssl);
|
||||
#endif
|
||||
cp->ssl_shake_state = comm_ssl_shake_write;
|
||||
/* https verification */
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
/* because we set SSL_VERIFY_PEER, in netevent in
|
||||
* ssl_handshake, it'll check if the certificate
|
||||
* verification has succeeded */
|
||||
/* SSL_VERIFY_PEER is set on the sslctx */
|
||||
/* and the certificates to verify with are loaded into
|
||||
* it with SSL_load_verify_locations or
|
||||
* SSL_CTX_set_default_verify_paths */
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(cp->ssl, host)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
comm_point_delete(cp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
|
||||
/* set timeout on TCP connection */
|
||||
@@ -2494,7 +2525,6 @@ serviced_get_mem(struct serviced_query* sq)
|
||||
s += sizeof(*sb);
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP ||
|
||||
sq->status == serviced_query_PROBE_EDNS ||
|
||||
sq->status == serviced_query_UDP_EDNS_FRAG ||
|
||||
sq->status == serviced_query_UDP_EDNS_fallback) {
|
||||
s += sizeof(struct pending);
|
||||
|
||||
@@ -359,8 +359,6 @@ struct serviced_query {
|
||||
serviced_query_TCP_EDNS,
|
||||
/** TCP without EDNS sent */
|
||||
serviced_query_TCP,
|
||||
/** probe to test EDNS lameness (EDNS is dropped) */
|
||||
serviced_query_PROBE_EDNS,
|
||||
/** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */
|
||||
serviced_query_UDP_EDNS_fallback,
|
||||
/** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */
|
||||
@@ -572,12 +570,14 @@ struct comm_point* outnet_comm_point_for_udp(struct outside_network* outnet,
|
||||
* @param timeout: timeout for the TCP connection.
|
||||
* timeout in milliseconds, or -1 for no (change to the) timeout.
|
||||
* So seconds*1000.
|
||||
* @param ssl: set to true for TLS.
|
||||
* @param host: hostname for host name verification of TLS (or NULL if no TLS).
|
||||
* @return tcp_out commpoint, or NULL.
|
||||
*/
|
||||
struct comm_point* outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
comm_point_callback_type* cb, void* cb_arg,
|
||||
struct sockaddr_storage* to_addr, socklen_t to_addrlen,
|
||||
struct sldns_buffer* query, int timeout);
|
||||
struct sldns_buffer* query, int timeout, int ssl, char* host);
|
||||
|
||||
/**
|
||||
* Create http commpoint suitable for communication to the destination.
|
||||
|
||||
+7
-1
@@ -325,8 +325,14 @@ sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim,
|
||||
if (c == '\n' && p != 0) {
|
||||
/* in parentheses */
|
||||
/* do not write ' ' if we want to skip spaces */
|
||||
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' '))))
|
||||
if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) {
|
||||
/* check for space for the space character */
|
||||
if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
|
||||
*t = '\0';
|
||||
return -1;
|
||||
}
|
||||
*t++ = ' ';
|
||||
}
|
||||
lc = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
+191
-191
@@ -236,7 +236,7 @@ static const sldns_rdf_type type_caa_wireformat[] = {
|
||||
*/
|
||||
static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 0 */
|
||||
{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 1 */
|
||||
{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 2 */
|
||||
@@ -344,7 +344,7 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 53 */
|
||||
{LDNS_RR_TYPE_SMIMEA, "SMIMEA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 54 */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 55
|
||||
* Hip ends with 0 or more Rendezvous Servers represented as dname's.
|
||||
* Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
|
||||
@@ -358,8 +358,8 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 57 */
|
||||
{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 58 */
|
||||
{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
|
||||
@@ -372,54 +372,54 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
{LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 62 */
|
||||
{LDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* 99 */
|
||||
{LDNS_RR_TYPE_SPF, "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* UINFO [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* UID [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* GID [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* UNSPEC [IANA-Reserved] */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* 104 */
|
||||
{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
@@ -435,145 +435,145 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 109 */
|
||||
{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
|
||||
/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
|
||||
* So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
|
||||
@@ -605,7 +605,7 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 258 */
|
||||
{LDNS_RR_TYPE_AVC, "AVC", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
|
||||
/* split in array, no longer contiguous */
|
||||
@@ -614,7 +614,7 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
/* 32768 */
|
||||
{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
{(enum sldns_enum_rr_type)0, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 32769 */
|
||||
{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
|
||||
@@ -710,18 +710,18 @@ sldns_get_rr_type_by_name(const char *name)
|
||||
|
||||
/* special cases for query types */
|
||||
if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
|
||||
return 251;
|
||||
return LDNS_RR_TYPE_IXFR;
|
||||
} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
|
||||
return 252;
|
||||
return LDNS_RR_TYPE_AXFR;
|
||||
} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
|
||||
return 253;
|
||||
return LDNS_RR_TYPE_MAILB;
|
||||
} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
|
||||
return 254;
|
||||
return LDNS_RR_TYPE_MAILA;
|
||||
} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
|
||||
return 255;
|
||||
return LDNS_RR_TYPE_ANY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (enum sldns_enum_rr_type)0;
|
||||
}
|
||||
|
||||
sldns_rr_class
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user