mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
1771
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e06b929220 | ||
|
|
f3473f6d30 | ||
|
|
0c07861404 | ||
|
|
00cf7195f5 | ||
|
|
0927fe6fc4 | ||
|
|
6c5e67a5a2 | ||
|
|
269c168f7e | ||
|
|
1bdae426ee | ||
|
|
6e4ecf7bc1 | ||
|
|
9753f36463 | ||
|
|
6cd77933a3 | ||
|
|
826828673a | ||
|
|
a06d761f74 | ||
|
|
6c464386c6 | ||
|
|
209dc32624 | ||
|
|
04b4f515a7 | ||
|
|
6cda81b7e4 | ||
|
|
6612974d12 | ||
|
|
a9e15f36d8 | ||
|
|
e6ffacc16a | ||
|
|
d3497f6bd1 | ||
|
|
7f25bb4730 | ||
|
|
d69132b921 | ||
|
|
39a557833d | ||
|
|
c802298fca | ||
|
|
7ec290255d | ||
|
|
131d38f8f2 | ||
|
|
40fbc3fa8a | ||
|
|
aa53b933cc | ||
|
|
bc4bdbabea | ||
|
|
f5339ec7e5 | ||
|
|
3b24d845ff | ||
|
|
bf0a91aa41 | ||
|
|
d6e55a586c | ||
|
|
2d27203718 | ||
|
|
490d4c26cf | ||
|
|
92d01d8265 | ||
|
|
5943c6f2e3 | ||
|
|
74e06cc4b3 | ||
|
|
c906401597 | ||
|
|
48e0d3356a | ||
|
|
b7ffa6618c | ||
|
|
8490508559 | ||
|
|
6965cef5e8 | ||
|
|
e0f17c2443 | ||
|
|
d3b6e1679c | ||
|
|
9a972aa5b2 | ||
|
|
12171e3124 | ||
|
|
3d2692d6bc | ||
|
|
ee0a65250a | ||
|
|
d0c4ce2dc5 | ||
|
|
5d5e4579de | ||
|
|
e0d426ebb1 | ||
|
|
450155bfa0 | ||
|
|
d3b5f287b1 | ||
|
|
b7a633fdc0 | ||
|
|
c365e3ab9a | ||
|
|
4693929471 | ||
|
|
aa8dfe94d3 | ||
|
|
18840665bc | ||
|
|
f9a1ac3f0b | ||
|
|
bc013b66ed | ||
|
|
a5a9672dc4 | ||
|
|
21def26405 | ||
|
|
bb09b649f7 | ||
|
|
a8485d58ca | ||
|
|
7262a249f1 | ||
|
|
0ea86f6ccb | ||
|
|
ad8104bb7c | ||
|
|
3a19ceaae6 | ||
|
|
cb55b5906a | ||
|
|
9e6f8567de | ||
|
|
9d700e1f85 | ||
|
|
8ad4c9f92a | ||
|
|
3124eb052d | ||
|
|
3b9c7e2826 | ||
|
|
08ca72fffe | ||
|
|
5e92836760 | ||
|
|
2925fa46b0 | ||
|
|
515df834a5 | ||
|
|
83d9f9d268 | ||
|
|
c18f61a3c4 | ||
|
|
707eb6108d | ||
|
|
b7acaaa9b8 | ||
|
|
f5b7169729 | ||
|
|
a565add710 | ||
|
|
ca2139bf3d | ||
|
|
4694323b1c | ||
|
|
efc8022ca4 | ||
|
|
54b84381f4 | ||
|
|
d253db04fd | ||
|
|
c4c849d878 | ||
|
|
fc49d145b5 | ||
|
|
b7864b0c48 | ||
|
|
2a3548e1ef | ||
|
|
dedc1e2340 | ||
|
|
20ff80c5bb | ||
|
|
3a6f1ecafa | ||
|
|
63a02f3a87 | ||
|
|
dc23502abb | ||
|
|
48ecf95108 | ||
|
|
0215500261 | ||
|
|
38e12229b8 | ||
|
|
9de4c398e1 | ||
|
|
68d51317fe | ||
|
|
68d92b7bbb | ||
|
|
7ba51fce24 | ||
|
|
9056613a79 | ||
|
|
a152c7f907 | ||
|
|
f273716b80 | ||
|
|
c125fe67bc | ||
|
|
e55f38fa83 | ||
|
|
9a055c2df4 | ||
|
|
285a7fdd21 | ||
|
|
4613d2bf04 | ||
|
|
3b82e690ef | ||
|
|
5314f63343 | ||
|
|
24fd871245 | ||
|
|
7e46204bf7 | ||
|
|
93e5705259 | ||
|
|
4d1d8b4cdd | ||
|
|
d1b92a6ce2 | ||
|
|
3322f631e5 | ||
|
|
64f508fa00 | ||
|
|
d9dd7bc36f | ||
|
|
1aa7168c6a | ||
|
|
ee2545d939 | ||
|
|
3e03e2c26d | ||
|
|
260837e050 | ||
|
|
48724de155 | ||
|
|
2e4d64684e | ||
|
|
752aea8407 | ||
|
|
d188096a01 | ||
|
|
422213c171 | ||
|
|
44075a06a5 | ||
|
|
c357e0fea4 | ||
|
|
2c1ecb2231 | ||
|
|
b788e29265 | ||
|
|
4c4ca2433c | ||
|
|
64cccdb8d5 | ||
|
|
4d51c6b86e | ||
|
|
e3abd772f7 | ||
|
|
08968baec1 | ||
|
|
42d764eeda | ||
|
|
811cf6db0c | ||
|
|
e1c678864d | ||
|
|
48c038391a | ||
|
|
f09b058776 | ||
|
|
29b5b25852 | ||
|
|
15e1b16da0 | ||
|
|
7077660932 | ||
|
|
a4fc32809c | ||
|
|
1f7d1a00ff | ||
|
|
51e431ada1 | ||
|
|
e25f80799a | ||
|
|
9ea58b5bc0 | ||
|
|
af96ff157e | ||
|
|
2baa748bc7 | ||
|
|
6ce577c4d9 | ||
|
|
6bf1293bcd | ||
|
|
9272725cdd | ||
|
|
7167153db5 | ||
|
|
275f18cc8e | ||
|
|
91bec32cdc | ||
|
|
72d3b588ca | ||
|
|
159bf52384 | ||
|
|
1f1b93cce6 | ||
|
|
31cedb47cb | ||
|
|
bdfa65c6ab | ||
|
|
b49cc2e667 | ||
|
|
e21d38dcb9 | ||
|
|
37d751e135 | ||
|
|
9eeb95a960 | ||
|
|
0502ab3026 | ||
|
|
e049fb303c | ||
|
|
eb052e1543 | ||
|
|
fb150f9655 | ||
|
|
cbb4575a18 | ||
|
|
16c496bff6 | ||
|
|
1ebf851bf0 | ||
|
|
ddb751751c | ||
|
|
5906811ff1 | ||
|
|
174bb48ae8 | ||
|
|
e4bdc527ba | ||
|
|
56a80fbbf4 | ||
|
|
b2894e23a9 | ||
|
|
67d541d690 | ||
|
|
8ffdbc2714 | ||
|
|
11139c1b4e | ||
|
|
3fb0493d3f | ||
|
|
67a0614db7 | ||
|
|
e9810e1154 | ||
|
|
4a8669612a | ||
|
|
f6bf015f90 | ||
|
|
e50152aa1f | ||
|
|
d05c259458 | ||
|
|
a5167e495f | ||
|
|
3c2b1fa801 | ||
|
|
4b644b7965 | ||
|
|
15e8f5c6d4 | ||
|
|
5924a591be | ||
|
|
328e8d2294 | ||
|
|
f44118408b | ||
|
|
4e8a1ede3b | ||
|
|
978d3840dc | ||
|
|
6a324a37ca | ||
|
|
e78957706c | ||
|
|
a69304011a | ||
|
|
090a4e417d | ||
|
|
de4e6ad99d | ||
|
|
a2411361b6 | ||
|
|
ead06af086 | ||
|
|
f04f7fdf17 | ||
|
|
db945f018b | ||
|
|
b0247b6e93 | ||
|
|
201b949689 | ||
|
|
2d184f7505 | ||
|
|
62152e0493 | ||
|
|
19f8f4d9f9 | ||
|
|
ad38783297 | ||
|
|
9cc8aa1ddf | ||
|
|
6b97cb1dd1 | ||
|
|
cca128b871 | ||
|
|
9423b5b8b2 | ||
|
|
dde9fade26 | ||
|
|
4445d9c5aa | ||
|
|
8143ce6967 | ||
|
|
6f4c79ab95 | ||
|
|
fd94b0bc9b | ||
|
|
6ded710013 | ||
|
|
d83b1979c4 | ||
|
|
097e530c49 | ||
|
|
dbd5ea4f37 | ||
|
|
c48f01445e | ||
|
|
b891fe113c | ||
|
|
48b40b305a | ||
|
|
26aa550bd2 | ||
|
|
a4342ceb3a | ||
|
|
946ed23f73 | ||
|
|
5385e2e094 | ||
|
|
7977e1c4cb | ||
|
|
72d7587138 | ||
|
|
3926035f30 | ||
|
|
140ab1f701 | ||
|
|
18226f1c17 | ||
|
|
e573f55dcd | ||
|
|
cd3d54b504 | ||
|
|
2757e0ff51 | ||
|
|
43e32eae33 | ||
|
|
3ab188ea21 | ||
|
|
7ebb890a4a | ||
|
|
9fb65e2b9e | ||
|
|
639a773c39 | ||
|
|
d104727c91 | ||
|
|
94ac072f9b | ||
|
|
8e53f0b14f | ||
|
|
2b9569c7fe | ||
|
|
165b048e07 | ||
|
|
caee84d92e | ||
|
|
89087ae294 | ||
|
|
c72ca35f08 | ||
|
|
fb5f3f076d | ||
|
|
40e713e121 | ||
|
|
1cb7d5a194 | ||
|
|
f854f4e867 | ||
|
|
54d8473ec6 | ||
|
|
6ea1ae17f7 | ||
|
|
e09873e0c8 | ||
|
|
5d7e001c63 | ||
|
|
4990dae87d | ||
|
|
ca39cfd6ae | ||
|
|
0272889c44 | ||
|
|
7c39cbc0a9 | ||
|
|
4ba45c34ed | ||
|
|
92eb12d26b | ||
|
|
7ac4eb229d | ||
|
|
3c86bf51de | ||
|
|
58d91646f1 | ||
|
|
e1d119af7e | ||
|
|
c32c9a0ae2 | ||
|
|
1245457967 | ||
|
|
e8d29f973d | ||
|
|
2ebc4eae2f | ||
|
|
ee3f26bb3d | ||
|
|
1e9381f76c | ||
|
|
725d4822e7 | ||
|
|
5ec15bc333 | ||
|
|
37354c8927 | ||
|
|
78e9b8949c | ||
|
|
2eb39abbaf | ||
|
|
f675077502 | ||
|
|
89618ff9ba | ||
|
|
6fdc822aa0 | ||
|
|
736a298eac | ||
|
|
2527ad1d46 | ||
|
|
50178d764a | ||
|
|
61922ce9da | ||
|
|
531ce9e85c | ||
|
|
68c57314c4 | ||
|
|
59d15ac9cf | ||
|
|
4a14ef8c3a | ||
|
|
8861fb17fa | ||
|
|
a433a25ba3 | ||
|
|
ab9d732796 | ||
|
|
ca6e8ec6c2 | ||
|
|
5cd2d10fe5 | ||
|
|
c8390e390d | ||
|
|
a3e2bfbb0c | ||
|
|
ba074c8bef | ||
|
|
46607e7c0c | ||
|
|
f81d0ac047 | ||
|
|
1d11f470df | ||
|
|
a525284421 | ||
|
|
ceb0214b7d | ||
|
|
d55084ea9e | ||
|
|
0a238280b9 | ||
|
|
e6aab488c8 | ||
|
|
cf6e1b6ea9 | ||
|
|
edc8f363a7 | ||
|
|
7a7d7caf6a | ||
|
|
b1a50720e5 | ||
|
|
e35b1dfbd5 | ||
|
|
42d7cdb7d5 | ||
|
|
890c8deb0f | ||
|
|
f0c19be06f | ||
|
|
a9e13f3590 | ||
|
|
22e82765f9 | ||
|
|
72032a95bb | ||
|
|
79a8db1ee1 | ||
|
|
e6c560e5c9 | ||
|
|
efc01c928c | ||
|
|
754e6f1349 | ||
|
|
0af62aba53 | ||
|
|
c49a4e60fe | ||
|
|
1dc4d7a9f6 | ||
|
|
5e477e8a31 | ||
|
|
fca884a7e6 | ||
|
|
6cb0c4c61d | ||
|
|
b20fefb858 | ||
|
|
6a8ed4bb15 | ||
|
|
2f7908b669 | ||
|
|
cdf6544b46 | ||
|
|
eb4932a463 | ||
|
|
d7e4525829 | ||
|
|
795a33c6e5 | ||
|
|
a87f05be7b | ||
|
|
ca497815b8 | ||
|
|
3163a93121 | ||
|
|
ca31ea7dc8 | ||
|
|
db6030dd39 | ||
|
|
52b04806f4 | ||
|
|
eb799026ff | ||
|
|
ea7c5ac392 | ||
|
|
46b3440aea | ||
|
|
a453ab629c | ||
|
|
bbba236a36 | ||
|
|
ddb82af523 | ||
|
|
a7ae0ade66 | ||
|
|
b6d04f500b | ||
|
|
83200a3431 | ||
|
|
eb8ec9c18b | ||
|
|
3527171397 | ||
|
|
ed6e3c0c66 | ||
|
|
7da369e85a | ||
|
|
e41daa954e | ||
|
|
48a56751e9 | ||
|
|
9e9810ab8b | ||
|
|
249d5a706b | ||
|
|
00fe4b0306 | ||
|
|
c5f0ec36bb | ||
|
|
1175269bbd | ||
|
|
9d78ad6898 | ||
|
|
8deb912fa9 | ||
|
|
41ab788cab | ||
|
|
56e0e5b9af | ||
|
|
6ea24c5c86 | ||
|
|
867886800a | ||
|
|
ea90f50ca8 | ||
|
|
2541ccbb1b | ||
|
|
4ae823fbc2 | ||
|
|
42a35ac26e | ||
|
|
4cc559d7eb | ||
|
|
1a568a1b8c | ||
|
|
0ce7769719 | ||
|
|
291ac59888 | ||
|
|
a3be2b73b6 | ||
|
|
39f6071854 | ||
|
|
82f2ee63c5 | ||
|
|
afbc7bb4fe | ||
|
|
47a5dc8cae | ||
|
|
a6dc0743b4 | ||
|
|
01bfd3f207 | ||
|
|
f22ac44f89 | ||
|
|
2460737490 | ||
|
|
12c0cf7cee | ||
|
|
b5a237424b | ||
|
|
f6a527c25a | ||
|
|
852a2e1105 | ||
|
|
f5d8861bbf | ||
|
|
a912786ca9 | ||
|
|
49019ba3a9 | ||
|
|
a83fc176cc | ||
|
|
aa602fdd0c | ||
|
|
45d4cbaa42 | ||
|
|
45712de9a2 | ||
|
|
e6ebabc0cc | ||
|
|
8b05dcdf8c | ||
|
|
b75ff25cfd | ||
|
|
3e86d30a50 | ||
|
|
59a66601f0 | ||
|
|
a6603c94d8 | ||
|
|
5551bf20e6 | ||
|
|
31f81adadb | ||
|
|
a3f95d3358 | ||
|
|
afd49e897f | ||
|
|
f35293caba | ||
|
|
8fd489ea69 | ||
|
|
2fade6f970 | ||
|
|
022a716e5b | ||
|
|
4ec55910c4 | ||
|
|
50091d49ea | ||
|
|
ce0b39007d | ||
|
|
74ec8a758b | ||
|
|
70c8d09edd | ||
|
|
8f2b9b461b | ||
|
|
dd59521e52 | ||
|
|
ded7fdafb3 | ||
|
|
74c1d5b3f5 | ||
|
|
764a0dc765 | ||
|
|
f78f6a3b29 | ||
|
|
c0c722cd97 | ||
|
|
4770359384 | ||
|
|
6983189528 | ||
|
|
fc55345dcb | ||
|
|
9bc30967d2 | ||
|
|
61100b6463 | ||
|
|
d684bee4b0 | ||
|
|
2f9050dde8 | ||
|
|
1cfa21f23d | ||
|
|
e855d5779a | ||
|
|
d973b756a0 | ||
|
|
1116bf6400 | ||
|
|
7a211e5a07 | ||
|
|
12d880ad47 | ||
|
|
f95dce8e34 | ||
|
|
027884aad2 | ||
|
|
21f175b1ac | ||
|
|
506dad946b | ||
|
|
444681af9d | ||
|
|
2932d530c1 | ||
|
|
200e22ceea | ||
|
|
fa892b2456 | ||
|
|
3b7b7adffc | ||
|
|
75be0d3e14 | ||
|
|
69f0adf83b | ||
|
|
4231883480 | ||
|
|
e4b702ef4f | ||
|
|
5db73977d8 | ||
|
|
04ab1c9c87 | ||
|
|
4bd97633a1 | ||
|
|
5184c91e9c | ||
|
|
d201a11a67 | ||
|
|
2fe398f4bf | ||
|
|
64806a0d14 | ||
|
|
16029281a8 | ||
|
|
c6ff5558de | ||
|
|
0d77f9af6c | ||
|
|
fc55a4b8ce | ||
|
|
72f8871e61 | ||
|
|
f1c4a4d515 | ||
|
|
2d20edb39f | ||
|
|
8b43b94b22 | ||
|
|
63b92ea1e8 | ||
|
|
9af8080f2b | ||
|
|
dd0b55250b | ||
|
|
753487ff7f | ||
|
|
c8ff4f55e7 | ||
|
|
6a13b51bed | ||
|
|
477bb1a6ff | ||
|
|
53ecdfc0b5 | ||
|
|
b7b5952c3a | ||
|
|
7d4445c03d | ||
|
|
3a21617c62 | ||
|
|
14a0433470 | ||
|
|
7d364f1111 | ||
|
|
3d1383bed3 | ||
|
|
a9c8da5cfb | ||
|
|
2902ee133b | ||
|
|
84adade86c | ||
|
|
ff5d0ce327 | ||
|
|
8876751ed1 | ||
|
|
7b0c2c5e5d | ||
|
|
833ab1aab3 | ||
|
|
b953cd9aa0 | ||
|
|
d75f58d659 | ||
|
|
fc86347578 | ||
|
|
6ca79ff727 | ||
|
|
889b979a0e | ||
|
|
ec6fde611c | ||
|
|
7189ba715d | ||
|
|
b280527e3e | ||
|
|
e7cc57ceae | ||
|
|
b5b79e3a36 | ||
|
|
db3ac2335c | ||
|
|
7f802b07ef | ||
|
|
c00a5d0723 | ||
|
|
d4bcfbe996 | ||
|
|
9cebc13150 | ||
|
|
a7776a15e5 | ||
|
|
b71695e8bb | ||
|
|
766005a356 | ||
|
|
19a35fb839 | ||
|
|
9914b7216b | ||
|
|
7a69ff4182 | ||
|
|
e431676457 | ||
|
|
46a364be8e | ||
|
|
ad6fa1eb45 | ||
|
|
d87774c3c6 | ||
|
|
79f315f480 | ||
|
|
8201d1422b | ||
|
|
b1ea8273f0 | ||
|
|
4e44e8663d | ||
|
|
9b583d2331 | ||
|
|
734a248284 | ||
|
|
e95edd3d36 | ||
|
|
ccc9e0749c | ||
|
|
d89a45d1e1 | ||
|
|
80f21f48c5 | ||
|
|
abe7a01bf5 | ||
|
|
e99b5046eb | ||
|
|
ff50993f36 | ||
|
|
d84529cc0e | ||
|
|
4d009e19fc | ||
|
|
233c14a476 | ||
|
|
06d33f61c1 | ||
|
|
52774b6b20 | ||
|
|
84b0207956 | ||
|
|
6f0c2956ac | ||
|
|
8ac054733b | ||
|
|
cfe009a31c | ||
|
|
64c8d18814 | ||
|
|
d033ce6c23 | ||
|
|
dfb6d32189 | ||
|
|
cbcbd5fa07 | ||
|
|
c32c43f9f2 | ||
|
|
34c063701e | ||
|
|
39a50f30a3 | ||
|
|
5f5cdd3be1 | ||
|
|
70b270925d | ||
|
|
4aaccef8f2 | ||
|
|
75da272afe | ||
|
|
d9cdb924ad | ||
|
|
941559c2b7 | ||
|
|
2e66809c65 | ||
|
|
740da89578 | ||
|
|
0fbfce4c99 | ||
|
|
dd096ccd22 | ||
|
|
445a066cbe | ||
|
|
2a90e8fa1e | ||
|
|
be1182c3db | ||
|
|
4fe2122890 | ||
|
|
658e5f1553 | ||
|
|
04d805b0eb | ||
|
|
8ca34be36a | ||
|
|
6f9310173d | ||
|
|
c809bb9ece | ||
|
|
d96e718f80 | ||
|
|
0e0c57734a | ||
|
|
4b6e41e3de | ||
|
|
a1babfff1e | ||
|
|
5203954068 | ||
|
|
6e0756e819 | ||
|
|
a695ba447c | ||
|
|
d8b7b5ee27 | ||
|
|
c053513cbd | ||
|
|
fd723aed27 | ||
|
|
7cc6a89e21 | ||
|
|
150e1b0491 | ||
|
|
0f3c638193 | ||
|
|
7b46067029 | ||
|
|
d9afcae346 | ||
|
|
062f7b7ba2 | ||
|
|
90d556d650 | ||
|
|
d1904bd509 | ||
|
|
aad363ddd1 | ||
|
|
1a6cc6e5dc | ||
|
|
c93b4b3158 | ||
|
|
21cd836e82 | ||
|
|
8af3d73b9b | ||
|
|
a83f5d7260 | ||
|
|
f37242566b | ||
|
|
711c0548f0 | ||
|
|
a1d4e151ee | ||
|
|
ba0f382eee | ||
|
|
4ccac696ca | ||
|
|
a238f35d7d | ||
|
|
a77ebed550 | ||
|
|
84e95d6c68 | ||
|
|
01db6c365c | ||
|
|
510e79a053 | ||
|
|
2c8ebe6206 | ||
|
|
80308880d2 | ||
|
|
edcef18274 | ||
|
|
99fd6cf711 | ||
|
|
605e6c9bda | ||
|
|
4fc7b434d7 | ||
|
|
8fc2320b5c | ||
|
|
8175161059 | ||
|
|
6cc761f6b2 | ||
|
|
723980fe77 | ||
|
|
e7601870cc | ||
|
|
8dae5d9f81 | ||
|
|
1bd4dbf302 | ||
|
|
a269db3828 | ||
|
|
055f5e68a3 | ||
|
|
584c2cf804 | ||
|
|
6320776b25 | ||
|
|
d8bd6e2281 | ||
|
|
201c158377 | ||
|
|
226d66ca92 | ||
|
|
cee3098e87 | ||
|
|
00323b71d7 | ||
|
|
5151190dbc | ||
|
|
52ebdd85da | ||
|
|
0c10453546 | ||
|
|
a4dcd5eb91 | ||
|
|
334498d9b9 | ||
|
|
d2055b83d8 | ||
|
|
1db2ab678d | ||
|
|
9d197eb110 | ||
|
|
e430e95d30 | ||
|
|
e18ab07c62 | ||
|
|
963cfb58be | ||
|
|
3cd288a9f2 | ||
|
|
2193d06af6 | ||
|
|
eed157d36e | ||
|
|
8a87fc6ae7 | ||
|
|
2c8a91c2f9 | ||
|
|
60e53d36b7 | ||
|
|
c7f1d2d889 | ||
|
|
c9bae13502 | ||
|
|
22ab255231 | ||
|
|
03a37d1ff6 | ||
|
|
33a2613a49 | ||
|
|
551e476a17 | ||
|
|
4f78b37c61 | ||
|
|
a601fd6d3c | ||
|
|
557a309f9d | ||
|
|
20aa782ce5 | ||
|
|
e7b45298c1 | ||
|
|
c25eb2c4c8 | ||
|
|
b130a8b459 | ||
|
|
94e92b197a | ||
|
|
5cb93eb7e1 | ||
|
|
af0bd5b0b4 | ||
|
|
9d9eee8402 | ||
|
|
65e7be5190 | ||
|
|
e9e2871f18 | ||
|
|
4e5c23d969 | ||
|
|
d8dcee4c71 | ||
|
|
fa0623a9b5 | ||
|
|
f66a519dff | ||
|
|
1ec02f7229 | ||
|
|
8dc35cfce3 | ||
|
|
2ace7f0c58 | ||
|
|
51593d47ac | ||
|
|
2902e4ab5f | ||
|
|
e4eb76a5f3 | ||
|
|
40ed82f522 | ||
|
|
ce87858c78 | ||
|
|
042ba77c63 | ||
|
|
c228e0ac16 | ||
|
|
2889be5e90 | ||
|
|
7459b1dceb | ||
|
|
bcdc13514a | ||
|
|
311f163aed | ||
|
|
a96a7a6a20 | ||
|
|
cfddbcb5be | ||
|
|
c0118410a2 | ||
|
|
cca5cfc88f | ||
|
|
ce7fd591c6 | ||
|
|
1d9108fdbc | ||
|
|
e8aab3f3f4 | ||
|
|
c262e1f892 | ||
|
|
1a81965748 | ||
|
|
bdd245ff7d | ||
|
|
7fa2b19389 | ||
|
|
5f7d73ae88 | ||
|
|
f9b814c06a | ||
|
|
1cf77d4255 | ||
|
|
3cf6c3f7ca | ||
|
|
d0ee8c1cbd | ||
|
|
4504dd3737 | ||
|
|
87474563ff | ||
|
|
2c03028fa3 | ||
|
|
68eab24db7 | ||
|
|
acfa55713c | ||
|
|
dafe849c5b | ||
|
|
20dbd6339e | ||
|
|
e4268663e6 | ||
|
|
59fe188954 | ||
|
|
28e6c86e61 | ||
|
|
67b4ab2c90 | ||
|
|
68044510e5 | ||
|
|
50bc604586 | ||
|
|
39c18add57 | ||
|
|
6ab0db6e25 | ||
|
|
10e5ab2c5f | ||
|
|
730aa097f8 | ||
|
|
171740222c | ||
|
|
93c92eeabb | ||
|
|
b8540e1e70 | ||
|
|
a29a61529c | ||
|
|
135fdd5839 | ||
|
|
cd6bb00f2c | ||
|
|
a1b2261b7b | ||
|
|
1e48e73222 | ||
|
|
779d65208e | ||
|
|
ee9fd34d1f | ||
|
|
a53c452f25 | ||
|
|
fc2d2459af | ||
|
|
114d650d32 | ||
|
|
0c51af0fb4 | ||
|
|
e756724f86 | ||
|
|
f4eaf6c0ff | ||
|
|
e67d4c99d6 | ||
|
|
26f057d668 | ||
|
|
868ce6372d | ||
|
|
90040b24ce | ||
|
|
4207b58700 | ||
|
|
d4dcdba07e | ||
|
|
75a2a05c7c | ||
|
|
c5897dc058 | ||
|
|
05041f9cff | ||
|
|
f5f83bc025 | ||
|
|
93189d3083 | ||
|
|
1c3f0293fd | ||
|
|
614ed2717b | ||
|
|
8f1cb41725 | ||
|
|
81de07e208 | ||
|
|
b42a21d419 | ||
|
|
e13dfc743d | ||
|
|
d5544a0f13 | ||
|
|
d68c1e29b6 | ||
|
|
6e54225bd7 | ||
|
|
ed5a9ed1b1 | ||
|
|
49622dd51a | ||
|
|
e856908696 | ||
|
|
065506d1a8 | ||
|
|
b63032b4dd | ||
|
|
85c4e58831 | ||
|
|
5b61afd38c | ||
|
|
8fbb03de5e | ||
|
|
1cb1e90f53 | ||
|
|
c50f9dd412 | ||
|
|
9efe85fb4c | ||
|
|
6476a11189 | ||
|
|
398e260145 | ||
|
|
e382b884d3 | ||
|
|
f03245c362 | ||
|
|
2d6e0d8eea | ||
|
|
6f4818ebcb | ||
|
|
57bbbfc0e6 | ||
|
|
348e246b66 | ||
|
|
f469049198 | ||
|
|
5aa8ae510e | ||
|
|
e24d7c64a8 | ||
|
|
6a51e9e037 | ||
|
|
58b7e732b8 | ||
|
|
de35486fb7 | ||
|
|
318d4e91cc | ||
|
|
f99dd8f6dc | ||
|
|
137d1d896a | ||
|
|
42ee37847f | ||
|
|
5aaa5e253d | ||
|
|
d2a843b422 | ||
|
|
6d7e0d68cf | ||
|
|
66836f591e | ||
|
|
ec0d6f196e | ||
|
|
e55b89096f | ||
|
|
57baa78dd1 | ||
|
|
9473b0b2c5 | ||
|
|
8f14388cb4 | ||
|
|
3753d01253 | ||
|
|
9556d59536 | ||
|
|
184f26355a | ||
|
|
6accd3d681 | ||
|
|
b4f055effc | ||
|
|
85fd23769f | ||
|
|
b770699319 | ||
|
|
fe5370a98a | ||
|
|
4b354d38c1 | ||
|
|
a9b7638f4b | ||
|
|
42fdfd8121 | ||
|
|
2106692a89 | ||
|
|
7b19ba3d57 | ||
|
|
4d3524f496 | ||
|
|
7da19e96ce | ||
|
|
583e8b71e4 | ||
|
|
465af58457 | ||
|
|
748b70ae8b | ||
|
|
6d1b4e050d | ||
|
|
00700bbe13 | ||
|
|
78e6060858 | ||
|
|
2665ae0414 | ||
|
|
77bdbc6e98 | ||
|
|
76772fe786 | ||
|
|
5714260953 | ||
|
|
25a88d6d54 | ||
|
|
808995e041 | ||
|
|
0f0bb21a89 | ||
|
|
00d622bed7 | ||
|
|
014833d0e6 | ||
|
|
6c14c7520b | ||
|
|
e5e72eb398 | ||
|
|
9e193be648 | ||
|
|
7dcfe531e4 | ||
|
|
e965775064 | ||
|
|
6e13c6f401 | ||
|
|
2916cfb3b0 | ||
|
|
da2bda6f4d | ||
|
|
adda4f6ace | ||
|
|
c316b1d7d5 | ||
|
|
af84a27dff | ||
|
|
aee3706f66 | ||
|
|
8e135d5f59 | ||
|
|
5d6358b66d | ||
|
|
4089147351 | ||
|
|
18ea62e369 | ||
|
|
d000523b00 | ||
|
|
0758d29324 | ||
|
|
af7abd4dfd | ||
|
|
7e061e4d5f | ||
|
|
ad180402ea | ||
|
|
812d8f71e8 | ||
|
|
58fdcf06e8 | ||
|
|
f7fe95ad7b | ||
|
|
5b117c851a | ||
|
|
e5d43a6f4e | ||
|
|
9f7a16c7ab | ||
|
|
f24d0e4054 | ||
|
|
9115eb88ed | ||
|
|
5980d9c389 | ||
|
|
4fc622031d | ||
|
|
dde8631600 | ||
|
|
8c88ab4747 | ||
|
|
a4a9fbdb8f | ||
|
|
1420d59949 | ||
|
|
27a5239ccf | ||
|
|
dc31cf3652 | ||
|
|
03db238a51 | ||
|
|
8d2ff8a6bf | ||
|
|
b912169f15 | ||
|
|
473783e432 | ||
|
|
59136055b9 | ||
|
|
70b2c24a4e | ||
|
|
11e80ce3ab | ||
|
|
12c51866d0 | ||
|
|
7495b25f94 | ||
|
|
810862dc65 | ||
|
|
a8264065f6 | ||
|
|
8dd683768b | ||
|
|
c9ac6a5eab | ||
|
|
a4244e79ca | ||
|
|
833021d84d | ||
|
|
2c459443da | ||
|
|
1646b26369 | ||
|
|
056176ec9a | ||
|
|
3102fa5775 | ||
|
|
b1d8b549e0 | ||
|
|
d69ba6f39f | ||
|
|
882741bf55 | ||
|
|
dd1b35412f | ||
|
|
5dc6798e75 | ||
|
|
8aa338ba2d | ||
|
|
4f5b934688 | ||
|
|
b9c9fc066f | ||
|
|
833c4b1300 | ||
|
|
c79de51da8 | ||
|
|
9c71e5733d | ||
|
|
a5f133ef2f | ||
|
|
1645ea8b8b | ||
|
|
de5c0d4228 | ||
|
|
e4e00db42e | ||
|
|
3609287344 | ||
|
|
fa49fc77e3 | ||
|
|
9dbb5662b7 | ||
|
|
ba49524708 | ||
|
|
36dd4a2124 | ||
|
|
20a2574da1 | ||
|
|
bf13191b87 | ||
|
|
93a609d6db | ||
|
|
5fcae2f0e0 | ||
|
|
0248872938 | ||
|
|
565b3ef8cb | ||
|
|
af252929e8 | ||
|
|
4326b10169 | ||
|
|
d82de651c6 | ||
|
|
61c2333174 | ||
|
|
88a706acf8 | ||
|
|
7da16febc4 | ||
|
|
079de39b46 | ||
|
|
1d9185229e | ||
|
|
ef120738c0 | ||
|
|
396d4223d9 | ||
|
|
9aa4b5a7a6 | ||
|
|
939cf38576 | ||
|
|
9df07b4036 | ||
|
|
1e4165d25b | ||
|
|
989922631a | ||
|
|
53e8f992d9 | ||
|
|
6c0a863584 | ||
|
|
f1407d8814 | ||
|
|
e13675d6cb | ||
|
|
a930b94658 | ||
|
|
13a7783d7b | ||
|
|
b7e8dc1182 | ||
|
|
bb81684206 | ||
|
|
82ac0071b7 | ||
|
|
b3bf416888 | ||
|
|
f6287fc718 | ||
|
|
c3712a288f | ||
|
|
1a69e4c9ee | ||
|
|
c0789a8785 | ||
|
|
c3fac2550f | ||
|
|
0feee99055 | ||
|
|
1d0fc2d179 | ||
|
|
41621fb1df | ||
|
|
6b3df091fe | ||
|
|
7e200ce90e | ||
|
|
cfce0a5e60 | ||
|
|
72bfa5a48c | ||
|
|
1464bedce2 | ||
|
|
68ff1730ac | ||
|
|
82a6a2f8cc | ||
|
|
0ae684830a | ||
|
|
ec9e4eb406 | ||
|
|
394f9403df | ||
|
|
36b5d74fc4 | ||
|
|
f6b4f2a149 | ||
|
|
cf5aa85f29 | ||
|
|
8f2f004778 | ||
|
|
522fcccea2 | ||
|
|
61456ff81d | ||
|
|
ff92edcd41 | ||
|
|
874c349b44 | ||
|
|
c3f6f0a332 | ||
|
|
4c64c4b78e | ||
|
|
016f742f16 | ||
|
|
1042134eec | ||
|
|
b33df3cc63 | ||
|
|
299086d447 | ||
|
|
86e1948afe | ||
|
|
8c47d16e29 | ||
|
|
c0f410f721 | ||
|
|
29fdcf0c71 | ||
|
|
e7d5a89ae2 | ||
|
|
24536473d8 | ||
|
|
14d7658897 | ||
|
|
e9772b609e | ||
|
|
05cb07093d | ||
|
|
569cccea24 | ||
|
|
814a886354 | ||
|
|
a21ac9838d | ||
|
|
3cc1f4a74e | ||
|
|
6fb602d57b | ||
|
|
9f2ac374f4 | ||
|
|
3e7758ee58 | ||
|
|
351e0e6986 | ||
|
|
efc79beb2d | ||
|
|
57ad169605 | ||
|
|
bb55cc1685 | ||
|
|
ade0ba63ff | ||
|
|
7bddf97450 | ||
|
|
ac362625c3 | ||
|
|
90a9de9d52 | ||
|
|
9285e10fef | ||
|
|
c6534ac6b3 | ||
|
|
b7e08045b1 | ||
|
|
e00ce7e02e | ||
|
|
bda4c4a375 | ||
|
|
57aefd102e | ||
|
|
b78373216d | ||
|
|
24131ca29e | ||
|
|
72c4c6b30c | ||
|
|
fd6456dd56 | ||
|
|
53d85f903c | ||
|
|
9877e52161 | ||
|
|
627285af23 | ||
|
|
16543731f5 | ||
|
|
344f12dd99 | ||
|
|
14913d75c0 | ||
|
|
e098285892 | ||
|
|
1e0c957dcd | ||
|
|
ea26e5038e | ||
|
|
2c4be0c201 | ||
|
|
9b3f3101e3 | ||
|
|
e149bc7046 | ||
|
|
a8db52120b | ||
|
|
92a525225b | ||
|
|
1e8d20de0d | ||
|
|
89d98564c3 | ||
|
|
c4e199ecca | ||
|
|
5ae1544583 | ||
|
|
05a5dc2d0d | ||
|
|
19473d95eb | ||
|
|
8686b0abbf | ||
|
|
d68ece28c4 | ||
|
|
453c84b237 | ||
|
|
20a3d3be5f | ||
|
|
d982dff464 | ||
|
|
2abaca7a49 | ||
|
|
ae4f6a259b | ||
|
|
da6ac0c4ff | ||
|
|
1d45b4a1e0 | ||
|
|
40787a06d8 | ||
|
|
90b42b56b6 | ||
|
|
13a76ba0a6 | ||
|
|
f1d5d5d682 | ||
|
|
0a499ec2ee | ||
|
|
41d3e2027c | ||
|
|
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 | ||
|
|
bbb737ca5a | ||
|
|
ebad5416d7 | ||
|
|
8802509a61 | ||
|
|
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 | ||
|
|
5eabc429bc | ||
|
|
9b310f4084 | ||
|
|
d104d3be22 | ||
|
|
7dfbcdf276 | ||
|
|
941b324187 | ||
|
|
21472c2393 | ||
|
|
488e4c66cd | ||
|
|
e8b8d42f8b | ||
|
|
e6a179e27a | ||
|
|
f79811435b | ||
|
|
f177dc974c | ||
|
|
8eeb910e3d | ||
|
|
1762437121 | ||
|
|
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 | ||
|
|
f3dfb4d537 | ||
|
|
9843b836ee | ||
|
|
4ac33aa104 | ||
|
|
2b5cd8e9b4 | ||
|
|
e45e9f1ce0 | ||
|
|
05b9f4fd28 | ||
|
|
1089fd6dc1 | ||
|
|
366296ec14 | ||
|
|
7f9aa6734a | ||
|
|
9902a5f81d | ||
|
|
cd0a2b1af1 | ||
|
|
bc39217070 | ||
|
|
ccb576f95e | ||
|
|
a374dfb669 | ||
|
|
79fa94834e | ||
|
|
e35d5f5a2d | ||
|
|
334e2b1e35 | ||
|
|
06847ff3be | ||
|
|
80c2c69fa7 | ||
|
|
8b752e359e | ||
|
|
d3b3d64ef3 | ||
|
|
c602ba7319 | ||
|
|
bdb6c153e4 | ||
|
|
d8a8730cac | ||
|
|
a16111d471 | ||
|
|
0532cdd357 | ||
|
|
e84b913585 | ||
|
|
a5027f5f56 | ||
|
|
06a58ca248 | ||
|
|
4700d79024 | ||
|
|
9d9884c442 | ||
|
|
c1c75929fa | ||
|
|
8cb3656b3e | ||
|
|
a90f173875 | ||
|
|
b266db3920 | ||
|
|
fd415d8833 | ||
|
|
b5a52f8c86 | ||
|
|
67271242bf | ||
|
|
965f16cc89 | ||
|
|
4cbf4f4996 | ||
|
|
008813f0a2 | ||
|
|
88fce791df | ||
|
|
7180284d82 | ||
|
|
401fc15443 | ||
|
|
4eb7771f97 | ||
|
|
abbb5c0f6d | ||
|
|
0987a82877 | ||
|
|
fa506e3cda | ||
|
|
df0c844eed | ||
|
|
199e6c586b | ||
|
|
1c5d081853 | ||
|
|
21f740d313 | ||
|
|
e860d39f54 | ||
|
|
fe0b1da859 | ||
|
|
27811ffaa9 | ||
|
|
7d5ab2f4de | ||
|
|
5f5c00203e | ||
|
|
b4b0065554 | ||
|
|
c94e13220b | ||
|
|
9ce7045413 | ||
|
|
a8d6147ae4 | ||
|
|
368386c011 | ||
|
|
d5ebc63add | ||
|
|
d323e1bda8 | ||
|
|
36819adcc2 | ||
|
|
da46ea24d5 | ||
|
|
395d83cfc8 | ||
|
|
1aa1facabc | ||
|
|
78b2f1cc20 | ||
|
|
164f302011 | ||
|
|
cc39725cf3 | ||
|
|
63b2628a18 | ||
|
|
0f3eac4a0e | ||
|
|
72738471f1 | ||
|
|
c1e75c0369 | ||
|
|
b16c872a60 | ||
|
|
364441e0f5 | ||
|
|
ed95b07764 | ||
|
|
bf2307ca97 | ||
|
|
1ec96d8f07 | ||
|
|
3499d3c647 | ||
|
|
ee06aaaad9 | ||
|
|
af6c5dea43 | ||
|
|
b57771d42b | ||
|
|
6067ce6d2b | ||
|
|
081fd4fdae | ||
|
|
3021e320dd | ||
|
|
a77c35ef50 | ||
|
|
bc83e0b016 | ||
|
|
09a0e6ee30 | ||
|
|
268580f348 | ||
|
|
a4f4d7b6ba | ||
|
|
e2a2dcdfd5 | ||
|
|
14b11384a4 | ||
|
|
a03f0a388e | ||
|
|
0b77c9d676 | ||
|
|
1c3ba0cef7 | ||
|
|
19c2ece763 | ||
|
|
b0b69321f9 | ||
|
|
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 | ||
|
|
a7f68865e4 | ||
|
|
8dac8c00ce | ||
|
|
83bf2fd253 | ||
|
|
2a78803049 | ||
|
|
46acf0f99d | ||
|
|
ba67920f9a | ||
|
|
186c9e8e82 | ||
|
|
edf1ad369a | ||
|
|
52ea271a65 | ||
|
|
ae54e9013b | ||
|
|
8a3ae4d08a | ||
|
|
1cc54b080a | ||
|
|
63171a2522 | ||
|
|
2e023a5699 | ||
|
|
1c1fc36d76 | ||
|
|
42d7db578a | ||
|
|
d4a6380562 | ||
|
|
8133251662 | ||
|
|
5a8d314ce3 | ||
|
|
99f36a4e1e | ||
|
|
61a28c2ee5 | ||
|
|
2552a81b40 | ||
|
|
ab6f1d0fc7 | ||
|
|
c8a56bfa8f | ||
|
|
d1150541bb | ||
|
|
ead84a5a64 | ||
|
|
c6369e9ffa | ||
|
|
74f11b852c | ||
|
|
474afc9016 | ||
|
|
edcf2ddd12 | ||
|
|
bd3c02bd59 | ||
|
|
32b1d900ff | ||
|
|
4eac399dfd | ||
|
|
c26fc84945 | ||
|
|
2b47ca080e | ||
|
|
c66e47c372 | ||
|
|
9274d2630e | ||
|
|
348cbab016 | ||
|
|
b43b8d47f8 | ||
|
|
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 | ||
|
|
25c8497ba6 | ||
|
|
5577e55400 | ||
|
|
27472f1270 | ||
|
|
30a14c2716 | ||
|
|
d4a69e4d2a | ||
|
|
000e75581b | ||
|
|
2e5e31e8ac | ||
|
|
ae2653fcc5 | ||
|
|
f7118f29b9 | ||
|
|
57a5e75840 | ||
|
|
8d14e7c0a4 | ||
|
|
e0745813f4 | ||
|
|
0171d06aa2 | ||
|
|
4daf8f5bdb | ||
|
|
8893735a2d | ||
|
|
00ba747be7 | ||
|
|
504ef71975 | ||
|
|
9926fcac4b | ||
|
|
01d8dc2240 | ||
|
|
4fe427ded2 | ||
|
|
b0ca964984 | ||
|
|
e8c4f20f66 | ||
|
|
b0daf867c2 | ||
|
|
8385c462ed | ||
|
|
afd4063f20 | ||
|
|
ed24498f2e | ||
|
|
f2b12c0761 | ||
|
|
df85836b15 | ||
|
|
3f2b6828e5 | ||
|
|
1958d9fbd5 | ||
|
|
0c04b5eaf5 | ||
|
|
8e5a32f4dc | ||
|
|
efe5c8e6be | ||
|
|
1e61604aab | ||
|
|
488eaf09ce | ||
|
|
8b1012613e | ||
|
|
256ab3d935 | ||
|
|
a07337fd6d | ||
|
|
be79ffa371 | ||
|
|
c580e0e33c | ||
|
|
d2f7999b4e | ||
|
|
611e37aa2d | ||
|
|
3f2d186694 | ||
|
|
73f01304f0 | ||
|
|
77bd7d228b | ||
|
|
b97b04a9db | ||
|
|
6e4583a528 | ||
|
|
586b811b87 | ||
|
|
070019c9be | ||
|
|
ce04bcb463 | ||
|
|
cf1bfbba5d | ||
|
|
a4fd088875 | ||
|
|
27023b3f21 | ||
|
|
b2a7933045 | ||
|
|
749d1b9ebc | ||
|
|
87bdb489f9 | ||
|
|
37e9f5591a | ||
|
|
d546e7766d | ||
|
|
62f69f9b40 | ||
|
|
168bc963d3 | ||
|
|
1f148e632f | ||
|
|
c887ae1022 | ||
|
|
375d3e7520 | ||
|
|
3b171545b6 | ||
|
|
aa5efa172d | ||
|
|
a2961e50fb | ||
|
|
adc498d29d | ||
|
|
1ff3e51ee1 | ||
|
|
f9c0f359a7 | ||
|
|
cc538f4f9f | ||
|
|
900cd200a2 | ||
|
|
45e73bcc8e | ||
|
|
26eaf2d1ee | ||
|
|
2f32ef7646 | ||
|
|
b7abbd1d72 | ||
|
|
f364edafd3 | ||
|
|
e3f08cb2a2 | ||
|
|
a92b00ef3c | ||
|
|
3dbdde7fed | ||
|
|
6da37e5ecd | ||
|
|
007123ee2c | ||
|
|
10c085f81d | ||
|
|
1d315e11cf | ||
|
|
c91b657a40 | ||
|
|
60f59271d6 | ||
|
|
40abe08ac8 | ||
|
|
ae1790b8e8 | ||
|
|
aa5fb8b10b | ||
|
|
6de329359c | ||
|
|
2e34a8f643 | ||
|
|
bded93f69b | ||
|
|
38e77d50f2 | ||
|
|
f8e585f308 | ||
|
|
5bda4f9822 | ||
|
|
d2d7b987fa | ||
|
|
7579216922 | ||
|
|
330c6e1cb0 | ||
|
|
41e5a66b73 | ||
|
|
cc5ab744c5 | ||
|
|
0ae750e552 | ||
|
|
cabc120f22 | ||
|
|
c96c2d8a45 | ||
|
|
8aa53f027d | ||
|
|
4bf9d12419 | ||
|
|
f93746b1af | ||
|
|
23dc22b78d | ||
|
|
5e3c30beac | ||
|
|
86f16bef93 | ||
|
|
f2e90b0872 | ||
|
|
1249e0db3f | ||
|
|
15c4dd79f4 | ||
|
|
e324a7819a | ||
|
|
81e9f82a8d | ||
|
|
5d298ed474 | ||
|
|
82e1e3959f | ||
|
|
7181c0fa6a | ||
|
|
49f27c06af | ||
|
|
7247718e12 | ||
|
|
61acc76244 | ||
|
|
2faa4f9ee2 | ||
|
|
2beae211ee | ||
|
|
d3ff7a9333 | ||
|
|
23df700f15 | ||
|
|
755233c720 | ||
|
|
bca54a8b25 | ||
|
|
b5aab36d41 | ||
|
|
d7cfe91cb3 | ||
|
|
a31d45b13e | ||
|
|
23f475bccc | ||
|
|
025fdd0049 | ||
|
|
5bb6dbe21c | ||
|
|
c225ced1a9 | ||
|
|
3a58ad15e8 | ||
|
|
5106ad7a2c | ||
|
|
8c044a616b | ||
|
|
9ccf611954 | ||
|
|
5dfcf122d1 | ||
|
|
7b092127cb | ||
|
|
b26257248d | ||
|
|
3c7d270958 | ||
|
|
c15eae814f | ||
|
|
0e72e06886 | ||
|
|
abff4d1237 | ||
|
|
386f23334b | ||
|
|
a523683d4c | ||
|
|
b25332e1f4 | ||
|
|
a6ec2c6fc7 | ||
|
|
9cb404ba5f | ||
|
|
12251022ec | ||
|
|
00a0cabf7f | ||
|
|
d6ed0e868f | ||
|
|
700ad78f10 | ||
|
|
d65accbb23 | ||
|
|
78767f2014 | ||
|
|
21af42a281 | ||
|
|
0b0ece9db0 | ||
|
|
23edc18cac | ||
|
|
7153c94bd7 | ||
|
|
4df697b4b7 | ||
|
|
7fd32916e8 | ||
|
|
3f837bc440 | ||
|
|
f0769bed93 | ||
|
|
a1bfc07105 | ||
|
|
beba72d6db | ||
|
|
a4a5bfaa2f | ||
|
|
62ea384d19 | ||
|
|
53b1e11eba | ||
|
|
7fae96eb1e | ||
|
|
d386641820 |
@@ -0,0 +1,2 @@
|
||||
github: [NLnetLabs]
|
||||
custom: ['https://nlnetlabs.nl/funding/']
|
||||
+20
-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
|
||||
@@ -28,12 +31,28 @@
|
||||
/unbound.h
|
||||
/asynclook
|
||||
/delayer
|
||||
/dohclient
|
||||
/lock-verify
|
||||
/memstats
|
||||
/perf
|
||||
/petal
|
||||
/pktview
|
||||
/streamtcp
|
||||
/unbound-dnstap-socket
|
||||
/testbound
|
||||
/unittest
|
||||
|
||||
/contrib/libunbound.pc
|
||||
/contrib/unbound.service
|
||||
/contrib/unbound.socket
|
||||
/contrib/unbound_portable.service
|
||||
/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
|
||||
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
language: c
|
||||
|
||||
git:
|
||||
depth: 5
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libssl-dev
|
||||
- libevent-dev
|
||||
- libexpat-dev
|
||||
- clang
|
||||
homebrew:
|
||||
packages:
|
||||
- openssl
|
||||
- libevent
|
||||
- expat
|
||||
update: true
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- os: linux
|
||||
name: GCC on Linux, Amd64
|
||||
compiler: gcc
|
||||
arch: amd64
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: Clang on Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: osx
|
||||
name: Clang on OS X, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
env:
|
||||
- TEST_OSX=yes
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/"
|
||||
- os: linux
|
||||
name: Libevent, GCC on Linux, Amd64
|
||||
compiler: gcc
|
||||
arch: amd64
|
||||
env:
|
||||
- TEST_LIBEVENT=yes
|
||||
- CONFIG_OPTS="--with-libevent"
|
||||
- os: linux
|
||||
name: Libevent, Clang on Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
env:
|
||||
- TEST_LIBEVENT=yes
|
||||
- CONFIG_OPTS="--with-libevent"
|
||||
- os: osx
|
||||
name: Libevent, Clang on OS X, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
env:
|
||||
- TEST_OSX=yes
|
||||
- TEST_LIBEVENT=yes
|
||||
- CONFIG_OPTS="--with-ssl=/usr/local/opt/openssl/ --with-libevent=/usr/local/opt/libevent/"
|
||||
- os: linux
|
||||
name: UBsan, GCC on Linux, Amd64
|
||||
compiler: gcc
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_UBSAN=yes
|
||||
- os: linux
|
||||
name: UBsan, Clang on Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_UBSAN=yes
|
||||
- os: linux
|
||||
name: Asan, GCC on Linux, Amd64
|
||||
compiler: gcc
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ASAN=yes
|
||||
- os: linux
|
||||
name: Asan, Clang on Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ASAN=yes
|
||||
- os: linux
|
||||
name: GCC on Linux, Aarch64
|
||||
compiler: gcc
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: Clang on Linux, Aarch64
|
||||
compiler: clang
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: GCC on Linux, PowerPC64
|
||||
compiler: gcc
|
||||
arch: ppc64le
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: Clang on Linux, PowerPC64
|
||||
compiler: clang
|
||||
arch: ppc64le
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: GCC on Linux, s390x
|
||||
compiler: gcc
|
||||
arch: s390x
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: linux
|
||||
name: Clang on Linux, s390x
|
||||
compiler: clang
|
||||
arch: s390x
|
||||
dist: bionic
|
||||
env:
|
||||
- CONFIG_OPTS="--enable-debug --disable-flto"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: Apple iPhone on iOS, armv7
|
||||
compiler: clang
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=armv7-apple-ios
|
||||
- OPENSSL_HOST=ios-cross
|
||||
- IOS_SDK=iPhoneOS
|
||||
- IOS_CPU=armv7s
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: Apple iPhone on iOS, arm64
|
||||
compiler: clang
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=aarch64-apple-ios
|
||||
- OPENSSL_HOST=ios64-cross
|
||||
- IOS_SDK=iPhoneOS
|
||||
- IOS_CPU=arm64
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: Apple TV on iOS, arm64
|
||||
compiler: clang
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=aarch64-apple-ios
|
||||
- OPENSSL_HOST=ios64-cross
|
||||
- IOS_SDK=AppleTVOS
|
||||
- IOS_CPU=arm64
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: Apple Watch on iOS, armv7
|
||||
compiler: clang
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=armv7-apple-ios
|
||||
- OPENSSL_HOST=ios-cross
|
||||
- IOS_SDK=WatchOS
|
||||
- IOS_CPU=armv7k
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: iPhoneSimulator on OS X, i386
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=i386-apple-ios
|
||||
- OPENSSL_HOST=iphoneos-cross
|
||||
- IOS_CPU=i386
|
||||
- IOS_SDK=iPhoneSimulator
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: iPhoneSimulator on OS X, x86_64
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=x86_64-apple-ios
|
||||
- OPENSSL_HOST=iphoneos-cross
|
||||
- IOS_CPU=x86_64
|
||||
- IOS_SDK=iPhoneSimulator
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: AppleTVSimulator on OS X, x86_64
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=x86_64-apple-ios
|
||||
- OPENSSL_HOST=iphoneos-cross
|
||||
- IOS_CPU=x86_64
|
||||
- IOS_SDK=AppleTVSimulator
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: WatchSimulator on OS X, i386
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=i386-apple-ios
|
||||
- OPENSSL_HOST=iphoneos-cross
|
||||
- IOS_CPU=i386
|
||||
- IOS_SDK=WatchSimulator
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
- os: linux
|
||||
name: Android armv7a, Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ANDROID=yes
|
||||
- AUTOTOOLS_HOST=armv7a-linux-androideabi
|
||||
- OPENSSL_HOST=android-arm
|
||||
- ANDROID_CPU=armv7a
|
||||
- ANDROID_API=23
|
||||
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
|
||||
- ANDROID_SDK_ROOT="$HOME/android-sdk"
|
||||
- ANDROID_NDK_ROOT="$HOME/android-ndk"
|
||||
- os: linux
|
||||
name: Android aarch64, Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ANDROID=yes
|
||||
- AUTOTOOLS_HOST=aarch64-linux-android
|
||||
- OPENSSL_HOST=android-arm64
|
||||
- ANDROID_CPU=aarch64
|
||||
- ANDROID_API=23
|
||||
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
|
||||
- ANDROID_SDK_ROOT="$HOME/android-sdk"
|
||||
- ANDROID_NDK_ROOT="$HOME/android-ndk"
|
||||
- os: linux
|
||||
name: Android x86, Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ANDROID=yes
|
||||
- AUTOTOOLS_HOST=i686-linux-android
|
||||
- OPENSSL_HOST=android-x86
|
||||
- ANDROID_CPU=x86
|
||||
- ANDROID_API=23
|
||||
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
|
||||
- ANDROID_SDK_ROOT="$HOME/android-sdk"
|
||||
- ANDROID_NDK_ROOT="$HOME/android-ndk"
|
||||
- os: linux
|
||||
name: Android x86_64, Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ANDROID=yes
|
||||
- AUTOTOOLS_HOST=x86_64-linux-android
|
||||
- OPENSSL_HOST=android-x86_64
|
||||
- ANDROID_CPU=x86_64
|
||||
- ANDROID_API=23
|
||||
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
|
||||
- ANDROID_SDK_ROOT="$HOME/android-sdk"
|
||||
- ANDROID_NDK_ROOT="$HOME/android-ndk"
|
||||
|
||||
allow_failures:
|
||||
- os: linux
|
||||
name: Android armv7a, Linux, Amd64
|
||||
- os: linux
|
||||
name: Android aarch64, Linux, Amd64
|
||||
- os: linux
|
||||
name: Android x86, Linux, Amd64
|
||||
- os: linux
|
||||
name: Android x86_64, Linux, Amd64
|
||||
|
||||
before_script:
|
||||
- |
|
||||
if [ "$TEST_ANDROID" = "yes" ]; then
|
||||
./contrib/android/install_tools.sh
|
||||
elif [ "$TEST_IOS" = "yes" ]; then
|
||||
./contrib/ios/install_tools.sh
|
||||
fi
|
||||
|
||||
# The Travis docs say to avoid calling exit in the script. It leads to
|
||||
# some code duplication to avoid failures in cross-compiles. Also see
|
||||
# https://docs.travis-ci.com/user/job-lifecycle/ in the Travis docs.
|
||||
script:
|
||||
- |
|
||||
if [ "$TEST_UBSAN" = "yes" ]; then
|
||||
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover"
|
||||
./configure
|
||||
make -j 2
|
||||
make test
|
||||
elif [ "$TEST_ASAN" = "yes" ]; then
|
||||
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
|
||||
./configure
|
||||
make -j 2
|
||||
make test
|
||||
elif [ "$TEST_IOS" = "yes" ]; then
|
||||
export AUTOTOOLS_BUILD="$(./config.guess)"
|
||||
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
|
||||
source ./contrib/ios/setenv_ios.sh
|
||||
./contrib/ios/install_openssl.sh
|
||||
./contrib/ios/install_expat.sh
|
||||
./configure \
|
||||
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$IOS_PREFIX" \
|
||||
--with-ssl="$IOS_PREFIX" --disable-gost \
|
||||
--with-libexpat="$IOS_PREFIX";
|
||||
make -j 2
|
||||
make install
|
||||
elif [ "$TEST_ANDROID" = "yes" ]; then
|
||||
export AUTOTOOLS_BUILD="$(./config.guess)"
|
||||
export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
|
||||
./contrib/android/install_ndk.sh
|
||||
source ./contrib/android/setenv_android.sh
|
||||
./contrib/android/install_openssl.sh
|
||||
./contrib/android/install_expat.sh
|
||||
./configure \
|
||||
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$ANDROID_PREFIX" \
|
||||
--with-ssl="$ANDROID_PREFIX" --disable-gost \
|
||||
--with-libexpat="$ANDROID_PREFIX";
|
||||
make -j 2
|
||||
make install
|
||||
elif [ "$TEST_OSX" = "yes" ]; then
|
||||
./configure --enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/
|
||||
make -j 2
|
||||
make test
|
||||
(cd testdata/clang-analysis.tdir; bash clang-analysis.test)
|
||||
else
|
||||
./configure ${CONFIG_OPTS}
|
||||
make -j 2
|
||||
make test
|
||||
(cd testdata/clang-analysis.tdir; bash clang-analysis.test)
|
||||
fi
|
||||
+745
-587
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,278 @@
|
||||
# Travis Testing
|
||||
|
||||
Unbound 1.10 and above leverage Travis CI to increase coverage of compilers and platforms. Compilers include Clang and GCC; while platforms include Android, iOS, Linux, and OS X on AMD64, Aarch64, PowerPC and s390x hardware.
|
||||
|
||||
Android is tested on armv7a, aarch64, x86 and x86_64. The Android recipes build and install OpenSSL and Expat, and then builds Unbound. The testing is tailored for Android NDK-r19 and above, and includes NDK-r20 and NDK-r21. Mips and Mips64 are not tested because they are no longer supported under current NDKs.
|
||||
|
||||
iOS is tested for iPhoneOS, WatchOS, AppleTVOS, iPhoneSimulator, AppleTVSimulator and WatchSimulator. The testing uses Xcode 10 on OS X 10.13.
|
||||
|
||||
The Unbound Travis configuration file `.travis.yml` does not use top-level keys like `os:` and `compiler:` so there is no matrix expansion. Instead Unbound specifies the exact job to run under the `jobs:` and `include:` keys.
|
||||
|
||||
## Typical recipe
|
||||
|
||||
A typical recipe tests Clang and GCC on various hardware. The hardware includes AMD64, Aarch64, PowerPC and s390x. PowerPC is a little-endian platform, and s390x is a big-endian platform. There are pairs of recipes that are similar to the following.
|
||||
|
||||
```
|
||||
- os: linux
|
||||
name: GCC on Linux, Aarch64
|
||||
compiler: gcc
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
- os: linux
|
||||
name: Clang on Linux, Aarch64
|
||||
compiler: clang
|
||||
arch: arm64
|
||||
dist: bionic
|
||||
```
|
||||
|
||||
OS X provides a single recipe to test Clang. GCC is not tested because GCC is an alias for Clang.
|
||||
|
||||
## Sanitizer builds
|
||||
|
||||
Two sanitizer builds are tested using Clang and GCC, for a total of four builds. The first sanitizer is Undefined Behavior sanitizer (UBsan), and the second is Address sanitizer (Asan). The sanitizers are only run on AMD64 hardware. Note the environment includes `TEST_UBSAN=yes` or `TEST_ASAN=yes` for the sanitizer builds.
|
||||
|
||||
The recipes are similar to the following.
|
||||
|
||||
```
|
||||
- os: linux
|
||||
name: UBsan, GCC on Linux, Amd64
|
||||
compiler: gcc
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env: TEST_UBSAN=yes
|
||||
- os: linux
|
||||
name: UBsan, Clang on Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env: TEST_UBSAN=yes
|
||||
```
|
||||
|
||||
When the Travis script encounters a sanitizer it uses different `CFLAGS` and configuration string.
|
||||
|
||||
```
|
||||
if [ "$TEST_UBSAN" = "yes" ]; then
|
||||
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover"
|
||||
./configure
|
||||
make -j 2
|
||||
make test
|
||||
elif [ "$TEST_ASAN" = "yes" ]; then
|
||||
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
|
||||
./configure
|
||||
make -j 2
|
||||
make test
|
||||
...
|
||||
```
|
||||
|
||||
## Android builds
|
||||
|
||||
Travis tests Android builds for the armv7a, aarch64, x86 and x86_64 architectures. The builds are trickier than other builds for several reasons. The testing requires installation of the Android NDK and SDK, it requires a cross-compile, and requires OpenSSL and Expat prerequisites. The Android cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the Android recipes.
|
||||
|
||||
### Android job
|
||||
|
||||
The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
|
||||
|
||||
```
|
||||
- os: linux
|
||||
name: Android armv7a, Linux, Amd64
|
||||
compiler: clang
|
||||
arch: amd64
|
||||
dist: bionic
|
||||
env:
|
||||
- TEST_ANDROID=yes
|
||||
- AUTOTOOLS_HOST=armv7a-linux-androideabi
|
||||
- OPENSSL_HOST=android-arm
|
||||
- ANDROID_CPU=armv7a
|
||||
- ANDROID_API=23
|
||||
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
|
||||
- ANDROID_SDK_ROOT="$HOME/android-sdk"
|
||||
- ANDROID_NDK_ROOT="$HOME/android-ndk"
|
||||
```
|
||||
|
||||
### ANDROID_NDK_ROOT
|
||||
|
||||
The second step for Android is to set the environmental variables `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT`. This is an important step because the NDK and SDK use the variables internally to locate their own tools. Also see [Recommended NDK Directory?](https://groups.google.com/forum/#!topic/android-ndk/qZjhOaynHXc) on the android-ndk mailing list. (Many folks miss this step, or use incorrect variables like `ANDROID_NDK_HOME` or `ANDROID_SDK_HOME`).
|
||||
|
||||
If you are working from a developer machine you probably already have the necessary tools installed. You should ensure `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` are set properly.
|
||||
|
||||
### Tool installation
|
||||
|
||||
The second step installs tools needed for OpenSSL, Expat and Unbound. This step is handled in by the script `contrib/android/install_tools.sh`. The tools include curl, tar, zip, unzip and java.
|
||||
|
||||
```
|
||||
before_script:
|
||||
- |
|
||||
if [ "$TEST_ANDROID" = "yes" ]; then
|
||||
./contrib/android/install_tools.sh
|
||||
elif [ "$TEST_IOS" = "yes" ]; then
|
||||
./contrib/ios/install_tools.sh
|
||||
fi
|
||||
```
|
||||
|
||||
### NDK installation
|
||||
|
||||
The third step installs the NDK and SDK. This step is handled in by the script `contrib/android/install_ndk.sh`. The script uses `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` to place the NDK and SDK in the `$HOME` directory.
|
||||
|
||||
If you are working from a developer machine you probably already have a NDK and SDK installed.
|
||||
|
||||
### Android environment
|
||||
|
||||
The fourth step sets the Android cross-compile environment using the script `contrib/android/setenv_android.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so Android headers and libraries are found; and adds the path to the toolchain to `PATH`.
|
||||
|
||||
`contrib/android/setenv_android.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `ANDROID_CPU` and `ANDROID_API` tell `contrib/android/setenv_android.sh` which tools and libraries to select.
|
||||
|
||||
The `contrib/android/setenv_android.sh` script specifies the tools in a `case` statement like the following. There is a case for each of the architectures armv7a, aarch64, x86 and x86_64.
|
||||
|
||||
```
|
||||
armv8a|aarch64|arm64|arm64-v8a)
|
||||
CC="aarch64-linux-android$ANDROID_API-clang"
|
||||
CXX="aarch64-linux-android$ANDROID_API-clang++"
|
||||
LD="aarch64-linux-android-ld"
|
||||
AS="aarch64-linux-android-as"
|
||||
AR="aarch64-linux-android-ar"
|
||||
RANLIB="aarch64-linux-android-ranlib"
|
||||
STRIP="aarch64-linux-android-strip"
|
||||
|
||||
CFLAGS="-funwind-tables -fexceptions"
|
||||
CXXFLAGS="-funwind-tables -fexceptions -frtti"
|
||||
```
|
||||
|
||||
### OpenSSL and Expat
|
||||
|
||||
The fifth step builds OpenSSL and Expat. OpenSSL and Expat are built for Android using the scripts `contrib/android/install_openssl.sh` and `contrib/android/install_expat.sh`. The scripts download, configure and install the latest release version of the libraries. The libraries are configured with `--prefix="$ANDROID_PREFIX"` so the headers are placed in `$ANDROID_PREFIX/include` directory, and the libraries are placed in the `$ANDROID_PREFIX/lib` directory.
|
||||
|
||||
`ANDROID_PREFIX` is the value `$HOME/android$ANDROID_API-$ANDROID_CPU`. The libraries will be installed in `$HOME/android23-armv7a`, `$HOME/android23-aarch64`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported. `PKG_CONFIG_PATH` is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/android23-armv7a/lib/pkgconfig` and `$HOME/android23-aarch64/lib/pkgconfig`.
|
||||
|
||||
OpenSSL also uses a custom configuration file called `15-android.conf`. It is a copy of the OpenSSL's project file and located at `contrib/android/15-android.conf`. The Unbound version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The Unbound version has legacy NDK support removed and some other fixes, like `ANDROID_NDK_ROOT` awareness. The changes mean Unbound's `15-android.conf` will only work with Unbound, with NDK-r19 and above, and a properly set environment.
|
||||
|
||||
OpenSSL is configured with `no-engine`. If you want to include OpenSSL engines then edit `contrib/android/install_openssl.sh` and remove the config option.
|
||||
|
||||
### Android build
|
||||
|
||||
Finally, once OpenSSL and Expat are built, then the Travis script configures and builds Unbound. The recipe looks as follows.
|
||||
|
||||
```
|
||||
elif [ "$TEST_ANDROID" = "yes" ]; then
|
||||
export AUTOTOOLS_BUILD="$(./config.guess)"
|
||||
export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
|
||||
./contrib/android/install_ndk.sh
|
||||
source ./contrib/android/setenv_android.sh
|
||||
./contrib/android/install_openssl.sh
|
||||
./contrib/android/install_expat.sh
|
||||
./configure \
|
||||
--build="$AUTOTOOLS_BUILD" \
|
||||
--host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$ANDROID_PREFIX" \
|
||||
--with-ssl="$ANDROID_PREFIX" \
|
||||
--with-libexpat="$ANDROID_PREFIX" \
|
||||
--disable-gost;
|
||||
make -j 2
|
||||
make install
|
||||
```
|
||||
|
||||
Travis only smoke tests an Android build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an emulator, push the tests to the device and run them.
|
||||
|
||||
### Android flags
|
||||
|
||||
`contrib/android/setenv_android.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from `ndk-build`, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.
|
||||
|
||||
`CXXFLAGS` includes `-fexceptions` and `-frtti` because exceptions and runtime type info are disabled by default. `CFLAGS` include `-funwind-tables` and `-fexceptions` to ensure C++ exceptions pass through C code, if needed. Also see `docs/CPLUSPLUS-SUPPORT.html` in the NDK docs.
|
||||
|
||||
To inspect the flags used by `ndk-build` for a platform clone ASOP's [ndk-samples](https://github.com/android/ndk-samples/tree/master/hello-jni) and build the `hello-jni` project. Use the `V=1` flag to see the full compiler output from `ndk-build`.
|
||||
|
||||
## iOS builds
|
||||
|
||||
Travis tests iOS builds for the armv7a, armv7s and aarch64 architectures for iPhoneOS, AppleTVOS and WatchOS. iPhoneOS is tested using both 32-bit builds (iPhones) and 64-bit builds (iPads). Travis also tests compiles against the simulators. The builds are trickier than other builds for several reasons. The testing requires a cross-compile, and requires OpenSSL and Expat prerequisites. The iOS cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the iOS recipes.
|
||||
|
||||
### iOS job
|
||||
|
||||
The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
|
||||
|
||||
```
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
name: Apple iPhone on iOS, armv7
|
||||
compiler: clang
|
||||
env:
|
||||
- TEST_IOS=yes
|
||||
- AUTOTOOLS_HOST=armv7-apple-ios
|
||||
- OPENSSL_HOST=ios-cross
|
||||
- IOS_SDK=iPhoneOS
|
||||
- IOS_CPU=armv7s
|
||||
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
```
|
||||
|
||||
### Tool installation
|
||||
|
||||
The second step installs tools needed for OpenSSL, Expat and Unbound. This step is handled in by the script `contrib/ios/install_tools.sh`. The tools include autotools, curl and perl. The installation happens at the `before_script:` stage of Travis.
|
||||
|
||||
```
|
||||
before_script:
|
||||
- |
|
||||
if [ "$TEST_ANDROID" = "yes" ]; then
|
||||
./contrib/android/install_tools.sh
|
||||
elif [ "$TEST_IOS" = "yes" ]; then
|
||||
./contrib/ios/install_tools.sh
|
||||
fi
|
||||
```
|
||||
|
||||
### iOS environment
|
||||
|
||||
The third step sets the iOS cross-compile environment using the script `contrib/ios/setenv_ios.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so iOS headers and libraries are found; and adds the path to the toolchain to `PATH`.
|
||||
|
||||
`contrib/ios/setenv_ios.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `IOS_SDK` and `IOS_CPU` tell `contrib/ios/setenv_ios.sh` which tools and libraries to select.
|
||||
|
||||
The `contrib/ios/setenv_ios.sh` script specifies the tools to use during the cross-compile. For Apple SDKs, the tool names are the same as a desktop. There are no special prefixes for the mobile tools.
|
||||
|
||||
```
|
||||
CPP=cpp
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
LD=ld
|
||||
AS=as
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
STRIP=strip
|
||||
```
|
||||
|
||||
If you are working from a developer machine you probably already have the necessary tools installed.
|
||||
|
||||
### OpenSSL and Expat
|
||||
|
||||
The fourth step builds OpenSSL and Expat. OpenSSL and Expat are built for iOS using the scripts `contrib/ios/install_openssl.sh` and `contrib/ios/install_expat.sh`. The scripts download, configure and install the latest release version of the libraries. The libraries are configured with `--prefix="$IOS_PREFIX"` so the headers are placed in `$IOS_PREFIX/include` directory, and the libraries are placed in the `$IOS_PREFIX/lib` directory.
|
||||
|
||||
`IOS_PREFIX` is the value `$HOME/$IOS_SDK-$IOS_CPU`. The scheme handles both iOS SDKs and cpu architectures so the pair recieves a unique installation directory. The libraries will be installed in `$HOME/iPhoneOS-armv7s`, `$HOME/iPhoneOS-arm64`, `$HOME/iPhoneSimulator-i386`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported.
|
||||
|
||||
`PKG_CONFIG_PATH` is an important variable. It is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/iPhoneOS-armv7s/lib/pkgconfig` and `$HOME/iPhoneOS-arm64/lib/pkgconfig`.
|
||||
|
||||
OpenSSL also uses a custom configuration file called `15-ios.conf`. It is a copy of the OpenSSL's project file and located at `contrib/ios/15-ios.conf`. The Unbound version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The changes mean Unbound's `15-ios.conf` will only work with Unbound and a properly set environment.
|
||||
|
||||
OpenSSL is configured with `no-engine`. Engines require dynamic loading so engines are disabled permanently in `15-ios.conf`.
|
||||
|
||||
### iOS build
|
||||
|
||||
Finally, once OpenSSL and Expat are built, then the Travis script configures and builds Unbound. The full recipe looks as follows.
|
||||
|
||||
```
|
||||
elif [ "$TEST_IOS" = "yes" ]; then
|
||||
export AUTOTOOLS_BUILD="$(./config.guess)"
|
||||
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
|
||||
source ./contrib/ios/setenv_ios.sh
|
||||
./contrib/ios/install_openssl.sh
|
||||
./contrib/ios/install_expat.sh
|
||||
./configure \
|
||||
--build="$AUTOTOOLS_BUILD" \
|
||||
--host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$IOS_PREFIX" \
|
||||
--with-ssl="$IOS_PREFIX" \
|
||||
--with-libexpat="$IOS_PREFIX" \
|
||||
--disable-gost;
|
||||
make -j 2
|
||||
make install
|
||||
```
|
||||
|
||||
Travis only smoke tests an iOS build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an simulator, push the tests to the device and run them.
|
||||
|
||||
### iOS flags
|
||||
|
||||
`contrib/ios/setenv_ios.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from Xcode, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.
|
||||
@@ -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://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
You can learn 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
+48
-94
@@ -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,
|
||||
@@ -736,7 +736,6 @@ _LT_CONFIG_SAVE_COMMANDS([
|
||||
cat <<_LT_EOF >> "$cfgfile"
|
||||
#! $SHELL
|
||||
# Generated automatically by $as_me ($PACKAGE) $VERSION
|
||||
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
|
||||
# Provide generalized library-building support services.
|
||||
@@ -1048,8 +1047,8 @@ int forced_loaded() { return 2;}
|
||||
_LT_EOF
|
||||
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
|
||||
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
|
||||
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
|
||||
cat > conftest.c << _LT_EOF
|
||||
@@ -1499,7 +1498,7 @@ need_locks=$enable_libtool_lock
|
||||
m4_defun([_LT_PROG_AR],
|
||||
[AC_CHECK_TOOLS(AR, [ar], false)
|
||||
: ${AR=ar}
|
||||
: ${AR_FLAGS=cru}
|
||||
: ${AR_FLAGS=cr}
|
||||
_LT_DECL([], [AR], [1], [The archiver])
|
||||
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
|
||||
|
||||
@@ -2873,9 +2872,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
# before this can be enabled.
|
||||
hardcode_into_libs=yes
|
||||
|
||||
# Add ABI-specific directories to the system library path.
|
||||
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
|
||||
|
||||
# Ideally, we could use ldconfig to report *all* directores which are
|
||||
# searched for libraries, however this is still not possible. Aside from not
|
||||
# being certain /sbin/ldconfig is available, command
|
||||
@@ -2884,7 +2880,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
# appending ld.so.conf contents (and includes) to the search path.
|
||||
if test -f /etc/ld.so.conf; then
|
||||
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
|
||||
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
|
||||
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
|
||||
fi
|
||||
|
||||
# We used to test for /lib/ld.so.1 and disable shared libraries on
|
||||
@@ -2896,6 +2892,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
dynamic_linker='GNU/Linux ld.so'
|
||||
;;
|
||||
|
||||
netbsdelf*-gnu)
|
||||
version_type=linux
|
||||
need_lib_prefix=no
|
||||
need_version=no
|
||||
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
|
||||
soname_spec='${libname}${release}${shared_ext}$major'
|
||||
shlibpath_var=LD_LIBRARY_PATH
|
||||
shlibpath_overrides_runpath=no
|
||||
hardcode_into_libs=yes
|
||||
dynamic_linker='NetBSD ld.elf_so'
|
||||
;;
|
||||
|
||||
netbsd*)
|
||||
version_type=sunos
|
||||
need_lib_prefix=no
|
||||
@@ -3555,7 +3563,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
netbsd*)
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
|
||||
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
|
||||
else
|
||||
@@ -4061,7 +4069,8 @@ _LT_EOF
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
# Now try to grab the symbols.
|
||||
nlist=conftest.nm
|
||||
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
|
||||
$ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
|
||||
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
|
||||
# Try sorting and uniquifying the output.
|
||||
if sort "$nlist" | uniq > "$nlist"T; then
|
||||
mv -f "$nlist"T "$nlist"
|
||||
@@ -4433,7 +4442,7 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
netbsd*)
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
;;
|
||||
*qnx* | *nto*)
|
||||
# QNX uses GNU C++, but need to define -shared option too, otherwise
|
||||
@@ -4701,6 +4710,12 @@ m4_if([$1], [CXX], [
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
|
||||
;;
|
||||
# flang / f18. f95 an alias for gfortran or flang on Debian
|
||||
flang* | f18* | f95*)
|
||||
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
|
||||
;;
|
||||
# icc used to be incompatible with GCC.
|
||||
# ICC 10 doesn't accept -KPIC any more.
|
||||
icc* | ifort*)
|
||||
@@ -4945,6 +4960,9 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
linux* | k*bsd*-gnu | gnu*)
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
;;
|
||||
*)
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
|
||||
;;
|
||||
@@ -5007,6 +5025,9 @@ dnl Note also adjust exclude_expsyms for C++ above.
|
||||
openbsd* | bitrig*)
|
||||
with_gnu_ld=no
|
||||
;;
|
||||
linux* | k*bsd*-gnu | gnu*)
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
;;
|
||||
esac
|
||||
|
||||
_LT_TAGVAR(ld_shlibs, $1)=yes
|
||||
@@ -5261,7 +5282,7 @@ _LT_EOF
|
||||
fi
|
||||
;;
|
||||
|
||||
netbsd*)
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
|
||||
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
|
||||
wlarc=
|
||||
@@ -5782,6 +5803,7 @@ _LT_EOF
|
||||
if test yes = "$lt_cv_irix_exported_symbol"; then
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
|
||||
fi
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
else
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
|
||||
@@ -5803,7 +5825,7 @@ _LT_EOF
|
||||
esac
|
||||
;;
|
||||
|
||||
netbsd*)
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
|
||||
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
|
||||
else
|
||||
@@ -6425,7 +6447,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
|
||||
else
|
||||
GXX=no
|
||||
@@ -6800,7 +6822,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# explicitly linking system object files so we need to strip them
|
||||
# from the output so that they don't get included in the library
|
||||
# dependencies.
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
;;
|
||||
*)
|
||||
if test yes = "$GXX"; then
|
||||
@@ -6865,7 +6887,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# explicitly linking system object files so we need to strip them
|
||||
# from the output so that they don't get included in the library
|
||||
# dependencies.
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
;;
|
||||
*)
|
||||
if test yes = "$GXX"; then
|
||||
@@ -7204,7 +7226,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
|
||||
else
|
||||
# FIXME: insert proper C++ library support
|
||||
@@ -7288,7 +7310,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
else
|
||||
# g++ 2.7 appears to require '-G' NOT '-shared' on this
|
||||
# platform.
|
||||
@@ -7299,7 +7321,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
fi
|
||||
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
|
||||
@@ -9044,9 +9066,9 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 11 (pkg-config-0.29.1)
|
||||
|
||||
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
dnl serial 11 (pkg-config-0.29.1)
|
||||
dnl
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
dnl
|
||||
@@ -9320,77 +9342,9 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])dnl PKG_CHECK_VAR
|
||||
|
||||
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl ------------------------------------------
|
||||
dnl
|
||||
dnl Prepare a "--with-" configure option using the lowercase
|
||||
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
|
||||
dnl PKG_CHECK_MODULES in a single macro.
|
||||
AC_DEFUN([PKG_WITH_MODULES],
|
||||
[
|
||||
m4_pushdef([with_arg], m4_tolower([$1]))
|
||||
|
||||
m4_pushdef([description],
|
||||
[m4_default([$5], [build with ]with_arg[ support])])
|
||||
|
||||
m4_pushdef([def_arg], [m4_default([$6], [auto])])
|
||||
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
|
||||
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
|
||||
|
||||
m4_case(def_arg,
|
||||
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
|
||||
[m4_pushdef([with_without],[--with-]with_arg)])
|
||||
|
||||
AC_ARG_WITH(with_arg,
|
||||
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
|
||||
[AS_TR_SH([with_]with_arg)=def_arg])
|
||||
|
||||
AS_CASE([$AS_TR_SH([with_]with_arg)],
|
||||
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
|
||||
[auto],[PKG_CHECK_MODULES([$1],[$2],
|
||||
[m4_n([def_action_if_found]) $3],
|
||||
[m4_n([def_action_if_not_found]) $4])])
|
||||
|
||||
m4_popdef([with_arg])
|
||||
m4_popdef([description])
|
||||
m4_popdef([def_arg])
|
||||
|
||||
])dnl PKG_WITH_MODULES
|
||||
|
||||
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl -----------------------------------------------
|
||||
dnl
|
||||
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
|
||||
dnl check._[VARIABLE-PREFIX] is exported as make variable.
|
||||
AC_DEFUN([PKG_HAVE_WITH_MODULES],
|
||||
[
|
||||
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
|
||||
|
||||
AM_CONDITIONAL([HAVE_][$1],
|
||||
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
|
||||
])dnl PKG_HAVE_WITH_MODULES
|
||||
|
||||
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl ------------------------------------------------------
|
||||
dnl
|
||||
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
|
||||
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
|
||||
dnl and preprocessor variable.
|
||||
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
|
||||
[
|
||||
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
|
||||
|
||||
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
||||
|
||||
# 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 +9375,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,
|
||||
|
||||
+44
-51
@@ -2,7 +2,10 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 34
|
||||
# Version 37
|
||||
# 2021-01-05 fix defun for aclocal
|
||||
# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
|
||||
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
|
||||
# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0.
|
||||
# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0).
|
||||
# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20
|
||||
@@ -446,15 +449,12 @@ AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE],
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_format_attribute,
|
||||
[ac_cv_c_format_attribute=no
|
||||
AC_TRY_COMPILE(
|
||||
[#include <stdio.h>
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
|
||||
void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
], [
|
||||
]], [[
|
||||
f ("%s", "str");
|
||||
],
|
||||
[ac_cv_c_format_attribute="yes"],
|
||||
[ac_cv_c_format_attribute="no"])
|
||||
]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_format_attribute)
|
||||
@@ -483,14 +483,11 @@ AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_unused_attribute,
|
||||
[ac_cv_c_unused_attribute=no
|
||||
AC_TRY_COMPILE(
|
||||
[#include <stdio.h>
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
|
||||
void f (char *u __attribute__((unused)));
|
||||
], [
|
||||
]], [[
|
||||
f ("x");
|
||||
],
|
||||
[ac_cv_c_unused_attribute="yes"],
|
||||
[ac_cv_c_unused_attribute="no"])
|
||||
]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
|
||||
])
|
||||
|
||||
dnl Setup ATTR_UNUSED config.h parts.
|
||||
@@ -547,7 +544,7 @@ dnl as a requirement so that is gets called before LIBTOOL
|
||||
dnl because libtools 'AC_REQUIRE' names are right after this one, before
|
||||
dnl this function contents.
|
||||
AC_REQUIRE([ACX_LIBTOOL_C_PRE])
|
||||
AC_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
])
|
||||
|
||||
dnl Detect if u_char type is defined, otherwise define it.
|
||||
@@ -673,17 +670,17 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
ACX_RUNTIME_PATH_ADD([$ssldir/lib])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for HMAC_Update in -lcrypto])
|
||||
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
|
||||
LIBS="$LIBS -lcrypto"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
|
||||
AC_TRY_LINK(, [
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
|
||||
int EVP_sha256(void);
|
||||
(void)EVP_sha256();
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
], [
|
||||
AC_DEFINE([HAVE_EVP_SHA256], 1,
|
||||
[If you have EVP_sha256])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
# check if -lwsock32 or -lgdi32 are needed.
|
||||
BAKLIBS="$LIBS"
|
||||
@@ -691,12 +688,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
LIBS="$LIBS -lgdi32 -lws2_32"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
|
||||
int EVP_sha256(void);
|
||||
(void)EVP_sha256();
|
||||
]])],[
|
||||
AC_DEFINE([HAVE_EVP_SHA256], 1,
|
||||
[If you have EVP_sha256])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -705,12 +702,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
LIBS="$LIBS -ldl"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -ldl])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
|
||||
int EVP_sha256(void);
|
||||
(void)EVP_sha256();
|
||||
]])],[
|
||||
AC_DEFINE([HAVE_EVP_SHA256], 1,
|
||||
[If you have EVP_sha256])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -719,12 +716,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
LIBS="$LIBS -ldl -pthread"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
|
||||
int EVP_sha256(void);
|
||||
(void)EVP_sha256();
|
||||
]])],[
|
||||
AC_DEFINE([HAVE_EVP_SHA256], 1,
|
||||
[If you have EVP_sha256])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -749,8 +746,7 @@ dnl Checks main header files of SSL.
|
||||
dnl
|
||||
AC_DEFUN([ACX_WITH_SSL],
|
||||
[
|
||||
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
|
||||
[enable SSL (will check /usr/local/ssl
|
||||
AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
|
||||
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
|
||||
],[
|
||||
withval="yes"
|
||||
@@ -768,8 +764,7 @@ dnl Checks main header files of SSL.
|
||||
dnl
|
||||
AC_DEFUN([ACX_WITH_SSL_OPTIONAL],
|
||||
[
|
||||
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
|
||||
[enable SSL (will check /usr/local/ssl
|
||||
AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
|
||||
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
|
||||
],[
|
||||
withval="yes"
|
||||
@@ -1061,7 +1056,7 @@ dnl defines MKDIR_HAS_ONE_ARG
|
||||
AC_DEFUN([ACX_MKDIR_ONE_ARG],
|
||||
[
|
||||
AC_MSG_CHECKING([whether mkdir has one arg])
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
@@ -1070,14 +1065,12 @@ AC_TRY_COMPILE([
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
], [
|
||||
]], [[
|
||||
(void)mkdir("directory");
|
||||
],
|
||||
AC_MSG_RESULT(yes)
|
||||
]])],[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
|
||||
,
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
],[AC_MSG_RESULT(no)
|
||||
])
|
||||
])dnl end of ACX_MKDIR_ONE_ARG
|
||||
|
||||
dnl Check for ioctlsocket function. works on mingw32 too.
|
||||
|
||||
+8
-3
@@ -58,6 +58,11 @@ $ac_distutils_result])
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
if test -z "$PYTHON_LIBDIR"; then
|
||||
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print(get_config_var('LIBDIR'));"`
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
@@ -80,11 +85,11 @@ $ac_distutils_result])
|
||||
|
||||
LIBS="$LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_TRY_LINK([
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <Python.h>
|
||||
],[
|
||||
]],[[
|
||||
Py_Initialize();
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
]])],[pythonexists=yes],[pythonexists=no])
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
|
||||
+75
-25
@@ -64,13 +64,26 @@
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_HTOBE64
|
||||
# ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
# else
|
||||
/* not OSX */
|
||||
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on 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 /* _ENDIAN */
|
||||
# endif /* HAVE_LIBKERN_OSBYTEORDER_H */
|
||||
#endif /* HAVE_BE64TOH */
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
@@ -147,7 +160,7 @@ testframe_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
|
||||
static void
|
||||
testframe_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
char* key, uint8_t* data, size_t data_len, time_t ATTR_UNUSED(ttl))
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
@@ -205,10 +218,6 @@ static int
|
||||
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
|
||||
{
|
||||
const char* backend_str = cfg->cachedb_backend;
|
||||
|
||||
/* If unspecified we use the in-memory test DB. */
|
||||
if(!backend_str)
|
||||
backend_str = "testframe";
|
||||
cachedb_env->backend = cachedb_find_backend(backend_str);
|
||||
if(!cachedb_env->backend) {
|
||||
log_err("cachedb: cannot find backend name '%s'", backend_str);
|
||||
@@ -231,6 +240,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,9 +250,20 @@ 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;
|
||||
if(env->cfg->serve_expired_reply_ttl)
|
||||
log_warn(
|
||||
"cachedb: serve-expired-reply-ttl is set but not working for data "
|
||||
"originating from the external cache; 0 TLL is used for those.");
|
||||
if(env->cfg->serve_expired_client_timeout)
|
||||
log_warn(
|
||||
"cachedb: serve-expired-client-timeout is set but not working for "
|
||||
"data originating from the external cache; expired data are used "
|
||||
"in the reply without first trying to refresh the data.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -312,8 +334,7 @@ calc_hash(struct module_qstate* qstate, char* buf, size_t len)
|
||||
size_t clen = 0;
|
||||
uint8_t hash[CACHEDB_HASHSIZE/8];
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
const char* secret = qstate->env->cfg->cachedb_secret ?
|
||||
qstate->env->cfg->cachedb_secret : "default";
|
||||
const char* secret = qstate->env->cfg->cachedb_secret;
|
||||
size_t i;
|
||||
|
||||
/* copy the hash info into the clear buffer */
|
||||
@@ -336,7 +357,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) */
|
||||
@@ -412,8 +437,14 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
&expiry, sizeof(expiry));
|
||||
expiry = be64toh(expiry);
|
||||
|
||||
/* Check if we are allowed to return expired entries:
|
||||
* - serve_expired needs to be set
|
||||
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
|
||||
* than that. */
|
||||
if((time_t)expiry < *qstate->env->now &&
|
||||
!qstate->env->cfg->serve_expired)
|
||||
(!qstate->env->cfg->serve_expired ||
|
||||
(SERVE_EXPIRED_TTL &&
|
||||
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -424,16 +455,17 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
static void
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
if(subtract >= 0 && data->ttl > subtract)
|
||||
data->ttl -= subtract;
|
||||
else data->ttl = 0;
|
||||
for(i=0; i<total; i++) {
|
||||
for(i=0; i<total; i++) {
|
||||
if(subtract >= 0 && data->rr_ttl[i] > subtract)
|
||||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
}
|
||||
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
|
||||
}
|
||||
|
||||
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
|
||||
@@ -444,8 +476,10 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
size_t i;
|
||||
if(adjust >= 0 && msg->rep->ttl > adjust)
|
||||
msg->rep->ttl -= adjust;
|
||||
else msg->rep->ttl = 0;
|
||||
else
|
||||
msg->rep->ttl = 0;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
|
||||
@@ -573,7 +607,8 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
|
||||
/* call backend */
|
||||
(*ie->backend->store)(qstate->env, ie, key,
|
||||
sldns_buffer_begin(qstate->env->scratch_buffer),
|
||||
sldns_buffer_limit(qstate->env->scratch_buffer));
|
||||
sldns_buffer_limit(qstate->env->scratch_buffer),
|
||||
qstate->return_msg->rep->ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -651,7 +686,8 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
return;
|
||||
}
|
||||
|
||||
/* lookup inside unbound's internal cache */
|
||||
/* lookup inside unbound's internal cache.
|
||||
* This does not look for expired entries. */
|
||||
if(cachedb_intcache_lookup(qstate)) {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(qstate->return_msg->rep)
|
||||
@@ -659,8 +695,9 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
else log_info("cachedb internal cache lookup: rcode %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)
|
||||
?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name
|
||||
:"??");
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
@@ -675,6 +712,19 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate);
|
||||
/* In case we have expired data but there is a client timer for expired
|
||||
* answers, pass execution to next module in order to try updating the
|
||||
* data first.
|
||||
* TODO: this needs revisit. The expired data stored from cachedb has
|
||||
* 0 TTL which is picked up by iterator later when looking in the cache.
|
||||
* Document that ext cachedb does not work properly with
|
||||
* serve_stale_reply_ttl yet. */
|
||||
if(qstate->need_refetch && qstate->serve_expired_data &&
|
||||
qstate->serve_expired_data->timer) {
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ struct cachedb_backend {
|
||||
|
||||
/** Store (env, cachedb_env, key, data, data_len) */
|
||||
void (*store)(struct module_env*, struct cachedb_env*, char*,
|
||||
uint8_t*, size_t);
|
||||
uint8_t*, size_t, time_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
+53
-6
@@ -59,6 +59,9 @@ struct redis_moddata {
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
};
|
||||
|
||||
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
|
||||
const char*, const uint8_t*, size_t);
|
||||
|
||||
static redisContext*
|
||||
redis_connect(const struct redis_moddata* moddata)
|
||||
{
|
||||
@@ -114,6 +117,33 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
for(i = 0; i < moddata->numctxs; i++)
|
||||
moddata->ctxs[i] = redis_connect(moddata);
|
||||
cachedb_env->backend_data = moddata;
|
||||
if(env->cfg->redis_expire_records) {
|
||||
redisReply* rep = NULL;
|
||||
int redis_reply_type = 0;
|
||||
/** check if setex command is supported */
|
||||
rep = redis_command(env, cachedb_env,
|
||||
"SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
|
||||
if(!rep) {
|
||||
/** init failed, no response from redis server*/
|
||||
log_err("redis_init: failed to init redis, the "
|
||||
"redis-expire-records option requires the SETEX command "
|
||||
"(redis >= 2.0.0)");
|
||||
return 0;
|
||||
}
|
||||
redis_reply_type = rep->type;
|
||||
freeReplyObject(rep);
|
||||
switch(redis_reply_type) {
|
||||
case REDIS_REPLY_STATUS:
|
||||
break;
|
||||
default:
|
||||
/** init failed, setex command not supported */
|
||||
log_err("redis_init: failed to init redis, the "
|
||||
"redis-expire-records option requires the SETEX command "
|
||||
"(redis >= 2.0.0)");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -219,7 +249,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch (rep->type) {
|
||||
switch(rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
@@ -249,16 +279,33 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
|
||||
static void
|
||||
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
char* key, uint8_t* data, size_t data_len, time_t ttl)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
|
||||
int n;
|
||||
int set_ttl = (env->cfg->redis_expire_records &&
|
||||
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
|
||||
/* Supported commands:
|
||||
* - "SET " + key + " %b"
|
||||
* - "SETEX " + key + " " + ttl + " %b"
|
||||
*/
|
||||
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
|
||||
|
||||
if (!set_ttl) {
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
} else {
|
||||
/* add expired ttl time to redis ttl to avoid premature eviction of key */
|
||||
ttl += env->cfg->serve_expired_ttl;
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u",
|
||||
key, (int)data_len, (uint32_t)ttl);
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key,
|
||||
(uint32_t)ttl);
|
||||
}
|
||||
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_store: unexpected failure to build command");
|
||||
return;
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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.4 2014/07/12 20:41:47 wouter Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
@@ -204,7 +204,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)
|
||||
@@ -428,7 +428,7 @@ 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);
|
||||
|
||||
@@ -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
+539
-334
File diff suppressed because it is too large
Load Diff
+144
-8
@@ -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
|
||||
|
||||
@@ -19,6 +28,9 @@
|
||||
/* Whether daemon is deprecated */
|
||||
#undef DEPRECATED_DAEMON
|
||||
|
||||
/* Define this to enable kernel based UDP source port randomization. */
|
||||
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
|
||||
/* default dnstap socket path */
|
||||
#undef DNSTAP_SOCKET_PATH
|
||||
|
||||
@@ -45,12 +57,24 @@
|
||||
/* 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
|
||||
|
||||
/* Whether the C compiler accepts the "weak" attribute */
|
||||
#undef HAVE_ATTR_WEAK
|
||||
|
||||
/* If we have be64toh */
|
||||
#undef HAVE_BE64TOH
|
||||
|
||||
/* Define to 1 if you have the <bsd/stdlib.h> header file. */
|
||||
#undef HAVE_BSD_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <bsd/string.h> header file. */
|
||||
#undef HAVE_BSD_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `chown' function. */
|
||||
#undef HAVE_CHOWN
|
||||
|
||||
@@ -60,6 +84,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 +101,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
|
||||
@@ -82,6 +113,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
|
||||
and to 0 if you don't. */
|
||||
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
@@ -148,12 +183,18 @@
|
||||
/* Define to 1 if you have the `endservent' function. */
|
||||
#undef HAVE_ENDSERVENT
|
||||
|
||||
/* Define to 1 if you have the `ENGINE_cleanup' function. */
|
||||
#undef HAVE_ENGINE_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `ERR_free_strings' function. */
|
||||
#undef HAVE_ERR_FREE_STRINGS
|
||||
|
||||
/* 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 +210,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 +222,12 @@
|
||||
/* 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_MAC_CTX_set_params' function. */
|
||||
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
|
||||
#undef HAVE_EVP_MD_CTX_NEW
|
||||
|
||||
@@ -199,6 +249,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
|
||||
|
||||
@@ -223,6 +276,9 @@
|
||||
/* Define to 1 if you have the `getentropy' function. */
|
||||
#undef HAVE_GETENTROPY
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
#undef HAVE_GETIFADDRS
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
@@ -247,8 +303,14 @@
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
/* Define to 1 if you have the `HMAC_Init_ex' function. */
|
||||
#undef HAVE_HMAC_INIT_EX
|
||||
|
||||
/* If we have htobe64 */
|
||||
#undef HAVE_HTOBE64
|
||||
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#undef HAVE_IFADDRS_H
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
@@ -277,6 +339,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Use portable libbsd functions */
|
||||
#undef HAVE_LIBBSD
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
#undef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
|
||||
@@ -316,6 +381,15 @@
|
||||
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
|
||||
#undef HAVE_NETTLE_EDDSA_H
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define this to use nghttp2 client. */
|
||||
#undef HAVE_NGHTTP2
|
||||
|
||||
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
|
||||
#undef HAVE_NGHTTP2_NGHTTP2_H
|
||||
|
||||
/* Use libnss for crypto */
|
||||
#undef HAVE_NSS
|
||||
|
||||
@@ -331,6 +405,9 @@
|
||||
/* Define to 1 if you have the <openssl/conf.h> header file. */
|
||||
#undef HAVE_OPENSSL_CONF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/core_names.h> header file. */
|
||||
#undef HAVE_OPENSSL_CORE_NAMES_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/dh.h> header file. */
|
||||
#undef HAVE_OPENSSL_DH_H
|
||||
|
||||
@@ -382,7 +459,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 +516,19 @@
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
|
||||
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
|
||||
|
||||
/* 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_evp_cb'
|
||||
function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_peername' function. */
|
||||
#undef HAVE_SSL_GET0_PEERNAME
|
||||
|
||||
@@ -508,6 +595,9 @@
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sha2.h> header file. */
|
||||
#undef HAVE_SYS_SHA2_H
|
||||
|
||||
@@ -535,6 +625,9 @@
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <TargetConditionals.h> header file. */
|
||||
#undef HAVE_TARGETCONDITIONALS_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
@@ -574,9 +667,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
|
||||
|
||||
@@ -648,9 +747,13 @@
|
||||
your system. */
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
/* Return type of signal handlers, but autoconf 2.70 says 'your code may
|
||||
safely assume C89 semantics that RETSIGTYPE is void.' */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* if REUSEPORT is enabled by default */
|
||||
#undef REUSEPORT_DEFAULT
|
||||
|
||||
/* default rootkey location */
|
||||
#undef ROOT_ANCHOR_FILE
|
||||
|
||||
@@ -666,6 +769,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 +790,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 +841,12 @@
|
||||
/* Define to 1 to use ipsecmod support. */
|
||||
#undef USE_IPSECMOD
|
||||
|
||||
/* Define to 1 to use ipset support */
|
||||
#undef USE_IPSET
|
||||
|
||||
/* Define if you enable libevent */
|
||||
#undef USE_LIBEVENT
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
@@ -781,6 +896,9 @@
|
||||
/* the version of the windows API enabled */
|
||||
#undef WINVER
|
||||
|
||||
/* Define if you want dynlib module. */
|
||||
#undef WITH_DYNLIBMODULE
|
||||
|
||||
/* Define if you want Python module. */
|
||||
#undef WITH_PYTHONMODULE
|
||||
|
||||
@@ -929,8 +1047,14 @@
|
||||
|
||||
|
||||
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifndef UNBOUND_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
@@ -1144,6 +1268,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 +1287,15 @@ 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_LIBBSD
|
||||
#include <bsd/string.h>
|
||||
#include <bsd/stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBRESSL
|
||||
# if !HAVE_DECL_STRLCPY
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
@@ -1171,12 +1309,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);
|
||||
@@ -1250,6 +1384,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for DNS over HTTPS traffic. */
|
||||
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
Vendored
+1377
-1407
File diff suppressed because it is too large
Load Diff
+482
-131
File diff suppressed because it is too large
Load Diff
+18
-1
@@ -27,10 +27,12 @@ distribution but may be helpful.
|
||||
works like the BIND feature (removes AAAA records unless AAAA-only domain).
|
||||
Useful for certain 'broken IPv6 default route' scenarios.
|
||||
Patch from Stephane Lapie for ASAHI Net.
|
||||
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
|
||||
* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
|
||||
Contributed by Yuri Voinov.
|
||||
* unbound.socket and unbound.service: systemd files for unbound, install them
|
||||
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
|
||||
* unbound_portable.service.in: systemd file for use unbound as portable service,
|
||||
see comments in the file. Contributed by Frzk.
|
||||
* redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
|
||||
instead of SERVFAIL. Contributed by SIDN.
|
||||
* fastrpz.patch: fastrpz support from Farsight Security.
|
||||
@@ -38,3 +40,18 @@ 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.
|
||||
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
|
||||
contributed by Andreas Schulze.
|
||||
* metrics.awk: awk script that can convert unbound-control stats to
|
||||
Prometheus metrics format output.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Index: trunk/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- trunk/doc/unbound.conf.5.in (revision 4357)
|
||||
+++ trunk/doc/unbound.conf.5.in (working copy)
|
||||
@@ -701,6 +701,13 @@
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index f426ac5f..147fbfa9 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -872,6 +872,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
This option only has effect when qname-minimisation is enabled. Default is no.
|
||||
.TP
|
||||
+.B aaaa\-filter: \fI<yes or no>
|
||||
+Activate behavior similar to BIND's AAAA-filter.
|
||||
@@ -13,17 +13,18 @@ Index: trunk/doc/unbound.conf.5.in
|
||||
+This also causes an additional A query to be sent for each AAAA query.
|
||||
+This breaks DNSSEC!
|
||||
+.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for
|
||||
Index: trunk/iterator/iter_scrub.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_scrub.c (revision 4357)
|
||||
+++ trunk/iterator/iter_scrub.c (working copy)
|
||||
@@ -617,6 +617,32 @@
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
|
||||
index aae934dd..55c55de0 100644
|
||||
--- a/iterator/iter_scrub.c
|
||||
+++ b/iterator/iter_scrub.c
|
||||
@@ -667,6 +667,32 @@ static int sanitize_nsec_is_overreach(struct rrset_parse* rrset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
+/**
|
||||
+ * ASN: Lookup A records from rrset cache.
|
||||
+ * @param qinfo: the question originally asked.
|
||||
+ * @param env: module environment with config and cache.
|
||||
@@ -49,11 +50,10 @@ Index: trunk/iterator/iter_scrub.c
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
/**
|
||||
* Given a response event, remove suspect RRsets from the response.
|
||||
* "Suspect" rrsets are potentially poison. Note that this routine expects
|
||||
* the response to be in a "normalized" state -- that is, all "irrelevant"
|
||||
@@ -635,6 +661,7 @@
|
||||
@@ -686,6 +712,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
|
||||
struct iter_env* ie)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ Index: trunk/iterator/iter_scrub.c
|
||||
int del_addi = 0; /* if additional-holding rrsets are deleted, we
|
||||
do not trust the normalized additional-A-AAAA any more */
|
||||
struct rrset_parse* rrset, *prev;
|
||||
@@ -670,6 +697,13 @@
|
||||
@@ -721,6 +748,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
||||
@@ -75,11 +75,10 @@ Index: trunk/iterator/iter_scrub.c
|
||||
/* At this point, we brutally remove ALL rrsets that aren't
|
||||
* children of the originating zone. The idea here is that,
|
||||
* as far as we know, the server that we contacted is ONLY
|
||||
@@ -680,6 +714,24 @@
|
||||
prev = NULL;
|
||||
@@ -732,6 +766,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset = msg->rrset_first;
|
||||
while(rrset) {
|
||||
+
|
||||
|
||||
+ /* ASN: For AAAA records only... */
|
||||
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
+ /* ASN: If this is not a AAAA query, then remove AAAA
|
||||
@@ -97,14 +96,15 @@ Index: trunk/iterator/iter_scrub.c
|
||||
+ LDNS_RR_TYPE_AAAA, qinfo->qclass);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
|
||||
+
|
||||
/* remove private addresses */
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
Index: trunk/iterator/iter_utils.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_utils.c (revision 4357)
|
||||
+++ trunk/iterator/iter_utils.c (working copy)
|
||||
@@ -175,6 +175,7 @@
|
||||
rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
|
||||
index 7bc67da6..e10f547a 100644
|
||||
--- a/iterator/iter_utils.c
|
||||
+++ b/iterator/iter_utils.c
|
||||
@@ -175,6 +175,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
@@ -112,11 +112,11 @@ Index: trunk/iterator/iter_utils.c
|
||||
return 1;
|
||||
}
|
||||
|
||||
Index: trunk/iterator/iterator.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.c (revision 4357)
|
||||
+++ trunk/iterator/iterator.c (working copy)
|
||||
@@ -1847,6 +1847,53 @@
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 23b07ea9..ca29b48c 100644
|
||||
--- a/iterator/iterator.c
|
||||
+++ b/iterator/iterator.c
|
||||
@@ -2127,6 +2127,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ Index: trunk/iterator/iterator.c
|
||||
+ * ASN: This event state was added as an intermediary step between
|
||||
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
|
||||
+ * purpose of caching A records for the queried name.
|
||||
+ *
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param iq: iterator query state.
|
||||
+ * @param ie: iterator shared global environment.
|
||||
@@ -147,9 +147,9 @@ Index: trunk/iterator/iterator.c
|
||||
+
|
||||
+ /* re-throw same query, but with a different type */
|
||||
+ if(!generate_sub_request(iq->qchase.qname,
|
||||
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass, qstate, id, iq,
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
|
||||
+ "preloading of A record for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
@@ -170,7 +170,7 @@ Index: trunk/iterator/iterator.c
|
||||
|
||||
/**
|
||||
* This is the request event state where the request will be sent to one of
|
||||
@@ -1894,6 +1941,13 @@
|
||||
@@ -2186,6 +2233,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -184,11 +184,11 @@ Index: trunk/iterator/iterator.c
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
if(!iq->dp) {
|
||||
@@ -3095,6 +3149,61 @@
|
||||
@@ -3574,6 +3628,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+/**
|
||||
+ * ASN: Do final processing on responses to A queries originated from AAAA
|
||||
+ * queries. Events reach this state after the iterative resolution algorithm
|
||||
+ * terminates.
|
||||
@@ -246,7 +246,7 @@ Index: trunk/iterator/iterator.c
|
||||
/*
|
||||
* Return priming query results to interested super querystates.
|
||||
*
|
||||
@@ -3114,6 +3223,9 @@
|
||||
@@ -3593,6 +3702,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
|
||||
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
|
||||
super->minfo[id])->state == DSNS_FIND_STATE)
|
||||
processDSNSResponse(qstate, id, super);
|
||||
@@ -256,7 +256,7 @@ Index: trunk/iterator/iterator.c
|
||||
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
|
||||
error_supers(qstate, id, super);
|
||||
else if(qstate->is_priming)
|
||||
@@ -3151,6 +3263,9 @@
|
||||
@@ -3630,6 +3742,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
case INIT_REQUEST_3_STATE:
|
||||
cont = processInitRequest3(qstate, iq, id);
|
||||
break;
|
||||
@@ -266,7 +266,7 @@ Index: trunk/iterator/iterator.c
|
||||
case QUERYTARGETS_STATE:
|
||||
cont = processQueryTargets(qstate, iq, ie, id);
|
||||
break;
|
||||
@@ -3460,6 +3575,8 @@
|
||||
@@ -3961,6 +4076,8 @@ iter_state_to_string(enum iter_state state)
|
||||
return "INIT REQUEST STATE (stage 2)";
|
||||
case INIT_REQUEST_3_STATE:
|
||||
return "INIT REQUEST STATE (stage 3)";
|
||||
@@ -275,7 +275,7 @@ Index: trunk/iterator/iterator.c
|
||||
case QUERYTARGETS_STATE :
|
||||
return "QUERY TARGETS STATE";
|
||||
case PRIME_RESP_STATE :
|
||||
@@ -3484,6 +3601,7 @@
|
||||
@@ -3985,6 +4102,7 @@ iter_state_is_responsestate(enum iter_state s)
|
||||
case INIT_REQUEST_STATE :
|
||||
case INIT_REQUEST_2_STATE :
|
||||
case INIT_REQUEST_3_STATE :
|
||||
@@ -283,11 +283,11 @@ Index: trunk/iterator/iterator.c
|
||||
case QUERYTARGETS_STATE :
|
||||
case COLLECT_CLASS_STATE :
|
||||
return 0;
|
||||
Index: trunk/iterator/iterator.h
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.h (revision 4357)
|
||||
+++ trunk/iterator/iterator.h (working copy)
|
||||
@@ -130,6 +130,9 @@
|
||||
diff --git a/iterator/iterator.h b/iterator/iterator.h
|
||||
index 342ac207..731948d1 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -135,6 +135,9 @@ struct iter_env {
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
|
||||
@@ -297,10 +297,11 @@ Index: trunk/iterator/iterator.h
|
||||
/** lock on ratelimit counter */
|
||||
lock_basic_type queries_ratelimit_lock;
|
||||
/** number of queries that have been ratelimited */
|
||||
@@ -182,6 +185,14 @@
|
||||
@@ -186,6 +189,14 @@ enum iter_state {
|
||||
*/
|
||||
INIT_REQUEST_3_STATE,
|
||||
|
||||
/**
|
||||
+ /**
|
||||
+ * This state is responsible for intercepting AAAA queries,
|
||||
+ * and launch a A subquery on the same target, to populate the
|
||||
+ * cache with A records, so the AAAA filter scrubbing logic can
|
||||
@@ -308,29 +309,28 @@ Index: trunk/iterator/iterator.h
|
||||
+ */
|
||||
+ ASN_FETCH_A_FOR_AAAA_STATE,
|
||||
+
|
||||
+ /**
|
||||
/**
|
||||
* Each time a delegation point changes for a given query or a
|
||||
* query times out and/or wakes up, this state is (re)visited.
|
||||
* This state is responsible for iterating through a list of
|
||||
@@ -364,6 +375,13 @@
|
||||
* be used when creating the state. A higher one will be attempted.
|
||||
@@ -375,6 +386,13 @@ struct iter_qstate {
|
||||
*/
|
||||
int refetch_glue;
|
||||
+
|
||||
|
||||
+ /**
|
||||
+ * ASN: This is a flag that, if true, means that this query is
|
||||
+ * for fetching A records to populate cache and determine if we must
|
||||
+ * return AAAA records or not.
|
||||
+ */
|
||||
+ int fetch_a_for_aaaa;
|
||||
|
||||
+
|
||||
/** list of pending queries to authoritative servers. */
|
||||
struct outbound_list outlist;
|
||||
Index: trunk/pythonmod/interface.i
|
||||
===================================================================
|
||||
--- trunk/pythonmod/interface.i (revision 4357)
|
||||
+++ trunk/pythonmod/interface.i (working copy)
|
||||
@@ -851,6 +851,7 @@
|
||||
|
||||
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
|
||||
index f08b575d..47f1bb2e 100644
|
||||
--- a/pythonmod/interface.i
|
||||
+++ b/pythonmod/interface.i
|
||||
@@ -975,6 +975,7 @@ struct config_file {
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
@@ -338,11 +338,11 @@ Index: trunk/pythonmod/interface.i
|
||||
struct config_strlist* private_address;
|
||||
struct config_strlist* private_domain;
|
||||
size_t unwanted_threshold;
|
||||
Index: trunk/util/config_file.c
|
||||
===================================================================
|
||||
--- trunk/util/config_file.c (revision 4357)
|
||||
+++ trunk/util/config_file.c (working copy)
|
||||
@@ -195,6 +195,7 @@
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 0ab8614a..729fb147 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -218,6 +218,7 @@ config_create(void)
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->harden_algo_downgrade = 0;
|
||||
cfg->use_caps_bits_for_id = 0;
|
||||
@@ -350,11 +350,11 @@ Index: trunk/util/config_file.c
|
||||
cfg->caps_whitelist = NULL;
|
||||
cfg->private_address = NULL;
|
||||
cfg->private_domain = NULL;
|
||||
Index: trunk/util/config_file.h
|
||||
===================================================================
|
||||
--- trunk/util/config_file.h (revision 4357)
|
||||
+++ trunk/util/config_file.h (working copy)
|
||||
@@ -209,6 +209,8 @@
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index e61257a3..dabaa7bb 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -260,6 +260,8 @@ struct config_file {
|
||||
int harden_algo_downgrade;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
@@ -363,11 +363,11 @@ Index: trunk/util/config_file.h
|
||||
/** 0x20 whitelist, domains that do not use capsforid */
|
||||
struct config_strlist* caps_whitelist;
|
||||
/** strip away these private addrs from answers, no DNS Rebinding */
|
||||
Index: trunk/util/configlexer.lex
|
||||
===================================================================
|
||||
--- trunk/util/configlexer.lex (revision 4357)
|
||||
+++ trunk/util/configlexer.lex (working copy)
|
||||
@@ -279,6 +279,7 @@
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index 79a0edca..4eaec678 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -304,6 +304,7 @@ harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
|
||||
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
|
||||
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
|
||||
@@ -375,11 +375,11 @@ Index: trunk/util/configlexer.lex
|
||||
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
|
||||
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
|
||||
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
|
||||
Index: trunk/util/configparser.y
|
||||
===================================================================
|
||||
--- trunk/util/configparser.y (revision 4357)
|
||||
+++ trunk/util/configparser.y (working copy)
|
||||
@@ -95,6 +95,7 @@
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index 1d0e8658..f284dd43 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
||||
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
|
||||
@@ -387,7 +387,7 @@ Index: trunk/util/configparser.y
|
||||
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
||||
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||
@@ -203,6 +204,7 @@
|
||||
@@ -233,6 +234,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
||||
server_harden_referral_path | server_private_address |
|
||||
server_private_domain | server_extended_statistics |
|
||||
@@ -395,12 +395,10 @@ Index: trunk/util/configparser.y
|
||||
server_local_data_ptr | server_jostle_timeout |
|
||||
server_unwanted_reply_threshold | server_log_time_ascii |
|
||||
server_domain_insecure | server_val_sig_skew_min |
|
||||
@@ -1183,6 +1185,15 @@
|
||||
OUTYY(("P(server_caps_whitelist:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
|
||||
@@ -1563,6 +1565,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
|
||||
yyerror("out of memory");
|
||||
+ }
|
||||
+ ;
|
||||
}
|
||||
;
|
||||
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
|
||||
@@ -408,6 +406,8 @@ Index: trunk/util/configparser.y
|
||||
+ yyerror("expected yes or no.");
|
||||
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
|
||||
+ free($2);
|
||||
}
|
||||
;
|
||||
+ }
|
||||
+ ;
|
||||
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_private_address:%s)\n", $2));
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#### Android...
|
||||
#
|
||||
# Heavily hacked 15-android.conf based on OpenSSL's config file of the same name.
|
||||
# This 15-android.conf avoids compiler errors using NDK-r20. This 15-android.conf
|
||||
# requires an environment set (sourced) using setenv-android.sh.
|
||||
|
||||
my %targets = (
|
||||
"android" => {
|
||||
inherit_from => [ "linux-generic32" ],
|
||||
template => 1,
|
||||
bin_cflags => add("-fPIE"),
|
||||
bin_lflags => add("-pie"),
|
||||
enable => [ ],
|
||||
},
|
||||
|
||||
"android-arm" => {
|
||||
inherit_from => [ "android", asm("armv4_asm") ],
|
||||
bn_ops => [ "BN_LLONG", "RC4_CHAR" ],
|
||||
},
|
||||
"android-arm64" => {
|
||||
inherit_from => [ "android", asm("aarch64_asm") ],
|
||||
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_CHAR" ],
|
||||
perlasm_scheme => "linux64",
|
||||
},
|
||||
|
||||
"android-x86" => {
|
||||
inherit_from => [ "android", asm("x86_asm") ],
|
||||
cflags => add(picker(release => "-fomit-frame-pointer")),
|
||||
bn_ops => [ "BN_LLONG", "RC4_INT" ],
|
||||
perlasm_scheme => "android",
|
||||
},
|
||||
"android-x86_64" => {
|
||||
inherit_from => [ "android", asm("x86_64_asm") ],
|
||||
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_INT" ],
|
||||
perlasm_scheme => "elf",
|
||||
},
|
||||
);
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading Expat"
|
||||
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to download Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking Expat"
|
||||
rm -rf ./expat-2.2.9
|
||||
if ! tar -xf expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd expat-2.2.9 || exit 1
|
||||
|
||||
echo "Configuring Expat"
|
||||
if ! ./configure --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" --prefix="$ANDROID_PREFIX"; then
|
||||
echo "Error: Failed to configure Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
|
||||
echo "Fixing Makefiles"
|
||||
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
|
||||
do
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
done)
|
||||
|
||||
echo "Building Expat"
|
||||
if ! make; then
|
||||
echo "Failed to build Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Expat"
|
||||
if ! make install; then
|
||||
echo "Failed to install Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$ANDROID_SDK_ROOT" ]; then
|
||||
echo "ERROR: ANDROID_SDK_ROOT is not a valid path. Please set it."
|
||||
echo "SDK root is $ANDROID_SDK_ROOT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$ANDROID_NDK_ROOT" ]; then
|
||||
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
|
||||
echo "NDK root is $ANDROID_NDK_ROOT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using ANDROID_SDK_ROOT: $ANDROID_SDK_ROOT"
|
||||
echo "Using ANDROID_NDK_ROOT: $ANDROID_NDK_ROOT"
|
||||
|
||||
echo "Downloading SDK"
|
||||
if ! curl -L -k -s -o "$HOME/android-sdk.zip" https://dl.google.com/android/repository/commandlinetools-linux-6200805_latest.zip;
|
||||
then
|
||||
echo "Failed to download SDK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Downloading NDK"
|
||||
if ! curl -L -k -s -o "$HOME/android-ndk.zip" https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip;
|
||||
then
|
||||
echo "Failed to download NDK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking SDK to $ANDROID_SDK_ROOT"
|
||||
if ! unzip -qq "$HOME/android-sdk.zip" -d "$ANDROID_SDK_ROOT";
|
||||
then
|
||||
echo "Failed to unpack SDK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking NDK to $ANDROID_NDK_ROOT"
|
||||
if ! unzip -qq "$HOME/android-ndk.zip" -d "$HOME";
|
||||
then
|
||||
echo "Failed to unpack NDK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! mv "$HOME/android-ndk-r20b" "$ANDROID_NDK_ROOT";
|
||||
then
|
||||
echo "Failed to move $HOME/android-ndk-r20b to $ANDROID_NDK_ROOT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f "$HOME/android-sdk.zip"
|
||||
rm -f "$HOME/android-ndk.zip"
|
||||
|
||||
# https://stackoverflow.com/a/47028911/608639
|
||||
touch "$ANDROID_SDK_ROOT/repositories.cfg"
|
||||
|
||||
echo "Finished installing SDK and NDK"
|
||||
|
||||
exit 0
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading OpenSSL"
|
||||
if ! curl -L -k -s -o openssl-1.1.1d.tar.gz https://www.openssl.org/source/openssl-1.1.1d.tar.gz;
|
||||
then
|
||||
echo "Failed to download OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking OpenSSL"
|
||||
rm -rf ./openssl-1.1.1d
|
||||
if ! tar -xf openssl-1.1.1d.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd openssl-1.1.1d || exit 1
|
||||
|
||||
if ! cp ../contrib/android/15-android.conf Configurations/; then
|
||||
echo "Failed to copy OpenSSL Android config"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Configuring OpenSSL"
|
||||
if ! ./Configure "$OPENSSL_HOST" no-comp no-asm no-hw no-engine shared \
|
||||
--prefix="$ANDROID_PREFIX" --openssldir="$ANDROID_PREFIX"; then
|
||||
echo "Failed to configure OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building OpenSSL"
|
||||
if ! make; then
|
||||
echo "Failed to build OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing OpenSSL"
|
||||
if ! make install_sw; then
|
||||
echo "Failed to install OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This step should install tools needed for all packages - OpenSSL, Expat and Unbound
|
||||
echo "Updating tools"
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qq install --no-install-recommends curl tar zip unzip perl openjdk-8-jdk autoconf automake libtool pkg-config
|
||||
Executable
+203
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# ====================================================================
|
||||
# Sets the cross compile environment for Android
|
||||
#
|
||||
# Based upon OpenSSL's setenv-android.sh by TH, JW, and SM.
|
||||
# Heavily modified by JWW for Crypto++.
|
||||
# Updated by Skycoder42 for current recommendations for Android.
|
||||
# Modified by JWW for Unbound.
|
||||
# ====================================================================
|
||||
|
||||
#########################################
|
||||
##### Some validation #####
|
||||
#########################################
|
||||
|
||||
if [ -z "$ANDROID_API" ]; then
|
||||
echo "ANDROID_API is not set. Please set it"
|
||||
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
if [ -z "$ANDROID_CPU" ]; then
|
||||
echo "ANDROID_CPU is not set. Please set it"
|
||||
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$ANDROID_NDK_ROOT" ]; then
|
||||
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
|
||||
echo "NDK root is $ANDROID_NDK_ROOT"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# cryptest-android.sh may run this script without sourcing.
|
||||
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
|
||||
echo "setenv-android.sh is usually sourced, but not this time."
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
# Need to set THIS_HOST to darwin-x86_64, linux-x86_64,
|
||||
# windows, or windows-x86_64
|
||||
|
||||
if [[ "$(uname -s | grep -i -c darwin)" -ne 0 ]]; then
|
||||
THIS_HOST=darwin-x86_64
|
||||
elif [[ "$(uname -s | grep -i -c linux)" -ne 0 ]]; then
|
||||
THIS_HOST=linux-x86_64
|
||||
else
|
||||
echo "ERROR: Unknown host"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
ANDROID_TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/bin"
|
||||
ANDROID_SYSROOT="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/sysroot"
|
||||
|
||||
# Error checking
|
||||
if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
|
||||
echo "ERROR: ANDROID_TOOLCHAIN is not a valid path. Please set it."
|
||||
echo "Path is $ANDROID_TOOLCHAIN"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -d "$ANDROID_SYSROOT" ]; then
|
||||
echo "ERROR: ANDROID_SYSROOT is not a valid path. Please set it."
|
||||
echo "Path is $ANDROID_SYSROOT"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
THE_ARCH=$(tr '[:upper:]' '[:lower:]' <<< "$ANDROID_CPU")
|
||||
|
||||
# https://developer.android.com/ndk/guides/abis.html
|
||||
case "$THE_ARCH" in
|
||||
armv7*|armeabi*)
|
||||
CC="armv7a-linux-androideabi$ANDROID_API-clang"
|
||||
CXX="armv7a-linux-androideabi$ANDROID_API-clang++"
|
||||
LD="arm-linux-androideabi-ld"
|
||||
AS="arm-linux-androideabi-as"
|
||||
AR="arm-linux-androideabi-ar"
|
||||
RANLIB="arm-linux-androideabi-ranlib"
|
||||
STRIP="arm-linux-androideabi-strip"
|
||||
|
||||
CFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions"
|
||||
CXXFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions -frtti"
|
||||
;;
|
||||
|
||||
armv8*|aarch64|arm64*)
|
||||
CC="aarch64-linux-android$ANDROID_API-clang"
|
||||
CXX="aarch64-linux-android$ANDROID_API-clang++"
|
||||
LD="aarch64-linux-android-ld"
|
||||
AS="aarch64-linux-android-as"
|
||||
AR="aarch64-linux-android-ar"
|
||||
RANLIB="aarch64-linux-android-ranlib"
|
||||
STRIP="aarch64-linux-android-strip"
|
||||
|
||||
CFLAGS="-funwind-tables -fexceptions"
|
||||
CXXFLAGS="-funwind-tables -fexceptions -frtti"
|
||||
;;
|
||||
|
||||
x86)
|
||||
CC="i686-linux-android$ANDROID_API-clang"
|
||||
CXX="i686-linux-android$ANDROID_API-clang++"
|
||||
LD="i686-linux-android-ld"
|
||||
AS="i686-linux-android-as"
|
||||
AR="i686-linux-android-ar"
|
||||
RANLIB="i686-linux-android-ranlib"
|
||||
STRIP="i686-linux-android-strip"
|
||||
|
||||
CFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions"
|
||||
CXXFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
|
||||
;;
|
||||
|
||||
x86_64|x64)
|
||||
CC="x86_64-linux-android$ANDROID_API-clang"
|
||||
CXX="x86_64-linux-android$ANDROID_API-clang++"
|
||||
LD="x86_64-linux-android-ld"
|
||||
AS="x86_64-linux-android-as"
|
||||
AR="x86_64-linux-android-ar"
|
||||
RANLIB="x86_64-linux-android-ranlib"
|
||||
STRIP="x86_64-linux-android-strip"
|
||||
|
||||
CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions"
|
||||
CXXFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "ERROR: Unknown architecture $ANDROID_CPU"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#####################################################################
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$CC" ]; then
|
||||
echo "ERROR: Failed to find Android clang. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$CXX" ]; then
|
||||
echo "ERROR: Failed to find Android clang++. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$RANLIB" ]; then
|
||||
echo "ERROR: Failed to find Android ranlib. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$AR" ]; then
|
||||
echo "ERROR: Failed to find Android ar. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$AS" ]; then
|
||||
echo "ERROR: Failed to find Android as. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$ANDROID_TOOLCHAIN/$LD" ]; then
|
||||
echo "ERROR: Failed to find Android ld. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
LENGTH=${#ANDROID_TOOLCHAIN}
|
||||
SUBSTR=${PATH:0:$LENGTH}
|
||||
if [ "$SUBSTR" != "$ANDROID_TOOLCHAIN" ]; then
|
||||
export PATH="$ANDROID_TOOLCHAIN:$PATH"
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
export CPP CC CXX LD AS AR RANLIB STRIP
|
||||
export ANDROID_SYSROOT="$AOSP_SYSROOT"
|
||||
export CPPFLAGS="-D__ANDROID_API__=$ANDROID_API"
|
||||
export CFLAGS="$CFLAGS --sysroot=$AOSP_SYSROOT"
|
||||
export CXXFLAGS="$CXXFLAGS -stdlib=libc++ --sysroot=$AOSP_SYSROOT"
|
||||
|
||||
#####################################################################
|
||||
|
||||
echo "ANDROID_TOOLCHAIN: $ANDROID_TOOLCHAIN"
|
||||
|
||||
echo "CPP: $(command -v "$CPP")"
|
||||
echo "CC: $(command -v "$CC")"
|
||||
echo "CXX: $(command -v "$CXX")"
|
||||
echo "LD: $(command -v "$LD")"
|
||||
echo "AS: $(command -v "$AS")"
|
||||
echo "AR: $(command -v "$AR")"
|
||||
|
||||
echo "ANDROID_SYSROOT: $ANDROID_SYSROOT"
|
||||
|
||||
echo "CPPFLAGS: $CPPFLAGS"
|
||||
echo "CFLAGS: $CFLAGS"
|
||||
echo "CXXFLAGS: $CXXFLAGS"
|
||||
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
|
||||
@@ -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));
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
|
||||
#
|
||||
# unbound.conf:
|
||||
# rpz:
|
||||
# name: "spamhaus-drop.rpz.local."
|
||||
# zonefile: "/path/tp/spamhaus-drop.rpz.local"
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "spamhaus-drop"
|
||||
#
|
||||
|
||||
use strict;
|
||||
use vars qw{$o1 $o2 $o3 $o4 $m};
|
||||
|
||||
# trailing dots required
|
||||
my $origin = 'drop.spamhaus.org.rpz.local.';
|
||||
my $mname = 'localhost.';
|
||||
my $rname = 'root.localhost.';
|
||||
my $ns = $mname;
|
||||
|
||||
my $rpz_action = '.'; # return NXDOMAIN
|
||||
#my $rpz_action = '*.'; # return NODATA
|
||||
#my $rpz_action = 'rpz-drop.'; # drop the query
|
||||
|
||||
print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
|
||||
print "$origin NS $ns\n";
|
||||
while(<>) {
|
||||
if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
|
||||
print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
} else {
|
||||
print "$_";
|
||||
}
|
||||
}
|
||||
|
||||
# add a testpoint: ask for "dns.google"
|
||||
# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
|
||||
exit;
|
||||
+199
-205
@@ -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 bac212df..4824927f 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
|
||||
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
|
||||
DNSTAP_SRC=@DNSTAP_SRC@
|
||||
@@ -17,26 +13,26 @@ Index: unbound-1.7.0~rc1/Makefile.in
|
||||
+FASTRPZ_OBJ=@FASTRPZ_OBJ@
|
||||
DNSCRYPT_SRC=@DNSCRYPT_SRC@
|
||||
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
|
||||
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
|
||||
@@ -134,7 +136,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_
|
||||
@@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.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) $(DYNLIBMOD_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_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
|
||||
@@ -428,6 +430,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 f7a4095e..d5a4fa01 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -1364,4 +1364,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 5c373d9d..e45abd89 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,21 +73,21 @@ 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
|
||||
;;
|
||||
@@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
|
||||
esac
|
||||
|
||||
|
||||
+# check for Fastrpz with fastrpz/rpz.m4
|
||||
+ck_FASTRPZ
|
||||
+
|
||||
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 5d427925..f89f1437 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
|
||||
@@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
|
||||
fatal_exit("dt_create failed");
|
||||
#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)
|
||||
@@ -729,6 +740,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 3effbafb..4d4c34da 100644
|
||||
--- a/daemon/daemon.h
|
||||
+++ b/daemon/daemon.h
|
||||
@@ -138,6 +138,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 23e3244c..b63d49b7 100644
|
||||
--- a/daemon/worker.c
|
||||
+++ b/daemon/worker.c
|
||||
@@ -76,6 +76,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
|
||||
@@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
/* not secure */
|
||||
secure = 0;
|
||||
break;
|
||||
@@ -182,12 +178,12 @@ 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,
|
||||
secure = 0;
|
||||
@@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
} else *is_secure_answer = 0;
|
||||
+#ifdef ENABLE_FASTRPZ
|
||||
+ if(repinfo->rpz) {
|
||||
+ /* Scan the cached answer for RPZ hits.
|
||||
@@ -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*
|
||||
@@ -1436,6 +1475,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,14 +220,14 @@ 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:
|
||||
@@ -1486,12 +1534,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 */
|
||||
- if(answer_from_cache(worker, &qinfo,
|
||||
+ ret = answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &alias_rrset, &partial_rep,
|
||||
(struct reply_info*)e->data,
|
||||
cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
|
||||
&alias_rrset, &partial_rep, (struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
- &edns)) {
|
||||
@@ -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:
|
||||
@@ -1548,11 +1605,19 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
@@ -270,14 +266,14 @@ Index: unbound-1.7.0~rc1/daemon/worker.c
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/doc/unbound.conf.5.in
|
||||
+++ unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
@@ -1581,6 +1581,81 @@ It must be /96 or shorter. The default
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index cd43f04e..b92a1af8 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
+.SS "Response Policy Zone Rewriting"
|
||||
+.LP
|
||||
+Response policy zone rewriting is controlled with the
|
||||
@@ -356,10 +352,11 @@ Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
Index: unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
===================================================================
|
||||
diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
|
||||
new file mode 100644
|
||||
index 00000000..645279d1
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
+++ b/fastrpz/librpz.h
|
||||
@@ -0,0 +1,957 @@
|
||||
+/*
|
||||
+ * Define the interface from a DNS resolver to the Response Policy Zone
|
||||
@@ -1318,11 +1315,12 @@ Index: unbound-1.7.0~rc1/fastrpz/librpz.h
|
||||
+#endif /* LIBRPZ_LIB_OPEN */
|
||||
+
|
||||
+#endif /* LIBRPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
|
||||
new file mode 100644
|
||||
index 00000000..c5ab7801
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
@@ -0,0 +1,1357 @@
|
||||
+++ b/fastrpz/rpz.c
|
||||
@@ -0,0 +1,1352 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
|
||||
+ *
|
||||
@@ -1438,8 +1436,6 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+static void
|
||||
+log_fnc(librpz_log_level_t level, void* ATTR_UNUSED(ctx), const char* buf)
|
||||
+{
|
||||
+ char label_buf[sizeof("rpz ")+8];
|
||||
+
|
||||
+ /* Setting librpz_log_level overrides the unbound "verbose" level. */
|
||||
+ if(level > LIBRPZ_LOG_TRACE1 &&
|
||||
+ level <= librpz->log_level_val(LIBRPZ_LOG_INVALID))
|
||||
@@ -1949,12 +1945,9 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+ case st_ck_ns:
|
||||
+ /* An NSDNAME or NSIP check failed for lack of cached data. */
|
||||
+ return false;
|
||||
+#pragma clang diagnostic push
|
||||
+#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
+ default:
|
||||
+ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
|
||||
+ rpz->st);
|
||||
+#pragma clang diagnostic pop
|
||||
+ }
|
||||
+
|
||||
+ /* Wait for a trigger. */
|
||||
@@ -2680,10 +2673,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.c
|
||||
+}
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
|
||||
new file mode 100644
|
||||
index 00000000..5d7e31c5
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
+++ b/fastrpz/rpz.h
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
|
||||
@@ -2823,10 +2817,11 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.h
|
||||
+
|
||||
+#endif /* ENABLE_FASTRPZ */
|
||||
+#endif /* UNBOUND_FASTRPZ_RPZ_H */
|
||||
Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
===================================================================
|
||||
diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
|
||||
new file mode 100644
|
||||
index 00000000..21235355
|
||||
--- /dev/null
|
||||
+++ unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
+++ b/fastrpz/rpz.m4
|
||||
@@ -0,0 +1,64 @@
|
||||
+# fastrpz/rpz.m4
|
||||
+
|
||||
@@ -2892,10 +2887,10 @@ Index: unbound-1.7.0~rc1/fastrpz/rpz.m4
|
||||
+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
|
||||
+ fi
|
||||
+])
|
||||
Index: unbound-1.7.0~rc1/iterator/iterator.c
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/iterator/iterator.c
|
||||
+++ unbound-1.7.0~rc1/iterator/iterator.c
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 23b07ea9..c3d31a33 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;
|
||||
@@ -563,6 +566,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
|
||||
@@ -571,6 +591,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*
|
||||
@@ -1231,6 +1254,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*
|
||||
@@ -1317,8 +1341,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*
|
||||
@@ -1326,7 +1349,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
|
||||
@@ -2801,6 +2839,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
|
||||
@@ -3563,12 +3657,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 342ac207..49b0ecdd 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -396,6 +396,16 @@ struct iter_qstate {
|
||||
*/
|
||||
int minimise_count;
|
||||
|
||||
@@ -3109,12 +3104,12 @@ 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,
|
||||
* the QNAME minimisation QTYPE is blocked. Used to determine if
|
||||
diff --git a/services/cache/dns.c b/services/cache/dns.c
|
||||
index 7b6e142c..6d7449f5 100644
|
||||
--- a/services/cache/dns.c
|
||||
+++ b/services/cache/dns.c
|
||||
@@ -969,6 +969,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 4b0c5db4..eb9cfa5b 100644
|
||||
--- a/services/mesh.c
|
||||
+++ b/services/mesh.c
|
||||
@@ -61,6 +61,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
|
||||
@@ -1207,6 +1210,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
|
||||
@@ -1434,6 +1444,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
|
||||
@@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
if(!r)
|
||||
return 0;
|
||||
r->query_reply = *rep;
|
||||
@@ -3176,24 +3171,24 @@ 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)
|
||||
free(cfg->dnstap_socket_path);
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 0e9ee471..a5fd72e0 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_tls_client_cert_file);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
+ if (cfg->rpz_cstr)
|
||||
+ 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 66e5025d..504f4f92 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -522,6 +522,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 83cea4b9..9a7feea4 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -467,6 +467,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,19 +3215,19 @@ 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 fe600a99..ce43390f 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -128,6 +128,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
|
||||
+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
|
||||
%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
|
||||
%token VAR_IP_DSCP
|
||||
@@ -179,7 +180,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);
|
||||
@@ -2939,6 +2940,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 be69f628..f10773aa 100644
|
||||
--- a/util/data/msgencode.c
|
||||
+++ b/util/data/msgencode.c
|
||||
@@ -592,6 +592,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;
|
||||
@@ -779,6 +808,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 4b0294f9..3b3838f6 100644
|
||||
--- a/util/data/packed_rrset.c
|
||||
+++ b/util/data/packed_rrset.c
|
||||
@@ -256,6 +256,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 729877ba..ccd1a0c2 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 3e7a433e..f20d806f 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
|
||||
@@ -596,6 +599,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
|
||||
@@ -685,6 +691,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
|
||||
@@ -728,6 +737,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);
|
||||
@@ -3175,6 +3187,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*
|
||||
@@ -3184,6 +3199,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)
|
||||
@@ -3205,6 +3223,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 bb2cd1e5..666067e8 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 c3ca0a27..15251988 100644
|
||||
--- a/validator/validator.c
|
||||
+++ b/validator/validator.c
|
||||
@@ -2761,6 +2761,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*
|
||||
@@ -2794,6 +2800,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
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#### iPhoneOS/iOS
|
||||
#
|
||||
# It takes recent enough Xcode to use following two targets. It shouldn't
|
||||
# be a problem by now, but if they don't work, original targets below
|
||||
# that depend on manual definition of environment variables should still
|
||||
# work...
|
||||
#
|
||||
my %targets = (
|
||||
"ios-common" => {
|
||||
template => 1,
|
||||
inherit_from => [ "darwin-common" ],
|
||||
sys_id => "iOS",
|
||||
disable => [ "engine", "async" ],
|
||||
},
|
||||
"ios-xcrun" => {
|
||||
inherit_from => [ "ios-common", asm("armv4_asm") ],
|
||||
bn_ops => [ "BN_LLONG", "RC4_CHAR" ],
|
||||
perlasm_scheme => "ios32",
|
||||
},
|
||||
"ios64-xcrun" => {
|
||||
inherit_from => [ "ios-common", asm("aarch64_asm") ],
|
||||
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_CHAR" ],
|
||||
perlasm_scheme => "ios64",
|
||||
},
|
||||
"iossimulator-xcrun" => {
|
||||
inherit_from => [ "ios-common" ],
|
||||
},
|
||||
|
||||
"iphoneos-cross" => {
|
||||
inherit_from => [ "ios-common" ],
|
||||
cflags => add("-Wall -fno-common"),
|
||||
},
|
||||
"ios-cross" => {
|
||||
inherit_from => [ "ios-xcrun" ],
|
||||
cflags => add("-Wall -fno-common"),
|
||||
},
|
||||
"ios64-cross" => {
|
||||
inherit_from => [ "ios64-xcrun" ],
|
||||
cflags => add("-Wall -fno-common"),
|
||||
},
|
||||
);
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading Expat"
|
||||
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to download Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking Expat"
|
||||
rm -rf ./expat-2.2.9
|
||||
if ! tar -xf expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd expat-2.2.9 || exit 1
|
||||
|
||||
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
|
||||
|
||||
echo "Configuring Expat"
|
||||
if ! ./configure \
|
||||
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$IOS_PREFIX" ; then
|
||||
echo "Error: Failed to configure Expat"
|
||||
cat config.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
|
||||
echo "Fixing Makefiles"
|
||||
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
|
||||
do
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
done)
|
||||
|
||||
echo "Building Expat"
|
||||
if ! make; then
|
||||
echo "Failed to build Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Expat"
|
||||
if ! make install; then
|
||||
echo "Failed to install Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading OpenSSL"
|
||||
if ! curl -L -k -s -o openssl-1.1.1d.tar.gz https://www.openssl.org/source/openssl-1.1.1d.tar.gz;
|
||||
then
|
||||
echo "Failed to download OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking OpenSSL"
|
||||
rm -rf ./openssl-1.1.1d
|
||||
if ! tar -xf openssl-1.1.1d.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd openssl-1.1.1d || exit 1
|
||||
|
||||
if ! cp ../contrib/ios/15-ios.conf Configurations/; then
|
||||
echo "Failed to copy OpenSSL ios config"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# OpenSSL 1.1.1d patch. OK to remove once OpenSSL version is bumped.
|
||||
# ocsp.c:947:23: error: 'fork' is unavailable: not available on tvOS and watchOS.
|
||||
# Also see https://github.com/openssl/openssl/issues/7607.
|
||||
if ! patch -u -p0 < ../contrib/ios/openssl.patch; then
|
||||
echo "Failed to patch OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Configuring OpenSSL"
|
||||
if ! ./Configure "$OPENSSL_HOST" -DNO_FORK no-comp no-asm no-hw no-engine no-tests no-unit-test \
|
||||
--prefix="$IOS_PREFIX" --openssldir="$IOS_PREFIX"; then
|
||||
echo "Failed to configure OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building OpenSSL"
|
||||
if ! make; then
|
||||
echo "Failed to build OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing OpenSSL"
|
||||
if ! make install_sw; then
|
||||
echo "Failed to install OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This step should install tools needed for all packages - OpenSSL, Expat and Unbound
|
||||
echo "Updating tools"
|
||||
brew update 1>/dev/null
|
||||
echo "Installing tools"
|
||||
# already installed are: autoconf automake libtool pkg-config
|
||||
brew install curl perl 1>/dev/null
|
||||
@@ -0,0 +1,48 @@
|
||||
--- apps/speed.c
|
||||
+++ apps/speed.c
|
||||
@@ -99,6 +99,13 @@
|
||||
#endif
|
||||
#include <openssl/modes.h>
|
||||
|
||||
+/* fork() breaks AppleTVOS, WatchOS, AppleTVSimulator and WatchSimulator */
|
||||
+/* Users should configure with -DNO_FORK */
|
||||
+#if defined(NO_FORK)
|
||||
+# undef HAVE_FORK
|
||||
+# define HAVE_FORK 0
|
||||
+#endif
|
||||
+
|
||||
#ifndef HAVE_FORK
|
||||
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
|
||||
# define HAVE_FORK 0
|
||||
@@ -110,6 +117,7 @@
|
||||
#if HAVE_FORK
|
||||
# undef NO_FORK
|
||||
#else
|
||||
+# undef NO_FORK
|
||||
# define NO_FORK
|
||||
#endif
|
||||
|
||||
--- apps/ocsp.c
|
||||
+++ apps/ocsp.c
|
||||
@@ -36,6 +36,13 @@
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/rand.h>
|
||||
|
||||
+/* fork() breaks AppleTVOS, WatchOS, AppleTVSimulator and WatchSimulator */
|
||||
+/* Users should configure with -DNO_FORK */
|
||||
+#if defined(NO_FORK)
|
||||
+# undef HAVE_FORK
|
||||
+# define HAVE_FORK 0
|
||||
+#endif
|
||||
+
|
||||
#ifndef HAVE_FORK
|
||||
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
|
||||
# define HAVE_FORK 0
|
||||
@@ -47,6 +54,7 @@
|
||||
#if HAVE_FORK
|
||||
# undef NO_FORK
|
||||
#else
|
||||
+# undef NO_FORK
|
||||
# define NO_FORK
|
||||
#endif
|
||||
|
||||
Executable
+274
@@ -0,0 +1,274 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# ====================================================================
|
||||
# Sets the cross compile environment for Xcode/iOS
|
||||
#
|
||||
# Based upon OpenSSL's setenv-ios.sh by TH, JW, and SM.
|
||||
# Heavily modified by JWW for Crypto++.
|
||||
# Modified by JWW for Unbound.
|
||||
# ====================================================================
|
||||
|
||||
#########################################
|
||||
##### Some validation #####
|
||||
#########################################
|
||||
|
||||
# In the past we could mostly infer arch or cpu from the SDK (and
|
||||
# mostly vice-versa). Nowadays we need it set for us because Apple
|
||||
# platforms can be either 32-bit or 64-bit.
|
||||
|
||||
if [ -z "$IOS_SDK" ]; then
|
||||
echo "IOS_SDK is not set. Please set it"
|
||||
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
if [ -z "$IOS_CPU" ]; then
|
||||
echo "IOS_CPU is not set. Please set it"
|
||||
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# cryptest-ios.sh may run this script without sourcing.
|
||||
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
|
||||
echo "setenv-ios.sh is usually sourced, but not this time."
|
||||
fi
|
||||
|
||||
#########################################
|
||||
##### Small Fixups, if needed #####
|
||||
#########################################
|
||||
|
||||
if [[ "$IOS_SDK" == "iPhone" ]]; then
|
||||
IOS_SDK=iPhoneOS
|
||||
fi
|
||||
|
||||
if [[ "$IOS_SDK" == "iPhoneOSSimulator" ]]; then
|
||||
IOS_SDK=iPhoneSimulator
|
||||
fi
|
||||
|
||||
if [[ "$IOS_SDK" == "TV" || "$IOS_SDK" == "AppleTV" ]]; then
|
||||
IOS_SDK=AppleTVOS
|
||||
fi
|
||||
|
||||
if [[ "$IOS_SDK" == "Watch" || "$IOS_SDK" == "AppleWatch" ]]; then
|
||||
IOS_SDK=WatchOS
|
||||
fi
|
||||
|
||||
if [[ "$IOS_CPU" == "aarch64" || "$IOS_CPU" == "armv8"* ]] ; then
|
||||
IOS_CPU=arm64
|
||||
fi
|
||||
|
||||
########################################
|
||||
##### Environment #####
|
||||
########################################
|
||||
|
||||
# The flags below were tested with Xcode 8 on Travis. If
|
||||
# you use downlevel versions of Xcode, then you can push
|
||||
# xxx-version-min=n lower. For example, Xcode 6 can use
|
||||
# -miphoneos-version-min=5.
|
||||
|
||||
# iPhones can be either 32-bit or 64-bit
|
||||
if [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "armv7"* ]]; then
|
||||
MIN_VER=-miphoneos-version-min=6
|
||||
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "arm64" ]]; then
|
||||
MIN_VER=-miphoneos-version-min=6
|
||||
|
||||
# Fixups for convenience
|
||||
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "i386" ]]; then
|
||||
IOS_SDK=iPhoneSimulator
|
||||
# MIN_VER=-miphoneos-version-min=6
|
||||
MIN_VER=-miphonesimulator-version-min=6
|
||||
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "x86_64" ]]; then
|
||||
IOS_SDK=iPhoneSimulator
|
||||
# MIN_VER=-miphoneos-version-min=6
|
||||
MIN_VER=-miphonesimulator-version-min=6
|
||||
|
||||
# Simulator builds
|
||||
elif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "i386" ]]; then
|
||||
MIN_VER=-miphonesimulator-version-min=6
|
||||
elif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "x86_64" ]]; then
|
||||
MIN_VER=-miphonesimulator-version-min=6
|
||||
|
||||
# Apple TV can be 32-bit Intel (1st gen), 32-bit ARM (2nd, 3rd gen) or 64-bit ARM (4th gen)
|
||||
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "i386" ]]; then
|
||||
MIN_VER=-mappletvos-version-min=6
|
||||
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "armv7"* ]]; then
|
||||
MIN_VER=-mappletvos-version-min=6
|
||||
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "arm64" ]]; then
|
||||
MIN_VER=-mappletvos-version-min=6
|
||||
|
||||
# Simulator builds
|
||||
elif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "i386" ]]; then
|
||||
MIN_VER=-mappletvsimulator-version-min=6
|
||||
elif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "x86_64" ]]; then
|
||||
MIN_VER=-mappletvsimulator-version-min=6
|
||||
|
||||
# Watch can be either 32-bit or 64-bit ARM. TODO: figure out which
|
||||
# -mwatchos-version-min=n is needed for arm64. 9 is not enough.
|
||||
elif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "armv7"* ]]; then
|
||||
MIN_VER=-mwatchos-version-min=6
|
||||
elif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "arm64" ]]; then
|
||||
MIN_VER=-mwatchos-version-min=10
|
||||
|
||||
# Simulator builds. TODO: figure out which -watchos-version-min=n
|
||||
# is needed for arm64. 6 compiles and links, but is it correct?
|
||||
elif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "i386" ]]; then
|
||||
MIN_VER=-mwatchsimulator-version-min=6
|
||||
elif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "x86_64" ]]; then
|
||||
MIN_VER=-mwatchsimulator-version-min=6
|
||||
|
||||
# And the final catch-all
|
||||
else
|
||||
echo "IOS_SDK and IOS_CPU are not valid. Please fix them"
|
||||
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
# Xcode 6 and below cannot handle -miphonesimulator-version-min
|
||||
# Fix it so the simulator will compile as expected. This trick
|
||||
# may work on other SDKs, but it was not tested.
|
||||
|
||||
if [ -n "$(command -v xcodebuild 2>/dev/null)" ]; then
|
||||
# Output of xcodebuild is similar to "Xcode 6.2". The first cut gets
|
||||
# the dotted decimal value. The second cut gets the major version.
|
||||
XCODE_VERSION=$(xcodebuild -version 2>/dev/null | head -n 1 | cut -f2 -d" " | cut -f1 -d".")
|
||||
if [ -z "$XCODE_VERSION" ]; then XCODE_VERSION=100; fi
|
||||
|
||||
if [ "$XCODE_VERSION" -le 6 ]; then
|
||||
MIN_VER="${MIN_VER//iphonesimulator/iphoneos}"
|
||||
fi
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
# Allow a user override? I think we should be doing this. The use case is,
|
||||
# move /Applications/Xcode somewhere else for a side-by-side installation.
|
||||
if [ -z "${XCODE_DEVELOPER-}" ]; then
|
||||
XCODE_DEVELOPER=$(xcode-select -print-path 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [ ! -d "$XCODE_DEVELOPER" ]; then
|
||||
echo "ERROR: unable to find XCODE_DEVELOPER directory."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# XCODE_DEVELOPER_SDK is the SDK location.
|
||||
XCODE_DEVELOPER_SDK="$XCODE_DEVELOPER/Platforms/$IOS_SDK.platform"
|
||||
|
||||
if [ ! -d "$XCODE_DEVELOPER_SDK" ]; then
|
||||
echo "ERROR: unable to find XCODE_DEVELOPER_SDK directory."
|
||||
echo " Is the SDK supported by Xcode and installed?"
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# XCODE_TOOLCHAIN is the location of the actual compiler tools.
|
||||
if [ -d "$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/" ]; then
|
||||
XCODE_TOOLCHAIN="$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/"
|
||||
elif [ -d "$XCODE_DEVELOPER_SDK/Developer/usr/bin/" ]; then
|
||||
XCODE_TOOLCHAIN="$XCODE_DEVELOPER_SDK/Developer/usr/bin/"
|
||||
fi
|
||||
|
||||
if [ -z "$XCODE_TOOLCHAIN" ] || [ ! -d "$XCODE_TOOLCHAIN" ]; then
|
||||
echo "ERROR: unable to find Xcode cross-compiler tools."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# XCODE_SDK is the SDK name/version being used - adjust the list as appropriate.
|
||||
# For example, remove 4.3, 6.2, and 6.1 if they are not installed. We go back to
|
||||
# the 1.0 SDKs because Apple WatchOS uses low numbers, like 2.0 and 2.1.
|
||||
XCODE_SDK=
|
||||
for i in $(seq -f "%.1f" 30.0 -0.1 1.0)
|
||||
do
|
||||
if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then
|
||||
XCODE_SDK="$IOS_SDK$i.sdk"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Error checking
|
||||
if [ -z "$XCODE_SDK" ]; then
|
||||
echo "ERROR: unable to find a SDK."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
IOS_SYSROOT="$XCODE_DEVELOPER_SDK/Developer/SDKs/$XCODE_SDK"
|
||||
|
||||
if [ -z "$IOS_SYSROOT" ] || [ ! -d "$IOS_SYSROOT" ]; then
|
||||
echo "ERROR: unable to find IOS_SYSROOT directory."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
# We want to set AR=libtool and ARFLAGS="-static -o",
|
||||
# but I am not sure Autotools can handle it.
|
||||
CPP=cpp; CC=clang; CXX=clang++; LD=ld
|
||||
AS=as; AR=ar; RANLIB=ranlib; STRIP=strip
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$CC" ]; then
|
||||
echo "ERROR: Failed to find iOS clang. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$CXX" ]; then
|
||||
echo "ERROR: Failed to find iOS clang++. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$RANLIB" ]; then
|
||||
echo "ERROR: Failed to find iOS ranlib. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$AR" ]; then
|
||||
echo "ERROR: Failed to find iOS ar. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$AS" ]; then
|
||||
echo "ERROR: Failed to find iOS as. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$LD" ]; then
|
||||
echo "ERROR: Failed to find iOS ld. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
LENGTH=${#XCODE_TOOLCHAIN}
|
||||
SUBSTR=${PATH:0:$LENGTH}
|
||||
if [ "$SUBSTR" != "$XCODE_TOOLCHAIN" ]; then
|
||||
export PATH="$XCODE_TOOLCHAIN":"$PATH"
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
export CPP CC CXX LD AS AR RANLIB STRIP
|
||||
export IOS_SYSROOT
|
||||
export CFLAGS="-arch $IOS_CPU $MIN_VER --sysroot=$IOS_SYSROOT"
|
||||
export CXXFLAGS="-arch $IOS_CPU $MIN_VER -stdlib-libc++ --sysroot=$IOS_SYSROOT"
|
||||
|
||||
#####################################################################
|
||||
|
||||
echo "XCODE_TOOLCHAIN: $XCODE_TOOLCHAIN"
|
||||
|
||||
echo "CPP: $(command -v "$CPP")"
|
||||
echo "CC: $(command -v "$CC")"
|
||||
echo "CXX: $(command -v "$CXX")"
|
||||
echo "LD: $(command -v "$LD")"
|
||||
echo "AS: $(command -v "$AS")"
|
||||
echo "AR: $(command -v "$AR")"
|
||||
|
||||
echo "IOS_SYSROOT: $IOS_SYSROOT"
|
||||
|
||||
echo "CPPFLAGS: $CPPFLAGS"
|
||||
echo "CFLAGS: $CFLAGS"
|
||||
echo "CXXFLAGS: $CXXFLAGS"
|
||||
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
|
||||
@@ -7,7 +7,7 @@ Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound -lssl -lcrypto
|
||||
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# read output of unbound-control stats
|
||||
# and output prometheus metrics style output.
|
||||
# use these options:
|
||||
# server: extended-statistics: yes
|
||||
# statistics-cumulative: no
|
||||
# statistics-interval: 0
|
||||
# remote-control: control-enable: yes
|
||||
# Can use it like unbound-control stats | awk -f "metrics.awk"
|
||||
|
||||
BEGIN {
|
||||
FS="=";
|
||||
}
|
||||
# everything like total.num.queries=value is put in val["total.num.queries"]
|
||||
/^.*\..*=/ {
|
||||
val[$1]=$2;
|
||||
}
|
||||
# print the output metrics
|
||||
END {
|
||||
print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
|
||||
print "# TYPE unbound_hits_queries gauge"
|
||||
print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
|
||||
for (x=0; x<99; x++) {
|
||||
if(val["thread" $x ".num.queries"] != "") {
|
||||
print "unbound_hits_queries{type=\"thread" $x ".num.queries\"} " val["thread" $x ".num.queries"];
|
||||
}
|
||||
}
|
||||
print "unbound_hits_queries{type=\"total.num.cachehits\"} " val["total.num.cachehits"];
|
||||
print "unbound_hits_queries{type=\"total.num.prefetch\"} " val["total.num.prefetch"];
|
||||
print "unbound_hits_queries{type=\"num.query.tcp\"} " val["num.query.tcp"];
|
||||
print "unbound_hits_queries{type=\"num.query.tcpout\"} " val["num.query.tcpout"];
|
||||
print "unbound_hits_queries{type=\"num.query.tls\"} " val["num.query.tls"];
|
||||
print "unbound_hits_queries{type=\"num.query.tls.resume\"} " val["num.query.tls.resume"];
|
||||
print "unbound_hits_queries{type=\"num.query.ipv6\"} " val["num.query.ipv6"];
|
||||
print "unbound_hits_queries{type=\"unwanted.queries\"} " val["unwanted.queries"];
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_queue_queries Unbound requestlist size"
|
||||
print "# TYPE unbound_queue_queries gauge"
|
||||
print "unbound_queue_queries{type=\"total.requestlist.avg\"} " val["total.requestlist.avg"];
|
||||
print "unbound_queue_queries{type=\"total.requestlist.max\"} " val["total.requestlist.max"];
|
||||
print "unbound_queue_queries{type=\"total.requestlist.overwritten\"} " val["total.requestlist.overwritten"];
|
||||
print "unbound_queue_queries{type=\"total.requestlist.exceeded\"} " val["total.requestlist.exceeded"];
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_memory_bytes Unbound memory usage"
|
||||
print "# TYPE unbound_memory_bytes gauge"
|
||||
print "unbound_memory_bytes{type=\"mem.cache.rrset\"} " val["mem.cache.rrset"];
|
||||
print "unbound_memory_bytes{type=\"mem.cache.message\"} " val["mem.cache.message"];
|
||||
print "unbound_memory_bytes{type=\"mem.mod.iterator\"} " val["mem.mod.iterator"];
|
||||
if(val["mem.mod.validator"] != "") {
|
||||
print "unbound_memory_bytes{type=\"mem.mod.validator\"} " val["mem.mod.validator"];
|
||||
}
|
||||
if(val["mem.mod.respip"] != "") {
|
||||
print "unbound_memory_bytes{type=\"mem.mod.respip\"} " val["mem.mod.respip"];
|
||||
}
|
||||
if(val["mem.mod.subnet"] != "") {
|
||||
print "unbound_memory_bytes{type=\"mem.mod.subnet\"} " val["mem.mod.subnet"];
|
||||
}
|
||||
if(val["mem.mod.ipsecmod"] != "") {
|
||||
print "unbound_memory_bytes{type=\"mem.mod.ipsecmod\"} " val["mem.mod.ipsecmod"];
|
||||
}
|
||||
if(val["mem.mod.dynlibmod"] != "") {
|
||||
print "unbound_memory_bytes{type=\"mem.mod.dynlibmod\"} " val["mem.mod.dynlibmod"];
|
||||
}
|
||||
print "unbound_memory_bytes{type=\"msg.cache.count\"} " val["msg.cache.count"];
|
||||
print "unbound_memory_bytes{type=\"rrset.cache.count\"} " val["rrset.cache.count"];
|
||||
print "unbound_memory_bytes{type=\"infra.cache.count\"} " val["infra.cache.count"];
|
||||
print "unbound_memory_bytes{type=\"key.cache.count\"} " val["key.cache.count"];
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_type_queries Unbound DNS queries by type"
|
||||
print "# TYPE unbound_by_type_queries gauge"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.type./) {
|
||||
if(val[x] != "") {
|
||||
split(x, a, ".");
|
||||
print "unbound_by_type_queries{type=\"" a[4] "\"} " val[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_class_queries Unbound DNS queries by class"
|
||||
print "# TYPE unbound_by_class_queries gauge"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.class./) {
|
||||
if(val[x] != "") {
|
||||
split(x, a, ".");
|
||||
print "unbound_by_class_queries{class=\"" a[4] "\"} " val[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
|
||||
print "# TYPE unbound_by_opcode_queries gauge"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.opcode./) {
|
||||
if(val[x] != "") {
|
||||
split(x, a, ".");
|
||||
print "unbound_by_opcode_queries{opcode=\"" a[4] "\"} " val[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
|
||||
print "# TYPE unbound_by_rcode_queries gauge"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.answer.rcode./) {
|
||||
if(val[x] != "") {
|
||||
split(x, a, ".");
|
||||
print "unbound_by_rcode_queries{rcode=\"" a[4] "\"} " val[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
|
||||
print "# TYPE unbound_by_flags_queries gauge"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.flags./) {
|
||||
if(val[x] != "") {
|
||||
split(x, a, ".");
|
||||
print "unbound_by_flags_queries{flag=\"" a[4] "\"} " val[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
if(val["num.query.edns.present"] != "") {
|
||||
print "unbound_by_flags_queries{flag=\"num.query.edns.present\"} " val["num.query.edns.present"];
|
||||
}
|
||||
if(val["num.query.edns.DO"] != "") {
|
||||
print "unbound_by_flags_queries{flag=\"num.query.edns.DO\"} " val["num.query.edns.DO"];
|
||||
}
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
|
||||
print "# TYPE unbound_histogram_seconds gauge"
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000004.to.000000.000008\"} " val["histogram.000000.000004.to.000000.000008"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000008.to.000000.000016\"} " val["histogram.000000.000008.to.000000.000016"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000016.to.000000.000032\"} " val["histogram.000000.000016.to.000000.000032"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000032.to.000000.000064\"} " val["histogram.000000.000032.to.000000.000064"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000064.to.000000.000128\"} " val["histogram.000000.000064.to.000000.000128"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000128.to.000000.000256\"} " val["histogram.000000.000128.to.000000.000256"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000256.to.000000.000512\"} " val["histogram.000000.000256.to.000000.000512"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000512.to.000000.001024\"} " val["histogram.000000.000512.to.000000.001024"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.001024.to.000000.002048\"} " val["histogram.000000.001024.to.000000.002048"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.002048.to.000000.004096\"} " val["histogram.000000.002048.to.000000.004096"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.004096.to.000000.008192\"} " val["histogram.000000.004096.to.000000.008192"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.008192.to.000000.016384\"} " val["histogram.000000.008192.to.000000.016384"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.016384.to.000000.032768\"} " val["histogram.000000.016384.to.000000.032768"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.032768.to.000000.065536\"} " val["histogram.000000.032768.to.000000.065536"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.065536.to.000000.131072\"} " val["histogram.000000.065536.to.000000.131072"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.131072.to.000000.262144\"} " val["histogram.000000.131072.to.000000.262144"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.262144.to.000000.524288\"} " val["histogram.000000.262144.to.000000.524288"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.524288.to.000001.000000\"} " val["histogram.000000.524288.to.000001.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000001.000000.to.000002.000000\"} " val["histogram.000001.000000.to.000002.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000002.000000.to.000004.000000\"} " val["histogram.000002.000000.to.000004.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000004.000000.to.000008.000000\"} " val["histogram.000004.000000.to.000008.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000008.000000.to.000016.000000\"} " val["histogram.000008.000000.to.000016.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000016.000000.to.000032.000000\"} " val["histogram.000016.000000.to.000032.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000032.000000.to.000064.000000\"} " val["histogram.000032.000000.to.000064.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000064.000000.to.000128.000000\"} " val["histogram.000064.000000.to.000128.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000128.000000.to.000256.000000\"} " val["histogram.000128.000000.to.000256.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000256.000000.to.000512.000000\"} " val["histogram.000256.000000.to.000512.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"000512.000000.to.001024.000000\"} " val["histogram.000512.000000.to.001024.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"001024.000000.to.002048.000000\"} " val["histogram.001024.000000.to.002048.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"002048.000000.to.004096.000000\"} " val["histogram.002048.000000.to.004096.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"004096.000000.to.008192.000000\"} " val["histogram.004096.000000.to.008192.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"008192.000000.to.016384.000000\"} " val["histogram.008192.000000.to.016384.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"016384.000000.to.032768.000000\"} " val["histogram.016384.000000.to.032768.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"032768.000000.to.065536.000000\"} " val["histogram.032768.000000.to.065536.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"065536.000000.to.131072.000000\"} " val["histogram.065536.000000.to.131072.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"131072.000000.to.262144.000000\"} " val["histogram.131072.000000.to.262144.000000"];
|
||||
print "unbound_histogram_seconds{bucket=\"262144.000000.to.524288.000000\"} " val["histogram.262144.000000.to.524288.000000"];
|
||||
print ""
|
||||
}
|
||||
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
|
||||
|
||||
@@ -1,16 +1,60 @@
|
||||
; For further details about the directives used in this unit file, including
|
||||
; the below, please refer to systemd's official documentation, available at
|
||||
; https://www.freedesktop.org/software/systemd/man/systemd.exec.html.
|
||||
;
|
||||
;
|
||||
; - `ProtectSystem=strict` implies we mount the entire file system hierarchy
|
||||
; read-only for the processes invoked by the unit except for the API file
|
||||
; system subtrees /dev, /proc and /sys (which are protected by
|
||||
; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=).
|
||||
;
|
||||
; - `PrivateTmp=yes` secures access to temporary files of the process, and
|
||||
; makes sharing between processes via /tmp or /var/tmp impossible.
|
||||
;
|
||||
; - `ProtectHome=yes` makes the directories /home, /root, and /run/user
|
||||
; inaccessible and empty for processes invoked by the unit.
|
||||
;
|
||||
; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies
|
||||
; (accessible through /sys/fs/cgroup) read-only to all processes invoked by
|
||||
; the unit. It also implies `MountAPIVFS=yes`.
|
||||
;
|
||||
; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the
|
||||
; unit User and Group with read-write permissions (0755) as soon as the
|
||||
; unit starts. This allows unbound to store its pidfile. The directory and
|
||||
; its content are automatically removed by systemd when the unit stops.
|
||||
;
|
||||
; - `NoNewPrivileges=yes` ensures that the service process and all its
|
||||
; children can never gain new privileges through execve().
|
||||
;
|
||||
; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID
|
||||
; (SUID) or set-group-ID (SGID) bits on files or directories will be denied.
|
||||
;
|
||||
; - `RestrictRealTime=yes` ensures that any attempts to enable realtime
|
||||
; scheduling in a process invoked by the unit will be denied.
|
||||
;
|
||||
; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing
|
||||
; is prohibited.
|
||||
;
|
||||
; - `LockPersonality=yes` locks down the personality system call so that the
|
||||
; kernel execution domain may not be changed from the default.
|
||||
;
|
||||
;
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
Wants=network-online.target nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound
|
||||
ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
@@ -18,11 +62,23 @@ PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
|
||||
RestrictAddressFamilies=AF_INET AF_UNIX
|
||||
RuntimeDirectory=unbound
|
||||
ConfigurationDirectory=unbound
|
||||
StateDirectory=unbound
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
RestrictNamespaces=yes
|
||||
LockPersonality=yes
|
||||
RestrictSUIDSGID=yes
|
||||
ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
|
||||
|
||||
# Below rules are needed when chroot is enabled (usually it's enabled by default).
|
||||
# If chroot is disabled like chroot: "" then they may be safely removed.
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
|
||||
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
|
||||
BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
|
||||
BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
|
||||
BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
|
||||
|
||||
@@ -174,11 +174,11 @@ get_state ( ) {
|
||||
if test "$1" = "autoconf" ; then
|
||||
if test ! -f $conf; then
|
||||
echo no "($conf does not exist)"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
if test ! -d `dirname $state`; then
|
||||
echo no "(`dirname $state` directory does not exist)"
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
echo yes
|
||||
exit 0
|
||||
@@ -242,6 +242,8 @@ if test "$1" = "config" ; then
|
||||
p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
|
||||
p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
|
||||
p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
|
||||
p_config "num.query.tls" "TLS queries" "ABSOLUTE"
|
||||
p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
|
||||
p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
|
||||
p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
|
||||
p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
|
||||
@@ -443,7 +445,8 @@ hits)
|
||||
for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
|
||||
sed -e 's/=.*//'` total.num.queries \
|
||||
total.num.cachehits total.num.prefetch num.query.tcp \
|
||||
num.query.tcpout num.query.ipv6 unwanted.queries \
|
||||
num.query.tcpout num.query.tls num.query.tls.resume \
|
||||
num.query.ipv6 unwanted.queries \
|
||||
unwanted.replies; do
|
||||
if grep "^"$x"=" $state >/dev/null 2>&1; then
|
||||
print_value $x
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
; This unit file is provided to run unbound as portable service.
|
||||
; https://systemd.io/PORTABLE_SERVICES/
|
||||
;
|
||||
; To use this unit file, please make sure you either compile unbound with the
|
||||
; following options:
|
||||
;
|
||||
; - --with-chroot-dir=""
|
||||
;
|
||||
; Or put the following options in your unbound configuration file:
|
||||
;
|
||||
; - chroot: ""
|
||||
;
|
||||
;
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectSystem=strict
|
||||
RuntimeDirectory=unbound
|
||||
ConfigurationDirectory=unbound
|
||||
StateDirectory=unbound
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
RestrictNamespaces=yes
|
||||
LockPersonality=yes
|
||||
RestrictSUIDSGID=yes
|
||||
BindPaths=/run/systemd/notify
|
||||
BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
|
||||
Binary file not shown.
Binary file not shown.
+1
-1
@@ -273,7 +273,7 @@ check_data(const char* data, const struct config_strlist* head)
|
||||
if(res == 0)
|
||||
return 1;
|
||||
log_err("rr data [char %d] parse error %s",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-13,
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-2,
|
||||
sldns_get_errorstr_parse(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
+22
-21
@@ -62,7 +62,7 @@
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
{
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
@@ -73,7 +73,7 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
|
||||
/** dump rrset key and data info */
|
||||
static int
|
||||
dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now)
|
||||
{
|
||||
size_t i;
|
||||
@@ -99,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
|
||||
/** dump lruhash rrset cache */
|
||||
static int
|
||||
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
@@ -118,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
|
||||
/** dump rrset cache */
|
||||
static int
|
||||
dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct rrset_cache* r = worker->env.rrset_cache;
|
||||
size_t slab;
|
||||
@@ -137,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** dump message to rrset reference */
|
||||
static int
|
||||
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
char* nm, *tp, *cl;
|
||||
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
@@ -164,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
|
||||
time_t now)
|
||||
{
|
||||
size_t i;
|
||||
@@ -246,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
||||
|
||||
/** dump lruhash msg cache */
|
||||
static int
|
||||
dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info* k;
|
||||
@@ -274,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
|
||||
/** dump msg cache */
|
||||
static int
|
||||
dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct slabhash* sh = worker->env.msg_cache;
|
||||
size_t slab;
|
||||
@@ -291,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
dump_cache(SSL* ssl, struct worker* worker)
|
||||
dump_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!dump_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -302,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** read a line from ssl into buffer */
|
||||
static int
|
||||
ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
ssl_read_buf(RES* ssl, sldns_buffer* buf)
|
||||
{
|
||||
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_capacity(buf));
|
||||
@@ -310,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
|
||||
/** check fixed text on line */
|
||||
static int
|
||||
read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
|
||||
{
|
||||
if(!ssl_read_buf(ssl, buf)) return 0;
|
||||
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
|
||||
@@ -318,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
|
||||
/** load an RR into rrset */
|
||||
static int
|
||||
load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
|
||||
load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
|
||||
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
|
||||
unsigned int i, int is_rrsig, int* go_on, time_t now)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
|
||||
/** load an rrset entry */
|
||||
static int
|
||||
load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
struct regional* region = worker->scratchpad;
|
||||
@@ -519,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load rrset cache */
|
||||
static int
|
||||
load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
load_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
|
||||
@@ -575,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
|
||||
/** load a msg rrset reference */
|
||||
static int
|
||||
load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
struct regional *region, struct ub_packed_rrset_key** rrset,
|
||||
int* go_on)
|
||||
{
|
||||
@@ -620,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
|
||||
/** load a msg entry */
|
||||
static int
|
||||
load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
struct regional* region = worker->scratchpad;
|
||||
struct query_info qinf;
|
||||
@@ -653,6 +653,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
rep.qdcount = (uint16_t)qdcount;
|
||||
rep.ttl = (time_t)ttl;
|
||||
rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
|
||||
rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
|
||||
rep.security = (enum sec_status)security;
|
||||
if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
|
||||
log_warn("error too many rrsets");
|
||||
@@ -685,7 +686,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load msg cache */
|
||||
static int
|
||||
load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
load_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
|
||||
@@ -698,7 +699,7 @@ load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
load_cache(SSL* ssl, struct worker* worker)
|
||||
load_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!load_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -709,7 +710,7 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
@@ -785,7 +786,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
{
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
|
||||
@@ -813,7 +814,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
/* deep links into the iterator module */
|
||||
|
||||
+4
-3
@@ -72,6 +72,7 @@
|
||||
#ifndef DAEMON_DUMPCACHE_H
|
||||
#define DAEMON_DUMPCACHE_H
|
||||
struct worker;
|
||||
#include "daemon/remote.h"
|
||||
|
||||
/**
|
||||
* Dump cache(s) to text
|
||||
@@ -80,7 +81,7 @@ struct worker;
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl print error.
|
||||
*/
|
||||
int dump_cache(SSL* ssl, struct worker* worker);
|
||||
int dump_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Load cache(s) from text
|
||||
@@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker);
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int load_cache(SSL* ssl, struct worker* worker);
|
||||
int load_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Print the delegation used to lookup for this name.
|
||||
@@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker);
|
||||
* @param nmlabs: labels in name.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int nmlabs);
|
||||
|
||||
#endif /* DAEMON_DUMPCACHE_H */
|
||||
|
||||
+72
-31
@@ -76,6 +76,8 @@
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/edns.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
@@ -104,10 +106,8 @@ static int sig_record_reload = 0;
|
||||
/** cleaner ssl memory freeup */
|
||||
static void* comp_meth = NULL;
|
||||
#endif
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/** remove buffers for parsing and init */
|
||||
int ub_c_lex_destroy(void);
|
||||
#endif
|
||||
|
||||
/** used when no other sighandling happens, so we don't die
|
||||
* when multiple signals in quick succession are sent to us.
|
||||
@@ -182,15 +182,8 @@ static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
if(sig_record_reload) {
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "RELOADING=1");
|
||||
# endif
|
||||
if(sig_record_reload)
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
@@ -229,7 +222,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
|
||||
@@ -256,8 +251,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,
|
||||
@@ -279,11 +272,29 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->tcl = tcl_list_create();
|
||||
if(!daemon->tcl) {
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
daemon->time_last_stat = daemon->time_boot;
|
||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
if(!(daemon->env->edns_strings = edns_strings_create())) {
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
@@ -297,6 +308,8 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
if(daemon->cfg->port != daemon->listening_port) {
|
||||
char** resif = NULL;
|
||||
int num_resif = 0;
|
||||
size_t i;
|
||||
struct listen_port* p0;
|
||||
daemon->reuseport = 0;
|
||||
@@ -307,15 +320,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
}
|
||||
if(!resolve_interface_names(daemon->cfg->ifs,
|
||||
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
|
||||
return 0;
|
||||
/* see if we want to reuseport */
|
||||
#ifdef SO_REUSEPORT
|
||||
if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
|
||||
daemon->reuseport = 1;
|
||||
#endif
|
||||
/* try to use reuseport */
|
||||
p0 = listening_ports_open(daemon->cfg, &daemon->reuseport);
|
||||
p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
|
||||
if(!p0) {
|
||||
listening_ports_free(p0);
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
if(daemon->reuseport) {
|
||||
@@ -329,6 +346,7 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
if(!(daemon->ports = (struct listen_port**)calloc(
|
||||
daemon->num_ports, sizeof(*daemon->ports)))) {
|
||||
listening_ports_free(p0);
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
daemon->ports[0] = p0;
|
||||
@@ -337,16 +355,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
for(i=1; i<daemon->num_ports; i++) {
|
||||
if(!(daemon->ports[i]=
|
||||
listening_ports_open(daemon->cfg,
|
||||
resif, num_resif,
|
||||
&daemon->reuseport))
|
||||
|| !daemon->reuseport ) {
|
||||
for(i=0; i<daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
config_del_strarray(resif, num_resif);
|
||||
daemon->listening_port = daemon->cfg->port;
|
||||
}
|
||||
if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
|
||||
@@ -426,9 +447,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));
|
||||
@@ -452,11 +471,9 @@ daemon_create_workers(struct daemon* daemon)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
if(daemon->cfg->dnstap) {
|
||||
#ifdef USE_DNSTAP
|
||||
daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path,
|
||||
(unsigned int)daemon->num);
|
||||
daemon->dtenv = dt_create(daemon->cfg);
|
||||
if (!daemon->dtenv)
|
||||
fatal_exit("dt_create failed");
|
||||
dt_apply_cfg(daemon->dtenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
@@ -574,6 +591,9 @@ void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
log_assert(daemon);
|
||||
if(!(daemon->views = views_create()))
|
||||
@@ -584,6 +604,8 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||
fatal_exit("Could not setup access control list");
|
||||
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
||||
fatal_exit("Could not setup TCP connection limits");
|
||||
if(daemon->cfg->dnscrypt) {
|
||||
#ifdef USE_DNSCRYPT
|
||||
daemon->dnscenv = dnsc_create();
|
||||
@@ -611,20 +633,31 @@ daemon_fork(struct daemon* daemon)
|
||||
fatal_exit("Could not set up per-view response IP sets");
|
||||
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
|
||||
have_view_respip_cfg;
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* setup modules */
|
||||
daemon_setup_modules(daemon);
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* Set-up EDNS strings */
|
||||
if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
|
||||
fatal_exit("Could not set up EDNS strings");
|
||||
|
||||
/* response-ip-xxx options don't work as expected without the respip
|
||||
* module. To avoid run-time operational surprise we reject such
|
||||
* configuration. */
|
||||
if(daemon->use_response_ip &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("response-ip options require respip module");
|
||||
/* RPZ response ip triggers don't work as expected without the respip
|
||||
* module. To avoid run-time operational surprise we reject such
|
||||
* configuration. */
|
||||
if(daemon->use_rpz &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
@@ -657,12 +690,20 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
ret = sd_notify(0, "READY=1");
|
||||
if(ret <= 0 && getenv("NOTIFY_SOCKET"))
|
||||
fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
|
||||
"access/permission to use the socket presented by systemd.",
|
||||
getenv("NOTIFY_SOCKET"),
|
||||
(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "STOPPING=1");
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
@@ -733,23 +774,24 @@ daemon_delete(struct daemon* daemon)
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
edns_known_options_delete(daemon->env);
|
||||
edns_strings_delete(daemon->env->edns_strings);
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
#ifdef HAVE_SSL
|
||||
listen_sslctx_delete_ticket_keys();
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
|
||||
#endif
|
||||
free(daemon);
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/* lex cleanup */
|
||||
ub_c_lex_destroy();
|
||||
#endif
|
||||
/* libcrypto cleanup */
|
||||
#ifdef HAVE_SSL
|
||||
# if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
@@ -764,7 +806,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) && defined(HAVE_ENGINE_CLEANUP)
|
||||
ENGINE_cleanup();
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
@@ -800,9 +842,8 @@ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
daemon->cfg = cfg;
|
||||
config_apply(cfg);
|
||||
if(!daemon->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
||||
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs)) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
|
||||
@@ -113,6 +113,8 @@ struct daemon {
|
||||
struct module_stack mods;
|
||||
/** access control, which client IPs are allowed to connect */
|
||||
struct acl_list* acl;
|
||||
/** TCP connection limit, limit connections from client IPs */
|
||||
struct tcl_list* tcl;
|
||||
/** local authority zones */
|
||||
struct local_zones* local_zones;
|
||||
/** last time of statistics printout */
|
||||
@@ -130,6 +132,8 @@ struct daemon {
|
||||
struct respip_set* respip_set;
|
||||
/** some response-ip tags or actions are configured if true */
|
||||
int use_response_ip;
|
||||
/** some RPZ policies are configured */
|
||||
int use_rpz;
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
|
||||
+549
-296
File diff suppressed because it is too large
Load Diff
+21
-6
@@ -73,6 +73,8 @@ struct rc_state {
|
||||
/** the ssl state */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor */
|
||||
int fd;
|
||||
/** the rc this is part of */
|
||||
struct daemon_remote* rc;
|
||||
};
|
||||
@@ -103,6 +105,19 @@ struct daemon_remote {
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection to print to, either SSL or plain over fd
|
||||
*/
|
||||
struct remote_stream {
|
||||
#ifdef HAVE_SSL
|
||||
/** SSL structure, nonNULL if using SSL */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor for plain transfer */
|
||||
int fd;
|
||||
};
|
||||
typedef struct remote_stream RES;
|
||||
|
||||
/**
|
||||
* Create new remote control state for the daemon.
|
||||
* @param cfg: config file with key file settings.
|
||||
@@ -166,26 +181,26 @@ void daemon_remote_exec(struct worker* worker);
|
||||
* @param text: the text.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_print_text(SSL* ssl, const char* text);
|
||||
int ssl_print_text(RES* ssl, const char* text);
|
||||
|
||||
/**
|
||||
* printf style printing to the ssl connection
|
||||
* @param ssl: the SSL connection to print to. Blocking.
|
||||
* @param ssl: the RES connection to print to. Blocking.
|
||||
* @param format: printf style format string.
|
||||
* @return success or false on a network failure.
|
||||
*/
|
||||
int ssl_printf(SSL* ssl, const char* format, ...)
|
||||
int ssl_printf(RES* ssl, const char* format, ...)
|
||||
ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/**
|
||||
* Read until \n is encountered
|
||||
* If SSL signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the SSL connection to read from. blocking.
|
||||
* If stream signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the RES connection to read from. blocking.
|
||||
* @param buf: buffer to read to.
|
||||
* @param max: size of buffer.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_read_line(SSL* ssl, char* buf, size_t max);
|
||||
int ssl_read_line(RES* ssl, char* buf, size_t max);
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#endif /* DAEMON_REMOTE_H */
|
||||
|
||||
+68
-4
@@ -63,6 +63,12 @@
|
||||
#include "services/authzone.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_neg.h"
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -71,7 +77,7 @@ stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long l
|
||||
#ifndef S_SPLINT_S
|
||||
(*d_sec) += add_sec;
|
||||
(*d_usec) += add_usec;
|
||||
if((*d_usec) > 1000000) {
|
||||
if((*d_usec) >= 1000000) {
|
||||
(*d_usec) -= 1000000;
|
||||
(*d_sec)++;
|
||||
}
|
||||
@@ -124,6 +130,33 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
/** Set the EDNS Subnet stats. */
|
||||
static void
|
||||
set_subnet_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "subnet");
|
||||
struct subnet_env* sne;
|
||||
if(m == -1)
|
||||
return;
|
||||
sne = (struct subnet_env*)worker->env.modinfo[m];
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
} else {
|
||||
lock_rw_rdlock(&sne->biglock);
|
||||
}
|
||||
svr->num_query_subnet = (long long)(sne->num_msg_nocache + sne->num_msg_cache);
|
||||
svr->num_query_subnet_cache = (long long)sne->num_msg_cache;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
sne->num_msg_cache = 0;
|
||||
sne->num_msg_nocache = 0;
|
||||
}
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
/** Set the neg cache stats. */
|
||||
static void
|
||||
set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
@@ -238,8 +271,11 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
|
||||
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
|
||||
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
|
||||
for(i=0; i<16; i++)
|
||||
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
|
||||
for(i=0; i<UB_STATS_RCODE_NUM; i++)
|
||||
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
|
||||
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
|
||||
timehist_export(worker->env.mesh->histogram, s->svr.hist,
|
||||
NUM_BUCKETS_HIST);
|
||||
/* values from outside network */
|
||||
@@ -298,9 +334,22 @@ 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();
|
||||
s->svr.mem_http2_query_buffer =
|
||||
(long long)http2_get_query_buffer_size();
|
||||
s->svr.mem_http2_response_buffer =
|
||||
(long long)http2_get_response_buffer_size();
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
#ifdef CLIENT_SUBNET
|
||||
/* EDNS Subnet usage numbers */
|
||||
set_subnet_stats(worker, &s->svr, reset);
|
||||
#else
|
||||
s->svr.num_query_subnet = 0;
|
||||
s->svr.num_query_subnet_cache = 0;
|
||||
#endif
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
@@ -356,6 +405,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
|
||||
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
|
||||
total->svr.ans_expired += a->svr.ans_expired;
|
||||
#ifdef USE_DNSCRYPT
|
||||
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
|
||||
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
|
||||
@@ -374,6 +424,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.qclass_big += a->svr.qclass_big;
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
|
||||
total->svr.qtls += a->svr.qtls;
|
||||
total->svr.qtls_resume += a->svr.qtls_resume;
|
||||
total->svr.qhttps += a->svr.qhttps;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
@@ -386,7 +439,6 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.qEDNS += a->svr.qEDNS;
|
||||
total->svr.qEDNS_DO += a->svr.qEDNS_DO;
|
||||
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
|
||||
total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
|
||||
total->svr.ans_secure += a->svr.ans_secure;
|
||||
total->svr.ans_bogus += a->svr.ans_bogus;
|
||||
total->svr.unwanted_replies += a->svr.unwanted_replies;
|
||||
@@ -402,6 +454,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
|
||||
for(i=0; i<NUM_BUCKETS_HIST; i++)
|
||||
total->svr.hist[i] += a->svr.hist[i];
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
|
||||
total->svr.rpz_action[i] += a->svr.rpz_action[i];
|
||||
}
|
||||
|
||||
total->mesh_num_states += a->mesh_num_states;
|
||||
@@ -428,8 +482,18 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
stats->qclass[qclass]++;
|
||||
else stats->qclass_big++;
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp)
|
||||
if(c->type != comm_udp) {
|
||||
stats->qtcp++;
|
||||
if(c->ssl != NULL) {
|
||||
stats->qtls++;
|
||||
#ifdef HAVE_SSL
|
||||
if(SSL_session_reused(c->ssl))
|
||||
stats->qtls_resume++;
|
||||
#endif
|
||||
if(c->type == comm_http)
|
||||
stats->qhttps++;
|
||||
}
|
||||
}
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
stats->qipv6++;
|
||||
if( (flags&BIT_QR) )
|
||||
|
||||
+146
-57
@@ -67,6 +67,7 @@
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#ifndef S_SPLINT_S
|
||||
/* splint chokes on this system header file */
|
||||
@@ -87,30 +88,28 @@
|
||||
# include "nss.h"
|
||||
#endif
|
||||
|
||||
/** print usage. */
|
||||
static void usage(void)
|
||||
#ifdef HAVE_TARGETCONDITIONALS_H
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
|
||||
#undef HAVE_FORK
|
||||
#endif
|
||||
|
||||
/** print build options. */
|
||||
static void
|
||||
print_build_options(void)
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
time_t t;
|
||||
struct timeval now;
|
||||
struct ub_event_base* base;
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
printf("-c file config file to read instead of %s\n", CONFIGFILE);
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
printf(" install, remove - manage the services entry\n");
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("Version %s\n\n", PACKAGE_VERSION);
|
||||
printf("Configure line: %s\n", CONFCMDLINE);
|
||||
base = ub_default_event_base(0,&t,&now);
|
||||
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
printf("Linked libs: %s %s (it uses %s), %s\n",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef SSLEAY_VERSION
|
||||
@@ -124,16 +123,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
|
||||
@@ -172,6 +197,33 @@ checkrlimits(struct config_file* cfg)
|
||||
size_t total = numthread * perthread + misc;
|
||||
size_t avail;
|
||||
struct rlimit rlim;
|
||||
size_t memsize_expect = cfg->msg_cache_size + cfg->rrset_cache_size
|
||||
+ (cfg->do_tcp?cfg->stream_wait_size:0)
|
||||
+ (cfg->ip_ratelimit?cfg->ip_ratelimit_size:0)
|
||||
+ (cfg->ratelimit?cfg->ratelimit_size:0)
|
||||
+ (cfg->dnscrypt?cfg->dnscrypt_shared_secret_cache_size + cfg->dnscrypt_nonce_cache_size:0)
|
||||
+ cfg->infra_cache_numhosts * (sizeof(struct infra_key)+sizeof(struct infra_data));
|
||||
if(strstr(cfg->module_conf, "validator") && (cfg->trust_anchor_file_list || cfg->trust_anchor_list || cfg->auto_trust_anchor_file_list || cfg->trusted_keys_file_list)) {
|
||||
memsize_expect += cfg->key_cache_size + cfg->neg_cache_size;
|
||||
}
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(cfg)) {
|
||||
memsize_expect += cfg->http_query_buffer_size + cfg->http_response_buffer_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(getrlimit(RLIMIT_AS, &rlim) == 0) {
|
||||
if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
|
||||
rlim.rlim_cur < (rlim_t)memsize_expect) {
|
||||
log_warn("the ulimit(max memory size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
|
||||
}
|
||||
}
|
||||
if(getrlimit(RLIMIT_DATA, &rlim) == 0) {
|
||||
if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
|
||||
rlim.rlim_cur < memsize_expect) {
|
||||
log_warn("the ulimit(data seg size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
|
||||
}
|
||||
}
|
||||
|
||||
if(total > 1024 &&
|
||||
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
|
||||
@@ -242,21 +294,10 @@ checkrlimits(struct config_file* cfg)
|
||||
#endif /* S_SPLINT_S */
|
||||
}
|
||||
|
||||
/** set default logfile identity based on value from argv[0] at startup **/
|
||||
static void
|
||||
log_ident_set_fromdefault(struct config_file* cfg,
|
||||
const char *log_default_identity)
|
||||
{
|
||||
if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
|
||||
log_ident_set(log_default_identity);
|
||||
else
|
||||
log_ident_set(cfg->log_identity);
|
||||
}
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
@@ -272,7 +313,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
|
||||
}
|
||||
|
||||
log_ident_set_fromdefault(cfg, log_default_identity);
|
||||
log_ident_set_or_default(cfg->log_identity);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
@@ -323,22 +364,44 @@ readpid (const char* file)
|
||||
/** write pid to file.
|
||||
* @param pidfile: file name of pid file.
|
||||
* @param pid: pid to write to file.
|
||||
* @return false on failure
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
writepid (const char* pidfile, pid_t pid)
|
||||
{
|
||||
FILE* f;
|
||||
int fd;
|
||||
char pidbuf[32];
|
||||
size_t count = 0;
|
||||
snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid);
|
||||
|
||||
if ((f = fopen(pidfile, "w")) == NULL ) {
|
||||
if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC
|
||||
#ifdef O_NOFOLLOW
|
||||
| O_NOFOLLOW
|
||||
#endif
|
||||
, 0644)) == -1) {
|
||||
log_err("cannot open pidfile %s: %s",
|
||||
pidfile, strerror(errno));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) {
|
||||
log_err("cannot write to pidfile %s: %s",
|
||||
pidfile, strerror(errno));
|
||||
while(count < strlen(pidbuf)) {
|
||||
ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
|
||||
if(r == -1) {
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
log_err("cannot write to pidfile %s: %s",
|
||||
pidfile, strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
log_err("cannot write any bytes to pidfile %s: "
|
||||
"write returns 0 bytes written", pidfile);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
count += r;
|
||||
}
|
||||
fclose(f);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,6 +492,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)))
|
||||
@@ -474,16 +555,17 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
/* write new pidfile (while still root, so can be outside chroot) */
|
||||
#ifdef HAVE_KILL
|
||||
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
|
||||
writepid(daemon->pidfile, getpid());
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
|
||||
pidinchroot) {
|
||||
if(writepid(daemon->pidfile, getpid())) {
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
|
||||
pidinchroot) {
|
||||
# ifdef HAVE_CHOWN
|
||||
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
|
||||
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
daemon->pidfile, strerror(errno));
|
||||
}
|
||||
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
|
||||
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
daemon->pidfile, strerror(errno));
|
||||
}
|
||||
# endif /* HAVE_CHOWN */
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -502,6 +584,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
|
||||
log_warn("unable to setusercontext %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
#else
|
||||
(void)pwd;
|
||||
#endif /* HAVE_SETUSERCONTEXT */
|
||||
}
|
||||
#endif /* HAVE_GETPWNAM */
|
||||
@@ -604,11 +688,10 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* @param cmdline_verbose: verbosity resulting from commandline -v.
|
||||
* These increase verbosity as specified in the config file.
|
||||
* @param debug_mode: if set, do not daemonize.
|
||||
* @param log_default_identity: Default identity to report in logs
|
||||
* @param need_pidfile: if false, no pidfile is checked or created.
|
||||
*/
|
||||
static void
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity, int need_pidfile)
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile)
|
||||
{
|
||||
struct config_file* cfg = NULL;
|
||||
struct daemon* daemon = NULL;
|
||||
@@ -626,11 +709,13 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char*
|
||||
fatal_exit("Could not alloc config defaults");
|
||||
if(!config_read(cfg, cfgfile, daemon->chroot)) {
|
||||
if(errno != ENOENT)
|
||||
fatal_exit("Could not read config file: %s",
|
||||
cfgfile);
|
||||
fatal_exit("Could not read config file: %s."
|
||||
" Maybe try unbound -dd, it stays on "
|
||||
"the commandline to see more errors, "
|
||||
"or unbound-checkconf", cfgfile);
|
||||
log_warn("Continuing with default config settings");
|
||||
}
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
|
||||
if(!done_setup)
|
||||
config_lookup_uid(cfg);
|
||||
|
||||
@@ -696,9 +781,10 @@ main(int argc, char* argv[])
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
|
||||
log_ident_set_default(log_ident_default);
|
||||
log_ident_set(log_ident_default);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
cfgfile = optarg;
|
||||
@@ -719,6 +805,9 @@ main(int argc, char* argv[])
|
||||
case 'w':
|
||||
winopt = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
print_build_options();
|
||||
return 0;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
@@ -727,7 +816,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
@@ -743,11 +832,11 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile);
|
||||
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;
|
||||
|
||||
+311
-167
@@ -61,13 +61,16 @@
|
||||
#include "services/authzone.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/rpz.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/edns.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "validator/autotrust.h"
|
||||
#include "validator/val_anchor.h"
|
||||
#include "respip/respip.h"
|
||||
@@ -77,6 +80,7 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#include "dnstap/dtstream.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@@ -477,6 +481,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* Then check if it needs validation, if so, this routine fails,
|
||||
* so that iterator can prime and validator can verify rrsets.
|
||||
*/
|
||||
struct edns_data edns_bak;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure = 0;
|
||||
time_t timenow = *worker->env.now;
|
||||
@@ -509,7 +514,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
return 0;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
@@ -534,19 +540,24 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
}
|
||||
/* return this delegation from the cache */
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
return 0;
|
||||
msg->rep->flags |= BIT_QR|BIT_RA;
|
||||
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
|
||||
repinfo->c, worker->scratchpad) ||
|
||||
!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
repinfo->c->buffer, 0, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
@@ -567,9 +578,10 @@ static int
|
||||
apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, struct reply_info* rep,
|
||||
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** encode_repp)
|
||||
struct reply_info** encode_repp, struct auth_zones* az)
|
||||
{
|
||||
struct respip_action_info actinfo = {respip_none, NULL};
|
||||
struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
|
||||
actinfo.action = respip_none;
|
||||
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_A &&
|
||||
qinfo->qtype != LDNS_RR_TYPE_AAAA &&
|
||||
@@ -577,7 +589,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
|
||||
alias_rrset, 0, worker->scratchpad))
|
||||
alias_rrset, 0, worker->scratchpad, az))
|
||||
return 0;
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
@@ -590,9 +602,19 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
/* If address info is returned, it means the action should be an
|
||||
* 'inform' variant and the information should be logged. */
|
||||
if(actinfo.addrinfo) {
|
||||
respip_inform_print(actinfo.addrinfo, qinfo->qname,
|
||||
respip_inform_print(&actinfo, qinfo->qname,
|
||||
qinfo->qtype, qinfo->qclass, qinfo->local_alias,
|
||||
repinfo);
|
||||
|
||||
if(worker->stats.extended && actinfo.rpz_used) {
|
||||
if(actinfo.rpz_disabled)
|
||||
worker->stats.rpz_action[RPZ_DISABLED_ACTION]++;
|
||||
if(actinfo.rpz_cname_override)
|
||||
worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
|
||||
else
|
||||
worker->stats.rpz_action[
|
||||
respip_action_to_rpz_action(actinfo.action)]++;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -608,54 +630,53 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
* be completely dropped, '*need_drop' will be set to 1. */
|
||||
static int
|
||||
answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, int* need_drop,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
struct respip_client_info* cinfo, int* need_drop, int* is_expired_answer,
|
||||
int* is_secure_answer, struct ub_packed_rrset_key** alias_rrset,
|
||||
struct reply_info** partial_repp,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct comm_reply* repinfo, struct edns_data* edns)
|
||||
{
|
||||
struct edns_data edns_bak;
|
||||
time_t timenow = *worker->env.now;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
struct reply_info* encode_rep = rep;
|
||||
struct reply_info* partial_rep = *partial_repp;
|
||||
int secure;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
if(worker->env.cfg->serve_expired) {
|
||||
/* always lock rrsets, rep->ttl is ignored */
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
/* below, rrsets with ttl before timenow become TTL 0 in
|
||||
* the response */
|
||||
/* This response was served with zero TTL */
|
||||
if (timenow >= rep->ttl) {
|
||||
worker->stats.zero_ttl_responses++;
|
||||
}
|
||||
} else {
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
|
||||
/* Check TTL */
|
||||
if(rep->ttl < timenow) {
|
||||
/* Check if we need to serve expired now */
|
||||
if(worker->env.cfg->serve_expired &&
|
||||
!worker->env.cfg->serve_expired_client_timeout) {
|
||||
if(worker->env.cfg->serve_expired_ttl &&
|
||||
rep->serve_expired_ttl < timenow)
|
||||
return 0;
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
*is_expired_answer = 1;
|
||||
} else {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
* we will refetch the message format from the
|
||||
* authoritative server
|
||||
* authoritative server
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
||||
return 0;
|
||||
/* locked and ids and ttls are OK. */
|
||||
}
|
||||
/* locked and ids and ttls are OK. */
|
||||
|
||||
/* check CNAME chain (if any) */
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_DNAME))) {
|
||||
if(!reply_check_cname_chain(qinfo, rep)) {
|
||||
/* cname chain invalid, redo iterator steps */
|
||||
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
||||
bail_out:
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
return 0;
|
||||
goto bail_out;
|
||||
}
|
||||
}
|
||||
/* check security status of the cached answer */
|
||||
@@ -667,56 +688,61 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
goto bail_out;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.ans_bogus ++;
|
||||
worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++;
|
||||
}
|
||||
return 1;
|
||||
} else if( rep->security == sec_status_unchecked && must_validate) {
|
||||
} else if(rep->security == sec_status_unchecked && must_validate) {
|
||||
verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
|
||||
"validation");
|
||||
goto bail_out; /* need to validate cache entry first */
|
||||
} else if(rep->security == sec_status_secure) {
|
||||
if(reply_all_rrsets_secure(rep))
|
||||
secure = 1;
|
||||
else {
|
||||
if(reply_all_rrsets_secure(rep)) {
|
||||
*is_secure_answer = 1;
|
||||
} else {
|
||||
if(must_validate) {
|
||||
verbose(VERB_ALGO, "Cache reply: secure entry"
|
||||
" changed status");
|
||||
goto bail_out; /* rrset changed, re-verify */
|
||||
}
|
||||
secure = 0;
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
} else secure = 0;
|
||||
} else *is_secure_answer = 0;
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
goto bail_out;
|
||||
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
|
||||
if(worker->daemon->use_response_ip && !partial_rep &&
|
||||
!apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset,
|
||||
&encode_rep)) {
|
||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||
!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
|
||||
repinfo, alias_rrset,
|
||||
&encode_rep, worker->env.auth_zones)) {
|
||||
goto bail_out;
|
||||
} else if(partial_rep &&
|
||||
!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
|
||||
must_validate, &encode_rep, worker->scratchpad)) {
|
||||
must_validate, &encode_rep, worker->scratchpad,
|
||||
worker->env.auth_zones)) {
|
||||
goto bail_out;
|
||||
}
|
||||
if(encode_rep != rep)
|
||||
secure = 0; /* if rewritten, it can't be considered "secure" */
|
||||
if(encode_rep != rep) {
|
||||
/* if rewritten, it can't be considered "secure" */
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
if(!encode_rep || *alias_rrset) {
|
||||
sldns_buffer_clear(repinfo->c->buffer);
|
||||
sldns_buffer_flip(repinfo->c->buffer);
|
||||
if(!encode_rep)
|
||||
*need_drop = 1;
|
||||
else {
|
||||
@@ -728,11 +754,14 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!*partial_repp)
|
||||
goto bail_out;
|
||||
}
|
||||
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
} else if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
|
||||
repinfo->c, worker->scratchpad) ||
|
||||
!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
@@ -741,26 +770,30 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* is bad while holding locks. */
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
|
||||
rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
if(secure) worker->stats.ans_secure++;
|
||||
server_stats_insrcode(&worker->stats, repinfo->c->buffer);
|
||||
}
|
||||
/* go and return this buffer to the client */
|
||||
return 1;
|
||||
|
||||
bail_out:
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Reply to client and perform prefetch to keep cache up to date.
|
||||
* If the buffer for the reply is empty, it indicates that only prefetch is
|
||||
* necessary and the reply should be suppressed (because it's dropped or
|
||||
* being deferred). */
|
||||
/** Reply to client and perform prefetch to keep cache up to date. */
|
||||
static void
|
||||
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway)
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
|
||||
{
|
||||
/* first send answer to client to keep its latency
|
||||
* as small as a cachereply */
|
||||
if(sldns_buffer_limit(repinfo->c->buffer) != 0)
|
||||
if(!noreply) {
|
||||
if(repinfo->c->tcp_req_info) {
|
||||
sldns_buffer_copy(
|
||||
repinfo->c->tcp_req_info->spool_buffer,
|
||||
repinfo->c->buffer);
|
||||
}
|
||||
comm_point_send_reply(repinfo);
|
||||
}
|
||||
server_stats_prefetch(&worker->stats, worker);
|
||||
|
||||
/* create the prefetch in the mesh as a normal lookup without
|
||||
@@ -779,10 +812,11 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
* @param num: number of strings in array.
|
||||
* @param edns: edns reply information.
|
||||
* @param worker: worker with scratch region.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
*/
|
||||
static void
|
||||
chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
struct worker* worker)
|
||||
struct worker* worker, struct comm_reply* repinfo)
|
||||
{
|
||||
int i;
|
||||
unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
|
||||
@@ -815,7 +849,8 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
|
||||
LDNS_RCODE_NOERROR, edns, worker->scratchpad))
|
||||
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
edns->opt_list = NULL;
|
||||
if(sldns_buffer_capacity(pkt) >=
|
||||
sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
|
||||
@@ -825,9 +860,9 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
/** Reply with one string */
|
||||
static void
|
||||
chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
|
||||
struct worker* worker)
|
||||
struct worker* worker, struct comm_reply* repinfo)
|
||||
{
|
||||
chaos_replystr(pkt, (char**)&str, 1, edns, worker);
|
||||
chaos_replystr(pkt, (char**)&str, 1, edns, worker, repinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -835,9 +870,11 @@ chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
|
||||
* @param pkt: buffer
|
||||
* @param edns: edns reply information.
|
||||
* @param w: worker with scratch region.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
*/
|
||||
static void
|
||||
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
#define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */
|
||||
#define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */
|
||||
@@ -848,7 +885,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
|
||||
if(!w->env.need_to_validate) {
|
||||
/* no validator module, reply no trustanchors */
|
||||
chaos_replystr(pkt, NULL, 0, edns, w);
|
||||
chaos_replystr(pkt, NULL, 0, edns, w, repinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -882,7 +919,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
}
|
||||
lock_basic_unlock(&w->env.anchors->lock);
|
||||
|
||||
chaos_replystr(pkt, str_array, num, edns, w);
|
||||
chaos_replystr(pkt, str_array, num, edns, w, repinfo);
|
||||
regional_free_all(w->scratchpad);
|
||||
}
|
||||
|
||||
@@ -891,12 +928,13 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
* @param pkt: packet buffer.
|
||||
* @return: true if a reply is to be sent.
|
||||
*/
|
||||
static int
|
||||
answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, sldns_buffer* pkt)
|
||||
answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* pkt)
|
||||
{
|
||||
struct config_file* cfg = w->env.cfg;
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
|
||||
@@ -912,13 +950,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
chaos_replyonestr(pkt, buf, edns, w);
|
||||
chaos_replyonestr(pkt, buf, edns, w, repinfo);
|
||||
} else {
|
||||
log_err("gethostname: %s", strerror(errno));
|
||||
chaos_replyonestr(pkt, "no hostname", edns, w);
|
||||
chaos_replyonestr(pkt, "no hostname", edns, w, repinfo);
|
||||
}
|
||||
}
|
||||
else chaos_replyonestr(pkt, cfg->identity, edns, w);
|
||||
else chaos_replyonestr(pkt, cfg->identity, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
@@ -929,8 +967,8 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
if(cfg->hide_version)
|
||||
return 0;
|
||||
if(cfg->version==NULL || cfg->version[0]==0)
|
||||
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
|
||||
else chaos_replyonestr(pkt, cfg->version, edns, w);
|
||||
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w, repinfo);
|
||||
else chaos_replyonestr(pkt, cfg->version, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
@@ -938,7 +976,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
{
|
||||
if(cfg->hide_trustanchor)
|
||||
return 0;
|
||||
chaos_trustanchor(pkt, edns, w);
|
||||
chaos_trustanchor(pkt, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1067,17 +1105,19 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct acl_addr* acladdr;
|
||||
int rc = 0;
|
||||
int need_drop = 0;
|
||||
int is_expired_answer = 0;
|
||||
int is_secure_answer = 0;
|
||||
/* We might have to chase a CNAME chain internally, in which case
|
||||
* we'll have up to two replies and combine them to build a complete
|
||||
* answer. These variables control this case. */
|
||||
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 && error != NETEVENT_DONE)|| !repinfo) {
|
||||
/* some bad tcp query DNS formats give these error calls */
|
||||
verbose(VERB_ALGO, "handle request called with err=%d", error);
|
||||
return 0;
|
||||
@@ -1127,9 +1167,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->dtenv.log_client_query_messages)
|
||||
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
|
||||
c->buffer);
|
||||
/*
|
||||
* sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
|
||||
*/
|
||||
if(worker->dtenv.log_client_query_messages) {
|
||||
log_addr(VERB_ALGO, "request from client", &repinfo->addr, repinfo->addrlen);
|
||||
log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
||||
}
|
||||
#endif
|
||||
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
|
||||
repinfo->addrlen);
|
||||
@@ -1156,16 +1201,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++;
|
||||
@@ -1187,13 +1232,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
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) {
|
||||
@@ -1205,7 +1249,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
LDNS_RCODE_REFUSED);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
}
|
||||
goto send_reply;
|
||||
}
|
||||
@@ -1227,7 +1270,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
LDNS_RCODE_FORMERR);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
}
|
||||
goto send_reply;
|
||||
}
|
||||
@@ -1243,32 +1285,55 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.edns_version != 0) {
|
||||
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||
(int)edns.udp_size);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
edns.udp_size = NORMAL_UDP_SIZE;
|
||||
if(edns.edns_present) {
|
||||
struct edns_option* edns_opt;
|
||||
if(edns.edns_version != 0) {
|
||||
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
edns.padding_block_size = 0;
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.udp_size < NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||
(int)edns.udp_size);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
edns.udp_size = NORMAL_UDP_SIZE;
|
||||
}
|
||||
if(c->type != comm_udp) {
|
||||
edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
|
||||
if(edns_opt && edns_opt->opt_len > 0) {
|
||||
edns.ext_rcode = 0;
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
verbose(VERB_ALGO, "query with bad edns keepalive.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, LDNS_RCODE_FORMERR, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
|
||||
c->type == comm_udp) {
|
||||
@@ -1298,8 +1363,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(c->type != comm_udp)
|
||||
edns.udp_size = 65535; /* max size for TCP replies */
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
&edns, c->buffer)) {
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
&edns, repinfo, c->buffer)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
@@ -1320,12 +1384,22 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.auth_zones &&
|
||||
rpz_apply_qname_trigger(worker->env.auth_zones,
|
||||
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
|
||||
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.auth_zones &&
|
||||
auth_zones_answer(worker->env.auth_zones, &worker->env,
|
||||
&qinfo, &edns, c->buffer, worker->scratchpad)) {
|
||||
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1336,7 +1410,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
|
||||
acl != acl_deny_non_local && acl != acl_refuse_non_local)
|
||||
LDNS_RA_SET(sldns_buffer_begin(c->buffer));
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
@@ -1365,7 +1438,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
regional_free_all(worker->scratchpad);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
@@ -1393,7 +1465,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
/* If we may apply IP-based actions to the answer, build the client
|
||||
* information. As this can be expensive, skip it if there is
|
||||
* absolutely no possibility of it. */
|
||||
if(worker->daemon->use_response_ip &&
|
||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||
(qinfo.qtype == LDNS_RR_TYPE_A ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_AAAA ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_ANY)) {
|
||||
@@ -1414,12 +1486,14 @@ lookup_cache:
|
||||
* each pass. We should still pass the original qinfo to
|
||||
* answer_from_cache(), however, since it's used to build the reply. */
|
||||
if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
|
||||
is_expired_answer = 0;
|
||||
is_secure_answer = 0;
|
||||
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 */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
cinfo, &need_drop, &alias_rrset, &partial_rep,
|
||||
(struct reply_info*)e->data,
|
||||
cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
|
||||
&alias_rrset, &partial_rep, (struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
@@ -1427,9 +1501,11 @@ lookup_cache:
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
* lookup. */
|
||||
if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
|
||||
&& *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) {
|
||||
if((worker->env.cfg->prefetch && *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) ||
|
||||
(worker->env.cfg->serve_expired &&
|
||||
*worker->env.now >= ((struct reply_info*)e->data)->ttl)) {
|
||||
|
||||
time_t leeway = ((struct reply_info*)e->
|
||||
data)->ttl - *worker->env.now;
|
||||
if(((struct reply_info*)e->data)->ttl
|
||||
@@ -1438,7 +1514,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);
|
||||
@@ -1513,16 +1590,38 @@ send_reply_rc:
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
if(is_expired_answer) {
|
||||
worker->stats.ans_expired++;
|
||||
}
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
if(worker->stats.extended) {
|
||||
if(is_secure_answer) worker->stats.ans_secure++;
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->dtenv.log_client_response_messages)
|
||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
|
||||
c->type, c->buffer);
|
||||
/*
|
||||
* sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.)
|
||||
*/
|
||||
if(worker->dtenv.log_client_response_messages) {
|
||||
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||
log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
|
||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
||||
}
|
||||
#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)) {
|
||||
@@ -1629,26 +1728,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;
|
||||
#ifdef USE_DNSTAP
|
||||
if(daemon->cfg->dnstap) {
|
||||
log_assert(daemon->dtenv != NULL);
|
||||
memcpy(&worker->dtenv, daemon->dtenv, sizeof(struct dt_env));
|
||||
if(!dt_init(&worker->dtenv))
|
||||
fatal_exit("dt_init failed");
|
||||
}
|
||||
#endif
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
return worker;
|
||||
}
|
||||
|
||||
@@ -1707,10 +1794,23 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
} else { /* !do_sigs */
|
||||
worker->comsig = NULL;
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(cfg->dnstap) {
|
||||
log_assert(worker->daemon->dtenv != NULL);
|
||||
memcpy(&worker->dtenv, worker->daemon->dtenv, sizeof(struct dt_env));
|
||||
if(!dt_init(&worker->dtenv, worker->base))
|
||||
fatal_exit("dt_init failed");
|
||||
}
|
||||
#endif
|
||||
worker->front = listen_create(worker->base, ports,
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
worker->daemon->listen_sslctx, dtenv, worker_handle_request,
|
||||
worker);
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
cfg->do_tcp_keepalive
|
||||
? cfg->tcp_keepalive_timeout
|
||||
: cfg->tcp_idle_timeout,
|
||||
cfg->harden_large_queries, cfg->http_max_streams,
|
||||
cfg->http_endpoint, cfg->http_notls_downstream,
|
||||
worker->daemon->tcl, worker->daemon->listen_sslctx,
|
||||
dtenv, worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1719,19 +1819,21 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker->back = outside_network_create(worker->base,
|
||||
cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
|
||||
cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
|
||||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
|
||||
cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
|
||||
&worker_alloc_cleanup, worker,
|
||||
cfg->do_udp || cfg->udp_upstream_without_downstream,
|
||||
worker->daemon->connect_sslctx, cfg->delay_close,
|
||||
dtenv);
|
||||
cfg->tls_use_sni, dtenv, cfg->udp_connect);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
iterator_set_ip46_support(&worker->daemon->mods, worker->daemon->env,
|
||||
worker->back);
|
||||
/* start listening to commands */
|
||||
if(!tube_setup_bg_listen(worker->cmd, worker->base,
|
||||
&worker_handle_control_cmd, worker)) {
|
||||
@@ -1760,8 +1862,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;
|
||||
@@ -1780,6 +1880,10 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
return 0;
|
||||
}
|
||||
worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
|
||||
/* Pass on daemon variables that we would need in the mesh area */
|
||||
worker->env.mesh->use_response_ip = worker->daemon->use_response_ip;
|
||||
worker->env.mesh->use_rpz = worker->daemon->use_rpz;
|
||||
|
||||
worker->env.detach_subs = &mesh_detach_subs;
|
||||
worker->env.attach_sub = &mesh_attach_sub;
|
||||
worker->env.add_sub = &mesh_add_sub;
|
||||
@@ -1823,7 +1927,23 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
#endif
|
||||
) {
|
||||
auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
|
||||
auth_zones_pickup_zonemd_verify(worker->env.auth_zones,
|
||||
&worker->env);
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->daemon->cfg->dnstap
|
||||
#ifndef THREADS_DISABLED
|
||||
&& worker->thread_num == 0
|
||||
#endif
|
||||
) {
|
||||
if(!dt_io_thread_start(dtenv->dtio, comm_base_internal(
|
||||
worker->base), worker->daemon->num)) {
|
||||
log_err("could not start dnstap io thread");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* USE_DNSTAP */
|
||||
if(!worker->env.mesh || !worker->env.scratch_buffer) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
@@ -1867,11 +1987,20 @@ 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 */
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(worker->daemon->cfg->dnstap
|
||||
#ifndef THREADS_DISABLED
|
||||
&& worker->thread_num == 0
|
||||
#endif
|
||||
) {
|
||||
dt_io_thread_stop(worker->dtenv.dtio);
|
||||
}
|
||||
dt_deinit(&worker->dtenv);
|
||||
#endif /* USE_DNSTAP */
|
||||
comm_base_delete(worker->base);
|
||||
ub_randfree(worker->rndstate);
|
||||
alloc_clear(&worker->alloc);
|
||||
@@ -1972,22 +2101,22 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
@@ -2000,13 +2129,28 @@ int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
|
||||
void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
|
||||
void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
+233
-54
@@ -48,6 +48,9 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
@@ -67,12 +70,9 @@ static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
|
||||
#define MAX_PTR_QNAME_IPV4 30
|
||||
|
||||
/**
|
||||
* Per-query module-specific state. This is usually a dynamically-allocated
|
||||
* structure, but in our case we only need to store one variable describing the
|
||||
* state the query is in. So we repurpose the minfo pointer by storing an
|
||||
* integer in there.
|
||||
* State of DNS64 processing for a query.
|
||||
*/
|
||||
enum dns64_qstate {
|
||||
enum dns64_state {
|
||||
DNS64_INTERNAL_QUERY, /**< Internally-generated query, no DNS64
|
||||
processing. */
|
||||
DNS64_NEW_QUERY, /**< Query for which we're the first module in
|
||||
@@ -81,6 +81,19 @@ enum dns64_qstate {
|
||||
for which this sub-query is finished. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Per-query module-specific state. For the DNS64 module.
|
||||
*/
|
||||
struct dns64_qstate {
|
||||
/** State of the DNS64 module. */
|
||||
enum dns64_state state;
|
||||
/** If the dns64 module started with no_cache bool set in the qstate,
|
||||
* a message to tell it to not modify the cache contents, then this
|
||||
* is true. The dns64 module is then free to modify that flag for
|
||||
* its own purposes.
|
||||
* Otherwise, it is false, the dns64 module was not told to no_cache */
|
||||
int started_no_cache_store;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
@@ -111,6 +124,11 @@ struct dns64_env {
|
||||
* This is the CIDR length of the prefix. It needs to be between 0 and 96.
|
||||
*/
|
||||
int prefix_net;
|
||||
|
||||
/**
|
||||
* Tree of names for which AAAA is ignored. always synthesize from A.
|
||||
*/
|
||||
rbtree_type ignore_aaaa;
|
||||
};
|
||||
|
||||
|
||||
@@ -173,18 +191,24 @@ 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));
|
||||
if (offset/8+4 < 16)
|
||||
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
|
||||
uint32_t ipv4 = 0;
|
||||
int i, pos;
|
||||
log_assert(ipv6_len == 16); (void)ipv6_len;
|
||||
log_assert(offset == 32 || offset == 40 || offset == 48 || offset == 56 ||
|
||||
offset == 64 || offset == 96);
|
||||
for(i = 0, pos = offset / 8; i < 4; i++, pos++) {
|
||||
if (pos == 8)
|
||||
pos++;
|
||||
ipv4 = ipv4 << 8;
|
||||
ipv4 |= ipv6[pos];
|
||||
}
|
||||
return ipv4;
|
||||
}
|
||||
|
||||
@@ -196,22 +220,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); (void)nm_len;
|
||||
|
||||
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;
|
||||
@@ -223,13 +251,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;
|
||||
@@ -257,24 +287,30 @@ 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)
|
||||
{
|
||||
size_t i;
|
||||
int pos;
|
||||
log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
|
||||
log_assert(prefix_net == 32 || prefix_net == 40 || prefix_net == 48 ||
|
||||
prefix_net == 56 || prefix_net == 64 || prefix_net == 96);
|
||||
(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);
|
||||
aaaa[prefix_net/8+1] |= a[1] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+2] |= a[1] << (8-prefix_net%8);
|
||||
aaaa[prefix_net/8+2] |= a[2] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+3] |= a[2] << (8-prefix_net%8);
|
||||
aaaa[prefix_net/8+3] |= a[3] >> (0+prefix_net%8);
|
||||
if (prefix_net/8+4 < 16) /* <-- my beautiful symmetry is destroyed! */
|
||||
aaaa[prefix_net/8+4] |= a[3] << (8-prefix_net%8);
|
||||
for(i = 0, pos = prefix_net / 8; i < a_len; i++, pos++) {
|
||||
if(pos == 8)
|
||||
aaaa[pos++] = 0;
|
||||
aaaa[pos] = a[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +320,40 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* insert ignore_aaaa element into the tree
|
||||
* @param dns64_env: module env.
|
||||
* @param str: string with domain name.
|
||||
* @return false on failure.
|
||||
*/
|
||||
static int
|
||||
dns64_insert_ignore_aaaa(struct dns64_env* dns64_env, char* str)
|
||||
{
|
||||
/* parse and insert element */
|
||||
struct name_tree_node* node;
|
||||
node = (struct name_tree_node*)calloc(1, sizeof(*node));
|
||||
if(!node) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->name = sldns_str2wire_dname(str, &node->len);
|
||||
if(!node->name) {
|
||||
free(node);
|
||||
log_err("cannot parse dns64-ignore-aaaa: %s", str);
|
||||
return 0;
|
||||
}
|
||||
node->labs = dname_count_labels(node->name);
|
||||
node->dclass = LDNS_RR_CLASS_IN;
|
||||
if(!name_tree_insert(&dns64_env->ignore_aaaa, node,
|
||||
node->name, node->len, node->labs, node->dclass)) {
|
||||
/* ignore duplicate element */
|
||||
free(node->name);
|
||||
free(node);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function applies the configuration found in the parsed configuration
|
||||
* file \a cfg to this instance of the dns64 module. Currently only the DNS64
|
||||
@@ -295,6 +365,7 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
@@ -306,11 +377,18 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (dns64_env->prefix_net < 0 || dns64_env->prefix_net > 96) {
|
||||
log_err("dns64-prefix length it not between 0 and 96: %s",
|
||||
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
|
||||
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
|
||||
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
|
||||
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
|
||||
cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
|
||||
if(!dns64_insert_ignore_aaaa(dns64_env, s->str))
|
||||
return 0;
|
||||
}
|
||||
name_tree_init_parents(&dns64_env->ignore_aaaa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -329,7 +407,8 @@ dns64_init(struct module_env* env, int id)
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
env->modinfo[id] = (void*)dns64_env;
|
||||
env->modinfo[id] = (void*)dns64_env;
|
||||
name_tree_init(&dns64_env->ignore_aaaa);
|
||||
if (!dns64_apply_cfg(dns64_env, env->cfg)) {
|
||||
log_err("dns64: could not apply configuration settings.");
|
||||
return 0;
|
||||
@@ -337,6 +416,16 @@ dns64_init(struct module_env* env, int id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** free ignore AAAA elements */
|
||||
static void
|
||||
free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct name_tree_node* n = (struct name_tree_node*)node;
|
||||
if(!n) return;
|
||||
free(n->name);
|
||||
free(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinitializes this instance of the dns64 module.
|
||||
*
|
||||
@@ -346,8 +435,14 @@ dns64_init(struct module_env* env, int id)
|
||||
void
|
||||
dns64_deinit(struct module_env* env, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env;
|
||||
if (!env)
|
||||
return;
|
||||
dns64_env = (struct dns64_env*)env->modinfo[id];
|
||||
if(dns64_env) {
|
||||
traverse_postorder(&dns64_env->ignore_aaaa, free_ignore_aaaa_node,
|
||||
NULL);
|
||||
}
|
||||
free(env->modinfo[id]);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
@@ -372,7 +467,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. */
|
||||
|
||||
/*
|
||||
@@ -395,7 +491,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));
|
||||
@@ -405,7 +502,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
if (subq) {
|
||||
subq->curmod = id;
|
||||
subq->ext_state[id] = module_state_initial;
|
||||
subq->minfo[id] = NULL;
|
||||
subq->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
return module_wait_subquery;
|
||||
@@ -440,6 +537,25 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
return module_wait_subquery;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if query name is in the always synth config.
|
||||
* The ignore-aaaa list has names for which the AAAA for the domain is
|
||||
* ignored and the A is always used to create the answer.
|
||||
* @param qstate: query state.
|
||||
* @param id: module id.
|
||||
* @return true if the name is covered by ignore-aaaa.
|
||||
*/
|
||||
static int
|
||||
dns64_always_synth_for_qname(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id];
|
||||
int labs = dname_count_labels(qstate->qinfo.qname);
|
||||
struct name_tree_node* node = name_tree_lookup(&dns64_env->ignore_aaaa,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len, labs,
|
||||
qstate->qinfo.qclass);
|
||||
return (node != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "pass" event for a query. This event is received when a new query
|
||||
* is received by this module. The query may have been generated internally by
|
||||
@@ -456,7 +572,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
static enum module_ext_state
|
||||
handle_event_pass(struct module_qstate* qstate, int id)
|
||||
{
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
if (iq && iq->state == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
|
||||
&& qstate->qinfo.qname_len == 74
|
||||
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
|
||||
@@ -464,12 +581,20 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
return handle_ipv6_ptr(qstate, id);
|
||||
|
||||
if (qstate->env->cfg->dns64_synthall &&
|
||||
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
iq && iq->state == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
if(dns64_always_synth_for_qname(qstate, id) &&
|
||||
iq && iq->state == DNS64_NEW_QUERY
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
|
||||
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/* We are finished when our sub-query is finished. */
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
|
||||
if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
|
||||
return module_finished;
|
||||
|
||||
/* Otherwise, pass request to next module. */
|
||||
@@ -490,6 +615,7 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
static enum module_ext_state
|
||||
handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
/*
|
||||
* In many cases we have nothing special to do. From most to least common:
|
||||
*
|
||||
@@ -501,17 +627,36 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
* synthesize in (sec 5.1.2 of RFC6147).
|
||||
* - A successful AAAA query with an answer.
|
||||
*/
|
||||
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
||||
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
||||
|| (qstate->query_flags & BIT_CD)
|
||||
|| (qstate->return_msg &&
|
||||
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& !(qstate->return_msg &&
|
||||
qstate->return_msg->rep &&
|
||||
reply_find_answer_rrset(&qstate->qinfo,
|
||||
qstate->return_msg->rep)))
|
||||
return module_finished;
|
||||
/* not internal, type AAAA, not CD, and no answer RRset,
|
||||
* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
/* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& dns64_always_synth_for_qname(qstate, id)) {
|
||||
/* if it is not internal, AAAA, not CD and listed domain,
|
||||
* generate from A record and ignore AAAA */
|
||||
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/* Store the response in cache. */
|
||||
if ( (!iq || !iq->started_no_cache_store) &&
|
||||
qstate->return_msg && qstate->return_msg->rep &&
|
||||
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
|
||||
0, 0, 0, NULL, qstate->query_flags))
|
||||
log_err("out of memory");
|
||||
|
||||
/* do nothing */
|
||||
return module_finished;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,6 +675,7 @@ void
|
||||
dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
struct dns64_qstate* iq;
|
||||
(void)outbound;
|
||||
verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]),
|
||||
@@ -539,7 +685,12 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
switch(event) {
|
||||
case module_event_new:
|
||||
/* Tag this query as being new and fall through. */
|
||||
qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
|
||||
iq = (struct dns64_qstate*)regional_alloc(
|
||||
qstate->region, sizeof(*iq));
|
||||
qstate->minfo[id] = iq;
|
||||
iq->state = DNS64_NEW_QUERY;
|
||||
iq->started_no_cache_store = qstate->no_cache_store;
|
||||
qstate->no_cache_store = 1;
|
||||
/* fallthrough */
|
||||
case module_event_pass:
|
||||
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
||||
@@ -551,6 +702,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
|
||||
@@ -571,7 +727,7 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
|
||||
*dd_out = NULL;
|
||||
return; /* integer overflow protection in alloc */
|
||||
}
|
||||
if (!(dd = *dd_out = regional_alloc(region,
|
||||
if (!(dd = *dd_out = regional_alloc_zero(region,
|
||||
sizeof(struct packed_rrset_data)
|
||||
+ fd->count * (sizeof(size_t) + sizeof(time_t) +
|
||||
sizeof(uint8_t*) + 2 + 16)))) {
|
||||
@@ -606,8 +762,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];
|
||||
}
|
||||
|
||||
@@ -677,8 +835,9 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
* Build the actual reply.
|
||||
*/
|
||||
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
|
||||
rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets,
|
||||
rep->ar_numrrsets, rep->rrset_count, rep->security);
|
||||
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
|
||||
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
|
||||
rep->rrset_count, rep->security);
|
||||
if(!cp)
|
||||
return;
|
||||
|
||||
@@ -705,6 +864,12 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
|
||||
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, 0);
|
||||
/* Delete negative AAAA in msg cache for CNAMEs,
|
||||
* stored by the iterator module */
|
||||
if(i != 0) /* if not the first RR */
|
||||
msg_cache_remove(super->env, dk->rk.dname,
|
||||
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, 0);
|
||||
} else {
|
||||
dk->entry.hash = fk->entry.hash;
|
||||
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
|
||||
@@ -756,9 +921,10 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
|
||||
* initial query's domain name.
|
||||
*/
|
||||
answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
|
||||
log_assert(answer);
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
if(answer) {
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -774,6 +940,7 @@ void
|
||||
dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super)
|
||||
{
|
||||
struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id];
|
||||
log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
|
||||
&qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "super is", &super->qinfo);
|
||||
@@ -782,15 +949,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)
|
||||
@@ -805,7 +984,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");
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ AC_DEFUN([dnsc_DNSCRYPT],
|
||||
[opt_dnscrypt=$enableval], [opt_dnscrypt=no])
|
||||
|
||||
if test "x$opt_dnscrypt" != "xno"; then
|
||||
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path],
|
||||
AC_ARG_WITH([libsodium], AS_HELP_STRING([--with-libsodium=path],
|
||||
[Path where libsodium is installed, for dnscrypt]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
|
||||
+134
-85
@@ -39,19 +39,22 @@
|
||||
#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"
|
||||
#include "util/netevent.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include <fstrm.h>
|
||||
#include <protobuf-c/protobuf-c.h>
|
||||
|
||||
#include "dnstap/dnstap.h"
|
||||
#include "dnstap/dtstream.h"
|
||||
#include "dnstap/dnstap.pb-c.h"
|
||||
|
||||
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
|
||||
#define DNSTAP_INITIAL_BUF_SIZE 256
|
||||
|
||||
struct dt_msg {
|
||||
@@ -86,13 +89,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
fstrm_res res;
|
||||
if (!buf)
|
||||
return;
|
||||
res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
|
||||
fstrm_free_wrapper, NULL);
|
||||
if (res != fstrm_res_success)
|
||||
free(buf);
|
||||
dt_msg_queue_submit(env->msgqueue, buf, len_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -118,56 +115,50 @@ dt_msg_init(const struct dt_env *env,
|
||||
}
|
||||
}
|
||||
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
/* check that the socket file can be opened and exists, print error if not */
|
||||
static void
|
||||
check_socket_file(const char* socket_path)
|
||||
{
|
||||
#ifdef UNBOUND_DEBUG
|
||||
fstrm_res res;
|
||||
#endif
|
||||
struct dt_env *env;
|
||||
struct fstrm_iothr_options *fopt;
|
||||
struct fstrm_unix_writer_options *fuwopt;
|
||||
struct fstrm_writer *fw;
|
||||
struct fstrm_writer_options *fwopt;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
|
||||
socket_path);
|
||||
log_assert(socket_path != NULL);
|
||||
log_assert(num_workers > 0);
|
||||
struct dt_env *
|
||||
dt_create(struct config_file* cfg)
|
||||
{
|
||||
struct dt_env *env;
|
||||
|
||||
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
|
||||
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
|
||||
char* p = cfg->dnstap_socket_path;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(p,
|
||||
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
|
||||
p += strlen(cfg->chrootdir);
|
||||
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
|
||||
p);
|
||||
check_socket_file(p);
|
||||
}
|
||||
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
fwopt = fstrm_writer_options_init();
|
||||
#ifdef UNBOUND_DEBUG
|
||||
res =
|
||||
#else
|
||||
(void)
|
||||
#endif
|
||||
fstrm_writer_options_add_content_type(fwopt,
|
||||
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
log_assert(res == fstrm_res_success);
|
||||
|
||||
fuwopt = fstrm_unix_writer_options_init();
|
||||
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
|
||||
|
||||
fw = fstrm_unix_writer_init(fuwopt, fwopt);
|
||||
log_assert(fw != NULL);
|
||||
|
||||
fopt = fstrm_iothr_options_init();
|
||||
fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
|
||||
env->iothr = fstrm_iothr_init(fopt, &fw);
|
||||
if (env->iothr == NULL) {
|
||||
verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed");
|
||||
fstrm_writer_destroy(&fw);
|
||||
env->dtio = dt_io_thread_create();
|
||||
if(!env->dtio) {
|
||||
log_err("malloc failure");
|
||||
free(env);
|
||||
env = NULL;
|
||||
return NULL;
|
||||
}
|
||||
fstrm_iothr_options_destroy(&fopt);
|
||||
fstrm_unix_writer_options_destroy(&fuwopt);
|
||||
fstrm_writer_options_destroy(&fwopt);
|
||||
|
||||
if(!dt_io_thread_apply_cfg(env->dtio, cfg)) {
|
||||
dt_io_thread_delete(env->dtio);
|
||||
free(env);
|
||||
return NULL;
|
||||
}
|
||||
dt_apply_cfg(env, cfg);
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -253,21 +244,35 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
}
|
||||
|
||||
int
|
||||
dt_init(struct dt_env *env)
|
||||
dt_init(struct dt_env *env, struct comm_base* base)
|
||||
{
|
||||
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
|
||||
if (env->ioq == NULL)
|
||||
env->msgqueue = dt_msg_queue_create(base);
|
||||
if(!env->msgqueue) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
if(!dt_io_thread_register_queue(env->dtio, env->msgqueue)) {
|
||||
log_err("malloc failure");
|
||||
dt_msg_queue_delete(env->msgqueue);
|
||||
env->msgqueue = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dt_deinit(struct dt_env* env)
|
||||
{
|
||||
dt_io_thread_unregister_queue(env->dtio, env->msgqueue);
|
||||
dt_msg_queue_delete(env->msgqueue);
|
||||
}
|
||||
|
||||
void
|
||||
dt_delete(struct dt_env *env)
|
||||
{
|
||||
if (!env)
|
||||
return;
|
||||
verbose(VERB_OPS, "closing dnstap socket");
|
||||
fstrm_iothr_destroy(&env->iothr);
|
||||
dt_io_thread_delete(env->dtio);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
@@ -297,44 +302,75 @@ dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
|
||||
|
||||
static void
|
||||
dt_msg_fill_net(struct dt_msg *dm,
|
||||
struct sockaddr_storage *ss,
|
||||
struct sockaddr_storage *qs,
|
||||
struct sockaddr_storage *rs,
|
||||
enum comm_point_type cptype,
|
||||
ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
|
||||
uint32_t *port, protobuf_c_boolean *has_port)
|
||||
ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
|
||||
uint32_t *qport, protobuf_c_boolean *has_qport,
|
||||
ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
|
||||
uint32_t *rport, protobuf_c_boolean *has_rport)
|
||||
{
|
||||
log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
|
||||
if (ss->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
|
||||
log_assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
|
||||
if (qs->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *q = (struct sockaddr_in6 *) qs;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = s->sin6_addr.s6_addr;
|
||||
addr->len = 16; /* IPv6 */
|
||||
*has_addr = 1;
|
||||
qaddr->data = q->sin6_addr.s6_addr;
|
||||
qaddr->len = 16; /* IPv6 */
|
||||
*has_qaddr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin6_port);
|
||||
*has_port = 1;
|
||||
} else if (ss->ss_family == AF_INET) {
|
||||
struct sockaddr_in *s = (struct sockaddr_in *) ss;
|
||||
*qport = ntohs(q->sin6_port);
|
||||
*has_qport = 1;
|
||||
} else if (qs->ss_family == AF_INET) {
|
||||
struct sockaddr_in *q = (struct sockaddr_in *) qs;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = (uint8_t *) &s->sin_addr.s_addr;
|
||||
addr->len = 4; /* IPv4 */
|
||||
*has_addr = 1;
|
||||
qaddr->data = (uint8_t *) &q->sin_addr.s_addr;
|
||||
qaddr->len = 4; /* IPv4 */
|
||||
*has_qaddr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin_port);
|
||||
*has_port = 1;
|
||||
*qport = ntohs(q->sin_port);
|
||||
*has_qport = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This block is to fill second set of fields in DNSTAP-message defined as request_/response_ names.
|
||||
* Additional responsive structure is: struct sockaddr_storage *rs
|
||||
*/
|
||||
if (rs && rs->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *r = (struct sockaddr_in6 *) rs;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
raddr->data = r->sin6_addr.s6_addr;
|
||||
raddr->len = 16; /* IPv6 */
|
||||
*has_raddr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*rport = ntohs(r->sin6_port);
|
||||
*has_rport = 1;
|
||||
} else if (rs && rs->ss_family == AF_INET) {
|
||||
struct sockaddr_in *r = (struct sockaddr_in *) rs;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
raddr->data = (uint8_t *) &r->sin_addr.s_addr;
|
||||
raddr->len = 4; /* IPv4 */
|
||||
*has_raddr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*rport = ntohs(r->sin_port);
|
||||
*has_rport = 1;
|
||||
}
|
||||
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
if (cptype == comm_udp) {
|
||||
/* socket_protocol */
|
||||
@@ -350,6 +386,7 @@ dt_msg_fill_net(struct dt_msg *dm,
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *qmsg)
|
||||
{
|
||||
@@ -369,11 +406,14 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
dt_msg_fill_net(&dm, qsock, rsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
&dm.m.query_port, &dm.m.has_query_port,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
@@ -382,6 +422,7 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *rmsg)
|
||||
{
|
||||
@@ -401,11 +442,13 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
dt_msg_fill_net(&dm, qsock, rsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
&dm.m.query_port, &dm.m.has_query_port,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
@@ -414,6 +457,7 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
sldns_buffer *qmsg)
|
||||
@@ -449,11 +493,13 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
dt_msg_fill_net(&dm, rsock, qsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
&dm.m.response_port, &dm.m.has_response_port,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
@@ -462,6 +508,7 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
@@ -505,11 +552,13 @@ dt_msg_send_outside_response(struct dt_env *env,
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
dt_msg_fill_net(&dm, rsock, qsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
&dm.m.response_port, &dm.m.has_response_port,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
|
||||
+25
-12
@@ -40,16 +40,16 @@
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
struct config_file;
|
||||
struct fstrm_io;
|
||||
struct fstrm_queue;
|
||||
struct sldns_buffer;
|
||||
struct dt_msg_queue;
|
||||
|
||||
struct dt_env {
|
||||
/** dnstap I/O thread */
|
||||
struct fstrm_iothr *iothr;
|
||||
/** the io thread (made by the struct daemon) */
|
||||
struct dt_io_thread* dtio;
|
||||
|
||||
/** dnstap I/O thread input queue */
|
||||
struct fstrm_iothr_queue *ioq;
|
||||
/** valid in worker struct, not in daemon struct, the per-worker
|
||||
* message list */
|
||||
struct dt_msg_queue* msgqueue;
|
||||
|
||||
/** dnstap "identity" field, NULL if disabled */
|
||||
char *identity;
|
||||
@@ -84,12 +84,11 @@ struct dt_env {
|
||||
* of the structure) to ensure lock-free access to its own per-worker circular
|
||||
* queue. Duplicate the environment object if more than one worker needs to
|
||||
* share access to the dnstap I/O socket.
|
||||
* @param socket_path: path to dnstap logging socket, must be non-NULL.
|
||||
* @param num_workers: number of worker threads, must be > 0.
|
||||
* @param cfg: with config settings.
|
||||
* @return dt_env object, NULL on failure.
|
||||
*/
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers);
|
||||
dt_create(struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Apply config settings.
|
||||
@@ -102,10 +101,16 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
/**
|
||||
* Initialize per-worker state in dnstap environment object.
|
||||
* @param env: dnstap environment object to initialize, created with dt_create().
|
||||
* @param base: event base for wakeup timer.
|
||||
* @return: true on success, false on failure.
|
||||
*/
|
||||
int
|
||||
dt_init(struct dt_env *env);
|
||||
dt_init(struct dt_env *env, struct comm_base* base);
|
||||
|
||||
/**
|
||||
* Deletes the per-worker state created by dt_init
|
||||
*/
|
||||
void dt_deinit(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* Delete dnstap environment object. Closes dnstap I/O socket and deletes all
|
||||
@@ -118,12 +123,14 @@ dt_delete(struct dt_env *env);
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_QUERY.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param rsock: local (service) address/port.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param qmsg: query message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *qmsg);
|
||||
|
||||
@@ -131,12 +138,14 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param rsock: local (service) address/port.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param rmsg: response message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *rmsg);
|
||||
|
||||
@@ -145,7 +154,8 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
* FORWARDER_QUERY. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the query is being sent to.
|
||||
* @param rsock: address/port of server (upstream) the query is being sent to.
|
||||
* @param qsock: address/port of server (local) the query is being sent from.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
@@ -154,6 +164,7 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
struct sldns_buffer *qmsg);
|
||||
@@ -163,7 +174,8 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
* FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the response was received from.
|
||||
* @param rsock: address/port of server (upstream) the response was received from.
|
||||
* @param qsock: address/port of server (local) the response was received to.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
@@ -176,6 +188,7 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
|
||||
+2
-9
@@ -7,7 +7,7 @@ AC_DEFUN([dt_DNSTAP],
|
||||
[
|
||||
AC_ARG_ENABLE([dnstap],
|
||||
AS_HELP_STRING([--enable-dnstap],
|
||||
[Enable dnstap support (requires fstrm, protobuf-c)]),
|
||||
[Enable dnstap support (requires protobuf-c)]),
|
||||
[opt_dnstap=$enableval], [opt_dnstap=no])
|
||||
|
||||
AC_ARG_WITH([dnstap-socket-path],
|
||||
@@ -20,7 +20,7 @@ AC_DEFUN([dt_DNSTAP],
|
||||
if test -z "$PROTOC_C"; then
|
||||
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
|
||||
fi
|
||||
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
|
||||
AC_ARG_WITH([protobuf-c], AS_HELP_STRING([--with-protobuf-c=path],
|
||||
[Path where protobuf-c is installed, for dnstap]), [
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
|
||||
@@ -40,13 +40,6 @@ AC_DEFUN([dt_DNSTAP],
|
||||
fi
|
||||
fi
|
||||
])
|
||||
AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
|
||||
[Path where libfstrm is installed, for dnstap]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
])
|
||||
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
|
||||
AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!]))
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
|
||||
$2
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Definitions for the Frame Streams data transport protocol for
|
||||
* dnstap message logs.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dnstap/dnstap_fstrm.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
void* fstrm_create_control_frame_start(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* start framestream message:
|
||||
* 4byte 0: control indicator.
|
||||
* 4byte bigendian: length of control frame
|
||||
* 4byte bigendian: type START
|
||||
* 4byte bigendian: option: content-type
|
||||
* 4byte bigendian: length of string
|
||||
* string of content type (dnstap)
|
||||
*/
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control)
|
||||
return NULL;
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_START);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_stop(size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* stop framestream message:
|
||||
* 4byte 0: control indicator.
|
||||
* 4byte bigendian: length of control frame
|
||||
* 4byte bigendian: type STOP
|
||||
*/
|
||||
n = 4+4+4;
|
||||
control = malloc(n);
|
||||
if(!control)
|
||||
return NULL;
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4);
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_STOP);
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* start bidirectional stream:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type READY
|
||||
* 4 bytes bigendian frame option content type
|
||||
* 4 bytes bigendian length of string
|
||||
* string of content type.
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* control frame on reply:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type ACCEPT
|
||||
* 4 bytes bigendian frame option content type
|
||||
* 4 bytes bigendian length of string
|
||||
* string of content type.
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_finish(size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* control frame on reply:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type FINISH
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4;
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4);
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH);
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
char* fstrm_describe_control(void* pkt, size_t len)
|
||||
{
|
||||
uint32_t frametype = 0;
|
||||
char buf[512];
|
||||
char* str = buf;
|
||||
size_t remain, slen = sizeof(buf);
|
||||
uint8_t* pos;
|
||||
|
||||
buf[0]=0;
|
||||
if(len < 4) {
|
||||
snprintf(buf, sizeof(buf), "malformed control frame, "
|
||||
"too short, len=%u", (unsigned int)len);
|
||||
return strdup(buf);
|
||||
}
|
||||
frametype = sldns_read_uint32(pkt);
|
||||
if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) {
|
||||
(void)sldns_str_print(&str, &slen, "accept");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_START) {
|
||||
(void)sldns_str_print(&str, &slen, "start");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_STOP) {
|
||||
(void)sldns_str_print(&str, &slen, "stop");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_READY) {
|
||||
(void)sldns_str_print(&str, &slen, "ready");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_FINISH) {
|
||||
(void)sldns_str_print(&str, &slen, "finish");
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen, "type%d", (int)frametype);
|
||||
}
|
||||
|
||||
/* show the content type options */
|
||||
pos = pkt + 4;
|
||||
remain = len - 4;
|
||||
while(remain >= 8) {
|
||||
uint32_t field_type = sldns_read_uint32(pos);
|
||||
uint32_t field_len = sldns_read_uint32(pos+4);
|
||||
if(remain < field_len) {
|
||||
(void)sldns_str_print(&str, &slen, "malformed_field");
|
||||
break;
|
||||
}
|
||||
if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
|
||||
char tempf[512];
|
||||
(void)sldns_str_print(&str, &slen, " content-type(");
|
||||
if(field_len < sizeof(tempf)-1) {
|
||||
memmove(tempf, pos+8, field_len);
|
||||
tempf[field_len] = 0;
|
||||
(void)sldns_str_print(&str, &slen, "%s", tempf);
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen, "<error-too-long>");
|
||||
}
|
||||
(void)sldns_str_print(&str, &slen, ")");
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen,
|
||||
" field(type %u, length %u)",
|
||||
(unsigned int)field_type,
|
||||
(unsigned int)field_len);
|
||||
}
|
||||
pos += 8 + field_len;
|
||||
remain -= (8 + field_len);
|
||||
}
|
||||
if(remain > 0)
|
||||
(void)sldns_str_print(&str, &slen, " trailing-bytes"
|
||||
"(length %u)", (unsigned int)remain);
|
||||
return strdup(buf);
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Definitions for the Frame Streams data transport protocol for
|
||||
* dnstap message logs.
|
||||
*/
|
||||
|
||||
#ifndef DNSTAP_FSTRM_H
|
||||
#define DNSTAP_FSTRM_H
|
||||
|
||||
/* Frame Streams data transfer protocol encode for DNSTAP messages.
|
||||
* The protocol looks to be specified in the libfstrm library.
|
||||
*
|
||||
* Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent
|
||||
* comments and fstrm/control.c for some bytesize details (the content type
|
||||
* length).
|
||||
*
|
||||
* The Frame Streams can be unidirectional or bi-directional.
|
||||
* bi-directional streams use control frame types READY, ACCEPT and FINISH.
|
||||
* uni-directional streams use control frame types START and STOP.
|
||||
* unknown control frame types should be ignored by the receiver, they
|
||||
* do not change the data frame encoding.
|
||||
*
|
||||
* bi-directional control frames implement a simple handshake protocol
|
||||
* between sender and receiver.
|
||||
*
|
||||
* The uni-directional control frames have one start and one stop frame,
|
||||
* before and after the data. The start frame can have a content type.
|
||||
* The start and stop frames are not optional.
|
||||
*
|
||||
* data frames are preceded by 4byte length, bigendian.
|
||||
* zero length data frames are not possible, they are an escape that
|
||||
* signals the presence of a control frame.
|
||||
*
|
||||
* a control frame consists of 0 value in 4byte bigendian, this is really
|
||||
* the data frame length, with 0 the escape sequence that indicates one
|
||||
* control frame follows.
|
||||
* Then, 4byte bigendian, length of the control frame message.
|
||||
* Then, the control frame payload (of that length). with in it:
|
||||
* 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH).
|
||||
* perhaps nothing more (STOP, FINISH), but for other types maybe
|
||||
* control fields
|
||||
* 4byte bigendian, the control-field-type, currently only content-type.
|
||||
* 4byte bigendian, length of the string for this option.
|
||||
* .. bytes of that string.
|
||||
*
|
||||
* The START type can have only one field. Field max len 256.
|
||||
* control frame max frame length 512 (excludes the 0-escape and control
|
||||
* frame length bytes).
|
||||
*
|
||||
* the bidirectional type of transmission is like this:
|
||||
* client sends READY (with content type included),
|
||||
* client waits for ACCEPT (with content type included),
|
||||
* client sends START (with matched content type from ACCEPT)
|
||||
* .. data frames
|
||||
* client sends STOP.
|
||||
* client waits for FINISH frame.
|
||||
*
|
||||
*/
|
||||
|
||||
/** max length of Frame Streams content type field string */
|
||||
#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256
|
||||
/** control frame value to denote the control frame ACCEPT */
|
||||
#define FSTRM_CONTROL_FRAME_ACCEPT 0x01
|
||||
/** control frame value to denote the control frame START */
|
||||
#define FSTRM_CONTROL_FRAME_START 0x02
|
||||
/** control frame value to denote the control frame STOP */
|
||||
#define FSTRM_CONTROL_FRAME_STOP 0x03
|
||||
/** control frame value to denote the control frame READY */
|
||||
#define FSTRM_CONTROL_FRAME_READY 0x04
|
||||
/** control frame value to denote the control frame FINISH */
|
||||
#define FSTRM_CONTROL_FRAME_FINISH 0x05
|
||||
/** the constant that denotes the control field type that is the
|
||||
* string for the content type of the stream. */
|
||||
#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01
|
||||
/** the content type for DNSTAP frame streams */
|
||||
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type START.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
|
||||
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_start(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type READY.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
|
||||
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type STOP.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_stop(size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type ACCEPT.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* for dnstap streams use DNSTAP_CONTENT_TYPE.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type FINISH.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_finish(size_t* len);
|
||||
|
||||
/**
|
||||
* Return string that describes a control packet. For debug, logs.
|
||||
* Like 'start content-type(protobuf:dnstap.Dnstap)' or 'stop'.
|
||||
* @param pkt: the packet data, that is the data after the 4 zero start
|
||||
* bytes and 4 length bytes.
|
||||
* @param len: the length of the control packet data, in pkt. This is the
|
||||
* ntohl of the 4 bytes length preceding the data.
|
||||
* @return zero delimited string, malloced. Or NULL on malloc failure.
|
||||
*/
|
||||
char* fstrm_describe_control(void* pkt, size_t len);
|
||||
|
||||
#endif /* DNSTAP_FSTRM_H */
|
||||
+2184
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* An implementation of the Frame Streams data transport protocol for
|
||||
* the Unbound DNSTAP message logging facility.
|
||||
*/
|
||||
|
||||
#ifndef DTSTREAM_H
|
||||
#define DTSTREAM_H
|
||||
|
||||
#include "util/locks.h"
|
||||
struct dt_msg_entry;
|
||||
struct dt_io_list_item;
|
||||
struct dt_io_thread;
|
||||
struct config_file;
|
||||
struct comm_base;
|
||||
|
||||
/**
|
||||
* A message buffer with dnstap messages queued up. It is per-worker.
|
||||
* It has locks to synchronize. If the buffer is full, a new message
|
||||
* cannot be added and is discarded. A thread reads the messages and sends
|
||||
* them.
|
||||
*/
|
||||
struct dt_msg_queue {
|
||||
/** lock of the buffer structure. Hold this lock to add or remove
|
||||
* entries to the buffer. Release it so that other threads can also
|
||||
* put messages to log, or a message can be taken out to send away
|
||||
* by the writer thread.
|
||||
*/
|
||||
lock_basic_type lock;
|
||||
/** the maximum size of the buffer, in bytes */
|
||||
size_t maxsize;
|
||||
/** current size of the buffer, in bytes. data bytes of messages.
|
||||
* If a new message make it more than maxsize, the buffer is full */
|
||||
size_t cursize;
|
||||
/** number of messages in the queue */
|
||||
int msgcount;
|
||||
/** list of messages. The messages are added to the back and taken
|
||||
* out from the front. */
|
||||
struct dt_msg_entry* first, *last;
|
||||
/** reference to the io thread to wakeup */
|
||||
struct dt_io_thread* dtio;
|
||||
/** the wakeup timer for dtio, on worker event base */
|
||||
struct comm_timer* wakeup_timer;
|
||||
};
|
||||
|
||||
/**
|
||||
* An entry in the dt_msg_queue. contains one DNSTAP message.
|
||||
* It is malloced.
|
||||
*/
|
||||
struct dt_msg_entry {
|
||||
/** next in the list. */
|
||||
struct dt_msg_entry* next;
|
||||
/** the buffer with the data to send, an encoded DNSTAP message */
|
||||
void* buf;
|
||||
/** the length to send. */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Containing buffer and counter for reading DNSTAP frames.
|
||||
*/
|
||||
struct dt_frame_read_buf {
|
||||
/** Buffer containing frame, except length counter(s). */
|
||||
void* buf;
|
||||
/** Number of bytes written to buffer. */
|
||||
size_t buf_count;
|
||||
/** Capacity of the buffer. */
|
||||
size_t buf_cap;
|
||||
|
||||
/** Frame length field. Will contain the 2nd length field for control
|
||||
* frames. */
|
||||
uint32_t frame_len;
|
||||
/** Number of bytes that have been written to the frame_length field. */
|
||||
size_t frame_len_done;
|
||||
|
||||
/** Set to 1 if this is a control frame, 0 otherwise (ie data frame). */
|
||||
int control_frame;
|
||||
};
|
||||
|
||||
/**
|
||||
* IO thread that reads from the queues and writes them.
|
||||
*/
|
||||
struct dt_io_thread {
|
||||
/** the thread number for the dtio thread,
|
||||
* must be first to cast thread arg to int* in checklock code. */
|
||||
int threadnum;
|
||||
/** event base, for event handling */
|
||||
void* event_base;
|
||||
/** list of queues that is registered to get written */
|
||||
struct dt_io_list_item* io_list;
|
||||
/** iterator point in the io_list, to pick from them in a
|
||||
* round-robin fashion, instead of only from the first when busy.
|
||||
* if NULL it means start at the start of the list. */
|
||||
struct dt_io_list_item* io_list_iter;
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
|
||||
void* ssl_ctx;
|
||||
/** if SNI will be used for TLS connections. */
|
||||
int tls_use_sni;
|
||||
|
||||
/** file descriptor that the thread writes to */
|
||||
int fd;
|
||||
/** event structure that the thread uses */
|
||||
void* event;
|
||||
/** the event is added */
|
||||
int event_added;
|
||||
/** event added is a write event */
|
||||
int event_added_is_write;
|
||||
/** check for nonblocking connect errors on fd */
|
||||
int check_nb_connect;
|
||||
/** ssl for current connection, type SSL* */
|
||||
void* ssl;
|
||||
/** true if the handshake for SSL is done, 0 if not */
|
||||
int ssl_handshake_done;
|
||||
/** true if briefly the SSL wants a read event, 0 if not.
|
||||
* This happens during negotiation, we then do not want to write,
|
||||
* but wait for a read event. */
|
||||
int ssl_brief_read;
|
||||
/** true if SSL_read is waiting for a write event. Set back to 0 after
|
||||
* single write event is handled. */
|
||||
int ssl_brief_write;
|
||||
|
||||
/** the buffer that currently getting written, or NULL if no
|
||||
* (partial) message written now */
|
||||
void* cur_msg;
|
||||
/** length of the current message */
|
||||
size_t cur_msg_len;
|
||||
/** number of bytes written for the current message */
|
||||
size_t cur_msg_done;
|
||||
/** number of bytes of the length that have been written,
|
||||
* for the current message length that precedes the frame */
|
||||
size_t cur_msg_len_done;
|
||||
|
||||
/** lock on wakeup_timer_enabled */
|
||||
lock_basic_type wakeup_timer_lock;
|
||||
/** if wakeup timer is enabled in some thread */
|
||||
int wakeup_timer_enabled;
|
||||
/** command pipe that stops the pipe if closed. Used to quit
|
||||
* the program. [0] is read, [1] is written to. */
|
||||
int commandpipe[2];
|
||||
/** the event to listen to the commandpipe */
|
||||
void* command_event;
|
||||
/** the io thread wants to exit */
|
||||
int want_to_exit;
|
||||
|
||||
/** in stop flush, this is nonNULL and references the stop_ev */
|
||||
void* stop_flush_event;
|
||||
|
||||
/** the timer event for connection retries */
|
||||
void* reconnect_timer;
|
||||
/** if the reconnect timer is added to the event base */
|
||||
int reconnect_is_added;
|
||||
/** the current reconnection timeout, it is increased with
|
||||
* exponential backoff, in msec */
|
||||
int reconnect_timeout;
|
||||
|
||||
/** If the log server is connected to over unix domain sockets,
|
||||
* eg. a file is named that is created to log onto. */
|
||||
int upstream_is_unix;
|
||||
/** if the log server is connected to over TCP. The ip address and
|
||||
* port are used */
|
||||
int upstream_is_tcp;
|
||||
/** if the log server is connected to over TLS. ip address, port,
|
||||
* and client certificates can be used for authentication. */
|
||||
int upstream_is_tls;
|
||||
|
||||
/** Perform bidirectional Frame Streams handshake before sending
|
||||
* messages. */
|
||||
int is_bidirectional;
|
||||
/** Set if the READY control frame has been sent. */
|
||||
int ready_frame_sent;
|
||||
/** Set if valid ACCEPT frame is received. */
|
||||
int accept_frame_received;
|
||||
/** (partially) read frame */
|
||||
struct dt_frame_read_buf read_frame;
|
||||
|
||||
/** the file path for unix socket (or NULL) */
|
||||
char* socket_path;
|
||||
/** the ip address and port number (or NULL) */
|
||||
char* ip_str;
|
||||
/** is the TLS upstream authenticated by name, if nonNULL,
|
||||
* we use the same cert bundle as used by other TLS streams. */
|
||||
char* tls_server_name;
|
||||
/** are client certificates in use */
|
||||
int use_client_certs;
|
||||
/** client cert files: the .key file */
|
||||
char* client_key_file;
|
||||
/** client cert files: the .pem file */
|
||||
char* client_cert_file;
|
||||
};
|
||||
|
||||
/**
|
||||
* IO thread list of queues list item
|
||||
* lists a worker queue that should be looked at and sent to the log server.
|
||||
*/
|
||||
struct dt_io_list_item {
|
||||
/** next in the list of buffers to inspect */
|
||||
struct dt_io_list_item* next;
|
||||
/** buffer of this worker */
|
||||
struct dt_msg_queue* queue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new (empty) worker message queue. Limit set to default on max.
|
||||
* @param base: event base for wakeup timer.
|
||||
* @return NULL on malloc failure or a new queue (not locked).
|
||||
*/
|
||||
struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base);
|
||||
|
||||
/**
|
||||
* Delete a worker message queue. It has to be unlinked from access,
|
||||
* so it can be deleted without lock worries. The queue is emptied (deleted).
|
||||
* @param mq: message queue.
|
||||
*/
|
||||
void dt_msg_queue_delete(struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Submit a message to the queue. The queue is locked by the routine,
|
||||
* the message is inserted, and then the queue is unlocked so the
|
||||
* message can be picked up by the writer thread.
|
||||
* @param mq: message queue.
|
||||
* @param buf: buffer with message (dnstap contents).
|
||||
* The buffer must have been malloced by caller. It is linked in
|
||||
* the queue, and is free()d after use. If the routine fails
|
||||
* the buffer is freed as well (and nothing happens, the item
|
||||
* could not be logged).
|
||||
* @param len: length of buffer.
|
||||
*/
|
||||
void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len);
|
||||
|
||||
/** timer callback to wakeup dtio thread to process messages */
|
||||
void mq_wakeup_cb(void* arg);
|
||||
|
||||
/**
|
||||
* Create IO thread.
|
||||
* @return new io thread object. not yet started. or NULL malloc failure.
|
||||
*/
|
||||
struct dt_io_thread* dt_io_thread_create(void);
|
||||
|
||||
/**
|
||||
* Delete the IO thread structure.
|
||||
* @param dtio: the io thread that is deleted. It must not be running.
|
||||
*/
|
||||
void dt_io_thread_delete(struct dt_io_thread* dtio);
|
||||
|
||||
/**
|
||||
* Apply config to the dtio thread
|
||||
* @param dtio: io thread, not yet started.
|
||||
* @param cfg: config file struct.
|
||||
* @return false on malloc failure.
|
||||
*/
|
||||
int dt_io_thread_apply_cfg(struct dt_io_thread* dtio,
|
||||
struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Register a msg queue to the io thread. It will be polled to see if
|
||||
* there are messages and those then get removed and sent, when the thread
|
||||
* is running.
|
||||
* @param dtio: the io thread.
|
||||
* @param mq: message queue to register.
|
||||
* @return false on failure (malloc failure).
|
||||
*/
|
||||
int dt_io_thread_register_queue(struct dt_io_thread* dtio,
|
||||
struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Unregister queue from io thread.
|
||||
* @param dtio: the io thread.
|
||||
* @param mq: message queue.
|
||||
*/
|
||||
void dt_io_thread_unregister_queue(struct dt_io_thread* dtio,
|
||||
struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Start the io thread
|
||||
* @param dtio: the io thread.
|
||||
* @param event_base_nothr: the event base to attach the events to, in case
|
||||
* we are running without threads. With threads, this is ignored
|
||||
* and a thread is started to process the dnstap log messages.
|
||||
* @param numworkers: number of worker threads. The dnstap io thread is
|
||||
* that number +1 as the threadnumber (in logs).
|
||||
* @return false on failure.
|
||||
*/
|
||||
int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr,
|
||||
int numworkers);
|
||||
|
||||
/**
|
||||
* Stop the io thread
|
||||
* @param dtio: the io thread.
|
||||
*/
|
||||
void dt_io_thread_stop(struct dt_io_thread* dtio);
|
||||
|
||||
/** callback for the dnstap reconnect, to start reconnecting to output */
|
||||
void dtio_reconnect_timeout_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the dnstap events, to write to the output */
|
||||
void dtio_output_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the dnstap commandpipe, to stop the dnstap IO */
|
||||
void dtio_cmd_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the timer when the thread stops and wants to finish up */
|
||||
void dtio_stop_timer_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the output when the thread stops and wants to finish up */
|
||||
void dtio_stop_ev_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for unbound-dnstap-socket */
|
||||
void dtio_tap_callback(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for unbound-dnstap-socket */
|
||||
void dtio_mainfdcallback(int fd, short bits, void* arg);
|
||||
|
||||
#endif /* DTSTREAM_H */
|
||||
File diff suppressed because it is too large
Load Diff
+2232
-3
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ RFC 4343: case insensitive handling of domain names.
|
||||
RFC 4509: SHA256 DS hash.
|
||||
RFC 4592: wildcards.
|
||||
RFC 4697: No DNS Resolution Misbehavior.
|
||||
RFC 5001: DNS Name Server Identifier (NSID) Option
|
||||
RFC 5011: update of trust anchors with timers.
|
||||
RFC 5155: NSEC3, NSEC3PARAM types
|
||||
RFC 5358: reflectors-are-evil: access control list for recursive
|
||||
|
||||
+3
-1
@@ -76,6 +76,8 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
Disable support for RSASHA256 and RSASHA512 crypto.
|
||||
* --disable-gost
|
||||
Disable support for GOST crypto, RFC 5933.
|
||||
* --enable-subnet
|
||||
Enable EDNS client subnet processing.
|
||||
|
||||
* 'make test' runs a series of self checks.
|
||||
|
||||
@@ -97,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"
|
||||
```
|
||||
@@ -14,7 +14,6 @@ o (option) store primed key data in a overlaid keyhints file (sort of like draft
|
||||
o windows version, auto update feature, a query to check for the version.
|
||||
o command the server with TSIG inband. get-config, clearcache,
|
||||
get stats, get memstats, get ..., reload, clear one zone from cache
|
||||
o NSID rfc 5001 support.
|
||||
o timers rfc 5011 support.
|
||||
o Treat YXDOMAIN from a DNAME properly, in iterator (not throwaway), validator.
|
||||
o make timeout backoffs randomized (a couple percent random) to spread traffic.
|
||||
@@ -29,7 +28,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.
|
||||
|
||||
+281
-47
@@ -5,9 +5,13 @@
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
# Use this anywhere in the file to include other text into this file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# Use this anywhere in the file to include other text, that explicitly starts a
|
||||
# clause, into this file. Text after this directive needs to start a clause.
|
||||
#include-toplevel: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
@@ -70,6 +74,9 @@ server:
|
||||
# Set this to yes to prefer ipv6 upstream servers over ipv4.
|
||||
# prefer-ip6: no
|
||||
|
||||
# Prefer ipv4 upstream servers, even if ipv6 is available.
|
||||
# prefer-ip4: no
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously. About double the
|
||||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
@@ -103,7 +110,8 @@ server:
|
||||
# so-sndbuf: 0
|
||||
|
||||
# use SO_REUSEPORT to distribute queries over threads.
|
||||
# so-reuseport: no
|
||||
# at extreme load it could be better to turn it off to distribute even.
|
||||
# so-reuseport: yes
|
||||
|
||||
# use IP_TRANSPARENT so the interface: addresses can be non-local
|
||||
# and you can config non-existing IPs that are going to work later on
|
||||
@@ -115,14 +123,22 @@ server:
|
||||
# Linux only. On Linux you also have ip-transparent that is similar.
|
||||
# ip-freebind: no
|
||||
|
||||
# the value of the Differentiated Services Codepoint (DSCP)
|
||||
# in the differentiated services field (DS) of the outgoing
|
||||
# IP packets
|
||||
# ip-dscp: 0
|
||||
|
||||
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
|
||||
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts)
|
||||
# edns-buffer-size: 4096
|
||||
# is set with msg-buffer-size).
|
||||
# edns-buffer-size: 1232
|
||||
|
||||
# Maximum UDP response size (not applied to TCP response).
|
||||
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
|
||||
# max-udp-size: 4096
|
||||
|
||||
# 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 +161,13 @@ server:
|
||||
# msec to wait before close of port on timeout UDP. 0 disables.
|
||||
# delay-close: 0
|
||||
|
||||
# perform connect for UDP sockets to mitigate ICMP side channel.
|
||||
# udp-connect: yes
|
||||
|
||||
# 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
|
||||
@@ -172,6 +195,9 @@ server:
|
||||
# minimum wait time for responses, increase if uplink is long. In msec.
|
||||
# infra-cache-min-rtt: 50
|
||||
|
||||
# enable to make server probe down hosts more frequently.
|
||||
# infra-keep-probing: no
|
||||
|
||||
# the number of slabs to use for the Infrastructure cache.
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
@@ -212,6 +238,15 @@ server:
|
||||
# Default is 0, system default MSS.
|
||||
# outgoing-tcp-mss: 0
|
||||
|
||||
# Idle TCP timeout, connection closed in milliseconds
|
||||
# tcp-idle-timeout: 30000
|
||||
|
||||
# Enable EDNS TCP keepalive option.
|
||||
# edns-tcp-keepalive: no
|
||||
|
||||
# Timeout for EDNS TCP keepalive, in msec.
|
||||
# edns-tcp-keepalive-timeout: 120000
|
||||
|
||||
# Use systemd socket activation for UDP, TCP, and control sockets.
|
||||
# use-systemd: no
|
||||
|
||||
@@ -269,7 +304,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 /.
|
||||
@@ -309,6 +344,17 @@ server:
|
||||
# timetoresolve, fromcache and responsesize.
|
||||
# log-replies: no
|
||||
|
||||
# log with tag 'query' and 'reply' instead of 'info' for
|
||||
# filtering log-queries and log-replies from the log.
|
||||
# log-tag-queryreply: no
|
||||
|
||||
# log the local-zone actions, like local-zone type inform is enabled
|
||||
# also for the other local zone types.
|
||||
# log-local-actions: no
|
||||
|
||||
# print log lines that say why queries return SERVFAIL to clients.
|
||||
# log-servfail: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
@@ -331,6 +377,9 @@ server:
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
# NSID identity (hex string, or "ascii_somestring"). default disabled.
|
||||
# nsid: "aabbccdd"
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
@@ -342,7 +391,7 @@ server:
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
# harden-short-bufsize: yes
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
@@ -357,7 +406,7 @@ server:
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden against queries that fall under dnssec-signed nxdomain names.
|
||||
# harden-below-nxdomain: no
|
||||
# harden-below-nxdomain: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
@@ -391,8 +440,8 @@ server:
|
||||
|
||||
# Domains (and domains in them) without support for dns-0x20 and
|
||||
# the fallback fails because they keep sending different answers.
|
||||
# caps-whitelist: "licdn.com"
|
||||
# caps-whitelist: "senderbase.org"
|
||||
# caps-exempt: "licdn.com"
|
||||
# caps-exempt: "senderbase.org"
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
@@ -433,18 +482,24 @@ server:
|
||||
# if yes, perform key lookups adjacent to normal lookups.
|
||||
# prefetch-key: no
|
||||
|
||||
# deny queries of type ANY with an empty response.
|
||||
# deny-any: no
|
||||
|
||||
# if yes, Unbound rotates RRSet order in response.
|
||||
# rrset-roundrobin: no
|
||||
# rrset-roundrobin: yes
|
||||
|
||||
# if yes, Unbound doesn't insert authority/additional sections
|
||||
# into response messages when those sections are not required.
|
||||
# minimal-responses: no
|
||||
# minimal-responses: yes
|
||||
|
||||
# true to disable DNSSEC lameness check in iterator.
|
||||
# disable-dnssec-lame-check: no
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. Syntax: "[dns64] [validator] iterator"
|
||||
# most modules have to be listed at the beginning of the line,
|
||||
# except cachedb(just before iterator), and python (at the beginning,
|
||||
# or, just before the iterator).
|
||||
# module-config: "validator iterator"
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
@@ -459,15 +514,10 @@ 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
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# DLV is going to be decommissioned. Please do not use it any more.
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
@@ -524,9 +574,36 @@ server:
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
# Serve expired responses from cache, with TTL 0 in the response,
|
||||
# and then attempt to fetch the data afresh.
|
||||
# Serve expired responses from cache, with serve-expired-reply-ttl in
|
||||
# the response, and then attempt to fetch the data afresh.
|
||||
# serve-expired: no
|
||||
#
|
||||
# Limit serving of expired responses to configured seconds after
|
||||
# expiration. 0 disables the limit.
|
||||
# serve-expired-ttl: 0
|
||||
#
|
||||
# Set the TTL of expired records to the serve-expired-ttl value after a
|
||||
# failed attempt to retrieve the record from upstream. This makes sure
|
||||
# that the expired records will be served as long as there are queries
|
||||
# for it.
|
||||
# serve-expired-ttl-reset: no
|
||||
#
|
||||
# TTL value to use when replying with expired data.
|
||||
# serve-expired-reply-ttl: 30
|
||||
#
|
||||
# Time in milliseconds before replying to the client with expired data.
|
||||
# This essentially enables the serve-stale behavior as specified in
|
||||
# RFC 8767 that first tries to resolve before
|
||||
# immediately responding with expired data. 0 disables this behavior.
|
||||
# A recommended value is 1800.
|
||||
# serve-expired-client-timeout: 0
|
||||
|
||||
# Return the original TTL as received from the upstream name server rather
|
||||
# than the decrementing TTL as stored in the cache. Enabling this feature
|
||||
# does not impact cache expiry, it only changes the TTL unbound embeds in
|
||||
# responses to queries. Note that enabling this feature implicitly disables
|
||||
# enforcement of the configured minimum and maximum TTL.
|
||||
# serve-original-ttl: no
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
|
||||
@@ -538,6 +615,9 @@ server:
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# if enabled, ZONEMD verification failures do not block the zone.
|
||||
# zonemd-permissive-mode: no
|
||||
|
||||
# instruct the auto-trust-anchor-file probing to add anchors after ttl.
|
||||
# add-holddown: 2592000 # 30 days
|
||||
|
||||
@@ -561,7 +641,7 @@ server:
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# the amount of memory to use for the negative cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
|
||||
@@ -610,6 +690,9 @@ server:
|
||||
# local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
|
||||
# And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
|
||||
|
||||
# Add example.com into ipset
|
||||
# local-zone: "example.com" ipset
|
||||
|
||||
# If unbound is running service for the local host then it is useful
|
||||
# to perform lan-wide lookups to the upstream, and unblock the
|
||||
# long list of local-zones above. If this unbound is a dns server
|
||||
@@ -633,8 +716,11 @@ 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 always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name
|
||||
# o inform_redirect redirects queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, always_nodata,
|
||||
# always_deny resolve in that way but ignore local data for
|
||||
# that name
|
||||
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
@@ -668,12 +754,37 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets) with plain DNS inside
|
||||
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
|
||||
# Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
# https-port: 443
|
||||
|
||||
# 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"
|
||||
|
||||
# Pad responses to padded queries received over TLS
|
||||
# pad-responses: yes
|
||||
|
||||
# Padded responses will be padded to the closest multiple of this size.
|
||||
# pad-responses-block-size: 468
|
||||
|
||||
# Use the SNI extension for TLS connections. Default is yes.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-sni: yes
|
||||
|
||||
# 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.
|
||||
@@ -685,13 +796,41 @@ server:
|
||||
# Add system certs to the cert bundle, from the Windows Cert Store
|
||||
# tls-win-cert: no
|
||||
|
||||
# Pad queries over TLS upstreams
|
||||
# pad-queries: yes
|
||||
|
||||
# Padded queries will be padded to the closest multiple of this size.
|
||||
# pad-queries-block-size: 128
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# tls-additional-ports: portno for each of the port numbers.
|
||||
# tls-additional-port: portno for each of the port numbers.
|
||||
|
||||
# HTTP endpoint to provide DNS-over-HTTPS service on.
|
||||
# http-endpoint: "/dns-query"
|
||||
|
||||
# HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS value to use.
|
||||
# http-max-streams: 100
|
||||
|
||||
# Maximum number of bytes used for all HTTP/2 query buffers.
|
||||
# http-query-buffer-size: 4m
|
||||
|
||||
# Maximum number of bytes used for all HTTP/2 response buffers.
|
||||
# http-response-buffer-size: 4m
|
||||
|
||||
# Set TCP_NODELAY socket option on sockets used for DNS-over-HTTPS
|
||||
# service.
|
||||
# http-nodelay: yes
|
||||
|
||||
# Disable TLS for DNS-over-HTTP downstream service.
|
||||
# http-notls-downstream: no
|
||||
|
||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||
# dns64-prefix: 64:ff9b::0/96
|
||||
|
||||
# DNS64 ignore AAAA records for these domains and use A instead.
|
||||
# dns64-ignore-aaaa: "example.com"
|
||||
|
||||
# ratelimit for uncached, new queries, this limits recursion effort.
|
||||
# ratelimiting is experimental, and may help against randomqueryflood.
|
||||
# if 0(default) it is disabled, otherwise state qps allowed per zone.
|
||||
@@ -725,11 +864,14 @@ server:
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-permil: 0
|
||||
# Limit the number of connections simultaneous from a netblock
|
||||
# tcp-connection-limit: 192.0.2.0/24 12
|
||||
|
||||
# select from the fastest servers this many times out of 1000. 0 means
|
||||
# the fast server select is disabled. prefetches are not sped up.
|
||||
# fast-server-permil: 0
|
||||
# the number of servers that will be used in the fast server selection.
|
||||
# fast-server-num: 3
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
@@ -755,37 +897,52 @@ server:
|
||||
# ipsecmod-ignore-bogus: no
|
||||
#
|
||||
# Domains for which ipsecmod will be triggered. If not defined (default)
|
||||
# all domains are treated as being whitelisted.
|
||||
# ipsecmod-whitelist: "example.com"
|
||||
# ipsecmod-whitelist: "nlnetlabs.nl"
|
||||
# all domains are treated as being allowed.
|
||||
# ipsecmod-allow: "example.com"
|
||||
# ipsecmod-allow: "nlnetlabs.nl"
|
||||
|
||||
|
||||
# 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
|
||||
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
||||
|
||||
# Dynamic library config section. To enable:
|
||||
# o use --with-dynlibmodule to configure before compiling.
|
||||
# o list dynlib in the module-config string (above) to enable.
|
||||
# It can be placed anywhere, the dynlib module is only a very thin wrapper
|
||||
# to load modules dynamically.
|
||||
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
|
||||
# the module-config then you need one dynlib-file per instance.
|
||||
dynlib:
|
||||
# Script file to load
|
||||
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# Set to no and use an absolute path as control-interface to use
|
||||
# a unix local named pipe for unbound-control.
|
||||
# control-use-cert: yes
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# set to an absolute path to use a unix local name pipe, certificates
|
||||
# are not used for that, so key and cert files need not be present.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 8953
|
||||
|
||||
# for localhost, you can disable use of TLS by setting this to "no"
|
||||
# For local sockets this option is ignored, and TLS is not used.
|
||||
# control-use-cert: "yes"
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
@@ -812,6 +969,7 @@ remote-control:
|
||||
# stub-prime: no
|
||||
# stub-first: no
|
||||
# stub-tls-upstream: no
|
||||
# stub-no-cache: no
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
@@ -828,6 +986,7 @@ remote-control:
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-first: no
|
||||
# forward-tls-upstream: no
|
||||
# forward-no-cache: no
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
||||
@@ -838,24 +997,35 @@ remote-control:
|
||||
# upstream (which saves a lookup to the upstream). The first example
|
||||
# has a copy of the root for local usage. The second serves example.org
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from masters) sources of
|
||||
# download it), primary: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from primaries) sources of
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# primary: 199.9.14.201 # b.root-servers.net
|
||||
# primary: 192.33.4.12 # c.root-servers.net
|
||||
# primary: 199.7.91.13 # d.root-servers.net
|
||||
# primary: 192.5.5.241 # f.root-servers.net
|
||||
# primary: 192.112.36.4 # g.root-servers.net
|
||||
# primary: 193.0.14.129 # k.root-servers.net
|
||||
# primary: 192.0.47.132 # xfr.cjr.dns.icann.org
|
||||
# primary: 192.0.32.132 # xfr.lax.dns.icann.org
|
||||
# primary: 2001:500:200::b # b.root-servers.net
|
||||
# primary: 2001:500:2::c # c.root-servers.net
|
||||
# primary: 2001:500:2d::d # d.root-servers.net
|
||||
# primary: 2001:500:2f::f # f.root-servers.net
|
||||
# primary: 2001:500:12::d0d # g.root-servers.net
|
||||
# primary: 2001:7fd::1 # k.root-servers.net
|
||||
# primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
|
||||
# primary: 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
|
||||
# for-upstream: yes
|
||||
# zonemd-reject-absence: no
|
||||
# zonefile: "example.org.zone"
|
||||
|
||||
# Views
|
||||
@@ -899,7 +1069,7 @@ remote-control:
|
||||
# Enable external backend DB as auxiliary cache. Specify the backend name
|
||||
# (default is "testframe", which has no use other than for debugging and
|
||||
# testing) and backend-specific options. The 'cachedb' module must be
|
||||
# included in module-config.
|
||||
# included in module-config, just before the iterator module.
|
||||
# cachedb:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
@@ -912,3 +1082,67 @@ remote-control:
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
# # set timeout on redis records based on DNS response TTL
|
||||
# redis-expire-records: no
|
||||
|
||||
# IPSet
|
||||
# Add specify domain into set via ipset.
|
||||
# Note: To enable ipset unbound needs to run as root user.
|
||||
# ipset:
|
||||
# # set name for ip v4 addresses
|
||||
# name-v4: "list-v4"
|
||||
# # set name for ip v6 addresses
|
||||
# name-v6: "list-v6"
|
||||
#
|
||||
|
||||
# Dnstap logging support, if compiled in. To enable, set the dnstap-enable
|
||||
# to yes and also some of dnstap-log-..-messages to yes. And select an
|
||||
# upstream log destination, by socket path, TCP or TLS destination.
|
||||
# dnstap:
|
||||
# dnstap-enable: no
|
||||
# # if set to yes frame streams will be used in bidirectional mode
|
||||
# dnstap-bidirectional: yes
|
||||
# dnstap-socket-path: "@DNSTAP_SOCKET_PATH@"
|
||||
# # if "" use the unix socket in dnstap-socket-path, otherwise,
|
||||
# # set it to "IPaddress[@port]" of the destination.
|
||||
# dnstap-ip: ""
|
||||
# # if set to yes if you want to use TLS to dnstap-ip, no for TCP.
|
||||
# dnstap-tls: yes
|
||||
# # name for authenticating the upstream server. or "" disabled.
|
||||
# dnstap-tls-server-name: ""
|
||||
# # if "", it uses the cert bundle from the main unbound config.
|
||||
# dnstap-tls-cert-bundle: ""
|
||||
# # key file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-key-file: ""
|
||||
# # cert file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-cert-file: ""
|
||||
# dnstap-send-identity: no
|
||||
# dnstap-send-version: no
|
||||
# # if "" it uses the hostname.
|
||||
# dnstap-identity: ""
|
||||
# # if "" it uses the package version.
|
||||
# dnstap-version: ""
|
||||
# dnstap-log-resolver-query-messages: no
|
||||
# dnstap-log-resolver-response-messages: no
|
||||
# dnstap-log-client-query-messages: no
|
||||
# dnstap-log-client-response-messages: no
|
||||
# dnstap-log-forwarder-query-messages: no
|
||||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME and Response IP
|
||||
# Address trigger are the only supported triggers. Supported actions are:
|
||||
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Policies can be loaded from
|
||||
# file, using zone transfer, or using HTTP. The respip module needs to be added
|
||||
# to the module-config, e.g.: module-config: "respip validator iterator".
|
||||
# rpz:
|
||||
# name: "rpz.example.com"
|
||||
# zonefile: "rpz.example.com"
|
||||
# primary: 192.0.2.0
|
||||
# allow-notify: 192.0.2.0/32
|
||||
# url: http://www.example.com/rpz.example.org.zone
|
||||
# rpz-action-override: cname
|
||||
# rpz-cname-override: www.example.org
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "example policy"
|
||||
# tags: "example"
|
||||
|
||||
+14
-3
@@ -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
|
||||
@@ -386,12 +396,13 @@ The result of the DNS resolution and validation is returned as
|
||||
char* canonname; /* canonical name of result */
|
||||
int rcode; /* additional error code in case of no data */
|
||||
void* answer_packet; /* full network format answer packet */
|
||||
int answer_len; /* length of packet in octets */
|
||||
int answer_len; /* length of packet in octets */
|
||||
int havedata; /* true if there is data */
|
||||
int nxdomain; /* true if nodata because name does not exist */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
char* why_bogus; /* string with error if bogus */
|
||||
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
|
||||
int ttl; /* number of seconds the result is valid */
|
||||
};
|
||||
.fi
|
||||
|
||||
@@ -69,6 +69,13 @@ 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 \-S
|
||||
Do not use SNI for the HTTPS connection. Default is to use SNI.
|
||||
.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.
|
||||
@@ -109,6 +116,11 @@ It does so, because the tool when used for bootstrapping the recursive
|
||||
resolver, cannot use that recursive resolver itself because it is bootstrapping
|
||||
that server.
|
||||
.TP
|
||||
.B \-R
|
||||
Allow fallback from \-f resolv.conf file to direct root servers query.
|
||||
It allows you to prefer local resolvers, but fallback automatically
|
||||
to direct root query if they do not respond or do not support DNSSEC.
|
||||
.TP
|
||||
.B \-v
|
||||
More verbose. Once prints informational messages, multiple times may enable
|
||||
large debug amounts (such as full certificates or byte\-dumps of downloaded
|
||||
|
||||
@@ -293,6 +293,24 @@ ips are dropped before checking the cache.
|
||||
List the auth zones that are configured. Printed one per line with a
|
||||
status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B auth_zone_reload \fIzone\fR
|
||||
Reload the auth zone from zonefile. The zonefile is read in overwriting
|
||||
the current contents of the zone in memory. This changes the auth zone
|
||||
contents itself, not the cache contents. Such cache contents exists if
|
||||
you set unbound to validate with for-upstream yes and that can be cleared
|
||||
with \fBflush_zone\fR \fIzone\fR.
|
||||
.TP
|
||||
.B auth_zone_transfer \fIzone\fR
|
||||
Transfer the auth zone from master. The auth zone probe sequence is started,
|
||||
where the masters are probed to see if they have an updated zone (with the SOA
|
||||
serial check). And then the zone is transferred for a newer zone version.
|
||||
.TP
|
||||
.B rpz_enable \fIzone\fR
|
||||
Enable the RPZ zone if it had previously been disabled.
|
||||
.TP
|
||||
.B rpz_enable \fIzone\fR
|
||||
Disable the RPZ zone.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
@@ -310,6 +328,12 @@ status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B view_local_data_remove \fIview\fR \fIname
|
||||
\fIlocal_data_remove\fR for given view.
|
||||
.TP
|
||||
.B view_local_datas_remove \fIview\fR
|
||||
Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_remove.
|
||||
.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"
|
||||
@@ -364,8 +388,8 @@ and resulted in recursive processing, taking a slot in the requestlist.
|
||||
Not part of the recursivereplies (or the histogram thereof) or cachemiss,
|
||||
as a cache response was sent.
|
||||
.TP
|
||||
.I threadX.num.zero_ttl
|
||||
number of replies with ttl zero, because they served an expired cache entry.
|
||||
.I threadX.num.expired
|
||||
number of replies that served an expired cache entry.
|
||||
.TP
|
||||
.I threadX.num.recursivereplies
|
||||
The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries.
|
||||
@@ -428,7 +452,7 @@ summed over threads.
|
||||
.I total.num.prefetch
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.zero_ttl
|
||||
.I total.num.expired
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.recursivereplies
|
||||
@@ -484,6 +508,18 @@ 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 mem.http.query_buffer
|
||||
Memory in bytes used by the HTTP/2 query buffers. Containing (partial) DNS
|
||||
queries waiting for request stream completion.
|
||||
.TP
|
||||
.I mem.http.response_buffer
|
||||
Memory in bytes used by the HTTP/2 response buffers. Containing DNS responses
|
||||
waiting to be written back to the clients.
|
||||
.TP
|
||||
.I histogram.<sec>.<usec>.to.<sec>.<usec>
|
||||
Shows a histogram, summed over all threads. Every element counts the
|
||||
recursive queries whose reply time fit between the lower and upper bound.
|
||||
@@ -515,6 +551,19 @@ Number of queries that were made using TCP towards the unbound server.
|
||||
Number of queries that the unbound server made using TCP outgoing towards
|
||||
other servers.
|
||||
.TP
|
||||
.I num.query.tls
|
||||
Number of queries that were made using TLS towards the unbound server.
|
||||
These are also counted in num.query.tcp, because TLS uses TCP.
|
||||
.TP
|
||||
.I num.query.tls.resume
|
||||
Number of TLS session resumptions, these are queries over TLS towards
|
||||
the unbound server where the client negotiated a TLS session resumption key.
|
||||
.TP
|
||||
.I num.query.https
|
||||
Number of queries that were made using HTTPS towards the unbound server.
|
||||
These are also counted in num.query.tcp and num.query.tls, because HTTPS
|
||||
uses TLS and TCP.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the unbound server.
|
||||
.TP
|
||||
@@ -625,6 +674,19 @@ answered using cached data.
|
||||
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.subnet
|
||||
Number of queries that got an answer that contained EDNS client subnet data.
|
||||
.TP
|
||||
.I num.query.subnet_cache
|
||||
Number of queries answered from the edns client subnet cache. These are
|
||||
counted as cachemiss by the main counters, but hit the client subnet
|
||||
specific cache, after getting processed by the edns client subnet module.
|
||||
.TP
|
||||
.I num.rpz.action.<rpz_action>
|
||||
Number of queries answered using configured RPZ policy, per RPZ action type.
|
||||
Possible actions are: nxdomain, nodata, passthru, drop, local_data, disabled,
|
||||
and cname_override.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
||||
@@ -12,20 +12,20 @@
|
||||
\- unbound DNS lookup utility
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-host
|
||||
.RB [ \-C
|
||||
.IR configfile ]
|
||||
.RB [ \-vdhr46D ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-t
|
||||
.IR type ]
|
||||
.I hostname
|
||||
.RB [ \-y
|
||||
.IR key ]
|
||||
.RB [ \-f
|
||||
.IR keyfile ]
|
||||
.RB [ \-F
|
||||
.IR namedkeyfile ]
|
||||
.RB [ \-C
|
||||
.IR configfile ]
|
||||
.I hostname
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-host
|
||||
uses the unbound validating resolver to query for the hostname and display
|
||||
@@ -86,6 +86,8 @@ are read.
|
||||
.B \-C \fIconfigfile
|
||||
Uses the specified unbound.conf to prime
|
||||
.IR libunbound (3).
|
||||
Pass it as first argument if you want to override some options from the
|
||||
config file with further arguments on the commandline.
|
||||
.TP
|
||||
.B \-r
|
||||
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
|
||||
|
||||
+4
-1
@@ -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),
|
||||
|
||||
+663
-127
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -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
|
||||
|
||||
@@ -1137,7 +1143,7 @@ COMPACT_LATEX = NO
|
||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||
# executive. If left blank a4wide will be used.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
#PAPER_TYPE = a4wide
|
||||
|
||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||
# packages that should be included in the LaTeX output.
|
||||
@@ -1445,7 +1451,7 @@ EXTERNAL_GROUPS = YES
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of `which perl').
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
@@ -1467,7 +1473,7 @@ CLASS_DIAGRAMS = YES
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
#MSCGEN_PATH =
|
||||
|
||||
# If set to YES, the inheritance and collaboration graphs will hide
|
||||
# inheritance and usage relations if the target is undocumented
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
#include "config.h"
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "dynlibmod/dynlibmod.h"
|
||||
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "services/cache/dns.h"
|
||||
|
||||
#include "dynlibmod/dnsmessage.h"
|
||||
|
||||
struct dynlibmod_section_txt {
|
||||
char *txt;
|
||||
struct dynlibmod_section_txt *next;
|
||||
};
|
||||
|
||||
struct dynlibmod_dnsmessage {
|
||||
char *rr_name;
|
||||
sldns_rr_type rr_type;
|
||||
sldns_rr_class rr_class;
|
||||
uint32_t default_ttl;
|
||||
uint16_t flags;
|
||||
|
||||
// Question, Answer, Authority, and Additional sections
|
||||
struct dynlibmod_section_txt *sections[4];
|
||||
};
|
||||
|
||||
struct dynlibmod_dnsmessage *dynlibmod_dnsmessage_new(char *rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class, uint16_t flags, uint32_t default_ttl) {
|
||||
struct dynlibmod_dnsmessage *dns_message = malloc(sizeof(struct dynlibmod_dnsmessage));
|
||||
|
||||
if (!dns_message) {
|
||||
log_err("dynlibmod_dnsmessage_new: malloc failure allocating dns_message");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(dns_message, 0, sizeof(struct dynlibmod_dnsmessage));
|
||||
|
||||
if (rr_name) {
|
||||
dns_message->rr_name = strdup(rr_name);
|
||||
|
||||
if (!dns_message->rr_name) {
|
||||
log_err("dynlibmod_dnsmessage_new: malloc failure allocating rr_name");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
dns_message->rr_type = rr_type;
|
||||
dns_message->rr_class = rr_class;
|
||||
dns_message->flags = flags;
|
||||
dns_message->default_ttl = default_ttl;
|
||||
|
||||
return(dns_message);
|
||||
|
||||
error:
|
||||
if (dns_message)
|
||||
free(rr_name);
|
||||
|
||||
free(dns_message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dynlibmod_dnsmessage_free(struct dynlibmod_dnsmessage *dnsmessage) {
|
||||
if (!dnsmessage)
|
||||
return;
|
||||
|
||||
free(dnsmessage->rr_name);
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (struct dynlibmod_section_txt *ptr = dnsmessage->sections[i]; ptr;) {
|
||||
free(ptr->txt);
|
||||
struct dynlibmod_section_txt *tmp = ptr;
|
||||
ptr = ptr->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
free(dnsmessage);
|
||||
}
|
||||
|
||||
void dynlibmod_msg_append(struct dynlibmod_dnsmessage *msg, sldns_pkt_section section, const char *format, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
dynlibmod_vmsg_append(msg, section, format, args);
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
void dynlibmod_vmsg_append(struct dynlibmod_dnsmessage *msg, sldns_pkt_section section, const char *format, va_list args) {
|
||||
struct dynlibmod_section_txt *txt = malloc(sizeof(struct dynlibmod_section_txt));
|
||||
|
||||
if (!txt) {
|
||||
log_err("dynlibmod_vmsg_append: malloc failure allocating section txt structure");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(txt, 0, sizeof(struct dynlibmod_section_txt));
|
||||
|
||||
va_list cpy_args;
|
||||
va_copy(cpy_args, args);
|
||||
|
||||
int len = vsnprintf(NULL, 0, format, args);
|
||||
len++;
|
||||
txt->txt = malloc(len);
|
||||
|
||||
if (!txt->txt) {
|
||||
va_end(cpy_args);
|
||||
log_err("dynlibmod_vmsg_append: malloc failure allocating section txt member");
|
||||
goto error;
|
||||
}
|
||||
|
||||
vsnprintf(txt->txt, len, format, cpy_args);
|
||||
va_end(cpy_args);
|
||||
|
||||
if (!msg->sections[section]) {
|
||||
msg->sections[section] = txt;
|
||||
return;
|
||||
}
|
||||
|
||||
struct dynlibmod_section_txt *ptr = NULL;
|
||||
for (ptr = msg->sections[section]; ptr->next; ptr = ptr->next)
|
||||
;
|
||||
|
||||
ptr->next = txt;
|
||||
return;
|
||||
|
||||
error:
|
||||
if (txt)
|
||||
free(txt->txt);
|
||||
free(txt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate a section from a dynlibmod_dnsmessage structure and add all of it's members to the dns message
|
||||
*/
|
||||
static int _dynlibmod_pushRRList(sldns_buffer* qb, struct dynlibmod_section_txt *txt, uint32_t default_ttl, int qsec, size_t count_offset) {
|
||||
size_t len;
|
||||
char* s;
|
||||
|
||||
for (; txt; txt = txt->next) {
|
||||
s = txt->txt;
|
||||
|
||||
len = sldns_buffer_remaining(qb);
|
||||
if(qsec) {
|
||||
if(sldns_str2wire_rr_question_buf(s, sldns_buffer_current(qb), &len, NULL, NULL, 0, NULL, 0)!= 0)
|
||||
return 0;
|
||||
} else {
|
||||
if(sldns_str2wire_rr_buf(s, sldns_buffer_current(qb), &len, NULL, default_ttl, NULL, 0, NULL, 0) != 0)
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_skip(qb, len);
|
||||
|
||||
sldns_buffer_write_u16_at(qb, count_offset,
|
||||
sldns_buffer_read_u16_at(qb, count_offset)+1);
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
create_response(struct module_qstate* qstate, sldns_buffer* pkt)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
|
||||
/* parse message */
|
||||
prs = (struct msg_parse*) regional_alloc(qstate->env->scratch,
|
||||
sizeof(struct msg_parse));
|
||||
if(!prs) {
|
||||
log_err("create_response: out of memory on incoming message");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(prs, 0, sizeof(*prs));
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
|
||||
sldns_buffer_set_position(pkt, 0);
|
||||
if(parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
|
||||
verbose(VERB_ALGO, "create_response: parse error on reply packet");
|
||||
return 0;
|
||||
}
|
||||
/* edns is not examined, but removed from message to help cache */
|
||||
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
|
||||
LDNS_RCODE_NOERROR)
|
||||
return 0;
|
||||
|
||||
/* remove CD-bit, we asked for in case we handle validation ourself */
|
||||
prs->flags &= ~BIT_CD;
|
||||
|
||||
/* allocate response dns_msg in region */
|
||||
qstate->return_msg = (struct dns_msg*) regional_alloc(qstate->region,
|
||||
sizeof(struct dns_msg));
|
||||
if(!qstate->return_msg)
|
||||
return 0;
|
||||
|
||||
memset(qstate->return_msg, 0, sizeof(*qstate->return_msg));
|
||||
if(!parse_create_msg(pkt, prs, NULL, &qstate->return_msg->qinfo,
|
||||
&qstate->return_msg->rep, qstate->region)) {
|
||||
log_err("create_response: malloc failure: allocating incoming dns_msg");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the AA flag was set, make sure to reach the client. */
|
||||
qstate->return_msg->rep->authoritative =
|
||||
(uint8_t)(qstate->return_msg->rep->flags&BIT_AA?1:0);
|
||||
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("create_response: packet:", &qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A low level function for preparing a DNS answer by parsing a
|
||||
* dynlibmod_dnsmessage.
|
||||
*/
|
||||
int
|
||||
dynlibmod_set_return_msg(struct module_qstate* qstate, struct dynlibmod_dnsmessage *msg) {
|
||||
sldns_buffer *qb = 0;
|
||||
int res = 1;
|
||||
size_t l;
|
||||
|
||||
if ((qb = sldns_buffer_new(LDNS_RR_BUF_SIZE)) == NULL) return 0;
|
||||
|
||||
/* write header */
|
||||
sldns_buffer_write_u16(qb, 0); /* ID */
|
||||
sldns_buffer_write_u16(qb, msg->flags); /* flags */
|
||||
sldns_buffer_write_u16(qb, 1); /* qdcount */
|
||||
sldns_buffer_write_u16(qb, 0); /* ancount */
|
||||
sldns_buffer_write_u16(qb, 0); /* nscount */
|
||||
sldns_buffer_write_u16(qb, 0); /* arcount */
|
||||
|
||||
/* write the query */
|
||||
l = sldns_buffer_remaining(qb);
|
||||
if(sldns_str2wire_dname_buf(msg->rr_name, sldns_buffer_current(qb), &l) != 0) {
|
||||
sldns_buffer_free(qb);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_skip(qb, l);
|
||||
if (msg->rr_type == 0) { msg->rr_type = LDNS_RR_TYPE_A; }
|
||||
if (msg->rr_class == 0) { msg->rr_class = LDNS_RR_CLASS_IN; }
|
||||
sldns_buffer_write_u16(qb, msg->rr_type);
|
||||
sldns_buffer_write_u16(qb, msg->rr_class);
|
||||
|
||||
/* write RR sections */
|
||||
if(res && msg->sections[LDNS_SECTION_QUESTION] && !_dynlibmod_pushRRList(qb, msg->sections[LDNS_SECTION_QUESTION], msg->default_ttl, 1, LDNS_QDCOUNT_OFF))
|
||||
res = 0;
|
||||
if(res && msg->sections[LDNS_SECTION_ANSWER] && !_dynlibmod_pushRRList(qb, msg->sections[LDNS_SECTION_ANSWER], msg->default_ttl, 0, LDNS_ANCOUNT_OFF))
|
||||
res = 0;
|
||||
if(res && msg->sections[LDNS_SECTION_AUTHORITY] && !_dynlibmod_pushRRList(qb, msg->sections[LDNS_SECTION_AUTHORITY], msg->default_ttl, 0, LDNS_NSCOUNT_OFF))
|
||||
res = 0;
|
||||
if(res && msg->sections[LDNS_SECTION_ADDITIONAL] && !_dynlibmod_pushRRList(qb, msg->sections[LDNS_SECTION_ADDITIONAL], msg->default_ttl, 0, LDNS_ARCOUNT_OFF))
|
||||
res = 0;
|
||||
|
||||
if (res) res = create_response(qstate, qb);
|
||||
|
||||
if (qb) sldns_buffer_free(qb);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file Implements the dnsmessage api in C for unbound plugins using the dynlib module
|
||||
*/
|
||||
|
||||
#ifndef DYNLIBMOD_DNSMESSAGE_H
|
||||
#define DYNLIBMOD_DNSMESSAGE_H
|
||||
|
||||
/**
|
||||
* Structure encapsulates a new DNS Message.
|
||||
* Created by dnylibmod_dnsmessage, it's sections
|
||||
* are filled out by dnlibmod_msg_append.
|
||||
* Then it is finalized by dynlibmod_set_return_msg
|
||||
*/
|
||||
struct dynlibmod_dnsmessage;
|
||||
|
||||
/**
|
||||
* Allocate a new dnsmessage structure and store the details provided. Must
|
||||
* be freed by dynlibmod_dnsmessage_free after the call to dynlibmod_set_resturn_msg. (The message
|
||||
* structure is no longer required at that point)
|
||||
*/
|
||||
struct dynlibmod_dnsmessage *dynlibmod_dnsmessage_new(char *rr_name, sldns_rr_type rr_type, sldns_rr_class rr_class, uint16_t flags, uint32_t default_ttl);
|
||||
|
||||
/**
|
||||
* Free a dnsmessage structure.
|
||||
*/
|
||||
void dynlibmod_dnsmessage_free(struct dynlibmod_dnsmessage *dnsmessage);
|
||||
|
||||
/**
|
||||
* Print an record to one of the 4 DNS sections. Uses printf conventions. See example code for usage.
|
||||
*/
|
||||
void dynlibmod_msg_append(struct dynlibmod_dnsmessage *msg, sldns_pkt_section section, const char *format, ...);
|
||||
|
||||
/**
|
||||
* An alternative to dynlibmod_msg_append for use in creating wrapper functions
|
||||
*/
|
||||
void dynlibmod_vmsg_append(struct dynlibmod_dnsmessage *msg, sldns_pkt_section section, const char *format, va_list args);
|
||||
|
||||
/**
|
||||
* Finalize the DNS message and store it in the qstate for return to unbound
|
||||
*/
|
||||
int dynlibmod_set_return_msg(struct module_qstate* qstate, struct dynlibmod_dnsmessage *msg);
|
||||
|
||||
#endif /* DYNLIBMOD_DNSMESSAGE_H */
|
||||
@@ -0,0 +1,306 @@
|
||||
/**
|
||||
* \file
|
||||
* This file contains the dynamic library module for Unbound.
|
||||
* This loads a dynamic library (.dll, .so) and calls that for the
|
||||
* module actions.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "dynlibmod/dynlibmod.h"
|
||||
#include "util/module.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
#if HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#define __DYNMOD HMODULE
|
||||
#define __DYNSYM FARPROC
|
||||
#define __LOADSYM GetProcAddress
|
||||
static void log_dlerror() {
|
||||
DWORD dwLastError = GetLastError();
|
||||
LPSTR MessageBuffer;
|
||||
DWORD dwBufferLength;
|
||||
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM ;
|
||||
if((dwBufferLength = FormatMessageA(
|
||||
dwFormatFlags,
|
||||
NULL, // module to get message from (NULL == system)
|
||||
dwLastError,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
|
||||
(LPSTR) &MessageBuffer,
|
||||
0,
|
||||
NULL
|
||||
)))
|
||||
{
|
||||
log_err("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
|
||||
LocalFree(MessageBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static HMODULE open_library(const char* fname) {
|
||||
return LoadLibrary(fname);
|
||||
}
|
||||
|
||||
static void close_library(const char* fname, __DYNMOD handle) {
|
||||
(void)fname;
|
||||
(void)handle;
|
||||
}
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define __DYNMOD void*
|
||||
#define __DYNSYM void*
|
||||
#define __LOADSYM dlsym
|
||||
static void log_dlerror() {
|
||||
log_err("dynlibmod: %s", dlerror());
|
||||
}
|
||||
|
||||
static void* open_library(const char* fname) {
|
||||
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
|
||||
}
|
||||
|
||||
static void close_library(const char* fname, __DYNMOD handle) {
|
||||
if(!handle) return;
|
||||
if(dlclose(handle) != 0) {
|
||||
log_err("dlclose %s: %s", fname, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** module counter for multiple dynlib modules */
|
||||
static int dynlib_mod_count = 0;
|
||||
|
||||
/** dynlib module init */
|
||||
int dynlibmod_init(struct module_env* env, int id) {
|
||||
int dynlib_mod_idx = dynlib_mod_count++;
|
||||
struct config_strlist* cfg_item = env->cfg->dynlib_file;
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
|
||||
__DYNMOD dynamic_library;
|
||||
if (!de)
|
||||
{
|
||||
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
env->modinfo[id] = (void*) de;
|
||||
|
||||
de->fname = NULL;
|
||||
for(int i = dynlib_mod_idx;
|
||||
i != 0 && cfg_item != NULL;
|
||||
i--, cfg_item = cfg_item->next) {}
|
||||
|
||||
if (cfg_item == NULL || cfg_item->str == NULL || cfg_item->str[0] == 0) {
|
||||
log_err("dynlibmod[%d]: no dynamic library given.", dynlib_mod_idx);
|
||||
return 0;
|
||||
} else {
|
||||
de->fname = cfg_item->str;
|
||||
}
|
||||
verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
|
||||
dynamic_library = open_library(de->fname);
|
||||
de->dynamic_library = (void*)dynamic_library;
|
||||
if (dynamic_library == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
__DYNSYM initializer;
|
||||
__DYNSYM deinitializer;
|
||||
__DYNSYM operate;
|
||||
__DYNSYM inform;
|
||||
__DYNSYM clear;
|
||||
__DYNSYM get_mem;
|
||||
initializer = __LOADSYM(dynamic_library,"init");
|
||||
if (initializer == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load init procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_init = (func_init_t)(void*)initializer;
|
||||
}
|
||||
deinitializer = __LOADSYM(dynamic_library,"deinit");
|
||||
if (deinitializer == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load deinit procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_deinit = (func_deinit_t)(void*)deinitializer;
|
||||
}
|
||||
operate = __LOADSYM(dynamic_library,"operate");
|
||||
if (operate == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load operate procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_operate = (func_operate_t)(void*)operate;
|
||||
}
|
||||
inform = __LOADSYM(dynamic_library,"inform_super");
|
||||
if (inform == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load inform_super procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_inform = (func_inform_t)(void*)inform;
|
||||
}
|
||||
clear = __LOADSYM(dynamic_library,"clear");
|
||||
if (clear == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load clear procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_clear = (func_clear_t)(void*)clear;
|
||||
}
|
||||
get_mem = __LOADSYM(dynamic_library,"get_mem");
|
||||
if (get_mem == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load get_mem procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_get_mem = (func_get_mem_t)(void*)get_mem;
|
||||
}
|
||||
}
|
||||
de->inplace_cb_delete_wrapped = &inplace_cb_delete_wrapped;
|
||||
de->inplace_cb_register_wrapped = &inplace_cb_register_wrapped;
|
||||
return de->func_init(env, id);
|
||||
}
|
||||
|
||||
/** dynlib module deinit */
|
||||
void dynlibmod_deinit(struct module_env* env, int id) {
|
||||
struct dynlibmod_env* de = env->modinfo[id];
|
||||
if(de == NULL)
|
||||
return;
|
||||
de->func_deinit(env, id);
|
||||
close_library(de->fname, (__DYNMOD)de->dynamic_library);
|
||||
dynlib_mod_count--;
|
||||
de->fname = NULL;
|
||||
free(de);
|
||||
}
|
||||
|
||||
/** dynlib module operate on a query */
|
||||
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_operate(qstate, event, id, outbound);
|
||||
}
|
||||
|
||||
/** dynlib module */
|
||||
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_inform(qstate, id, super);
|
||||
}
|
||||
|
||||
/** dynlib module cleanup query state */
|
||||
void dynlibmod_clear(struct module_qstate* qstate, int id) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_clear(qstate, id);
|
||||
}
|
||||
|
||||
/** dynlib module alloc size routine */
|
||||
size_t dynlibmod_get_mem(struct module_env* env, int id) {
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*)env->modinfo[id];
|
||||
size_t size;
|
||||
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
|
||||
if(!de)
|
||||
return 0;
|
||||
|
||||
size = de->func_get_mem(env, id);
|
||||
return size + sizeof(*de);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region,
|
||||
struct timeval* start_time, int id, void* callback) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) callback;
|
||||
return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, start_time, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_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* callback) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) callback;
|
||||
return ((inplace_cb_query_func_type*) cb_pair->cb)(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
|
||||
int id, void* cb_args) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
|
||||
return ((inplace_cb_edns_back_parsed_func_type*) cb_pair->cb)(qstate, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
|
||||
struct dns_msg* response, int id, void* cb_args) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
|
||||
return ((inplace_cb_query_response_func_type*) cb_pair->cb)(qstate, response, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
struct module_env* env, int id) {
|
||||
struct cb_pair* cb_pair = malloc(sizeof(struct cb_pair));
|
||||
if(cb_pair == NULL) {
|
||||
log_err("dynlibmod[%d]: malloc failure", id);
|
||||
return 0;
|
||||
}
|
||||
cb_pair->cb = cb;
|
||||
cb_pair->cb_arg = cbarg;
|
||||
if(type >= inplace_cb_reply && type <= inplace_cb_reply_servfail) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_reply_generic, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_query) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_query_generic, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_query_response) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_query_response, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_edns_back_parsed) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_edns_back_parsed, type, (void*) cb_pair, env, id);
|
||||
} else {
|
||||
free(cb_pair);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
|
||||
int id) {
|
||||
struct inplace_cb* temp = env->inplace_cb_lists[type];
|
||||
struct inplace_cb* prev = NULL;
|
||||
|
||||
while(temp) {
|
||||
if(temp->id == id) {
|
||||
if(!prev) {
|
||||
env->inplace_cb_lists[type] = temp->next;
|
||||
free(temp->cb_arg);
|
||||
free(temp);
|
||||
temp = env->inplace_cb_lists[type];
|
||||
}
|
||||
else {
|
||||
prev->next = temp->next;
|
||||
free(temp->cb_arg);
|
||||
free(temp);
|
||||
temp = prev->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block dynlibmod_block = {
|
||||
"dynlib",
|
||||
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
|
||||
&dynlibmod_clear, &dynlibmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* dynlibmod_get_funcblock(void)
|
||||
{
|
||||
return &dynlibmod_block;
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* dynlibmod.h: module header file
|
||||
*
|
||||
* Copyright (c) 2019, Peter Munch-Ellingsen (peterme AT peterme.net)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* Dynamic loading module for unbound. Loads dynamic library.
|
||||
*/
|
||||
#ifndef DYNLIBMOD_H
|
||||
#define DYNLIBMOD_H
|
||||
#include "util/module.h"
|
||||
#include "services/outbound_list.h"
|
||||
|
||||
/**
|
||||
* Get the module function block.
|
||||
* @return: function block with function pointers to module methods.
|
||||
*/
|
||||
struct module_func_block* dynlibmod_get_funcblock(void);
|
||||
|
||||
/** dynlib module init */
|
||||
int dynlibmod_init(struct module_env* env, int id);
|
||||
|
||||
/** dynlib module deinit */
|
||||
void dynlibmod_deinit(struct module_env* env, int id);
|
||||
|
||||
/** dynlib module operate on a query */
|
||||
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound);
|
||||
|
||||
/** dynlib module */
|
||||
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
|
||||
/** dynlib module cleanup query state */
|
||||
void dynlibmod_clear(struct module_qstate* qstate, int id);
|
||||
|
||||
/** dynlib module alloc size routine */
|
||||
size_t dynlibmod_get_mem(struct module_env* env, int id);
|
||||
|
||||
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region,
|
||||
struct timeval* start_time, int id, void* callback);
|
||||
|
||||
int dynlib_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* callback);
|
||||
|
||||
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
|
||||
int id, void* cb_args);
|
||||
|
||||
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
|
||||
struct dns_msg* response, int id, void* cb_args);
|
||||
|
||||
int
|
||||
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
struct module_env* env, int id);
|
||||
|
||||
void
|
||||
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
|
||||
int id);
|
||||
|
||||
struct cb_pair {
|
||||
void *cb;
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Global state for the module.
|
||||
*/
|
||||
|
||||
typedef int (*func_init_t)(struct module_env*, int);
|
||||
typedef void (*func_deinit_t)(struct module_env*, int);
|
||||
typedef void (*func_operate_t)(struct module_qstate*, enum module_ev, int, struct outbound_entry*);
|
||||
typedef void (*func_inform_t)(struct module_qstate*, int, struct module_qstate*);
|
||||
typedef void (*func_clear_t)(struct module_qstate*, int);
|
||||
typedef size_t (*func_get_mem_t)(struct module_env*, int);
|
||||
typedef void (*inplace_cb_delete_wrapped_t)(struct module_env*, enum inplace_cb_list_type, int);
|
||||
typedef int (*inplace_cb_register_wrapped_t)(void*, enum inplace_cb_list_type, void*, struct module_env*, int);
|
||||
|
||||
|
||||
struct dynlibmod_env {
|
||||
/** Dynamic library filename. */
|
||||
const char* fname;
|
||||
/** dynamic library handle */
|
||||
void* dynamic_library;
|
||||
/** Module init function */
|
||||
func_init_t func_init;
|
||||
/** Module deinit function */
|
||||
func_deinit_t func_deinit;
|
||||
/** Module operate function */
|
||||
func_operate_t func_operate;
|
||||
/** Module super_inform function */
|
||||
func_inform_t func_inform;
|
||||
/** Module clear function */
|
||||
func_clear_t func_clear;
|
||||
/** Module get_mem function */
|
||||
func_get_mem_t func_get_mem;
|
||||
/** Wrapped inplace callback functions to circumvent callback whitelisting */
|
||||
inplace_cb_delete_wrapped_t inplace_cb_delete_wrapped;
|
||||
inplace_cb_register_wrapped_t inplace_cb_register_wrapped;
|
||||
/** Pointer to any data the dynamic library might want to keep */
|
||||
void *dyn_env;
|
||||
};
|
||||
|
||||
|
||||
#endif /* DYNLIBMOD_H */
|
||||
@@ -0,0 +1,16 @@
|
||||
CFLAGS=-I../.. -c -Wall -Werror -fpic -g -Wno-unused-variable
|
||||
|
||||
all: resgen.so helloworld.so
|
||||
|
||||
resgen.so: resgen.o
|
||||
$(CC) -shared -Wall -Werror -g -o resgen.so resgen.o
|
||||
|
||||
helloworld.so: helloworld.o
|
||||
$(CC) -shared -Wall -Werror -g -o helloworld.so helloworld.o
|
||||
|
||||
clean:
|
||||
-rm -rf *.o *.so
|
||||
|
||||
.PHONY : all clean
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This is an example to show how dynamic libraries can be made to work with
|
||||
* unbound. To build a .so file simply run:
|
||||
* gcc -I../.. -shared -Wall -Werror -fpic -o helloworld.so helloworld.c
|
||||
* And to build for windows, first make unbound with the --with-dynlibmod
|
||||
* switch, then use this command:
|
||||
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic
|
||||
* -o helloworld.dll helloworld.c -L../.. -l:libunbound.dll.a
|
||||
* to cross-compile a 64-bit Windows DLL. The libunbound.dll.a is produced
|
||||
* by the compile step that makes unbound.exe and allows the dynlib dll to
|
||||
* access definitions in unbound.exe.
|
||||
*/
|
||||
|
||||
#include "../../config.h"
|
||||
#include "../../util/module.h"
|
||||
#include "../../sldns/parseutil.h"
|
||||
#include "../dynlibmod.h"
|
||||
|
||||
/* Declare the EXPORT macro that expands to exporting the symbol for DLLs when
|
||||
* compiling for Windows. All procedures marked with EXPORT in this example are
|
||||
* called directly by the dynlib module and must be present for the module to
|
||||
* load correctly. */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
/* Forward declare a callback, implemented at the bottom of this file */
|
||||
int reply_callback(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region,
|
||||
struct timeval* start_time, int id, void* callback);
|
||||
|
||||
/* Init is called when the module is first loaded. It should be used to set up
|
||||
* the environment for this module and do any other initialisation required. */
|
||||
EXPORT int init(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from init");
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
|
||||
de->inplace_cb_register_wrapped(&reply_callback,
|
||||
inplace_cb_reply,
|
||||
NULL, env, id);
|
||||
struct dynlibmod_env* local_env = env->modinfo[id];
|
||||
local_env->dyn_env = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deinit is run as the program is shutting down. It should be used to clean up
|
||||
* the environment and any left over data. */
|
||||
EXPORT void deinit(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from deinit");
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
|
||||
de->inplace_cb_delete_wrapped(env, inplace_cb_reply, id);
|
||||
if (de->dyn_env != NULL) free(de->dyn_env);
|
||||
}
|
||||
|
||||
/* Operate is called every time a query passes by this module. The event can be
|
||||
* used to determine which direction in the module chain it came from. */
|
||||
EXPORT void operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* entry) {
|
||||
log_info("dynlib: hello world from operate");
|
||||
log_info("dynlib: incoming query: %s %s(%d) %s(%d)",
|
||||
qstate->qinfo.qname,
|
||||
sldns_lookup_by_id(sldns_rr_classes, qstate->qinfo.qclass)->name,
|
||||
qstate->qinfo.qclass,
|
||||
sldns_rr_descript(qstate->qinfo.qtype)->_name,
|
||||
qstate->qinfo.qtype);
|
||||
if (event == module_event_new || event == module_event_pass) {
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env == NULL) {
|
||||
env->dyn_env = calloc(3, sizeof(int));
|
||||
((int *)env->dyn_env)[0] = 42;
|
||||
((int *)env->dyn_env)[1] = 102;
|
||||
((int *)env->dyn_env)[2] = 192;
|
||||
} else {
|
||||
log_err("dynlib: already has data!");
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
} else if (event == module_event_moddone) {
|
||||
qstate->ext_state[id] = module_finished;
|
||||
} else {
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Inform super is called when a query is completed or errors out, but only if
|
||||
* a sub-query has been registered to it by this module. Look at
|
||||
* mesh_attach_sub in services/mesh.h to see how this is done. */
|
||||
EXPORT void inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super) {
|
||||
log_info("dynlib: hello world from inform_super");
|
||||
}
|
||||
|
||||
/* Clear is called once a query is complete and the response has been sent
|
||||
* back. It is used to clear up any per-query allocations. */
|
||||
EXPORT void clear(struct module_qstate* qstate, int id) {
|
||||
log_info("dynlib: hello world from clear");
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env != NULL) {
|
||||
free(env->dyn_env);
|
||||
env->dyn_env = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mem is called when Unbound is printing performance information. This
|
||||
* only happens explicitly and is only used to show memory usage to the user. */
|
||||
EXPORT size_t get_mem(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from get_mem");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The callback that was forward declared earlier. It is registered in the init
|
||||
* procedure to run when a query is being replied to. */
|
||||
int reply_callback(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region,
|
||||
struct timeval* start_time, int id, void* callback) {
|
||||
log_info("dynlib: hello world from callback");
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env != NULL) {
|
||||
log_info("dynlib: numbers gotten from query: %d, %d, and %d",
|
||||
((int *)env->dyn_env)[0],
|
||||
((int *)env->dyn_env)[1],
|
||||
((int *)env->dyn_env)[2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This is an example to show how dynamic libraries can be made to work with
|
||||
* unbound. To build a .so file simply run:
|
||||
* gcc -I../.. -shared -Wall -Werror -fpic -o resgen.so resgen.c
|
||||
* And to build for windows, first make unbound with the --with-dynlibmod
|
||||
* switch, then use this command:
|
||||
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic
|
||||
* -o resgen.dll resgen.c -L../.. -l:libunbound.dll.a
|
||||
* to cross-compile a 64-bit Windows DLL. The libunbound.dll.a is produced
|
||||
* by the compile step that makes unbound.exe and allows the dynlib dll to
|
||||
* access definitions in unbound.exe.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dynlibmod/dynlibmod.h"
|
||||
#include "dynlibmod/dnsmessage.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/cache/dns.h"
|
||||
|
||||
|
||||
/* Declare the EXPORT macro that expands to exporting the symbol for DLLs when
|
||||
* compiling for Windows. All procedures marked with EXPORT in this example are
|
||||
* called directly by the dynlib module and must be present for the module to
|
||||
* load correctly. */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
int endswith(char *str, const char *suffix, char **ptr) {
|
||||
size_t lstr = strlen(str);
|
||||
size_t lsuffix = strlen(suffix);
|
||||
|
||||
// String too long
|
||||
if (lsuffix > lstr)
|
||||
return 0;
|
||||
|
||||
int ret = memcmp(str + (lstr - lsuffix), suffix, lsuffix);
|
||||
|
||||
if (ret) // no match
|
||||
return 0;
|
||||
|
||||
if (ptr)
|
||||
*ptr = str + (lstr - lsuffix);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Init is called when the module is first loaded. It should be used to set up
|
||||
* the environment for this module and do any other initialisation required. */
|
||||
EXPORT int init(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from init");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deinit is run as the program is shutting down. It should be used to clean up
|
||||
* the environment and any left over data. */
|
||||
EXPORT void deinit(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from deinit");
|
||||
}
|
||||
|
||||
/* Operate is called every time a query passes by this module. The event can be
|
||||
* used to determine which direction in the module chain it came from. */
|
||||
EXPORT void operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* entry) {
|
||||
char *qname = sldns_wire2str_dname(qstate->qinfo.qname, qstate->qinfo.qname_len);
|
||||
struct dynlibmod_dnsmessage *msg = NULL;
|
||||
|
||||
log_info("dynlib: hello world from operate");
|
||||
log_info("dynlib: incoming query: %s %s(%d) %s(%d)",
|
||||
qname,
|
||||
sldns_lookup_by_id(sldns_rr_classes, qstate->qinfo.qclass)->name,
|
||||
qstate->qinfo.qclass,
|
||||
sldns_rr_descript(qstate->qinfo.qtype)->_name,
|
||||
qstate->qinfo.qtype);
|
||||
|
||||
switch(event) {
|
||||
case module_event_new:
|
||||
case module_event_pass:
|
||||
if (endswith(qname, ".resgentest.", NULL)) {
|
||||
msg = dynlibmod_dnsmessage_new(qname, (sldns_rr_type) qstate->qinfo.qtype, LDNS_RR_CLASS_IN, BIT_QR | BIT_RA | BIT_AA, 0);
|
||||
dynlibmod_msg_append(msg, LDNS_SECTION_ANSWER, "%s 10 IN A 127.1.2.3", qname);
|
||||
if (!dynlibmod_set_return_msg(qstate, msg)) {
|
||||
log_info("Failed to set return message");
|
||||
qstate->ext_state[id] = module_error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
qstate->return_msg->rep->security = sec_status_indeterminate;
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
goto cleanup;
|
||||
}
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
goto cleanup;
|
||||
|
||||
case module_event_moddone:
|
||||
qstate->ext_state[id] = module_finished;
|
||||
goto cleanup;
|
||||
|
||||
default:
|
||||
qstate->ext_state[id] = module_error;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
dynlibmod_dnsmessage_free(msg);
|
||||
free(qname);
|
||||
}
|
||||
|
||||
/* Inform super is called when a query is completed or errors out, but only if
|
||||
* a sub-query has been registered to it by this module. Look at
|
||||
* mesh_attach_sub in services/mesh.h to see how this is done. */
|
||||
EXPORT void inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super) {
|
||||
log_info("dynlib: hello world from inform_super");
|
||||
}
|
||||
|
||||
/* Clear is called once a query is complete and the response has been sent
|
||||
* back. It is used to clear up any per-query allocations. */
|
||||
EXPORT void clear(struct module_qstate* qstate, int id) {
|
||||
log_info("dynlib: hello world from clear");
|
||||
}
|
||||
|
||||
/* Get mem is called when Unbound is printing performance information. This
|
||||
* only happens explicitly and is only used to show memory usage to the user. */
|
||||
EXPORT size_t get_mem(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from get_mem");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# Example configuration file for resgen.py
|
||||
server:
|
||||
verbosity: 1
|
||||
interface: 0.0.0.0
|
||||
do-daemonize: no
|
||||
access-control: 0.0.0.0/0 allow
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
logfile: ""
|
||||
pidfile: "unbound.pid"
|
||||
module-config: "validator dynlib iterator"
|
||||
|
||||
dynlib:
|
||||
dynlib-file: "./examples/resgen.so"
|
||||
|
||||
@@ -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.
|
||||
|
||||
+116
-50
@@ -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,8 +203,9 @@ 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");
|
||||
log_err("subnetcache: could not create cache");
|
||||
free(sn_env);
|
||||
env->modinfo[id] = NULL;
|
||||
return 0;
|
||||
@@ -203,21 +214,21 @@ subnetmod_init(struct module_env *env, int id)
|
||||
sn_env->whitelist = ecs_whitelist_create();
|
||||
if(!sn_env->whitelist ||
|
||||
!ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) {
|
||||
log_err("subnet: could not create ECS whitelist");
|
||||
log_err("subnetcache: could not create ECS whitelist");
|
||||
slabhash_delete(sn_env->subnet_msg_cache);
|
||||
free(sn_env);
|
||||
env->modinfo[id] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verbose(VERB_QUERY, "subnet: option registered (%d)",
|
||||
verbose(VERB_QUERY, "subnetcache: option registered (%d)",
|
||||
env->cfg->client_subnet_opcode);
|
||||
/* Create new mesh state for all queries. */
|
||||
env->unique_mesh = 1;
|
||||
if(!edns_register_option(env->cfg->client_subnet_opcode,
|
||||
env->cfg->client_subnet_always_forward /* bypass cache */,
|
||||
0 /* no aggregation */, env)) {
|
||||
log_err("subnet: could not register opcode");
|
||||
log_err("subnetcache: could not register opcode");
|
||||
ecs_whitelist_delete(sn_env->whitelist);
|
||||
slabhash_delete(sn_env->subnet_msg_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,42 +334,46 @@ 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);
|
||||
log_err("Subnet cache insertion failed");
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
log_err("subnetcache: cache insertion failed");
|
||||
return;
|
||||
}
|
||||
lock_quick_lock(&sne->alloc.lock);
|
||||
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);
|
||||
log_err("Subnet cache insertion failed");
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
log_err("subnetcache: cache insertion failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -371,13 +386,11 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
|
||||
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
|
||||
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
|
||||
edns->subnet_source_mask,
|
||||
sq->ecs_server_in.subnet_scope_mask, rep,
|
||||
edns->subnet_source_mask, sq->max_scope, 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);
|
||||
}
|
||||
@@ -417,7 +430,7 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
}
|
||||
|
||||
qstate->return_msg = tomsg(NULL, &qstate->qinfo,
|
||||
(struct reply_info *)node->elem, qstate->region, *env->now,
|
||||
(struct reply_info *)node->elem, qstate->region, *env->now, 0,
|
||||
env->scratch);
|
||||
scope = (uint8_t)node->scope;
|
||||
lock_rw_unlock(&e->lock);
|
||||
@@ -464,12 +477,17 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
|
||||
memset(c_out, 0, sizeof(*c_out));
|
||||
|
||||
if (!qstate->return_msg) return module_error;
|
||||
if (!qstate->return_msg) {
|
||||
/* already an answer and its not a message, but retain
|
||||
* the actual rcode, instead of module_error, so send
|
||||
* module_finished */
|
||||
return module_finished;
|
||||
}
|
||||
|
||||
/* We have not asked for subnet data */
|
||||
if (!sq->subnet_sent) {
|
||||
if (s_in->subnet_validdata)
|
||||
verbose(VERB_QUERY, "subnet: received spurious data");
|
||||
verbose(VERB_QUERY, "subnetcache: received spurious data");
|
||||
if (sq->subnet_downstream) /* Copy back to client */
|
||||
cp_edns_bad_response(c_out, c_in);
|
||||
return module_finished;
|
||||
@@ -481,10 +499,12 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
* consequence the answer ended up in the regular cache. It
|
||||
* 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);
|
||||
verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
|
||||
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;
|
||||
@@ -501,7 +521,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
s_out->subnet_source_mask))
|
||||
{
|
||||
/* we can not accept, restart query without option */
|
||||
verbose(VERB_QUERY, "subnet: forged data");
|
||||
verbose(VERB_QUERY, "subnetcache: forged data");
|
||||
s_out->subnet_validdata = 0;
|
||||
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
|
||||
qstate->env->cfg->client_subnet_opcode);
|
||||
@@ -510,7 +530,10 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
if(!sq->started_no_cache_store) {
|
||||
update_cache(qstate, id);
|
||||
}
|
||||
sne->num_msg_nocache++;
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
|
||||
if (sq->subnet_downstream) {
|
||||
@@ -519,7 +542,20 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
c_out->subnet_addr_fam = c_in->subnet_addr_fam;
|
||||
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;
|
||||
c_out->subnet_scope_mask = sq->max_scope;
|
||||
/* 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;
|
||||
@@ -611,6 +647,19 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
|
||||
qstate->env->cfg->client_subnet_opcode);
|
||||
sq->subnet_sent = 0;
|
||||
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
|
||||
} else if (!sq->track_max_scope &&
|
||||
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR &&
|
||||
response->rep->an_numrrsets > 0
|
||||
) {
|
||||
struct ub_packed_rrset_key* s = response->rep->rrsets[0];
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME &&
|
||||
query_dname_compare(qstate->qinfo.qname,
|
||||
s->rk.dname) == 0) {
|
||||
/* CNAME response for QNAME. From now on keep track of
|
||||
* longest received ECS prefix for all queries on this
|
||||
* qstate. */
|
||||
sq->track_max_scope = 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -626,16 +675,19 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
||||
return 1;
|
||||
if((ecs_opt = edns_opt_list_find(
|
||||
qstate->edns_opts_back_in,
|
||||
qstate->env->cfg->client_subnet_opcode))) {
|
||||
if(parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
|
||||
sq->subnet_sent &&
|
||||
sq->ecs_server_in.subnet_validdata)
|
||||
qstate->env->cfg->client_subnet_opcode)) &&
|
||||
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
|
||||
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
|
||||
/* Only skip global cache store if we sent an ECS option
|
||||
* and received one back. Answers from non-whitelisted
|
||||
* servers will end up in global cache. Answers for
|
||||
* queries with 0 source will not (unless nameserver
|
||||
* does not support ECS). */
|
||||
qstate->no_cache_store = 1;
|
||||
if(!sq->track_max_scope || (sq->track_max_scope &&
|
||||
sq->ecs_server_in.subnet_scope_mask >
|
||||
sq->max_scope))
|
||||
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -648,10 +700,10 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
struct subnet_env *sne = qstate->env->modinfo[id];
|
||||
struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id];
|
||||
|
||||
verbose(VERB_QUERY, "subnet[module %d] operate: extstate:%s "
|
||||
verbose(VERB_QUERY, "subnetcache[module %d] operate: extstate:%s "
|
||||
"event:%s", id, strextstate(qstate->ext_state[id]),
|
||||
strmodulevent(event));
|
||||
log_query_info(VERB_QUERY, "subnet operate: query", &qstate->qinfo);
|
||||
log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo);
|
||||
|
||||
if((event == module_event_new || event == module_event_pass) &&
|
||||
sq == NULL) {
|
||||
@@ -686,15 +738,27 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
/* No clients are interested in result or we could not
|
||||
* parse it, we don't do client subnet */
|
||||
sq->ecs_server_out.subnet_validdata = 0;
|
||||
verbose(VERB_ALGO, "subnet: pass to next module");
|
||||
verbose(VERB_ALGO, "subnetcache: pass to next module");
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Limit to minimum allowed source mask */
|
||||
if(sq->ecs_client_in.subnet_source_mask != 0 && (
|
||||
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 &&
|
||||
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv4) ||
|
||||
(sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 &&
|
||||
sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv6))) {
|
||||
qstate->return_rcode = LDNS_RCODE_REFUSED;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
if (lookup_and_reply(qstate, id, sq)) {
|
||||
sne->num_msg_cache++;
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
verbose(VERB_QUERY, "subnet: answered from cache");
|
||||
verbose(VERB_QUERY, "subnetcache: answered from cache");
|
||||
qstate->ext_state[id] = module_finished;
|
||||
|
||||
ecs_opt_list_append(&sq->ecs_client_out,
|
||||
@@ -734,17 +798,19 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
|
||||
/* pass request to next module */
|
||||
verbose(VERB_ALGO,
|
||||
"subnet: not found in cache. pass to next module");
|
||||
"subnetcache: not found in cache. pass to next module");
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
/* Query handed back by next module, we have a 'final' answer */
|
||||
if(sq && event == module_event_moddone) {
|
||||
qstate->ext_state[id] = eval_response(qstate, id, sq);
|
||||
if(qstate->ext_state[id] == module_finished) {
|
||||
if(qstate->ext_state[id] == module_finished &&
|
||||
qstate->return_msg) {
|
||||
ecs_opt_list_append(&sq->ecs_client_out,
|
||||
&qstate->edns_opts_front_out, qstate);
|
||||
}
|
||||
qstate->no_cache_store = sq->started_no_cache_store;
|
||||
return;
|
||||
}
|
||||
if(sq && outbound) {
|
||||
@@ -753,7 +819,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
/* We are being revisited */
|
||||
if(event == module_event_pass || event == module_event_new) {
|
||||
/* Just pass it on, we already did the work */
|
||||
verbose(VERB_ALGO, "subnet: pass to next module");
|
||||
verbose(VERB_ALGO, "subnetcache: pass to next module");
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
@@ -762,7 +828,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
log_err("subnet: bad event %s", strmodulevent(event));
|
||||
log_err("subnetcache: bad event %s", strmodulevent(event));
|
||||
qstate->ext_state[id] = module_error;
|
||||
return;
|
||||
}
|
||||
@@ -795,7 +861,7 @@ subnetmod_get_mem(struct module_env *env, int id)
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block subnetmod_block = {
|
||||
"subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
"subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user