mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
2238
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
753487ff7f | ||
|
|
c8ff4f55e7 | ||
|
|
6a13b51bed | ||
|
|
477bb1a6ff | ||
|
|
53ecdfc0b5 | ||
|
|
b7b5952c3a | ||
|
|
7d4445c03d | ||
|
|
3a21617c62 | ||
|
|
14a0433470 | ||
|
|
7d364f1111 | ||
|
|
2902ee133b | ||
|
|
84adade86c | ||
|
|
8876751ed1 | ||
|
|
7b0c2c5e5d | ||
|
|
833ab1aab3 | ||
|
|
b953cd9aa0 | ||
|
|
d75f58d659 | ||
|
|
fc86347578 | ||
|
|
6ca79ff727 | ||
|
|
889b979a0e | ||
|
|
7189ba715d | ||
|
|
b280527e3e | ||
|
|
e7cc57ceae | ||
|
|
db3ac2335c | ||
|
|
7f802b07ef | ||
|
|
c00a5d0723 | ||
|
|
d4bcfbe996 | ||
|
|
9cebc13150 | ||
|
|
e99b5046eb | ||
|
|
ff50993f36 | ||
|
|
d84529cc0e | ||
|
|
4d009e19fc | ||
|
|
233c14a476 | ||
|
|
06d33f61c1 | ||
|
|
52774b6b20 | ||
|
|
84b0207956 | ||
|
|
6f0c2956ac | ||
|
|
8ac054733b | ||
|
|
2a90e8fa1e | ||
|
|
be1182c3db | ||
|
|
5203954068 | ||
|
|
6e0756e819 | ||
|
|
c053513cbd | ||
|
|
062f7b7ba2 | ||
|
|
90d556d650 | ||
|
|
c93b4b3158 | ||
|
|
21cd836e82 | ||
|
|
8af3d73b9b | ||
|
|
f37242566b | ||
|
|
711c0548f0 | ||
|
|
a1d4e151ee | ||
|
|
ba0f382eee | ||
|
|
4ccac696ca | ||
|
|
a238f35d7d | ||
|
|
a77ebed550 | ||
|
|
84e95d6c68 | ||
|
|
01db6c365c | ||
|
|
510e79a053 | ||
|
|
2c8ebe6206 | ||
|
|
80308880d2 | ||
|
|
edcef18274 | ||
|
|
99fd6cf711 | ||
|
|
8175161059 | ||
|
|
1bd4dbf302 | ||
|
|
a269db3828 | ||
|
|
584c2cf804 | ||
|
|
6320776b25 | ||
|
|
d8bd6e2281 | ||
|
|
201c158377 | ||
|
|
226d66ca92 | ||
|
|
cee3098e87 | ||
|
|
00323b71d7 | ||
|
|
5151190dbc | ||
|
|
52ebdd85da | ||
|
|
0c10453546 | ||
|
|
a4dcd5eb91 | ||
|
|
334498d9b9 | ||
|
|
d2055b83d8 | ||
|
|
1db2ab678d | ||
|
|
9d197eb110 | ||
|
|
e430e95d30 | ||
|
|
e18ab07c62 | ||
|
|
963cfb58be | ||
|
|
3cd288a9f2 | ||
|
|
2193d06af6 | ||
|
|
eed157d36e | ||
|
|
8a87fc6ae7 | ||
|
|
c7f1d2d889 | ||
|
|
c9bae13502 | ||
|
|
22ab255231 | ||
|
|
03a37d1ff6 | ||
|
|
33a2613a49 | ||
|
|
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 | ||
|
|
0f0bb21a89 | ||
|
|
00d622bed7 | ||
|
|
e5e72eb398 | ||
|
|
9e193be648 | ||
|
|
7dcfe531e4 | ||
|
|
e965775064 | ||
|
|
6e13c6f401 | ||
|
|
2916cfb3b0 | ||
|
|
da2bda6f4d | ||
|
|
adda4f6ace | ||
|
|
c316b1d7d5 | ||
|
|
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 | ||
|
|
a4244e79ca | ||
|
|
833021d84d | ||
|
|
2c459443da | ||
|
|
1646b26369 | ||
|
|
056176ec9a | ||
|
|
b1d8b549e0 | ||
|
|
d69ba6f39f | ||
|
|
882741bf55 | ||
|
|
dd1b35412f | ||
|
|
5dc6798e75 | ||
|
|
8aa338ba2d | ||
|
|
4f5b934688 | ||
|
|
b9c9fc066f | ||
|
|
833c4b1300 | ||
|
|
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 | ||
|
|
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 | ||
|
|
7c5e38294a | ||
|
|
1cadc5d677 | ||
|
|
7509bf208e | ||
|
|
ec34bc9af1 | ||
|
|
8d1af17449 | ||
|
|
0db1573d34 | ||
|
|
b3c45a8edb | ||
|
|
1a0bd1a150 | ||
|
|
5a726fb61f | ||
|
|
6792d2d036 | ||
|
|
d32fb26adb | ||
|
|
d4ba7731ad | ||
|
|
b9607297e9 | ||
|
|
9ed59fdf34 | ||
|
|
8bcb44a019 | ||
|
|
6b28c8ace2 | ||
|
|
55088951c0 | ||
|
|
55a0d89f0d | ||
|
|
d532c9913c | ||
|
|
261bf354b7 | ||
|
|
50b6dc4b81 | ||
|
|
ba29a4a078 | ||
|
|
676644d8e8 | ||
|
|
f64a897cbc | ||
|
|
8b209f8f68 | ||
|
|
16b6619dfa | ||
|
|
a8c8fa6bc6 | ||
|
|
6d7e5df98f | ||
|
|
1d5d95c8cb | ||
|
|
8f886fc6dd | ||
|
|
581f975b38 | ||
|
|
d2c8bcf318 | ||
|
|
ef1ed6365c | ||
|
|
82418e2bf7 | ||
|
|
6fefbb4115 | ||
|
|
85bf0bd994 | ||
|
|
913d4537f4 | ||
|
|
4e2bafafef | ||
|
|
bffb7c52d5 | ||
|
|
38c4d3d09d | ||
|
|
2951f21dab | ||
|
|
d97a635084 | ||
|
|
2c9d9fe211 | ||
|
|
583411768d | ||
|
|
a55df65bc9 | ||
|
|
d6de848e29 | ||
|
|
649a98d855 | ||
|
|
127759b160 | ||
|
|
5b29f1b3ac | ||
|
|
755177fb4c | ||
|
|
ee9c42bee5 | ||
|
|
4d06c36342 | ||
|
|
1508d3708c | ||
|
|
ea6266f736 | ||
|
|
406a9d8350 | ||
|
|
2be0263dfa | ||
|
|
deea985a20 | ||
|
|
0d18256828 | ||
|
|
abe18e41bc | ||
|
|
716282cc1a | ||
|
|
f5a59fea5d | ||
|
|
2e70e3a0d3 | ||
|
|
7ff459af13 | ||
|
|
5bee11a6d3 | ||
|
|
0b21483b17 | ||
|
|
7444b3a8bf | ||
|
|
f39e39ed47 | ||
|
|
1989c52ca0 | ||
|
|
d8df0ddef8 | ||
|
|
7f6e3852b8 | ||
|
|
23656b2b0e | ||
|
|
c16a32d2be | ||
|
|
9d28279475 | ||
|
|
913de80cbc | ||
|
|
e4c8085408 | ||
|
|
1b055c6ca7 | ||
|
|
630600e70d | ||
|
|
4809fe1b95 | ||
|
|
2d6715878d | ||
|
|
4691979679 | ||
|
|
4e5af01354 | ||
|
|
b23b39bcfd | ||
|
|
4f974e3465 | ||
|
|
85994fb61c | ||
|
|
ad9784c5e8 | ||
|
|
c239c3f395 | ||
|
|
8d22d3c13d | ||
|
|
6ef9cafc0e | ||
|
|
471ed1befe | ||
|
|
e822adf725 | ||
|
|
d91f09896d | ||
|
|
d41cdb6ce8 | ||
|
|
fbee729c5b | ||
|
|
89ad258515 | ||
|
|
0e5abca6b7 | ||
|
|
9cd2f836bd | ||
|
|
1f9caf5805 | ||
|
|
c515215eea | ||
|
|
100cc496de | ||
|
|
0a06c5bfa2 | ||
|
|
6f4451b761 | ||
|
|
55b5227431 | ||
|
|
2be98b581a | ||
|
|
4e0128f16a | ||
|
|
3d1f9ae9d3 | ||
|
|
5fabe62e70 | ||
|
|
39f6488471 | ||
|
|
170c03f7db | ||
|
|
e5c14bfd16 | ||
|
|
4a0d32ec53 | ||
|
|
9f0d521b88 | ||
|
|
78031b37fc | ||
|
|
e1e629e592 | ||
|
|
554b8b35ae | ||
|
|
874165904f | ||
|
|
1d2d33d01a | ||
|
|
59935375a3 | ||
|
|
e784758a21 | ||
|
|
f7fe1a1093 | ||
|
|
3a287a70cd | ||
|
|
d111aaf64f | ||
|
|
cc617eadc9 | ||
|
|
54e15f5ace | ||
|
|
d1a76b55bc | ||
|
|
a48abc2f8b | ||
|
|
3a7d4d7c8d | ||
|
|
5e6c2e37ca | ||
|
|
b8c60d092f | ||
|
|
b57c76ed05 | ||
|
|
8da3f91a1d | ||
|
|
fdedd3aa38 | ||
|
|
a5fbb38fe2 | ||
|
|
3b25c475f5 | ||
|
|
babe659a64 | ||
|
|
980711e658 | ||
|
|
3a69cf5c69 | ||
|
|
5c8819f1ac | ||
|
|
f6f2ab1e4a | ||
|
|
1a7540c80a | ||
|
|
5919273709 | ||
|
|
4a3a6d1294 | ||
|
|
9407439587 | ||
|
|
d754cd3de4 | ||
|
|
9f88892190 | ||
|
|
1df2544e07 | ||
|
|
0e390bca00 | ||
|
|
8de66ab4b8 | ||
|
|
8148308cff | ||
|
|
24fc3242fc | ||
|
|
cd955fa34d | ||
|
|
28e9561a94 | ||
|
|
6905e41b57 | ||
|
|
075f470778 | ||
|
|
b8c72d7cbc | ||
|
|
b89db70821 | ||
|
|
a92e9692c1 | ||
|
|
3d57bf0a3b | ||
|
|
ec21a197ac | ||
|
|
ccf1ff8f02 | ||
|
|
76eee77b08 | ||
|
|
5b7942d197 | ||
|
|
a5df3a131e | ||
|
|
a901fc5fe7 | ||
|
|
a554c14f18 | ||
|
|
da06b1c76c | ||
|
|
b32284af57 | ||
|
|
54bd1fdd62 | ||
|
|
da961fd840 | ||
|
|
8449dc1b9d | ||
|
|
0648475a66 | ||
|
|
eff62cecac | ||
|
|
e63a4cd0fd | ||
|
|
dd2ba08f7c | ||
|
|
d19f3c8c07 | ||
|
|
427836884e | ||
|
|
1ad34fe7ae | ||
|
|
77f78152ee | ||
|
|
ad89368b4e | ||
|
|
5b41e86d51 | ||
|
|
48bd83f3b4 | ||
|
|
db766ce064 | ||
|
|
75eb720ab5 | ||
|
|
88c43a1b45 | ||
|
|
0ab8edd170 | ||
|
|
10e165c574 | ||
|
|
18aed94e0c | ||
|
|
3b87862c8a | ||
|
|
6fc79a70a3 | ||
|
|
a1b7abfb9f | ||
|
|
ff6ab04ecd | ||
|
|
bf6f33ceaf | ||
|
|
324d6e7c36 | ||
|
|
7edf4a3e75 | ||
|
|
e6b770b686 | ||
|
|
172b84f7ce | ||
|
|
dfb8fb2986 | ||
|
|
b5739f66a3 | ||
|
|
862b0b568c | ||
|
|
237e796955 | ||
|
|
1931d6e9cf | ||
|
|
b02f855df8 | ||
|
|
632ea0d02e | ||
|
|
a66fd181e5 | ||
|
|
cb28d35bd2 | ||
|
|
004609b5a7 | ||
|
|
fdd1199cb1 | ||
|
|
e95a9ac466 | ||
|
|
30891d6fff | ||
|
|
8605797002 | ||
|
|
cc9a0671f3 | ||
|
|
0b5e37dcee | ||
|
|
abeb60d511 | ||
|
|
4b9df2bae1 | ||
|
|
61d431e44f | ||
|
|
6a0b5aa8e3 | ||
|
|
392be1e787 | ||
|
|
84e819dc31 | ||
|
|
c1047e6a6c | ||
|
|
ca60143bdf | ||
|
|
c834b5eecd | ||
|
|
10cd092a78 | ||
|
|
0c4a702a39 | ||
|
|
ed002df8f5 | ||
|
|
bbcea9d913 | ||
|
|
657753aac2 | ||
|
|
7de2b4e047 | ||
|
|
f6946b9412 | ||
|
|
70f3d25173 | ||
|
|
fdd1a602d5 | ||
|
|
bea3b6b72d | ||
|
|
7d5dc75dc5 | ||
|
|
2e1f4420a8 | ||
|
|
0362614f94 | ||
|
|
208d045cf5 | ||
|
|
47909a6f2d | ||
|
|
f4ff97c297 | ||
|
|
0121427ef1 | ||
|
|
a1e63e8118 | ||
|
|
b9f4ff6e9f | ||
|
|
942ced78ed | ||
|
|
9ae592209f | ||
|
|
dc2e0ec3b6 | ||
|
|
dd77a1fb9a | ||
|
|
2ef71d6def | ||
|
|
414ed74526 | ||
|
|
01eab08c1c | ||
|
|
5fd83a85e8 | ||
|
|
093131438d | ||
|
|
603b62fdb5 | ||
|
|
ec179380f4 | ||
|
|
7eddb38162 | ||
|
|
c54dfcade9 | ||
|
|
859ca7db68 | ||
|
|
df6fbb82be | ||
|
|
4b4b1eec8b | ||
|
|
d759fdd457 | ||
|
|
fa57a0fbac | ||
|
|
2a6250e3fb | ||
|
|
be26349e37 | ||
|
|
b2943670ca | ||
|
|
7e8d3423cd | ||
|
|
0df528cc9e | ||
|
|
21d1989e05 | ||
|
|
fa90bbc07a | ||
|
|
44eb7bfd25 | ||
|
|
6cb75924d9 | ||
|
|
cb98f5896f | ||
|
|
dfba6bf690 | ||
|
|
06b80629bc | ||
|
|
87edf6497d | ||
|
|
6bae276ecb | ||
|
|
b1abc813fc | ||
|
|
1264f8cff8 | ||
|
|
3b393e0e2d | ||
|
|
a7d55a5ad8 | ||
|
|
30da6bde6f | ||
|
|
d918602521 | ||
|
|
e2aef3fa43 | ||
|
|
1ed537dc52 | ||
|
|
072347e594 | ||
|
|
743ea6815b | ||
|
|
2f69cd1765 | ||
|
|
c1e91553b9 | ||
|
|
36a54a9c9d | ||
|
|
d88bb99957 | ||
|
|
6030306d9c | ||
|
|
aeeb123b1e | ||
|
|
019d363dcd | ||
|
|
038303e6a5 | ||
|
|
635c4b5b89 | ||
|
|
975a7b1fc0 | ||
|
|
52aeaf4924 | ||
|
|
6c2fa12f10 | ||
|
|
f3304d408c | ||
|
|
05e3539856 | ||
|
|
ff384cd658 | ||
|
|
62fff935da | ||
|
|
35bd34f8e6 | ||
|
|
02fdb4c879 | ||
|
|
621b1c57a3 | ||
|
|
d905317682 | ||
|
|
9e59d5eb52 | ||
|
|
10b8997cc5 | ||
|
|
d41209512e | ||
|
|
8cf7e424e2 | ||
|
|
cba64aaaa4 | ||
|
|
31b331ca67 | ||
|
|
e13088d911 | ||
|
|
d016f85110 | ||
|
|
bcadc2b45c | ||
|
|
afb2d5f105 | ||
|
|
15d892c62d | ||
|
|
eb0f3256d9 | ||
|
|
f9add77d7b | ||
|
|
4863f45f7e | ||
|
|
6f88df1fc8 | ||
|
|
aa76ed9baf | ||
|
|
bdb6a5501a | ||
|
|
7bf7524d22 | ||
|
|
b37bc47eaa | ||
|
|
c5c2cb13d4 | ||
|
|
8752326d8c | ||
|
|
52e2331dd4 | ||
|
|
5ad3bbb27f | ||
|
|
a253d276d7 | ||
|
|
effb5c4203 | ||
|
|
64f4a0d800 | ||
|
|
5ef3663385 | ||
|
|
9a727c3c1a | ||
|
|
3e1e982625 | ||
|
|
d506659635 | ||
|
|
9247e8522b | ||
|
|
ef740d0cca | ||
|
|
ac9b95ca0c | ||
|
|
bbe5c6acf0 | ||
|
|
5e4faec554 | ||
|
|
207beff489 | ||
|
|
60beab1e8d | ||
|
|
7afdc695fe | ||
|
|
3264fa8a6f | ||
|
|
55d8fe2837 | ||
|
|
3427b992f7 | ||
|
|
ee8f07a686 | ||
|
|
a37e562079 | ||
|
|
c49226613b | ||
|
|
3ede03449c | ||
|
|
60318b18f7 | ||
|
|
32a4e9bfe6 | ||
|
|
7d17a926ac | ||
|
|
ce1f757ce0 | ||
|
|
b01f0db381 | ||
|
|
0b7d3bfd30 | ||
|
|
0042a5c5fc | ||
|
|
edd22eb36c | ||
|
|
eb25148123 | ||
|
|
0fcc88689d | ||
|
|
03d62b2e43 | ||
|
|
93b07b3526 | ||
|
|
08ceb2a737 | ||
|
|
4194c613bf | ||
|
|
6a5e7be380 | ||
|
|
e583448a6d | ||
|
|
a17400b45e | ||
|
|
a1153ba1f7 | ||
|
|
425dec3037 | ||
|
|
a270aa3c53 | ||
|
|
8a6d68e5d2 | ||
|
|
79c45131d1 | ||
|
|
fe18bbcb1f | ||
|
|
7a322130d6 | ||
|
|
41e555aadf | ||
|
|
2f270e6fbb | ||
|
|
cfcf5437f4 | ||
|
|
f5a2cb3593 | ||
|
|
1624efa939 | ||
|
|
6a8a202b71 | ||
|
|
3c3f1b42bb | ||
|
|
9a44fc5142 | ||
|
|
e3cc298ffd | ||
|
|
cd46a535cd | ||
|
|
80f310e2a4 | ||
|
|
ffc2f687cf | ||
|
|
e5b8a37a20 | ||
|
|
3dc206c721 | ||
|
|
d8960d2c55 | ||
|
|
64a5e6af4a | ||
|
|
b320c7ebd5 | ||
|
|
293e94d0ed | ||
|
|
8d1e4b3648 | ||
|
|
6e23e40a2f | ||
|
|
61605c1dfa | ||
|
|
c8cdd542dd | ||
|
|
5797c77f55 | ||
|
|
ae67923bab | ||
|
|
1159e53618 | ||
|
|
3de694be05 | ||
|
|
7b18274d7e | ||
|
|
9f49585a63 | ||
|
|
de731edc0d | ||
|
|
4f9236ae55 | ||
|
|
ff6a1cee12 | ||
|
|
6d8a924889 | ||
|
|
e396684a54 | ||
|
|
8abb85e4b2 | ||
|
|
6f4b0c4fa6 | ||
|
|
cb0e3980d8 | ||
|
|
36eeb92391 | ||
|
|
b7d9b59aa9 | ||
|
|
62e88b46cc | ||
|
|
7f6827aaae | ||
|
|
abb6cfdebd | ||
|
|
feb890564b | ||
|
|
1d3e6758b2 | ||
|
|
c52c07c086 | ||
|
|
554ff98fd5 | ||
|
|
160b70f417 | ||
|
|
c8189d1018 | ||
|
|
316f594fa5 | ||
|
|
bedac6bc28 | ||
|
|
40a4688400 | ||
|
|
399b0dd686 | ||
|
|
ecfe84702b | ||
|
|
0f4fdb6669 | ||
|
|
71788cf43a | ||
|
|
5165e14802 | ||
|
|
ead37db595 | ||
|
|
522bff52fe | ||
|
|
d514a9c709 | ||
|
|
67f54eea66 | ||
|
|
1a0bb5ad5a | ||
|
|
7e8e85459c | ||
|
|
5fba7e4339 | ||
|
|
962fea87d3 | ||
|
|
08a3461810 | ||
|
|
60d4c9bd54 | ||
|
|
7a9d8f49f4 | ||
|
|
50b7b2113e | ||
|
|
0b8117df2f | ||
|
|
0393f598d5 | ||
|
|
5573d7508b | ||
|
|
542162b4e0 | ||
|
|
e7260518ea | ||
|
|
82258dff59 | ||
|
|
a2f8946764 | ||
|
|
171a7a107e | ||
|
|
6195229d76 | ||
|
|
062515d9bc | ||
|
|
311264b960 | ||
|
|
bdd2cd248d | ||
|
|
1f6a7da0b0 | ||
|
|
71d2d60b85 | ||
|
|
4e66465e22 | ||
|
|
2288777334 | ||
|
|
cf0429f3e1 | ||
|
|
dff6c5ff7a | ||
|
|
df78cb7ccb | ||
|
|
acada5a8f6 | ||
|
|
20f8dafcd4 | ||
|
|
7bb1d8a8d1 | ||
|
|
39b5f5bbc6 | ||
|
|
7ebe1fe115 | ||
|
|
843bd4156e | ||
|
|
ca8d0a0e92 | ||
|
|
5989d675ce | ||
|
|
c4869780d1 | ||
|
|
998793998d | ||
|
|
e2459be7e1 | ||
|
|
33de42e729 | ||
|
|
b3b854072b | ||
|
|
54eabdde58 | ||
|
|
6e6ff89972 | ||
|
|
0992621839 | ||
|
|
7e9d37acae | ||
|
|
bfddc0dc64 | ||
|
|
b9196d48d2 | ||
|
|
75cb40edd1 | ||
|
|
124f8d57ab | ||
|
|
f78e04a12c | ||
|
|
b93fd4e0c9 | ||
|
|
401e456a17 | ||
|
|
69828ed94b | ||
|
|
627299f5e4 | ||
|
|
e4c60435d2 | ||
|
|
486edb10db | ||
|
|
8c4e7ffb14 | ||
|
|
dd0da65da9 | ||
|
|
75395a12e5 | ||
|
|
8b2397542e | ||
|
|
6132c9f8d5 | ||
|
|
ca57014bf2 | ||
|
|
3304a4f622 | ||
|
|
6538b82928 | ||
|
|
aa1b0fca72 | ||
|
|
aa9365446b | ||
|
|
632c1e83f8 | ||
|
|
115c8f8dd5 | ||
|
|
b8f4099e55 | ||
|
|
6c899d8947 | ||
|
|
3b5b21d29f | ||
|
|
65dde0c965 | ||
|
|
eb3144bacb | ||
|
|
efd19f766f | ||
|
|
4c8fb76a72 | ||
|
|
37c1739483 | ||
|
|
71fba3d221 | ||
|
|
1a44a8402e | ||
|
|
f8000b355e | ||
|
|
1329ff5f36 | ||
|
|
658c759b3d | ||
|
|
6e0ba733f3 | ||
|
|
0b10c8da28 | ||
|
|
0d271cbb09 | ||
|
|
a40e8ae321 | ||
|
|
95544096bf | ||
|
|
58fc4b8ea8 | ||
|
|
cf2da96a28 | ||
|
|
e1b6145e5c | ||
|
|
903fe8db7e | ||
|
|
39be1377e2 | ||
|
|
de4c7bd317 | ||
|
|
f78acf53fb | ||
|
|
92d625b648 | ||
|
|
305f6f0295 | ||
|
|
7641f23f87 | ||
|
|
491b0a26e4 | ||
|
|
5febdd39a1 | ||
|
|
c5cfa6c09c | ||
|
|
d0d6e34746 | ||
|
|
1db056b19c | ||
|
|
893159454f | ||
|
|
ce54c45394 | ||
|
|
4e502fd624 | ||
|
|
ad2e157763 | ||
|
|
d42090d63b | ||
|
|
1d181f0ade | ||
|
|
93d1d33f3f | ||
|
|
9649cc8c50 | ||
|
|
cb26ca2ce7 | ||
|
|
657948dd0c | ||
|
|
7e8d548d24 | ||
|
|
4770bfbb5b | ||
|
|
3018dc636a | ||
|
|
f610f40558 | ||
|
|
eb67febcc4 | ||
|
|
3676f20923 | ||
|
|
7940e854e6 | ||
|
|
cb253fafe7 | ||
|
|
33001c8c4b | ||
|
|
a511d5d95e | ||
|
|
619b808b31 | ||
|
|
56bde1ceca | ||
|
|
7925a98141 | ||
|
|
461c8c97db | ||
|
|
593949c88e | ||
|
|
73873da0c0 | ||
|
|
dae84a96fb | ||
|
|
89c2383c71 | ||
|
|
582a7f449e | ||
|
|
8d853b7eb6 | ||
|
|
a482b5cf12 | ||
|
|
0f8b560bd5 | ||
|
|
8466ee1c62 | ||
|
|
d4e0116ba8 | ||
|
|
16f2e53d5f | ||
|
|
17dd3370fc | ||
|
|
710778dfdd | ||
|
|
ef589f8981 | ||
|
|
16428ccbd2 | ||
|
|
c9e5433a70 | ||
|
|
4b39a9eaf8 | ||
|
|
1c02193ddb | ||
|
|
2be864c218 | ||
|
|
22339c9ba9 | ||
|
|
a8bfa02af1 | ||
|
|
8fedcffc02 | ||
|
|
5a0ae9a055 | ||
|
|
4d7d32c846 | ||
|
|
e3058de235 | ||
|
|
d7304e7c75 | ||
|
|
bde9269510 | ||
|
|
a5c7c469ee | ||
|
|
4e0787dcf3 | ||
|
|
7e59ef65e6 | ||
|
|
06e794898f | ||
|
|
5591fdff8d | ||
|
|
ae31233b19 | ||
|
|
b96a41d19e | ||
|
|
a416f30459 | ||
|
|
a2bc93547f | ||
|
|
bdac428d79 | ||
|
|
f7595c3348 | ||
|
|
a5abaed4ce | ||
|
|
7338c1b892 | ||
|
|
4321a363a4 | ||
|
|
d30ae35c62 | ||
|
|
292a337dad | ||
|
|
897635b32b | ||
|
|
e56c63172c | ||
|
|
3f7af974a3 | ||
|
|
d8272d4010 | ||
|
|
1163c6345b | ||
|
|
b7a9969e73 | ||
|
|
4fb762f6e4 | ||
|
|
78fecfe558 | ||
|
|
02282ba679 | ||
|
|
553544feac | ||
|
|
b0fd814975 | ||
|
|
80029d63f0 | ||
|
|
f0bf15d2cb | ||
|
|
fadd01e93e | ||
|
|
29ac62d7b0 | ||
|
|
01697a9ab8 | ||
|
|
d1cbf19798 | ||
|
|
451e1900a9 | ||
|
|
86f0baf146 | ||
|
|
7c9584e408 | ||
|
|
f952ac1dee | ||
|
|
52dd15dd87 | ||
|
|
984c6c33bc | ||
|
|
84be084384 | ||
|
|
91bafce012 | ||
|
|
77b328475a | ||
|
|
cc31f2f6e9 | ||
|
|
a83c7764f5 | ||
|
|
f374268521 | ||
|
|
ca48de34e9 | ||
|
|
2042facc8b | ||
|
|
df947d4056 | ||
|
|
3d6783e38c | ||
|
|
6c456aa15e | ||
|
|
bf1b3c1166 | ||
|
|
45517ad616 | ||
|
|
6d57b0ddb7 | ||
|
|
038550c889 | ||
|
|
2b9d47ff01 | ||
|
|
bc64aa2cf2 | ||
|
|
a6fba1b8a6 | ||
|
|
05215e8e7d | ||
|
|
fdbac8e51d | ||
|
|
e3385174c3 | ||
|
|
94ce9cad2a | ||
|
|
6ac9904ee5 | ||
|
|
4a429c11d5 | ||
|
|
cbf8c632dc | ||
|
|
578fc220ad | ||
|
|
cae9809e11 | ||
|
|
570564a375 | ||
|
|
5058406b84 | ||
|
|
7e6e9a0155 | ||
|
|
6137f1b0b2 | ||
|
|
689fdc1d0b | ||
|
|
791767d62f | ||
|
|
7455717359 | ||
|
|
3289d8482c | ||
|
|
8ce59e67d5 | ||
|
|
5f48fa3a6e | ||
|
|
0fff8a32b5 | ||
|
|
975c915632 | ||
|
|
307c1b3321 | ||
|
|
37da5dcdb6 | ||
|
|
35ae8ef313 | ||
|
|
14ec958b8f | ||
|
|
5b34bde1a4 | ||
|
|
44cfd1d49b | ||
|
|
7b1687ac0e | ||
|
|
648c15fbac | ||
|
|
34fd9dd88d | ||
|
|
37799b8560 | ||
|
|
64adf68436 | ||
|
|
f97dcc8e40 | ||
|
|
86dcdaae33 | ||
|
|
9fb526d554 | ||
|
|
e338cb00f3 | ||
|
|
d3edcc3fab | ||
|
|
e6a54f732e | ||
|
|
2e7c9ad2f3 | ||
|
|
367c3f034e | ||
|
|
901d83fcff | ||
|
|
4b22dcb7ad | ||
|
|
86c28f2d57 | ||
|
|
41fccf9fe4 | ||
|
|
4c17395deb | ||
|
|
240a012bd8 | ||
|
|
929b623e59 | ||
|
|
709d8223f5 | ||
|
|
8746283787 | ||
|
|
ff1b857f90 | ||
|
|
c010e93d4a | ||
|
|
5d522b0017 | ||
|
|
42c2282f12 | ||
|
|
8e23542b85 | ||
|
|
ef80a99397 | ||
|
|
ba11247f93 | ||
|
|
e5431ca7e5 | ||
|
|
b019a6aad9 | ||
|
|
3a1ffe4c69 | ||
|
|
9b4b0de746 | ||
|
|
a3441215f1 | ||
|
|
5adb2dc4cf | ||
|
|
3f7248fa11 | ||
|
|
5839981255 | ||
|
|
cd7db58ce3 | ||
|
|
3d74d8e95b | ||
|
|
3869421258 | ||
|
|
b4b2c18909 | ||
|
|
95d5334783 | ||
|
|
6f757b28f3 | ||
|
|
db2cf53e7b | ||
|
|
33ba1f38d6 | ||
|
|
3d680a6d82 | ||
|
|
c9bcf1b3f7 | ||
|
|
242b255aac | ||
|
|
5351f69e49 | ||
|
|
631d2b4214 | ||
|
|
235e1399eb | ||
|
|
163e7046cb | ||
|
|
41d174b7f6 | ||
|
|
07bbd6c95a | ||
|
|
f761bc3cdd | ||
|
|
e28903cb6d | ||
|
|
4f487cf746 | ||
|
|
87fd7da6d7 | ||
|
|
f15350b776 | ||
|
|
3ac8cf0380 | ||
|
|
9323fa7688 | ||
|
|
c879fa1e79 | ||
|
|
ba448fbd54 | ||
|
|
7b948b0647 | ||
|
|
3e1ff464f1 | ||
|
|
3b96c4c9cd | ||
|
|
b7a314a7dc | ||
|
|
3044b805b3 | ||
|
|
e500340621 | ||
|
|
61b23e3811 | ||
|
|
c604b9c6a9 | ||
|
|
6450a5b191 | ||
|
|
e502757963 | ||
|
|
3815009cf1 | ||
|
|
92bff79d3d | ||
|
|
2dce3856cd | ||
|
|
a6e3ed1025 | ||
|
|
d3b85ed7d8 | ||
|
|
9581c39dcc | ||
|
|
88e8fb1029 | ||
|
|
3e5cf4da0b | ||
|
|
632e60eccd | ||
|
|
f4673d87ce | ||
|
|
3132937112 | ||
|
|
e6678abba6 | ||
|
|
ba274dd312 | ||
|
|
11031a7d36 | ||
|
|
efe248c46a | ||
|
|
68e4ef21db | ||
|
|
fa81710d16 | ||
|
|
3b4cbcf631 | ||
|
|
589eabc0cb | ||
|
|
c22f958152 | ||
|
|
680e14cb65 | ||
|
|
b8cd36af89 | ||
|
|
680a504652 | ||
|
|
0e79c3ddc0 | ||
|
|
20888cfa59 | ||
|
|
d2548b25f2 | ||
|
|
705e3e8d1c | ||
|
|
96961081b0 | ||
|
|
27182d614b | ||
|
|
b76d5dfc5b | ||
|
|
147a6c8548 | ||
|
|
6e2e8c047f | ||
|
|
58cb15c52a | ||
|
|
a4fae019de | ||
|
|
a9a65800b8 | ||
|
|
f8ba15e8dd | ||
|
|
2785225a43 | ||
|
|
f22a9f2762 | ||
|
|
4cd296a3f3 | ||
|
|
cfef4ba047 | ||
|
|
304f1bb457 | ||
|
|
44ab21485d | ||
|
|
3d62b46073 | ||
|
|
4621d209ca | ||
|
|
8c1ecf875e | ||
|
|
9b43579c03 | ||
|
|
ae2263d165 | ||
|
|
db72f77581 | ||
|
|
63d4bcde56 | ||
|
|
365a5666f3 | ||
|
|
5935cf1c41 | ||
|
|
9d2b5ca345 | ||
|
|
503df095b2 | ||
|
|
70dbd1c382 | ||
|
|
223c7c0080 | ||
|
|
dd2711d78c | ||
|
|
840142397d | ||
|
|
de7bc9f96e | ||
|
|
750ead5be2 | ||
|
|
9c0944ec1e | ||
|
|
0b3138e1bf | ||
|
|
b587c7f72d | ||
|
|
145bdd7466 | ||
|
|
51652cf8d5 | ||
|
|
db82fbadc1 | ||
|
|
3334ab389c | ||
|
|
52dbaa4ac1 | ||
|
|
8a19ff3baf | ||
|
|
2127c65561 | ||
|
|
b3a7ec4f56 | ||
|
|
23545a077c | ||
|
|
cd842fafb9 | ||
|
|
9996021d34 | ||
|
|
5a56d54086 | ||
|
|
e5a6403b81 | ||
|
|
42d2190343 | ||
|
|
ac5ba1b8ec | ||
|
|
10e6b1ed99 | ||
|
|
c879d6824b | ||
|
|
e2e34ad273 | ||
|
|
1fe24566ad | ||
|
|
9d4eb4cac5 | ||
|
|
d77901e8ed | ||
|
|
0c954d99c3 | ||
|
|
2db3851430 | ||
|
|
843300dec5 | ||
|
|
19ebdbf6a6 | ||
|
|
1508a5bb2c | ||
|
|
f4bf45d809 | ||
|
|
db4645fc65 | ||
|
|
7ef6c46aaf | ||
|
|
3514843818 | ||
|
|
5a80c71607 | ||
|
|
35e1120341 | ||
|
|
0143885a41 | ||
|
|
d57f06e3d8 | ||
|
|
a03a3d1d55 | ||
|
|
56928896b8 | ||
|
|
ca5eca9567 | ||
|
|
536cf2364d | ||
|
|
189ad71ac0 | ||
|
|
bc8435c736 | ||
|
|
658dde3b9f | ||
|
|
3bf062aa2d | ||
|
|
9bc918fa7b | ||
|
|
d2dee3d5a4 | ||
|
|
c389329878 | ||
|
|
9c88c4a164 | ||
|
|
bf46530c5a | ||
|
|
df4b4e6902 | ||
|
|
ab4be7357f | ||
|
|
29ada8b41a | ||
|
|
42f14e7c4d | ||
|
|
6b7e0676b9 | ||
|
|
36f1332181 | ||
|
|
ef38c58e5f | ||
|
|
e71f0b2f34 | ||
|
|
3cbc01e51f | ||
|
|
596f8701ab | ||
|
|
5a03642d50 | ||
|
|
7169b484b1 | ||
|
|
95e9dff362 | ||
|
|
48ca4dc880 | ||
|
|
1e77fb2630 | ||
|
|
17023457a9 | ||
|
|
eaa6e239f7 | ||
|
|
2a39f48deb | ||
|
|
941b31f90b | ||
|
|
a758f2370a | ||
|
|
72f2fe3399 | ||
|
|
fe80669639 | ||
|
|
1394dcba69 | ||
|
|
b6b3e2b914 | ||
|
|
3e54a83820 | ||
|
|
b9282f12b1 | ||
|
|
ed4aefc59e | ||
|
|
c697604224 | ||
|
|
13c1c11623 | ||
|
|
54b820773c | ||
|
|
dfe52a0de5 | ||
|
|
61b9ea24a8 | ||
|
|
c9495c33a7 | ||
|
|
2121961929 | ||
|
|
568dc57186 | ||
|
|
43e975b10d | ||
|
|
e7030b6b87 | ||
|
|
5a478514ee | ||
|
|
68d0253d64 | ||
|
|
86aa83e46f | ||
|
|
96f8d17f4f | ||
|
|
e47f0ca8f4 | ||
|
|
034febc8e3 | ||
|
|
2fffe65332 | ||
|
|
5b63c08c72 | ||
|
|
48acd0bf4d | ||
|
|
68f6a22d75 | ||
|
|
5d2dc481ef | ||
|
|
2b14eb5b4a | ||
|
|
b5b5d7bf84 | ||
|
|
6ff2a2e407 | ||
|
|
12f96dc321 | ||
|
|
2cd83d1b58 | ||
|
|
c2c82f60f8 | ||
|
|
af75a61f69 | ||
|
|
81c9d10596 | ||
|
|
db98d1a664 | ||
|
|
68d797e322 | ||
|
|
2d69c5d879 | ||
|
|
230ef2110b | ||
|
|
2fc81904c6 | ||
|
|
ff091efe7b | ||
|
|
7ea03d9ee2 | ||
|
|
a2555b39d7 | ||
|
|
2cc017981b | ||
|
|
886a4fb7f1 | ||
|
|
0e97374466 | ||
|
|
65bcb9b0ca | ||
|
|
44889af074 | ||
|
|
f7ed002f66 | ||
|
|
c6e54c4b1f | ||
|
|
415fc52b08 | ||
|
|
17302c0e23 | ||
|
|
73704e9ed5 | ||
|
|
1618b3c040 | ||
|
|
08899f2224 | ||
|
|
a0ac8fd214 | ||
|
|
d98cd61ec9 | ||
|
|
6b506545cd | ||
|
|
8336eab1e1 | ||
|
|
83396d9644 | ||
|
|
6137af9c86 | ||
|
|
031caba9c0 | ||
|
|
3904c2be9a | ||
|
|
40dd2acfd9 | ||
|
|
41b78b263d | ||
|
|
8072ea6930 | ||
|
|
0b193d9c88 | ||
|
|
7463335255 | ||
|
|
6387299f94 | ||
|
|
0f197e85cc | ||
|
|
688fa185b0 | ||
|
|
29cd24bbc6 | ||
|
|
9d14e3c281 | ||
|
|
709d450bd7 | ||
|
|
cffec5e0fe | ||
|
|
74603017b6 | ||
|
|
84d6b865dd | ||
|
|
58a1b9928c | ||
|
|
7fcec8102f | ||
|
|
e583c42b81 | ||
|
|
2e43f7ac2b | ||
|
|
f39692acc7 | ||
|
|
36dc04734e | ||
|
|
3d60a6f446 | ||
|
|
feb1b86d1c | ||
|
|
01f90611b1 | ||
|
|
455a681204 | ||
|
|
ac506c5a20 | ||
|
|
3e41fd11fc | ||
|
|
22804de061 | ||
|
|
b41c4da040 | ||
|
|
ab2435a1b9 | ||
|
|
83041d2695 | ||
|
|
dc6cd053da | ||
|
|
6e185cb944 | ||
|
|
46d476b0c2 | ||
|
|
dcc41cc8e1 | ||
|
|
5f8a0836bd | ||
|
|
990c3eef48 | ||
|
|
636e2ef520 | ||
|
|
f64c2d8d08 | ||
|
|
0d5d685514 | ||
|
|
e77a3a9941 | ||
|
|
7fdde81b8f | ||
|
|
9dfe6c85e9 | ||
|
|
f103787644 | ||
|
|
f1d01113d2 | ||
|
|
f101785ea1 | ||
|
|
a7e6f630d7 | ||
|
|
fd07245a0a | ||
|
|
fe4760787e | ||
|
|
b8df3634cc | ||
|
|
6062e896b9 | ||
|
|
038f4ca8b5 | ||
|
|
fbae76885a | ||
|
|
59fd18e8ce | ||
|
|
edf80f5e3d | ||
|
|
a3ed29156a | ||
|
|
728fce7494 | ||
|
|
2958b53293 | ||
|
|
e562403e1c | ||
|
|
5d061f13f9 | ||
|
|
6362a12bd7 | ||
|
|
df53793680 | ||
|
|
47e2026ca6 | ||
|
|
1cf82595a7 | ||
|
|
98a2afd40b | ||
|
|
1ce7fded61 | ||
|
|
2e55b493c6 | ||
|
|
575fe62425 | ||
|
|
9f8b2bb468 | ||
|
|
197a50ea96 | ||
|
|
c9a5913cf8 | ||
|
|
c16592282a | ||
|
|
eaa3428d58 | ||
|
|
3bcb955a07 | ||
|
|
a36136f82c | ||
|
|
11a6ce0f3c | ||
|
|
426507adeb | ||
|
|
198ea7fa1e | ||
|
|
3e936c2eb6 | ||
|
|
465e834113 | ||
|
|
ecb9007bb0 | ||
|
|
6a6cf23179 | ||
|
|
856c37012b | ||
|
|
29218ce28a | ||
|
|
029ac847ad | ||
|
|
f524a3d990 | ||
|
|
45fe94db52 | ||
|
|
deee3c8b6a | ||
|
|
e6bbdc611a | ||
|
|
7d76a151b3 | ||
|
|
d7581d0ac6 | ||
|
|
9df6ae099b | ||
|
|
5ce528e0d7 | ||
|
|
e82aa87a2b | ||
|
|
bcfbe0d9c4 | ||
|
|
4f1625afb7 | ||
|
|
73b5cc9a26 | ||
|
|
5dd79ce27a | ||
|
|
01f2ebcf46 | ||
|
|
1072e47639 |
@@ -0,0 +1 @@
|
||||
testdata/*.[0-9] linguist-documentation
|
||||
@@ -0,0 +1,2 @@
|
||||
github: [NLnetLabs]
|
||||
custom: ['https://nlnetlabs.nl/funding/']
|
||||
+20
-1
@@ -1,12 +1,15 @@
|
||||
*.lo
|
||||
*.o
|
||||
/.libs/
|
||||
/.source
|
||||
/Makefile
|
||||
/autom4te.cache/
|
||||
/config.h
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/doc/example.conf
|
||||
/doc/libunbound.3
|
||||
/doc/unbound-anchor.8
|
||||
@@ -17,6 +20,7 @@
|
||||
/doc/unbound.conf.5
|
||||
/libtool
|
||||
/libunbound.la
|
||||
/_unbound.la
|
||||
/smallapp/unbound-control-setup.sh
|
||||
/unbound
|
||||
/unbound-anchor
|
||||
@@ -33,6 +37,21 @@
|
||||
/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
|
||||
+657
-302
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 lean more about Unbound by reading our
|
||||
[documentation](https://nlnetlabs.nl/documentation/unbound/).
|
||||
|
||||
## Compiling
|
||||
|
||||
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
|
||||
installed. Unbound can be compiled and installed using:
|
||||
|
||||
```
|
||||
./configure && make && make install
|
||||
```
|
||||
|
||||
You can use libevent if you want. libevent is useful when using many (10000)
|
||||
outgoing ports. By default max 256 ports are opened at the same time and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
|
||||
Use the `--with-libevent=dir` configure option to compile Unbound with libevent
|
||||
support.
|
||||
|
||||
## Unbound configuration
|
||||
|
||||
All of Unbound's configuration options are described in the man pages, which
|
||||
will be installed and are available on the Unbound
|
||||
[documentation page](https://nlnetlabs.nl/documentation/unbound/).
|
||||
|
||||
An example configuration file is located in
|
||||
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
|
||||
+14
-3
@@ -103,9 +103,20 @@ AC_DEFUN([AC_PROG_SWIG],[
|
||||
if test -z "$available_patch" ; then
|
||||
[available_patch=0]
|
||||
fi
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; then
|
||||
[badversion=0]
|
||||
if test $available_major -lt $required_major ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -lt $required_minor ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -eq $required_minor \
|
||||
-a $available_patch -lt $required_patch ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $badversion -eq 1 ; then
|
||||
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
|
||||
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
|
||||
Vendored
+396
-2
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 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,
|
||||
@@ -9044,3 +9044,397 @@ 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 Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful, but
|
||||
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
dnl General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl As a special exception to the GNU General Public License, if you
|
||||
dnl distribute this file as part of a program that contains a
|
||||
dnl configuration script generated by Autoconf, you may include it under
|
||||
dnl the same distribution terms that you use for the rest of that
|
||||
dnl program.
|
||||
|
||||
dnl PKG_PREREQ(MIN-VERSION)
|
||||
dnl -----------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Verify that the version of the pkg-config macros are at least
|
||||
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
|
||||
dnl installed version of pkg-config, this checks the developer's version
|
||||
dnl of pkg.m4 when generating configure.
|
||||
dnl
|
||||
dnl To ensure that this macro is defined, also add:
|
||||
dnl m4_ifndef([PKG_PREREQ],
|
||||
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
|
||||
dnl
|
||||
dnl See the "Since" comment for each macro you use to see what version
|
||||
dnl of the macros you require.
|
||||
m4_defun([PKG_PREREQ],
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
|
||||
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
dnl ----------------------------------
|
||||
dnl Since: 0.16
|
||||
dnl
|
||||
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
|
||||
dnl first found in the path. Checks that the version of pkg-config found
|
||||
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
|
||||
dnl used since that's the first version where most current features of
|
||||
dnl pkg-config existed.
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])dnl PKG_PROG_PKG_CONFIG
|
||||
|
||||
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------------------------------
|
||||
dnl Since: 0.18
|
||||
dnl
|
||||
dnl Check to see whether a particular set of modules exists. Similar to
|
||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
dnl
|
||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
dnl only at the first occurence in configure.ac, so if the first place
|
||||
dnl it's called might be skipped (such as if it is within an "if", you
|
||||
dnl have to call PKG_CHECK_EXISTS manually
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
dnl ---------------------------------------------
|
||||
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
|
||||
dnl pkg_failed based on the result.
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])dnl _PKG_CONFIG
|
||||
|
||||
dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
dnl ---------------------------
|
||||
dnl Internal check to see if pkg-config supports short errors.
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl --------------------------------------------------------------
|
||||
dnl Since: 0.4.0
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
|
||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])dnl PKG_CHECK_MODULES
|
||||
|
||||
|
||||
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl ---------------------------------------------------------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Checks for existence of MODULES and gathers its build flags with
|
||||
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
|
||||
dnl and VARIABLE-PREFIX_LIBS from --libs.
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
|
||||
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
|
||||
dnl configure.ac.
|
||||
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
_save_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES($@)
|
||||
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
|
||||
])dnl PKG_CHECK_MODULES_STATIC
|
||||
|
||||
|
||||
dnl PKG_INSTALLDIR([DIRECTORY])
|
||||
dnl -------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable pkgconfigdir as the location where a module
|
||||
dnl should install pkg-config .pc files. By default the directory is
|
||||
dnl $libdir/pkgconfig, but the default can be changed by passing
|
||||
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
dnl parameter.
|
||||
AC_DEFUN([PKG_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
|
||||
[with_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
])dnl PKG_INSTALLDIR
|
||||
|
||||
|
||||
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
|
||||
dnl --------------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
dnl module should install arch-independent pkg-config .pc files. By
|
||||
dnl default the directory is $datadir/pkgconfig, but the default can be
|
||||
dnl changed by passing DIRECTORY. The user can override through the
|
||||
dnl --with-noarch-pkgconfigdir parameter.
|
||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([noarch-pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
|
||||
[with_noarch_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
])dnl PKG_NOARCH_INSTALLDIR
|
||||
|
||||
|
||||
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------
|
||||
dnl Since: 0.28
|
||||
dnl
|
||||
dnl Retrieves the value of the pkg-config variable for the given module.
|
||||
AC_DEFUN([PKG_CHECK_VAR],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
||||
|
||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
||||
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-2018 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ([2.52])dnl
|
||||
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# 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,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# --------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
|
||||
+39
-18
@@ -2,7 +2,9 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 32
|
||||
# Version 34
|
||||
# 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
|
||||
# 2015-12-11 FLTO check for new OSX, clang.
|
||||
# 2015-11-18 spelling check fix.
|
||||
@@ -671,30 +673,30 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
ACX_RUNTIME_PATH_ADD([$ssldir/lib])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for HMAC_CTX_init in -lcrypto])
|
||||
AC_MSG_CHECKING([for HMAC_Update in -lcrypto])
|
||||
LIBS="$LIBS -lcrypto"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
|
||||
AC_TRY_LINK(, [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
# check if -lwsock32 or -lgdi32 are needed.
|
||||
BAKLIBS="$LIBS"
|
||||
BAKSSLLIBS="$LIBSSL_LIBS"
|
||||
LIBS="$LIBS -lgdi32"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32"
|
||||
LIBS="$LIBS -lgdi32 -lws2_32"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -704,15 +706,30 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -ldl])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
int HMAC_Update(void);
|
||||
(void)HMAC_Update();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
|
||||
[If you have HMAC_Update])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
|
||||
LIBS="$BAKLIBS"
|
||||
LIBSSL_LIBS="$BAKSSLLIBS"
|
||||
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_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
@@ -822,7 +839,11 @@ dnl see if on windows
|
||||
if test "$ac_cv_header_windows_h" = "yes"; then
|
||||
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
||||
USE_WINSOCK="1"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
if echo $LIBS | grep 'lws2_32' >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -lws2_32"
|
||||
fi
|
||||
fi
|
||||
],
|
||||
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
|
||||
|
||||
+7
-3
@@ -22,8 +22,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
@@ -54,11 +53,16 @@ $ac_distutils_result])
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print(get_config_var('BLDLIBRARY'));"`
|
||||
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
|
||||
fi
|
||||
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
|
||||
#
|
||||
|
||||
@@ -0,0 +1,858 @@
|
||||
/*
|
||||
* cachedb/cachedb.c - cache from a database external to the program module
|
||||
*
|
||||
* Copyright (c) 2016, 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
|
||||
*
|
||||
* This file contains a module that uses an external database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "cachedb/redis.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "validator/val_neg.h"
|
||||
#include "validator/val_secalgo.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
/* header file for htobe64 */
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#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). */
|
||||
struct testframe_moddata {
|
||||
/** lock for mutex */
|
||||
lock_basic_type lock;
|
||||
/** key for single stored data element, NULL if none */
|
||||
char* stored_key;
|
||||
/** data for single stored data element, NULL if none */
|
||||
uint8_t* stored_data;
|
||||
/** length of stored data */
|
||||
size_t stored_datalen;
|
||||
};
|
||||
|
||||
static int
|
||||
testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct testframe_moddata* d;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_init");
|
||||
d = (struct testframe_moddata*)calloc(1,
|
||||
sizeof(struct testframe_moddata));
|
||||
cachedb_env->backend_data = (void*)d;
|
||||
if(!cachedb_env->backend_data) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
lock_basic_init(&d->lock);
|
||||
lock_protect(&d->lock, d, sizeof(*d));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
testframe_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_deinit");
|
||||
if(!d)
|
||||
return;
|
||||
lock_basic_destroy(&d->lock);
|
||||
free(d->stored_key);
|
||||
free(d->stored_data);
|
||||
free(d);
|
||||
}
|
||||
|
||||
static int
|
||||
testframe_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_lookup of %s", key);
|
||||
lock_basic_lock(&d->lock);
|
||||
if(d->stored_key && strcmp(d->stored_key, key) == 0) {
|
||||
if(d->stored_datalen > sldns_buffer_capacity(result_buffer)) {
|
||||
lock_basic_unlock(&d->lock);
|
||||
return 0; /* too large */
|
||||
}
|
||||
verbose(VERB_ALGO, "testframe_lookup found %d bytes",
|
||||
(int)d->stored_datalen);
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, d->stored_data,
|
||||
d->stored_datalen);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
lock_basic_unlock(&d->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_basic_unlock(&d->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
testframe_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
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;
|
||||
(void)env;
|
||||
lock_basic_lock(&d->lock);
|
||||
verbose(VERB_ALGO, "testframe_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* free old data element (if any) */
|
||||
free(d->stored_key);
|
||||
d->stored_key = NULL;
|
||||
free(d->stored_data);
|
||||
d->stored_data = NULL;
|
||||
d->stored_datalen = 0;
|
||||
|
||||
d->stored_data = memdup(data, data_len);
|
||||
if(!d->stored_data) {
|
||||
lock_basic_unlock(&d->lock);
|
||||
log_err("out of memory");
|
||||
return;
|
||||
}
|
||||
d->stored_datalen = data_len;
|
||||
d->stored_key = strdup(key);
|
||||
if(!d->stored_key) {
|
||||
free(d->stored_data);
|
||||
d->stored_data = NULL;
|
||||
d->stored_datalen = 0;
|
||||
lock_basic_unlock(&d->lock);
|
||||
return;
|
||||
}
|
||||
lock_basic_unlock(&d->lock);
|
||||
/* (key,data) successfully stored */
|
||||
}
|
||||
|
||||
/** The testframe backend is for unit tests */
|
||||
static struct cachedb_backend testframe_backend = { "testframe",
|
||||
testframe_init, testframe_deinit, testframe_lookup, testframe_store
|
||||
};
|
||||
|
||||
/** find a particular backend from possible backends */
|
||||
static struct cachedb_backend*
|
||||
cachedb_find_backend(const char* str)
|
||||
{
|
||||
#ifdef USE_REDIS
|
||||
if(strcmp(str, redis_backend.name) == 0)
|
||||
return &redis_backend;
|
||||
#endif
|
||||
if(strcmp(str, testframe_backend.name) == 0)
|
||||
return &testframe_backend;
|
||||
/* TODO add more backends here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** apply configuration to cachedb module 'global' state */
|
||||
static int
|
||||
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
|
||||
{
|
||||
const char* backend_str = cfg->cachedb_backend;
|
||||
cachedb_env->backend = cachedb_find_backend(backend_str);
|
||||
if(!cachedb_env->backend) {
|
||||
log_err("cachedb: cannot find backend name '%s'", backend_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO see if more configuration needs to be applied or not */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
cachedb_init(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
|
||||
sizeof(struct cachedb_env));
|
||||
if(!cachedb_env) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
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 */
|
||||
if(!cachedb_env->backend || !cachedb_env->backend->name)
|
||||
return 1;
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_deinit(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* cachedb_env;
|
||||
if(!env || !env->modinfo[id])
|
||||
return;
|
||||
cachedb_env = (struct cachedb_env*)env->modinfo[id];
|
||||
/* free contents */
|
||||
/* TODO */
|
||||
if(cachedb_env->enabled) {
|
||||
(*cachedb_env->backend->deinit)(env, cachedb_env);
|
||||
}
|
||||
|
||||
free(cachedb_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
/** new query for cachedb */
|
||||
static int
|
||||
cachedb_new(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct cachedb_qstate* iq = (struct cachedb_qstate*)regional_alloc(
|
||||
qstate->region, sizeof(struct cachedb_qstate));
|
||||
qstate->minfo[id] = iq;
|
||||
if(!iq)
|
||||
return 0;
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
/* initialise it */
|
||||
/* TODO */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error
|
||||
* @param qstate: our query state
|
||||
* @param id: module id
|
||||
* @param rcode: error code (DNS errcode).
|
||||
* @return: 0 for use by caller, to make notation easy, like:
|
||||
* return error_response(..).
|
||||
*/
|
||||
static int
|
||||
error_response(struct module_qstate* qstate, int id, int rcode)
|
||||
{
|
||||
verbose(VERB_QUERY, "return error response %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??");
|
||||
qstate->return_rcode = rcode;
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the query name, type, class and dbacess-secret into lookup buffer.
|
||||
* @param qstate: query state with query info
|
||||
* and env->cfg with secret.
|
||||
* @param buf: returned buffer with hash to lookup
|
||||
* @param len: length of the buffer.
|
||||
*/
|
||||
static void
|
||||
calc_hash(struct module_qstate* qstate, char* buf, size_t len)
|
||||
{
|
||||
uint8_t clear[1024];
|
||||
size_t clen = 0;
|
||||
uint8_t hash[CACHEDB_HASHSIZE/8];
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
const char* secret = qstate->env->cfg->cachedb_secret;
|
||||
size_t i;
|
||||
|
||||
/* copy the hash info into the clear buffer */
|
||||
if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
|
||||
memmove(clear+clen, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len);
|
||||
clen += qstate->qinfo.qname_len;
|
||||
}
|
||||
if(clen + 4 < sizeof(clear)) {
|
||||
uint16_t t = htons(qstate->qinfo.qtype);
|
||||
uint16_t c = htons(qstate->qinfo.qclass);
|
||||
memmove(clear+clen, &t, 2);
|
||||
memmove(clear+clen+2, &c, 2);
|
||||
clen += 4;
|
||||
}
|
||||
if(secret && secret[0] && clen + strlen(secret) < sizeof(clear)) {
|
||||
memmove(clear+clen, secret, strlen(secret));
|
||||
clen += strlen(secret);
|
||||
}
|
||||
|
||||
/* 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) */
|
||||
log_assert(len >= sizeof(hash)*2 + 1);
|
||||
(void)len;
|
||||
for(i=0; i<sizeof(hash); i++) {
|
||||
buf[i*2] = hex[(hash[i]&0xf0)>>4];
|
||||
buf[i*2+1] = hex[hash[i]&0x0f];
|
||||
}
|
||||
buf[sizeof(hash)*2] = 0;
|
||||
}
|
||||
|
||||
/** convert data from return_msg into the data buffer */
|
||||
static int
|
||||
prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
uint64_t timestamp, expiry;
|
||||
size_t oldlim;
|
||||
struct edns_data edns;
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
edns.edns_present = 1;
|
||||
edns.bits = EDNS_DO;
|
||||
edns.ext_rcode = 0;
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
|
||||
if(!qstate->return_msg || !qstate->return_msg->rep)
|
||||
return 0;
|
||||
/* We don't store the reply if its TTL is 0 unless serve-expired is
|
||||
* enabled. Such a reply won't be reusable and simply be a waste for
|
||||
* the backend. It's also compatible with the default behavior of
|
||||
* dns_cache_store_msg(). */
|
||||
if(qstate->return_msg->rep->ttl == 0 &&
|
||||
!qstate->env->cfg->serve_expired)
|
||||
return 0;
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
if(!reply_info_answer_encode(&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->query_flags,
|
||||
buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0))
|
||||
return 0;
|
||||
|
||||
/* TTLs in the return_msg are relative to time(0) so we have to
|
||||
* store that, we also store the smallest ttl in the packet+time(0)
|
||||
* as the packet expiry time */
|
||||
/* qstate->return_msg->rep->ttl contains that relative shortest ttl */
|
||||
timestamp = (uint64_t)*qstate->env->now;
|
||||
expiry = timestamp + (uint64_t)qstate->return_msg->rep->ttl;
|
||||
timestamp = htobe64(timestamp);
|
||||
expiry = htobe64(expiry);
|
||||
oldlim = sldns_buffer_limit(buf);
|
||||
if(oldlim + sizeof(timestamp)+sizeof(expiry) >=
|
||||
sldns_buffer_capacity(buf))
|
||||
return 0; /* doesn't fit. */
|
||||
sldns_buffer_set_limit(buf, oldlim + sizeof(timestamp)+sizeof(expiry));
|
||||
sldns_buffer_write_at(buf, oldlim, ×tamp, sizeof(timestamp));
|
||||
sldns_buffer_write_at(buf, oldlim+sizeof(timestamp), &expiry,
|
||||
sizeof(expiry));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check expiry, return true if matches OK */
|
||||
static int
|
||||
good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
uint64_t expiry;
|
||||
/* the expiry time is the last bytes of the buffer */
|
||||
if(sldns_buffer_limit(buf) < sizeof(expiry))
|
||||
return 0;
|
||||
sldns_buffer_read_at(buf, sldns_buffer_limit(buf)-sizeof(expiry),
|
||||
&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 ||
|
||||
(SERVE_EXPIRED_TTL &&
|
||||
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
|
||||
* negative, set the TTL to 0. */
|
||||
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;
|
||||
if(subtract >= 0 && data->ttl > subtract)
|
||||
data->ttl -= subtract;
|
||||
else data->ttl = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
|
||||
* negative, set the TTLs to 0. */
|
||||
static void
|
||||
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;
|
||||
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->
|
||||
rep->rrsets[i]->entry.data, adjust);
|
||||
}
|
||||
}
|
||||
|
||||
/** convert dns message in buffer to return_msg */
|
||||
static int
|
||||
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
uint64_t timestamp, expiry;
|
||||
time_t adjust;
|
||||
size_t lim = sldns_buffer_limit(buf);
|
||||
if(lim < LDNS_HEADER_SIZE+sizeof(timestamp)+sizeof(expiry))
|
||||
return 0; /* too short */
|
||||
|
||||
/* remove timestamp and expiry from end */
|
||||
sldns_buffer_read_at(buf, lim-sizeof(expiry), &expiry, sizeof(expiry));
|
||||
sldns_buffer_read_at(buf, lim-sizeof(expiry)-sizeof(timestamp),
|
||||
×tamp, sizeof(timestamp));
|
||||
expiry = be64toh(expiry);
|
||||
timestamp = be64toh(timestamp);
|
||||
|
||||
/* parse DNS packet */
|
||||
regional_free_all(qstate->env->scratch);
|
||||
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
|
||||
sizeof(struct msg_parse));
|
||||
if(!prs)
|
||||
return 0; /* out of memory */
|
||||
memset(prs, 0, sizeof(*prs));
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
sldns_buffer_set_limit(buf, lim - sizeof(expiry)-sizeof(timestamp));
|
||||
if(parse_packet(buf, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
return 0;
|
||||
}
|
||||
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qstate->return_msg = dns_alloc_msg(buf, prs, qstate->region);
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
if(!qstate->return_msg)
|
||||
return 0;
|
||||
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
|
||||
/* see how much of the TTL expired, and remove it */
|
||||
if(*qstate->env->now <= (time_t)timestamp) {
|
||||
verbose(VERB_ALGO, "cachedb msg adjust by zero");
|
||||
return 1; /* message from the future (clock skew?) */
|
||||
}
|
||||
adjust = *qstate->env->now - (time_t)timestamp;
|
||||
if(qstate->return_msg->rep->ttl < adjust) {
|
||||
verbose(VERB_ALGO, "cachedb msg expired");
|
||||
/* If serve-expired is enabled, we still use an expired message
|
||||
* setting the TTL to 0. */
|
||||
if(qstate->env->cfg->serve_expired)
|
||||
adjust = -1;
|
||||
else
|
||||
return 0; /* message expired */
|
||||
}
|
||||
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
|
||||
adjust_msg_ttl(qstate->return_msg, adjust);
|
||||
|
||||
/* Similar to the unbound worker, if serve-expired is enabled and
|
||||
* the msg would be considered to be expired, mark the state so a
|
||||
* refetch will be scheduled. The comparison between 'expiry' and
|
||||
* 'now' should be redundant given how these values were calculated,
|
||||
* but we check it just in case as does good_expiry_and_qinfo(). */
|
||||
if(qstate->env->cfg->serve_expired &&
|
||||
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
|
||||
qstate->need_refetch = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the qstate.qinfo in extcache, store in qstate.return_msg.
|
||||
* return true if lookup was successful.
|
||||
*/
|
||||
static int
|
||||
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(qstate, key, sizeof(key));
|
||||
|
||||
/* call backend to fetch data for key into scratch buffer */
|
||||
if( !(*ie->backend->lookup)(qstate->env, ie, key,
|
||||
qstate->env->scratch_buffer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check expiry date and check if query-data matches */
|
||||
if( !good_expiry_and_qinfo(qstate, qstate->env->scratch_buffer) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse dns message into return_msg */
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer) ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the qstate.return_msg in extcache for key qstate.info
|
||||
*/
|
||||
static void
|
||||
cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(qstate, key, sizeof(key));
|
||||
|
||||
/* prepare data in scratch buffer */
|
||||
if(!prep_data(qstate, qstate->env->scratch_buffer))
|
||||
return;
|
||||
|
||||
/* call backend */
|
||||
(*ie->backend->store)(qstate->env, ie, key,
|
||||
sldns_buffer_begin(qstate->env->scratch_buffer),
|
||||
sldns_buffer_limit(qstate->env->scratch_buffer),
|
||||
qstate->return_msg->rep->ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if unbound's internal cache can answer the query
|
||||
*/
|
||||
static int
|
||||
cachedb_intcache_lookup(struct module_qstate* qstate)
|
||||
{
|
||||
struct dns_msg* msg;
|
||||
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch,
|
||||
1 /* no partial messages with only a CNAME */
|
||||
);
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer,
|
||||
*qstate->env->now, 1/*add SOA*/, NULL,
|
||||
qstate->env->cfg);
|
||||
}
|
||||
if(!msg)
|
||||
return 0;
|
||||
/* this is the returned msg */
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = msg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store query into the internal cache of unbound.
|
||||
*/
|
||||
static void
|
||||
cachedb_intcache_store(struct module_qstate* qstate)
|
||||
{
|
||||
uint32_t store_flags = qstate->query_flags;
|
||||
|
||||
if(qstate->env->cfg->serve_expired)
|
||||
store_flags |= DNSCACHE_STORE_ZEROTTL;
|
||||
if(!qstate->return_msg)
|
||||
return;
|
||||
(void)dns_cache_store(qstate->env, &qstate->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
|
||||
qstate->region, store_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a cachedb module event with a query
|
||||
* @param qstate: query state (from the mesh), passed between modules.
|
||||
* contains qstate->env module environment with global caches and so on.
|
||||
* @param iq: query state specific for this module. per-query.
|
||||
* @param ie: environment specific for this module. global.
|
||||
* @param id: module id.
|
||||
*/
|
||||
static void
|
||||
cachedb_handle_query(struct module_qstate* qstate,
|
||||
struct cachedb_qstate* ATTR_UNUSED(iq),
|
||||
struct cachedb_env* ie, int id)
|
||||
{
|
||||
/* check if we are enabled, and skip if so */
|
||||
if(!ie->enabled) {
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
if(qstate->blacklist || qstate->no_cache_lookup) {
|
||||
/* cache is blacklisted or we are instructed from edns to not look */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
log_dns_msg("cachedb internal cache lookup",
|
||||
&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
|
||||
:"??");
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ask backend cache to see if we have data */
|
||||
if(cachedb_extcache_lookup(qstate, ie)) {
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg(ie->backend->name,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* no cache fetches */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a cachedb module event with a response from the iterator.
|
||||
* @param qstate: query state (from the mesh), passed between modules.
|
||||
* contains qstate->env module environment with global caches and so on.
|
||||
* @param iq: query state specific for this module. per-query.
|
||||
* @param ie: environment specific for this module. global.
|
||||
* @param id: module id.
|
||||
*/
|
||||
static void
|
||||
cachedb_handle_response(struct module_qstate* qstate,
|
||||
struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
|
||||
{
|
||||
/* check if we are not enabled or instructed to not cache, and skip */
|
||||
if(!ie->enabled || qstate->no_cache_store) {
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the item into the backend cache */
|
||||
cachedb_extcache_store(qstate, ie);
|
||||
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
struct cachedb_env* ie = (struct cachedb_env*)qstate->env->modinfo[id];
|
||||
struct cachedb_qstate* iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
verbose(VERB_QUERY, "cachedb[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
||||
if(iq) log_query_info(VERB_QUERY, "cachedb operate: query",
|
||||
&qstate->qinfo);
|
||||
|
||||
/* perform cachedb state machine */
|
||||
if((event == module_event_new || event == module_event_pass) &&
|
||||
iq == NULL) {
|
||||
if(!cachedb_new(qstate, id)) {
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
}
|
||||
if(iq && (event == module_event_pass || event == module_event_new)) {
|
||||
cachedb_handle_query(qstate, iq, ie, id);
|
||||
return;
|
||||
}
|
||||
if(iq && (event == module_event_moddone)) {
|
||||
cachedb_handle_response(qstate, iq, ie, id);
|
||||
return;
|
||||
}
|
||||
if(iq && outbound) {
|
||||
/* cachedb does not need to process responses at this time
|
||||
* ignore it.
|
||||
cachedb_process_response(qstate, iq, ie, id, outbound, event);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if(event == module_event_error) {
|
||||
verbose(VERB_ALGO, "got called with event error, giving up");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
if(!iq && (event == module_event_moddone)) {
|
||||
/* during priming, module done but we never started */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
log_err("bad event for cachedb");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_inform_super(struct module_qstate* ATTR_UNUSED(qstate),
|
||||
int ATTR_UNUSED(id), struct module_qstate* ATTR_UNUSED(super))
|
||||
{
|
||||
/* cachedb does not use subordinate requests at this time */
|
||||
verbose(VERB_ALGO, "cachedb inform_super was called");
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_clear(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct cachedb_qstate* iq;
|
||||
if(!qstate)
|
||||
return;
|
||||
iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
if(iq) {
|
||||
/* free contents of iq */
|
||||
/* TODO */
|
||||
}
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
cachedb_get_mem(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* ie = (struct cachedb_env*)env->modinfo[id];
|
||||
if(!ie)
|
||||
return 0;
|
||||
return sizeof(*ie); /* TODO - more mem */
|
||||
}
|
||||
|
||||
/**
|
||||
* The cachedb function block
|
||||
*/
|
||||
static struct module_func_block cachedb_block = {
|
||||
"cachedb",
|
||||
&cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
cachedb_get_funcblock(void)
|
||||
{
|
||||
return &cachedb_block;
|
||||
}
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* cachedb/cachedb.h - cache from a database external to the program module
|
||||
*
|
||||
* Copyright (c) 2016, 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
|
||||
*
|
||||
* This file contains a module that uses an external database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
#include "util/module.h"
|
||||
struct cachedb_backend;
|
||||
|
||||
/**
|
||||
* The global variable environment contents for the cachedb
|
||||
* Shared between threads, this represents long term information.
|
||||
* Like database connections.
|
||||
*/
|
||||
struct cachedb_env {
|
||||
/** true is cachedb is enabled, the backend is turned on */
|
||||
int enabled;
|
||||
|
||||
/** the backend routines */
|
||||
struct cachedb_backend* backend;
|
||||
|
||||
/** backend specific data here */
|
||||
void* backend_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Per query state for the cachedb module.
|
||||
*/
|
||||
struct cachedb_qstate {
|
||||
int todo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backend call routines
|
||||
*/
|
||||
struct cachedb_backend {
|
||||
/** backend name */
|
||||
const char* name;
|
||||
|
||||
/** Init(env, cachedb_env): false on setup failure */
|
||||
int (*init)(struct module_env*, struct cachedb_env*);
|
||||
|
||||
/** Deinit - close db for program exit */
|
||||
void (*deinit)(struct module_env*, struct cachedb_env*);
|
||||
|
||||
/** Lookup (env, cachedb_env, key, result_buffer): true if found */
|
||||
int (*lookup)(struct module_env*, struct cachedb_env*, char*,
|
||||
struct sldns_buffer*);
|
||||
|
||||
/** Store (env, cachedb_env, key, data, data_len) */
|
||||
void (*store)(struct module_env*, struct cachedb_env*, char*,
|
||||
uint8_t*, size_t, time_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** Init the cachedb module */
|
||||
int cachedb_init(struct module_env* env, int id);
|
||||
/** Deinit the cachedb module */
|
||||
void cachedb_deinit(struct module_env* env, int id);
|
||||
/** Operate on an event on a query (in qstate). */
|
||||
void cachedb_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound);
|
||||
/** Subordinate query done, inform this super request of its conclusion */
|
||||
void cachedb_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
/** clear the cachedb query-specific contents out of qstate */
|
||||
void cachedb_clear(struct module_qstate* qstate, int id);
|
||||
/** return memory estimate for cachedb module */
|
||||
size_t cachedb_get_mem(struct module_env* env, int id);
|
||||
|
||||
/**
|
||||
* Get the function block with pointers to the cachedb functions
|
||||
* @return the function block for "cachedb".
|
||||
*/
|
||||
struct module_func_block* cachedb_get_funcblock(void);
|
||||
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* cachedb/redis.c - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/redis.h"
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#ifdef USE_REDIS
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
struct redis_moddata {
|
||||
redisContext** ctxs; /* thread-specific redis contexts */
|
||||
int numctxs; /* number of ctx entries */
|
||||
const char* server_host; /* server's IP address or host name */
|
||||
int server_port; /* server's TCP port */
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
redisContext* ctx;
|
||||
|
||||
ctx = redisConnectWithTimeout(moddata->server_host,
|
||||
moddata->server_port, moddata->timeout);
|
||||
if(!ctx || ctx->err) {
|
||||
const char *errstr = "out of memory";
|
||||
if(ctx)
|
||||
errstr = ctx->errstr;
|
||||
log_err("failed to connect to redis server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
if(ctx)
|
||||
redisFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
int i;
|
||||
struct redis_moddata* moddata = NULL;
|
||||
|
||||
verbose(VERB_ALGO, "redis_init");
|
||||
|
||||
moddata = calloc(1, sizeof(struct redis_moddata));
|
||||
if(!moddata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
moddata->numctxs = env->cfg->num_threads;
|
||||
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
|
||||
if(!moddata->ctxs) {
|
||||
log_err("out of memory");
|
||||
free(moddata);
|
||||
return 0;
|
||||
}
|
||||
/* note: server_host is a shallow reference to configured string.
|
||||
* we don't have to free it in this module. */
|
||||
moddata->server_host = env->cfg->redis_server_host;
|
||||
moddata->server_port = env->cfg->redis_server_port;
|
||||
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
|
||||
for(i = 0; i < moddata->numctxs; i++)
|
||||
moddata->ctxs[i] = redis_connect(moddata);
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct redis_moddata* moddata = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
|
||||
verbose(VERB_ALGO, "redis_deinit");
|
||||
|
||||
if(!moddata)
|
||||
return;
|
||||
if(moddata->ctxs) {
|
||||
int i;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
if(moddata->ctxs[i])
|
||||
redisFree(moddata->ctxs[i]);
|
||||
}
|
||||
free(moddata->ctxs);
|
||||
}
|
||||
free(moddata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a redis command and get a reply. Unified so that it can be used for
|
||||
* both SET and GET. If 'data' is non-NULL the command is supposed to be
|
||||
* SET and GET otherwise, but the implementation of this function is agnostic
|
||||
* about the semantics (except for logging): 'command', 'data', and 'data_len'
|
||||
* are opaquely passed to redisCommand().
|
||||
* This function first checks whether a connection with a redis server has
|
||||
* been established; if not it tries to set up a new one.
|
||||
* It returns redisReply returned from redisCommand() or NULL if some low
|
||||
* level error happens. The caller is responsible to check the return value,
|
||||
* if it's non-NULL, it has to free it with freeReplyObject().
|
||||
*/
|
||||
static redisReply*
|
||||
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
const char* command, const uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisContext* ctx;
|
||||
redisReply* rep;
|
||||
struct redis_moddata* d = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
|
||||
/* We assume env->alloc->thread_num is a unique ID for each thread
|
||||
* in [0, num-of-threads). We could treat it as an error condition
|
||||
* if the assumption didn't hold, but it seems to be a fundamental
|
||||
* assumption throughout the unbound architecture, so we simply assert
|
||||
* it. */
|
||||
log_assert(env->alloc->thread_num < d->numctxs);
|
||||
ctx = d->ctxs[env->alloc->thread_num];
|
||||
|
||||
/* If we've not established a connection to the server or we've closed
|
||||
* it on a failure, try to re-establish a new one. Failures will be
|
||||
* logged in redis_connect(). */
|
||||
if(!ctx) {
|
||||
ctx = redis_connect(d);
|
||||
d->ctxs[env->alloc->thread_num] = ctx;
|
||||
}
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
/* Send the command and get a reply, synchronously. */
|
||||
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
|
||||
if(!rep) {
|
||||
/* Once an error as a NULL-reply is returned the context cannot
|
||||
* be reused and we'll need to set up a new connection. */
|
||||
log_err("redis_command: failed to receive a reply, "
|
||||
"closing connection: %s", ctx->errstr);
|
||||
redisFree(ctx);
|
||||
d->ctxs[env->alloc->thread_num] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check error in reply to unify logging in that case.
|
||||
* The caller may perform context-dependent checks and logging. */
|
||||
if(rep->type == REDIS_REPLY_ERROR)
|
||||
log_err("redis: %s resulted in an error: %s",
|
||||
data ? "set" : "get", rep->str);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
verbose(VERB_ALGO, "redis_lookup of %s", key);
|
||||
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_lookup: unexpected failure to build command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch(rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
verbose(VERB_ALGO, "redis_lookup found %d bytes",
|
||||
(int)rep->len);
|
||||
if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
|
||||
log_err("redis_lookup: replied data too long: %lu",
|
||||
(size_t)rep->len);
|
||||
break;
|
||||
}
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, rep->str, rep->len);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
ret = 1;
|
||||
break;
|
||||
case REDIS_REPLY_ERROR:
|
||||
break; /* already logged */
|
||||
default:
|
||||
log_err("redis_lookup: unexpected type of reply for (%d)",
|
||||
rep->type);
|
||||
break;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len, time_t ttl)
|
||||
{
|
||||
redisReply* rep;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_store: unexpected failure to build command");
|
||||
return;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
|
||||
if(rep) {
|
||||
verbose(VERB_ALGO, "redis_store set completed");
|
||||
if(rep->type != REDIS_REPLY_STATUS &&
|
||||
rep->type != REDIS_REPLY_ERROR) {
|
||||
log_err("redis_store: unexpected type of reply (%d)",
|
||||
rep->type);
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
}
|
||||
|
||||
struct cachedb_backend redis_backend = { "redis",
|
||||
redis_init, redis_deinit, redis_lookup, redis_store
|
||||
};
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* cachedb/redis.h - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
/** the redis backend definition, contains callable functions
|
||||
* and name string */
|
||||
extern struct cachedb_backend redis_backend;
|
||||
+16
-1
@@ -33,6 +33,9 @@
|
||||
*/
|
||||
#include "config.h"
|
||||
#define LOCKRET(func) func
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
|
||||
void _ARC4_LOCK(void);
|
||||
@@ -46,9 +49,13 @@ void _ARC4_LOCK(void)
|
||||
void _ARC4_UNLOCK(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
}
|
||||
#else /* !THREADS_DISABLED */
|
||||
|
||||
static lock_quick_t arc4lock;
|
||||
static lock_quick_type arc4lock;
|
||||
static int arc4lockinit = 0;
|
||||
|
||||
void _ARC4_LOCK(void)
|
||||
@@ -64,4 +71,12 @@ void _ARC4_UNLOCK(void)
|
||||
{
|
||||
lock_quick_unlock(&arc4lock);
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
if(arc4lockinit) {
|
||||
arc4lockinit = 0;
|
||||
lock_quick_destroy(&arc4lock);
|
||||
}
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
+75
-2
@@ -48,6 +48,9 @@
|
||||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define KEYSZ 32
|
||||
#define IVSZ 8
|
||||
@@ -68,9 +71,76 @@ static struct {
|
||||
|
||||
static inline void _rs_rekey(u_char *dat, size_t datlen);
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
fallback_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;
|
||||
}
|
||||
|
||||
/* fallback for getentropy in case libc returns failure */
|
||||
static int
|
||||
fallback_getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
# ifdef HAVE_FCNTL
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
#endif
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (fallback_gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
assert(buf);
|
||||
if (n < KEYSZ + IVSZ)
|
||||
return;
|
||||
|
||||
@@ -111,11 +181,14 @@ _rs_stir(void)
|
||||
u_char rnd[KEYSZ + IVSZ];
|
||||
|
||||
if (getentropy(rnd, sizeof rnd) == -1) {
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
raise(SIGKILL);
|
||||
raise(SIGKILL);
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!rs)
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "util/locks.h"
|
||||
|
||||
/** the lock for ctime buffer */
|
||||
static lock_basic_t ctime_lock;
|
||||
static lock_basic_type ctime_lock;
|
||||
/** has it been inited */
|
||||
static int ctime_r_init = 0;
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_ATTR_WEAK
|
||||
__attribute__((weak)) void
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
__explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+66
-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,20 +50,25 @@
|
||||
#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
|
||||
#include <sys/vfs.h>
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define REPEAT 5
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
@@ -72,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);
|
||||
#ifdef SYS_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);
|
||||
@@ -102,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)
|
||||
@@ -110,18 +104,21 @@ getentropy(void *buf, size_t len)
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef SYS_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
|
||||
|
||||
/*
|
||||
@@ -175,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
|
||||
@@ -193,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;
|
||||
}
|
||||
|
||||
#ifdef SYS_getrandom
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
@@ -218,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)
|
||||
@@ -266,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)
|
||||
@@ -277,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
|
||||
@@ -308,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,
|
||||
@@ -343,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)
|
||||
{
|
||||
@@ -354,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;
|
||||
@@ -371,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) {
|
||||
@@ -379,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);
|
||||
|
||||
@@ -398,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;
|
||||
@@ -525,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),
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* strsep implementation for compatibility.
|
||||
*
|
||||
* LICENSE
|
||||
* Copyright (c) 2016, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 NLnetLabs 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 OWNER 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.
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/** see if character is in the delimiter array */
|
||||
static int
|
||||
in_delim(char c, const char* delim)
|
||||
{
|
||||
const char* p;
|
||||
if(!delim)
|
||||
return 0;
|
||||
for(p=delim; *p; p++) {
|
||||
if(*p == c)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *strsep(char **stringp, const char *delim)
|
||||
{
|
||||
char* s;
|
||||
char* orig;
|
||||
if(stringp == NULL || *stringp == NULL)
|
||||
return NULL;
|
||||
orig = *stringp;
|
||||
s = *stringp;
|
||||
while(*s && !in_delim(*s, delim))
|
||||
s++;
|
||||
if(*s) {
|
||||
*s = 0;
|
||||
*stringp = s+1;
|
||||
} else {
|
||||
*stringp = NULL;
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
Vendored
+533
-424
File diff suppressed because it is too large
Load Diff
+289
-10
@@ -1,11 +1,23 @@
|
||||
/* 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
|
||||
|
||||
/* Define this to enable client subnet option. */
|
||||
#undef CLIENT_SUBNET
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -16,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
|
||||
|
||||
@@ -27,6 +42,9 @@
|
||||
internal symbols */
|
||||
#undef EXPORT_ALL_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#undef HAVE_ACCEPT4
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
@@ -39,15 +57,36 @@
|
||||
/* 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
|
||||
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -62,6 +101,26 @@
|
||||
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
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED448
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
@@ -74,6 +133,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REDISCONNECT
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
@@ -101,15 +164,33 @@
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `DSA_SIG_set0' function. */
|
||||
#undef HAVE_DSA_SIG_SET0
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#undef HAVE_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the `endprotoent' function. */
|
||||
#undef HAVE_ENDPROTOENT
|
||||
|
||||
/* Define to 1 if you have the `endpwent' function. */
|
||||
#undef HAVE_ENDPWENT
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -125,6 +206,24 @@
|
||||
/* 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
|
||||
|
||||
/* Define to 1 if you have the `EVP_DigestVerify' function. */
|
||||
#undef HAVE_EVP_DIGESTVERIFY
|
||||
|
||||
/* Define to 1 if you have the `EVP_dss1' function. */
|
||||
#undef HAVE_EVP_DSS1
|
||||
|
||||
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
|
||||
#undef HAVE_EVP_MD_CTX_NEW
|
||||
|
||||
/* Define to 1 if you have the `EVP_sha1' function. */
|
||||
#undef HAVE_EVP_SHA1
|
||||
|
||||
@@ -143,6 +242,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
|
||||
|
||||
@@ -188,8 +290,17 @@
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* If you have HMAC_CTX_init */
|
||||
#undef HAVE_HMAC_CTX_INIT
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* Define to 1 if you have the `HMAC_Init_ex' function. */
|
||||
#undef HAVE_HMAC_INIT_EX
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
/* If we have htobe64 */
|
||||
#undef HAVE_HTOBE64
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
@@ -218,6 +329,12 @@
|
||||
/* 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
|
||||
|
||||
/* Define if we have LibreSSL */
|
||||
#undef HAVE_LIBRESSL
|
||||
|
||||
@@ -248,24 +365,54 @@
|
||||
/* Use libnettle for crypto */
|
||||
#undef HAVE_NETTLE
|
||||
|
||||
/* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
|
||||
#undef HAVE_NETTLE_DSA_COMPAT_H
|
||||
|
||||
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
|
||||
#undef HAVE_NETTLE_EDDSA_H
|
||||
|
||||
/* Use libnss for crypto */
|
||||
#undef HAVE_NSS
|
||||
|
||||
/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
|
||||
#undef HAVE_OPENSSL_ADD_ALL_DIGESTS
|
||||
|
||||
/* Define to 1 if you have the <openssl/bn.h> header file. */
|
||||
#undef HAVE_OPENSSL_BN_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_config' function. */
|
||||
#undef HAVE_OPENSSL_CONFIG
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define to 1 if you have the <openssl/dsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_DSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
|
||||
#undef HAVE_OPENSSL_INIT_CRYPTO
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
|
||||
#undef HAVE_OPENSSL_INIT_SSL
|
||||
|
||||
/* Define to 1 if you have the <openssl/rand.h> header file. */
|
||||
#undef HAVE_OPENSSL_RAND_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
@@ -290,15 +437,15 @@
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define to 1 if you have the `reallocarray' function. */
|
||||
/* Define to 1 if you have the `RAND_cleanup' function. */
|
||||
#undef HAVE_RAND_CLEANUP
|
||||
|
||||
/* If we have reallocarray(3) */
|
||||
#undef HAVE_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the `recvmsg' function. */
|
||||
#undef HAVE_RECVMSG
|
||||
|
||||
/* define if you have the sbrk() call */
|
||||
#undef HAVE_SBRK
|
||||
|
||||
/* Define to 1 if you have the `sendmsg' function. */
|
||||
#undef HAVE_SENDMSG
|
||||
|
||||
@@ -326,6 +473,9 @@
|
||||
/* Define to 1 if you have the `SHA512_Update' function. */
|
||||
#undef HAVE_SHA512_UPDATE
|
||||
|
||||
/* Define to 1 if you have the `shmget' function. */
|
||||
#undef HAVE_SHMGET
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
@@ -347,6 +497,22 @@
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
|
||||
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_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
|
||||
|
||||
/* Define to 1 if you have the `SSL_set1_host' function. */
|
||||
#undef HAVE_SSL_SET1_HOST
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
@@ -377,6 +543,9 @@
|
||||
/* Define to 1 if you have the `strptime' function. */
|
||||
#undef HAVE_STRPTIME
|
||||
|
||||
/* Define to 1 if you have the `strsep' function. */
|
||||
#undef HAVE_STRSEP
|
||||
|
||||
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
|
||||
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
|
||||
|
||||
@@ -389,6 +558,15 @@
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if systemd should be used */
|
||||
#undef HAVE_SYSTEMD
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#undef HAVE_SYS_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
@@ -398,6 +576,9 @@
|
||||
/* Define to 1 if you have the <sys/sha2.h> header file. */
|
||||
#undef HAVE_SYS_SHA2_H
|
||||
|
||||
/* Define to 1 if you have the <sys/shm.h> header file. */
|
||||
#undef HAVE_SYS_SHM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
@@ -419,6 +600,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
|
||||
|
||||
@@ -458,9 +642,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
|
||||
|
||||
@@ -535,6 +725,9 @@
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* if REUSEPORT is enabled by default */
|
||||
#undef REUSEPORT_DEFAULT
|
||||
|
||||
/* default rootkey location */
|
||||
#undef ROOT_ANCHOR_FILE
|
||||
|
||||
@@ -550,12 +743,18 @@
|
||||
/* 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
|
||||
|
||||
/* define if (v)snprintf does not return length needed, (but length used) */
|
||||
#undef SNPRINTF_RET_BROKEN
|
||||
|
||||
/* Define to 1 if libsodium supports sodium_set_misuse_handler */
|
||||
#undef SODIUM_MISUSE_HANDLER
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
@@ -565,6 +764,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
|
||||
|
||||
@@ -580,21 +782,60 @@
|
||||
/* define this to enable debug checks. */
|
||||
#undef UNBOUND_DEBUG
|
||||
|
||||
/* Define to 1 to use cachedb support */
|
||||
#undef USE_CACHEDB
|
||||
|
||||
/* Define to 1 to enable dnscrypt support */
|
||||
#undef USE_DNSCRYPT
|
||||
|
||||
/* Define to 1 to enable dnscrypt with xchacha20 support */
|
||||
#undef USE_DNSCRYPT_XCHACHA20
|
||||
|
||||
/* Define to 1 to enable dnstap support */
|
||||
#undef USE_DNSTAP
|
||||
|
||||
/* Define this to enable DSA support. */
|
||||
#undef USE_DSA
|
||||
|
||||
/* Define this to enable ECDSA support. */
|
||||
#undef USE_ECDSA
|
||||
|
||||
/* Define this to enable an EVP workaround for older openssl */
|
||||
#undef USE_ECDSA_EVP_WORKAROUND
|
||||
|
||||
/* Define this to enable ED25519 support. */
|
||||
#undef USE_ED25519
|
||||
|
||||
/* Define this to enable ED448 support. */
|
||||
#undef USE_ED448
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#undef USE_GOST
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_MSG_FASTOPEN
|
||||
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
/* Define this to use hiredis client. */
|
||||
#undef USE_REDIS
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#undef USE_SHA1
|
||||
|
||||
/* Define this to enable SHA256 and SHA512 support. */
|
||||
#undef USE_SHA2
|
||||
|
||||
@@ -620,12 +861,18 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define this to enable server TCP Fast Open. */
|
||||
#undef USE_TCP_FASTOPEN
|
||||
|
||||
/* Whether the windows socket API is used */
|
||||
#undef USE_WINSOCK
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -774,8 +1021,14 @@
|
||||
|
||||
|
||||
|
||||
#ifndef _OPENBSD_SOURCE
|
||||
#define _OPENBSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#ifndef UNBOUND_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** Use small-ldns codebase */
|
||||
@@ -979,17 +1232,44 @@ int memcmp(const void *x, const void *y, size_t n);
|
||||
char *ctime_r(const time_t *timep, char *buf);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRSEP
|
||||
#define strsep unbound_strsep
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ISBLANK
|
||||
#define isblank unbound_isblank
|
||||
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
|
||||
|
||||
#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
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);
|
||||
@@ -1003,17 +1283,14 @@ 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);
|
||||
void _ARC4_LOCK(void);
|
||||
void _ARC4_UNLOCK(void);
|
||||
void _ARC4_LOCK_DESTROY(void);
|
||||
#endif
|
||||
#ifndef HAVE_ARC4RANDOM_UNIFORM
|
||||
uint32_t arc4random_uniform(uint32_t upper_bound);
|
||||
@@ -1079,6 +1356,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
Vendored
+1375
-1373
File diff suppressed because it is too large
Load Diff
+751
-78
File diff suppressed because it is too large
Load Diff
+25
-1
@@ -27,5 +27,29 @@ 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.
|
||||
* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
|
||||
* 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.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Index: trunk/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- trunk/doc/unbound.conf.5.in (revision 3587)
|
||||
--- trunk/doc/unbound.conf.5.in (revision 4357)
|
||||
+++ trunk/doc/unbound.conf.5.in (working copy)
|
||||
@@ -593,6 +593,13 @@
|
||||
possible. Best effort approach, full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR. Default is off.
|
||||
@@ -701,6 +701,13 @@
|
||||
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.
|
||||
.TP
|
||||
+.B aaaa\-filter: \fI<yes or no>
|
||||
+Activate behavior similar to BIND's AAAA-filter.
|
||||
@@ -13,12 +13,12 @@ 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
|
||||
.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.
|
||||
Index: trunk/iterator/iter_scrub.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_scrub.c (revision 3587)
|
||||
--- trunk/iterator/iter_scrub.c (revision 4357)
|
||||
+++ trunk/iterator/iter_scrub.c (working copy)
|
||||
@@ -617,6 +617,32 @@
|
||||
}
|
||||
@@ -75,10 +75,11 @@ 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
|
||||
@@ -681,6 +715,24 @@
|
||||
@@ -680,6 +714,24 @@
|
||||
prev = NULL;
|
||||
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
|
||||
@@ -96,13 +97,12 @@ 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 ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
Index: trunk/iterator/iter_utils.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_utils.c (revision 3587)
|
||||
--- trunk/iterator/iter_utils.c (revision 4357)
|
||||
+++ trunk/iterator/iter_utils.c (working copy)
|
||||
@@ -175,6 +175,7 @@
|
||||
}
|
||||
@@ -114,9 +114,9 @@ Index: trunk/iterator/iter_utils.c
|
||||
|
||||
Index: trunk/iterator/iterator.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.c (revision 3587)
|
||||
--- trunk/iterator/iterator.c (revision 4357)
|
||||
+++ trunk/iterator/iterator.c (working copy)
|
||||
@@ -1776,6 +1776,53 @@
|
||||
@@ -1847,6 +1847,53 @@
|
||||
|
||||
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
|
||||
@@ -1823,6 +1870,13 @@
|
||||
@@ -1894,6 +1941,13 @@
|
||||
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) {
|
||||
@@ -2922,6 +2976,61 @@
|
||||
@@ -3095,6 +3149,61 @@
|
||||
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.
|
||||
@@ -244,9 +244,9 @@ Index: trunk/iterator/iterator.c
|
||||
+/* ASN: End of added code */
|
||||
+
|
||||
/*
|
||||
* Return priming query results to interestes super querystates.
|
||||
* Return priming query results to interested super querystates.
|
||||
*
|
||||
@@ -2941,6 +3050,9 @@
|
||||
@@ -3114,6 +3223,9 @@
|
||||
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)
|
||||
@@ -2978,6 +3090,9 @@
|
||||
@@ -3151,6 +3263,9 @@
|
||||
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;
|
||||
@@ -3270,6 +3385,8 @@
|
||||
@@ -3460,6 +3575,8 @@
|
||||
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 :
|
||||
@@ -3294,6 +3411,7 @@
|
||||
@@ -3484,6 +3601,7 @@
|
||||
case INIT_REQUEST_STATE :
|
||||
case INIT_REQUEST_2_STATE :
|
||||
case INIT_REQUEST_3_STATE :
|
||||
@@ -285,19 +285,19 @@ Index: trunk/iterator/iterator.c
|
||||
return 0;
|
||||
Index: trunk/iterator/iterator.h
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.h (revision 3587)
|
||||
--- trunk/iterator/iterator.h (revision 4357)
|
||||
+++ trunk/iterator/iterator.h (working copy)
|
||||
@@ -113,6 +113,9 @@
|
||||
@@ -130,6 +130,9 @@
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
|
||||
+ /** ASN: AAAA-filter flag */
|
||||
+ int aaaa_filter;
|
||||
+
|
||||
/** ip6.arpa dname in wireformat, used for qname-minimisation */
|
||||
uint8_t* ip6arpa_dname;
|
||||
};
|
||||
@@ -163,6 +166,14 @@
|
||||
/** lock on ratelimit counter */
|
||||
lock_basic_type queries_ratelimit_lock;
|
||||
/** number of queries that have been ratelimited */
|
||||
@@ -182,6 +185,14 @@
|
||||
INIT_REQUEST_3_STATE,
|
||||
|
||||
/**
|
||||
@@ -311,26 +311,26 @@ Index: trunk/iterator/iterator.h
|
||||
+ /**
|
||||
* 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 reponsible for iterating through a list of
|
||||
@@ -346,6 +357,13 @@
|
||||
* 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.
|
||||
*/
|
||||
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 3587)
|
||||
--- trunk/pythonmod/interface.i (revision 4357)
|
||||
+++ trunk/pythonmod/interface.i (working copy)
|
||||
@@ -632,6 +632,7 @@
|
||||
@@ -851,6 +851,7 @@
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
@@ -340,9 +340,9 @@ Index: trunk/pythonmod/interface.i
|
||||
size_t unwanted_threshold;
|
||||
Index: trunk/util/config_file.c
|
||||
===================================================================
|
||||
--- trunk/util/config_file.c (revision 3587)
|
||||
--- trunk/util/config_file.c (revision 4357)
|
||||
+++ trunk/util/config_file.c (working copy)
|
||||
@@ -176,6 +176,7 @@
|
||||
@@ -195,6 +195,7 @@
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->harden_algo_downgrade = 0;
|
||||
cfg->use_caps_bits_for_id = 0;
|
||||
@@ -352,9 +352,9 @@ Index: trunk/util/config_file.c
|
||||
cfg->private_domain = NULL;
|
||||
Index: trunk/util/config_file.h
|
||||
===================================================================
|
||||
--- trunk/util/config_file.h (revision 3587)
|
||||
--- trunk/util/config_file.h (revision 4357)
|
||||
+++ trunk/util/config_file.h (working copy)
|
||||
@@ -179,6 +179,8 @@
|
||||
@@ -209,6 +209,8 @@
|
||||
int harden_algo_downgrade;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
@@ -365,9 +365,9 @@ Index: trunk/util/config_file.h
|
||||
/** strip away these private addrs from answers, no DNS Rebinding */
|
||||
Index: trunk/util/configlexer.lex
|
||||
===================================================================
|
||||
--- trunk/util/configlexer.lex (revision 3587)
|
||||
--- trunk/util/configlexer.lex (revision 4357)
|
||||
+++ trunk/util/configlexer.lex (working copy)
|
||||
@@ -267,6 +267,7 @@
|
||||
@@ -279,6 +279,7 @@
|
||||
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) }
|
||||
@@ -377,9 +377,9 @@ Index: trunk/util/configlexer.lex
|
||||
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
|
||||
Index: trunk/util/configparser.y
|
||||
===================================================================
|
||||
--- trunk/util/configparser.y (revision 3587)
|
||||
--- trunk/util/configparser.y (revision 4357)
|
||||
+++ trunk/util/configparser.y (working copy)
|
||||
@@ -92,6 +92,7 @@
|
||||
@@ -95,6 +95,7 @@
|
||||
%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
|
||||
@@ -169,6 +170,7 @@
|
||||
@@ -203,6 +204,7 @@
|
||||
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,10 +395,12 @@ 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 |
|
||||
@@ -893,6 +895,15 @@
|
||||
@@ -1183,6 +1185,15 @@
|
||||
OUTYY(("P(server_caps_whitelist:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
+ }
|
||||
+ ;
|
||||
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
|
||||
@@ -406,8 +408,6 @@ 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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -0,0 +1,13 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
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}
|
||||
@@ -0,0 +1,42 @@
|
||||
# See ltrace.conf(5) for description of syntax of this file.
|
||||
typedef ub_type = enum(TYPE_A=1,TYPE_NS=2,TYPE_SOA=6,TYPE_MX=15,TYPE_TXT=16,TYPE_AAAA=28,TYPE_DS=43,TYPE_DNSKEY=48,TYPE_TLSA=52,TYPE_ANY=255);
|
||||
typedef ub_class = enum(CLASS_IN=1,CLASS_CH=3,CLASS_NONE=254,CLASS_ANY=255);
|
||||
typedef ub_rcode = enum(RCODE_NOERROR,RCODE_FORMERR,RCODE_SERVFAIL,RCODE_NXDOMAIN,RCODE_NOTIMPL,RCODE_REFUSED,RCODE_YXDOMAIN,RCODE_YXRRSET,RCODE_NXRRSET,RCODE_NOTAUTH,RCODE_NOTZONE);
|
||||
typedef ub_havedata = enum(no_data, have_data);
|
||||
typedef ub_nxdomain = enum(name_exists, nxdomain);
|
||||
typedef ub_secure = enum(not_secure, secure);
|
||||
typedef ub_bogus = enum(not_bogus, bogus);
|
||||
typedef ub_result = struct(string, ub_type, ub_class, array(void*,zero)*, array(int,zero)*, string, ub_rcode, void*, int, ub_havedata, ub_nxdomain, ub_secure, ub_bogus, string, int);
|
||||
typedef ub_ctx = void;
|
||||
ub_ctx* ub_ctx_create(void);
|
||||
void ub_ctx_delete(ub_ctx*);
|
||||
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);
|
||||
int ub_ctx_add_ta(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_file(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_autr(ub_ctx*, string);
|
||||
int ub_ctx_trustedkeys(ub_ctx*, string);
|
||||
int ub_ctx_debugout(ub_ctx*, void*);
|
||||
int ub_ctx_debuglevel(ub_ctx*, int);
|
||||
int ub_ctx_async(ub_ctx*, bool(int));
|
||||
int ub_poll(ub_ctx*);
|
||||
int ub_wait(ub_ctx*);
|
||||
int ub_fd(ub_ctx*);
|
||||
int ub_process(ub_ctx*);
|
||||
int ub_resolve(ub_ctx*, string, ub_type, ub_class, +ub_result**);
|
||||
int ub_resolve_async(ub_ctx*, string, ub_type, ub_class, void*, void*, +int*);
|
||||
int ub_cancel(ub_ctx*, int);
|
||||
void ub_resolve_free(ub_result*);
|
||||
string ub_strerror(int);
|
||||
int ub_ctx_print_local_zones(ub_ctx*);
|
||||
int ub_ctx_zone_add(ub_ctx*, string, string);
|
||||
int ub_ctx_zone_remove(ub_ctx*, string);
|
||||
int ub_ctx_data_add(ub_ctx*, string);
|
||||
int ub_ctx_data_remove(ub_ctx*, string);
|
||||
string ub_version(void);
|
||||
@@ -91,7 +91,7 @@ while ( scalar keys %startstats < $numthreads || scalar keys %donestats < $numth
|
||||
$allstats{$inthread}->{outstandingexc} = $4;
|
||||
}
|
||||
elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) {
|
||||
$allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec.
|
||||
$allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to millisec.
|
||||
}
|
||||
elsif ( $line =~ m/info: histogram of recursion processing times/ ) {
|
||||
next;
|
||||
@@ -103,7 +103,7 @@ while ( scalar keys %startstats < $numthreads || scalar keys %donestats < $numth
|
||||
}
|
||||
elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) {
|
||||
# since after this line we're unsure if we get these numbers
|
||||
# at all, we sould consider this marker as the end of the
|
||||
# at all, we should consider this marker as the end of the
|
||||
# block. Chances that we're parsing a file halfway written
|
||||
# at this stage are small. Bold statement.
|
||||
$donestats{$inthread} = 1;
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
Index: daemon/worker.c
|
||||
===================================================================
|
||||
--- daemon/worker.c (revision 4191)
|
||||
+++ daemon/worker.c (working copy)
|
||||
@@ -663,8 +663,21 @@
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
goto bail_out;
|
||||
- error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
- qinfo, id, flags, edns);
|
||||
+ if (qinfo->qtype == LDNS_RR_TYPE_A &&
|
||||
+ worker->env.cfg->redirect_bogus_ipv4) {
|
||||
+ /* BAD cached */
|
||||
+ fixed_address_encode(repinfo->c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
|
||||
+ worker->env.cfg->redirect_bogus_ipv4);
|
||||
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA &&
|
||||
+ worker->env.cfg->redirect_bogus_ipv6) {
|
||||
+ fixed_address_encode(repinfo->c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
|
||||
+ worker->env.cfg->redirect_bogus_ipv6);
|
||||
+ } else {
|
||||
+ error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
+ qinfo, id, flags, edns);
|
||||
+ }
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
Index: doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- doc/unbound.conf.5.in (revision 4191)
|
||||
+++ doc/unbound.conf.5.in (working copy)
|
||||
@@ -1244,6 +1244,18 @@
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
+.TP 5
|
||||
+.B redirect-bogus-ipv4: \fI<IPv4 address>
|
||||
+Set a fixed address for DNSSEC failures that are cached
|
||||
+Instead of responding to A queries with SERVFAIL, respond
|
||||
+with NOERROR and the address specified here
|
||||
+The TTL of the response will be 5 seconds
|
||||
+.TP 5
|
||||
+.B redirect-bogus-ipv6: \fI<IPv4 address>
|
||||
+Set a fixed address for DNSSEC failures that are cached
|
||||
+Instead of responding to AAAA queries with SERVFAIL, respond
|
||||
+with NOERROR and the address specified here
|
||||
+The TTL of the response will be 5 seconds
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
Index: services/mesh.c
|
||||
===================================================================
|
||||
--- services/mesh.c (revision 4191)
|
||||
+++ services/mesh.c (working copy)
|
||||
@@ -1006,6 +1006,7 @@
|
||||
struct timeval end_time;
|
||||
struct timeval duration;
|
||||
int secure;
|
||||
+ int bogus_override = 0;
|
||||
/* Copy the client's EDNS for later restore, to make sure the edns
|
||||
* compare is with the correct edns options. */
|
||||
struct edns_data edns_bak = r->edns;
|
||||
@@ -1016,6 +1017,7 @@
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
+ bogus_override = 1;
|
||||
}
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
secure = 1;
|
||||
@@ -1047,17 +1049,34 @@
|
||||
} else if(rcode) {
|
||||
m->s.qinfo.qname = r->qname;
|
||||
m->s.qinfo.local_alias = r->local_alias;
|
||||
- if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
- if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
- rep, rcode, &r->edns, m->s.region))
|
||||
- r->edns.opt_list = NULL;
|
||||
- } else {
|
||||
- if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
||||
- &r->edns, m->s.region))
|
||||
- r->edns.opt_list = NULL;
|
||||
+ if(bogus_override && m->s.qinfo.qtype == LDNS_RR_TYPE_A &&
|
||||
+ m->s.env->cfg->redirect_bogus_ipv4) {
|
||||
+ fixed_address_encode(r->query_reply.c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
|
||||
+ r->qflags, &r->edns,
|
||||
+ m->s.env->cfg->redirect_bogus_ipv4);
|
||||
+ } else if(bogus_override &&
|
||||
+ m->s.qinfo.qtype == LDNS_RR_TYPE_AAAA &&
|
||||
+ m->s.env->cfg->redirect_bogus_ipv6) {
|
||||
+ fixed_address_encode(r->query_reply.c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
|
||||
+ r->qflags, &r->edns,
|
||||
+ m->s.env->cfg->redirect_bogus_ipv6);
|
||||
+ } else {
|
||||
+ if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
+ if(!inplace_cb_reply_servfail_call(m->s.env,
|
||||
+ &m->s.qinfo, &m->s,
|
||||
+ rep, rcode, &r->edns, m->s.region))
|
||||
+ r->edns.opt_list = NULL;
|
||||
+ } else {
|
||||
+ if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo,
|
||||
+ &m->s, rep, rcode, &r->edns,
|
||||
+ m->s.region))
|
||||
+ r->edns.opt_list = NULL;
|
||||
+ }
|
||||
+ error_encode(r->query_reply.c->buffer, rcode,
|
||||
+ &m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||
}
|
||||
- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
|
||||
- r->qid, r->qflags, &r->edns);
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
Index: util/config_file.c
|
||||
===================================================================
|
||||
--- util/config_file.c (revision 4191)
|
||||
+++ util/config_file.c (working copy)
|
||||
@@ -273,6 +273,8 @@
|
||||
cfg->ratelimit_factor = 10;
|
||||
cfg->qname_minimisation = 0;
|
||||
cfg->qname_minimisation_strict = 0;
|
||||
+ cfg->redirect_bogus_ipv4 = NULL;
|
||||
+ cfg->redirect_bogus_ipv6 = NULL;
|
||||
cfg->shm_enable = 0;
|
||||
cfg->shm_key = 11777;
|
||||
cfg->dnscrypt = 0;
|
||||
@@ -602,6 +604,10 @@
|
||||
}
|
||||
oi[cfg->num_out_ifs++] = d;
|
||||
cfg->out_ifs = oi;
|
||||
+ } else if (strcmp(opt, "redirect-bogus-ipv4:") == 0) {
|
||||
+ cfg->redirect_bogus_ipv4 = strdup(val);
|
||||
+ } else if (strcmp(opt, "redirect-bogus-ipv6:") == 0) {
|
||||
+ cfg->redirect_bogus_ipv6 = strdup(val);
|
||||
} else {
|
||||
/* unknown or unsupported (from the set_option interface):
|
||||
* interface, outgoing-interface, access-control,
|
||||
@@ -1250,6 +1256,12 @@
|
||||
free(cfg->dnstap_version);
|
||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
+ if (cfg->redirect_bogus_ipv4) {
|
||||
+ free(cfg->redirect_bogus_ipv4);
|
||||
+ }
|
||||
+ if (cfg->redirect_bogus_ipv6) {
|
||||
+ free(cfg->redirect_bogus_ipv6);
|
||||
+ }
|
||||
#ifdef USE_IPSECMOD
|
||||
free(cfg->ipsecmod_hook);
|
||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||
Index: util/config_file.h
|
||||
===================================================================
|
||||
--- util/config_file.h (revision 4191)
|
||||
+++ util/config_file.h (working copy)
|
||||
@@ -444,6 +444,9 @@
|
||||
/** minimise QNAME in strict mode, minimise according to RFC.
|
||||
* Do not apply fallback */
|
||||
int qname_minimisation_strict;
|
||||
+ /** construct fake responses for DNSSEC failures */
|
||||
+ char *redirect_bogus_ipv4;
|
||||
+ char *redirect_bogus_ipv6;
|
||||
/** SHM data - true if shm is enabled */
|
||||
int shm_enable;
|
||||
/** SHM data - key for the shm */
|
||||
Index: util/configlexer.lex
|
||||
===================================================================
|
||||
--- util/configlexer.lex (revision 4191)
|
||||
+++ util/configlexer.lex (working copy)
|
||||
@@ -410,6 +410,8 @@
|
||||
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
|
||||
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
|
||||
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
|
||||
+redirect-bogus-ipv4{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV4) }
|
||||
+redirect-bogus-ipv6{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV6) }
|
||||
dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) }
|
||||
dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) }
|
||||
dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
|
||||
Index: util/configparser.y
|
||||
===================================================================
|
||||
--- util/configparser.y (revision 4191)
|
||||
+++ util/configparser.y (working copy)
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#include "sldns/str2wire.h"
|
||||
#include "util/configyyrename.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
@@ -141,6 +142,7 @@
|
||||
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
|
||||
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
|
||||
+%token VAR_REDIRECT_BOGUS_IPV4 VAR_REDIRECT_BOGUS_IPV6
|
||||
%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
|
||||
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
|
||||
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
|
||||
@@ -228,6 +230,7 @@
|
||||
server_access_control_tag_data | server_access_control_view |
|
||||
server_qname_minimisation_strict | server_serve_expired |
|
||||
server_fake_dsa | server_log_identity | server_use_systemd |
|
||||
+ server_redirect_bogus_ipv4 | server_redirect_bogus_ipv6 |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
server_hide_trustanchor | server_trust_anchor_signaling |
|
||||
@@ -1873,6 +1876,34 @@
|
||||
#endif
|
||||
}
|
||||
;
|
||||
+server_redirect_bogus_ipv4: VAR_REDIRECT_BOGUS_IPV4 STRING_ARG
|
||||
+ {
|
||||
+ uint8_t data[4];
|
||||
+ size_t data_len = 4;
|
||||
+ OUTYY(("P(name:%s)\n", $2));
|
||||
+ if(cfg_parser->cfg->redirect_bogus_ipv4) {
|
||||
+ yyerror("redirect-bogus-ipv4, can only use one address");
|
||||
+ }
|
||||
+ if(sldns_str2wire_a_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
|
||||
+ yyerror("redirect-bogus-ipv4, not a valid IPv4 address");
|
||||
+ }
|
||||
+ free(cfg_parser->cfg->redirect_bogus_ipv4);
|
||||
+ cfg_parser->cfg->redirect_bogus_ipv4 = $2;
|
||||
+ }
|
||||
+server_redirect_bogus_ipv6: VAR_REDIRECT_BOGUS_IPV6 STRING_ARG
|
||||
+ {
|
||||
+ uint8_t data[16];
|
||||
+ size_t data_len = 16;
|
||||
+ OUTYY(("P(name:%s)\n", $2));
|
||||
+ if(cfg_parser->cfg->redirect_bogus_ipv6) {
|
||||
+ yyerror("redirect-bogus-ipv6, can only use one address");
|
||||
+ }
|
||||
+ if(sldns_str2wire_aaaa_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
|
||||
+ yyerror("redirect-bogus-ipv6, not a valid IPv6 address");
|
||||
+ }
|
||||
+ free(cfg_parser->cfg->redirect_bogus_ipv6);
|
||||
+ cfg_parser->cfg->redirect_bogus_ipv6 = $2;
|
||||
+ }
|
||||
stub_name: VAR_NAME STRING_ARG
|
||||
{
|
||||
OUTYY(("P(name:%s)\n", $2));
|
||||
Index: util/data/msgencode.c
|
||||
===================================================================
|
||||
--- util/data/msgencode.c (revision 4191)
|
||||
+++ util/data/msgencode.c (working copy)
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
+#include "sldns/str2wire.h"
|
||||
#include "services/localzone.h"
|
||||
|
||||
/** return code that means the function ran out of memory. negative so it does
|
||||
@@ -914,3 +915,63 @@
|
||||
attach_edns_record(buf, &es);
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+fixed_address_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
|
||||
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* data)
|
||||
+{
|
||||
+ uint16_t flags;
|
||||
+ uint8_t addr_data[16];
|
||||
+ size_t addr_len = 16;
|
||||
+ if (qinfo->qtype == LDNS_RR_TYPE_A) {
|
||||
+ sldns_str2wire_a_buf(data, addr_data, &addr_len);
|
||||
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA) {
|
||||
+ sldns_str2wire_aaaa_buf(data, addr_data, &addr_len);
|
||||
+ } else {
|
||||
+ return error_encode(buf, LDNS_RCODE_NOERROR, qinfo, qid, qflags, edns);
|
||||
+ }
|
||||
+ sldns_buffer_clear(buf);
|
||||
+ sldns_buffer_write(buf, &qid, sizeof(uint16_t));
|
||||
+ flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
|
||||
+ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
|
||||
+ sldns_buffer_write_u16(buf, flags);
|
||||
+ if(qinfo) flags = 1;
|
||||
+ else flags = 0;
|
||||
+ sldns_buffer_write_u16(buf, flags);
|
||||
+ sldns_buffer_write_u16(buf, 1);
|
||||
+ flags = 0;
|
||||
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
|
||||
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
|
||||
+ if(qinfo) {
|
||||
+ // query
|
||||
+ if(sldns_buffer_current(buf) == qinfo->qname)
|
||||
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
|
||||
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qtype);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qclass);
|
||||
+ // faked answer
|
||||
+ if(sldns_buffer_current(buf) == qinfo->qname)
|
||||
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
|
||||
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qtype);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qclass);
|
||||
+ sldns_buffer_write_u16(buf, 0);
|
||||
+ // TTL. Should we make this configurable too?
|
||||
+ sldns_buffer_write_u16(buf, 5);
|
||||
+ sldns_buffer_write_u16(buf, addr_len);
|
||||
+ sldns_buffer_write(buf, addr_data, addr_len);
|
||||
+ fflush(stderr);
|
||||
+ }
|
||||
+ sldns_buffer_flip(buf);
|
||||
+ if(edns) {
|
||||
+ struct edns_data es = *edns;
|
||||
+ es.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
+ es.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
+ es.ext_rcode = 0;
|
||||
+ es.bits &= EDNS_DO;
|
||||
+ if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
|
||||
+ edns->udp_size)
|
||||
+ return;
|
||||
+ attach_edns_record(buf, &es);
|
||||
+ }
|
||||
+}
|
||||
Index: util/data/msgencode.h
|
||||
===================================================================
|
||||
--- util/data/msgencode.h (revision 4191)
|
||||
+++ util/data/msgencode.h (working copy)
|
||||
@@ -128,4 +128,20 @@
|
||||
void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
|
||||
uint16_t qid, uint16_t qflags, struct edns_data* edns);
|
||||
|
||||
+/**
|
||||
+ * Encode a fixed address response.
|
||||
+ * This is a fake answer to either an A or AAA query
|
||||
+ *
|
||||
+ * It will answer with that address
|
||||
+ *
|
||||
+ * @param pkt: where to store the packet.
|
||||
+ * @param r: RCODE value to encode.
|
||||
+ * @param qinfo: if not NULL, the query is included.
|
||||
+ * @param qid: query ID to set in packet. network order.
|
||||
+ * @param qflags: original query flags (to copy RD and CD bits). host order.
|
||||
+ * @param edns: if not NULL, this is the query edns info,
|
||||
+ * and an edns reply is attached. Only attached if EDNS record fits reply.
|
||||
+ */
|
||||
+void fixed_address_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
|
||||
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* address);
|
||||
#endif /* UTIL_DATA_MSGENCODE_H */
|
||||
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
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import time
|
||||
from optparse import OptionParser
|
||||
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
def _calc_hashkey(qname, secret, qtype):
|
||||
qclass = 'IN' # CLASS is fixed for simplicity
|
||||
hobj = hashlib.sha256()
|
||||
hobj.update(dns.name.from_text(qname).to_wire())
|
||||
hobj.update(struct.pack('HH',
|
||||
socket.htons(dns.rdatatype.from_text(qtype)),
|
||||
socket.htons(dns.rdataclass.from_text(qclass))))
|
||||
hobj.update(secret)
|
||||
return hobj.hexdigest().upper()
|
||||
|
||||
def _redis_get(options, key):
|
||||
import redis
|
||||
return redis.Redis(options.address, int(options.port)).get(key)
|
||||
|
||||
def _dump_value(options, qname, key, value):
|
||||
print(';; query=%s/IN/%s' % (qname, options.qtype))
|
||||
print(';; key=%s' % key)
|
||||
if value is None:
|
||||
print(';; no value')
|
||||
return
|
||||
if len(value) < 16:
|
||||
print(';; broken value, short length: %d' % len(value))
|
||||
return
|
||||
now = int(time.time())
|
||||
timestamp = struct.unpack('!Q', value[-16:-8])[0]
|
||||
expire = struct.unpack('!Q', value[-8:])[0]
|
||||
print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
|
||||
(now, timestamp, expire, max(expire - now, 0)))
|
||||
print(dns.message.from_wire(value[:-16]))
|
||||
|
||||
def main():
|
||||
parser = OptionParser(usage='usage: %prog [options] query_name')
|
||||
parser.add_option("-a", "--address", dest="address", action="store",
|
||||
default='127.0.0.1', help="backend-server address",
|
||||
metavar='ADDRESS')
|
||||
parser.add_option("-b", "--backend", dest="backend", action="store",
|
||||
default='redis', help="backend name",
|
||||
metavar='BACKEND')
|
||||
parser.add_option("-p", "--port", dest="port", action="store",
|
||||
default='6379', help="backend-server port",
|
||||
metavar='PORT')
|
||||
parser.add_option("-s", "--secret", dest="secret", action="store",
|
||||
default='default', help="secret seed", metavar='SECRET')
|
||||
parser.add_option("-t", "--qtype", dest="qtype", action="store",
|
||||
default='A', help="query RR type", metavar='QTYPE')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('qname is missing')
|
||||
if options.backend == 'redis':
|
||||
get_func = _redis_get
|
||||
else:
|
||||
raise Exception('unknown backend name: %s\n' % options.backend)
|
||||
key = _calc_hashkey(args[0], options.secret, options.qtype)
|
||||
value = get_func(options, key)
|
||||
_dump_value(options, args[0], key, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
sys.stderr.write('%s\n' % e)
|
||||
exit(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
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
; 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.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_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
|
||||
@@ -0,0 +1,6 @@
|
||||
[Socket]
|
||||
ListenDatagram=127.0.0.1:1153
|
||||
ListenStream=127.0.0.1:1153
|
||||
# ListenStream=@UNBOUND_RUN_DIR@/control
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
+5
-17
@@ -150,7 +150,7 @@ get_state ( ) {
|
||||
fi
|
||||
done
|
||||
# try to get it
|
||||
echo $$ >$lock
|
||||
if echo $$ >$lock ; then : ; else break; fi
|
||||
done
|
||||
# do not refetch if the file exists and only LEE seconds old
|
||||
if test -f $state; then
|
||||
@@ -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"
|
||||
@@ -266,7 +268,6 @@ if test "$1" = "config" ; then
|
||||
echo "graph_args --base 1024 -l 0"
|
||||
echo "graph_vlabel memory used in bytes"
|
||||
echo "graph_category DNS"
|
||||
p_config "mem.total.sbrk" "Total memory" "GAUGE"
|
||||
p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
|
||||
p_config "mem.cache.message" "Message cache memory" "GAUGE"
|
||||
p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
|
||||
@@ -444,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
|
||||
@@ -458,20 +460,6 @@ queue)
|
||||
done
|
||||
;;
|
||||
memory)
|
||||
mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
|
||||
get_value 'mem.total.sbrk'
|
||||
if test $value -eq 0; then
|
||||
chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
|
||||
pidf=`$chk -o pidfile $conf 2>&1`
|
||||
pid=`cat $pidf 2>&1`
|
||||
value=`ps -p "$pid" -o rss= 2>&1`
|
||||
if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
|
||||
value=`expr $value \* 1024`
|
||||
else
|
||||
value=0
|
||||
fi
|
||||
fi
|
||||
echo "$mn.value" $value
|
||||
for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
|
||||
mem.mod.validator msg.cache.count rrset.cache.count \
|
||||
infra.cache.count key.cache.count; do
|
||||
|
||||
@@ -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_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.
+318
-9
@@ -45,6 +45,8 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
struct acl_list*
|
||||
acl_list_create(void)
|
||||
@@ -71,21 +73,21 @@ acl_list_delete(struct acl_list* acl)
|
||||
}
|
||||
|
||||
/** insert new address into acl_list structure */
|
||||
static int
|
||||
static struct acl_addr*
|
||||
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum acl_access control,
|
||||
int complain_duplicates)
|
||||
{
|
||||
struct acl_addr* node = regional_alloc(acl->region,
|
||||
struct acl_addr* node = regional_alloc_zero(acl->region,
|
||||
sizeof(struct acl_addr));
|
||||
if(!node)
|
||||
return 0;
|
||||
return NULL;
|
||||
node->control = control;
|
||||
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
|
||||
if(complain_duplicates)
|
||||
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
||||
}
|
||||
return 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
/** apply acl_list string */
|
||||
@@ -109,6 +111,8 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
control = acl_refuse_non_local;
|
||||
else if(strcmp(s2, "allow_snoop") == 0)
|
||||
control = acl_allow_snoop;
|
||||
else if(strcmp(s2, "allow_setrd") == 0)
|
||||
control = acl_allow_setrd;
|
||||
else {
|
||||
log_err("access control type %s unknown", str);
|
||||
return 0;
|
||||
@@ -125,6 +129,205 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** find or create node (NULL on parse or error) */
|
||||
static struct acl_addr*
|
||||
acl_find_or_create(struct acl_list* acl, const char* str)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
struct sockaddr_storage addr;
|
||||
int net;
|
||||
socklen_t addrlen;
|
||||
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||
log_err("cannot parse netblock: %s", str);
|
||||
return NULL;
|
||||
}
|
||||
/* find or create node */
|
||||
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
||||
addrlen, net))) {
|
||||
/* create node, type 'allow' since otherwise tags are
|
||||
* pointless, can override with specific access-control: cfg */
|
||||
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
|
||||
addrlen, net, acl_allow, 1))) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/** apply acl_tag string */
|
||||
static int
|
||||
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||
size_t bitmaplen)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->taglen = bitmaplen;
|
||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||
if(!node->taglist) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_view string */
|
||||
static int
|
||||
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
||||
struct views* vs)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||
if(!node->view) {
|
||||
log_err("no view with name: %s", str2);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&node->view->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_tag_action string */
|
||||
static int
|
||||
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
const char* str, const char* tag, const char* action)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
enum localzone_type t;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_actions) {
|
||||
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
||||
sizeof(*node->tag_actions)*cfg->num_tags);
|
||||
if(!node->tag_actions) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_actions_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if(!local_zone_str2type(action, &t)) {
|
||||
log_err("cannot parse access control action type: %s %s %s",
|
||||
str, tag, action);
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions[tagid] = (uint8_t)t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check wire data parse */
|
||||
static int
|
||||
check_data(const char* data, const struct config_strlist* head)
|
||||
{
|
||||
char buf[65536];
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t len = sizeof(rr);
|
||||
int res;
|
||||
/* '.' is sufficient for validation, and it makes the call to
|
||||
* sldns_wirerr_get_type() simpler below. */
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", data);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0,
|
||||
NULL, 0);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for the same tag. */
|
||||
if(res == 0 && head) {
|
||||
const char* err_data = NULL;
|
||||
|
||||
if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) {
|
||||
/* adding CNAME while other data already exists. */
|
||||
err_data = data;
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", head->str);
|
||||
len = sizeof(rr);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
if(res != 0) {
|
||||
/* This should be impossible here as head->str
|
||||
* has been validated, but we check it just in
|
||||
* case. */
|
||||
return 0;
|
||||
}
|
||||
if(sldns_wirerr_get_type(rr, len, 1) ==
|
||||
LDNS_RR_TYPE_CNAME) /* already have CNAME */
|
||||
err_data = head->str;
|
||||
}
|
||||
if(err_data) {
|
||||
log_err("redirect tag data '%s' must not coexist with "
|
||||
"other data.", err_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(res == 0)
|
||||
return 1;
|
||||
log_err("rr data [char %d] parse error %s",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-2,
|
||||
sldns_get_errorstr_parse(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** apply acl_tag_data string */
|
||||
static int
|
||||
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
const char* str, const char* tag, const char* data)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
char* dupdata;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_datas) {
|
||||
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
||||
acl->region, sizeof(*node->tag_datas)*cfg->num_tags);
|
||||
if(!node->tag_datas) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_datas_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_datas_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check data? */
|
||||
if(!check_data(data, node->tag_datas[tagid])) {
|
||||
log_err("cannot parse access-control-tag data: %s %s '%s'",
|
||||
str, tag, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dupdata = regional_strdup(acl->region, data);
|
||||
if(!dupdata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!cfg_region_strlist_insert(acl->region,
|
||||
&(node->tag_datas[tagid]), dupdata)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl_list config */
|
||||
static int
|
||||
read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
@@ -138,13 +341,114 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tags config */
|
||||
static int
|
||||
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_strbytelist* np, *p = cfg->acl_tags;
|
||||
cfg->acl_tags = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
|
||||
config_del_strbytelist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl view config */
|
||||
static int
|
||||
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
||||
{
|
||||
struct config_str2list* np, *p = cfg->acl_view;
|
||||
cfg->acl_view = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tag actions config */
|
||||
static int
|
||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = cfg->acl_tag_actions;
|
||||
cfg->acl_tag_actions = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
|
||||
p->str3)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p->str3);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tag datas config */
|
||||
static int
|
||||
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = cfg->acl_tag_datas;
|
||||
cfg->acl_tag_datas = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p->str3);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v)
|
||||
{
|
||||
regional_free_all(acl->region);
|
||||
addr_tree_init(&acl->tree);
|
||||
if(!read_acl_list(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_view(acl, cfg, v))
|
||||
return 0;
|
||||
if(!read_acl_tags(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_actions(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_datas(acl, cfg))
|
||||
return 0;
|
||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
||||
return 0;
|
||||
@@ -163,13 +467,18 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
}
|
||||
|
||||
enum acl_access
|
||||
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
acl_get_control(struct acl_addr* acl)
|
||||
{
|
||||
if(acl) return acl->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
return (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
addr, addrlen);
|
||||
if(r) return r->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
+35
-7
@@ -43,6 +43,7 @@
|
||||
#ifndef DAEMON_ACL_LIST_H
|
||||
#define DAEMON_ACL_LIST_H
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "services/view.h"
|
||||
struct config_file;
|
||||
struct regional;
|
||||
|
||||
@@ -62,7 +63,9 @@ enum acl_access {
|
||||
/** allow full access for recursion (+RD) queries */
|
||||
acl_allow,
|
||||
/** allow full access for all queries, recursion and cache snooping */
|
||||
acl_allow_snoop
|
||||
acl_allow_snoop,
|
||||
/** allow full access for recursion queries and set RD flag regardless of request */
|
||||
acl_allow_setrd
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -75,7 +78,7 @@ struct acl_list {
|
||||
* Tree of the addresses that are allowed/blocked.
|
||||
* contents of type acl_addr.
|
||||
*/
|
||||
rbtree_t tree;
|
||||
rbtree_type tree;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,6 +90,21 @@ struct acl_addr {
|
||||
struct addr_tree_node node;
|
||||
/** access control on this netblock */
|
||||
enum acl_access control;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** array per tagnumber of localzonetype(in one byte). NULL if none. */
|
||||
uint8_t* tag_actions;
|
||||
/** size of the tag_actions_array */
|
||||
size_t tag_actions_size;
|
||||
/** array per tagnumber, with per tag a list of rdata strings.
|
||||
* NULL if none. strings are like 'A 127.0.0.1' 'AAAA ::1' */
|
||||
struct config_strlist** tag_datas;
|
||||
/** size of the tag_datas array */
|
||||
size_t tag_datas_size;
|
||||
/* view element, NULL if none */
|
||||
struct view* view;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -105,19 +123,29 @@ void acl_list_delete(struct acl_list* acl);
|
||||
* Process access control config.
|
||||
* @param acl: where to store.
|
||||
* @param cfg: config options.
|
||||
* @param v: views structure
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v);
|
||||
|
||||
/**
|
||||
* Lookup address to see its access control status.
|
||||
* Lookup access control status for acl structure.
|
||||
* @param acl: structure for acl storage.
|
||||
* @return: what to do with message from this address.
|
||||
*/
|
||||
enum acl_access acl_get_control(struct acl_addr* acl);
|
||||
|
||||
/**
|
||||
* Lookup address to see its acl structure
|
||||
* @param acl: structure for address storage.
|
||||
* @param addr: address to check
|
||||
* @param addrlen: length of addr.
|
||||
* @return: what to do with message from this address.
|
||||
* @return: acl structure from this address.
|
||||
*/
|
||||
enum acl_access acl_list_lookup(struct acl_list* acl,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Get memory used by acl structure.
|
||||
|
||||
+25
-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,12 +73,13 @@ 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;
|
||||
/* rd lock held by caller */
|
||||
if(!k || !d) return 1;
|
||||
if(k->id == 0) return 1; /* deleted */
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
|
||||
/* meta line */
|
||||
@@ -98,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 */
|
||||
@@ -117,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;
|
||||
@@ -136,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);
|
||||
@@ -163,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;
|
||||
@@ -245,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;
|
||||
@@ -273,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;
|
||||
@@ -290,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;
|
||||
@@ -301,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));
|
||||
@@ -309,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);
|
||||
@@ -317,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)
|
||||
{
|
||||
@@ -434,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;
|
||||
@@ -518,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;
|
||||
@@ -563,6 +564,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
qinfo->qname_len = dname_len;
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
|
||||
qinfo->local_alias = NULL;
|
||||
if(!qinfo->qname) {
|
||||
log_warn("error out of memory");
|
||||
return NULL;
|
||||
@@ -573,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)
|
||||
{
|
||||
@@ -618,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;
|
||||
@@ -651,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");
|
||||
@@ -683,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;
|
||||
@@ -696,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;
|
||||
@@ -707,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;
|
||||
@@ -783,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;
|
||||
|
||||
@@ -811,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 */
|
||||
@@ -826,6 +829,7 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
qinfo.qname_len = nmlen;
|
||||
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||
qinfo.qclass = LDNS_RR_CLASS_IN;
|
||||
qinfo.local_alias = NULL;
|
||||
|
||||
dname_str(nm, b);
|
||||
if(!ssl_printf(ssl, "The following name servers are used for lookup "
|
||||
|
||||
+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 */
|
||||
|
||||
+162
-24
@@ -73,20 +73,29 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "services/modstack.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
/** How many quit requests happened. */
|
||||
static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
@@ -96,10 +105,8 @@ static int sig_record_reload = 0;
|
||||
/** cleaner ssl memory freeup */
|
||||
static void* comp_meth = NULL;
|
||||
#endif
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/** remove buffers for parsing and init */
|
||||
int ub_c_lex_destroy(void);
|
||||
#endif
|
||||
|
||||
/** used when no other sighandling happens, so we don't die
|
||||
* when multiple signals in quick succession are sent to us.
|
||||
@@ -204,20 +211,33 @@ daemon_init(void)
|
||||
signal_handling_record();
|
||||
checklock_start();
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
ERR_load_SSL_strings();
|
||||
# ifdef HAVE_OPENSSL_CONFIG
|
||||
OPENSSL_config("unbound");
|
||||
# endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
# ifdef USE_GOST
|
||||
(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
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/* grab the COMP method ptr because openssl leaks it */
|
||||
comp_meth = (void*)SSL_COMP_get_compression_methods();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
# else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
if(!ub_openssl_lock_init())
|
||||
fatal_exit("could not init openssl locks");
|
||||
@@ -230,8 +250,6 @@ daemon_init(void)
|
||||
/* init timezone info while we are not chrooted yet */
|
||||
tzset();
|
||||
#endif
|
||||
/* open /dev/random if needed */
|
||||
ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67);
|
||||
daemon->need_to_exit = 0;
|
||||
modstack_init(&daemon->mods);
|
||||
if(!(daemon->env = (struct module_env*)calloc(1,
|
||||
@@ -239,9 +257,24 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
/* init edns_known_options */
|
||||
if(!edns_known_options_init(daemon->env)) {
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
alloc_init(&daemon->superalloc, NULL, 0);
|
||||
daemon->acl = acl_list_create();
|
||||
if(!daemon->acl) {
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->tcl = tcl_list_create();
|
||||
if(!daemon->tcl) {
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
@@ -249,6 +282,14 @@ daemon_init(void)
|
||||
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;
|
||||
}
|
||||
return daemon;
|
||||
}
|
||||
|
||||
@@ -338,6 +379,7 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
}
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,13 +427,11 @@ 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));
|
||||
}
|
||||
hash_set_raninit((uint32_t)ub_random(daemon->rand));
|
||||
shufport = (int*)calloc(65536, sizeof(int));
|
||||
if(!shufport)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
@@ -407,13 +447,13 @@ daemon_create_workers(struct daemon* daemon)
|
||||
}
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
if(!daemon->workers)
|
||||
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
|
||||
@@ -530,17 +570,71 @@ daemon_stop_others(struct daemon* daemon)
|
||||
void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
log_assert(daemon);
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
|
||||
if(!(daemon->views = views_create()))
|
||||
fatal_exit("Could not create views: out of memory");
|
||||
/* create individual views and their localzone/data trees */
|
||||
if(!views_apply_cfg(daemon->views, daemon->cfg))
|
||||
fatal_exit("Could not set up views");
|
||||
|
||||
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();
|
||||
if (!daemon->dnscenv)
|
||||
fatal_exit("dnsc_create failed");
|
||||
dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnscrypt enabled in config but unbound was not built with "
|
||||
"dnscrypt support");
|
||||
#endif
|
||||
}
|
||||
/* create global local_zones */
|
||||
if(!(daemon->local_zones = local_zones_create()))
|
||||
fatal_exit("Could not create local zones: out of memory");
|
||||
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
|
||||
fatal_exit("Could not set up local zones");
|
||||
|
||||
/* process raw response-ip configuration data */
|
||||
if(!(daemon->respip_set = respip_set_create()))
|
||||
fatal_exit("Could not create response IP set");
|
||||
if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
|
||||
fatal_exit("Could not set up response IP set");
|
||||
if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
|
||||
&have_view_respip_cfg))
|
||||
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,
|
||||
&daemon->use_rpz))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* setup modules */
|
||||
daemon_setup_modules(daemon);
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
@@ -567,14 +661,34 @@ daemon_fork(struct daemon* daemon)
|
||||
#endif
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
if (!shm_main_init(daemon))
|
||||
log_warn("SHM has failed");
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
#ifdef HAVE_SYSTEMD
|
||||
ret = sd_notify(0, "READY=1");
|
||||
if(ret <= 0 && getenv("NOTIFY_SOCKET"))
|
||||
fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
|
||||
"access/permission to use the socket presented by systemd.",
|
||||
getenv("NOTIFY_SOCKET"),
|
||||
(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
/* we exited! a signal happened! Stop other threads */
|
||||
daemon_stop_others(daemon);
|
||||
|
||||
/* Shutdown SHM */
|
||||
shm_main_shutdown(daemon);
|
||||
|
||||
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
|
||||
}
|
||||
|
||||
@@ -589,21 +703,32 @@ daemon_cleanup(struct daemon* daemon)
|
||||
log_thread_set(NULL);
|
||||
/* clean up caches because
|
||||
* a) RRset IDs will be recycled after a reload, causing collisions
|
||||
* b) validation config can change, thus rrset, msg, keycache clear
|
||||
* The infra cache is kept, the timing and edns info is still valid */
|
||||
* b) validation config can change, thus rrset, msg, keycache clear */
|
||||
slabhash_clear(&daemon->env->rrset_cache->table);
|
||||
slabhash_clear(daemon->env->msg_cache);
|
||||
local_zones_delete(daemon->local_zones);
|
||||
daemon->local_zones = NULL;
|
||||
/* key cache is cleared by module desetup during next daemon_init() */
|
||||
respip_set_delete(daemon->respip_set);
|
||||
daemon->respip_set = NULL;
|
||||
views_delete(daemon->views);
|
||||
daemon->views = NULL;
|
||||
if(daemon->env->auth_zones)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
daemon->num = 0;
|
||||
alloc_clear_special(&daemon->superalloc);
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
@@ -624,22 +749,24 @@ daemon_delete(struct daemon* daemon)
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
edns_known_options_delete(daemon->env);
|
||||
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)
|
||||
@@ -647,21 +774,33 @@ daemon_delete(struct daemon* daemon)
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
# ifndef S_SPLINT_S
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
|
||||
ENGINE_cleanup();
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
# endif
|
||||
# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
|
||||
ERR_remove_state(0);
|
||||
# endif
|
||||
# ifdef HAVE_ERR_FREE_STRINGS
|
||||
ERR_free_strings();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
RAND_cleanup();
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
ub_openssl_lock_delete();
|
||||
# endif
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
_ARC4_LOCK_DESTROY();
|
||||
#endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_Shutdown();
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
@@ -678,9 +817,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,
|
||||
|
||||
+23
-3
@@ -45,9 +45,6 @@
|
||||
#include "util/locks.h"
|
||||
#include "util/alloc.h"
|
||||
#include "services/modstack.h"
|
||||
#ifdef UB_ON_WINDOWS
|
||||
# include "util/winsock_event.h"
|
||||
#endif
|
||||
struct config_file;
|
||||
struct worker;
|
||||
struct listen_port;
|
||||
@@ -56,14 +53,22 @@ struct module_env;
|
||||
struct rrset_cache;
|
||||
struct acl_list;
|
||||
struct local_zones;
|
||||
struct views;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
struct respip_set;
|
||||
struct shm_main_info;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
struct dt_env;
|
||||
#endif
|
||||
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
#ifdef USE_DNSCRYPT
|
||||
struct dnsc_env;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Structure holding worker list.
|
||||
* Holds globally visible information.
|
||||
@@ -108,15 +113,30 @@ 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 */
|
||||
struct timeval time_last_stat;
|
||||
/** time when daemon started */
|
||||
struct timeval time_boot;
|
||||
/** views structure containing view tree */
|
||||
struct views* views;
|
||||
#ifdef USE_DNSTAP
|
||||
/** the dnstap environment master value, copied and changed by threads*/
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
struct shm_main_info* shm_info;
|
||||
/** response-ip set with associated actions and tags. */
|
||||
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;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+924
-335
File diff suppressed because it is too large
Load Diff
+23
-8
@@ -56,8 +56,8 @@ struct comm_reply;
|
||||
struct comm_point;
|
||||
struct daemon_remote;
|
||||
|
||||
/** number of seconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120
|
||||
/** number of milliseconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120000
|
||||
|
||||
/**
|
||||
* a busy control command connection, SSL state
|
||||
@@ -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 */
|
||||
|
||||
+244
-53
@@ -56,72 +56,134 @@
|
||||
#include "util/timehist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "validator/validator.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#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
|
||||
timeval_add(struct timeval* d, const struct timeval* add)
|
||||
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
if(d->tv_usec > 1000000) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
(*d_sec) += add_sec;
|
||||
(*d_usec) += add_usec;
|
||||
if((*d_usec) >= 1000000) {
|
||||
(*d_usec) -= 1000000;
|
||||
(*d_sec)++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void server_stats_init(struct server_stats* stats, struct config_file* cfg)
|
||||
void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg)
|
||||
{
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
stats->extended = cfg->stat_extended;
|
||||
}
|
||||
|
||||
void server_stats_querymiss(struct server_stats* stats, struct worker* worker)
|
||||
void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker)
|
||||
{
|
||||
stats->num_queries_missed_cache++;
|
||||
stats->sum_query_list_size += worker->env.mesh->all.count;
|
||||
if(worker->env.mesh->all.count > stats->max_query_list_size)
|
||||
stats->max_query_list_size = worker->env.mesh->all.count;
|
||||
if((long long)worker->env.mesh->all.count > stats->max_query_list_size)
|
||||
stats->max_query_list_size = (long long)worker->env.mesh->all.count;
|
||||
}
|
||||
|
||||
void server_stats_prefetch(struct server_stats* stats, struct worker* worker)
|
||||
void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker)
|
||||
{
|
||||
stats->num_queries_prefetch++;
|
||||
/* changes the query list size so account that, like a querymiss */
|
||||
stats->sum_query_list_size += worker->env.mesh->all.count;
|
||||
if(worker->env.mesh->all.count > stats->max_query_list_size)
|
||||
stats->max_query_list_size = worker->env.mesh->all.count;
|
||||
if((long long)worker->env.mesh->all.count > stats->max_query_list_size)
|
||||
stats->max_query_list_size = (long long)worker->env.mesh->all.count;
|
||||
}
|
||||
|
||||
void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
int threadnum)
|
||||
{
|
||||
log_info("server stats for thread %d: %u queries, "
|
||||
"%u answers from cache, %u recursions, %u prefetch",
|
||||
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
|
||||
"ip ratelimiting",
|
||||
threadnum, (unsigned)stats->num_queries,
|
||||
(unsigned)(stats->num_queries -
|
||||
stats->num_queries_missed_cache),
|
||||
(unsigned)stats->num_queries_missed_cache,
|
||||
(unsigned)stats->num_queries_prefetch);
|
||||
(unsigned)stats->num_queries_prefetch,
|
||||
(unsigned)stats->num_queries_ip_ratelimited);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u jostled %u", threadnum,
|
||||
(unsigned)stats->max_query_list_size,
|
||||
(stats->num_queries_missed_cache+stats->num_queries_prefetch)?
|
||||
(double)stats->sum_query_list_size/
|
||||
(stats->num_queries_missed_cache+
|
||||
(double)(stats->num_queries_missed_cache+
|
||||
stats->num_queries_prefetch) : 0.0,
|
||||
(unsigned)worker->env.mesh->stats_dropped,
|
||||
(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,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* ve;
|
||||
struct val_neg_cache* neg;
|
||||
if(m == -1)
|
||||
return;
|
||||
ve = (struct val_env*)worker->env.modinfo[m];
|
||||
if(!ve->neg_cache)
|
||||
return;
|
||||
neg = ve->neg_cache;
|
||||
lock_basic_lock(&neg->lock);
|
||||
svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror;
|
||||
svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
neg->num_neg_cache_noerror = 0;
|
||||
neg->num_neg_cache_nxdomain = 0;
|
||||
}
|
||||
lock_basic_unlock(&neg->lock);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
static size_t
|
||||
get_rrset_bogus(struct worker* worker)
|
||||
get_rrset_bogus(struct worker* worker, int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* ve;
|
||||
@@ -131,56 +193,164 @@ get_rrset_bogus(struct worker* worker)
|
||||
ve = (struct val_env*)worker->env.modinfo[m];
|
||||
lock_basic_lock(&ve->bogus_lock);
|
||||
r = ve->num_rrset_bogus;
|
||||
if(!worker->env.cfg->stat_cumulative)
|
||||
if(reset && !worker->env.cfg->stat_cumulative)
|
||||
ve->num_rrset_bogus = 0;
|
||||
lock_basic_unlock(&ve->bogus_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** get number of ratelimited queries from iterator */
|
||||
static size_t
|
||||
get_queries_ratelimit(struct worker* worker, int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "iterator");
|
||||
struct iter_env* ie;
|
||||
size_t r;
|
||||
if(m == -1)
|
||||
return 0;
|
||||
ie = (struct iter_env*)worker->env.modinfo[m];
|
||||
lock_basic_lock(&ie->queries_ratelimit_lock);
|
||||
r = ie->num_queries_ratelimited;
|
||||
if(reset && !worker->env.cfg->stat_cumulative)
|
||||
ie->num_queries_ratelimited = 0;
|
||||
lock_basic_unlock(&ie->queries_ratelimit_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** get the number of shared secret cache miss */
|
||||
static size_t
|
||||
get_dnscrypt_cache_miss(struct worker* worker, int reset)
|
||||
{
|
||||
size_t r;
|
||||
struct dnsc_env* de = worker->daemon->dnscenv;
|
||||
if(!de) return 0;
|
||||
|
||||
lock_basic_lock(&de->shared_secrets_cache_lock);
|
||||
r = de->num_query_dnscrypt_secret_missed_cache;
|
||||
if(reset && !worker->env.cfg->stat_cumulative)
|
||||
de->num_query_dnscrypt_secret_missed_cache = 0;
|
||||
lock_basic_unlock(&de->shared_secrets_cache_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** get the number of replayed queries */
|
||||
static size_t
|
||||
get_dnscrypt_replay(struct worker* worker, int reset)
|
||||
{
|
||||
size_t r;
|
||||
struct dnsc_env* de = worker->daemon->dnscenv;
|
||||
|
||||
lock_basic_lock(&de->nonces_cache_lock);
|
||||
r = de->num_query_dnscrypt_replay;
|
||||
if(reset && !worker->env.cfg->stat_cumulative)
|
||||
de->num_query_dnscrypt_replay = 0;
|
||||
lock_basic_unlock(&de->nonces_cache_lock);
|
||||
return r;
|
||||
}
|
||||
#endif /* USE_DNSCRYPT */
|
||||
|
||||
void
|
||||
server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
|
||||
server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
{
|
||||
int i;
|
||||
struct listen_list* lp;
|
||||
|
||||
s->svr = worker->stats;
|
||||
s->mesh_num_states = worker->env.mesh->all.count;
|
||||
s->mesh_num_reply_states = worker->env.mesh->num_reply_states;
|
||||
s->mesh_jostled = worker->env.mesh->stats_jostled;
|
||||
s->mesh_dropped = worker->env.mesh->stats_dropped;
|
||||
s->mesh_replies_sent = worker->env.mesh->replies_sent;
|
||||
s->mesh_replies_sum_wait = worker->env.mesh->replies_sum_wait;
|
||||
s->mesh_num_states = (long long)worker->env.mesh->all.count;
|
||||
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
|
||||
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
|
||||
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
|
||||
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
|
||||
s->mesh_replies_sum_wait_sec = (long long)worker->env.mesh->replies_sum_wait.tv_sec;
|
||||
s->mesh_replies_sum_wait_usec = (long long)worker->env.mesh->replies_sum_wait.tv_usec;
|
||||
s->mesh_time_median = timehist_quartile(worker->env.mesh->histogram,
|
||||
0.50);
|
||||
|
||||
/* add in the values from the mesh */
|
||||
s->svr.ans_secure += worker->env.mesh->ans_secure;
|
||||
s->svr.ans_bogus += worker->env.mesh->ans_bogus;
|
||||
s->svr.ans_rcode_nodata += worker->env.mesh->ans_nodata;
|
||||
for(i=0; i<16; i++)
|
||||
s->svr.ans_rcode[i] += worker->env.mesh->ans_rcode[i];
|
||||
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<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 */
|
||||
s->svr.unwanted_replies = worker->back->unwanted_replies;
|
||||
s->svr.qtcp_outgoing = worker->back->num_tcp_outgoing;
|
||||
s->svr.unwanted_replies = (long long)worker->back->unwanted_replies;
|
||||
s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing;
|
||||
|
||||
/* get and reset validator rrset bogus number */
|
||||
s->svr.rrset_bogus = get_rrset_bogus(worker);
|
||||
s->svr.rrset_bogus = (long long)get_rrset_bogus(worker, reset);
|
||||
|
||||
/* get and reset iterator query ratelimit number */
|
||||
s->svr.queries_ratelimited = (long long)get_queries_ratelimit(worker, reset);
|
||||
|
||||
/* get cache sizes */
|
||||
s->svr.msg_cache_count = count_slabhash_entries(worker->env.msg_cache);
|
||||
s->svr.rrset_cache_count = count_slabhash_entries(&worker->env.rrset_cache->table);
|
||||
s->svr.infra_cache_count = count_slabhash_entries(worker->env.infra_cache->hosts);
|
||||
s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache);
|
||||
s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table);
|
||||
s->svr.infra_cache_count = (long long)count_slabhash_entries(worker->env.infra_cache->hosts);
|
||||
if(worker->env.key_cache)
|
||||
s->svr.key_cache_count = count_slabhash_entries(worker->env.key_cache->slab);
|
||||
s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab);
|
||||
else s->svr.key_cache_count = 0;
|
||||
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(worker->daemon->dnscenv) {
|
||||
s->svr.num_query_dnscrypt_secret_missed_cache =
|
||||
(long long)get_dnscrypt_cache_miss(worker, reset);
|
||||
s->svr.shared_secret_cache_count = (long long)count_slabhash_entries(
|
||||
worker->daemon->dnscenv->shared_secrets_cache);
|
||||
s->svr.nonce_cache_count = (long long)count_slabhash_entries(
|
||||
worker->daemon->dnscenv->nonces_cache);
|
||||
s->svr.num_query_dnscrypt_replay =
|
||||
(long long)get_dnscrypt_replay(worker, reset);
|
||||
} else {
|
||||
s->svr.num_query_dnscrypt_secret_missed_cache = 0;
|
||||
s->svr.shared_secret_cache_count = 0;
|
||||
s->svr.nonce_cache_count = 0;
|
||||
s->svr.num_query_dnscrypt_replay = 0;
|
||||
}
|
||||
#else
|
||||
s->svr.num_query_dnscrypt_secret_missed_cache = 0;
|
||||
s->svr.shared_secret_cache_count = 0;
|
||||
s->svr.nonce_cache_count = 0;
|
||||
s->svr.num_query_dnscrypt_replay = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(worker->env.auth_zones) {
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&worker->env.auth_zones->lock);
|
||||
} else {
|
||||
lock_rw_rdlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.num_query_authzone_up = (long long)worker->env.
|
||||
auth_zones->num_query_up;
|
||||
s->svr.num_query_authzone_down = (long long)worker->env.
|
||||
auth_zones->num_query_down;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker->env.auth_zones->num_query_up = 0;
|
||||
worker->env.auth_zones->num_query_down = 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.mem_stream_wait =
|
||||
(long long)tcp_req_info_get_stream_buffer_size();
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
#ifdef CLIENT_SUBNET
|
||||
/* EDNS Subnet usage numbers */
|
||||
set_subnet_stats(worker, &s->svr, reset);
|
||||
#else
|
||||
s->svr.num_query_subnet = 0;
|
||||
s->svr.num_query_subnet_cache = 0;
|
||||
#endif
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
for(lp = worker->front->cps; lp; lp = lp->next) {
|
||||
if(lp->com->type == comm_tcp_accept)
|
||||
s->svr.tcp_accept_usage += lp->com->cur_tcp_count;
|
||||
s->svr.tcp_accept_usage += (long long)lp->com->cur_tcp_count;
|
||||
}
|
||||
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
@@ -189,7 +359,7 @@ server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
|
||||
}
|
||||
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s, int reset)
|
||||
struct ub_stats_info* s, int reset)
|
||||
{
|
||||
uint8_t *reply = NULL;
|
||||
uint32_t len = 0;
|
||||
@@ -215,7 +385,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
|
||||
void server_stats_reply(struct worker* worker, int reset)
|
||||
{
|
||||
struct stats_info s;
|
||||
struct ub_stats_info s;
|
||||
server_stats_compile(worker, &s, reset);
|
||||
verbose(VERB_ALGO, "write stats replymsg");
|
||||
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
|
||||
@@ -223,12 +393,22 @@ void server_stats_reply(struct worker* worker, int reset)
|
||||
fatal_exit("could not write stat values over cmd channel");
|
||||
}
|
||||
|
||||
void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
{
|
||||
total->svr.num_queries += a->svr.num_queries;
|
||||
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
|
||||
total->svr.num_queries_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;
|
||||
total->svr.num_query_dnscrypt_cleartext += \
|
||||
a->svr.num_query_dnscrypt_cleartext;
|
||||
total->svr.num_query_dnscrypt_crypted_malformed += \
|
||||
a->svr.num_query_dnscrypt_crypted_malformed;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
/* the max size reached is upped to higher of both */
|
||||
if(a->svr.max_query_list_size > total->svr.max_query_list_size)
|
||||
total->svr.max_query_list_size = a->svr.max_query_list_size;
|
||||
@@ -239,6 +419,8 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.qclass_big += a->svr.qclass_big;
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
|
||||
total->svr.qtls += a->svr.qtls;
|
||||
total->svr.qtls_resume += a->svr.qtls_resume;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
@@ -253,20 +435,21 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
|
||||
total->svr.ans_secure += a->svr.ans_secure;
|
||||
total->svr.ans_bogus += a->svr.ans_bogus;
|
||||
total->svr.rrset_bogus += a->svr.rrset_bogus;
|
||||
total->svr.unwanted_replies += a->svr.unwanted_replies;
|
||||
total->svr.unwanted_queries += a->svr.unwanted_queries;
|
||||
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
|
||||
for(i=0; i<STATS_QTYPE_NUM; i++)
|
||||
for(i=0; i<UB_STATS_QTYPE_NUM; i++)
|
||||
total->svr.qtype[i] += a->svr.qtype[i];
|
||||
for(i=0; i<STATS_QCLASS_NUM; i++)
|
||||
for(i=0; i<UB_STATS_QCLASS_NUM; i++)
|
||||
total->svr.qclass[i] += a->svr.qclass[i];
|
||||
for(i=0; i<STATS_OPCODE_NUM; i++)
|
||||
for(i=0; i<UB_STATS_OPCODE_NUM; i++)
|
||||
total->svr.qopcode[i] += a->svr.qopcode[i];
|
||||
for(i=0; i<STATS_RCODE_NUM; i++)
|
||||
for(i=0; i<UB_STATS_RCODE_NUM; i++)
|
||||
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;
|
||||
@@ -274,27 +457,35 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->mesh_jostled += a->mesh_jostled;
|
||||
total->mesh_dropped += a->mesh_dropped;
|
||||
total->mesh_replies_sent += a->mesh_replies_sent;
|
||||
timeval_add(&total->mesh_replies_sum_wait, &a->mesh_replies_sum_wait);
|
||||
stats_timeval_add(&total->mesh_replies_sum_wait_sec, &total->mesh_replies_sum_wait_usec, a->mesh_replies_sum_wait_sec, a->mesh_replies_sum_wait_usec);
|
||||
/* the medians are averaged together, this is not as accurate as
|
||||
* taking the median over all of the data, but is good and fast
|
||||
* added up here, division later*/
|
||||
total->mesh_time_median += a->mesh_time_median;
|
||||
}
|
||||
|
||||
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
uint16_t flags = sldns_buffer_read_u16_at(c->buffer, 2);
|
||||
if(qtype < STATS_QTYPE_NUM)
|
||||
if(qtype < UB_STATS_QTYPE_NUM)
|
||||
stats->qtype[qtype]++;
|
||||
else stats->qtype_big++;
|
||||
if(qclass < STATS_QCLASS_NUM)
|
||||
if(qclass < UB_STATS_QCLASS_NUM)
|
||||
stats->qclass[qclass]++;
|
||||
else stats->qclass_big++;
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp)
|
||||
if(c->type != comm_udp) {
|
||||
stats->qtcp++;
|
||||
if(c->ssl != NULL) {
|
||||
stats->qtls++;
|
||||
#ifdef HAVE_SSL
|
||||
if(SSL_session_reused(c->ssl))
|
||||
stats->qtls_resume++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
stats->qipv6++;
|
||||
if( (flags&BIT_QR) )
|
||||
@@ -320,7 +511,7 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
}
|
||||
}
|
||||
|
||||
void server_stats_insrcode(struct server_stats* stats, sldns_buffer* buf)
|
||||
void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf)
|
||||
{
|
||||
if(stats->extended && sldns_buffer_limit(buf) != 0) {
|
||||
int r = (int)LDNS_RCODE_WIRE( sldns_buffer_begin(buf) );
|
||||
|
||||
+11
-130
@@ -50,143 +50,24 @@ struct comm_reply;
|
||||
struct edns_data;
|
||||
struct sldns_buffer;
|
||||
|
||||
/** number of qtype that is stored for in array */
|
||||
#define STATS_QTYPE_NUM 256
|
||||
/** number of qclass that is stored for in array */
|
||||
#define STATS_QCLASS_NUM 256
|
||||
/** number of rcodes in stats */
|
||||
#define STATS_RCODE_NUM 16
|
||||
/** number of opcodes in stats */
|
||||
#define STATS_OPCODE_NUM 16
|
||||
|
||||
/** per worker statistics */
|
||||
struct server_stats {
|
||||
/** number of queries from clients received. */
|
||||
size_t num_queries;
|
||||
/** number of queries that had a cache-miss. */
|
||||
size_t num_queries_missed_cache;
|
||||
/** number of prefetch queries - cachehits with prefetch */
|
||||
size_t num_queries_prefetch;
|
||||
|
||||
/**
|
||||
* Sum of the querylistsize of the worker for
|
||||
* every query that missed cache. To calculate average.
|
||||
*/
|
||||
size_t sum_query_list_size;
|
||||
/** max value of query list size reached. */
|
||||
size_t max_query_list_size;
|
||||
|
||||
/** Extended stats below (bool) */
|
||||
int extended;
|
||||
|
||||
/** qtype stats */
|
||||
size_t qtype[STATS_QTYPE_NUM];
|
||||
/** bigger qtype values not in array */
|
||||
size_t qtype_big;
|
||||
/** qclass stats */
|
||||
size_t qclass[STATS_QCLASS_NUM];
|
||||
/** bigger qclass values not in array */
|
||||
size_t qclass_big;
|
||||
/** query opcodes */
|
||||
size_t qopcode[STATS_OPCODE_NUM];
|
||||
/** number of queries over TCP */
|
||||
size_t qtcp;
|
||||
/** number of outgoing queries over TCP */
|
||||
size_t qtcp_outgoing;
|
||||
/** number of queries over IPv6 */
|
||||
size_t qipv6;
|
||||
/** number of queries with QR bit */
|
||||
size_t qbit_QR;
|
||||
/** number of queries with AA bit */
|
||||
size_t qbit_AA;
|
||||
/** number of queries with TC bit */
|
||||
size_t qbit_TC;
|
||||
/** number of queries with RD bit */
|
||||
size_t qbit_RD;
|
||||
/** number of queries with RA bit */
|
||||
size_t qbit_RA;
|
||||
/** number of queries with Z bit */
|
||||
size_t qbit_Z;
|
||||
/** number of queries with AD bit */
|
||||
size_t qbit_AD;
|
||||
/** number of queries with CD bit */
|
||||
size_t qbit_CD;
|
||||
/** number of queries with EDNS OPT record */
|
||||
size_t qEDNS;
|
||||
/** number of queries with EDNS with DO flag */
|
||||
size_t qEDNS_DO;
|
||||
/** answer rcodes */
|
||||
size_t ans_rcode[STATS_RCODE_NUM];
|
||||
/** answers with pseudo rcode 'nodata' */
|
||||
size_t ans_rcode_nodata;
|
||||
/** answers that were secure (AD) */
|
||||
size_t ans_secure;
|
||||
/** answers that were bogus (withheld as SERVFAIL) */
|
||||
size_t ans_bogus;
|
||||
/** rrsets marked bogus by validator */
|
||||
size_t rrset_bogus;
|
||||
/** unwanted traffic received on server-facing ports */
|
||||
size_t unwanted_replies;
|
||||
/** unwanted traffic received on client-facing ports */
|
||||
size_t unwanted_queries;
|
||||
/** usage of tcp accept list */
|
||||
size_t tcp_accept_usage;
|
||||
|
||||
/** histogram data exported to array
|
||||
* if the array is the same size, no data is lost, and
|
||||
* if all histograms are same size (is so by default) then
|
||||
* adding up works well. */
|
||||
size_t hist[NUM_BUCKETS_HIST];
|
||||
|
||||
/** number of message cache entries */
|
||||
size_t msg_cache_count;
|
||||
/** number of rrset cache entries */
|
||||
size_t rrset_cache_count;
|
||||
/** number of infra cache entries */
|
||||
size_t infra_cache_count;
|
||||
/** number of key cache entries */
|
||||
size_t key_cache_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Statistics to send over the control pipe when asked
|
||||
* This struct is made to be memcpied, sent in binary.
|
||||
*/
|
||||
struct stats_info {
|
||||
/** the thread stats */
|
||||
struct server_stats svr;
|
||||
|
||||
/** mesh stats: current number of states */
|
||||
size_t mesh_num_states;
|
||||
/** mesh stats: current number of reply (user) states */
|
||||
size_t mesh_num_reply_states;
|
||||
/** mesh stats: number of reply states overwritten with a new one */
|
||||
size_t mesh_jostled;
|
||||
/** mesh stats: number of incoming queries dropped */
|
||||
size_t mesh_dropped;
|
||||
/** mesh stats: replies sent */
|
||||
size_t mesh_replies_sent;
|
||||
/** mesh stats: sum of waiting times for the replies */
|
||||
struct timeval mesh_replies_sum_wait;
|
||||
/** mesh stats: median of waiting times for replies (in sec) */
|
||||
double mesh_time_median;
|
||||
};
|
||||
/* stats struct */
|
||||
#include "libunbound/unbound.h"
|
||||
|
||||
/**
|
||||
* Initialize server stats to 0.
|
||||
* @param stats: what to init (this is alloced by the caller).
|
||||
* @param cfg: with extended statistics option.
|
||||
*/
|
||||
void server_stats_init(struct server_stats* stats, struct config_file* cfg);
|
||||
void server_stats_init(struct ub_server_stats* stats, struct config_file* cfg);
|
||||
|
||||
/** add query if it missed the cache */
|
||||
void server_stats_querymiss(struct server_stats* stats, struct worker* worker);
|
||||
void server_stats_querymiss(struct ub_server_stats* stats, struct worker* worker);
|
||||
|
||||
/** add query if was cached and also resulted in a prefetch */
|
||||
void server_stats_prefetch(struct server_stats* stats, struct worker* worker);
|
||||
void server_stats_prefetch(struct ub_server_stats* stats, struct worker* worker);
|
||||
|
||||
/** display the stats to the log */
|
||||
void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
int threadnum);
|
||||
|
||||
/**
|
||||
@@ -197,7 +78,7 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
* @param reset: if stats can be reset.
|
||||
*/
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s, int reset);
|
||||
struct ub_stats_info* s, int reset);
|
||||
|
||||
/**
|
||||
* Compile stats into structure for this thread worker.
|
||||
@@ -207,7 +88,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
* @param reset: if true, depending on config stats are reset.
|
||||
* if false, statistics are not reset.
|
||||
*/
|
||||
void server_stats_compile(struct worker* worker, struct stats_info* s,
|
||||
void server_stats_compile(struct worker* worker, struct ub_stats_info* s,
|
||||
int reset);
|
||||
|
||||
/**
|
||||
@@ -223,7 +104,7 @@ void server_stats_reply(struct worker* worker, int reset);
|
||||
* @param total: sum of the two entries.
|
||||
* @param a: to add to it.
|
||||
*/
|
||||
void server_stats_add(struct stats_info* total, struct stats_info* a);
|
||||
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a);
|
||||
|
||||
/**
|
||||
* Add stats for this query
|
||||
@@ -234,7 +115,7 @@ void server_stats_add(struct stats_info* total, struct stats_info* a);
|
||||
* @param edns: edns record
|
||||
* @param repinfo: reply info with remote address
|
||||
*/
|
||||
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
|
||||
struct comm_reply* repinfo);
|
||||
|
||||
@@ -243,6 +124,6 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
* @param stats: the stats
|
||||
* @param buf: buffer with rcode. If buffer is length0: not counted.
|
||||
*/
|
||||
void server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf);
|
||||
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
|
||||
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
||||
+132
-118
@@ -57,6 +57,7 @@
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/ub_event.h"
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <openssl/crypto.h>
|
||||
@@ -66,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 */
|
||||
@@ -77,22 +79,6 @@
|
||||
#include <login_cap.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_MINI_EVENT
|
||||
# ifdef USE_WINSOCK
|
||||
# include "util/winsock_event.h"
|
||||
# else
|
||||
# include "util/mini_event.h"
|
||||
# endif
|
||||
#else
|
||||
# ifdef HAVE_EVENT_H
|
||||
# include <event.h>
|
||||
# else
|
||||
# include "event2/event.h"
|
||||
# include "event2/event_struct.h"
|
||||
# include "event2/event_compat.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
# include "winrc/win_svc.h"
|
||||
#endif
|
||||
@@ -102,92 +88,75 @@
|
||||
# include "nss.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
void* unbound_start_brk = 0;
|
||||
#ifdef HAVE_TARGETCONDITIONALS_H
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_EVENT_BASE_GET_METHOD) && (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
static const char* ev_backend2str(int b)
|
||||
{
|
||||
switch(b) {
|
||||
case EVBACKEND_SELECT: return "select";
|
||||
case EVBACKEND_POLL: return "poll";
|
||||
case EVBACKEND_EPOLL: return "epoll";
|
||||
case EVBACKEND_KQUEUE: return "kqueue";
|
||||
case EVBACKEND_DEVPOLL: return "devpoll";
|
||||
case EVBACKEND_PORT: return "evport";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
|
||||
#undef HAVE_FORK
|
||||
#endif
|
||||
|
||||
/** get the event system in use */
|
||||
static void get_event_sys(const char** n, const char** s, const char** m)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
*n = "event";
|
||||
*s = "winsock";
|
||||
*m = "WSAWaitForMultipleEvents";
|
||||
#elif defined(USE_MINI_EVENT)
|
||||
*n = "mini-event";
|
||||
*s = "internal";
|
||||
*m = "select";
|
||||
#else
|
||||
struct event_base* b;
|
||||
*s = event_get_version();
|
||||
# ifdef HAVE_EVENT_BASE_GET_METHOD
|
||||
*n = "libevent";
|
||||
b = event_base_new();
|
||||
*m = event_base_get_method(b);
|
||||
# elif defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
*n = "libev";
|
||||
b = (struct event_base*)ev_default_loop(EVFLAG_AUTO);
|
||||
*m = ev_backend2str(ev_backend((struct ev_loop*)b));
|
||||
# else
|
||||
*n = "unknown";
|
||||
*m = "not obtainable";
|
||||
b = NULL;
|
||||
# endif
|
||||
# ifdef HAVE_EVENT_BASE_FREE
|
||||
event_base_free(b);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print usage. */
|
||||
static void usage()
|
||||
/** print build options. */
|
||||
static void
|
||||
print_build_options(void)
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
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);
|
||||
get_event_sys(&evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
time_t t;
|
||||
struct timeval now;
|
||||
struct ub_event_base* base;
|
||||
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",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef SSLEAY_VERSION
|
||||
SSLeay_version(SSLEAY_VERSION)
|
||||
# else
|
||||
OpenSSL_version(OPENSSL_VERSION)
|
||||
# endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_GetVersion()
|
||||
#elif defined(HAVE_NETTLE)
|
||||
"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);
|
||||
}
|
||||
@@ -230,7 +199,7 @@ checkrlimits(struct config_file* cfg)
|
||||
struct rlimit rlim;
|
||||
|
||||
if(total > 1024 &&
|
||||
strncmp(event_get_version(), "mini-event", 10) == 0) {
|
||||
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
|
||||
log_warn("too many file descriptors requested. The builtin"
|
||||
"mini-event cannot handle more than 1024. Config "
|
||||
"for less fds or compile with libevent");
|
||||
@@ -244,7 +213,7 @@ checkrlimits(struct config_file* cfg)
|
||||
total = 1024;
|
||||
}
|
||||
if(perthread > 64 &&
|
||||
strncmp(event_get_version(), "winsock-event", 13) == 0) {
|
||||
strncmp(ub_event_get_version(), "winsock-event", 13) == 0) {
|
||||
log_err("too many file descriptors requested. The winsock"
|
||||
" event handler cannot handle more than 64 per "
|
||||
" thread. Config for less fds");
|
||||
@@ -300,17 +269,24 @@ checkrlimits(struct config_file* cfg)
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
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;
|
||||
if (debug_mode > 1) {
|
||||
cfg->use_syslog = 0;
|
||||
free(cfg->logfile);
|
||||
cfg->logfile = NULL;
|
||||
}
|
||||
daemon_apply_cfg(daemon, cfg);
|
||||
checkrlimits(cfg);
|
||||
|
||||
if (cfg->use_systemd && cfg->do_daemonize) {
|
||||
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
|
||||
}
|
||||
|
||||
log_ident_set_or_default(cfg->log_identity);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
@@ -438,10 +414,10 @@ detach(void)
|
||||
#endif /* HAVE_DAEMON */
|
||||
}
|
||||
|
||||
/** daemonize, drop user priviliges and chroot if needed */
|
||||
/** daemonize, drop user privileges and chroot if needed */
|
||||
static void
|
||||
perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
const char** cfgfile)
|
||||
const char** cfgfile, int need_pidfile)
|
||||
{
|
||||
#ifdef HAVE_KILL
|
||||
int pidinchroot;
|
||||
@@ -459,6 +435,38 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
w_config_adjust_directory(cfg);
|
||||
#endif
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
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)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
/* init syslog (as root) if needed, before daemonize, otherwise
|
||||
* a fork error could not be printed since daemonize closed stderr.*/
|
||||
if(cfg->use_syslog) {
|
||||
@@ -470,28 +478,15 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* So, using a logfile, the user does not see errors unless -d is
|
||||
* given to unbound on the commandline. */
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
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(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/* true if pidfile is inside chrootdir, or nochroot */
|
||||
pidinchroot = !(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
pidinchroot = need_pidfile && (!(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(cfg->pidfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir))==0);
|
||||
strlen(cfg->chrootdir))==0));
|
||||
|
||||
/* check old pid file before forking */
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
|
||||
/* calculate position of pidfile */
|
||||
if(cfg->pidfile[0] == '/')
|
||||
daemon->pidfile = strdup(cfg->pidfile);
|
||||
@@ -510,7 +505,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
|
||||
/* write new pidfile (while still root, so can be outside chroot) */
|
||||
#ifdef HAVE_KILL
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
|
||||
writepid(daemon->pidfile, getpid());
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
|
||||
pidinchroot) {
|
||||
@@ -525,6 +520,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
}
|
||||
#else
|
||||
(void)daemon;
|
||||
(void)need_pidfile;
|
||||
#endif /* HAVE_KILL */
|
||||
|
||||
/* Set user context */
|
||||
@@ -538,6 +534,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 */
|
||||
@@ -602,7 +600,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
log_warn("unable to initgroups %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
# endif /* HAVE_INITGROUPS */
|
||||
# ifdef HAVE_ENDPWENT
|
||||
endpwent();
|
||||
# endif
|
||||
|
||||
#ifdef HAVE_SETRESGID
|
||||
if(setresgid(cfg_gid,cfg_gid,cfg_gid) != 0)
|
||||
@@ -638,9 +638,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 need_pidfile: if false, no pidfile is checked or created.
|
||||
*/
|
||||
static void
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile)
|
||||
{
|
||||
struct config_file* cfg = NULL;
|
||||
struct daemon* daemon = NULL;
|
||||
@@ -658,8 +659,10 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
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);
|
||||
@@ -670,7 +673,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
if(!daemon_open_shared_ports(daemon))
|
||||
fatal_exit("could not open ports");
|
||||
if(!done_setup) {
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile);
|
||||
done_setup = 1;
|
||||
} else {
|
||||
/* reopen log after HUP to facilitate log rotation */
|
||||
@@ -717,21 +720,21 @@ main(int argc, char* argv[])
|
||||
int c;
|
||||
const char* cfgfile = CONFIGFILE;
|
||||
const char* winopt = NULL;
|
||||
const char* log_ident_default;
|
||||
int cmdline_verbose = 0;
|
||||
int debug_mode = 0;
|
||||
int need_pidfile = 1;
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
int cmdline_cfg = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/* take debug snapshot of heap */
|
||||
unbound_start_brk = sbrk(0);
|
||||
#endif
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_set(strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]);
|
||||
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:dhvw:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
cfgfile = optarg;
|
||||
@@ -743,12 +746,18 @@ main(int argc, char* argv[])
|
||||
cmdline_verbose++;
|
||||
verbosity++;
|
||||
break;
|
||||
case 'p':
|
||||
need_pidfile = 0;
|
||||
break;
|
||||
case 'd':
|
||||
debug_mode++;
|
||||
break;
|
||||
case 'w':
|
||||
winopt = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
print_build_options();
|
||||
return 0;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
@@ -757,7 +766,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
@@ -773,7 +782,12 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode);
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile);
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
#ifndef unbound_testbound
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
+876
-219
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -61,6 +61,7 @@ struct ub_randstate;
|
||||
struct regional;
|
||||
struct tube;
|
||||
struct daemon_remote;
|
||||
struct query_info;
|
||||
|
||||
/** worker commands */
|
||||
enum worker_commands {
|
||||
@@ -84,7 +85,7 @@ struct worker {
|
||||
/** global shared daemon structure */
|
||||
struct daemon* daemon;
|
||||
/** thread id */
|
||||
ub_thread_t thr_id;
|
||||
ub_thread_type thr_id;
|
||||
/** pipe, for commands for this worker */
|
||||
struct tube* cmd;
|
||||
/** the event base this worker works with */
|
||||
@@ -115,7 +116,7 @@ struct worker {
|
||||
/** allocation cache for this thread */
|
||||
struct alloc_cache alloc;
|
||||
/** per thread statistics */
|
||||
struct server_stats stats;
|
||||
struct ub_server_stats stats;
|
||||
/** thread scratch regional */
|
||||
struct regional* scratchpad;
|
||||
|
||||
|
||||
+226
-70
@@ -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,16 +191,19 @@ uitoa(unsigned n, char* s)
|
||||
*
|
||||
* \param ipv6 IPv6 address represented as a 128-bit array in big-endian
|
||||
* order.
|
||||
* \param ipv6_len length of the ipv6 byte array.
|
||||
* \param offset Index of the MSB of the IPv4 address embedded in the IPv6
|
||||
* address.
|
||||
*/
|
||||
static uint32_t
|
||||
extract_ipv4(const uint8_t ipv6[16], const int offset)
|
||||
extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
|
||||
{
|
||||
uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
|
||||
uint32_t ipv4;
|
||||
log_assert(ipv6_len == 16); (void)ipv6_len;
|
||||
ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
|
||||
if (offset/8+4 < 16)
|
||||
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
|
||||
return ipv4;
|
||||
@@ -196,22 +217,26 @@ extract_ipv4(const uint8_t ipv6[16], const int offset)
|
||||
* \param ipv4 IPv4 address represented as an unsigned 32-bit number.
|
||||
* \param ptr The result will be written here. Must be large enough, be
|
||||
* careful!
|
||||
* \param nm_len length of the ptr buffer.
|
||||
*
|
||||
* \return The number of characters written.
|
||||
*/
|
||||
static size_t
|
||||
ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
|
||||
ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
|
||||
{
|
||||
static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
|
||||
int i;
|
||||
char* c = ptr;
|
||||
log_assert(nm_len == MAX_PTR_QNAME_IPV4); (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 +248,15 @@ ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
|
||||
*
|
||||
* \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
|
||||
* \param ipv6 The result will be written here, in network byte order.
|
||||
* \param ipv6_len length of the ipv6 byte array.
|
||||
*
|
||||
* \return 1 on success, 0 on failure.
|
||||
*/
|
||||
static int
|
||||
ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
|
||||
ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len)
|
||||
{
|
||||
int i;
|
||||
log_assert(ipv6_len == 16); (void)ipv6_len;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int x;
|
||||
@@ -257,14 +284,20 @@ ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
|
||||
* Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
|
||||
*
|
||||
* \param prefix_addr DNS64 prefix address.
|
||||
* \param prefix_addr_len length of the prefix_addr buffer.
|
||||
* \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96.
|
||||
* \param a IPv4 address.
|
||||
* \param a_len length of the a buffer.
|
||||
* \param aaaa IPv6 address. The result will be written here.
|
||||
* \param aaaa_len length of the aaaa buffer.
|
||||
*/
|
||||
static void
|
||||
synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
const uint8_t a[4], uint8_t aaaa[16])
|
||||
synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len,
|
||||
int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[],
|
||||
size_t aaaa_len)
|
||||
{
|
||||
log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
|
||||
(void)prefix_addr_len; (void)a_len; (void)aaaa_len;
|
||||
memcpy(aaaa, prefix_addr, 16);
|
||||
aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
|
||||
@@ -284,6 +317,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 +362,7 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
@@ -311,6 +379,11 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
|
||||
if(!dns64_insert_ignore_aaaa(dns64_env, s->str))
|
||||
return 0;
|
||||
}
|
||||
name_tree_init_parents(&dns64_env->ignore_aaaa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -329,7 +402,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 +411,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 +430,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 +462,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
/* Convert the PTR query string to an IPv6 address. */
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
|
||||
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr,
|
||||
sizeof(sin6.sin6_addr.s6_addr)))
|
||||
return module_wait_module; /* Let other module handle this. */
|
||||
|
||||
/*
|
||||
@@ -395,7 +486,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
|
||||
return module_error;
|
||||
qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
|
||||
dns64_env->prefix_net), (char*)qinfo.qname);
|
||||
sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net),
|
||||
(char*)qinfo.qname, MAX_PTR_QNAME_IPV4);
|
||||
|
||||
/* Create the new sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
@@ -405,37 +497,12 @@ 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;
|
||||
}
|
||||
|
||||
/** allocate (special) rrset keys, return 0 on error */
|
||||
static int
|
||||
repinfo_alloc_rrset_keys(struct reply_info* rep,
|
||||
struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
if(region) {
|
||||
rep->rrsets[i] = (struct ub_packed_rrset_key*)
|
||||
regional_alloc(region,
|
||||
sizeof(struct ub_packed_rrset_key));
|
||||
if(rep->rrsets[i]) {
|
||||
memset(rep->rrsets[i], 0,
|
||||
sizeof(struct ub_packed_rrset_key));
|
||||
rep->rrsets[i]->entry.key = rep->rrsets[i];
|
||||
}
|
||||
}
|
||||
else return 0;/* rep->rrsets[i] = alloc_special_obtain(alloc);*/
|
||||
if(!rep->rrsets[i])
|
||||
return 0;
|
||||
rep->rrsets[i]->entry.data = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static enum module_ext_state
|
||||
generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
{
|
||||
@@ -465,6 +532,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
|
||||
@@ -481,7 +567,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"))
|
||||
@@ -489,12 +576,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. */
|
||||
@@ -515,27 +610,48 @@ 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:
|
||||
*
|
||||
* - An internal query.
|
||||
* - A query for a record type other than AAAA.
|
||||
* - CD FLAG was set on querier
|
||||
* - An AAAA query for which an error was returned.
|
||||
* - An AAAA query for which an error was returned.(qstate.return_rcode)
|
||||
* -> treated as servfail thus synthesize (sec 5.1.3 6147), thus
|
||||
* 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_rcode != LDNS_RCODE_NOERROR
|
||||
|| (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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -554,6 +670,7 @@ void
|
||||
dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
struct dns64_qstate* iq;
|
||||
(void)outbound;
|
||||
verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]),
|
||||
@@ -563,7 +680,13 @@ 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);
|
||||
break;
|
||||
@@ -574,6 +697,11 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
qstate->ext_state[id] = module_finished;
|
||||
break;
|
||||
}
|
||||
if(qstate->ext_state[id] == module_finished) {
|
||||
iq = (struct dns64_qstate*)qstate->minfo[id];
|
||||
if(iq && iq->state != DNS64_INTERNAL_QUERY)
|
||||
qstate->no_cache_store = iq->started_no_cache_store;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -629,8 +757,10 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
|
||||
dd->rr_data[i][1] = 16;
|
||||
synthesize_aaaa(
|
||||
((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
|
||||
sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
|
||||
dns64_env->prefix_net, &fd->rr_data[i][2],
|
||||
&dd->rr_data[i][2] );
|
||||
fd->rr_len[i]-2, &dd->rr_data[i][2],
|
||||
dd->rr_len[i]-2);
|
||||
dd->rr_ttl[i] = fd->rr_ttl[i];
|
||||
}
|
||||
|
||||
@@ -700,13 +830,14 @@ 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;
|
||||
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!repinfo_alloc_rrset_keys(cp, super->region)) {
|
||||
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -728,6 +859,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,
|
||||
@@ -779,9 +916,10 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
|
||||
* initial query's domain name.
|
||||
*/
|
||||
answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
|
||||
log_assert(answer);
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
if(answer) {
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,6 +935,7 @@ void
|
||||
dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super)
|
||||
{
|
||||
struct dns64_qstate* super_dq = (struct dns64_qstate*)super->minfo[id];
|
||||
log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
|
||||
&qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "super is", &super->qinfo);
|
||||
@@ -805,15 +944,31 @@ 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)
|
||||
super->return_rcode = qstate->return_rcode;
|
||||
|
||||
/* Generate a response suitable for the original query. */
|
||||
if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
|
||||
@@ -824,8 +979,9 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
}
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -871,7 +1027,7 @@ static struct module_func_block dns64_block = {
|
||||
* Function for returning the above function block.
|
||||
*/
|
||||
struct module_func_block *
|
||||
dns64_get_funcblock()
|
||||
dns64_get_funcblock(void)
|
||||
{
|
||||
return &dns64_block;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_CERT_H
|
||||
#define UNBOUND_DNSCRYPT_CERT_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* certificate type for dnscrypt for use in other header files
|
||||
*/
|
||||
|
||||
#include <sodium.h>
|
||||
#define CERT_MAGIC_CERT "DNSC"
|
||||
#define CERT_MAJOR_VERSION 1
|
||||
#define CERT_MINOR_VERSION 0
|
||||
#define CERT_OLD_MAGIC_HEADER "7PYqwfzt"
|
||||
|
||||
#define CERT_FILE_EXPIRE_DAYS 365
|
||||
|
||||
struct SignedCert {
|
||||
uint8_t magic_cert[4];
|
||||
uint8_t version_major[2];
|
||||
uint8_t version_minor[2];
|
||||
|
||||
// Signed Content
|
||||
uint8_t signed_content[64];
|
||||
uint8_t server_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t magic_query[8];
|
||||
uint8_t serial[4];
|
||||
uint8_t ts_begin[4];
|
||||
uint8_t ts_end[4];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
+1108
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,175 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_H
|
||||
#define UNBOUND_DNSCRYPT_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* dnscrypt functions for encrypting DNS packets.
|
||||
*/
|
||||
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
#ifdef USE_DNSCRYPT
|
||||
|
||||
#define DNSCRYPT_MAGIC_HEADER_LEN 8U
|
||||
#define DNSCRYPT_MAGIC_RESPONSE "r6fnvWj8"
|
||||
|
||||
#ifndef DNSCRYPT_MAX_PADDING
|
||||
# define DNSCRYPT_MAX_PADDING 256U
|
||||
#endif
|
||||
#ifndef DNSCRYPT_BLOCK_SIZE
|
||||
# define DNSCRYPT_BLOCK_SIZE 64U
|
||||
#endif
|
||||
#ifndef DNSCRYPT_MIN_PAD_LEN
|
||||
# define DNSCRYPT_MIN_PAD_LEN 8U
|
||||
#endif
|
||||
|
||||
#define crypto_box_HALF_NONCEBYTES (crypto_box_NONCEBYTES / 2U)
|
||||
|
||||
#include "config.h"
|
||||
#include "dnscrypt/cert.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
#define DNSCRYPT_QUERY_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES)
|
||||
#define DNSCRYPT_RESPONSE_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_NONCEBYTES + crypto_box_MACBYTES)
|
||||
|
||||
#define DNSCRYPT_REPLY_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES * 2 + crypto_box_MACBYTES)
|
||||
|
||||
struct sldns_buffer;
|
||||
struct config_file;
|
||||
struct comm_reply;
|
||||
struct slabhash;
|
||||
|
||||
typedef struct KeyPair_ {
|
||||
uint8_t crypt_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t crypt_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
} KeyPair;
|
||||
|
||||
typedef struct cert_ {
|
||||
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
|
||||
uint8_t es_version[2];
|
||||
KeyPair *keypair;
|
||||
} dnsccert;
|
||||
|
||||
struct dnsc_env {
|
||||
struct SignedCert *signed_certs;
|
||||
struct SignedCert **rotated_certs;
|
||||
dnsccert *certs;
|
||||
size_t signed_certs_count;
|
||||
size_t rotated_certs_count;
|
||||
uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES];
|
||||
uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES];
|
||||
KeyPair *keypairs;
|
||||
size_t keypairs_count;
|
||||
uint64_t nonce_ts_last;
|
||||
unsigned char hash_key[crypto_shorthash_KEYBYTES];
|
||||
char * provider_name;
|
||||
|
||||
/** Caches */
|
||||
struct slabhash *shared_secrets_cache;
|
||||
/** lock on shared secret cache counters */
|
||||
lock_basic_type shared_secrets_cache_lock;
|
||||
/** number of misses from shared_secrets_cache */
|
||||
size_t num_query_dnscrypt_secret_missed_cache;
|
||||
|
||||
/** slabhash keeping track of nonce/cient pk/server sk pairs. */
|
||||
struct slabhash *nonces_cache;
|
||||
/** lock on nonces_cache, used to avoid race condition in updating the hash */
|
||||
lock_basic_type nonces_cache_lock;
|
||||
/** number of replayed queries */
|
||||
size_t num_query_dnscrypt_replay;
|
||||
};
|
||||
|
||||
struct dnscrypt_query_header {
|
||||
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
|
||||
uint8_t publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t mac[crypto_box_MACBYTES];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize DNSCrypt environment.
|
||||
* Initialize sodium library and allocate the dnsc_env structure.
|
||||
* \return an uninitialized struct dnsc_env.
|
||||
*/
|
||||
struct dnsc_env * dnsc_create(void);
|
||||
|
||||
/**
|
||||
* Apply configuration.
|
||||
* Read certificates and secret keys from configuration. Initialize hashkey and
|
||||
* provider name as well as loading cert TXT records.
|
||||
* In case of issue applying configuration, this function fatals.
|
||||
* \param[in] env the struct dnsc_env to populate.
|
||||
* \param[in] cfg the config_file struct with dnscrypt options.
|
||||
* \return 0 on success.
|
||||
*/
|
||||
int dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Delete DNSCrypt environment
|
||||
*
|
||||
*/
|
||||
void dnsc_delete(struct dnsc_env *env);
|
||||
|
||||
/**
|
||||
* handle a crypted dnscrypt request.
|
||||
* Determine wether or not a query is coming over the dnscrypt listener and
|
||||
* attempt to uncurve it or detect if it is a certificate query.
|
||||
* return 0 in case of failure.
|
||||
*/
|
||||
int dnsc_handle_curved_request(struct dnsc_env* dnscenv,
|
||||
struct comm_reply* repinfo);
|
||||
/**
|
||||
* handle an unencrypted dnscrypt request.
|
||||
* Determine wether or not a query is going over the dnscrypt channel and
|
||||
* attempt to curve it unless it was not crypted like when it is a
|
||||
* certificate query.
|
||||
* \return 0 in case of failure.
|
||||
*/
|
||||
|
||||
int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
|
||||
|
||||
/**
|
||||
* Computes the size of the shared secret cache entry.
|
||||
*/
|
||||
size_t dnsc_shared_secrets_sizefunc(void *k, void *d);
|
||||
|
||||
/**
|
||||
* Compares two shared secret cache keys.
|
||||
*/
|
||||
int dnsc_shared_secrets_compfunc(void *m1, void *m2);
|
||||
|
||||
/**
|
||||
* Function to delete a shared secret cache key.
|
||||
*/
|
||||
void dnsc_shared_secrets_delkeyfunc(void *k, void* arg);
|
||||
|
||||
/**
|
||||
* Function to delete a share secret cache value.
|
||||
*/
|
||||
void dnsc_shared_secrets_deldatafunc(void* d, void* arg);
|
||||
|
||||
/**
|
||||
* Computes the size of the nonce cache entry.
|
||||
*/
|
||||
size_t dnsc_nonces_sizefunc(void *k, void *d);
|
||||
|
||||
/**
|
||||
* Compares two nonce cache keys.
|
||||
*/
|
||||
int dnsc_nonces_compfunc(void *m1, void *m2);
|
||||
|
||||
/**
|
||||
* Function to delete a nonce cache key.
|
||||
*/
|
||||
void dnsc_nonces_delkeyfunc(void *k, void* arg);
|
||||
|
||||
/**
|
||||
* Function to delete a nonce cache value.
|
||||
*/
|
||||
void dnsc_nonces_deldatafunc(void* d, void* arg);
|
||||
|
||||
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
# dnscrypt.m4
|
||||
|
||||
# dnsc_DNSCRYPT([action-if-true], [action-if-false])
|
||||
# --------------------------------------------------------------------------
|
||||
# Check for required dnscrypt libraries and add dnscrypt configure args.
|
||||
AC_DEFUN([dnsc_DNSCRYPT],
|
||||
[
|
||||
AC_ARG_ENABLE([dnscrypt],
|
||||
AS_HELP_STRING([--enable-dnscrypt],
|
||||
[Enable dnscrypt support (requires libsodium)]),
|
||||
[opt_dnscrypt=$enableval], [opt_dnscrypt=no])
|
||||
|
||||
if test "x$opt_dnscrypt" != "xno"; then
|
||||
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path],
|
||||
[Path where libsodium is installed, for dnscrypt]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
])
|
||||
AC_SEARCH_LIBS([sodium_init], [sodium], [],
|
||||
AC_MSG_ERROR([The sodium library was not found. Please install sodium!]))
|
||||
AC_SEARCH_LIBS([crypto_box_curve25519xchacha20poly1305_beforenm], [sodium],
|
||||
[
|
||||
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [1])
|
||||
AC_DEFINE(
|
||||
[USE_DNSCRYPT_XCHACHA20], [1],
|
||||
[Define to 1 to enable dnscrypt with xchacha20 support])
|
||||
],
|
||||
[
|
||||
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
|
||||
])
|
||||
AC_SEARCH_LIBS([sodium_set_misuse_handler], [sodium],
|
||||
[
|
||||
AC_DEFINE(
|
||||
[SODIUM_MISUSE_HANDLER], [1],
|
||||
[Define to 1 if libsodium supports sodium_set_misuse_handler])
|
||||
],
|
||||
[
|
||||
])
|
||||
$1
|
||||
else
|
||||
AC_SUBST([ENABLE_DNSCRYPT_XCHACHA20], [0])
|
||||
$2
|
||||
fi
|
||||
])
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_CONFIG_H
|
||||
#define UNBOUND_DNSCRYPT_CONFIG_H
|
||||
|
||||
/*
|
||||
* Process this file (dnscrypt_config.h.in) with AC_CONFIG_FILES to generate
|
||||
* dnscrypt_config.h.
|
||||
*
|
||||
* This file exists so that USE_DNSCRYPT can be used without including config.h.
|
||||
*/
|
||||
|
||||
#if @ENABLE_DNSCRYPT@ /* ENABLE_DNSCRYPT */
|
||||
# ifndef USE_DNSCRYPT
|
||||
# define USE_DNSCRYPT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* UNBOUND_DNSCRYPT_CONFIG_H */
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
CERT_EXPIRE_DAYS="$(( 365 * 15 ))"
|
||||
DIR="$(dirname "$0")"
|
||||
|
||||
|
||||
if [[ "$PWD" != *tdir ]]
|
||||
then
|
||||
echo "You should run this script with a .tdir directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i in 1 2
|
||||
do
|
||||
# Ephemeral key
|
||||
rm -f "${i}.key"
|
||||
dnscrypt-wrapper --gen-crypt-keypair \
|
||||
--crypt-secretkey-file="${i}.key" \
|
||||
--provider-publickey-file="${DIR}/keys${i}/public.key" \
|
||||
--provider-secretkey-file="${DIR}/keys${i}/secret.key"
|
||||
# Cert file
|
||||
for cipher in salsa chacha
|
||||
do
|
||||
rm -f "${i}_${cipher}.cert"
|
||||
extraarg=""
|
||||
if [ "${cipher}" == "chacha" ]
|
||||
then
|
||||
extraarg="-x"
|
||||
fi
|
||||
|
||||
dnscrypt-wrapper ${extraarg} --gen-cert-file \
|
||||
--provider-cert-file="${i}_${cipher}.cert" \
|
||||
--crypt-secretkey-file="${i}.key" \
|
||||
--provider-publickey-file="${DIR}/keys${i}/public.key" \
|
||||
--provider-secretkey-file="${DIR}/keys${i}/secret.key" \
|
||||
--cert-file-expire-days="${CERT_EXPIRE_DAYS}"
|
||||
done
|
||||
done
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
¸_A¡O#÷ÛÈfó—ÌoD¶_�eŶ)|'T¦éÜòO�
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
-&ç6\Uùõñh`^"…ºz/C9‚
óˆ¸_A¡O#÷ÛÈfó—ÌoD¶_�eŶ)|'T¦éÜòO�
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
ΓR ς�ύeµτ{φl�ΑKΛ€Ξ:5r\±}KΣηƒ
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
ηi%‚ 5fΝ™–νΙϋ�νBnκΝ―.Ί“ΓR ς�ύeµτ{φl�ΑKΛ€Ξ:5r\±}KΣηƒ
|
||||
+56
-48
@@ -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,49 +115,46 @@ 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)
|
||||
{
|
||||
fstrm_res res;
|
||||
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)) {
|
||||
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
|
||||
cfg->dnstap_socket_path);
|
||||
check_socket_file(cfg->dnstap_socket_path);
|
||||
}
|
||||
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
fwopt = fstrm_writer_options_init();
|
||||
res = 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;
|
||||
}
|
||||
|
||||
@@ -248,19 +242,33 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
int
|
||||
dt_init(struct dt_env *env)
|
||||
{
|
||||
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
|
||||
if (env->ioq == NULL)
|
||||
env->msgqueue = dt_msg_queue_create();
|
||||
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);
|
||||
@@ -475,7 +483,7 @@ dt_msg_send_outside_response(struct dt_env *env,
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
|
||||
} else {
|
||||
if (!env->log_resolver_query_messages)
|
||||
if (!env->log_resolver_response_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE);
|
||||
}
|
||||
|
||||
+13
-9
@@ -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.
|
||||
@@ -107,6 +106,11 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
int
|
||||
dt_init(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* per-worker I/O queues.
|
||||
|
||||
+1
-8
@@ -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],
|
||||
@@ -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
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// with this file. If not, see:
|
||||
//
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
syntax = "proto2";
|
||||
|
||||
package dnstap;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
+2128
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
/** 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** 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.
|
||||
* @return NULL on malloc failure or a new queue (not locked).
|
||||
*/
|
||||
struct dt_msg_queue* dt_msg_queue_create(void);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
Binary file not shown.
+3380
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user