mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
542
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
039f276b0c | ||
|
|
44a28f4343 | ||
|
|
cffd76e6e4 | ||
|
|
54046475e7 | ||
|
|
caeebbf4fa | ||
|
|
521bd29041 | ||
|
|
9abe770f9e | ||
|
|
41a5b9efca | ||
|
|
980f3f10b7 | ||
|
|
83cf9d20c8 | ||
|
|
a4c7a739d9 | ||
|
|
c0093acd97 | ||
|
|
62ab524058 | ||
|
|
c56fdce932 | ||
|
|
502a542820 | ||
|
|
23af66982c | ||
|
|
a4a7894f79 | ||
|
|
5423af1836 | ||
|
|
e19f71ffa0 | ||
|
|
009b2d7c0b | ||
|
|
eb6253aa6c | ||
|
|
5bc9a80e40 | ||
|
|
6e8e4e87b7 | ||
|
|
ff33e077de | ||
|
|
9890caff91 | ||
|
|
45c07da4a0 | ||
|
|
7617c18be1 | ||
|
|
463d7e09c5 | ||
|
|
b3caa5ab37 | ||
|
|
479bebfff4 | ||
|
|
586893d761 | ||
|
|
07f5b21b7b | ||
|
|
4f1a72bb75 | ||
|
|
aa8a6eeadf | ||
|
|
bf8bc06860 | ||
|
|
1727bfc34e | ||
|
|
1d8013c67a | ||
|
|
5b66f07e38 | ||
|
|
81cfcd8053 | ||
|
|
8171793d2a | ||
|
|
9a08ad419e | ||
|
|
3b78d84a7e | ||
|
|
d3bc6d6b5a | ||
|
|
9bb3fdd547 | ||
|
|
f42d27e1a2 | ||
|
|
d7868e4077 | ||
|
|
2c33330994 | ||
|
|
7782cf2b97 | ||
|
|
a909fa9a3a | ||
|
|
e0b639accd | ||
|
|
ce45cbda6d | ||
|
|
6f37df3b92 | ||
|
|
b07370a4c2 | ||
|
|
1a02ab895b | ||
|
|
989a6f4f89 | ||
|
|
5ff6b1c5fb | ||
|
|
4d49d792c3 | ||
|
|
5d2e8e8e97 | ||
|
|
455c3d130d | ||
|
|
c43987e8e1 | ||
|
|
0679bf6502 | ||
|
|
35f077bc06 | ||
|
|
71959c05df | ||
|
|
1c75281303 | ||
|
|
5007a44e52 | ||
|
|
2043463b6a | ||
|
|
d59a8baec2 | ||
|
|
c467aabbf1 | ||
|
|
430a6bd697 | ||
|
|
ee1c4c1cce | ||
|
|
44e2f9b0d9 | ||
|
|
1f7304d146 | ||
|
|
9dc9f0a8e8 | ||
|
|
19ab8e1429 | ||
|
|
aff6654685 | ||
|
|
d0cef76cff | ||
|
|
82b8ddc9bb | ||
|
|
2588d76522 | ||
|
|
5d4249a6b0 | ||
|
|
2c134eb981 | ||
|
|
c4cfcdab6b | ||
|
|
75fbd42ca3 | ||
|
|
aae91da6d2 | ||
|
|
90b4b1dae9 | ||
|
|
795a25c117 | ||
|
|
45acda0535 | ||
|
|
9c822ebc9e | ||
|
|
165a235f4d | ||
|
|
46d341b036 | ||
|
|
7923a28c13 | ||
|
|
2e02003687 | ||
|
|
c611bbba3f | ||
|
|
b322353d8b | ||
|
|
7ccf79d42d | ||
|
|
d7dafa112b | ||
|
|
dcb11b2ee4 | ||
|
|
30d0bf14eb | ||
|
|
1f45bbbd63 | ||
|
|
3f68f01313 | ||
|
|
18e9cbb39f | ||
|
|
ca9c1fa2a8 | ||
|
|
310cbbc372 | ||
|
|
3bca178111 | ||
|
|
4774b8b129 | ||
|
|
e46441787c | ||
|
|
cd3a1ff351 | ||
|
|
e80d0936f3 | ||
|
|
41a29b050b | ||
|
|
37d8551a7a | ||
|
|
17ffb78b10 | ||
|
|
51ba9a4856 | ||
|
|
0fc43d4a62 | ||
|
|
e5cab7b264 | ||
|
|
8e2ef1caeb | ||
|
|
c7bea9d33a | ||
|
|
415236c002 | ||
|
|
0a35d358ee | ||
|
|
544b3f8428 | ||
|
|
9f9edf9ce6 | ||
|
|
eb3eb4f250 | ||
|
|
de7808f2e0 | ||
|
|
4f2461a124 | ||
|
|
a24f9ff9ea | ||
|
|
dafe1ae21b | ||
|
|
b8c4d7088d | ||
|
|
f974f7880b | ||
|
|
bad061a35a | ||
|
|
ba47856946 | ||
|
|
a1a71348bf | ||
|
|
e3b8b9bcea | ||
|
|
902323da2f | ||
|
|
b422db1c80 | ||
|
|
568253e4ff | ||
|
|
6b959f8043 | ||
|
|
ea36edbc03 | ||
|
|
0e7ff77cd2 | ||
|
|
012d05073b | ||
|
|
b93f679049 | ||
|
|
6770898042 | ||
|
|
e89cbd00fa | ||
|
|
b8a2dfb2c9 | ||
|
|
7d90b75ce8 | ||
|
|
0210f4ae41 | ||
|
|
d8e6209a2e | ||
|
|
4e176a0aa6 | ||
|
|
78ed2ec08a | ||
|
|
6f1f6dafb5 | ||
|
|
28be658942 | ||
|
|
ca94ca57b4 | ||
|
|
1e2111f593 | ||
|
|
0deef63323 | ||
|
|
701b4ccdd6 | ||
|
|
a8dccbdd40 | ||
|
|
c42056b9aa | ||
|
|
1cd84ce84e | ||
|
|
948567bea8 | ||
|
|
ed67590f74 | ||
|
|
21e791248f | ||
|
|
a85b563d37 | ||
|
|
3251765048 | ||
|
|
5ecf670277 | ||
|
|
df59a81a56 | ||
|
|
f3579ce5f2 | ||
|
|
f015b01072 | ||
|
|
01cd1823a4 | ||
|
|
0205e3ae29 | ||
|
|
48d786dcc8 | ||
|
|
538ca28828 | ||
|
|
b6076e3b6d | ||
|
|
783178c785 | ||
|
|
1f4222aa94 | ||
|
|
74abf6ced0 | ||
|
|
870b34a8ec | ||
|
|
75611ab90d | ||
|
|
49d65b8ebf | ||
|
|
6f4522a55c | ||
|
|
b97dbd3c8f | ||
|
|
112df5ab6c | ||
|
|
a134925d91 | ||
|
|
38bc0800ee | ||
|
|
dcea0777bf | ||
|
|
894ba681f0 | ||
|
|
72aa0bad92 | ||
|
|
f73ce55c6e | ||
|
|
658e84f7a0 | ||
|
|
f1bd145b60 | ||
|
|
b5f7bf86ac | ||
|
|
56d8c3d59d | ||
|
|
2b9e9b4111 | ||
|
|
d9a6ccfb52 | ||
|
|
cd5ac9634c | ||
|
|
b5f2b7d36b | ||
|
|
91e49260a7 | ||
|
|
a0d67a87f0 | ||
|
|
43d9c09372 | ||
|
|
e33276b5c3 | ||
|
|
630e83f58b | ||
|
|
ff77c81fd1 | ||
|
|
560e1c86b3 | ||
|
|
73da11fe07 | ||
|
|
7b03403efd | ||
|
|
902cad61c6 | ||
|
|
82f83d8d06 | ||
|
|
fa842c30de | ||
|
|
506af05011 | ||
|
|
f644c06516 | ||
|
|
9755c94372 | ||
|
|
f0138c1cca | ||
|
|
374a7f45c2 | ||
|
|
f3b66c177b | ||
|
|
d535e6919e | ||
|
|
0c7b289051 | ||
|
|
5decb468c2 | ||
|
|
5e90d568eb | ||
|
|
9e8a5100ad | ||
|
|
1dc1ffabb4 | ||
|
|
c299e49384 | ||
|
|
8595d94e0f | ||
|
|
bfceac5b2e | ||
|
|
b794eb84ac | ||
|
|
1cf8bdae51 | ||
|
|
1bc4092127 | ||
|
|
1e97b85e45 | ||
|
|
edae0ad954 | ||
|
|
d453b4a43b | ||
|
|
7bd415ffdd | ||
|
|
d232dbd4a5 | ||
|
|
373758092f | ||
|
|
b6406cae1e | ||
|
|
298aff3ad2 | ||
|
|
efee0803d0 | ||
|
|
ec30ae3ca6 | ||
|
|
4ead61eb63 | ||
|
|
206a6bb539 | ||
|
|
fb5fa2bdb1 | ||
|
|
8b2f5dcaf0 | ||
|
|
4d97a3a400 | ||
|
|
368dc659ea | ||
|
|
e49e0539d8 | ||
|
|
aec8f4644f | ||
|
|
6f745bc49e | ||
|
|
ef564b5a29 | ||
|
|
c1b2364d1d | ||
|
|
790fe91662 | ||
|
|
819f9d817a | ||
|
|
e0bc4f2c97 | ||
|
|
efcb61fb22 | ||
|
|
d94c548dab | ||
|
|
a18c4eaebc | ||
|
|
e92fd4ff33 | ||
|
|
7bd75483e1 | ||
|
|
573fd6652b | ||
|
|
13d2817b62 | ||
|
|
f39e5fe3a8 | ||
|
|
a569062627 | ||
|
|
a40ec4b935 | ||
|
|
427ddba6d7 | ||
|
|
b757b29910 | ||
|
|
3898abde02 | ||
|
|
8466ac7e7f | ||
|
|
80f6ed2ff0 | ||
|
|
19d72a41cb | ||
|
|
07411c16a9 | ||
|
|
5ca6d8c50b | ||
|
|
16e920f416 | ||
|
|
89f0fd7252 | ||
|
|
a40ec010be | ||
|
|
1b8519e619 | ||
|
|
add0079981 | ||
|
|
2c56564e4e | ||
|
|
baaaae857a | ||
|
|
b6099d5f55 | ||
|
|
8c36960c29 | ||
|
|
3c5c0b2727 | ||
|
|
6dd6542f04 | ||
|
|
6451748967 | ||
|
|
b2ff49e4c4 | ||
|
|
38ec4f4777 | ||
|
|
413d579e58 | ||
|
|
3494191250 | ||
|
|
4b449309e5 | ||
|
|
71b6537666 | ||
|
|
886721c060 | ||
|
|
cdb2726e68 | ||
|
|
caaa90a200 | ||
|
|
5e2189bb35 | ||
|
|
7758098250 | ||
|
|
b86b9f7fdc | ||
|
|
daf63c7e89 | ||
|
|
578c1632ce | ||
|
|
37f403955b | ||
|
|
dd42c84b5e | ||
|
|
ffe442608c | ||
|
|
21389820a7 | ||
|
|
1562a13332 | ||
|
|
ea0148caf8 | ||
|
|
8cc8261947 | ||
|
|
7c2813eb82 | ||
|
|
81023e116d | ||
|
|
5cacd20a6e | ||
|
|
1aedf47ebe | ||
|
|
d75777ec63 | ||
|
|
d1a27b6d34 | ||
|
|
dd7f5cc718 | ||
|
|
718e235a47 | ||
|
|
9f1ee24abb | ||
|
|
6a152952bf | ||
|
|
f3d98d17f4 | ||
|
|
9ea5b16bae | ||
|
|
f32d07786a | ||
|
|
7138a4cf42 | ||
|
|
53a026eb4e | ||
|
|
768c4b2643 | ||
|
|
3eda6e26ff | ||
|
|
54bd0fff06 | ||
|
|
4ad2eb2549 | ||
|
|
bfe96b89f0 | ||
|
|
3b386055c7 | ||
|
|
5a9dcd323d | ||
|
|
3ee3492095 | ||
|
|
1e1ac9900a | ||
|
|
397985b2c8 | ||
|
|
93f6117ab2 | ||
|
|
f46febcc97 | ||
|
|
d745581dbd | ||
|
|
62fca9e1fb | ||
|
|
ac9c3b84b1 | ||
|
|
49913a1c9e | ||
|
|
5445bf72ba | ||
|
|
1fa1c9d1b1 | ||
|
|
af102d24ce | ||
|
|
a5c428bb8d | ||
|
|
445f8a4e22 | ||
|
|
a5c76d0579 | ||
|
|
db94e389da | ||
|
|
c3bf9f1bb3 | ||
|
|
3322c9e141 | ||
|
|
2e20c86309 | ||
|
|
0b4fe963d5 | ||
|
|
7ad28caa41 | ||
|
|
c6da8de517 | ||
|
|
c1f4b92026 | ||
|
|
f9aeb8904d | ||
|
|
64e3db1f04 | ||
|
|
a12dcdcdc4 | ||
|
|
d369a1ac48 | ||
|
|
3a7f86982e | ||
|
|
6803b9461f | ||
|
|
868df9f584 | ||
|
|
7dcca025f4 | ||
|
|
e0cd16b38c | ||
|
|
ebd14d9f35 | ||
|
|
31ec67fcce | ||
|
|
11f11a5377 | ||
|
|
0799d77798 | ||
|
|
910167b38c | ||
|
|
60f4826ff7 | ||
|
|
a87d222547 | ||
|
|
25467d37e3 | ||
|
|
faf17d6e86 | ||
|
|
0f3e00e3a6 | ||
|
|
eaff1bdeb5 | ||
|
|
d8b8eabeac | ||
|
|
e5c414355e | ||
|
|
dbf9f42142 | ||
|
|
a30d1f9f20 | ||
|
|
ee8465d887 | ||
|
|
00170dfa41 | ||
|
|
912db8d277 | ||
|
|
d0c6177f44 | ||
|
|
5069af975f | ||
|
|
b0ef703c1b | ||
|
|
c154c6b7b4 | ||
|
|
2978e72596 | ||
|
|
6e9d768c6c | ||
|
|
d8392b01d3 | ||
|
|
f861f19843 | ||
|
|
97a73402fc | ||
|
|
41e589b08b | ||
|
|
cfd739e2eb | ||
|
|
bcd6fee1f4 | ||
|
|
6355d45e70 | ||
|
|
76c0cb3913 | ||
|
|
116e9d9d8d | ||
|
|
61135d1456 | ||
|
|
5f27e00a19 | ||
|
|
0d575036cb | ||
|
|
afe9d4bb67 | ||
|
|
159d59a3dc | ||
|
|
ac4535d4e5 | ||
|
|
8c2d5d42d9 | ||
|
|
363a4712b2 | ||
|
|
c02fd13138 | ||
|
|
e4c5af61c6 | ||
|
|
254e6ec34f | ||
|
|
47d7fd59ca | ||
|
|
6015524e34 | ||
|
|
80ef8e2f7e | ||
|
|
157c7cde0d | ||
|
|
1947f8cbb1 | ||
|
|
541ca65c9c | ||
|
|
53b51dbdef | ||
|
|
7de3900654 | ||
|
|
208e698306 | ||
|
|
eafa979e0f | ||
|
|
97a3830515 | ||
|
|
2bf8d9b4b2 | ||
|
|
a9754e0727 | ||
|
|
1811270c68 | ||
|
|
f30fc9133c | ||
|
|
7a2c1c8d47 | ||
|
|
fef17eadb6 | ||
|
|
840d7fd34f | ||
|
|
ae866b00a9 | ||
|
|
0acf55404c | ||
|
|
ffe0bd51d8 | ||
|
|
c2261b63f1 | ||
|
|
23ab46e3a5 | ||
|
|
84edc1428b | ||
|
|
e6fbf88b59 | ||
|
|
4b2d6d20af | ||
|
|
f6b2f66311 | ||
|
|
b67ed83149 | ||
|
|
ce71720093 | ||
|
|
8b31d0b2e0 | ||
|
|
cf068986ff | ||
|
|
c699ba2c40 | ||
|
|
340eb440da | ||
|
|
a2dcd9c019 | ||
|
|
dfef08c21f | ||
|
|
df8005ff3c | ||
|
|
8148211e53 | ||
|
|
ca09b7014b | ||
|
|
e5a5749603 | ||
|
|
95f5b577d4 | ||
|
|
205f6d1afc | ||
|
|
cf64f7ae9e | ||
|
|
5f6eb6d58e | ||
|
|
5c0e815e73 | ||
|
|
b182b66e0e | ||
|
|
b58159d34b | ||
|
|
36b3f6e254 | ||
|
|
e00e0ddd2f | ||
|
|
e0a3873245 | ||
|
|
81d095149c | ||
|
|
63d3cb7ff4 | ||
|
|
0007337afe | ||
|
|
c53328dd07 | ||
|
|
cb925371ef | ||
|
|
fb436db87a | ||
|
|
2b873f1b57 | ||
|
|
2705aaaad9 | ||
|
|
00fe7f1b87 | ||
|
|
a63515ba51 | ||
|
|
46a9e9cba4 | ||
|
|
b22145d504 | ||
|
|
6e0d34659b | ||
|
|
80fa6c037a | ||
|
|
af9c45effc | ||
|
|
78600ddee1 | ||
|
|
dfcbd8cb48 | ||
|
|
b59ec4d4d3 | ||
|
|
eb408dcbc8 | ||
|
|
87603429a1 | ||
|
|
cc6375e909 | ||
|
|
d1e812a4af | ||
|
|
7ac31bc1d5 | ||
|
|
37c3bef544 | ||
|
|
7ca106cc8c | ||
|
|
45abfa8720 | ||
|
|
ce2067ec6b | ||
|
|
0b04be414e | ||
|
|
c90fd40a5e | ||
|
|
bea2b17277 | ||
|
|
dee84257a1 | ||
|
|
b33f5f66ec | ||
|
|
a46c9197c4 | ||
|
|
bfc64ade3c | ||
|
|
900142fb79 | ||
|
|
5aa65f431b | ||
|
|
f8655d2f5b | ||
|
|
a3ff369cfd | ||
|
|
c76429ab57 | ||
|
|
0a9116f856 | ||
|
|
9f4a9249c6 | ||
|
|
8b860e8f12 | ||
|
|
c41e1a09ab | ||
|
|
59c1ec5a95 | ||
|
|
0b39c4232f | ||
|
|
bcb13a174b | ||
|
|
d525f6ab69 | ||
|
|
f89c4c4774 | ||
|
|
5326670faf | ||
|
|
244a09bfa3 | ||
|
|
2b7969bc84 | ||
|
|
f3d116387d | ||
|
|
e6c5255466 | ||
|
|
6e9d214816 | ||
|
|
c1ae463da5 | ||
|
|
865852d3f7 | ||
|
|
4eb2bdf2b1 | ||
|
|
062ad0eb69 | ||
|
|
ca89f7290c | ||
|
|
33ae9fd843 | ||
|
|
4c76f1c003 | ||
|
|
ccdc0e3c53 | ||
|
|
9cb69874f6 | ||
|
|
12aae4fd6f | ||
|
|
1bdf2b2b6a | ||
|
|
159c7e4d6c | ||
|
|
38d57b0f80 | ||
|
|
666b066bf6 | ||
|
|
d714dfe8d8 | ||
|
|
340a6185d2 | ||
|
|
d00c045084 | ||
|
|
d090698555 | ||
|
|
11f61b6b26 | ||
|
|
4b00c5f76b | ||
|
|
31ffc5a6a9 | ||
|
|
aa1b565b41 | ||
|
|
3d3b875a70 | ||
|
|
3d42b1fffa | ||
|
|
3e8ccb027f | ||
|
|
05643589cf | ||
|
|
b616c4f833 | ||
|
|
cb4985f527 | ||
|
|
098f932df8 | ||
|
|
4ac7881829 | ||
|
|
bcf49eaf96 | ||
|
|
9e96c6e3aa | ||
|
|
9a9f012352 | ||
|
|
386ff5debe | ||
|
|
d7ee842525 | ||
|
|
ea1f00ebad | ||
|
|
b1ed30d5f4 | ||
|
|
aa0f26e3fa | ||
|
|
9e21fb7fac | ||
|
|
8b919a3780 | ||
|
|
32f6afbb48 | ||
|
|
576fe7d4c8 | ||
|
|
27f450e8fa | ||
|
|
ecad71c519 |
+156
-51
@@ -2,10 +2,14 @@
|
||||
# See the file LICENSE for the license
|
||||
|
||||
debug_enabled=@debug_enabled@
|
||||
ifeq "$(QUIET)" ""
|
||||
ifeq ($(debug_enabled),yes)
|
||||
QUIET=yes
|
||||
LIBTOOLQUIET=yes
|
||||
else
|
||||
QUIET=no
|
||||
LIBTOOLQUIET=yes
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq "$(QUIET)" "yes"
|
||||
@@ -33,39 +37,56 @@ doxygen=@doxygen@
|
||||
libtool=@libtool@
|
||||
ldnsdir=@ldnsdir@
|
||||
staticexe=@staticexe@
|
||||
EXEEXT=@EXEEXT@
|
||||
configfile=@ub_conf_file@
|
||||
UNBOUND_RUN_DIR=@UNBOUND_RUN_DIR@
|
||||
CHECKLOCK_SRC=@CHECKLOCK_SRC@
|
||||
UB_ON_WINDOWS=@UB_ON_WINDOWS@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
WITH_PYUNBOUND=@WITH_PYUNBOUND@
|
||||
PYTHON_SITE_PKG=@PYTHON_SITE_PKG@
|
||||
|
||||
SWIG=@SWIG@
|
||||
YACC=@YACC@
|
||||
LEX=@LEX@
|
||||
STRIP=@STRIP@
|
||||
CC=@CC@
|
||||
CPPFLAGS=-I$(srcdir) -I. @CPPFLAGS@ @DEFS@
|
||||
CPPFLAGS=-I. @CPPFLAGS@
|
||||
ifneq "$(srcdir)" "."
|
||||
CPPFLAGS:=-I$(srcdir) $(CPPFLAGS)
|
||||
endif
|
||||
CPPFLAGS:=$(strip $(CPPFLAGS))
|
||||
CFLAGS=@CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBS=@LIBS@
|
||||
LIBS=$(strip @LIBS@)
|
||||
LIBOBJS=@LIBOBJS@
|
||||
RUNTIME_PATH=@RUNTIME_PATH@
|
||||
DEPFLAG=@DEPFLAG@
|
||||
DATE=$(shell date +%Y%m%d)
|
||||
LIBTOOL=$(libtool)
|
||||
ifeq "$(QUIET)" "yes"
|
||||
ifeq "$(LIBTOOLQUIET)" "yes"
|
||||
LIBTOOL+=--quiet
|
||||
endif
|
||||
BUILD=build/
|
||||
|
||||
WINDRES=@WINDRES@
|
||||
LINT=splint
|
||||
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list
|
||||
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -Dglob64=glob -Dglobfree64=globfree
|
||||
# compat with openssl linux edition.
|
||||
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned
|
||||
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray
|
||||
|
||||
INSTALL=$(srcdir)/install-sh
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
PYTHONMOD_SRC=$(srcdir)/pythonmod/*.c
|
||||
endif
|
||||
|
||||
COMMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/services/*.c \
|
||||
$(srcdir)/services/cache/*.c $(srcdir)/util/*.c \
|
||||
$(srcdir)/util/data/*.c $(srcdir)/util/storage/*.c \
|
||||
$(srcdir)/iterator/*.c $(srcdir)/validator/*.c)) \
|
||||
$(srcdir)/iterator/*.c $(srcdir)/validator/*.c $(PYTHONMOD_SRC))) \
|
||||
util/configparser.c util/configlexer.c $(CHECKLOCK_SRC)
|
||||
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.lo))
|
||||
COMPAT_SRC=$(addprefix compat/,$(LIBOBJS:.o=.c))
|
||||
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS:.o=.lo))
|
||||
UNITTEST_SRC=$(patsubst $(srcdir)/%,%, \
|
||||
$(wildcard $(srcdir)/testcode/unit*.c)) \
|
||||
@@ -95,7 +116,7 @@ SIGNIT_SRC=testcode/signit.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
MEMSTATS_SRC=testcode/memstats.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
ASYNCLOOK_SRC=testcode/asynclook.c
|
||||
ASYNCLOOK_SRC=testcode/asynclook.c util/log.c util/locks.c
|
||||
ASYNCLOOK_OBJ=$(addprefix $(BUILD),$(ASYNCLOOK_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
STREAMTCP_SRC=testcode/streamtcp.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
STREAMTCP_OBJ=$(addprefix $(BUILD),$(STREAMTCP_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
@@ -116,9 +137,39 @@ ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.lo) \
|
||||
$(addprefix compat/,$(LIBOBJS:.o=.lo))) $(COMPAT_OBJ)
|
||||
|
||||
ifeq "$(UB_ON_WINDOWS)" "yes"
|
||||
DAEMON_SRC+=winrc/win_svc.c winrc/w_inst.c
|
||||
DAEMON_OBJ+=$(BUILD)winrc/rsrc_unbound.o $(BUILD)winrc/win_svc.lo
|
||||
HOST_OBJ+=$(BUILD)winrc/rsrc_unbound_host.o
|
||||
CONTROL_OBJ+=$(BUILD)winrc/rsrc_unbound_control.o
|
||||
CHECKCONF_OBJ+=$(BUILD)winrc/rsrc_unbound_checkconf.o
|
||||
|
||||
WINAPPS=$(addsuffix $(EXEEXT), unbound-service-install \
|
||||
unbound-service-remove anchor-update)
|
||||
COMPAT_WINAPP=$(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
SVCINST_SRC=winrc/unbound-service-install.c winrc/w_inst.c
|
||||
SVCINST_OBJ=$(addprefix $(BUILD),$(SVCINST_SRC:.c=.lo)) $(COMPAT_WINAPP) \
|
||||
$(BUILD)winrc/rsrc_svcinst.o
|
||||
SVCUNINST_SRC=winrc/unbound-service-remove.c winrc/w_inst.c
|
||||
SVCUNINST_OBJ=$(addprefix $(BUILD),$(SVCUNINST_SRC:.c=.lo)) $(COMPAT_WINAPP) \
|
||||
$(BUILD)winrc/rsrc_svcuninst.o
|
||||
ANCHORUPD_SRC=winrc/anchor-update.c
|
||||
ANCHORUPD_OBJ=$(addprefix $(BUILD),$(ANCHORUPD_SRC:.c=.lo)) $(COMPAT_WINAPP) \
|
||||
$(BUILD)winrc/rsrc_anchorupd.o
|
||||
ALL_SRC:=$(sort $(ALL_SRC) $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC))
|
||||
ALL_OBJ:=$(sort $(ALL_OBJ) $(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ))
|
||||
|
||||
$(BUILD)%.o: $(srcdir)/%.rc $(srcdir)/config.h
|
||||
$(INFO) Resource $<
|
||||
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
|
||||
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(WINDRES) $(CPPFLAGS) $< $@
|
||||
endif
|
||||
|
||||
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS)
|
||||
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined
|
||||
LINK=$(LIBTOOL) --tag=CC --mode=link $(strip $(CC) $(staticexe) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS))
|
||||
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(strip $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined)
|
||||
|
||||
.PHONY: clean realclean doc lint all install uninstall tests test download_ldns strip lib
|
||||
|
||||
@@ -127,12 +178,12 @@ $(BUILD)%.lo: $(srcdir)/%.c
|
||||
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
|
||||
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(COMPILE) -c $< -o $@
|
||||
$Q$(COMPILE) -o $@ -c $<
|
||||
|
||||
all: $(COMMON_OBJ) unbound unbound-checkconf lib unbound-host unbound-control unbound-control-setup
|
||||
all: $(COMMON_OBJ) unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup $(WINAPPS)
|
||||
|
||||
TEST_BIN=asynclook delayer harvest lock-verify memstats perf pktview signit \
|
||||
streamtcp testbound unittest
|
||||
TEST_BIN=$(addsuffix $(EXEEXT),asynclook delayer harvest lock-verify \
|
||||
memstats perf pktview signit streamtcp testbound unittest)
|
||||
tests: all $(TEST_BIN)
|
||||
|
||||
test: tests
|
||||
@@ -140,76 +191,89 @@ test: tests
|
||||
|
||||
lib: libunbound.la
|
||||
|
||||
libunbound.la: $(LIBUNBOUND_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK_LIB) --export-symbols $(srcdir)/libunbound/ubsyms.def -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
|
||||
ifeq ($(patsubst ldns-src%,ldns-src,$(ldnsdir)),ldns-src)
|
||||
ldnslib=$(ldnsdir)/lib/libldns.a
|
||||
$(ldnslib):
|
||||
$(ldnslib): $(ldnsdir)/lib
|
||||
$(ldnsdir)/lib:
|
||||
@if test ! -z "$(ldnsdir)"; \
|
||||
then (cd $(ldnsdir) && $(MAKE)); fi
|
||||
else
|
||||
ldnslib=
|
||||
endif
|
||||
|
||||
unbound: $(DAEMON_OBJ) $(ldnslib)
|
||||
libunbound.la: $(LIBUNBOUND_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK_LIB) -export-symbols $(srcdir)/libunbound/ubsyms.def -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(DAEMON_OBJ)) -lssl $(LIBS)
|
||||
|
||||
unbound-checkconf: $(CHECKCONF_OBJ) $(ldnslib)
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(CHECKCONF_OBJ)) $(LIBS)
|
||||
|
||||
unbound-control: $(CONTROL_OBJ) $(ldnslib)
|
||||
unbound-control$(EXEEXT): $(CONTROL_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(CONTROL_OBJ)) -lssl $(LIBS)
|
||||
|
||||
unbound-host: $(HOST_OBJ) libunbound.la $(ldnslib)
|
||||
unbound-host$(EXEEXT): $(HOST_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(HOST_OBJ)) -L. -L.libs -lunbound $(LIBS)
|
||||
|
||||
unittest: $(UNITTEST_OBJ) $(ldnslib)
|
||||
unbound-service-install$(EXEEXT): $(SVCINST_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(SVCINST_OBJ)) $(LIBS)
|
||||
|
||||
unbound-service-remove$(EXEEXT): $(SVCUNINST_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(SVCUNINST_OBJ)) $(LIBS)
|
||||
|
||||
anchor-update$(EXEEXT): $(ANCHORUPD_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(ANCHORUPD_OBJ)) -L. -L.libs -lunbound $(LIBS)
|
||||
|
||||
unittest$(EXEEXT): $(UNITTEST_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(UNITTEST_OBJ)) $(LIBS)
|
||||
|
||||
testbound: $(TESTBOUND_OBJ) $(ldnslib)
|
||||
testbound$(EXEEXT): $(TESTBOUND_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(TESTBOUND_OBJ)) -lssl $(LIBS)
|
||||
|
||||
lock-verify: $(LOCKVERIFY_OBJ) $(ldnslib)
|
||||
lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(LOCKVERIFY_OBJ)) $(LIBS)
|
||||
|
||||
pktview: $(PKTVIEW_OBJ) $(ldnslib)
|
||||
pktview$(EXEEXT): $(PKTVIEW_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(PKTVIEW_OBJ)) $(LIBS)
|
||||
|
||||
signit: $(SIGNIT_OBJ) $(ldnslib)
|
||||
signit$(EXEEXT): $(SIGNIT_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(SIGNIT_OBJ)) $(LIBS)
|
||||
|
||||
memstats: $(MEMSTATS_OBJ) $(ldnslib)
|
||||
memstats$(EXEEXT): $(MEMSTATS_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(MEMSTATS_OBJ)) $(LIBS)
|
||||
|
||||
asynclook: $(ASYNCLOOK_OBJ) $(ldnslib) libunbound.la
|
||||
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ) $(ldnslib) libunbound.la
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(ASYNCLOOK_OBJ)) $(LIBS) -L. -L.libs -lunbound
|
||||
|
||||
streamtcp: $(STREAMTCP_OBJ) $(ldnslib)
|
||||
streamtcp$(EXEEXT): $(STREAMTCP_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(STREAMTCP_OBJ)) $(LIBS)
|
||||
|
||||
perf: $(PERF_OBJ) $(ldnslib)
|
||||
perf$(EXEEXT): $(PERF_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(PERF_OBJ)) $(LIBS)
|
||||
|
||||
delayer: $(DELAYER_OBJ) $(ldnslib)
|
||||
delayer$(EXEEXT): $(DELAYER_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(DELAYER_OBJ)) $(LIBS)
|
||||
|
||||
harvest: $(HARVEST_OBJ) $(ldnslib) libunbound.la
|
||||
harvest$(EXEEXT): $(HARVEST_OBJ) $(ldnslib) libunbound.la
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(HARVEST_OBJ)) $(LIBS) -L. -L.libs -lunbound
|
||||
|
||||
@@ -223,6 +287,26 @@ unbound-control-setup: $(srcdir)/smallapp/unbound-control-setup.sh
|
||||
# cp $(ldnsdir)/examples/ldns-testpkts.c testcode/ldns-testpkts.c
|
||||
# cp $(ldnsdir)/examples/ldns-testpkts.h testcode/ldns-testpkts.h
|
||||
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
$(srcdir)/pythonmod/pythonmod.c: pythonmod/interface.h
|
||||
%.h: $(srcdir)/%.i $(srcdir)/config.h
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$(INFO) Swig $<
|
||||
$Q$(SWIG) $(CPPFLAGS) -o $@ -python $<
|
||||
endif
|
||||
|
||||
ifeq "$(WITH_PYUNBOUND)" "yes"
|
||||
libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i $(srcdir)/libunbound/unbound.h
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$(INFO) Swig $<
|
||||
$Q$(SWIG) -python -o $@ $(CPPFLAGS) $<
|
||||
|
||||
all: _unbound.la
|
||||
_unbound.la: $(BUILD)libunbound/python/libunbound_wrap.lo libunbound.la
|
||||
$(INFO) Link $@
|
||||
$Q$(LIBTOOL) --tag=CC --mode=link $(strip $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS) -module -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined) -o $@ $< -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS)
|
||||
endif
|
||||
|
||||
util/config_file.c: util/configparser.h
|
||||
util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
|
||||
$(INFO) Lex $<
|
||||
@@ -230,7 +314,8 @@ ifeq "$(strip $(LEX))" ":"
|
||||
$Qecho "rebuild lexer, but no lex program, skipped"
|
||||
else
|
||||
@-if test ! -d util; then $(INSTALL) -d util; fi
|
||||
$Qecho "#include \"util/configyyrename.h\"" > $@
|
||||
$Qecho "#include \"config.h\"" > $@
|
||||
$Qecho "#include \"util/configyyrename.h\"" >> $@
|
||||
$Q$(LEX) -t $< >> $@
|
||||
endif
|
||||
|
||||
@@ -241,8 +326,8 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound unbound-checkconf unbound-host unbound-control unbound-control-setup libunbound.la
|
||||
rm -rf autom4te.cache .libs build doc/html
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup libunbound.la
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
|
||||
realclean: clean
|
||||
rm -f config.status config.log config.h.in config.h
|
||||
@@ -266,12 +351,18 @@ tags: $(srcdir)/*.[ch] $(srcdir)/*/*.[ch]
|
||||
doc:
|
||||
if test -n "$(doxygen)"; then \
|
||||
$(doxygen) $(srcdir)/doc/unbound.doxygen; fi
|
||||
ifeq "$(findstring yes,$(WITH_PYUNBOUND)$(WITH_PYTHONMODULE))" "yes"
|
||||
if test -x "`which sphinx-build 2>&1`"; then \
|
||||
sphinx-build -b html pythonmod/doc doc/html/pythonmod; \
|
||||
sphinx-build -b html libunbound/python/doc doc/html/pyunbound;\
|
||||
fi
|
||||
endif
|
||||
|
||||
strip:
|
||||
strip unbound
|
||||
strip unbound-checkconf
|
||||
strip unbound-control
|
||||
strip unbound-host
|
||||
$(STRIP) unbound$(EXEEXT)
|
||||
$(STRIP) unbound-checkconf$(EXEEXT)
|
||||
$(STRIP) unbound-control$(EXEEXT)
|
||||
$(STRIP) unbound-host$(EXEEXT)
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
||||
@@ -282,10 +373,19 @@ install:
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
|
||||
$(LIBTOOL) --mode=install cp unbound $(DESTDIR)$(sbindir)/unbound
|
||||
$(LIBTOOL) --mode=install cp unbound-checkconf $(DESTDIR)$(sbindir)/unbound-checkconf
|
||||
$(LIBTOOL) --mode=install cp unbound-control $(DESTDIR)$(sbindir)/unbound-control
|
||||
$(LIBTOOL) --mode=install cp unbound-host $(DESTDIR)$(sbindir)/unbound-host
|
||||
$(LIBTOOL) --mode=install cp unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT)
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
|
||||
$(INSTALL) -c -m 644 pythonmod/unboundmodule.py $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
|
||||
endif
|
||||
ifeq "$(WITH_PYUNBOUND)" "yes"
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
|
||||
$(INSTALL) -c -m 644 libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
|
||||
$(LIBTOOL) --mode=install cp _unbound.la $(DESTDIR)$(PYTHON_SITE_PKG)
|
||||
endif
|
||||
$(INSTALL) -c -m 644 doc/unbound.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-checkconf.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-control.8 $(DESTDIR)$(mandir)/man8
|
||||
@@ -299,19 +399,26 @@ install:
|
||||
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||
|
||||
uninstall:
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound $(DESTDIR)$(sbindir)/unbound-checkconf $(DESTDIR)$(sbindir)/unbound-host $(DESTDIR)$(sbindir)/unbound-control $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8
|
||||
rm -f -- $(DESTDIR)$(mandir)/man1/unbound-host.1 $(DESTDIR)$(mandir)/man3/libunbound.3
|
||||
rm -f -- $(DESTDIR)$(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
|
||||
endif
|
||||
ifeq "$(WITH_PYUNBOUND)" "yes"
|
||||
rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(PYTHON_SITE_PKG)/_unbound.la
|
||||
endif
|
||||
@echo
|
||||
@echo "You still need to remove "`dirname $(DESTDIR)$(configfile)`" , $(DESTDIR)$(configfile) by hand"
|
||||
|
||||
download_ldns:
|
||||
svn export https://www.nlnetlabs.nl/svn/ldns/trunk/makedist.sh ldns_makedist.sh
|
||||
./ldns_makedist.sh -s -d https://www.nlnetlabs.nl/svn/ldns/trunk
|
||||
mv ldns-*_pre_*.tar.gz ldns-src.tar.gz
|
||||
rm ldns-*_pre_*.tar.gz.sha1 ldns_makedist.sh
|
||||
mv ldns-[0-9]*.tar.gz ldns-src.tar.gz
|
||||
rm ldns-*.tar.gz.sha1 ldns_makedist.sh
|
||||
|
||||
iana_update:
|
||||
curl -o port-numbers.tmp http://www.iana.org/assignments/port-numbers
|
||||
@@ -325,14 +432,12 @@ $(BUILD)%.d: $(srcdir)/%.c
|
||||
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
|
||||
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $(CFLAGS) $< \
|
||||
| sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.lo $@ : !g'\'' > $@; \
|
||||
[ -s $@ ] || rm -f $@'
|
||||
$Q$(SHELL) -ec '$(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) $< | sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.lo $@ : !g'\'' > $@; [ -s $@ ] || rm -f $@'
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),realclean)
|
||||
ifeq ($(debug_enabled),yes)
|
||||
-include $(addprefix $(BUILD),$(ALL_SRC:.c=.d))
|
||||
-include $(addprefix $(BUILD),$(ALL_SRC:.c=.d) $(COMPAT_SRC:.c=.d))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -2,8 +2,9 @@ Unbound README
|
||||
* ./configure && make && make install
|
||||
* on BSDs and Solaris use gmake (GNU make).
|
||||
* You can use libevent if you want. libevent is useful when using
|
||||
many (10000) outgoing ports. By default 16 ports are used and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
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.
|
||||
* More detailed README, README.svn, README.tests in doc directory
|
||||
* manual pages can be found in doc directory, and are installed, unbound(8).
|
||||
* example configuration file doc/example.conf
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
# ===========================================================================
|
||||
# http://autoconf-archive.cryp.to/ac_pkg_swig.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AC_PROG_SWIG([major.minor.micro])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro searches for a SWIG installation on your system. If found you
|
||||
# should call SWIG via $(SWIG). You can use the optional first argument to
|
||||
# check if the version of the available SWIG is greater than or equal to
|
||||
# the value of the argument. It should have the format: N[.N[.N]] (N is a
|
||||
# number between 0 and 999. Only the first N is mandatory.)
|
||||
#
|
||||
# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
|
||||
# the swig package is this version number or higher.
|
||||
#
|
||||
# In configure.in, use as:
|
||||
#
|
||||
# AC_PROG_SWIG(1.3.17)
|
||||
# SWIG_ENABLE_CXX
|
||||
# SWIG_MULTI_MODULE_SUPPORT
|
||||
# SWIG_PYTHON
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2008-04-12
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
|
||||
# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
|
||||
# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Macro Archive. When you make and
|
||||
# distribute a modified version of the Autoconf Macro, you may extend this
|
||||
# special exception to the GPL to apply to your modified version as well.
|
||||
|
||||
AC_DEFUN([AC_PROG_SWIG],[
|
||||
AC_PATH_PROG([SWIG],[swig])
|
||||
if test -z "$SWIG" ; then
|
||||
AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
|
||||
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
|
||||
elif test -n "$1" ; then
|
||||
AC_MSG_CHECKING([for SWIG version])
|
||||
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
|
||||
AC_MSG_RESULT([$swig_version])
|
||||
if test -n "$swig_version" ; then
|
||||
# Calculate the required version number components
|
||||
[required=$1]
|
||||
[required_major=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_major" ; then
|
||||
[required_major=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_minor" ; then
|
||||
[required_minor=0]
|
||||
fi
|
||||
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
|
||||
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_patch" ; then
|
||||
[required_patch=0]
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
[available=$swig_version]
|
||||
[available_major=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_major" ; then
|
||||
[available_major=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_minor" ; then
|
||||
[available_minor=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
|
||||
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
|
||||
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
|
||||
AC_MSG_NOTICE([SWIG executable is '$SWIG'])
|
||||
SWIG_LIB=`$SWIG -swiglib`
|
||||
AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([cannot determine SWIG version])
|
||||
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([SWIG_LIB])
|
||||
])
|
||||
Vendored
+5344
-3963
File diff suppressed because it is too large
Load Diff
+1207
File diff suppressed because it is too large
Load Diff
+200
@@ -0,0 +1,200 @@
|
||||
AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
|
||||
version to use, for example '2.3'. This string
|
||||
will be appended to the Python interpreter
|
||||
canonical name.])
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
if test -z "$PYTHON_VERSION"; then
|
||||
PYTHON_VERSION=`$PYTHON -c "import sys, string; \
|
||||
print string.split(sys.version)[[0]]"`
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver >= '2.1.0'"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
#
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver $1"`
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# 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
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([cannot import Python module "distutils".
|
||||
Please check your Python installation. The error was:
|
||||
$ac_distutils_result])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for Python include path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
if test -z "$PYTHON_CPPFLAGS"; then
|
||||
python_path=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_inc();"`
|
||||
if test -n "${python_path}"; then
|
||||
python_path="-I$python_path"
|
||||
fi
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
py_version=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print join(get_config_vars('VERSION'))"`
|
||||
if test "$py_version" = "[None]"; then
|
||||
if test -n "$PYTHON_VERSION"; then
|
||||
py_version=$PYTHON_VERSION
|
||||
else
|
||||
py_version=`$PYTHON -c "import sys; \
|
||||
print sys.version[[:3]]"`
|
||||
fi
|
||||
fi
|
||||
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print '-L' + get_python_lib(0,1), \
|
||||
'-L' + os.path.dirname(get_python_lib(0,1)), \
|
||||
'-lpython';"`$py_version
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
|
||||
print distutils.sysconfig.get_python_lib(0,0);"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_SITE_PKG])
|
||||
AC_SUBST([PYTHON_SITE_PKG])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS'), conf('LIBS')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LINKFORSHARED')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
||||
AC_LANG_PUSH([C])
|
||||
# save current global flags
|
||||
LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_TRY_LINK([
|
||||
#include <Python.h>
|
||||
],[
|
||||
Py_Initialize();
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
if test ! "$pythonexists" = "yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
AC_LANG_POP
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
|
||||
#
|
||||
# all done!
|
||||
#
|
||||
])
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* taken from ldns 1.6.1 */
|
||||
#include "config.h"
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
|
||||
/** the lock for ctime buffer */
|
||||
static lock_basic_t ctime_lock;
|
||||
/** has it been inited */
|
||||
static int ctime_r_init = 0;
|
||||
|
||||
/** cleanup ctime_r on exit */
|
||||
static void
|
||||
ctime_r_cleanup(void)
|
||||
{
|
||||
if(ctime_r_init) {
|
||||
ctime_r_init = 0;
|
||||
lock_basic_destroy(&ctime_lock);
|
||||
}
|
||||
}
|
||||
|
||||
char *ctime_r(const time_t *timep, char *buf)
|
||||
{
|
||||
char* result;
|
||||
if(!ctime_r_init) {
|
||||
/* still small race where this init can be done twice,
|
||||
* which is mostly harmless */
|
||||
ctime_r_init = 1;
|
||||
lock_basic_init(&ctime_lock);
|
||||
atexit(&ctime_r_cleanup);
|
||||
}
|
||||
lock_basic_lock(&ctime_lock);
|
||||
result = ctime(timep);
|
||||
if(buf && result)
|
||||
strcpy(buf, result);
|
||||
lock_basic_unlock(&ctime_lock);
|
||||
return result;
|
||||
}
|
||||
+2
-5
@@ -1,11 +1,8 @@
|
||||
/* Just a replacement, if the original malloc is not
|
||||
GNU-compliant. See autoconf documentation. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
#undef malloc
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
void *malloc ();
|
||||
@@ -14,7 +11,7 @@ void *malloc ();
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
void *
|
||||
rpl_malloc (size_t n)
|
||||
rpl_malloc_unbound (size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
|
||||
Vendored
+65
-20
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2007-05-17'
|
||||
timestamp='2009-04-27'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -56,8 +56,8 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -324,14 +324,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7; exit ;;
|
||||
esac ;;
|
||||
s390x:SunOS:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
@@ -532,7 +548,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[45])
|
||||
*:AIX:*:[456])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -793,12 +809,15 @@ EOF
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
EM64T | authenticamd | genuineintel)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
@@ -833,7 +852,14 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
@@ -925,6 +951,9 @@ EOF
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-gnu
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
@@ -954,8 +983,8 @@ EOF
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa:Linux:*:*)
|
||||
echo xtensa-unknown-linux-gnu
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
@@ -975,9 +1004,6 @@ EOF
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
@@ -1092,8 +1118,11 @@ EOF
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
@@ -1131,6 +1160,16 @@ EOF
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1206,6 +1245,9 @@ EOF
|
||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit ;;
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1314,6 +1356,9 @@ EOF
|
||||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
exit ;;
|
||||
i*86:AROS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-aros
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
@@ -1474,9 +1519,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
and
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
||||
+285
-68
@@ -10,6 +10,9 @@
|
||||
*/
|
||||
#undef DARWIN_BROKEN_SETREUID
|
||||
|
||||
/* Whether daemon is deprecated */
|
||||
#undef DEPRECATED_DAEMON
|
||||
|
||||
/* Define if you want to use debug lock checking (slow). */
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
|
||||
@@ -28,6 +31,16 @@
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#undef HAVE_CTIME_R
|
||||
|
||||
/* Define to 1 if you have the `daemon' function. */
|
||||
#undef HAVE_DAEMON
|
||||
|
||||
/* Define to 1 if you have the declaration of
|
||||
`SSL_COMP_get_compression_methods', and to 0 if you don't. */
|
||||
#undef HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
@@ -37,6 +50,9 @@
|
||||
/* Define to 1 if you have the `event_base_get_method' function. */
|
||||
#undef HAVE_EVENT_BASE_GET_METHOD
|
||||
|
||||
/* Define to 1 if you have the `event_base_new' function. */
|
||||
#undef HAVE_EVENT_BASE_NEW
|
||||
|
||||
/* Define to 1 if you have the `event_base_once' function. */
|
||||
#undef HAVE_EVENT_BASE_ONCE
|
||||
|
||||
@@ -52,6 +68,9 @@
|
||||
/* Define to 1 if you have the `EVP_sha512' function. */
|
||||
#undef HAVE_EVP_SHA512
|
||||
|
||||
/* Define to 1 if you have the `ev_loop' function. */
|
||||
#undef HAVE_EV_LOOP
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
@@ -73,9 +92,18 @@
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `glob' function. */
|
||||
#undef HAVE_GLOB
|
||||
|
||||
/* Define to 1 if you have the <glob.h> header file. */
|
||||
#undef HAVE_GLOB_H
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -88,18 +116,30 @@
|
||||
/* Define to 1 if you have the `inet_pton' function. */
|
||||
#undef HAVE_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the `initgroups' function. */
|
||||
#undef HAVE_INITGROUPS
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* if the function 'ioctlsocket' is available */
|
||||
#undef HAVE_IOCTLSOCKET
|
||||
|
||||
/* Define to 1 if you have the <iphlpapi.h> header file. */
|
||||
#undef HAVE_IPHLPAPI_H
|
||||
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the `ldns' library (-lldns). */
|
||||
#undef HAVE_LIBLDNS
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* Define to 1 if you have the <login_cap.h> header file. */
|
||||
#undef HAVE_LOGIN_CAP_H
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#undef HAVE_MALLOC
|
||||
@@ -116,6 +156,15 @@
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_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/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
|
||||
|
||||
@@ -137,6 +186,9 @@
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have Python libraries and header files. */
|
||||
#undef HAVE_PYTHON
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
@@ -164,6 +216,9 @@
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the `setusercontext' function. */
|
||||
#undef HAVE_SETUSERCONTEXT
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
@@ -194,6 +249,9 @@
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
@@ -203,6 +261,9 @@
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define if you have Swig libraries and header files. */
|
||||
#undef HAVE_SWIG
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
@@ -266,6 +327,16 @@
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
/* Define to 1 if you have the `_beginthreadex' function. */
|
||||
#undef HAVE__BEGINTHREADEX
|
||||
|
||||
/* if lex has yylex_destroy */
|
||||
#undef LEX_HAS_YYLEX_DESTROY
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to the maximum message length to pass to syslog. */
|
||||
#undef MAXSYSLOGMSGLEN
|
||||
|
||||
@@ -276,6 +347,30 @@
|
||||
lower performance). */
|
||||
#undef NONBLOCKING_IS_BROKEN
|
||||
|
||||
/* Put -D_ALL_SOURCE define in config.h */
|
||||
#undef OMITTED__D_ALL_SOURCE
|
||||
|
||||
/* Put -D_BSD_SOURCE define in config.h */
|
||||
#undef OMITTED__D_BSD_SOURCE
|
||||
|
||||
/* Put -D_GNU_SOURCE define in config.h */
|
||||
#undef OMITTED__D_GNU_SOURCE
|
||||
|
||||
/* Put -D_LARGEFILE_SOURCE=1 define in config.h */
|
||||
#undef OMITTED__D_LARGEFILE_SOURCE_1
|
||||
|
||||
/* Put -D_POSIX_C_SOURCE=200112 define in config.h */
|
||||
#undef OMITTED__D_POSIX_C_SOURCE_200112
|
||||
|
||||
/* Put -D_XOPEN_SOURCE=600 define in config.h */
|
||||
#undef OMITTED__D_XOPEN_SOURCE_600
|
||||
|
||||
/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */
|
||||
#undef OMITTED__D_XOPEN_SOURCE_EXTENDED_1
|
||||
|
||||
/* Put -D__EXTENSIONS__ define in config.h */
|
||||
#undef OMITTED__D__EXTENSIONS__
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
@@ -301,12 +396,21 @@
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* version number for resource files */
|
||||
#undef RSRC_PACKAGE_VERSION
|
||||
|
||||
/* Directory to chdir to */
|
||||
#undef RUN_DIR
|
||||
|
||||
/* Shared data */
|
||||
#undef SHARE_DIR
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Use win32 resources and API */
|
||||
#undef UB_ON_WINDOWS
|
||||
|
||||
/* default username */
|
||||
#undef UB_USERNAME
|
||||
|
||||
@@ -316,26 +420,53 @@
|
||||
/* define this to enable debug checks. */
|
||||
#undef UNBOUND_DEBUG
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#undef USE_GOST
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
/* Define this to enable SHA256 and SHA512 support. */
|
||||
#undef USE_SHA2
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Whether the windows socket API is used */
|
||||
#undef USE_WINSOCK
|
||||
|
||||
/* the version of the windows API enabled */
|
||||
#undef WINVER
|
||||
|
||||
/* Define if you want Python module. */
|
||||
#undef WITH_PYTHONMODULE
|
||||
|
||||
/* Define if you want PyUnbound. */
|
||||
#undef WITH_PYUNBOUND
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
@@ -345,6 +476,16 @@
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
@@ -372,10 +513,10 @@
|
||||
/* Define to `long long' if <sys/types.h> does not define. */
|
||||
#undef int64_t
|
||||
|
||||
/* Define to `char' if <sys/types.h> does not define. */
|
||||
/* Define to `signed char' if <sys/types.h> does not define. */
|
||||
#undef int8_t
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* Define if replacement function should be used. */
|
||||
#undef malloc
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
@@ -396,7 +537,7 @@
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define to `unsigned char' if <sys/types.h> does not define. */
|
||||
/* Define to 'unsigned char if not defined */
|
||||
#undef u_char
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
@@ -417,6 +558,40 @@
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
#undef vfork
|
||||
|
||||
#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
|
||||
#define _BSD_SOURCE 1
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
|
||||
#define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
|
||||
#define _POSIX_C_SOURCE 200112
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
|
||||
#define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
|
||||
#define _ALL_SOURCE 1
|
||||
#endif
|
||||
|
||||
#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
|
||||
#define _LARGEFILE_SOURCE 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef UNBOUND_DEBUG
|
||||
# define NDEBUG
|
||||
@@ -478,12 +653,24 @@
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_ATTR_FORMAT
|
||||
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
|
||||
__attribute__ ((format (archetype, string_index, first_to_check)))
|
||||
#else /* !HAVE_ATTR_FORMAT */
|
||||
# define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
|
||||
#endif /* !HAVE_ATTR_FORMAT */
|
||||
|
||||
|
||||
#if defined(DOXYGEN)
|
||||
# define ATTR_UNUSED(x) x
|
||||
#elif defined(__cplusplus)
|
||||
@@ -493,27 +680,108 @@
|
||||
#else /* !HAVE_ATTR_UNUSED */
|
||||
# define ATTR_UNUSED(x) x
|
||||
#endif /* !HAVE_ATTR_UNUSED */
|
||||
|
||||
|
||||
#ifndef HAVE_FSEEKO
|
||||
#define fseeko fseek
|
||||
#define ftello ftell
|
||||
#endif /* HAVE_FSEEKO */
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
/* using version of libevent that is not threadsafe. */
|
||||
# define LIBEVENT_SIGNAL_PROBLEM 1
|
||||
#endif
|
||||
|
||||
#ifndef RAND_MAX
|
||||
#define RAND_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#define snprintf snprintf_unbound
|
||||
#define vsnprintf vsnprintf_unbound
|
||||
#include <stdarg.h>
|
||||
int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
#define inet_pton inet_pton_unbound
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif /* HAVE_INET_PTON */
|
||||
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
#define inet_ntop inet_ntop_unbound
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
#define inet_aton inet_aton_unbound
|
||||
int inet_aton(const char *cp, struct in_addr *addr);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define memmove memmove_unbound
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy strlcpy_unbound
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_GMTIME_R
|
||||
#define gmtime_r gmtime_r_unbound
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_SLEEP
|
||||
#define sleep(x) Sleep((x)*1000) /* on win32 */
|
||||
#endif /* HAVE_SLEEP */
|
||||
|
||||
|
||||
#ifndef HAVE_USLEEP
|
||||
#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
|
||||
#endif /* HAVE_USLEEP */
|
||||
|
||||
|
||||
#ifndef HAVE_RANDOM
|
||||
#define random rand /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_RANDOM */
|
||||
|
||||
|
||||
#ifndef HAVE_SRANDOM
|
||||
#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_SRANDOM */
|
||||
|
||||
|
||||
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#define FD_SET_T (u_int)
|
||||
#else
|
||||
#define FD_SET_T
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef IPV6_MIN_MTU
|
||||
#define IPV6_MIN_MTU 1280
|
||||
#endif /* IPV6_MIN_MTU */
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_CTIME_R
|
||||
#define ctime_r unbound_ctime_r
|
||||
char *ctime_r(const time_t *timep, char *buf);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
/* using version of libevent that is not threadsafe. */
|
||||
# define LIBEVENT_SIGNAL_PROBLEM 1
|
||||
#endif
|
||||
|
||||
#ifndef CHECKED_INET6
|
||||
# define CHECKED_INET6
|
||||
# ifdef AF_INET6
|
||||
@@ -525,61 +793,10 @@
|
||||
|
||||
/* maximum nesting of included files */
|
||||
#define MAXINCLUDES 10
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#define snprintf snprintf_unbound
|
||||
#define vsnprintf vsnprintf_unbound
|
||||
#include <stdarg.h>
|
||||
int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
#ifndef HAVE_INET_PTON
|
||||
#define inet_pton inet_pton_unbound
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif /* HAVE_INET_PTON */
|
||||
#ifndef HAVE_INET_NTOP
|
||||
#define inet_ntop inet_ntop_unbound
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
#ifndef HAVE_INET_ATON
|
||||
#define inet_aton inet_aton_unbound
|
||||
int inet_aton(const char *cp, struct in_addr *addr);
|
||||
#endif
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define memmove memmove_unbound
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy strlcpy_unbound
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
#ifndef HAVE_GMTIME_R
|
||||
#define gmtime_r gmtime_r_unbound
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
struct sockaddr_storage;
|
||||
#include "compat/fake-rfc2553.h"
|
||||
#endif
|
||||
#ifndef HAVE_SLEEP
|
||||
#define sleep(x) Sleep((x)*1000) /* on win32 */
|
||||
#endif /* HAVE_SLEEP */
|
||||
#ifndef HAVE_USLEEP
|
||||
#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
|
||||
#endif /* HAVE_USLEEP */
|
||||
#ifndef HAVE_RANDOM
|
||||
#define random rand /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_RANDOM */
|
||||
#ifndef HAVE_SRANDOM
|
||||
#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_SRANDOM */
|
||||
|
||||
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#define FD_SET_T (u_int)
|
||||
#else
|
||||
#define FD_SET_T
|
||||
#endif
|
||||
|
||||
#include "ldns/ldns.h"
|
||||
|
||||
|
||||
Vendored
+80
-20
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2007-04-29'
|
||||
timestamp='2009-04-17'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -122,6 +122,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
@@ -249,13 +250,16 @@ case $basic_machine in
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64octeon | mips64octeonel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64r5900 | mips64r5900el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
@@ -268,6 +272,7 @@ case $basic_machine in
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
@@ -277,7 +282,7 @@ case $basic_machine in
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
@@ -286,7 +291,7 @@ case $basic_machine in
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
| z8k | z80)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
@@ -329,14 +334,17 @@ case $basic_machine in
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64octeon-* | mips64octeonel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64r5900-* | mips64r5900el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
@@ -358,20 +366,24 @@ case $basic_machine in
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
| z8k-* | z80-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -435,6 +447,10 @@ case $basic_machine in
|
||||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
aros)
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -443,10 +459,22 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -475,8 +503,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
cr16)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -514,6 +542,10 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
@@ -668,6 +700,14 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
@@ -813,6 +853,14 @@ case $basic_machine in
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
@@ -1021,6 +1069,10 @@ case $basic_machine in
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
@@ -1096,6 +1148,10 @@ case $basic_machine in
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
z80-*-coff)
|
||||
basic_machine=z80-unknown
|
||||
os=-sim
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
@@ -1134,7 +1190,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
@@ -1206,8 +1262,9 @@ case $os in
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -kopensolaris* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* \
|
||||
| -aos* | -aros* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
@@ -1216,7 +1273,7 @@ case $os in
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
@@ -1356,6 +1413,9 @@ case $os in
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
|
||||
+349
-796
File diff suppressed because it is too large
Load Diff
@@ -7,4 +7,12 @@ distribution but may be helpful.
|
||||
* unbound.spec and unbound.init: RPM specfile and Linux rc.d initfile.
|
||||
* update-anchor.sh: shell script that uses unbound-host to update a set
|
||||
of trust anchor files. Run from cron twice a month.
|
||||
* update-itar.sh: shell script that updates from itar.iana.org. Run from cron.
|
||||
* split-itar.sh: shell script to split anchors.mf from itar.iana.org into
|
||||
multiple key files so it can be used with auto-trust-anchor-file.
|
||||
* unbound_munin_ : plugin for munin statistics report
|
||||
* unbound_cacti.tar.gz : setup files for cacti statistics report
|
||||
* selinux: the .fc and .te files for SElinux protection of the unbound daemon
|
||||
* unbound.plist: launchd configuration file for MacOSX.
|
||||
* build-unbound-localzone-from-hosts.pl: perl script to turn /etc/hosts into
|
||||
a local-zone and local-data include file for unbound.conf.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/perl -WT
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $hostsfile = '/etc/hosts';
|
||||
my $localzonefile = '/etc/unbound/localzone.conf.new';
|
||||
|
||||
my $localzone = 'example.com';
|
||||
|
||||
open( HOSTS,"<${hostsfile}" ) or die( "Could not open ${hostsfile}: $!" );
|
||||
open( ZONE,">${localzonefile}" ) or die( "Could not open ${localzonefile}: $!" );
|
||||
|
||||
print ZONE "server:\n\n";
|
||||
print ZONE "local-zone: \"${localzone}\" transparent\n\n";
|
||||
|
||||
my %ptrhash;
|
||||
|
||||
while ( my $hostline = <HOSTS> ) {
|
||||
|
||||
# Skip comments
|
||||
if ( $hostline !~ "^#" and $hostline !~ '^\s+$' ) {
|
||||
|
||||
my @entries = split( /\s+/, $hostline );
|
||||
|
||||
my $ip;
|
||||
|
||||
my $count = 0;
|
||||
foreach my $entry ( @entries ) {
|
||||
if ( $count == 0 ) {
|
||||
$ip = $entry;
|
||||
} else {
|
||||
|
||||
if ( $count == 1) {
|
||||
|
||||
# Only return localhost for 127.0.0.1 and ::1
|
||||
if ( ($ip ne '127.0.0.1' and $ip ne '::1') or $entry =~ 'localhost' ) {
|
||||
if ( ! defined $ptrhash{$ip} ) {
|
||||
$ptrhash{$ip} = $entry;
|
||||
print ZONE "local-data-ptr: \"$ip $entry\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Use AAAA for IPv6 addresses
|
||||
my $a = 'A';
|
||||
if ( $ip =~ ':' ) {
|
||||
$a = 'AAAA';
|
||||
}
|
||||
|
||||
print ZONE "local-data: \"$entry ${a} $ip\"\n";
|
||||
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
print ZONE "\n";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/etc/unbound(/.*)? system_u:object_r:unbound_conf_t:s0
|
||||
/etc/rc\.d/init\.d/unbound -- system_u:object_r:unbound_initrc_exec_t:s0
|
||||
/usr/sbin/unbound -- system_u:object_r:unbound_exec_t:s0
|
||||
/var/run/unbound(/.*)? system_u:object_r:unbound_var_run_t:s0
|
||||
@@ -0,0 +1,42 @@
|
||||
policy_module(unbound, 0.1.0)
|
||||
|
||||
type unbound_t;
|
||||
type unbound_conf_t;
|
||||
type unbound_exec_t;
|
||||
type unbound_initrc_exec_t;
|
||||
type unbound_var_run_t;
|
||||
|
||||
init_daemon_domain(unbound_t, unbound_exec_t)
|
||||
init_script_file(unbound_initrc_exec_t)
|
||||
|
||||
role system_r types unbound_t;
|
||||
|
||||
# XXX
|
||||
# unbound-{checkconf,control} are not protected. Do we need protect them?
|
||||
|
||||
# Unbound daemon
|
||||
|
||||
auth_use_nsswitch(unbound_t)
|
||||
dev_read_urand(unbound_t)
|
||||
corenet_all_recvfrom_unlabeled(unbound_t)
|
||||
corenet_tcp_bind_all_nodes(unbound_t)
|
||||
corenet_tcp_bind_dns_port(unbound_t)
|
||||
corenet_tcp_bind_rndc_port(unbound_t)
|
||||
corenet_udp_bind_all_nodes(unbound_t)
|
||||
corenet_udp_bind_all_unreserved_ports(unbound_t)
|
||||
corenet_udp_bind_dns_port(unbound_t)
|
||||
files_read_etc_files(unbound_t)
|
||||
files_pid_file(unbound_var_run_t)
|
||||
files_type(unbound_conf_t)
|
||||
libs_use_ld_so(unbound_t)
|
||||
libs_use_shared_libs(unbound_t)
|
||||
logging_send_syslog_msg(unbound_t)
|
||||
manage_files_pattern(unbound_t, unbound_var_run_t, unbound_var_run_t)
|
||||
miscfiles_read_localization(unbound_t)
|
||||
read_files_pattern(unbound_t, unbound_conf_t, unbound_conf_t)
|
||||
|
||||
allow unbound_t self:capability { setuid chown net_bind_service setgid dac_override };
|
||||
allow unbound_t self:tcp_socket create_stream_socket_perms;
|
||||
allow unbound_t self:udp_socket create_socket_perms;
|
||||
|
||||
###################################################
|
||||
@@ -0,0 +1,46 @@
|
||||
#/usr/bin/env bash
|
||||
# Contributed by Tom Hendrikx <tom@whyscream.net>
|
||||
|
||||
PROGNAME=$(basename $0)
|
||||
|
||||
usage() {
|
||||
echo "$PROGNAME: split the anchors.mf file from IANA into separate files." >&2
|
||||
echo "" >&2
|
||||
echo "$PROGNAME uses 2 arguments:" >&2
|
||||
echo " - the path to the anchors.mf, available at: https://itar.iana.org/" >&2
|
||||
echo " - the directory to leave the files, defaults to '.' (current working dir)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -n "$1" ] && [ -r "$1" ]; then
|
||||
itar="$1"
|
||||
echo "Reading from: $itar"
|
||||
else
|
||||
echo "Error: no anchors file given" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
dir="$2"
|
||||
else
|
||||
dir=$(pwd)
|
||||
fi
|
||||
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo "Error: $dir is not a directory" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
while read cn line; do
|
||||
if [ $(expr match "$cn" '[a-zA-Z0-9-]*\.') -gt 0 ]; then
|
||||
# first line of key
|
||||
out="$dir/$cn"anchor
|
||||
echo "writing key for $cn to: $out"
|
||||
echo "$cn $line" > $out
|
||||
elif [ "$cn" == "DS" ]; then
|
||||
# second or later line of earlier defined key
|
||||
echo " $cn $line" >> $out
|
||||
fi
|
||||
done < "$itar"
|
||||
|
||||
echo "Done."
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
|
||||
<plist version="1.0">
|
||||
<!--
|
||||
Unbound plist file for use by MacOSX launchd(8) using launchctl(1).
|
||||
Copy this file to /Library/LaunchDaemons. Launchd keeps unbound running.
|
||||
|
||||
Setup your unbound.conf with the following additional settings.
|
||||
server:
|
||||
do-daemonize: no
|
||||
username: ""
|
||||
chroot: ""
|
||||
directory: ""
|
||||
These actions are performed by launchd (for the option values, see below).
|
||||
|
||||
-->
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>unbound</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>unbound</string>
|
||||
</array>
|
||||
|
||||
<key>UserName</key>
|
||||
<string>unbound</string>
|
||||
|
||||
<key>RootDirectory</key>
|
||||
<string>/usr/local/etc/unbound</string>
|
||||
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/usr/local/etc/unbound</string>
|
||||
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
+180
-43
@@ -1,23 +1,38 @@
|
||||
# initial python set up
|
||||
%{?!with_python: %define with_python 0}
|
||||
|
||||
%if %{with_python}
|
||||
%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
|
||||
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
|
||||
%endif
|
||||
|
||||
Summary: Validating, recursive, and caching DNS(SEC) resolver
|
||||
Name: unbound
|
||||
Version: 1.1.0
|
||||
Version: 1.3.1rc2
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
|
||||
Source1: unbound.init
|
||||
Source2: unbound.conf
|
||||
Source3: unbound.munin
|
||||
# See the unbound svn repository for further documentation on these
|
||||
Patch0: unbound-1.2-glob.patch
|
||||
|
||||
Group: System Environment/Daemons
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: flex, openssl-devel, ldns-devel >= 1.3.0, libevent-devel
|
||||
BuildRequires: flex, openssl-devel , ldns-devel >= 1.5.0,
|
||||
BuildRequires: libevent-devel
|
||||
%if %{with_python}
|
||||
BuildRequires: python-devel
|
||||
%endif
|
||||
|
||||
Requires(post): chkconfig
|
||||
Requires(preun): chkconfig
|
||||
Requires(preun): initscripts
|
||||
Requires(postun): initscripts
|
||||
Requires: ldns >= 1.3.0
|
||||
Requires: ldns >= 1.5.0, dnssec-conf >= 1.19
|
||||
Requires(pre): shadow-utils
|
||||
# Is this obsolete?
|
||||
#Provides: caching-nameserver
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS(SEC) resolver.
|
||||
@@ -30,11 +45,19 @@ Unbound is designed as a set of modular components, so that also
|
||||
DNSSEC (secure DNS) validation and stub-resolvers (that do not run
|
||||
as a server, but are linked into an application) are easily possible.
|
||||
|
||||
%package munin
|
||||
Summary: Plugin for the munin / munin-node monitoring package
|
||||
Group: System Environment/Daemons
|
||||
Requires: munin-node
|
||||
Requires: %{name} = %{version}-%{release}, bc
|
||||
|
||||
%description munin
|
||||
Plugin for the munin / munin-node monitoring package
|
||||
|
||||
%package devel
|
||||
Summary: Development package that includes the unbound header files
|
||||
Group: Development/Libraries
|
||||
Requires: %{name}-libs = %{version}-%{release}, openssl-devel, ldns-devel
|
||||
Requires: libevent-devel
|
||||
|
||||
%description devel
|
||||
The devel package contains the unbound library and the include files
|
||||
@@ -44,46 +67,54 @@ Summary: Libraries used by the unbound server and client applications
|
||||
Group: Applications/System
|
||||
Requires(post): /sbin/ldconfig
|
||||
Requires(postun): /sbin/ldconfig
|
||||
Requires: openssl >= 0.9.8g-12
|
||||
|
||||
%description libs
|
||||
Contains libraries used by the unbound server and client applications
|
||||
|
||||
%if %{with_python}
|
||||
%package python
|
||||
Summary: Python modules and extensions for unbound
|
||||
Group: Applications/System
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
|
||||
%description python
|
||||
Python modules and extensions for unbound
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch0 -p1
|
||||
|
||||
%build
|
||||
%configure --with-ldns= --with-libevent --with-pthreads --with-ssl \
|
||||
--disable-rpath --enable-debug --disable-static \
|
||||
--with-run-dir=%{_localstatedir}/lib/%{name}\
|
||||
--with-conf-file=%{_localstatedir}/lib/%{name}/unbound.conf \
|
||||
--with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid
|
||||
--with-conf-file=%{_sysconfdir}/%{name}/unbound.conf \
|
||||
--with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid \
|
||||
%if %{with_python}
|
||||
--with-pythonmodule --with-pyunbound \
|
||||
%endif
|
||||
--enable-sha2
|
||||
%{__make} CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" QUIET=no %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
%{__make} DESTDIR=%{buildroot} install
|
||||
install -d 0755 %{buildroot}%{_localstatedir}/lib/%{name}
|
||||
install -d 0755 %{buildroot}%{_initrddir}
|
||||
#install -m 0755 contrib/unbound.init %{buildroot}%{_initrddir}/unbound
|
||||
install -m 0755 %{SOURCE1} %{buildroot}%{_initrddir}/unbound
|
||||
#overwrite stock unbound.conf with our own
|
||||
install -m 0755 %{SOURCE2} %{buildroot}%{_localstatedir}/lib/%{name}
|
||||
install -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/unbound
|
||||
# Install munin plugin and its softlinks
|
||||
install -d 0755 %{buildroot}%{_sysconfdir}/munin/plugin-conf.d
|
||||
install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/unbound
|
||||
install -d 0755 %{buildroot}%{_datadir}/munin/plugins/
|
||||
install -m 0755 contrib/unbound_munin_ %{buildroot}%{_datadir}/munin/plugins/unbound
|
||||
for plugin in unbound_munin_hits unbound_munin_queue unbound_munin_memory unbound_munin_by_type unbound_munin_by_class unbound_munin_by_opcode unbound_munin_by_rcode unbound_munin_by_flags unbound_munin_histogram; do
|
||||
ln -s unbound %{buildroot}%{_datadir}/munin/plugins/$plugin
|
||||
done
|
||||
|
||||
# add symbolic link from /etc/unbound.conf -> /var/unbound/unbound.conf
|
||||
|
||||
( cd %{buildroot}%{_sysconfdir}/ ; ln -s ..%{_localstatedir}/lib/unbound/unbound.conf )
|
||||
# remove static library from install (fedora packaging guidelines)
|
||||
rm -rf %{buildroot}%{_libdir}/*.la
|
||||
|
||||
# The chroot needs /dev/log, /dev/random, /etc/resolv.conf and /etc/localtime
|
||||
# but the init script uses mount --bind, so just create empty files
|
||||
mkdir -p %{buildroot}%{_localstatedir}/lib/unbound/etc \
|
||||
%{buildroot}%{_localstatedir}/lib/unbound/dev
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/etc/resolv.conf
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/etc/localtime
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/dev/log
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/dev/random
|
||||
mkdir -p %{buildroot}%{_localstatedir}/lib/unbound/var/run/unbound
|
||||
mkdir -p %{buildroot}%{_localstatedir}/run/unbound
|
||||
|
||||
%clean
|
||||
@@ -93,21 +124,22 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%defattr(-,root,root,-)
|
||||
%doc doc/README doc/CREDITS doc/LICENSE doc/FEATURES
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}
|
||||
# the chroot env
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/%{name}
|
||||
%attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name}
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/dev
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/etc
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var/run
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var/run/unbound
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/unbound.conf
|
||||
%attr(0644,root,root) %config(noreplace) %{_localstatedir}/lib/%{name}/unbound.conf
|
||||
%attr(0644,root,root) %{_localstatedir}/lib/%{name}/dev/*
|
||||
%attr(0644,root,root) %{_localstatedir}/lib/%{name}/etc/*
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound.conf
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*/*
|
||||
|
||||
%if %{with_python}
|
||||
%files python
|
||||
%{python_sitelib}/*
|
||||
%endif
|
||||
|
||||
%files munin
|
||||
%defattr(-,root,root,-)
|
||||
%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/unbound
|
||||
%{_datadir}/munin/plugins/unbound*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%{_libdir}/libunbound.so
|
||||
@@ -122,18 +154,26 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%pre
|
||||
getent group unbound >/dev/null || groupadd -r unbound
|
||||
getent passwd unbound >/dev/null || \
|
||||
useradd -r -g unbound -d %{_localstatedir}/lib/%{name} -s /sbin/nologin \
|
||||
useradd -r -g unbound -d %{_sysconfdir}/unbound -s /sbin/nologin \
|
||||
-c "Unbound DNS resolver" unbound
|
||||
exit 0
|
||||
|
||||
%post
|
||||
%post
|
||||
/sbin/chkconfig --add %{name}
|
||||
# Check DNSSEC settings if this is a fresh install
|
||||
if [ "$1" -eq 1 ]; then
|
||||
if [ -r /etc/sysconfig/dnssec ]; then
|
||||
. /etc/sysconfig/dnssec
|
||||
[ -x /usr/sbin/dnssec-configure ] && \
|
||||
dnssec-configure -u --norestart --nocheck --dnssec="$DNSSEC" --dlv="$DLV" > \
|
||||
/dev/null 2>&1
|
||||
fi;
|
||||
fi
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
|
||||
|
||||
%preun
|
||||
if [ $1 -eq 0 ]; then
|
||||
if [ "$1" -eq 0 ]; then
|
||||
/sbin/service %{name} stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del %{name}
|
||||
fi
|
||||
@@ -146,6 +186,106 @@ fi
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Sat Jun 20 2009 Paul Wouters <paul@xelerance.com> - 1.3.0-2
|
||||
- Added missing glob patch to cvs
|
||||
- Place python macros within the %%with_python check
|
||||
|
||||
* Sat Jun 20 2009 Paul Wouters <paul@xelerance.com> - 1.3.0-1
|
||||
- Updated to 1.3.0
|
||||
- Added unbound-python sub package. disabled for now
|
||||
- Patch from svn to fix DLV lookups
|
||||
- Patches from svn to detect wrong truncated response from BIND 9.6.1 with
|
||||
minimal-responses)
|
||||
- Added Default-Start and Default-Stop to unbound.init
|
||||
- Re-enabled --enable-sha2
|
||||
- Re-enabled glob.patch
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-7
|
||||
- unbound-iterator.patch was not commited
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-6
|
||||
- Fix for https://bugzilla.redhat.com/show_bug.cgi?id=499793
|
||||
|
||||
* Tue Mar 17 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-5
|
||||
- Use --nocheck to avoid giving an error on missing unbound-remote certs/keys
|
||||
|
||||
* Tue Mar 10 2009 Adam Tkac <atkac redhat com> - 1.2.1-4
|
||||
- enable DNSSEC only if it is enabled in sysconfig/dnssec
|
||||
|
||||
* Mon Mar 09 2009 Adam Tkac <atkac redhat com> - 1.2.1-3
|
||||
- add DNSSEC support to initscript and enabled it per default
|
||||
- add requires dnssec-conf
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Tue Feb 10 2009 Paul Wouters <paul@xelerance.com - 1.2.1-1
|
||||
- updated to 1.2.1
|
||||
|
||||
* Sun Jan 18 2009 Tomas Mraz <tmraz@redhat.com> - 1.2.0-2
|
||||
- rebuild with new openssl
|
||||
|
||||
* Wed Jan 14 2009 Paul Wouters <paul@xelerance.com - 1.2.0-1
|
||||
- Updated to 1.2.0
|
||||
- Added dependancy on minimum SSL for CVE-2008-5077
|
||||
- Added dependancy on bc for unbound-munin
|
||||
- Added minimum requirement of libevent 1.4.5. Crashes with older versions
|
||||
(note: libevent is stale in EL-4 and not in EL-5, needs fixing there)
|
||||
- Removed dependancy on selinux-policy (will get used when available)
|
||||
- Enable options as per draft-wijngaards-dnsext-resolver-side-mitigation-00.txt
|
||||
- Enable unwanted-reply-threshold to mitigate against a Kaminsky attack
|
||||
- Enable val-clean-additional to drop addition unsigned data from signed
|
||||
response.
|
||||
- Removed patches (got merged into upstream)
|
||||
|
||||
* Mon Jan 5 2009 Paul Wouters <paul@xelerance.com> - 1.1.1-7
|
||||
- Modified scandir patch to silently fail when wildcard matches nothing
|
||||
- Patch to allow unbound-checkconf to find empty wildcard matches
|
||||
|
||||
* Mon Jan 5 2009 Paul Wouters <paul@xelerance.com> - 1.1.1-6
|
||||
- Added scandir patch for trusted-keys-file: option, which
|
||||
is used to load multiple dnssec keys in bind file format
|
||||
|
||||
* Mon Dec 8 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-4
|
||||
- Added Requires: for selinux-policy >= 3.5.13-33 for proper SElinux rules.
|
||||
|
||||
* Mon Dec 1 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-3
|
||||
- We did not own the /etc/unbound directory (#474020)
|
||||
- Fixed cvs anomalies
|
||||
|
||||
* Fri Nov 28 2008 Adam Tkac <atkac redhat com> - 1.1.1-2
|
||||
- removed all obsolete chroot related stuff
|
||||
- label control certs after generation correctly
|
||||
|
||||
* Thu Nov 20 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-1
|
||||
- Updated to unbound 1.1.1 which fixes a crasher and
|
||||
addresses nlnetlabs bug #219
|
||||
|
||||
* Wed Nov 19 2008 Paul Wouters <paul@xelerance.com> - 1.1.0-3
|
||||
- Remove the chroot, obsoleted by SElinux
|
||||
- Add additional munin plugin links supported by unbound plugin
|
||||
- Move configuration directory from /var/lib/unbound to /etc/unbound
|
||||
- Modified unbound.init and unbound.conf to account for chroot changes
|
||||
- Updated unbound.conf with new available options
|
||||
- Enabled dns-0x20 protection per default
|
||||
|
||||
* Wed Nov 19 2008 Adam Tkac <atkac redhat com> - 1.1.0-2
|
||||
- unbound-1.1.0-log_open.patch
|
||||
- make sure log is opened before chroot call
|
||||
- tracked as http://www.nlnetlabs.nl/bugs/show_bug.cgi?id=219
|
||||
- removed /dev/log and /var/run/unbound and /etc/resolv.conf from
|
||||
chroot, not needed
|
||||
- don't mount files in chroot, it causes problems during updates
|
||||
- fixed typo in default config file
|
||||
|
||||
* Fri Nov 14 2008 Paul Wouters <paul@xelerance.com> - 1.1.0-1
|
||||
- Updated to version 1.1.0
|
||||
- Updated unbound.conf's statistics options and remote-control
|
||||
to work properly for munin
|
||||
- Added unbound-munin package
|
||||
- Generate unbound remote-control key/certs on first startup
|
||||
- Required ldns is now 1.4.0
|
||||
|
||||
* Wed Oct 22 2008 Paul Wouters <paul@xelerance.com> - 1.0.2-5
|
||||
- Only call ldconfig in -libs package
|
||||
- Move configure into build section
|
||||
@@ -180,6 +320,3 @@ fi
|
||||
|
||||
* Wed Apr 23 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 0.11
|
||||
- Initial version.
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
+29
-4
@@ -123,8 +123,18 @@ get_value ( ) {
|
||||
get_state ( ) {
|
||||
# obtain lock for fetching the state
|
||||
# because there is a race condition in fetching and writing to file
|
||||
|
||||
# see if the lock is stale, if so, take it
|
||||
if test -f $lock ; then
|
||||
pid="`cat $lock 2>&1`"
|
||||
kill -0 "$pid" >/dev/null 2>&1
|
||||
if test $? -ne 0 -a "$pid" != $$ ; then
|
||||
echo $$ >$lock
|
||||
fi
|
||||
fi
|
||||
|
||||
i=0
|
||||
while test ! -f $lock || test "`cat $lock`" != $$; do
|
||||
while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
|
||||
while test -f $lock; do
|
||||
# wait
|
||||
i=`expr $i + 1`
|
||||
@@ -226,6 +236,7 @@ if test "$1" = "config" ; then
|
||||
p_config "total.num.queries" "total queries from clients"
|
||||
p_config "total.num.cachehits" "cache hits"
|
||||
p_config "num.query.tcp" "TCP queries"
|
||||
p_config "num.query.ipv6" "IPv6 queries"
|
||||
p_config "unwanted.queries" "queries that failed acl"
|
||||
p_config "unwanted.replies" "unwanted or unsolicited replies"
|
||||
echo "u_replies.warning $warn"
|
||||
@@ -412,8 +423,8 @@ hits)
|
||||
for x in thread0.num.queries thread1.num.queries thread2.num.queries \
|
||||
thread3.num.queries thread4.num.queries thread5.num.queries \
|
||||
thread6.num.queries thread7.num.queries total.num.queries \
|
||||
total.num.cachehits num.query.tcp unwanted.queries \
|
||||
unwanted.replies; do
|
||||
total.num.cachehits num.query.tcp num.query.ipv6 \
|
||||
unwanted.queries unwanted.replies; do
|
||||
if grep "^"$x"=" $state >/dev/null 2>&1; then
|
||||
print_qps $x
|
||||
fi
|
||||
@@ -426,7 +437,21 @@ queue)
|
||||
done
|
||||
;;
|
||||
memory)
|
||||
for x in mem.total.sbrk mem.cache.rrset mem.cache.message \
|
||||
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; do
|
||||
print_value $x
|
||||
done
|
||||
|
||||
@@ -8,7 +8,7 @@ ubhost=unbound-host
|
||||
|
||||
usage ( )
|
||||
{
|
||||
echo "usage: update-anchor [-b] <zone name> <trust anchor file>"
|
||||
echo "usage: update-anchor [-r hs] [-b] <zone name> <trust anchor file>"
|
||||
echo " performs an update of trust anchor file"
|
||||
echo " the trust anchor file is overwritten with the latest keys"
|
||||
echo " the trust anchor file should contain only keys for one zone"
|
||||
@@ -16,13 +16,15 @@ usage ( )
|
||||
echo " without -b the file is made in unbound format."
|
||||
echo " "
|
||||
echo "alternate:"
|
||||
echo " update-anchor [-b] -d directory"
|
||||
echo " update-anchor [-r hints] [-b] -d directory"
|
||||
echo " update all <zone>.anchor files in the directory."
|
||||
echo " "
|
||||
echo " name the files br.anchor se.anchor ..., and include them in"
|
||||
echo " the validating resolver config file."
|
||||
echo " put keys for the root in a file with the name root.anchor."
|
||||
echo ""
|
||||
echo "-r root.hints use different root hints. Strict option order."
|
||||
echo ""
|
||||
echo "Exit code 0 means anchors updated, 1 no changes, others are errors."
|
||||
exit 2
|
||||
}
|
||||
@@ -32,6 +34,12 @@ if test $# -eq 0; then
|
||||
fi
|
||||
bindformat="no"
|
||||
filearg='-f'
|
||||
roothints=""
|
||||
if test X"$1" = "X-r"; then
|
||||
shift
|
||||
roothints="$1"
|
||||
shift
|
||||
fi
|
||||
if test X"$1" = "X-b"; then
|
||||
shift
|
||||
bindformat="yes"
|
||||
@@ -46,10 +54,15 @@ do_update ( ) {
|
||||
# arguments: <zonename> <keyfile>
|
||||
zonename="$1"
|
||||
keyfile="$2"
|
||||
tmp2=$tmpfile.2
|
||||
|
||||
tmpfile="/tmp/update-anchor.$$"
|
||||
$ubhost -v $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile
|
||||
tmp2=$tmpfile.2
|
||||
tmp3=$tmpfile.3
|
||||
rh=""
|
||||
if test -n "$roothints"; then
|
||||
echo "server: root-hints: '$roothints'" > $tmp3
|
||||
rh="-C $tmp3"
|
||||
fi
|
||||
$ubhost -v $rh $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile
|
||||
if test $? -ne 0; then
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
@@ -65,7 +78,7 @@ do_update ( ) {
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
echo "Cause: result of lookup was not secure"
|
||||
echo " (keys too far out of date? domain changed ownership?)"
|
||||
echo " (keys too far out of date? domain changed ownership? need root hints?)"
|
||||
return 3
|
||||
fi
|
||||
|
||||
@@ -115,7 +128,7 @@ do_update ( ) {
|
||||
echo "$zonename key file $keyfile unchanged."
|
||||
fi
|
||||
|
||||
rm -f $tmpfile $tmp2
|
||||
rm -f $tmpfile $tmp2 $tmp3
|
||||
}
|
||||
|
||||
no_updated=1
|
||||
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
#!/bin/sh
|
||||
# update-itar.sh - update from the interim trust anchor repository
|
||||
# Copyright 2009, W.C.A. Wijngaards
|
||||
# This file is BSD licensed, see doc/LICENSE.
|
||||
|
||||
# --- Some settings
|
||||
|
||||
# directory where unbound works
|
||||
thedir="."
|
||||
# where is the file that unbound is going to read
|
||||
ub_ta_file="$thedir/anchors.mf"
|
||||
# where is the itar master file format
|
||||
itar_url="ftp://iana.org/itar/anchors.mf"
|
||||
# where is the itar PGP signature
|
||||
itar_sig="ftp://iana.org/itar/anchors.mf.sig"
|
||||
|
||||
# which command to fetch urls, cmd $dest $url. "wget -O" "curl -o"
|
||||
fetch_cmd="wget -O"
|
||||
# file with pgp public key
|
||||
pgp_pub_key_file="$thedir/update-itar.key"
|
||||
# our pgp keyring (goes into .gnupg directory)
|
||||
pgp_keyring_file="update-itar.ring"
|
||||
# pgp command to use
|
||||
pgp_cmd="gpg"
|
||||
|
||||
|
||||
# --- The script is below
|
||||
usage ( )
|
||||
{
|
||||
echo "usage: update-itar"
|
||||
echo " Updates the trust anchors from the interim trust"
|
||||
echo " anchor repository, https://itar.iana.org, and checks PGP sig."
|
||||
echo
|
||||
echo " Updates $ub_ta_file with the latest keys."
|
||||
echo " Read that file from the unbound config with"
|
||||
echo " trust-anchor-file: "'"'"$ub_ta_file"'"'
|
||||
echo
|
||||
echo " Exit code 0 means anchors updated, 1 no changes, "
|
||||
echo " others are errors. So, in a cronjob you can do:"
|
||||
echo " cd /usr/local/etc/unbound # your unbound work dir"
|
||||
echo " ./update-itar.sh && unbound-control reload"
|
||||
exit 2
|
||||
}
|
||||
|
||||
if test $# -ne 0; then
|
||||
usage
|
||||
fi
|
||||
tmpf="/tmp/update-itar.$$"
|
||||
|
||||
# one argument: explanation string
|
||||
error_exit ( )
|
||||
{
|
||||
if test -f $tmpf.log; then cat $tmpf.log; fi
|
||||
rm -f $tmpf $tmpf.sig $tmpf.log
|
||||
echo "Error updating trust anchors: $1"
|
||||
exit 2
|
||||
}
|
||||
|
||||
if test ! -f $pgp_pub_key_file || test ! -f $HOME/.gnupg/$pgp_keyring_file || \
|
||||
test "$pgp_pub_key_file" -nt $HOME/.gnupg/$pgp_keyring_file; then
|
||||
# default key contents right here
|
||||
if test ! -f $pgp_pub_key_file; then
|
||||
echo "creating default IANA ITAR pgp key file"
|
||||
cat >$pgp_pub_key_file <<EOF
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.5
|
||||
|
||||
mQGiBElr2DcRBAC+6YK6eSP7rzstvnMPQXMrpvVfuIR5FeTpGuwae9JP78V/iOXr
|
||||
N0yW8Dn6kdAztCMuRizL1Ij9IgaD7pjn8h09VgR4cN4LDv75rcQeWLzNxKy4UNRF
|
||||
aStL77RcIoTblBeCgHAK9FLzd0XfTGZCNaLNy9BYVSLyADOVDIqgBcrvBwCglz03
|
||||
QhOMIgaSx/XuRh6kYtynZ6kD/2GXx6pFs57b7rww8yOpdurCSOMB1wuEXiIXznTI
|
||||
06ARiib0G5VDvOdpy0LDU2526Q9f/WAERlhcExTgnTFigG4mRksUiDrrai4GIr+6
|
||||
JaivcGFVYdZZ4mZ088jcwujS/UY3C0ryGR9ufYUDAnfx6frhSl6o6j5is+jeGndF
|
||||
JYRAA/9B/1OXNVwFSiIxnP2aPUwsT1li1vaW8dhA/5PcuPLOVvEjPc1Pc16HGLhE
|
||||
8CRmMn66LqB1ccInE5hLKGGvV3pctjan+IOhaq3OHt/a+buDtTPgykchMZ2k1AzT
|
||||
RYk+gksxpIl6yTZsBH4hoRt8auxEJW8AiYbNtXXkNuWcoQL40bQsSUFOQSBUcnVz
|
||||
dCBBbmNob3IgUmVwb3NpdG9yeSA8aXRhckBpYW5hLm9yZz6IYAQTEQIAIAUCSWvY
|
||||
NwIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEPR9+zCB1GT0GUAAn29/TacF
|
||||
Teh87dls8pmkjxS4pKf1AKCJS/MvzR54AblO4DNMyc9q0G4frrkCDQRJa9g3EAgA
|
||||
ywoLxF4HVb9o926UIXw8JxNIzDPkt8galAcKRUmHQMNa/QA80WMl9Ia6DIxavGlV
|
||||
I5O1fvms297RV2KSSBjKWn6G+0me80A7aw0eHNg7habM5VtzDz5DhJbQFdJV9aYV
|
||||
DoTSnY6uR6iSSRrdZNaYdlCwDS8lBCnOKoGMArHzVCa2EdCBeCUY/eObOXtu8Gm3
|
||||
nDkuWeLPv08/0lvtr6d6VoDUEVPEsJAPONEYtpz/D+EZddUraF+3JscWqfRApBOz
|
||||
/8WHaeTNdzIH+h1ntktiizA6eH40EM6coQQxtIRsxg1DPTxofdovreMkcMI0EUUP
|
||||
awDn8gDtgG3g6Ud5zCdknwAEDQf/W3rxrEN6OZxJvWti8Iu6KOgxtuINiAsimPPX
|
||||
qy9KHowyEE9EMPzgADjWC9Reyusr4CwcootjWw7ryUwU0fXvVULKhg32NzLsx/Ci
|
||||
WtgCPSR58WZ1KKhnoB05+PTrwzhU+u64Cd/vJtFqGxSrANl2FAkPswHJMr8dMwAz
|
||||
uni7zzLJ+homW1T5AaixwmN3jeDHWshJH9E9JIhr5Y/8AzMl1V10r2u1c2ej0lBJ
|
||||
Y4GegI5cYAEBerS9d+mrbPlvbJ8AfuAuEf0y/PWJh0z1+Kck5qIbXMn/rpMBYvLJ
|
||||
Uj5CfqWlh8+hxqSYJDXtLm8hBiQFiMEew0jOc2Tw4F91OZ+jyYhJBBgRAgAJBQJJ
|
||||
a9g3AhsMAAoJEPR9+zCB1GT0AUwAn2ZtBwAyVxppdeTqilXufUvAkvjbAJ9dUpR1
|
||||
9a17/5BvDDJcIxSEKTJmDw==
|
||||
=zCNZ
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
EOF
|
||||
fi
|
||||
# import the new key
|
||||
$pgp_cmd --no-default-keyring --keyring $pgp_keyring_file \
|
||||
--primary-keyring $pgp_keyring_file \
|
||||
--import $pgp_pub_key_file >$tmpf.log 2>&1 \
|
||||
|| error_exit "could not import pgp public key into keyring"
|
||||
fi
|
||||
|
||||
$fetch_cmd $tmpf $itar_url >$tmpf.log 2>&1 \
|
||||
|| error_exit "fetching $itar_url failed"
|
||||
tail -2 $tmpf | grep "; End of file" >/dev/null 2>&1 || \
|
||||
error_exit "The file fetched from $itar_url was partial"
|
||||
$fetch_cmd $tmpf.sig $itar_sig >$tmpf.log 2>&1 \
|
||||
|| error_exit "fetching $itar_sig failed"
|
||||
|
||||
# check the file with pgp
|
||||
$pgp_cmd --no-default-keyring --keyring $pgp_keyring_file \
|
||||
--verify $tmpf.sig $tmpf >$tmpf.log 2>&1 \
|
||||
|| error_exit "the PGP signature failed!"
|
||||
|
||||
# check for differences
|
||||
val=1
|
||||
if diff "$ub_ta_file" $tmpf 2>/dev/null ; then
|
||||
# echo "The interim trust anchor repository did not change."
|
||||
:
|
||||
else
|
||||
echo "Updating $ub_ta_file"
|
||||
cp $tmpf $ub_ta_file
|
||||
val=0
|
||||
fi
|
||||
|
||||
rm -f $tmpf $tmpf.sig $tmpf.log
|
||||
exit $val
|
||||
+152
-51
@@ -43,14 +43,20 @@
|
||||
#include "daemon/cachedump.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/modstack.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
|
||||
/** convert to ldns rr */
|
||||
static ldns_rr*
|
||||
@@ -394,17 +400,16 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
*go_on = 0;
|
||||
return 1;
|
||||
}
|
||||
log_info("rd %s", (char*)ldns_buffer_begin(buf));
|
||||
status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
|
||||
LDNS_DEFAULT_TTL, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot parse rr :%s: %s\n",
|
||||
log_warn("error cannot parse rr :%s: %s",
|
||||
ldns_get_errorstr_by_id(status),
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
|
||||
(void)ssl_printf(ssl, "error expected rrsig but got %s\n",
|
||||
log_warn("error expected rrsig but got %s",
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
@@ -415,7 +420,7 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
ldns_buffer_skip(buf, 2);
|
||||
status = ldns_rr_rdata2buffer_wire(buf, rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot rr2wire :%s\n",
|
||||
log_warn("error cannot rr2wire :%s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
@@ -428,7 +433,7 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!d->rr_data[i]) {
|
||||
ldns_rr_free(rr);
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -443,7 +448,7 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
rk->rk.dname = regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!rk->rk.dname) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
@@ -455,7 +460,7 @@ load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
|
||||
/** move entry into cache */
|
||||
static int
|
||||
move_into_cache(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
move_into_cache(struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, struct worker* worker)
|
||||
{
|
||||
struct ub_packed_rrset_key* ak;
|
||||
@@ -466,7 +471,7 @@ move_into_cache(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
|
||||
ak = alloc_special_obtain(&worker->alloc);
|
||||
if(!ak) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
ak->entry.data = NULL;
|
||||
@@ -474,7 +479,7 @@ move_into_cache(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
ak->entry.hash = rrset_key_hash(&k->rk);
|
||||
ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
|
||||
if(!ak->rk.dname) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
ub_packed_rrset_parsedelete(ak, &worker->alloc);
|
||||
return 0;
|
||||
}
|
||||
@@ -484,6 +489,7 @@ move_into_cache(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
s += d->rr_len[i];
|
||||
ad = (struct packed_rrset_data*)malloc(s);
|
||||
if(!ad) {
|
||||
log_warn("error out of memory");
|
||||
ub_packed_rrset_parsedelete(ak, &worker->alloc);
|
||||
return 0;
|
||||
}
|
||||
@@ -528,13 +534,12 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
sizeof(*rk));
|
||||
d = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*d));
|
||||
if(!rk || !d) {
|
||||
(void) ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncmp(s, ";rrset", 6) != 0) {
|
||||
(void)ssl_printf(ssl, "error expected ';rrset' but got %s\n",
|
||||
s);
|
||||
log_warn("error expected ';rrset' but got %s", s);
|
||||
return 0;
|
||||
}
|
||||
s += 6;
|
||||
@@ -544,11 +549,13 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
}
|
||||
if(sscanf(s, " %u %u %u %u %u", &ttl, &rr_count, &rrsig_count,
|
||||
&trust, &security) != 5) {
|
||||
(void)ssl_printf(ssl, "error bad rrset spec %s\n", s);
|
||||
log_warn("error bad rrset spec %s", s);
|
||||
return 0;
|
||||
}
|
||||
if(rr_count == 0 && rrsig_count == 0)
|
||||
if(rr_count == 0 && rrsig_count == 0) {
|
||||
log_warn("bad rrset without contents");
|
||||
return 0;
|
||||
}
|
||||
d->count = (size_t)rr_count;
|
||||
d->rrsig_count = (size_t)rrsig_count;
|
||||
d->security = (enum sec_status)security;
|
||||
@@ -562,7 +569,7 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
d->rr_data = regional_alloc_zero(region,
|
||||
sizeof(uint8_t*)*(d->count+d->rrsig_count));
|
||||
if(!d->rr_len || !d->rr_ttl || !d->rr_data) {
|
||||
(void) ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -570,12 +577,14 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
for(i=0; i<rr_count; i++) {
|
||||
if(!load_rr(ssl, buf, region, rk, d, i, 0,
|
||||
&go_on, *worker->env.now)) {
|
||||
log_warn("could not read rr %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(i=0; i<rrsig_count; i++) {
|
||||
if(!load_rr(ssl, buf, region, rk, d, i+rr_count, 1,
|
||||
&go_on, *worker->env.now)) {
|
||||
log_warn("could not read rrsig %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -584,7 +593,7 @@ load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return move_into_cache(ssl, rk, d, worker);
|
||||
return move_into_cache(rk, d, worker);
|
||||
}
|
||||
|
||||
/** load rrset cache */
|
||||
@@ -604,7 +613,7 @@ load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
/** read qinfo from next three words */
|
||||
static char*
|
||||
load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
struct regional* region, SSL* ssl)
|
||||
struct regional* region)
|
||||
{
|
||||
/* s is part of the buf */
|
||||
char* s = str;
|
||||
@@ -616,7 +625,7 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
if(s) s = strchr(s+1, ' ');
|
||||
if(s) s = strchr(s+1, ' ');
|
||||
if(!s) {
|
||||
(void)ssl_printf(ssl, "error line too short, %s\n", str);
|
||||
log_warn("error line too short, %s", str);
|
||||
return NULL;
|
||||
}
|
||||
s[0] = 0;
|
||||
@@ -625,7 +634,7 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
/* parse them */
|
||||
status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot parse: %s %s\n",
|
||||
log_warn("error cannot parse: %s %s",
|
||||
ldns_get_errorstr_by_id(status), str);
|
||||
return NULL;
|
||||
}
|
||||
@@ -635,7 +644,7 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
|
||||
ldns_rr_free(rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot dname2wire: %s\n",
|
||||
log_warn("error cannot dname2wire: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
return NULL;
|
||||
}
|
||||
@@ -644,7 +653,7 @@ load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!qinfo->qname) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -670,12 +679,12 @@ load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker,
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = load_qinfo(s, &qinfo, buf, region, ssl);
|
||||
s = load_qinfo(s, &qinfo, buf, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
if(sscanf(s, " %u", &flags) != 1) {
|
||||
(void)ssl_printf(ssl, "error cannot parse flags: %s\n", s);
|
||||
log_warn("error cannot parse flags: %s", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -711,11 +720,11 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
regional_free_all(region);
|
||||
|
||||
if(strncmp(s, "msg ", 4) != 0) {
|
||||
(void)ssl_printf(ssl, "error expected msg but got %s\n", s);
|
||||
log_warn("error expected msg but got %s", s);
|
||||
return 0;
|
||||
}
|
||||
s += 4;
|
||||
s = load_qinfo(s, &qinf, buf, region, ssl);
|
||||
s = load_qinfo(s, &qinf, buf, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -723,7 +732,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
/* read remainder of line */
|
||||
if(sscanf(s, " %u %u %u %u %u %u %u", &flags, &qdcount, &ttl,
|
||||
&security, &an, &ns, &ar) != 7) {
|
||||
(void)ssl_printf(ssl, "error cannot parse numbers: %s\n", s);
|
||||
log_warn("error cannot parse numbers: %s", s);
|
||||
return 0;
|
||||
}
|
||||
rep.flags = (uint16_t)flags;
|
||||
@@ -749,7 +758,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
return 1; /* skip this one, not all references satisfied */
|
||||
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -779,6 +788,84 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||
return read_fixed(ssl, worker->env.scratch_buffer, "EOF");
|
||||
}
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
int lame, dlame, rlame, rtt, edns_vs, to, lost;
|
||||
uint8_t edns_lame_known;
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
|
||||
if(!ssl_printf(ssl, "%-16s\t", buf))
|
||||
return;
|
||||
if(a->bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS. "))
|
||||
return;
|
||||
}
|
||||
/* lookup in infra cache */
|
||||
/* uses type_A because most often looked up, but other
|
||||
* lameness won't be reported then */
|
||||
if(!infra_get_lame_rtt(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, dp->name, dp->namelen,
|
||||
LDNS_RR_TYPE_A, &lame, &dlame, &rlame, &rtt, &lost,
|
||||
*worker->env.now)) {
|
||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||
return;
|
||||
continue; /* skip stuff not in infra cache */
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s%s%srtt %d msec, %d lost. ",
|
||||
lame?"LAME ":"", dlame?"NoDNSSEC ":"",
|
||||
rlame?"NoAuthButRecursive ":"", rtt, lost))
|
||||
return;
|
||||
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
||||
*worker->env.now, &edns_vs, &edns_lame_known, &to)) {
|
||||
if(edns_vs == -1) {
|
||||
if(!ssl_printf(ssl, "noEDNS%s.",
|
||||
edns_lame_known?" probed":""))
|
||||
return;
|
||||
} else {
|
||||
if(!ssl_printf(ssl, "EDNS %d%s.",
|
||||
edns_vs, edns_lame_known?" probed":""))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!ssl_printf(ssl, "\n"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
{
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
|
||||
/* print the dp */
|
||||
if(msg)
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)k->entry.data;
|
||||
if(d->security == sec_status_bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
|
||||
return;
|
||||
}
|
||||
if(!dump_rrset(ssl, k, d, 0))
|
||||
return;
|
||||
}
|
||||
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||
/* since dp has not been used by iterator, all are available*/
|
||||
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
|
||||
"can be examined to query further addresses.\n"
|
||||
"%sIt provides %d IP addresses.\n",
|
||||
(int)n_ns, (int)n_miss, (dp->bogus?"It is BOGUS. ":""),
|
||||
(int)n_addr))
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
@@ -788,18 +875,34 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
struct regional* region = worker->scratchpad;
|
||||
char b[260];
|
||||
struct query_info qinfo;
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
struct iter_hints_stub* stub;
|
||||
struct iter_env* ie;
|
||||
regional_free_all(region);
|
||||
qinfo.qname = nm;
|
||||
qinfo.qname_len = nmlen;
|
||||
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||
qinfo.qclass = LDNS_RR_CLASS_IN;
|
||||
|
||||
if(modstack_find(&worker->daemon->mods, "iterator") == -1) {
|
||||
return ssl_printf(ssl, "error: no iterator module\n");
|
||||
}
|
||||
ie = (struct iter_env*)worker->env.modinfo[modstack_find(&worker->
|
||||
daemon->mods, "iterator")];
|
||||
|
||||
dname_str(nm, b);
|
||||
if(!ssl_printf(ssl, "The following name servers are used for lookup "
|
||||
"of %s\n", b))
|
||||
return 0;
|
||||
|
||||
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass);
|
||||
if(dp) {
|
||||
if(!ssl_printf(ssl, "forwarding request:\n"))
|
||||
return 0;
|
||||
print_dp_main(ssl, dp, NULL);
|
||||
print_dp_details(ssl, worker, dp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
|
||||
qinfo.qtype, qinfo.qclass, region, &msg,
|
||||
@@ -808,29 +911,10 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
return ssl_printf(ssl, "no delegation from "
|
||||
"cache; goes to configured roots\n");
|
||||
}
|
||||
/* print the dp */
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)k->entry.data;
|
||||
if(d->security == sec_status_bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
|
||||
return 0;
|
||||
}
|
||||
if(!dump_rrset(ssl, k, d, 0))
|
||||
return 0;
|
||||
}
|
||||
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||
/* since dp has not been used by iterator, all are available*/
|
||||
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
|
||||
"have no addresses in cache.\n"
|
||||
"It provides %d IP addresses. %s\n",
|
||||
(int)n_ns, (int)n_miss, (int)n_addr,
|
||||
(dp->bogus?"It is BOGUS":"") ))
|
||||
return 0;
|
||||
/* go up? */
|
||||
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
|
||||
print_dp_main(ssl, dp, msg);
|
||||
print_dp_details(ssl, worker, dp);
|
||||
if(!ssl_printf(ssl, "cache delegation was "
|
||||
"useless (no IP addresses)\n"))
|
||||
return 0;
|
||||
@@ -848,8 +932,25 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
stub = hints_lookup_stub(ie->hints, nm, qinfo.qclass, dp);
|
||||
if(stub) {
|
||||
if(stub->noprime) {
|
||||
if(!ssl_printf(ssl, "The noprime stub servers "
|
||||
"are used:\n"))
|
||||
return 0;
|
||||
} else {
|
||||
if(!ssl_printf(ssl, "The stub is primed "
|
||||
"with servers:\n"))
|
||||
return 0;
|
||||
}
|
||||
print_dp_main(ssl, stub->dp, NULL);
|
||||
print_dp_details(ssl, worker, stub->dp);
|
||||
} else {
|
||||
print_dp_main(ssl, dp, msg);
|
||||
print_dp_details(ssl, worker, dp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+76
-4
@@ -63,6 +63,15 @@ static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
static int sig_record_reload = 0;
|
||||
|
||||
#if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/** cleaner ssl memory freeup */
|
||||
static void* comp_meth = NULL;
|
||||
#endif
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/** remove buffers for parsing and init */
|
||||
void 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.
|
||||
* @param sig: signal number.
|
||||
@@ -165,12 +174,24 @@ daemon_init()
|
||||
checklock_start();
|
||||
ERR_load_crypto_strings();
|
||||
ERR_load_SSL_strings();
|
||||
#ifdef HAVE_OPENSSL_CONFIG
|
||||
OPENSSL_config("unbound");
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
(void)ldns_key_EVP_load_gost_id();
|
||||
#endif
|
||||
OpenSSL_add_all_algorithms();
|
||||
#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
|
||||
(void)SSL_library_init();
|
||||
#ifdef HAVE_TZSET
|
||||
/* 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,
|
||||
@@ -312,8 +333,14 @@ void close_other_pipes(struct daemon* daemon, int thr)
|
||||
int i;
|
||||
for(i=0; i<daemon->num; i++)
|
||||
if(i!=thr) {
|
||||
tube_delete(daemon->workers[i]->cmd);
|
||||
daemon->workers[i]->cmd = NULL;
|
||||
if(i==0) {
|
||||
/* only close read part, need to write stats */
|
||||
tube_close_read(daemon->workers[i]->cmd);
|
||||
} else {
|
||||
/* complete close channel to others */
|
||||
tube_delete(daemon->workers[i]->cmd);
|
||||
daemon->workers[i]->cmd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,6 +430,12 @@ daemon_fork(struct daemon* daemon)
|
||||
* them to the newly created threads.
|
||||
*/
|
||||
daemon_create_workers(daemon);
|
||||
|
||||
#ifdef HAVE_EV_LOOP
|
||||
/* in libev the first inited base gets signals */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
#endif
|
||||
|
||||
/* Now create the threads and init the workers.
|
||||
* By the way, this is thread #0 (the main thread).
|
||||
@@ -412,8 +445,11 @@ daemon_fork(struct daemon* daemon)
|
||||
/* Special handling for the main thread. This is the thread
|
||||
* that handles signals and remote control.
|
||||
*/
|
||||
#ifndef HAVE_EV_LOOP
|
||||
/* libevent has the last inited base get signals (or any base) */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
#endif
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
@@ -445,6 +481,7 @@ daemon_cleanup(struct daemon* daemon)
|
||||
local_zones_delete(daemon->local_zones);
|
||||
daemon->local_zones = NULL;
|
||||
/* key cache is cleared by module desetup during next daemon_init() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
free(daemon->workers);
|
||||
@@ -459,6 +496,7 @@ daemon_delete(struct daemon* daemon)
|
||||
if(!daemon)
|
||||
return;
|
||||
modstack_desetup(&daemon->mods, daemon->env);
|
||||
daemon_remote_delete(daemon->rc);
|
||||
listening_ports_free(daemon->ports);
|
||||
listening_ports_free(daemon->rc_ports);
|
||||
if(daemon->env) {
|
||||
@@ -469,13 +507,23 @@ daemon_delete(struct daemon* daemon)
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/* lex cleanup */
|
||||
ub_c_lex_destroy();
|
||||
#endif
|
||||
/* libcrypto cleanup */
|
||||
/* CONF_modules_unload(1); */
|
||||
#if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
sk_SSL_COMP_free(comp_meth);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
/* ENGINE_cleanup(); */
|
||||
ENGINE_cleanup();
|
||||
CONF_modules_free();
|
||||
#endif
|
||||
CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
|
||||
ERR_remove_state(0);
|
||||
ERR_free_strings();
|
||||
@@ -488,3 +536,27 @@ daemon_delete(struct daemon* daemon)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
msgreply_sizefunc, query_info_compare,
|
||||
query_entry_delete, reply_info_delete, NULL);
|
||||
if(!daemon->env->msg_cache) {
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
}
|
||||
if((daemon->env->rrset_cache = rrset_cache_adjust(
|
||||
daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache,
|
||||
cfg))==0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
|
||||
+16
-1
@@ -45,6 +45,9 @@
|
||||
#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;
|
||||
@@ -54,6 +57,7 @@ struct rrset_cache;
|
||||
struct acl_list;
|
||||
struct local_zones;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
|
||||
/**
|
||||
* Structure holding worker list.
|
||||
@@ -62,16 +66,20 @@ struct ub_randstate;
|
||||
struct daemon {
|
||||
/** The config settings */
|
||||
struct config_file* cfg;
|
||||
/** the chroot dir in use, NULL if none */
|
||||
char* chroot;
|
||||
/** pidfile that is used */
|
||||
char* pidfile;
|
||||
/** port number that has ports opened. */
|
||||
int listening_port;
|
||||
/** listening ports, opened, to be shared by threads */
|
||||
struct listen_port* ports;
|
||||
/** port number fore remote that has ports opened. */
|
||||
/** port number for remote that has ports opened. */
|
||||
int rc_port;
|
||||
/** listening ports for remote control */
|
||||
struct listen_port* rc_ports;
|
||||
/** remote control connections management (for first worker) */
|
||||
struct daemon_remote* rc;
|
||||
/** num threads allocated */
|
||||
int num;
|
||||
/** the worker entries */
|
||||
@@ -130,4 +138,11 @@ void daemon_cleanup(struct daemon* daemon);
|
||||
*/
|
||||
void daemon_delete(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Apply config settings.
|
||||
* @param daemon: the daemon.
|
||||
* @param cfg: new config settings.
|
||||
*/
|
||||
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
|
||||
|
||||
#endif /* DAEMON_H */
|
||||
|
||||
+464
-115
@@ -62,6 +62,11 @@
|
||||
#include "validator/validator.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_kentry.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/outside_network.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@@ -101,9 +106,9 @@ timeval_subtract(struct timeval* d, const struct timeval* end,
|
||||
const struct timeval* start)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
time_t end_usec = end->tv_usec;;
|
||||
time_t end_usec = end->tv_usec;
|
||||
d->tv_sec = end->tv_sec - start->tv_sec;
|
||||
while(end_usec < start->tv_usec) {
|
||||
if(end_usec < start->tv_usec) {
|
||||
end_usec += 1000000;
|
||||
d->tv_sec--;
|
||||
}
|
||||
@@ -131,18 +136,16 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
|
||||
}
|
||||
|
||||
struct daemon_remote*
|
||||
daemon_remote_create(struct worker* worker)
|
||||
daemon_remote_create(struct config_file* cfg)
|
||||
{
|
||||
char* s_cert;
|
||||
char* s_key;
|
||||
struct config_file* cfg = worker->daemon->cfg;
|
||||
struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
|
||||
sizeof(*rc));
|
||||
if(!rc) {
|
||||
log_err("out of memory in daemon_remote_create");
|
||||
return NULL;
|
||||
}
|
||||
rc->worker = worker;
|
||||
rc->max_active = 10;
|
||||
|
||||
if(!cfg->remote_control_enable) {
|
||||
@@ -161,39 +164,51 @@ daemon_remote_create(struct worker* worker)
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
s_cert = cfg->server_cert_file;
|
||||
s_key = cfg->server_key_file;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0]) {
|
||||
if(strncmp(s_cert, cfg->chrootdir, strlen(cfg->chrootdir))==0)
|
||||
s_cert += strlen(cfg->chrootdir);
|
||||
if(strncmp(s_key, cfg->chrootdir, strlen(cfg->chrootdir))==0)
|
||||
s_key += strlen(cfg->chrootdir);
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
|
||||
if(!s_cert || !s_key) {
|
||||
log_err("out of memory in remote control fname");
|
||||
goto setup_error;
|
||||
}
|
||||
verbose(VERB_ALGO, "setup SSL certificates");
|
||||
if (!SSL_CTX_use_certificate_file(rc->ctx,s_cert,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_use_PrivateKey_file(rc->ctx,s_key,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_check_private_key(rc->ctx)) {
|
||||
log_crypto_err("Error setting up SSL_CTX key and cert");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
if (!SSL_CTX_use_certificate_file(rc->ctx,s_cert,SSL_FILETYPE_PEM)) {
|
||||
log_err("Error for server-cert-file: %s", s_cert);
|
||||
log_crypto_err("Error in SSL_CTX use_certificate_file");
|
||||
goto setup_error;
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey_file(rc->ctx,s_key,SSL_FILETYPE_PEM)) {
|
||||
log_err("Error for server-key-file: %s", s_key);
|
||||
log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
|
||||
goto setup_error;
|
||||
}
|
||||
if(!SSL_CTX_check_private_key(rc->ctx)) {
|
||||
log_err("Error for server-key-file: %s", s_key);
|
||||
log_crypto_err("Error in SSL_CTX check_private_key");
|
||||
goto setup_error;
|
||||
}
|
||||
if(!SSL_CTX_load_verify_locations(rc->ctx, s_cert, NULL)) {
|
||||
log_crypto_err("Error setting up SSL_CTX verify locations");
|
||||
setup_error:
|
||||
free(s_cert);
|
||||
free(s_key);
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert));
|
||||
SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL);
|
||||
free(s_cert);
|
||||
free(s_key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void daemon_remote_delete(struct daemon_remote* rc)
|
||||
void daemon_remote_clear(struct daemon_remote* rc)
|
||||
{
|
||||
struct rc_state* p, *np;
|
||||
if(!rc) return;
|
||||
/* but do not close the ports */
|
||||
listen_list_delete(rc->accept_list);
|
||||
rc->accept_list = NULL;
|
||||
/* do close these sockets */
|
||||
p = rc->busy_list;
|
||||
while(p) {
|
||||
@@ -204,6 +219,15 @@ void daemon_remote_delete(struct daemon_remote* rc)
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
rc->busy_list = NULL;
|
||||
rc->active = 0;
|
||||
rc->worker = NULL;
|
||||
}
|
||||
|
||||
void daemon_remote_delete(struct daemon_remote* rc)
|
||||
{
|
||||
if(!rc) return;
|
||||
daemon_remote_clear(rc);
|
||||
if(rc->ctx) {
|
||||
SSL_CTX_free(rc->ctx);
|
||||
}
|
||||
@@ -247,6 +271,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||
""
|
||||
#endif
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open fd */
|
||||
@@ -267,7 +292,11 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||
/* alloc */
|
||||
n = (struct listen_port*)calloc(1, sizeof(*n));
|
||||
if(!n) {
|
||||
#ifndef USE_WINSOCK
|
||||
close(fd);
|
||||
#else
|
||||
closesocket(fd);
|
||||
#endif
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -327,9 +356,10 @@ accept_open(struct daemon_remote* rc, int fd)
|
||||
}
|
||||
|
||||
int daemon_remote_open_accept(struct daemon_remote* rc,
|
||||
struct listen_port* ports)
|
||||
struct listen_port* ports, struct worker* worker)
|
||||
{
|
||||
struct listen_port* p;
|
||||
rc->worker = worker;
|
||||
for(p = ports; p; p = p->next) {
|
||||
if(!accept_open(rc, p->fd)) {
|
||||
log_err("could not create accept comm point");
|
||||
@@ -359,7 +389,12 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
if(rc->active >= rc->max_active) {
|
||||
log_warn("drop incoming remote control: too many connections");
|
||||
comm_point_stop_listening(c);
|
||||
close_exit:
|
||||
#ifndef USE_WINSOCK
|
||||
close(newfd);
|
||||
#else
|
||||
closesocket(newfd);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -367,17 +402,15 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
n = (struct rc_state*)calloc(1, sizeof(*n));
|
||||
if(!n) {
|
||||
log_err("out of memory");
|
||||
close(newfd);
|
||||
return 0;
|
||||
goto close_exit;
|
||||
}
|
||||
/* start in reading state */
|
||||
n->c = comm_point_create_raw(rc->worker->base, newfd, 0,
|
||||
&remote_control_callback, n);
|
||||
if(!n->c) {
|
||||
log_err("out of memory");
|
||||
close(newfd);
|
||||
free(n);
|
||||
return 0;
|
||||
goto close_exit;
|
||||
}
|
||||
log_addr(VERB_QUERY, "new control connection from", &addr, addrlen);
|
||||
n->c->do_not_close = 0;
|
||||
@@ -389,18 +422,16 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
||||
n->ssl = SSL_new(rc->ctx);
|
||||
if(!n->ssl) {
|
||||
log_crypto_err("could not SSL_new");
|
||||
close(newfd);
|
||||
free(n);
|
||||
return 0;
|
||||
goto close_exit;
|
||||
}
|
||||
SSL_set_accept_state(n->ssl);
|
||||
(void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY);
|
||||
if(!SSL_set_fd(n->ssl, newfd)) {
|
||||
log_crypto_err("could not SSL_set_fd");
|
||||
close(newfd);
|
||||
SSL_free(n->ssl);
|
||||
free(n);
|
||||
return 0;
|
||||
goto close_exit;
|
||||
}
|
||||
|
||||
n->rc = rc;
|
||||
@@ -445,6 +476,8 @@ int
|
||||
ssl_print_text(SSL* ssl, const char* text)
|
||||
{
|
||||
int r;
|
||||
if(!ssl)
|
||||
return 0;
|
||||
ERR_clear_error();
|
||||
if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
@@ -483,6 +516,8 @@ ssl_read_line(SSL* ssl, char* buf, size_t max)
|
||||
{
|
||||
int r;
|
||||
size_t len = 0;
|
||||
if(!ssl)
|
||||
return 0;
|
||||
while(len < max) {
|
||||
ERR_clear_error();
|
||||
if((r=SSL_read(ssl, buf+len, 1)) <= 0) {
|
||||
@@ -623,7 +658,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
extern void* unbound_start_brk;
|
||||
void* cur = sbrk(0);
|
||||
if(!print_longnum(ssl, "mem.total.sbrk"SQ,
|
||||
(size_t)(cur - unbound_start_brk))) return 0;
|
||||
(size_t)((char*)cur - (char*)unbound_start_brk))) return 0;
|
||||
#endif /* HAVE_SBRK */
|
||||
msg = slabhash_get_mem(daemon->env->msg_cache);
|
||||
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
||||
@@ -769,6 +804,8 @@ print_ext(SSL* ssl, struct stats_info* s)
|
||||
/* transport */
|
||||
if(!ssl_printf(ssl, "num.query.tcp"SQ"%u\n",
|
||||
(unsigned)s->svr.qtcp)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.ipv6"SQ"%u\n",
|
||||
(unsigned)s->svr.qipv6)) return 0;
|
||||
/* flags */
|
||||
if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%u\n",
|
||||
(unsigned)s->svr.qbit_QR)) return 0;
|
||||
@@ -825,7 +862,7 @@ print_ext(SSL* ssl, struct stats_info* s)
|
||||
|
||||
/** do the stats command */
|
||||
static void
|
||||
do_stats(SSL* ssl, struct daemon_remote* rc)
|
||||
do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
|
||||
{
|
||||
struct daemon* daemon = rc->worker->daemon;
|
||||
struct stats_info total;
|
||||
@@ -833,7 +870,7 @@ do_stats(SSL* ssl, struct daemon_remote* rc)
|
||||
int i;
|
||||
/* gather all thread statistics in one place */
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
server_stats_obtain(rc->worker, daemon->workers[i], &s);
|
||||
server_stats_obtain(rc->worker, daemon->workers[i], &s, reset);
|
||||
if(!print_thread_stats(ssl, i, &s))
|
||||
return;
|
||||
if(i == 0)
|
||||
@@ -1006,6 +1043,22 @@ do_lookup(SSL* ssl, struct worker* worker, char* arg)
|
||||
free(nm);
|
||||
}
|
||||
|
||||
/** flush something from rrset and msg caches */
|
||||
static void
|
||||
do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
uint16_t t, uint16_t c)
|
||||
{
|
||||
hashvalue_t h;
|
||||
struct query_info k;
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
|
||||
k.qname = nm;
|
||||
k.qname_len = nmlen;
|
||||
k.qtype = t;
|
||||
k.qclass = c;
|
||||
h = query_info_hash(&k);
|
||||
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||
}
|
||||
|
||||
/** flush a type */
|
||||
static void
|
||||
do_flush_type(SSL* ssl, struct worker* worker, char* arg)
|
||||
@@ -1020,13 +1073,28 @@ do_flush_type(SSL* ssl, struct worker* worker, char* arg)
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
t = ldns_get_rr_type_by_name(arg2);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
t, LDNS_RR_CLASS_IN, 0);
|
||||
do_cache_remove(worker, nm, nmlen, t, LDNS_RR_CLASS_IN);
|
||||
|
||||
free(nm);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush statistics */
|
||||
static void
|
||||
do_flush_stats(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
worker_stats_clear(worker);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush requestlist */
|
||||
static void
|
||||
do_flush_requestlist(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
mesh_delete_all(worker->env.mesh);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Local info for deletion functions
|
||||
*/
|
||||
@@ -1043,6 +1111,8 @@ struct del_info {
|
||||
uint32_t expired;
|
||||
/** number of rrsets removed */
|
||||
size_t num_rrsets;
|
||||
/** number of msgs removed */
|
||||
size_t num_msgs;
|
||||
/** number of key entries removed */
|
||||
size_t num_keys;
|
||||
};
|
||||
@@ -1062,6 +1132,20 @@ zone_del_rrset(struct lruhash_entry* e, void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** callback to delete messages in a zone */
|
||||
static void
|
||||
zone_del_msg(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
/* entry is locked */
|
||||
struct del_info* inf = (struct del_info*)arg;
|
||||
struct msgreply_entry* k = (struct msgreply_entry*)e->key;
|
||||
if(dname_subdomain_c(k->key.qname, inf->name)) {
|
||||
struct reply_info* d = (struct reply_info*)e->data;
|
||||
d->ttl = inf->expired;
|
||||
inf->num_msgs++;
|
||||
}
|
||||
}
|
||||
|
||||
/** callback to delete keys in zone */
|
||||
static void
|
||||
zone_del_kcache(struct lruhash_entry* e, void* arg)
|
||||
@@ -1076,41 +1160,6 @@ zone_del_kcache(struct lruhash_entry* e, void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** traverse a lruhash */
|
||||
static void
|
||||
lruhash_traverse(struct lruhash* h, int wr,
|
||||
void (*func)(struct lruhash_entry*, void*), void* arg)
|
||||
{
|
||||
size_t i;
|
||||
struct lruhash_entry* e;
|
||||
|
||||
lock_quick_lock(&h->lock);
|
||||
for(i=0; i<h->size; i++) {
|
||||
lock_quick_lock(&h->array[i].lock);
|
||||
for(e = h->array[i].overflow_list; e; e = e->overflow_next) {
|
||||
if(wr) {
|
||||
lock_rw_wrlock(&e->lock);
|
||||
} else {
|
||||
lock_rw_rdlock(&e->lock);
|
||||
}
|
||||
(*func)(e, arg);
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
lock_quick_unlock(&h->array[i].lock);
|
||||
}
|
||||
lock_quick_unlock(&h->lock);
|
||||
}
|
||||
|
||||
/** traverse a slabhash */
|
||||
static void
|
||||
slabhash_traverse(struct slabhash* sh, int wr,
|
||||
void (*func)(struct lruhash_entry*, void*), void* arg)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<sh->size; i++)
|
||||
lruhash_traverse(sh->array[i], wr, func, arg);
|
||||
}
|
||||
|
||||
/** remove all rrsets and keys from zone from cache */
|
||||
static void
|
||||
do_flush_zone(SSL* ssl, struct worker* worker, char* arg)
|
||||
@@ -1119,7 +1168,6 @@ do_flush_zone(SSL* ssl, struct worker* worker, char* arg)
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
struct del_info inf;
|
||||
int idx;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
/* delete all RRs and key entries from zone */
|
||||
@@ -1131,96 +1179,397 @@ do_flush_zone(SSL* ssl, struct worker* worker, char* arg)
|
||||
inf.expired = *worker->env.now;
|
||||
inf.expired -= 3; /* handle 3 seconds skew between threads */
|
||||
inf.num_rrsets = 0;
|
||||
inf.num_msgs = 0;
|
||||
inf.num_keys = 0;
|
||||
slabhash_traverse(&worker->env.rrset_cache->table, 1,
|
||||
&zone_del_rrset, &inf);
|
||||
|
||||
slabhash_traverse(worker->env.msg_cache, 1, &zone_del_msg, &inf);
|
||||
|
||||
/* and validator cache */
|
||||
idx = modstack_find(&worker->daemon->mods, "validator");
|
||||
if(idx != -1) {
|
||||
struct val_env* ve = (struct val_env*)worker->env.modinfo[idx];
|
||||
slabhash_traverse(ve->kcache->slab, 1, &zone_del_kcache, &inf);
|
||||
if(worker->env.key_cache) {
|
||||
slabhash_traverse(worker->env.key_cache->slab, 1,
|
||||
&zone_del_kcache, &inf);
|
||||
}
|
||||
|
||||
free(nm);
|
||||
|
||||
(void)ssl_printf(ssl, "ok removed %u rrsets and %u key entries\n",
|
||||
(unsigned)inf.num_rrsets, (unsigned)inf.num_keys);
|
||||
(void)ssl_printf(ssl, "ok removed %u rrsets, %u messages "
|
||||
"and %u key entries\n", (unsigned)inf.num_rrsets,
|
||||
(unsigned)inf.num_msgs, (unsigned)inf.num_keys);
|
||||
}
|
||||
|
||||
/** remove name rrset from cache */
|
||||
static void
|
||||
do_flush_name(SSL* ssl, struct worker* worker, char* arg)
|
||||
do_flush_name(SSL* ssl, struct worker* w, char* arg)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_CNAME, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_DNAME, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_MX, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN, 0);
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen,
|
||||
LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN, 0);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_AAAA, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_CNAME, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_DNAME, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_MX, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN);
|
||||
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN);
|
||||
|
||||
free(nm);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** print root forwards */
|
||||
static int
|
||||
print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt* dp;
|
||||
struct delegpt_ns* ns;
|
||||
struct delegpt_addr* a;
|
||||
int f = 0;
|
||||
dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN);
|
||||
if(!dp)
|
||||
return ssl_printf(ssl, "off (using root hints)\n");
|
||||
/* if dp is returned it must be the root */
|
||||
log_assert(query_dname_compare(dp->name, root)==0);
|
||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||
dname_str(ns->name, buf);
|
||||
if(!ssl_printf(ssl, "%s%s", (f?" ":""), buf))
|
||||
return 0;
|
||||
f = 1;
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
|
||||
if(!ssl_printf(ssl, "%s%s", (f?" ":""), buf))
|
||||
return 0;
|
||||
f = 1;
|
||||
}
|
||||
return ssl_printf(ssl, "\n");
|
||||
}
|
||||
|
||||
/** parse args into delegpt */
|
||||
static struct delegpt*
|
||||
parse_delegpt(SSL* ssl, struct regional* region, char* args, uint8_t* root)
|
||||
{
|
||||
/* parse args and add in */
|
||||
char* p = args;
|
||||
char* todo;
|
||||
struct delegpt* dp = delegpt_create(region);
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
if(!dp || !delegpt_set_name(dp, region, root)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
while(p) {
|
||||
todo = p;
|
||||
p = strchr(p, ' '); /* find next spot, if any */
|
||||
if(p) {
|
||||
*p++ = 0; /* end this spot */
|
||||
p = skipwhite(p); /* position at next spot */
|
||||
}
|
||||
/* parse address */
|
||||
if(!extstrtoaddr(todo, &addr, &addrlen)) {
|
||||
(void)ssl_printf(ssl, "error cannot parse"
|
||||
" IP address '%s'\n", todo);
|
||||
return NULL;
|
||||
}
|
||||
/* add address */
|
||||
if(!delegpt_add_addr(dp, region, &addr, addrlen, 0, 1)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dp;
|
||||
}
|
||||
|
||||
/** do the status command */
|
||||
static void
|
||||
do_forward(SSL* ssl, struct worker* worker, char* args)
|
||||
{
|
||||
struct iter_forwards* fwd = worker->env.fwds;
|
||||
uint8_t* root = (uint8_t*)"\000";
|
||||
if(!fwd) {
|
||||
(void)ssl_printf(ssl, "error: structure not allocated\n");
|
||||
return;
|
||||
}
|
||||
if(args == NULL || args[0] == 0) {
|
||||
(void)print_root_fwds(ssl, fwd, root);
|
||||
return;
|
||||
}
|
||||
/* set root forwards for this thread. since we are in remote control
|
||||
* the actual mesh is not running, so we can freely edit it. */
|
||||
/* delete all the existing queries first */
|
||||
mesh_delete_all(worker->env.mesh);
|
||||
/* reset the fwd structure ; the cfg is unchanged (shared by threads)*/
|
||||
/* this reset frees up memory */
|
||||
forwards_apply_cfg(fwd, worker->env.cfg);
|
||||
if(strcmp(args, "off") == 0) {
|
||||
forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root);
|
||||
} else {
|
||||
struct delegpt* dp;
|
||||
if(!(dp = parse_delegpt(ssl, fwd->region, args, root)))
|
||||
return;
|
||||
if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** do the status command */
|
||||
static void
|
||||
do_status(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
int i;
|
||||
time_t uptime;
|
||||
if(!ssl_printf(ssl, "version: %s\n", PACKAGE_VERSION))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "verbosity: %d\n", verbosity))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "threads: %d\n", worker->daemon->num))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "modules: %d [", worker->daemon->mods.num))
|
||||
return;
|
||||
for(i=0; i<worker->daemon->mods.num; i++) {
|
||||
if(!ssl_printf(ssl, " %s", worker->daemon->mods.mod[i]->name))
|
||||
return;
|
||||
}
|
||||
if(!ssl_printf(ssl, " ]\n"))
|
||||
return;
|
||||
uptime = (time_t)time(NULL) - (time_t)worker->daemon->time_boot.tv_sec;
|
||||
if(!ssl_printf(ssl, "uptime: %u seconds\n", (unsigned)uptime))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "unbound (pid %d) is running...\n",
|
||||
(int)getpid()))
|
||||
return;
|
||||
}
|
||||
|
||||
/** get age for the mesh state */
|
||||
static void
|
||||
get_mesh_age(struct mesh_state* m, char* buf, size_t len,
|
||||
struct module_env* env)
|
||||
{
|
||||
if(m->reply_list) {
|
||||
struct timeval d;
|
||||
struct mesh_reply* r = m->reply_list;
|
||||
/* last reply is the oldest */
|
||||
while(r && r->next)
|
||||
r = r->next;
|
||||
timeval_subtract(&d, env->now_tv, &r->start_time);
|
||||
snprintf(buf, len, "%d.%6.6d", (int)d.tv_sec, (int)d.tv_usec);
|
||||
} else {
|
||||
snprintf(buf, len, "-");
|
||||
}
|
||||
}
|
||||
|
||||
/** get status of a mesh state */
|
||||
static void
|
||||
get_mesh_status(struct mesh_area* mesh, struct mesh_state* m,
|
||||
char* buf, size_t len)
|
||||
{
|
||||
enum module_ext_state s = m->s.ext_state[m->s.curmod];
|
||||
const char *modname = mesh->mods.mod[m->s.curmod]->name;
|
||||
size_t l;
|
||||
if(strcmp(modname, "iterator") == 0 && s == module_wait_reply &&
|
||||
m->s.minfo[m->s.curmod]) {
|
||||
/* break into iterator to find out who its waiting for */
|
||||
struct iter_qstate* qstate = (struct iter_qstate*)
|
||||
m->s.minfo[m->s.curmod];
|
||||
struct outbound_list* ol = &qstate->outlist;
|
||||
struct outbound_entry* e;
|
||||
snprintf(buf, len, "%s wait for", modname);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
if(ol->first == NULL)
|
||||
snprintf(buf, len, " (empty_list)");
|
||||
for(e = ol->first; e; e = e->next) {
|
||||
snprintf(buf, len, " ");
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
addr_to_str(&e->qsent->addr, e->qsent->addrlen,
|
||||
buf, len);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
}
|
||||
} else if(s == module_wait_subquery) {
|
||||
/* look in subs from mesh state to see what */
|
||||
char nm[257];
|
||||
struct mesh_state_ref* sub;
|
||||
snprintf(buf, len, "%s wants", modname);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
if(m->sub_set.count == 0)
|
||||
snprintf(buf, len, " (empty_list)");
|
||||
RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) {
|
||||
char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass);
|
||||
dname_str(sub->s->s.qinfo.qname, nm);
|
||||
snprintf(buf, len, " %s %s %s", t, c, nm);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
free(t);
|
||||
free(c);
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, len, "%s is %s", modname, strextstate(s));
|
||||
}
|
||||
}
|
||||
|
||||
/** do the dump_requestlist command */
|
||||
static void
|
||||
do_dump_requestlist(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
struct mesh_area* mesh;
|
||||
struct mesh_state* m;
|
||||
int num = 0;
|
||||
char buf[257];
|
||||
char timebuf[32];
|
||||
char statbuf[10240];
|
||||
if(!ssl_printf(ssl, "thread #%d\n", worker->thread_num))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "# type cl name seconds module status\n"))
|
||||
return;
|
||||
/* show worker mesh contents */
|
||||
mesh = worker->env.mesh;
|
||||
if(!mesh) return;
|
||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||
char* t = ldns_rr_type2str(m->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(m->s.qinfo.qclass);
|
||||
dname_str(m->s.qinfo.qname, buf);
|
||||
get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env);
|
||||
get_mesh_status(mesh, m, statbuf, sizeof(statbuf));
|
||||
if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n",
|
||||
num, t, c, buf, timebuf, statbuf)) {
|
||||
free(t);
|
||||
free(c);
|
||||
return;
|
||||
}
|
||||
num++;
|
||||
free(t);
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
void
|
||||
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
{
|
||||
int i;
|
||||
if(!cmd || !ssl)
|
||||
return;
|
||||
/* skip i=0 which is me */
|
||||
for(i=1; i<rc->worker->daemon->num; i++) {
|
||||
worker_send_cmd(rc->worker->daemon->workers[i],
|
||||
worker_cmd_remote);
|
||||
if(!tube_write_msg(rc->worker->daemon->workers[i]->cmd,
|
||||
(uint8_t*)cmd, strlen(cmd)+1, 0)) {
|
||||
ssl_printf(ssl, "error could not distribute cmd\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** execute a remote control command */
|
||||
static void
|
||||
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
struct worker* worker)
|
||||
{
|
||||
char* p = skipwhite(cmd);
|
||||
/* compare command - check longer strings first in case of substrings*/
|
||||
if(strncmp(p, "stop", 4) == 0) {
|
||||
do_stop(ssl, rc);
|
||||
return;
|
||||
} else if(strncmp(p, "reload", 6) == 0) {
|
||||
do_reload(ssl, rc);
|
||||
} else if(strncmp(p, "verbosity", 9) == 0) {
|
||||
do_verbosity(ssl, skipwhite(p+9));
|
||||
return;
|
||||
} else if(strncmp(p, "stats_noreset", 13) == 0) {
|
||||
do_stats(ssl, rc, 0);
|
||||
return;
|
||||
} else if(strncmp(p, "stats", 5) == 0) {
|
||||
do_stats(ssl, rc);
|
||||
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
|
||||
do_zone_remove(ssl, rc->worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_zone", 10) == 0) {
|
||||
do_zone_add(ssl, rc->worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "local_data_remove", 17) == 0) {
|
||||
do_data_remove(ssl, rc->worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_data", 10) == 0) {
|
||||
do_data_add(ssl, rc->worker, skipwhite(p+10));
|
||||
do_stats(ssl, rc, 1);
|
||||
return;
|
||||
} else if(strncmp(p, "status", 6) == 0) {
|
||||
do_status(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "dump_cache", 10) == 0) {
|
||||
(void)dump_cache(ssl, rc->worker);
|
||||
(void)dump_cache(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "load_cache", 10) == 0) {
|
||||
if(load_cache(ssl, rc->worker)) send_ok(ssl);
|
||||
if(load_cache(ssl, worker)) send_ok(ssl);
|
||||
return;
|
||||
} else if(strncmp(p, "forward", 7) == 0) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_forward(ssl, worker, skipwhite(p+7));
|
||||
return;
|
||||
} else if(strncmp(p, "flush_stats", 11) == 0) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_flush_stats(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "flush_requestlist", 17) == 0) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_flush_requestlist(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "lookup", 6) == 0) {
|
||||
do_lookup(ssl, rc->worker, skipwhite(p+6));
|
||||
do_lookup(ssl, worker, skipwhite(p+6));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
/* other processes must execute the command as well */
|
||||
/* commands that should not be distributed, returned above. */
|
||||
if(rc) { /* only if this thread is the master (rc) thread */
|
||||
/* done before the code below, which may split the string */
|
||||
distribute_cmd(rc, ssl, cmd);
|
||||
}
|
||||
#endif
|
||||
if(strncmp(p, "verbosity", 9) == 0) {
|
||||
do_verbosity(ssl, skipwhite(p+9));
|
||||
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
|
||||
do_zone_remove(ssl, worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_zone", 10) == 0) {
|
||||
do_zone_add(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "local_data_remove", 17) == 0) {
|
||||
do_data_remove(ssl, worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_data", 10) == 0) {
|
||||
do_data_add(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush_zone", 10) == 0) {
|
||||
do_flush_zone(ssl, rc->worker, skipwhite(p+10));
|
||||
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush_type", 10) == 0) {
|
||||
do_flush_type(ssl, rc->worker, skipwhite(p+10));
|
||||
do_flush_type(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush", 5) == 0) {
|
||||
do_flush_name(ssl, rc->worker, skipwhite(p+5));
|
||||
do_flush_name(ssl, worker, skipwhite(p+5));
|
||||
} else if(strncmp(p, "dump_requestlist", 16) == 0) {
|
||||
do_dump_requestlist(ssl, worker);
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
daemon_remote_exec(struct worker* worker)
|
||||
{
|
||||
/* read the cmd string */
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
if(!tube_read_msg(worker->cmd, &msg, &len, 0)) {
|
||||
log_err("daemon_remote_exec: tube_read_msg failed");
|
||||
return;
|
||||
}
|
||||
verbose(VERB_ALGO, "remote exec distributed: %s", (char*)msg);
|
||||
execute_cmd(NULL, NULL, (char*)msg, worker);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
/** handle remote control request */
|
||||
static void
|
||||
handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
@@ -1256,7 +1605,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
verbose(VERB_DETAIL, "control cmd: %s", buf);
|
||||
|
||||
/* figure out what to do */
|
||||
execute_cmd(rc, ssl, buf);
|
||||
execute_cmd(rc, ssl, buf, rc->worker);
|
||||
}
|
||||
|
||||
int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||
|
||||
+17
-3
@@ -96,10 +96,10 @@ struct daemon_remote {
|
||||
|
||||
/**
|
||||
* Create new remote control state for the daemon.
|
||||
* @param worker: worker with communication base. and links to command channels.
|
||||
* @param cfg: config file with key file settings.
|
||||
* @return new state, or NULL on failure.
|
||||
*/
|
||||
struct daemon_remote* daemon_remote_create(struct worker* worker);
|
||||
struct daemon_remote* daemon_remote_create(struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* remote control state to delete.
|
||||
@@ -107,6 +107,13 @@ struct daemon_remote* daemon_remote_create(struct worker* worker);
|
||||
*/
|
||||
void daemon_remote_delete(struct daemon_remote* rc);
|
||||
|
||||
/**
|
||||
* remote control state to clear up. Busy and accept points are closed.
|
||||
* Does not delete the rc itself, or the ssl context (with its keys).
|
||||
* @param rc: state to clear.
|
||||
*/
|
||||
void daemon_remote_clear(struct daemon_remote* rc);
|
||||
|
||||
/**
|
||||
* Open and create listening ports for remote control.
|
||||
* @param cfg: config options.
|
||||
@@ -119,10 +126,17 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
|
||||
* Setup comm points for accepting remote control connections.
|
||||
* @param rc: state
|
||||
* @param ports: already opened ports.
|
||||
* @param worker: worker with communication base. and links to command channels.
|
||||
* @return false on error.
|
||||
*/
|
||||
int daemon_remote_open_accept(struct daemon_remote* rc,
|
||||
struct listen_port* ports);
|
||||
struct listen_port* ports, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Handle nonthreaded remote cmd execution.
|
||||
* @param worker: this worker (the remote worker).
|
||||
*/
|
||||
void daemon_remote_exec(struct worker* worker);
|
||||
|
||||
/** handle remote control accept callbacks */
|
||||
int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*);
|
||||
|
||||
+16
-12
@@ -58,7 +58,7 @@ timeval_add(struct timeval* d, const struct timeval* add)
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
while(d->tv_usec > 1000000 ) {
|
||||
if(d->tv_usec > 1000000) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ get_rrset_bogus(struct worker* worker)
|
||||
}
|
||||
|
||||
void
|
||||
server_stats_compile(struct worker* worker, struct stats_info* s)
|
||||
server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -143,26 +143,26 @@ server_stats_compile(struct worker* worker, struct stats_info* s)
|
||||
/* get and reset validator rrset bogus number */
|
||||
s->svr.rrset_bogus = get_rrset_bogus(worker);
|
||||
|
||||
if(!worker->env.cfg->stat_cumulative) {
|
||||
server_stats_init(&worker->stats, worker->env.cfg);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
worker->back->unwanted_replies = 0;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker_stats_clear(worker);
|
||||
}
|
||||
}
|
||||
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s)
|
||||
struct stats_info* s, int reset)
|
||||
{
|
||||
uint8_t *reply = NULL;
|
||||
uint32_t len = 0;
|
||||
if(worker == who) {
|
||||
/* just fill it in */
|
||||
server_stats_compile(worker, s);
|
||||
server_stats_compile(worker, s, reset);
|
||||
return;
|
||||
}
|
||||
/* communicate over tube */
|
||||
verbose(VERB_ALGO, "write stats cmd");
|
||||
worker_send_cmd(who, worker_cmd_stats);
|
||||
if(reset)
|
||||
worker_send_cmd(who, worker_cmd_stats);
|
||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||
verbose(VERB_ALGO, "wait for stats reply");
|
||||
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
|
||||
fatal_exit("failed to read stats over cmd channel");
|
||||
@@ -173,10 +173,10 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
free(reply);
|
||||
}
|
||||
|
||||
void server_stats_reply(struct worker* worker)
|
||||
void server_stats_reply(struct worker* worker, int reset)
|
||||
{
|
||||
struct stats_info s;
|
||||
server_stats_compile(worker, &s);
|
||||
server_stats_compile(worker, &s, reset);
|
||||
verbose(VERB_ALGO, "write stats replymsg");
|
||||
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
|
||||
(uint8_t*)&s, sizeof(s), 0))
|
||||
@@ -197,6 +197,7 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.qtype_big += a->svr.qtype_big;
|
||||
total->svr.qclass_big += a->svr.qclass_big;
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
total->svr.qbit_TC += a->svr.qbit_TC;
|
||||
@@ -238,7 +239,8 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
}
|
||||
|
||||
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns)
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
uint16_t flags = ldns_buffer_read_u16_at(c->buffer, 2);
|
||||
if(qtype < STATS_QTYPE_NUM)
|
||||
@@ -250,6 +252,8 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp)
|
||||
stats->qtcp++;
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
stats->qipv6++;
|
||||
if( (flags&BIT_QR) )
|
||||
stats->qbit_QR++;
|
||||
if( (flags&BIT_AA) )
|
||||
|
||||
+16
-5
@@ -46,6 +46,7 @@
|
||||
struct worker;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
struct edns_data;
|
||||
|
||||
/** number of qtype that is stored for in array */
|
||||
@@ -87,6 +88,8 @@ struct server_stats {
|
||||
size_t qopcode[STATS_OPCODE_NUM];
|
||||
/** number of queries over TCP */
|
||||
size_t qtcp;
|
||||
/** number of queries over IPv6 */
|
||||
size_t qipv6;
|
||||
/** number of queries with QR bit */
|
||||
size_t qbit_QR;
|
||||
/** number of queries with AA bit */
|
||||
@@ -113,7 +116,7 @@ struct server_stats {
|
||||
size_t ans_rcode_nodata;
|
||||
/** answers that were secure (AD) */
|
||||
size_t ans_secure;
|
||||
/** answers with bogus content */
|
||||
/** answers that were bogus (withheld as SERVFAIL) */
|
||||
size_t ans_bogus;
|
||||
/** rrsets marked bogus by validator */
|
||||
size_t rrset_bogus;
|
||||
@@ -172,23 +175,29 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
* @param worker: the worker that is executing (the first worker).
|
||||
* @param who: on who to get the statistics info.
|
||||
* @param s: the stats block to fill in.
|
||||
* @param reset: if stats can be reset.
|
||||
*/
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s);
|
||||
struct stats_info* s, int reset);
|
||||
|
||||
/**
|
||||
* Compile stats into structure for this thread worker.
|
||||
* Also clears the statistics counters (if that is set by config file).
|
||||
* @param worker: the worker to compile stats for, also the executing worker.
|
||||
* @param s: stats block.
|
||||
* @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 stats_info* s,
|
||||
int reset);
|
||||
|
||||
/**
|
||||
* Send stats over comm tube in reply to query cmd
|
||||
* @param worker: this worker.
|
||||
* @param reset: if true, depending on config stats are reset.
|
||||
* if false, statistics are not reset.
|
||||
*/
|
||||
void server_stats_reply(struct worker* worker);
|
||||
void server_stats_reply(struct worker* worker, int reset);
|
||||
|
||||
/**
|
||||
* Addup stat blocks.
|
||||
@@ -204,9 +213,11 @@ void server_stats_add(struct stats_info* total, struct stats_info* a);
|
||||
* @param qtype: query type
|
||||
* @param qclass: query class
|
||||
* @param edns: edns record
|
||||
* @param repinfo: reply info with remote address
|
||||
*/
|
||||
void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns);
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
|
||||
struct comm_reply* repinfo);
|
||||
|
||||
/**
|
||||
* Add rcode for this query.
|
||||
|
||||
+95
-32
@@ -43,6 +43,7 @@
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
@@ -56,10 +57,16 @@
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef HAVE_LOGIN_CAP_H
|
||||
#include <login_cap.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_MINI_EVENT
|
||||
# ifdef USE_WINSOCK
|
||||
@@ -71,12 +78,17 @@
|
||||
# include <event.h>
|
||||
#endif
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
# include "winrc/win_svc.h"
|
||||
#endif
|
||||
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
void* unbound_start_brk = 0;
|
||||
|
||||
/** print usage. */
|
||||
static void usage()
|
||||
{
|
||||
const char** m;
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
@@ -84,14 +96,38 @@ static void usage()
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
printf(" install, remove - manage the services entry\n");
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("libevent %s, libldns %s, %s\n",
|
||||
event_get_version(), ldns_version(),
|
||||
printf("linked libs: event %s, ldns %s, %s\n",
|
||||
#ifdef USE_WINSOCK
|
||||
"winsock",
|
||||
#elif defined(USE_MINI_EVENT)
|
||||
"internal",
|
||||
#else
|
||||
event_get_version(),
|
||||
#endif
|
||||
ldns_version(),
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
printf("linked modules:");
|
||||
for(m = module_list_avail(); *m; m++)
|
||||
printf(" %s", *m);
|
||||
printf("\n");
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
}
|
||||
|
||||
#ifndef unbound_testbound
|
||||
int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** check file descriptor count */
|
||||
static void
|
||||
checkrlimits(struct config_file* cfg)
|
||||
@@ -175,27 +211,8 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
daemon->cfg = cfg;
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
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) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
msgreply_sizefunc, query_info_compare,
|
||||
query_entry_delete, reply_info_delete, NULL);
|
||||
if(!daemon->env->msg_cache) {
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
}
|
||||
if((daemon->env->rrset_cache = rrset_cache_adjust(
|
||||
daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache,
|
||||
cfg))==0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
daemon_apply_cfg(daemon, cfg);
|
||||
checkrlimits(cfg);
|
||||
}
|
||||
|
||||
@@ -291,6 +308,11 @@ checkoldpid(char* pidfile, int inchroot)
|
||||
static void
|
||||
detach(void)
|
||||
{
|
||||
#if defined(HAVE_DAEMON) && !defined(DEPRECATED_DAEMON)
|
||||
/* use POSIX daemon(3) function */
|
||||
if(daemon(1, 0) != 0)
|
||||
fatal_exit("daemon failed: %s", strerror(errno));
|
||||
#else /* no HAVE_DAEMON */
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
int fd;
|
||||
/* Take off... */
|
||||
@@ -316,6 +338,7 @@ detach(void)
|
||||
(void)close(fd);
|
||||
}
|
||||
#endif /* HAVE_WORKING_FORK */
|
||||
#endif /* HAVE_DAEMON */
|
||||
}
|
||||
|
||||
/** daemonize, drop user priviliges and chroot if needed */
|
||||
@@ -324,6 +347,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
const char** cfgfile)
|
||||
{
|
||||
#ifdef HAVE_GETPWNAM
|
||||
struct passwd *pwd = NULL;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
/* initialize, but not to 0 (root) */
|
||||
@@ -332,12 +356,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
log_assert(cfg);
|
||||
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
struct passwd *pwd;
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
uid = pwd->pw_uid;
|
||||
gid = pwd->pw_gid;
|
||||
endpwent();
|
||||
/* endpwent below, in case we need pwd for setusercontext */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -345,8 +368,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* a fork error could not be printed since daemonize closed stderr.*/
|
||||
if(cfg->use_syslog) {
|
||||
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
/* but syslog is not really opened by glibc until first msg */
|
||||
log_info("open syslog, startup in progress");
|
||||
}
|
||||
/* if using a logfile, we cannot open it because the logfile would
|
||||
* be created with the wrong permissions, we cannot chown it because
|
||||
@@ -354,6 +375,10 @@ 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 */
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/* check old pid file before forking */
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
@@ -389,11 +414,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
/* delete of pidfile could potentially work,
|
||||
* chown to get permissions */
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(chown(daemon->pidfile, uid, gid) == -1) {
|
||||
if(chown(daemon->pidfile, uid, gid) == -1) {
|
||||
fatal_exit("cannot chown %u.%u %s: %s",
|
||||
(unsigned)uid, (unsigned)gid,
|
||||
daemon->pidfile, strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,6 +452,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
if(!daemon->pidfile)
|
||||
log_err("out of memory in pidfile adjust");
|
||||
}
|
||||
daemon->chroot = strdup(cfg->chrootdir);
|
||||
if(!daemon->chroot)
|
||||
log_err("out of memory in daemon chroot dir storage");
|
||||
}
|
||||
#else
|
||||
(void)cfgfile;
|
||||
@@ -450,6 +478,22 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
/* drop permissions after chroot, getpwnam, pidfile, syslog done*/
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
#ifdef HAVE_SETUSERCONTEXT
|
||||
/* setusercontext does initgroups, setuid, setgid, and
|
||||
* also resource limits from login config, but we
|
||||
* still call setresuid, setresgid to be sure to set all uid*/
|
||||
if(setusercontext(NULL, pwd, uid, LOGIN_SETALL) != 0)
|
||||
log_warn("unable to setusercontext %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
#else /* !HAVE_SETUSERCONTEXT */
|
||||
# ifdef HAVE_INITGROUPS
|
||||
if(initgroups(cfg->username, gid) != 0)
|
||||
log_warn("unable to initgroups %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
# endif /* HAVE_INITGROUPS */
|
||||
#endif /* HAVE_SETUSERCONTEXT */
|
||||
endpwent();
|
||||
|
||||
#ifdef HAVE_SETRESGID
|
||||
if(setresgid(gid,gid,gid) != 0)
|
||||
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
|
||||
@@ -471,7 +515,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
verbose(VERB_QUERY, "drop user privileges, run as %s",
|
||||
cfg->username);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_GETPWNAM */
|
||||
/* file logging inited after chroot,chdir,setuid is done so that
|
||||
* it would succeed on SIGHUP as well */
|
||||
if(!cfg->use_syslog)
|
||||
@@ -502,7 +546,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
/* config stuff */
|
||||
if(!(cfg = config_create()))
|
||||
fatal_exit("Could not alloc config defaults");
|
||||
if(!config_read(cfg, cfgfile)) {
|
||||
if(!config_read(cfg, cfgfile, daemon->chroot)) {
|
||||
if(errno != ENOENT)
|
||||
fatal_exit("Could not read config file: %s",
|
||||
cfgfile);
|
||||
@@ -516,7 +560,11 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
if(!done_setup) {
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
done_setup = 1;
|
||||
} else log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
} else {
|
||||
/* reopen log after HUP to facilitate log rotation */
|
||||
if(!cfg->use_syslog)
|
||||
log_init(cfg->logfile, 0, cfg->chrootdir);
|
||||
}
|
||||
/* work */
|
||||
daemon_fork(daemon);
|
||||
|
||||
@@ -556,8 +604,10 @@ main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
const char* cfgfile = CONFIGFILE;
|
||||
const char* winopt = NULL;
|
||||
int cmdline_verbose = 0;
|
||||
int debug_mode = 0;
|
||||
int cmdline_cfg = 0;
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/* take debug snapshot of heap */
|
||||
@@ -566,10 +616,11 @@ main(int argc, char* argv[])
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhv")) != -1) {
|
||||
while( (c=getopt(argc, argv, "c:dhvw:")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
cfgfile = optarg;
|
||||
cmdline_cfg = 1;
|
||||
break;
|
||||
case 'v':
|
||||
cmdline_verbose ++;
|
||||
@@ -578,6 +629,9 @@ main(int argc, char* argv[])
|
||||
case 'd':
|
||||
debug_mode = 1;
|
||||
break;
|
||||
case 'w':
|
||||
winopt = optarg;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
@@ -588,6 +642,15 @@ main(int argc, char* argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_command_option(winopt, cfgfile, cmdline_verbose,
|
||||
cmdline_cfg);
|
||||
#else
|
||||
fatal_exit("option not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(argc != 0) {
|
||||
usage();
|
||||
return 1;
|
||||
|
||||
+115
-57
@@ -65,6 +65,8 @@
|
||||
#include "util/data/dname.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/tube.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "validator/autotrust.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@@ -73,6 +75,9 @@
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#ifdef UB_ON_WINDOWS
|
||||
#include "winrc/win_svc.h"
|
||||
#endif
|
||||
|
||||
/** Size of an UDP datagram */
|
||||
#define NORMAL_UDP_SIZE 512 /* bytes */
|
||||
@@ -158,7 +163,8 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
+ sizeof(worker->rndstate)
|
||||
+ regional_get_mem(worker->scratchpad)
|
||||
+ sizeof(*worker->env.scratch_buffer)
|
||||
+ ldns_buffer_capacity(worker->env.scratch_buffer);
|
||||
+ ldns_buffer_capacity(worker->env.scratch_buffer)
|
||||
+ forwards_get_mem(worker->env.fwds);
|
||||
if(cur_serv) {
|
||||
me += serviced_get_mem(cur_serv);
|
||||
}
|
||||
@@ -342,7 +348,15 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
|
||||
break;
|
||||
case worker_cmd_stats:
|
||||
verbose(VERB_ALGO, "got control cmd stats");
|
||||
server_stats_reply(worker);
|
||||
server_stats_reply(worker, 1);
|
||||
break;
|
||||
case worker_cmd_stats_noreset:
|
||||
verbose(VERB_ALGO, "got control cmd stats_noreset");
|
||||
server_stats_reply(worker, 0);
|
||||
break;
|
||||
case worker_cmd_remote:
|
||||
verbose(VERB_ALGO, "got control cmd remote");
|
||||
daemon_remote_exec(worker);
|
||||
break;
|
||||
default:
|
||||
log_err("bad command %d", (int)cmd);
|
||||
@@ -483,43 +497,6 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check cname chain in cache reply */
|
||||
static int
|
||||
check_cache_chain(struct reply_info* rep) {
|
||||
/* check only answer section rrs for matching cname chain.
|
||||
* the cache may return changed rdata, but owner names are untouched.*/
|
||||
size_t i;
|
||||
uint8_t* sname = rep->rrsets[0]->rk.dname;
|
||||
size_t snamelen = rep->rrsets[0]->rk.dname_len;
|
||||
for(i=0; i<rep->an_numrrsets; i++) {
|
||||
uint16_t t = ntohs(rep->rrsets[i]->rk.type);
|
||||
if(t == LDNS_RR_TYPE_DNAME)
|
||||
continue; /* skip dnames; note TTL 0 not cached */
|
||||
/* verify that owner matches current sname */
|
||||
if(query_dname_compare(sname, rep->rrsets[i]->rk.dname) != 0){
|
||||
/* cname chain broken */
|
||||
return 0;
|
||||
}
|
||||
/* if this is a cname; move on */
|
||||
if(t == LDNS_RR_TYPE_CNAME) {
|
||||
get_cname_target(rep->rrsets[i], &sname, &snamelen);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check security status in cache reply */
|
||||
static int
|
||||
all_rrsets_secure(struct reply_info* rep) {
|
||||
size_t i;
|
||||
for(i=0; i<rep->rrset_count; i++) {
|
||||
if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
|
||||
->security != sec_status_secure )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** answer query from the cache */
|
||||
static int
|
||||
answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
@@ -531,7 +508,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
int secure;
|
||||
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
|
||||
/* see if it is possible */
|
||||
if(rep->ttl <= timenow) {
|
||||
if(rep->ttl < timenow) {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
* we will refetch the message format from the
|
||||
* authoritative server
|
||||
@@ -545,7 +522,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_DNAME))) {
|
||||
if(!check_cache_chain(rep)) {
|
||||
if(!reply_check_cname_chain(rep)) {
|
||||
/* cname chain invalid, redo iterator steps */
|
||||
verbose(VERB_ALGO, "Cache reply: cname chain broken");
|
||||
bail_out:
|
||||
@@ -577,7 +554,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
"validation");
|
||||
goto bail_out; /* need to validate cache entry first */
|
||||
} else if(rep->security == sec_status_secure) {
|
||||
if(all_rrsets_secure(rep))
|
||||
if(reply_all_rrsets_secure(rep))
|
||||
secure = 1;
|
||||
else {
|
||||
if(must_validate) {
|
||||
@@ -741,6 +718,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
||||
verbose(VERB_ALGO, "worker check request: bad query.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
if(ret != -1) {
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
|
||||
@@ -753,6 +731,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
/* see if query is in the cache */
|
||||
if(!query_info_parse(&qinfo, c->buffer)) {
|
||||
verbose(VERB_ALGO, "worker parse request: formerror.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
ldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
@@ -762,6 +742,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
@@ -773,6 +754,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) {
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
ldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
@@ -784,6 +767,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||
*(uint16_t*)ldns_buffer_begin(c->buffer),
|
||||
ldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
@@ -794,10 +778,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||
(int)edns.udp_size);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
edns.udp_size = NORMAL_UDP_SIZE;
|
||||
}
|
||||
if(edns.edns_present && edns.udp_size < LDNS_HEADER_SIZE) {
|
||||
verbose(VERB_ALGO, "worker request: edns is too small.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_TC_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
@@ -810,7 +796,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if(worker->stats.extended)
|
||||
server_stats_insquery(&worker->stats, c, qinfo.qtype,
|
||||
qinfo.qclass, &edns);
|
||||
qinfo.qclass, &edns, repinfo);
|
||||
if(c->type != comm_udp)
|
||||
edns.udp_size = 65535; /* max size for TCP replies */
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
@@ -820,6 +806,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
|
||||
c->buffer, worker->scratchpad)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(ldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
@@ -868,6 +855,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
ldns_buffer_rewind(c->buffer);
|
||||
server_stats_querymiss(&worker->stats, worker);
|
||||
|
||||
if(verbosity >= VERB_CLIENT) {
|
||||
if(c->type == comm_udp)
|
||||
log_addr(VERB_CLIENT, "udp request from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
else log_addr(VERB_CLIENT, "tcp request from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
}
|
||||
|
||||
/* grab a work request structure for this new request */
|
||||
if(worker->env.mesh->num_reply_addrs>worker->request_size*16) {
|
||||
/* protect our memory usage from storing reply addresses */
|
||||
@@ -928,8 +923,10 @@ worker_restart_timer(struct worker* worker)
|
||||
{
|
||||
if(worker->env.cfg->stat_interval > 0) {
|
||||
struct timeval tv;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = worker->env.cfg->stat_interval;
|
||||
tv.tv_usec = 0;
|
||||
#endif
|
||||
comm_timer_set(worker->stat_timer, &tv);
|
||||
}
|
||||
}
|
||||
@@ -941,14 +938,24 @@ void worker_stat_timer_cb(void* arg)
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
worker_mem_report(worker, NULL);
|
||||
if(!worker->daemon->cfg->stat_cumulative) {
|
||||
server_stats_init(&worker->stats, worker->env.cfg);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
worker->back->unwanted_replies = 0;
|
||||
worker_stats_clear(worker);
|
||||
}
|
||||
/* start next timer */
|
||||
worker_restart_timer(worker);
|
||||
}
|
||||
|
||||
void worker_probe_timer_cb(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
struct timeval tv;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = (time_t)autr_probe_timer(&worker->env);
|
||||
tv.tv_usec = 0;
|
||||
#endif
|
||||
if(tv.tv_sec != 0)
|
||||
comm_timer_set(worker->env.probe_timer, &tv);
|
||||
}
|
||||
|
||||
struct worker*
|
||||
worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
{
|
||||
@@ -978,7 +985,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
{
|
||||
unsigned int seed;
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create();
|
||||
worker->base = comm_base_create(do_sigs);
|
||||
if(!worker->base) {
|
||||
log_err("could not create event handling base");
|
||||
worker_delete(worker);
|
||||
@@ -1010,18 +1017,16 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
return 0;
|
||||
}
|
||||
#endif /* LIBEVENT_SIGNAL_PROBLEM */
|
||||
if(!(worker->rc = daemon_remote_create(worker))) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
if(!daemon_remote_open_accept(worker->rc,
|
||||
worker->daemon->rc_ports)) {
|
||||
if(!daemon_remote_open_accept(worker->daemon->rc,
|
||||
worker->daemon->rc_ports, worker)) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_setup_worker(worker);
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
} else { /* !do_sigs */
|
||||
worker->comsig = NULL;
|
||||
worker->rc = NULL;
|
||||
}
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((unsigned int)worker->thread_num)<<17);
|
||||
@@ -1047,7 +1052,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
|
||||
cfg->unwanted_threshold, &worker_alloc_cleanup, worker);
|
||||
cfg->unwanted_threshold, &worker_alloc_cleanup, worker,
|
||||
cfg->do_udp);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1096,6 +1102,30 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker->env.kill_sub = &mesh_state_delete;
|
||||
worker->env.detect_cycle = &mesh_detect_cycle;
|
||||
worker->env.scratch_buffer = ldns_buffer_new(cfg->msg_buffer_size);
|
||||
if(!(worker->env.fwds = forwards_create()) ||
|
||||
!forwards_apply_cfg(worker->env.fwds, cfg)) {
|
||||
log_err("Could not set forward zones");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
/* one probe timer per process -- if we have 5011 anchors */
|
||||
if(autr_get_num_anchors(worker->env.anchors) > 0
|
||||
#ifndef THREADS_DISABLED
|
||||
&& worker->thread_num == 0
|
||||
#endif
|
||||
) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
worker->env.probe_timer = comm_timer_create(worker->base,
|
||||
worker_probe_timer_cb, worker);
|
||||
if(!worker->env.probe_timer) {
|
||||
log_err("could not create 5011-probe timer");
|
||||
} else {
|
||||
/* let timer fire, then it can reset itself */
|
||||
comm_timer_set(worker->env.probe_timer, &tv);
|
||||
}
|
||||
}
|
||||
if(!worker->env.mesh || !worker->env.scratch_buffer) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
@@ -1126,17 +1156,23 @@ worker_delete(struct worker* worker)
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
worker_mem_report(worker, NULL);
|
||||
}
|
||||
outside_network_quit_prepare(worker->back);
|
||||
mesh_delete(worker->env.mesh);
|
||||
ldns_buffer_free(worker->env.scratch_buffer);
|
||||
forwards_delete(worker->env.fwds);
|
||||
listen_delete(worker->front);
|
||||
outside_network_delete(worker->back);
|
||||
comm_signal_delete(worker->comsig);
|
||||
tube_delete(worker->cmd);
|
||||
comm_timer_delete(worker->stat_timer);
|
||||
daemon_remote_delete(worker->rc);
|
||||
comm_timer_delete(worker->env.probe_timer);
|
||||
free(worker->ports);
|
||||
if(worker->thread_num == 0)
|
||||
if(worker->thread_num == 0) {
|
||||
log_set_time(NULL);
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_desetup_worker(worker);
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
}
|
||||
comm_base_delete(worker->base);
|
||||
ub_randfree(worker->rndstate);
|
||||
alloc_clear(&worker->alloc);
|
||||
@@ -1198,6 +1234,13 @@ worker_alloc_cleanup(void* arg)
|
||||
slabhash_clear(worker->env.msg_cache);
|
||||
}
|
||||
|
||||
void worker_stats_clear(struct worker* worker)
|
||||
{
|
||||
server_stats_init(&worker->stats, worker->env.cfg);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
worker->back->unwanted_replies = 0;
|
||||
}
|
||||
|
||||
/* --- fake callbacks for fptr_wlist to work --- */
|
||||
int libworker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
@@ -1241,6 +1284,20 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
@@ -1258,3 +1315,4 @@ int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -43,7 +43,6 @@
|
||||
#ifndef DAEMON_WORKER_H
|
||||
#define DAEMON_WORKER_H
|
||||
|
||||
#include "config.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/alloc.h"
|
||||
@@ -66,7 +65,11 @@ enum worker_commands {
|
||||
/** make the worker quit */
|
||||
worker_cmd_quit,
|
||||
/** obtain statistics */
|
||||
worker_cmd_stats
|
||||
worker_cmd_stats,
|
||||
/** obtain statistics without statsclear */
|
||||
worker_cmd_stats_noreset,
|
||||
/** execute remote control command */
|
||||
worker_cmd_remote
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -98,8 +101,6 @@ struct worker {
|
||||
struct comm_point* cmd_com;
|
||||
/** timer for statistics */
|
||||
struct comm_timer* stat_timer;
|
||||
/** remote control state (for first thread only) */
|
||||
struct daemon_remote* rc;
|
||||
|
||||
/** number of requests that can be handled by this worker */
|
||||
size_t request_size;
|
||||
@@ -226,7 +227,16 @@ int worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||
/** cleanup the cache to remove all rrset IDs from it, arg is worker */
|
||||
void worker_alloc_cleanup(void* arg);
|
||||
|
||||
/**
|
||||
* Init worker stats - includes server_stats_init, outside network and mesh.
|
||||
* @param worker: the worker to init
|
||||
*/
|
||||
void worker_stats_clear(struct worker* worker);
|
||||
|
||||
/** statistics timer callback handler */
|
||||
void worker_stat_timer_cb(void* arg);
|
||||
|
||||
/** probe timer callback handler */
|
||||
void worker_probe_timer_cb(void* arg);
|
||||
|
||||
#endif /* DAEMON_WORKER_H */
|
||||
|
||||
+5
-1
@@ -11,6 +11,10 @@ At NLnet Labs, Jelte Jansen, Mark Santcroos and Matthijs Mekking
|
||||
reviewed the unbound C sources.
|
||||
|
||||
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
|
||||
|
||||
Ondřej Surý - running coverity analysis tool on 0.9 dev version.
|
||||
Alexander Gall - multihomed, anycast testing of unbound resolver server.
|
||||
Zdenek Vasicek and Marek Vavrusa - python module.
|
||||
cz.nic - sponsoring 'summer of code' development by Zdenek and Marek.
|
||||
Brett Carr - windows beta testing.
|
||||
Luca Bruno - patch for windows support in libunbound hosts and resolvconf().
|
||||
Tom Hendrikx - contributed split-itar.sh a useful script to 5011-track ITAR.
|
||||
|
||||
+954
@@ -1,8 +1,962 @@
|
||||
23 November 2009: Wouter
|
||||
- Patch from David Hubbard for libunbound manual page.
|
||||
- Fixup endless spinning in unbound-control stats reported by
|
||||
Attila Nagy. Probably caused by clock reversal.
|
||||
|
||||
20 November 2009: Wouter
|
||||
- contrib/split-itar.sh contributed by Tom Hendrikx.
|
||||
|
||||
19 November 2009: Wouter
|
||||
- better argument help for unbound-control.
|
||||
- iana portlist updated.
|
||||
|
||||
17 November 2009: Wouter
|
||||
- noted multiple entries for multiple domain names in example.conf.
|
||||
- iana portlist updated.
|
||||
|
||||
16 November 2009: Wouter
|
||||
- Fixed signer detection of CNAME responses without signatures.
|
||||
- Fix#282 libunbound memleak on error condition by Eric Sesterhenn.
|
||||
- Tests for CNAMEs to deeper trust anchors, secure and bogus.
|
||||
- svn tag 1.4.0rc1 made.
|
||||
|
||||
13 November 2009: Wouter
|
||||
- Fixed validation failure for CNAME to optout NSEC3 nodata answer.
|
||||
- unbound-host does not fail on type ANY.
|
||||
- Fixed wireparse failure to put RRSIGs together with data in some
|
||||
long ANY mix cases, which fixes validation failures.
|
||||
|
||||
12 November 2009: Wouter
|
||||
- iana portlist updated.
|
||||
- fix manpage errors reported by debian lintian.
|
||||
- review comments.
|
||||
- fixup very long vallog2 level error strings.
|
||||
|
||||
11 November 2009: Wouter
|
||||
- ldns tarball updated (to 1.6.2).
|
||||
- review comments.
|
||||
|
||||
10 November 2009: Wouter
|
||||
- Thanks to Surfnet found bug in new dnssec-retry code that failed
|
||||
to combine well when combined with DLV and a particular failure.
|
||||
- Fixed unbound-control -h output about argument optionality.
|
||||
- review comments.
|
||||
|
||||
5 November 2009: Wouter
|
||||
- lint fixes and portability tests.
|
||||
- better error text for multiple domain keys in one autotrust file.
|
||||
|
||||
2 November 2009: Wouter
|
||||
- Fix bug where autotrust does not work when started with a DS.
|
||||
- Updated GOST unit tests for unofficial algorithm number 249
|
||||
and DNSKEY-format changes in draft version -01.
|
||||
|
||||
29 October 2009: Wouter
|
||||
- iana portlist updated.
|
||||
- edns-buffer-size option, default 4096.
|
||||
- fixed do-udp: no.
|
||||
|
||||
28 October 2009: Wouter
|
||||
- removed abort on prealloc failure, error still printed but softfail.
|
||||
- iana portlist updated.
|
||||
- RFC 5702: RSASHA256 and RSASHA512 support enabled by default.
|
||||
- ldns tarball updated (which also enables rsasha256 support).
|
||||
|
||||
27 October 2009: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
8 October 2009: Wouter
|
||||
- please doxygen
|
||||
- add val-log-level print to corner case (nameserver.epost.bg).
|
||||
- more detail to errors from insecure delegation checks.
|
||||
- Fix double time subtraction in negative cache reported by
|
||||
Amanda Constant and Hugh Mahon.
|
||||
- Made new validator error string available from libunbound for
|
||||
applications. It is in result->why_bogus, a zero-terminated string.
|
||||
unbound-host prints it by default if a result is bogus.
|
||||
Also the errinf is public in module_qstate (for other modules).
|
||||
|
||||
7 October 2009: Wouter
|
||||
- retry for validation failure in DS and prime results. Less mem use.
|
||||
unit test. Provisioning in other tests for requeries.
|
||||
- retry for validation failure in DNSKEY in middle of chain of trust.
|
||||
unit test.
|
||||
- retry for empty non terminals in chain of trust and unit test.
|
||||
- Fixed security bug where the signatures for NSEC3 records were not
|
||||
checked when checking for absence of DS records. This could have
|
||||
enabled the substitution of an insecure delegation.
|
||||
- moved version number to 1.4.0 because of 1.3.4 release with only
|
||||
the NSEC3 patch from the entry above.
|
||||
- val-log-level: 2 shows extended error information for validation
|
||||
failures, but still one (longish) line per failure. For example:
|
||||
validation failure <example.com. DNSKEY IN>: signature expired from
|
||||
192.0.2.4 for trust anchor example.com. while building chain of trust
|
||||
validation failure <www.example.com. A IN>: no signatures from
|
||||
192.0.2.6 for key example.com. while building chain of trust
|
||||
|
||||
6 October 2009: Wouter
|
||||
- Test set updated to provide additional ns lookup result.
|
||||
The retry would attempt to fetch the data from other nameservers
|
||||
for bogus data, and this needed to be provisioned in the tests.
|
||||
|
||||
5 October 2009: Wouter
|
||||
- first validation failure retry code. Retries for data failures.
|
||||
And unit test.
|
||||
|
||||
2 October 2009: Wouter
|
||||
- improve 5011 modularization.
|
||||
- fix unbound-host so -d can be given before -C.
|
||||
- iana portlist updated.
|
||||
|
||||
28 September 2009: Wouter
|
||||
- autotrust-anchor-file can read multiline input and $ORIGIN.
|
||||
- prevent integer overflow in holddown calculation. review fixes.
|
||||
- fixed race condition in trust point revocation. review fix.
|
||||
- review fixes to comments, removed unused code.
|
||||
|
||||
25 September 2009: Wouter
|
||||
- so-rcvbuf: 4m option added. Set this on large busy servers to not
|
||||
drop the occasional packet in spikes due to full socket buffers.
|
||||
netstat -su keeps a counter of UDP dropped due to full buffers.
|
||||
- review of validator/autotrust.c, small fixes and comments.
|
||||
|
||||
23 September 2009: Wouter
|
||||
- 5011 query failed counts verification failures, not lookup failures.
|
||||
- 5011 probe failure handling fixup.
|
||||
- test unbound reading of original autotrust data.
|
||||
The metadata per-key, such as key state (PENDING, MISSING, VALID) is
|
||||
picked up, otherwise performs initial probe like usual.
|
||||
|
||||
22 September 2009: Wouter
|
||||
- autotrust test with algorithm rollover, new ordering of checks
|
||||
assists in orderly rollover.
|
||||
- autotrust test with algorithm rollover to unknown algorithm.
|
||||
checks if new keys are supported before adding them.
|
||||
- autotrust test with trust point revocation, becomes unsigned.
|
||||
- fix DNSSEC-missing-signature detection for minimal responses
|
||||
for qtype DNSKEY (assumes DNSKEY occurs at zone apex).
|
||||
|
||||
18 September 2009: Wouter
|
||||
- autotrust tests, fix trustpoint timer deletion code.
|
||||
fix count of valid anchors during missing remove.
|
||||
- autotrust: pick up REVOKE even if not signed with known other keys.
|
||||
|
||||
17 September 2009: Wouter
|
||||
- fix compile of unbound-host when --enable-alloc-checks.
|
||||
- Fix lookup problem reported by Koh-ichi Ito and Jaap Akkerhuis.
|
||||
- Manual page fixes reported by Tony Finch.
|
||||
|
||||
16 September 2009: Wouter
|
||||
- Fix memory leak reported by Tao Ma.
|
||||
- Fix memstats test tool for log-time-ascii log format.
|
||||
|
||||
15 September 2009: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
10 September 2009: Wouter
|
||||
- increased MAXSYSLOGLEN so .bg key can be printed in debug output.
|
||||
- use linebuffering for log-file: output, this can be significantly
|
||||
faster than the previous fflush method and enable some class of
|
||||
resolvers to use high verbosity (for short periods).
|
||||
Not on windows, because line buffering does not work there.
|
||||
|
||||
9 September 2009: Wouter
|
||||
- Fix bug where DNSSEC-bogus messages were marked with too high TTL.
|
||||
The RRsets would still expire at the normal time, but this would
|
||||
keep messages bogus in the cache for too long.
|
||||
- regression test for that bug.
|
||||
- documented that load_cache is meant for debugging.
|
||||
|
||||
8 September 2009: Wouter
|
||||
- fixup printing errors when load_cache, they were printed to the
|
||||
SSL connection which broke, now to the log.
|
||||
- new ldns - with fixed parse of large SOA values.
|
||||
|
||||
7 September 2009: Wouter
|
||||
- autotrust testbound scenarios.
|
||||
- autotrust fix that failure count is written to file.
|
||||
- autotrust fix that keys may become valid after add holddown time
|
||||
alone, before the probe returns.
|
||||
|
||||
4 September 2009: Wouter
|
||||
- Changes to make unbound work with libevent-2.0.3 alpha. (in
|
||||
configure detection due to new ssl dependency in libevent)
|
||||
- do not call sphinx for documentation when python is disabled.
|
||||
- remove EV_PERSIST from libevent timeout code to make the code
|
||||
compatible with the libevent-2.0. Works with older libevent too.
|
||||
- fix memory leak in python code.
|
||||
|
||||
3 September 2009: Wouter
|
||||
- Got a patch from Luca Bruno for libunbound support on windows to
|
||||
pick up the system resolvconf nameservers and hosts there.
|
||||
- included ldns updated (enum warning fixed).
|
||||
- makefile fix for parallel makes.
|
||||
- Patch from Zdenek Vasicek and Attila Nagy for using the source IP
|
||||
from python scripts. See pythonmod/examples/resip.py.
|
||||
- doxygen comment fixes.
|
||||
|
||||
2 September 2009: Wouter
|
||||
- TRAFFIC keyword for testbound. Simplifies test generation.
|
||||
${range lower val upper} to check probe timeout values.
|
||||
- test with 5011-prepublish rollover and revocation.
|
||||
- fix revocation of RR for autotrust, stray exclamation mark.
|
||||
|
||||
1 September 2009: Wouter
|
||||
- testbound variable arithmetic.
|
||||
- autotrust probe time is randomised.
|
||||
- autotrust: the probe is active and does not fetch from cache.
|
||||
|
||||
31 August 2009: Wouter
|
||||
- testbound variable processing.
|
||||
|
||||
28 August 2009: Wouter
|
||||
- fixup unbound-control lookup to print forward and stub servers.
|
||||
|
||||
27 August 2009: Wouter
|
||||
- autotrust: mesh answer callback is empty.
|
||||
|
||||
26 August 2009: Wouter
|
||||
- autotrust probing.
|
||||
- iana portlist updated.
|
||||
|
||||
25 August 2009: Wouter
|
||||
- fixup memleak in trust anchor unsupported algorithm check.
|
||||
- iana portlist updated.
|
||||
- autotrust options: add-holddown, del-holddown, keep-missing.
|
||||
- autotrust store revoked status of trust points.
|
||||
- ctime_r compat definition.
|
||||
- detect yylex_destroy() in configure.
|
||||
- detect SSL_get_compression_methods declaration in configure.
|
||||
- fixup DS lookup at anchor point with unsigned parent.
|
||||
- fixup DLV lookup for DS queries to unsigned domains.
|
||||
|
||||
24 August 2009: Wouter
|
||||
- cleaner memory allocation on exit. autotrust test routines.
|
||||
- free all memory on program exit, fix for ssl and flex.
|
||||
|
||||
21 August 2009: Wouter
|
||||
- autotrust: debug routines. Read,write and conversions work.
|
||||
|
||||
20 August 2009: Wouter
|
||||
- autotrust: save and read trustpoint variables.
|
||||
|
||||
19 August 2009: Wouter
|
||||
- autotrust: state table updates.
|
||||
- iana portlist updated.
|
||||
|
||||
17 August 2009: Wouter
|
||||
- autotrust: process events.
|
||||
|
||||
17 August 2009: Wouter
|
||||
- Fix so that servers are only blacklisted if they fail to reply
|
||||
to 16 queries in a row and the timeout gets above 2 minutes.
|
||||
- autotrust work, split up DS verification of DNSKEYs.
|
||||
|
||||
14 August 2009: Wouter
|
||||
- unbound-control lookup prints out infra cache information, like RTT.
|
||||
- Fix bug in DLV lookup reported by Amanda from Secure64.
|
||||
It could sometimes wrongly classify a domain as unsigned, which
|
||||
does not give the AD bit on replies.
|
||||
|
||||
13 August 2009: Wouter
|
||||
- autotrust read anchor files. locked trust anchors.
|
||||
|
||||
12 August 2009: Wouter
|
||||
- autotrust import work.
|
||||
|
||||
11 August 2009: Wouter
|
||||
- Check for openssl compatible with gost if enabled.
|
||||
- updated unit test for GOST=211 code.
|
||||
Nicer naming of test files.
|
||||
- iana portlist updated.
|
||||
|
||||
7 August 2009: Wouter
|
||||
- call OPENSSL_config() in unbound and unit test so that the
|
||||
operator can use openssl.cnf for configuration options.
|
||||
- removed small memory leak from config file reader.
|
||||
|
||||
6 August 2009: Wouter
|
||||
- configure --enable-gost for GOST support, experimental
|
||||
implementation of draft-dolmatov-dnsext-dnssec-gost-01.
|
||||
- iana portlist updated.
|
||||
- ldns tarball updated (with GOST support).
|
||||
|
||||
5 August 2009: Wouter
|
||||
- trunk moved to 1.3.4.
|
||||
|
||||
4 August 2009: Wouter
|
||||
- Added test that the examples from draft rsasha256-14 verify.
|
||||
- iana portlist updated.
|
||||
- tagged 1.3.3
|
||||
|
||||
3 August 2009: Wouter
|
||||
- nicer warning when algorithm not supported, tells you to upgrade.
|
||||
- iana portlist updated.
|
||||
|
||||
27 July 2009: Wouter
|
||||
- Updated unbound-cacti contribution from Dmitriy Demidov, with
|
||||
the queue statistics displayed in its own graph.
|
||||
- iana portlist updated.
|
||||
|
||||
22 July 2009: Wouter
|
||||
- Fix bug found by Michael Tokarev where unbound would try to
|
||||
prime the root servers even though forwarders are configured for
|
||||
the root.
|
||||
- tagged 1.3.3rc1
|
||||
|
||||
21 July 2009: Wouter
|
||||
- Fix server selection, so that it waits for open target queries when
|
||||
faced with lameness.
|
||||
|
||||
20 July 2009: Wouter
|
||||
- Ignore transient sendto errors, no route to host, and host, net down.
|
||||
- contrib/update-anchor.sh has -r option for root-hints.
|
||||
- feature val-log-level: 1 prints validation failures so you can
|
||||
keep track of them during dnssec deployment.
|
||||
|
||||
16 July 2009: Wouter
|
||||
- fix replacement malloc code. Used in crosscompile.
|
||||
- makedist -w creates crosscompiled setup.exe on fedora11.
|
||||
|
||||
15 July 2009: Wouter
|
||||
- dependencies for compat items, for crosscompile.
|
||||
- mingw32 crosscompile changes, dependencies and zipfile creation.
|
||||
and with System.dll from the windows NSIS you can make setup.exe.
|
||||
- package libgcc_s_sjlj exception handler for NSISdl.dll.
|
||||
|
||||
14 July 2009: Wouter
|
||||
- updated ldns tarball for solaris x64 compile assistance.
|
||||
- no need to define RAND_MAX from config.h.
|
||||
- iana portlist updated.
|
||||
- configure changes and ldns update for mingw32 crosscompile.
|
||||
|
||||
13 July 2009: Wouter
|
||||
- Fix for crash at start on windows.
|
||||
- tag for release 1.3.2.
|
||||
- trunk has version 1.3.3.
|
||||
- Fix for ID bits on windows to use all 16. RAND_MAX was not
|
||||
defined like you'd expect on mingw. Reported by Mees de Roo.
|
||||
|
||||
9 July 2009: Wouter
|
||||
- tag for release 1.3.1.
|
||||
- trunk has version 1.3.2.
|
||||
|
||||
7 July 2009: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
6 July 2009: Wouter
|
||||
- prettier error handling in SSL setup.
|
||||
- makedist.sh uname fix (same as ldns).
|
||||
- updated fedora spec file.
|
||||
|
||||
3 July 2009: Wouter
|
||||
- fixup linking when ldnsdir is "".
|
||||
|
||||
30 June 2009: Wouter
|
||||
- more lenient truncation checks.
|
||||
|
||||
29 June 2009: Wouter
|
||||
- ldns trunk r2959 imported as tarball, because of solaris cc compile
|
||||
support for c99. r2960 for better configure.
|
||||
- better wrongly_truncated check.
|
||||
- On Linux, fragment IPv6 datagrams to the IPv6 minimum MTU, to
|
||||
avoid dropped packets at routers.
|
||||
|
||||
26 June 2009: Wouter
|
||||
- Fix EDNS fallback when EDNS works for short answers but long answers
|
||||
are dropped.
|
||||
|
||||
22 June 2009: Wouter
|
||||
- fixup iter priv strict aliasing while preserving size of sockaddr.
|
||||
- iana portlist updated. (one less port allocated, one more fraction
|
||||
of a bit for security!)
|
||||
- updated fedora specfile in contrib from Paul Wouters.
|
||||
|
||||
19 June 2009: Wouter
|
||||
- Fixup strict aliasing warning in iter priv code.
|
||||
and config_file code.
|
||||
- iana portlist updated.
|
||||
- harden-referral-path: handle cases where NS is in answer section.
|
||||
|
||||
18 June 2009: Wouter
|
||||
- Fix of message parse bug where (specifically) an NSEC and RRSIG
|
||||
in the wrong order would be parsed, but put wrongly into internal
|
||||
structures so that later validation would fail.
|
||||
- Extreme lenience for wrongly truncated replies where a positive
|
||||
reply has an NS in the authority but no signatures. They are
|
||||
turned into minimal responses with only the (secure) answer.
|
||||
- autoconf 2.63 for configure.
|
||||
- python warnings suppress. Keep python API away from header files.
|
||||
|
||||
17 June 2009: Wouter
|
||||
- CREDITS entry for cz.nic, sponsoring a 'summer of code' that was
|
||||
used for the python code in unbound. (http://www.nic.cz/vip/ in cz).
|
||||
|
||||
16 June 2009: Wouter
|
||||
- Fixup opportunistic target query generation to it does not
|
||||
generate queries that are known to fail.
|
||||
- Touchup on munin total memory report.
|
||||
- messages picked out of the cache by the iterator are checked
|
||||
if their cname chain is still correct and if validation status
|
||||
has to be reexamined.
|
||||
|
||||
15 June 2009: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
14 June 2009: Wouter
|
||||
- Fixed bug where cached responses would lose their security
|
||||
status on second validation, which especially impacted dlv
|
||||
lookups. Reported by Hauke Lampe.
|
||||
|
||||
13 June 2009: Wouter
|
||||
- bug #254. removed random whitespace from example.conf.
|
||||
|
||||
12 June 2009: Wouter
|
||||
- Fixup potential wrong NSEC picked out of the cache.
|
||||
- If unfulfilled callbacks are deleted they are called with an error.
|
||||
- fptr wlist checks for mesh callbacks.
|
||||
- fwd above stub in configuration works.
|
||||
|
||||
11 June 2009: Wouter
|
||||
- Fix queries for type DS when forward or stub zones are there.
|
||||
They are performed to higherup domains, and thus treated as if
|
||||
going to higher zones when looking up the right forward or stub
|
||||
server. This makes a stub pointing to a local server that has
|
||||
a local view of example.com signed with the same keys as are
|
||||
publicly used work. Reported by Johan Ihren.
|
||||
- Added build-unbound-localzone-from-hosts.pl to contrib, from
|
||||
Dennis DeDonatis. It converts /etc/hosts into config statements.
|
||||
- same thing fixed for forward-zone and DS, chain of trust from
|
||||
public internet into the forward-zone works now. Added unit test.
|
||||
|
||||
9 June 2009: Wouter
|
||||
- openssl key files are opened apache-style, when user is root and
|
||||
before chrooting. This makes permissions on remote-control key
|
||||
files easier to set up. Fixes bug #251.
|
||||
- flush_type and flush_name remove msg cache entries.
|
||||
- codereview - dp copy bogus setting fix.
|
||||
|
||||
8 June 2009: Wouter
|
||||
- Removed RFC5011 REVOKE flag support. Partial 5011 support may cause
|
||||
inadvertant behaviour.
|
||||
- 1.3.0 tarball for release created.
|
||||
- 1.3.1 development in svn trunk.
|
||||
- iana portlist updated.
|
||||
- fix lint from complaining on ldns/sha.h.
|
||||
- help compiler figure out aliasing in priv_rrset_bad() routine.
|
||||
- fail to configure with python if swig is not found.
|
||||
- unbound_munin_ in contrib uses ps to show rss if sbrk does not work.
|
||||
|
||||
3 June 2009: Wouter
|
||||
- fixup bad free() when wrongly encoded DSA signature is seen.
|
||||
Reported by Paul Wouters.
|
||||
- review comments from Matthijs.
|
||||
|
||||
2 June 2009: Wouter
|
||||
- --enable-sha2 option. The draft rsasha256 changed its algorithm
|
||||
numbers too often. Therefore it is more prudent to disable the
|
||||
RSASHA256 and RSASHA512 support by default.
|
||||
- ldns trunk included as new tarball.
|
||||
- recreated the 1.3.0 tag in svn. rc1 tarball generated at this point.
|
||||
|
||||
29 May 2009: Wouter
|
||||
- fixup doc bug in README reported by Matthew Dempsky.
|
||||
|
||||
28 May 2009: Wouter
|
||||
- update iana port list
|
||||
- update ldns lib tarball
|
||||
|
||||
27 May 2009: Wouter
|
||||
- detect lack of IPv6 support on XP (with a different error code).
|
||||
- Fixup a crash-on-exit which was triggered by a very long queue.
|
||||
Unbound would try to re-use ports that came free, but this is
|
||||
of course not really possible because everything is deleted.
|
||||
Most easily triggered on XP (not Vista), maybe because of the
|
||||
network stack encouraging large messages backlogs.
|
||||
- change in debug statements.
|
||||
- Fixed bug that could cause a crash if root prime failed when there
|
||||
were message backlogs.
|
||||
|
||||
26 May 2009: Wouter
|
||||
- Thanks again to Brett Carr, found an assertion that was not true.
|
||||
Assertion checked if recursion parent query still existed.
|
||||
|
||||
29 April 2009: Wouter
|
||||
- Thanks to Brett Carr, caught windows resource leak, use
|
||||
closesocket() and not close() on sockets or else the network stack
|
||||
starts to leak handles.
|
||||
- Removed usage of windows Mutex because windows cannot handle enough
|
||||
mutexes open. Provide own mutex implementation using primitives.
|
||||
|
||||
28 April 2009: Wouter
|
||||
- created svn tag for 1.3.0.
|
||||
|
||||
27 April 2009: Wouter
|
||||
- optimised cname from cache.
|
||||
- ifdef windows functions in testbound.
|
||||
|
||||
23 April 2009: Wouter
|
||||
- fix for threadsafety in solaris thr_key_create() in tests.
|
||||
- iana portlist updated.
|
||||
- fix pylib test for Darwin.
|
||||
- fix pymod test for Darwin and a python threading bug in pymod init.
|
||||
- check python >= 2.4 in configure.
|
||||
- -ldl check for libcrypto 1.0.0beta.
|
||||
|
||||
21 April 2009: Wouter
|
||||
- fix for build outside sourcedir.
|
||||
- fix for configure script swig detection.
|
||||
|
||||
17 April 2009: Wouter
|
||||
- Fix reentrant in minievent handler for unix. Could have resulted
|
||||
in spurious event callbacks.
|
||||
- timers do not take up a fd slot for winsock handler.
|
||||
- faster fix for winsock reentrant check.
|
||||
- fix rsasha512 unit test for new (interim) algorithm number.
|
||||
- fix test:ldns doesn't like DOS line endings in keyfiles on unix.
|
||||
- fix compile warning on ubuntu (configlexer fwrite return value).
|
||||
- move python include directives into CPPFLAGS instead of CFLAGS.
|
||||
|
||||
16 April 2009: Wouter
|
||||
- winsock event handler exit very quickly on signal, even if
|
||||
under heavy load.
|
||||
- iana portlist updated.
|
||||
- fixup windows winsock handler reentrant problem.
|
||||
|
||||
14 April 2009: Wouter
|
||||
- bug #245: fix munin plugin, perform cleanup of stale lockfiles.
|
||||
- makedist.sh; better help text.
|
||||
- cache-min-ttl option and tests.
|
||||
- mingw detect error condition on TCP sockets (NOTCONN).
|
||||
|
||||
9 April 2009: Wouter
|
||||
- Fix for removal of RSASHA256_NSEC3 protonumber from ldns.
|
||||
- ldns tarball updated.
|
||||
- iana portlist update.
|
||||
- detect GOST support in openssl-1.0.0-beta1, and fix compile problem
|
||||
because that openssl defines the name STRING for itself.
|
||||
|
||||
6 April 2009: Wouter
|
||||
- windows compile fix.
|
||||
- Detect FreeBSD jail without ipv6 addresses assigned.
|
||||
- python libunbound wrapper unit test.
|
||||
- installs the following files. Default is to not build them.
|
||||
from configure --with-pythonmodule:
|
||||
/usr/lib/python2.x/site-packages/unboundmodule.py
|
||||
from configure --with-pyunbound:
|
||||
/usr/lib/python2.x/site-packages/unbound.py
|
||||
/usr/lib/python2.x/site-packages/_unbound.so*
|
||||
The example python scripts (pythonmod/examples and
|
||||
libunbound/python/examples) are not installed.
|
||||
- python invalidate routine respects packed rrset ids and locks.
|
||||
- clock skew checks in unbound, config statements.
|
||||
- nxdomain ttl considerations in requirements.txt
|
||||
|
||||
3 April 2009: Wouter
|
||||
- Fixed a bug that caused messages to be stored in the cache too
|
||||
long. Hard to trigger, but NXDOMAINs for nameservers or CNAME
|
||||
targets have been more vulnerable to the TTL miscalculation bug.
|
||||
- documentation test fixed for python addition.
|
||||
|
||||
2 April 2009: Wouter
|
||||
- pyunbound (libunbound python plugin) compiles using libtool.
|
||||
- documentation for pythonmod and pyunbound is generated in doc/html.
|
||||
- iana portlist updated.
|
||||
- fixed bug in unbound-control flush_zone where it would not flush
|
||||
every message in the target domain. This especially impacted
|
||||
NXDOMAIN messages which could remain in the cache regardless.
|
||||
- python module test package.
|
||||
|
||||
1 April 2009: Wouter
|
||||
- suppress errors when trying to contact authority servers that gave
|
||||
ipv6 AAAA records for their nameservers with ipv4 mapped contents.
|
||||
Still tries to do so, could work when deployed in intranet.
|
||||
Higher verbosity shows the error.
|
||||
- new libunbound calls documented.
|
||||
- pyunbound in libunbound/python. Removed compile warnings.
|
||||
Makefile to make it.
|
||||
|
||||
30 March 2009: Wouter
|
||||
- Fixup LDFLAGS from libevent sourcedir compile configure restore.
|
||||
- Fixup so no non-absolute rpaths are added.
|
||||
- Fixup validation of RRSIG queries, they are let through.
|
||||
- read /dev/random before chroot
|
||||
- checkconf fix no python checks when no python module enabled.
|
||||
- fix configure, pthread first, so other libs do not change outcome.
|
||||
|
||||
27 March 2009: Wouter
|
||||
- nicer -h output. report linked libraries and modules.
|
||||
- prints modules in intuitive order (config file friendly).
|
||||
- python compiles easily on BSD.
|
||||
|
||||
26 March 2009: Wouter
|
||||
- ignore swig varargs warnings with gcc.
|
||||
- remove duplicate example.conf text from python example configs.
|
||||
- outofdir compile fix for python.
|
||||
- pyunbound works.
|
||||
- print modules compiled in on -h. manpage.
|
||||
|
||||
25 March 2009: Wouter
|
||||
- initial import of the python contribution from Zdenek Vasicek and
|
||||
Marek Vavrusa.
|
||||
- pythonmod in Makefile; changes to remove warnings/errors for 1.3.0.
|
||||
|
||||
24 March 2009: Wouter
|
||||
- more neat configure.ac. Removed duplicate config.h includes.
|
||||
- neater config.h.in.
|
||||
- iana portlist updated.
|
||||
- fix util/configlexer.c and solaris -std=c99 flag.
|
||||
- fix postcommit aclocal errors.
|
||||
- spaces stripped. Makefile cleaner, /usr omitted from -I, -L, -R.
|
||||
- swap order of host detect and libtool generation.
|
||||
|
||||
23 March 2009: Wouter
|
||||
- added launchd plist example file for MacOSX to contrib.
|
||||
- deprecation test for daemon(3).
|
||||
- moved common configure actions to m4 include, prettier Makefile.
|
||||
|
||||
20 March 2009: Wouter
|
||||
- bug #239: module-config entries order is important. Documented.
|
||||
- build fix for test asynclook.
|
||||
|
||||
19 March 2009: Wouter
|
||||
- winrc/README.txt dos-format text file.
|
||||
- iana portlist updated.
|
||||
- use _beginthreadex() when available (performs stack alignment).
|
||||
- defaults for windows baked into configure.ac (used if on mingw).
|
||||
|
||||
18 March 2009: Wouter
|
||||
- Added tests, unknown algorithms become insecure. fallback works.
|
||||
- Fix for and test for unknown algorithms in a trust anchor
|
||||
definition. Trust anchors with no supported algos are ignored.
|
||||
This means a (higher)DS or DLV entry for them could succeed, and
|
||||
otherwise they are treated as insecure.
|
||||
- domain-insecure: "example.com" statement added. Sets domain
|
||||
insecure regardless of chain of trust DSs or DLVs. The inverse
|
||||
of a trust-anchor.
|
||||
|
||||
17 March 2009: Wouter
|
||||
- unit test for unsupported algorithm in anchor warning.
|
||||
- fixed so queries do not fail on opportunistic target queries.
|
||||
|
||||
16 March 2009: Wouter
|
||||
- fixup diff error printout in contrib/update-itar.sh.
|
||||
- added contrib/unbound_cacti for statistics support in cacti,
|
||||
contributed by Dmitriy Demidov.
|
||||
|
||||
13 March 2009: Wouter
|
||||
- doxygen and lex/yacc on linux.
|
||||
- strip update-anchor on makedist -w.
|
||||
- fix testbound on windows.
|
||||
- default log to syslog for windows.
|
||||
- uninstaller can stop unbound - changed text on it to reflect that.
|
||||
- remove debugging from windows 'cron' actions.
|
||||
|
||||
12 March 2009: Wouter
|
||||
- log to App.logs on windows prints executable identity.
|
||||
- fixup tests.
|
||||
- munin plugin fix benign locking error printout.
|
||||
- anchor-update for windows, called every 24 hours; unbound reloads.
|
||||
|
||||
11 March 2009: Wouter
|
||||
- winsock event handler resets WSAevents after signalled.
|
||||
- winsock event handler tests if signals are really signalled.
|
||||
- install and service with log to file works on XP and Vista on
|
||||
default install location.
|
||||
- on windows logging to the Application logbook works (as a service).
|
||||
- fix RUN_DIR on windows compile setting in makedist.
|
||||
- windows registry has Software\Unbound\ConfigFile element.
|
||||
If does not exist, the default is used. The -c switch overrides it.
|
||||
- fix makedist version cleanup function.
|
||||
|
||||
10 March 2009: Wouter
|
||||
- makedist -w strips out old rc.. and snapshot info from version.
|
||||
- setup.exe starts and stops unbound after install, before uninstall.
|
||||
- unbound-checkconf recognizes absolute pathnames on windows (C:...).
|
||||
|
||||
9 March 2009: Wouter
|
||||
- Nullsoft NSIS installer creation script.
|
||||
|
||||
5 March 2009: Wouter
|
||||
- fixup memory leak introduced on 18feb in mesh reentrant fix.
|
||||
|
||||
3 March 2009: Wouter
|
||||
- combined icon with 16x16(4) 32x32(4) 48x48(8) 64x64(8).
|
||||
- service works on xp/vista, no config necessary (using defaults).
|
||||
- windows registry settings.
|
||||
|
||||
2 March 2009: Wouter
|
||||
- fixup --export-symbols to be -export-symbls for libtool.
|
||||
This should fix extraneous symbols exported from libunbound.
|
||||
Thanks to Ondrej Sury and Robert Edmonds for finding it.
|
||||
- iana portlist updated.
|
||||
- document FAQ entry on stub/forward zones and default blocking.
|
||||
- fix asynclook test app for libunbound not exporting symbols.
|
||||
- service install and remove utils that work with vista UAC.
|
||||
|
||||
27 February 2009: Wouter
|
||||
- Fixup lexer, to not give warnings about fwrite. Appeared in
|
||||
new lexer features.
|
||||
- makedistro functionality for mingw. Has RC support.
|
||||
- support spaces and backslashes in configured defaults paths.
|
||||
- register, deregister in service control manager.
|
||||
|
||||
25 February 2009: Wouter
|
||||
- windres usage for application resources.
|
||||
|
||||
24 February 2009: Wouter
|
||||
- isc moved their dlv key download location.
|
||||
- fixup warning on vista/mingw.
|
||||
- makedist -w for window zip distribution first version.
|
||||
|
||||
20 February 2009: Wouter
|
||||
- Fixup contrib/update-itar.sh, the exit codes 1 and 0 were swapped.
|
||||
Nicer script layout. Added url to site in -h output.
|
||||
|
||||
19 February 2009: Wouter
|
||||
- unbound-checkconf and unbound print warnings when trust anchors
|
||||
have unsupported algorithms.
|
||||
- added contrib/update-itar.sh This script is similar to
|
||||
update-anchor.sh, and updates from the IANA ITAR repository.
|
||||
You can provide your own PGP key and trust repo, or can use the
|
||||
builtin. The program uses wget and gpg to work.
|
||||
- iana portlist updated.
|
||||
- update-itar.sh: using ftp:// urls because https godaddy certificate
|
||||
is not available everywhere and then gives fatal errors. The
|
||||
security is provided by pgp signature.
|
||||
|
||||
18 February 2009: Wouter
|
||||
- more cycle detection. Also for target queries.
|
||||
- fixup bug where during deletion of the mesh queries the callbacks
|
||||
that were reentrant caused assertion failures. Keep the mesh in
|
||||
a reentrant safe state. Affects libunbound, reload of server,
|
||||
on quit and flush_requestlist.
|
||||
- iana portlist updated.
|
||||
|
||||
13 February 2009: Wouter
|
||||
- forwarder information now per-thread duplicated.
|
||||
This keeps it read only for speed, with no locking necessary.
|
||||
- forward command for unbound control to change forwarders to use
|
||||
on the fly.
|
||||
- document that unbound-host reads no config file by default.
|
||||
- updated iana portlist.
|
||||
|
||||
12 February 2009: Wouter
|
||||
- call setusercontext if available (on BSD).
|
||||
- small refactor of stats clearing.
|
||||
- #227: flush_stats feature for unbound-control.
|
||||
- stats_noreset feature for unbound-control.
|
||||
- flush_requestlist feature for unbound-control.
|
||||
- libunbound version upped API (was changed 5 feb).
|
||||
- unbound-control status shows if root forwarding is in use.
|
||||
- slightly nicer memory management in iter-fwd code.
|
||||
|
||||
10 February 2009: Wouter
|
||||
- keys with rfc5011 REVOKE flag are skipped and not considered when
|
||||
validating data.
|
||||
- iana portlist updated
|
||||
- #226: dump_requestlist feature for unbound-control.
|
||||
|
||||
6 February 2009: Wouter
|
||||
- contrib contains specfile for fedora 1.2.1 (from Paul Wouters).
|
||||
- iana portlist updated.
|
||||
- fixup EOL in include directive (reported by Paul Wouters).
|
||||
You can no longer specify newlines in the names of included files.
|
||||
- config parser changed. Gives some syntax errors closer to where they
|
||||
occurred. Does not enforce a space after keyword anymore.
|
||||
Does not allow literal newlines inside quoted strings anymore.
|
||||
- verbosity level 5 logs customer IP for new requestlist entries.
|
||||
- test fix, lexer and cancel test.
|
||||
- new option log-time-ascii: yes if you enable it prints timestamps
|
||||
in the log file as Feb 06 13:45:26 (like syslog does).
|
||||
- detect event_base_new in libevent-1.4.1 and later and use it.
|
||||
- #231 unbound-checkconf -o option prints that value from config file.
|
||||
Useful for scripting in management scripts and the like.
|
||||
|
||||
5 February 2009: Wouter
|
||||
- ldns 1.5.0 rc as tarball included.
|
||||
- 1.3.0 development continues:
|
||||
change in libunbound API: ub_cancel can return an error, that
|
||||
the async_id did not exist, or that it was already delivered.
|
||||
The result could have been delivered just before the cancel
|
||||
routine managed to acquire the lock, so a caller may get the
|
||||
result at the same time they call cancel. For this case,
|
||||
ub_cancel tries to return an error code.
|
||||
Fixes race condition in ub_cancel() libunbound function.
|
||||
- MacOSX Leopard cleaner text output from configure.
|
||||
- initgroups(3) is called to drop secondary group permissions, if
|
||||
applicable.
|
||||
- configure option --with-ldns-builtin forces the use of the
|
||||
inluded ldns package with the unbound source. The -I include
|
||||
is put before the others, so it avoids bad include files from
|
||||
an older ldns install.
|
||||
- daemon(3) posix call is used when available.
|
||||
- testbound test for older fix added.
|
||||
|
||||
4 February 2009: Wouter
|
||||
- tag for release 1.2.1.
|
||||
- trunk setup for 1.3.0 development.
|
||||
|
||||
3 February 2009: Wouter
|
||||
- noted feature requests in doc/TODO.
|
||||
- printout more detailed errors on ssl certificate loading failures.
|
||||
- updated IANA portlist.
|
||||
|
||||
16 January 2009: Wouter
|
||||
- more quiet about ipv6 network failures, i.e. when ipv6 is not
|
||||
available (network unreachable). Debug still printed on high
|
||||
verbosity.
|
||||
- unbound-host -4 and -6 options. Stops annoying ipv6 errors when
|
||||
debugging with unbound-host -4 -d ...
|
||||
- more cycle detection for NS-check, addr-check, root-prime and
|
||||
stub-prime queries in the iterator. Avoids possible deadlock
|
||||
when priming fails.
|
||||
|
||||
15 January 2009: Wouter
|
||||
- bug #229: fixup configure checks for compilation with Solaris
|
||||
Sun cc compiler, ./configure CC=/opt/SUNWspro/bin/cc
|
||||
- fixup suncc warnings.
|
||||
- fix bug where unbound could crash using libevent 1.3 and older.
|
||||
- update testset for recent retry change.
|
||||
|
||||
14 January 2009: Wouter
|
||||
- 1.2.1 feature: negative caching for failed queries.
|
||||
Queries that failed are cached for 5 seconds (NORR_TTL).
|
||||
If the failure is local, like out of memory, it is not cached.
|
||||
- the TTL comparison for the cache used different comparisons,
|
||||
causing many cache responses that used the iterator and validator
|
||||
state machines unnecessarily.
|
||||
- retry from 4 to 5 so that EDNS drop retry is part of the first
|
||||
query resolve attempt, and cached error does not stop EDNS fallback.
|
||||
- remove debug prints that protect against bad referrals.
|
||||
- honor QUIET=no on make commandline (or QUIET=yes ).
|
||||
|
||||
13 January 2009: Wouter
|
||||
- fixed bug in lameness marking, removed printouts.
|
||||
- find NS rrset more cleanly for qtype NS.
|
||||
- Moved changes to 1.2.0 for release. Thanks to Mark Zealey for
|
||||
reporting and logs.
|
||||
- 1.2.1 feature: stops resolving AAAAs promiscuously when they
|
||||
are in the negative cache.
|
||||
|
||||
12 January 2009: Wouter
|
||||
- fixed bug in infrastructure lameness cache, did not lowercase
|
||||
name of zone to hash when setting lame.
|
||||
- lameness debugging printouts.
|
||||
|
||||
9 January 2009: Wouter
|
||||
- created svn tag for 1.2.0 release.
|
||||
- svn trunk contains 1.2.1 version number.
|
||||
- iana portlist updated for todays list.
|
||||
- removed debug print.
|
||||
|
||||
8 January 2009: Wouter
|
||||
- new version of ldns-trunk (today) included as tarball, fixed
|
||||
bug #224, building with -j race condition.
|
||||
- remove possible race condition in the test for race conditions.
|
||||
|
||||
7 January 2009: Wouter
|
||||
- version 1.2.0 in preparation.
|
||||
- feature to allow wildcards (*, ?, [], {}. ~) in trusted-keys-file
|
||||
statements. (Adapted from patch by Paul Wouters).
|
||||
- typo fix and iana portlist updated.
|
||||
- porting testsuite; unused var warning, and type fixup.
|
||||
|
||||
6 January 2009: Wouter
|
||||
- fixup packet-of-death when compiled with --enable-debug.
|
||||
A malformed packet could cause an internal assertion failure.
|
||||
- added test for HINFO canonicalisation behaviour.
|
||||
- fixup reported problem with transparent local-zone data where
|
||||
queries with different type could get nxdomain. Now queries
|
||||
with a different name get resolved normally, with different type
|
||||
get a correct NOERROR/NODATA answer.
|
||||
- HINFO no longer downcased for validation, making unbound compatible
|
||||
with bind and ldns.
|
||||
- fix reading included config files when chrooted.
|
||||
Give full path names for include files.
|
||||
Relative path names work if the start dir equals the working dir.
|
||||
- fix libunbound message transport when no packet buffer is available.
|
||||
|
||||
5 January 2009: Wouter
|
||||
- fixup getaddrinfo failure handling for remote control port.
|
||||
- added L.ROOT-SERVERS.NET. AAAA 2001:500:3::42 to builtin root hints.
|
||||
- fixup so it works with libev-3.51 from http://dist.schmorp.de/libev/
|
||||
- comm_timer_set performs base_set operation after event_add.
|
||||
|
||||
18 December 2008: Wouter
|
||||
- fixed bug reported by Duane Wessels: error in DLV lookup, would make
|
||||
some zones that had correct DLV keys as insecure.
|
||||
- follows -rc makedist from ldns changes (no _rc).
|
||||
- ldns tarball updated with 1.4.1rc for DLV unit test.
|
||||
- verbose prints about recursion lame detection and server selection.
|
||||
- fixup BSD port for infra host storage. It hashed wrongly.
|
||||
- fixup makedist snapshot name generation.
|
||||
- do not reopen syslog to avoid dev/log dependency.
|
||||
|
||||
17 December 2008: Wouter
|
||||
- follows ldns makedist.sh. -rc option. autom4te dir removed.
|
||||
- unbound-control status command.
|
||||
- extended statistics has a number of ipv6 queries counter.
|
||||
contrib/unbound_munin_ was updated to draw ipv6 in the hits graph.
|
||||
|
||||
16 December 2008: Wouter
|
||||
- follow makedist improvements from ldns, for maintainers prereleases.
|
||||
- snapshot version uses _ not - to help rpm distinguish the
|
||||
version number.
|
||||
|
||||
11 December 2008: Wouter
|
||||
- better fix for bug #219: use LOG_NDELAY with openlog() call.
|
||||
Thanks to Tamas Tevesz.
|
||||
|
||||
9 December 2008: Wouter
|
||||
- bug #221 fixed: unbound checkconf checks if key files exist if
|
||||
remote control is enabled. Also fixed NULL printf when not chrooted.
|
||||
- iana portlist updated.
|
||||
|
||||
3 December 2008: Wouter
|
||||
- Fix problem reported by Jaco Engelbrecht where unbound-control stats
|
||||
freezes up unbound if this was compiled without threading, and
|
||||
was using multiple processes.
|
||||
- iana portlist updated.
|
||||
- test for remote control with interprocess communication.
|
||||
- created command distribution mechanism so that remote control
|
||||
commands other than 'stats' work on all processes in a nonthreaded
|
||||
compiled version. dump/load cache work, on the first process.
|
||||
- fixup remote control local_data addition memory corruption bug.
|
||||
|
||||
1 December 2008: Wouter
|
||||
- SElinux policy files in contrib/selinux for the unbound daemon,
|
||||
by Paul Wouters and Adam Tkac.
|
||||
|
||||
25 November 2008: Wouter
|
||||
- configure complains when --without-ssl is given (bug #220).
|
||||
- skip unsupported feature tests on vista/mingw.
|
||||
- fixup testcode/streamtcp to work on vista/mingw.
|
||||
- root-hints test checks version of dig required.
|
||||
- blacklisted servers are polled at a low rate (1%) to see if they
|
||||
come back up. But not if there is some other working server.
|
||||
|
||||
24 November 2008: Wouter
|
||||
- document that the user of the server daemon needs read privileges
|
||||
on the keys and certificates generated by unbound-control-setup.
|
||||
This is different per system or distribution, usually, running the
|
||||
script under the same username as the server uses suffices.
|
||||
i.e. sudo -u unbound unbound-control-setup
|
||||
- testset port to vista/mingw.
|
||||
- tcp_sigpipe to freebsd port.
|
||||
|
||||
21 November 2008: Wouter
|
||||
- fixed tcp accept, errors were printed when they should not.
|
||||
- unbound-control-setup.sh removes read/write permissions other
|
||||
from the keys it creates (as suggested by Dmitriy Demidov).
|
||||
|
||||
20 November 2008: Wouter
|
||||
- fixup fatal error due to faulty error checking after tcp accept.
|
||||
- add check in rlimit to avoid integer underflow.
|
||||
- rlimit check with new formula; better estimate for number interfaces
|
||||
- nicer comments in rlimit check.
|
||||
- tag 1.1.1 created in svn.
|
||||
- trunk label is 1.1.2
|
||||
|
||||
19 November 2008: Wouter
|
||||
- bug #219: fixed so that syslog which delays opening until the first
|
||||
|
||||
+21
-8
@@ -58,24 +58,30 @@ This software is under BSD license, see LICENSE for details.
|
||||
* --with-username=user
|
||||
Set default user name to change to,
|
||||
the default is the "unbound" user.
|
||||
* --with-pyunbound
|
||||
Create libunbound wrapper usable from python.
|
||||
Needs python-devel and swig development tools.
|
||||
* --with-pythonmodule
|
||||
Compile the python module that processes responses in the server.
|
||||
* --disable-sha2
|
||||
Disable support for RSASHA256 and RSASHA512 crypto.
|
||||
* --enable-gost
|
||||
Enable draft support for GOST crypto.
|
||||
|
||||
* 'make test' attempts to run a series of tests, depending on the support
|
||||
programs that are installed.
|
||||
|
||||
Known issues
|
||||
------------
|
||||
o If there are no replies for a forward or stub zone, for a reverse zone,
|
||||
you may need to add a local-zone: name transparent or nodefault to the
|
||||
server: section of the config file to unblock the reverse zone.
|
||||
Only happens for (sub)zones that are blocked by default; e.g. 10.in-addr.arpa
|
||||
o If libevent is older (before 1.3c), unbound will exit instead of reload
|
||||
on sighup. On a restart 'did not exit gracefully last time' warning is
|
||||
printed. Perform ./configure --with-libevent=no or update libevent, rerun
|
||||
configure and recompile unbound to make sighup work correctly.
|
||||
It is strongly suggested to use the latest version of libevent (1.4 or more)
|
||||
on Solaris, because of fixes in the solaris event port code in libevent.
|
||||
o If you receive no answers deploying unbound on a private network.
|
||||
Check that the zone you configure as a stub zone is correct, listing working
|
||||
ip-addresses. Check that the NS data in the zone, those hostnames, are
|
||||
in fact those same, working, ip-addresses. Unbound will fetch the NS data
|
||||
from the zone and use that information in preference to the config
|
||||
information.
|
||||
It is strongly suggested to use a recent version of libevent.
|
||||
o If you are not receiving the correct source IP address on replies (e.g.
|
||||
you are running a multihomed, anycast server), the interface-automatic
|
||||
option can be enabled to set socket options to achieve the correct
|
||||
@@ -87,6 +93,13 @@ o The warning 'openssl has no entropy, seeding with time', with chroot
|
||||
o On Solaris 5.10 some libtool packages from repositories do not work with
|
||||
gcc, showing errors gcc: unrecognized option `-KPIC'
|
||||
To solve this do ./configure libtool=./libtool [your options...].
|
||||
o If unbound-control (or munin graphs) do not work, this can often be because
|
||||
the unbound-control-setup script creates the keys with restricted
|
||||
permissions, and the files need to be made readable or ownered by both the
|
||||
unbound daemon and unbound-control.
|
||||
o Crosscompile seems to hang. You tried to install unbound under wine.
|
||||
wine regedit and remove all the unbound entries from the registry or
|
||||
delete .wine/drive_c.
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
@@ -35,29 +35,37 @@ o overhaul outside-network servicedquery to merge with udpwait and tcpwait,
|
||||
o check into rebinding ports for efficiency, configure time test.
|
||||
o EVP hardware crypto support.
|
||||
o option to ignore all inception and expiration dates for rrsigs.
|
||||
o option to use builtin ldns explicitly. Or stop shipping builtin tarball.
|
||||
o cleaner code; return and func statements on newline.
|
||||
o memcached module that sits before validator module; checks for memcached
|
||||
data (on local lan), stores recursion lookup. Provides one cache for
|
||||
multiple resolver machines, coherent reply content in anycast setup.
|
||||
data (on local lan), stores recursion lookup. Provides one cache for multiple resolver machines, coherent reply content in anycast setup.
|
||||
o no openssl_add_all_algorithms, but only the ones necessary, less space.
|
||||
o listen to NOTIFY messages for zones and flush the cache for that zone
|
||||
if received. Useful when also having a stub to that auth server.
|
||||
Needs proper protection, TSIG, in place.
|
||||
o winevent - do not go more than 64 fds (by polling with select one by
|
||||
one), win95/98 have 100fd limit in the kernel, so this ruins w9x portability.
|
||||
|
||||
*** Features features, for later
|
||||
* dTLS, TLS, look to need special port numbers, cert storage, recent libssl.
|
||||
* aggressive negative caching for NSEC, NSEC3.
|
||||
* multiple queries per question, server exploration, server selection.
|
||||
* NSID support.
|
||||
* support TSIG on queries, for validating resolver deployment.
|
||||
* private TTL
|
||||
* retry-mode, where a bogus result triggers a retry-mode query, where a list
|
||||
of responses over a time interval is collected, and each is validated.
|
||||
or try in TCP mode. Do not 'try all servers several times', since we must
|
||||
not create packet storms with operator errors.
|
||||
* draft-timers
|
||||
* Windows port features
|
||||
o on windows version, implement that OS ancillary data capabilities for
|
||||
interface-automatic. IPPKTINFO, IP6PKTINFO for WSARecvMsg, WSASendMsg.
|
||||
o local-zone directive with authority service, full authority server
|
||||
is a non-goal.
|
||||
o configure option to force use of builtin ldns tarball.
|
||||
o include /etc/pki/dnssec-keys/production/*.conf with wildcard support.
|
||||
o infra and lame cache: easier size config (in Mb), show usage in graphs.
|
||||
- store time of dump in cachedumps, so that on a load the ttls can be
|
||||
compared to the absolute time, and now-expired items can be dealt with.
|
||||
|
||||
later
|
||||
- selective verbosity; ubcontrol trace example.com
|
||||
- cache fork-dump, pre-load
|
||||
- for fwds, send queries to N servers in fwd-list, use first reply.
|
||||
document high scalable, high available unbound setup onepager.
|
||||
- prefetch DNSKEY when DS in delegation seen (nonCD, underTA).
|
||||
- use libevent if available on system by default(?), default outgoing 256to1024
|
||||
|
||||
+81
-30
@@ -18,7 +18,7 @@ server:
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
@@ -37,7 +37,7 @@ server:
|
||||
# interface: 192.0.2.153
|
||||
# interface: 192.0.2.154
|
||||
# interface: 2001:DB8::5
|
||||
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
# Socket options are not supported on all platforms. experimental.
|
||||
# interface-automatic: no
|
||||
@@ -55,7 +55,7 @@ server:
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
@@ -72,7 +72,15 @@ server:
|
||||
|
||||
# number of incoming simultaneous tcp buffers to hold per thread.
|
||||
# incoming-num-tcp: 10
|
||||
|
||||
|
||||
# buffer size for UDP port 53 incoming (SO_RCVBUF socket option).
|
||||
# 0 is system default. Use 4m to catch query spikes for busy servers.
|
||||
# so-rcvbuf: 0
|
||||
|
||||
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
|
||||
# is set with msg-buffer-size). 1480 can solve fragmentation (timeouts).
|
||||
# edns-buffer-size: 4096
|
||||
|
||||
# buffer size for handling DNS data. No messages larger than this
|
||||
# size can be sent or received, by UDP or TCP. In bytes.
|
||||
# msg-buffer-size: 65552
|
||||
@@ -100,7 +108,11 @@ server:
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# rrset-cache-slabs: 4
|
||||
|
||||
|
||||
# the time to live (TTL) value lower bound, in seconds. Default 0.
|
||||
# If more than an hour could easily give trouble due to stale data.
|
||||
# cache-min-ttl: 0
|
||||
|
||||
# the time to live (TTL) value cap for RRsets and messages in the
|
||||
# cache. Items are not cached for longer. In seconds.
|
||||
# cache-max-ttl: 86400
|
||||
@@ -187,30 +199,33 @@ server:
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
# logfile: ""
|
||||
|
||||
|
||||
# Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
|
||||
# log to, with identity "unbound". If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
|
||||
# log-time-ascii: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
# root-hints: ""
|
||||
|
||||
|
||||
# enable to not answer id.server and hostname.bind queries.
|
||||
# hide-identity: no
|
||||
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
|
||||
# the identity to report. Leave "" or default to return hostname.
|
||||
# identity: ""
|
||||
|
||||
|
||||
# the version to report. Leave "" or default to return package version.
|
||||
# version: ""
|
||||
|
||||
|
||||
# the target fetch policy.
|
||||
# series of integers describing the policy per dependency depth.
|
||||
# The number of values in the list determines the maximum dependency
|
||||
@@ -220,16 +235,16 @@ server:
|
||||
# positive value: fetch that many targets opportunistically.
|
||||
# Enclose the list of numbers between quotes ("").
|
||||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden-short-bufsize: no
|
||||
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden-large-queries: no
|
||||
|
||||
|
||||
# Harden against out of zone rrsets, to avoid spoofing attempts.
|
||||
# harden-glue: yes
|
||||
|
||||
|
||||
# Harden against receiving dnssec-stripped data. If you turn it
|
||||
# off, failing to validate dnskey data for a trustanchor will
|
||||
# trigger insecure mode for that zone (like without a trustanchor).
|
||||
@@ -245,7 +260,7 @@ server:
|
||||
# Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# use-caps-for-id: no
|
||||
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||
@@ -261,7 +276,7 @@ server:
|
||||
# Allow the domain (and its subdomains) to contain private addresses.
|
||||
# local-data statements are allowed to contain private addresses too.
|
||||
# private-domain: "example.com"
|
||||
|
||||
|
||||
# If nonzero, unwanted replies are not only reported in statistics,
|
||||
# but also a running total is kept per thread. If it reaches the
|
||||
# threshold, a warning is printed and a defensive action is taken,
|
||||
@@ -273,18 +288,18 @@ server:
|
||||
# List one address per entry. List classless netblocks with /size,
|
||||
# do-not-query-address: 127.0.0.1/8
|
||||
# do-not-query-address: ::1
|
||||
|
||||
|
||||
# if yes, the above default do-not-query-address entries are present.
|
||||
# if no, localhost can be queried (for testing and debugging).
|
||||
# do-not-query-localhost: yes
|
||||
|
||||
|
||||
# module configuration of the server. A string with identifiers
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
# module-config: "validator iterator"
|
||||
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download https://secure.isc.org/ops/dlv/dlv.isc.org.key
|
||||
# Download http://ftp.isc.org/www/dlv/dlv.isc.org.key
|
||||
# dlv-anchor-file: "dlv.isc.org.key"
|
||||
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
@@ -292,6 +307,11 @@ server:
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
# initial file like trust-anchor-file, then it stores metadata.
|
||||
# Use several entries, one per domain name, to track multiple zones.
|
||||
# auto-trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
@@ -303,34 +323,57 @@ server:
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
|
||||
# Ignore chain of trust. Domain is treated as insecure.
|
||||
# domain-insecure: "example.com"
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# val-override-date: ""
|
||||
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
# some of the revalidation, until the time interval expires. in secs.
|
||||
# val-bogus-ttl: 60
|
||||
|
||||
|
||||
# The signature inception and expiration dates are allowed to be off
|
||||
# by 10% of the lifetime of the signature from our local clock.
|
||||
# This leeway is capped with a minimum and a maximum. In seconds.
|
||||
# val-sig-skew-min: 3600
|
||||
# val-sig-skew-max: 86400
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
|
||||
|
||||
# Turn permissive mode on to permit bogus messages. Thus, messages
|
||||
# for which security checks failed will be returned to clients,
|
||||
# instead of SERVFAIL. It still performs the security checks, which
|
||||
# result in interesting log files and possibly the AD bit in
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query.
|
||||
# val-log-level: 0
|
||||
|
||||
# It is possible to configure NSEC3 maximum iteration counts per
|
||||
# keysize. Keep this table very short, as linear search is done.
|
||||
# A message with an NSEC3 with larger count is marked insecure.
|
||||
# List in ascending order the keysize and count values.
|
||||
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
|
||||
|
||||
# instruct the auto-trust-anchor-file probing to add anchors after ttl.
|
||||
# add-holddown: 2592000 # 30 days
|
||||
|
||||
# instruct the auto-trust-anchor-file probing to del anchors after ttl.
|
||||
# del-holddown: 2592000 # 30 days
|
||||
|
||||
# auto-trust-anchor-file probing removes missing anchors after ttl.
|
||||
# If the value 0 is given, missing anchors are not removed.
|
||||
# keep-missing: 31622400 # 366 days
|
||||
|
||||
# the amount of memory to use for the key cache.
|
||||
# plain value in bytes or you can append k, m or G. default is "4Mb".
|
||||
@@ -340,7 +383,7 @@ server:
|
||||
# the number of slabs must be a power of 2.
|
||||
# more slabs reduce lock contention, but fragment memory usage.
|
||||
# key-cache-slabs: 4
|
||||
|
||||
|
||||
# the amount of memory to use for the negative cache (used for DLV).
|
||||
# plain value in bytes or you can append k, m or G. default is "1Mb".
|
||||
# neg-cache-size: 1m
|
||||
@@ -351,7 +394,7 @@ server:
|
||||
# o deny serves local data (if any), else, drops queries.
|
||||
# o refuse serves local data (if any), else, replies with error.
|
||||
# o static serves local data, else, nxdomain or nodata answer.
|
||||
# o transparent serves local data, else, resolves normally .
|
||||
# o transparent gives local data, but resolves normally for other names
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
#
|
||||
@@ -380,6 +423,14 @@ server:
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# Python config section. To enable:
|
||||
# o use --with-pythonmodule to configure before compiling.
|
||||
# o list python in the module-config string (above) to enable.
|
||||
# o and give a python-script to run.
|
||||
python:
|
||||
# Script file to load
|
||||
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
@@ -414,7 +465,7 @@ remote-control:
|
||||
# stub-zone:
|
||||
# name: "example.com"
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: "no"
|
||||
# stub-prime: no
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
|
||||
+53
-14
@@ -35,7 +35,12 @@
|
||||
.B ub_resolve_async,
|
||||
.B ub_cancel,
|
||||
.B ub_resolve_free,
|
||||
.B ub_strerror
|
||||
.B ub_strerror,
|
||||
.B ub_ctx_print_local_zones,
|
||||
.B ub_ctx_zone_add,
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver @version@ functions.
|
||||
.SH "SYNOPSIS"
|
||||
.LP
|
||||
@@ -95,9 +100,7 @@
|
||||
\fIint\fR
|
||||
\fBub_resolve\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
|
||||
.br
|
||||
\fIint\fR rrtype, \fIint\fR rrclass, \fIint*\fR secure,
|
||||
.br
|
||||
\fIint*\fR data, \fIstruct ub_result**\fR result);
|
||||
\fIint\fR rrtype, \fIint\fR rrclass, \fIstruct ub_result**\fR result);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_resolve_async\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
|
||||
@@ -114,6 +117,21 @@
|
||||
.LP
|
||||
\fIconst char *\fR
|
||||
\fBub_strerror\fR(\fIint\fR err);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_print_local_zones\fR(\fIstruct ub_ctx*\fR ctx);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_zone_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name, \fIchar*\fR zone_type);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_zone_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_data_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_ctx_data_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
|
||||
.SH "DESCRIPTION"
|
||||
.LP
|
||||
.B Unbound
|
||||
@@ -181,14 +199,16 @@ Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
|
||||
If they do not support DNSSEC, validation may fail.
|
||||
Only nameservers are picked up, the searchdomain, ndots and other
|
||||
settings from \fIresolv.conf\fR(5) are ignored.
|
||||
If fname NULL is passed, "/etc/resolv.conf" is used.
|
||||
If fname NULL is passed, "/etc/resolv.conf" is used (if on Windows,
|
||||
the system\-wide configured nameserver is picked instead).
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_hosts
|
||||
Read list of hosts from the filename given.
|
||||
Usually "/etc/hosts". When queried for, these addresses are not marked
|
||||
DNSSEC secure. If fname NULL is passed, "/etc/hosts" is used.
|
||||
DNSSEC secure. If fname NULL is passed, "/etc/hosts" is used
|
||||
(if on Windows, etc/hosts from WINDIR is picked instead).
|
||||
At this time it is only possible to set configuration before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
@@ -197,7 +217,7 @@ ub_ctx_add_ta
|
||||
Add a trust anchor to the given context.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
The format is a string, similar to the zone-file format,
|
||||
The format is a string, similar to the zone\-file format,
|
||||
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
|
||||
.TP
|
||||
.B ub_ctx_add_ta_file
|
||||
@@ -208,13 +228,13 @@ first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_trustedkeys
|
||||
Add trust anchors to the given context.
|
||||
Pass the name of a bind-style config file with trusted-keys{}.
|
||||
Pass the name of a bind\-style config file with trusted\-keys{}.
|
||||
At this time it is only possible to add trusted keys before the
|
||||
first resolve is done.
|
||||
.TP
|
||||
.B ub_ctx_debugout
|
||||
Set debug and error log output to the given stream. Pass NULL to disable
|
||||
output. Default is stderr. File-names or using syslog can be enabled
|
||||
output. Default is stderr. File\-names or using syslog can be enabled
|
||||
using config options, this routine is for using your own stream.
|
||||
.TP
|
||||
.B ub_ctx_debuglevel
|
||||
@@ -261,8 +281,6 @@ Will perform necessary callbacks.
|
||||
Perform resolution and validation of the target name.
|
||||
The name is a domain name in a zero terminated text string.
|
||||
The rrtype and rrclass are DNS type and class codes.
|
||||
The value secure returns true if the answer validated securely.
|
||||
The value data returns true if there was data.
|
||||
The result structure is newly allocated with the resulting data.
|
||||
.TP
|
||||
.B ub_resolve_async
|
||||
@@ -278,10 +296,13 @@ void my_callback_function(void* my_arg, int err,
|
||||
struct ub_result* result);
|
||||
.IP
|
||||
The async_id is returned so you can (at your option) decide to track it
|
||||
and cancel the request if needed.
|
||||
and cancel the request if needed. If you pass a NULL pointer the async_id
|
||||
is not returned.
|
||||
.TP
|
||||
.B ub_cancel
|
||||
Cancel an async query in progress.
|
||||
Cancel an async query in progress. This may return an error if the query
|
||||
does not exist, or the query is already being delivered, in that case you
|
||||
may still get a callback for the query.
|
||||
.TP
|
||||
.B ub_resolve_free
|
||||
Free struct ub_result contents after use.
|
||||
@@ -289,6 +310,23 @@ Free struct ub_result contents after use.
|
||||
.B ub_strerror
|
||||
Convert error value from one of the unbound library functions
|
||||
to a human readable string.
|
||||
.TP
|
||||
.B ub_ctx_print_local_zones
|
||||
Debug printout the local authority information to debug output.
|
||||
.TP
|
||||
.B ub_ctx_zone_add
|
||||
Add new zone to local authority info, like local\-zone \fIunbound.conf\fR(5)
|
||||
statement.
|
||||
.TP
|
||||
.B ub_ctx_zone_remove
|
||||
Delete zone from local authority info.
|
||||
.TP
|
||||
.B ub_ctx_data_add
|
||||
Add resource record data to local authority info, like local\-data
|
||||
\fIunbound.conf\fR(5) statement.
|
||||
.TP
|
||||
.B ub_ctx_data_remove
|
||||
Delete local authority data from the name given.
|
||||
.SH "RESULT DATA STRUCTURE"
|
||||
.LP
|
||||
The result of the DNS resolution and validation is returned as
|
||||
@@ -309,6 +347,7 @@ The result of the DNS resolution and validation is returned as
|
||||
int nxdomain; /* true if nodata because name does not exist */
|
||||
int secure; /* true if result is secure */
|
||||
int bogus; /* true if a security failure happened */
|
||||
char* why_bogus; /* string with error if bogus */
|
||||
};
|
||||
.fi
|
||||
.P
|
||||
@@ -326,7 +365,7 @@ returns NULL on an error (a malloc failure).
|
||||
.B ub_poll
|
||||
returns true if some information may be available, false otherwise.
|
||||
.B ub_fd
|
||||
returns a file descriptor or -1 on error.
|
||||
returns a file descriptor or \-1 on error.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
@@ -235,6 +235,9 @@ o EDNS fallback. Is done according to the EDNS RFC (and update draft-00).
|
||||
It minimizes the chances of a dropped query making a (DNSSEC) EDNS server
|
||||
falsely EDNS-nonsupporting, and thus DNSSEC-bogus, works well with
|
||||
middleboxes, and can detect the occasional authority that drops EDNS.
|
||||
For some boxes it is necessary to probe for every failing query, a
|
||||
reassurance that the DNS server does EDNS does not mean that path can
|
||||
take large DNS answers.
|
||||
|
||||
o 0x20 backoff.
|
||||
The draft describes to back off to the next server, and go through all
|
||||
@@ -243,3 +246,17 @@ o 0x20 backoff.
|
||||
They are sent to a random server, but no one address more than 4 times.
|
||||
It succeeds if one has 0x20 intact, or else all are equal.
|
||||
Otherwise, servfail is returned to the client.
|
||||
|
||||
o NXDOMAIN and SOA serial numbers.
|
||||
Unbound keeps TTL values for message formats, and thus rcodes, such
|
||||
as NXDOMAIN. Also it keeps the latest rrsets in the rrset cache.
|
||||
So it will faithfully negative cache for the exact TTL as originally
|
||||
specified for an NXDOMAIN message, but send a newer SOA record if
|
||||
this has been found in the mean time. In point, this could lead to a
|
||||
negative cached NXDOMAIN reply with a SOA RR where the serial number
|
||||
indicates a zone version where this domain is not any longer NXDOMAIN.
|
||||
These situations become consistent once the original TTL expires.
|
||||
If the domain is DNSSEC signed, by the way, then NSEC records are
|
||||
updated more carefully. If one of the NSEC records in an NXDOMAIN is
|
||||
updated from another query, the NXDOMAIN is dropped from the cache,
|
||||
and queried for again, so that its proof can be checked again.
|
||||
|
||||
@@ -9,14 +9,16 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.LP
|
||||
unbound-checkconf
|
||||
unbound\-checkconf
|
||||
\- Check unbound configuration file for errors.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound-checkconf
|
||||
.B unbound\-checkconf
|
||||
.RB [ \-h ]
|
||||
.IR cfgfile
|
||||
.RB [ \-o
|
||||
.IR option ]
|
||||
.RI [ cfgfile ]
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound-checkconf
|
||||
.B Unbound\-checkconf
|
||||
checks the configuration file for the
|
||||
\fIunbound\fR(8)
|
||||
DNS resolver for syntax and other errors.
|
||||
@@ -28,11 +30,15 @@ The available options are:
|
||||
.B \-h
|
||||
Show the version and commandline option help.
|
||||
.TP
|
||||
.B \-o\fI option
|
||||
If given, after checking the config file the value of this option is
|
||||
printed to stdout. For "" (disabled) options an empty line is printed.
|
||||
.TP
|
||||
.I cfgfile
|
||||
The config file to read with settings for unbound. It is checked.
|
||||
If omitted, the config file at the default location is checked.
|
||||
.SH "EXIT CODE"
|
||||
The unbound-checkconf program exits with status code 1 on error,
|
||||
The unbound\-checkconf program exits with status code 1 on error,
|
||||
0 for a correct config file.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.LP
|
||||
unbound-control
|
||||
.B unbound\-control,
|
||||
.B unbound\-control\-setup
|
||||
\- Unbound remote server control utility.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound-control
|
||||
.B unbound\-control
|
||||
.RB [ \-h ]
|
||||
.RB [ \-c
|
||||
.IR cfgfile ]
|
||||
@@ -20,7 +21,7 @@ unbound-control
|
||||
.IR server ]
|
||||
.IR command
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound-control
|
||||
.B Unbound\-control
|
||||
performs remote administration on the \fIunbound\fR(8) DNS server.
|
||||
It reads the configuration file, contacts the unbound server over SSL
|
||||
sends the command and displays the result.
|
||||
@@ -61,6 +62,14 @@ Print statistics. Resets the internal counters to zero, this can be
|
||||
controlled using the \fBstatistics\-cumulative\fR config statement.
|
||||
Statistics are printed with one [name]: [value] per line.
|
||||
.TP
|
||||
.B stats_noreset
|
||||
Peek at statistics. Prints them like the \fBstats\fR command does, but does not
|
||||
reset the internal counters to zero.
|
||||
.TP
|
||||
.B status
|
||||
Display server status. Exit code 3 if not running (the connection to the
|
||||
port is refused), 1 on error, 0 if running.
|
||||
.TP
|
||||
.B local_zone \fIname\fR \fItype
|
||||
Add new local zone with name and type. Like \fBlocal\-zone\fR config statement.
|
||||
If the zone already exists, the type is changed to the given argument.
|
||||
@@ -90,7 +99,8 @@ redirect it to a file to store the cache in a file.
|
||||
.B load_cache
|
||||
The contents of the cache is loaded from stdin. Uses the same format as
|
||||
dump_cache uses. Loading the cache with old, or wrong data can result
|
||||
in old or wrong data returned to clients.
|
||||
in old or wrong data returned to clients. Loading data into the cache
|
||||
in this way is supported in order to aid with debugging.
|
||||
.TP
|
||||
.B lookup \fIname
|
||||
Print to stdout the name servers that would be used to look up the
|
||||
@@ -111,14 +121,58 @@ Remove the name, type information from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
.TP
|
||||
.B flush_stats
|
||||
Reset statistics to zero.
|
||||
.TP
|
||||
.B flush_requestlist
|
||||
Drop the queries that are worked on. Stops working on the queries that the
|
||||
server is working on now. The cache is unaffected. No reply is sent for
|
||||
those queries, probably making those users request again later.
|
||||
Useful to make the server restart working on queries with new settings,
|
||||
such as a higher verbosity level.
|
||||
.TP
|
||||
.B dump_requestlist
|
||||
Show what is worked on. Prints all queries that the server is currently
|
||||
working on. Prints the time that users have been waiting. For internal
|
||||
requests, no time is printed. And then prints out the module status.
|
||||
.TP
|
||||
.B forward [off | addr ... ]
|
||||
Setup forwarding mode. Configures if the server should ask other upstream
|
||||
nameservers, should go to the internet root nameservers itself, or show
|
||||
the current config. You could pass the nameservers after a DHCP update.
|
||||
.IP
|
||||
Without arguments the current list of addresses used to forward all queries
|
||||
to is printed. On startup this is from the forward\-zone "." configuration.
|
||||
Afterwards it shows the status. It prints off when no forwarding is used.
|
||||
.IP
|
||||
If \fIoff\fR is passed, forwarding is disabled and the root nameservers
|
||||
are used. This can be used to avoid to avoid buggy or non\-DNSSEC supporting
|
||||
nameservers returned from DHCP. But may not work in hotels or hotspots.
|
||||
.IP
|
||||
If one or more IPv4 or IPv6 addresses are given, those are then used to forward
|
||||
queries to. The addresses must be separated with spaces. With '@port' the
|
||||
port number can be set explicitly (default port is 53 (DNS)).
|
||||
.IP
|
||||
By default the forwarder information from the config file for the root "." is
|
||||
used. The config file is not changed, so after a reload these changes are
|
||||
gone. Other forward zones from the config file are not affected by this command.
|
||||
.SH "EXIT CODE"
|
||||
The unbound-control program exits with status code 1 on error, 0 on success.
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
The setup requires a self\-signed certificate and private keys for both
|
||||
the server and client. The script \fIunbound\-control\-setup\fR generates
|
||||
these in the default run directory, or with \-d in another directory.
|
||||
Run the script under the same username as you have configured in unbound.conf
|
||||
so that the daemon is permitted to read the files, for example with:
|
||||
.nf
|
||||
sudo \-u unbound unbound\-control\-setup
|
||||
.fi
|
||||
If you have not configured
|
||||
a username in unbound.conf, the keys need read permission for the user
|
||||
credentials under which the daemon is started.
|
||||
The script preserves private keys present in the directory.
|
||||
After running the script as root, turn on \fBcontrol-enable\fR in
|
||||
After running the script as root, turn on \fBcontrol\-enable\fR in
|
||||
\fIunbound.conf\fR.
|
||||
.SH "STATISTIC COUNTERS"
|
||||
The \fIstats\fR command shows a number of statistic counters.
|
||||
@@ -232,13 +286,13 @@ Printed for the other query types as well, but only for the types for which
|
||||
queries were received, thus =0 entries are omitted for brevity.
|
||||
.TP
|
||||
.I num.query.type.other
|
||||
Number of queries with query types 256-65535.
|
||||
Number of queries with query types 256\-65535.
|
||||
.TP
|
||||
.I num.query.class.IN
|
||||
The total number of queries over all threads with query class IN (internet).
|
||||
Also printed for other classes (such as CH (CHAOS) sometimes used for
|
||||
debugging), or NONE, ANY, used by dynamic update.
|
||||
num.query.class.other is printed for classes 256-65535.
|
||||
num.query.class.other is printed for classes 256\-65535.
|
||||
.TP
|
||||
.I num.query.opcode.QUERY
|
||||
The total number of queries over all threads with query opcode QUERY.
|
||||
@@ -247,6 +301,9 @@ Also printed for other opcodes, UPDATE, ...
|
||||
.I num.query.tcp
|
||||
Number of queries that were made using TCP towards the unbound server.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the unbound server.
|
||||
.TP
|
||||
.I num.query.flags.RD
|
||||
The number of queries that had the RD flag set in the header.
|
||||
Also printed for flags QR, AA, TC, RA, Z, AD, CD.
|
||||
@@ -301,7 +358,7 @@ unbound configuration file.
|
||||
.TP
|
||||
.I @UNBOUND_RUN_DIR@
|
||||
directory with private keys (unbound_server.key and unbound_control.key) and
|
||||
self-signed certificates (unbound_server.pem and unbound_control.pem).
|
||||
self\-signed certificates (unbound_server.pem and unbound_control.pem).
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
+11
-1
@@ -14,7 +14,7 @@
|
||||
.SH "SYNOPSIS"
|
||||
.LP
|
||||
.B unbound\-host
|
||||
.RB [ \-vdhr ]
|
||||
.RB [ \-vdhr46 ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-t
|
||||
@@ -35,6 +35,10 @@ uses the unbound validating resolver to query for the hostname and display
|
||||
results. With the \fB\-v\fR option it displays validation
|
||||
status: secure, insecure, bogus (security failure).
|
||||
.P
|
||||
By default it reads no configuration file whatsoever. It attempts to reach
|
||||
the internet root servers. With \fB\-C\fR an unbound config file and with
|
||||
\fB\-r\fR resolv.conf can be read.
|
||||
.P
|
||||
The available options are:
|
||||
.TP
|
||||
.I hostname
|
||||
@@ -87,6 +91,12 @@ Read /etc/resolv.conf, and use the forward DNS servers from there (those could
|
||||
have been set by DHCP). More info in
|
||||
.IR resolv.conf (5).
|
||||
Breaks validation if those servers do not support DNSSEC.
|
||||
.TP
|
||||
.B \-4
|
||||
Use solely the IPv4 network for sending packets.
|
||||
.TP
|
||||
.B \-6
|
||||
Use solely the IPv6 network for sending packets.
|
||||
.SH "EXAMPLES"
|
||||
.LP
|
||||
Some examples of use. The keys shown below are fakes, thus a security failure
|
||||
|
||||
+149
-25
@@ -52,8 +52,8 @@ server:
|
||||
username: unbound
|
||||
# make sure unbound can access entropy from inside the chroot.
|
||||
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
|
||||
# mount --bind -n /dev/random /etc/unbound/dev/random
|
||||
# and mount --bind -n /dev/log /etc/unbound/dev/log
|
||||
# mount \-\-bind \-n /dev/random /etc/unbound/dev/random
|
||||
# and mount \-\-bind \-n /dev/log /etc/unbound/dev/log
|
||||
chroot: "/etc/unbound"
|
||||
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
|
||||
pidfile: "/etc/unbound/unbound.pid"
|
||||
@@ -73,7 +73,10 @@ Files can be included using the
|
||||
.B include:
|
||||
directive. It can appear anywhere, and takes a single filename as an argument.
|
||||
Processing continues as if the text from the included file was copied into
|
||||
the config file at that point.
|
||||
the config file at that point. If also using chroot, using full path names
|
||||
for the included files works, relative pathnames for the included names work
|
||||
if the directory where the daemon is started equals its chroot/working
|
||||
directory.
|
||||
.SS "Server Options"
|
||||
These options are part of the
|
||||
.B server:
|
||||
@@ -83,10 +86,9 @@ clause.
|
||||
The verbosity number, level 0 means no verbosity, only errors. Level 1
|
||||
gives operational information. Level 2 gives detailed operational
|
||||
information. Level 3 gives query level information, output per query.
|
||||
Level 4 gives algorithm level information.
|
||||
Default is level 1. The verbosity can also be increased from the commandline,
|
||||
see
|
||||
\fIunbound\fR(8).
|
||||
Level 4 gives algorithm level information. Level 5 logs client
|
||||
identification for cache misses. Default is level 1.
|
||||
The verbosity can also be increased from the commandline, see \fIunbound\fR(8).
|
||||
.TP
|
||||
.B statistics\-interval: \fI<seconds>
|
||||
The number of seconds between printing statistics to the log for every thread.
|
||||
@@ -113,10 +115,10 @@ Can be given multiple times to work on several interfaces. If none are
|
||||
given the default is to listen to localhost.
|
||||
The interfaces are not changed on a reload (kill \-HUP) but only on restart.
|
||||
.TP
|
||||
.B interface-automatic: \fI<yes or no>
|
||||
.B interface\-automatic: \fI<yes or no>
|
||||
Detect source interface on UDP queries and copy them to replies. This
|
||||
feature is experimental, and needs support in your OS for IPv6
|
||||
(and its socket options) and IPv4 (and have source-interface socket options).
|
||||
(and its socket options) and IPv4 (and have source\-interface socket options).
|
||||
Default value is no.
|
||||
.TP
|
||||
.B outgoing\-interface: \fI<ip address>
|
||||
@@ -140,7 +142,7 @@ Permit unbound to open this port or range of ports for use to send queries.
|
||||
A larger number of permitted outgoing ports increases resilience against
|
||||
spoofing attempts. Make sure these ports are not needed by other daemons.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
Give a port number or a range of the form "low-high", without spaces.
|
||||
Give a port number or a range of the form "low\-high", without spaces.
|
||||
.IP
|
||||
The \fBoutgoing\-port\-permit\fR and \fBoutgoing\-port\-avoid\fR statements
|
||||
are processed in the line order of the config file, adding the permitted ports
|
||||
@@ -153,7 +155,7 @@ Do not permit unbound to open this port or range of ports for use to send
|
||||
queries. Use this to make sure unbound does not grab a port that another
|
||||
daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
Give a port number or a range of the form "low-high", without spaces.
|
||||
Give a port number or a range of the form "low\-high", without spaces.
|
||||
.TP
|
||||
.B outgoing\-num\-tcp: \fI<number>
|
||||
Number of outgoing TCP buffers to allocate per thread. Default is 10. If set
|
||||
@@ -163,6 +165,17 @@ to 0, or if do_tcp is "no", no TCP queries to authoritative servers are done.
|
||||
Number of incoming TCP buffers to allocate per thread. Default is 10. If set
|
||||
to 0, or if do_tcp is "no", no TCP queries from clients are accepted.
|
||||
.TP
|
||||
.B edns\-buffer\-size: \fI<number>
|
||||
Number of bytes size to advertise as the EDNS reassembly buffer size.
|
||||
This is the value put into datagrams over UDP towards peers. The actual
|
||||
buffer size is determined by msg\-buffer\-size (both for TCP and UDP). Do
|
||||
not set lower than that value. Default is 4096 which is RFC recommended.
|
||||
If you have fragmentation reassembly problems, usually seen as timeouts,
|
||||
then a value of 1480 can fix it. Setting to 512 bypasses even the most
|
||||
stringent path MTU problems, but is seen as extreme, since the amount
|
||||
of TCP fallback generated is excessive (probably also for this resolver,
|
||||
consider tuning the outgoing tcp number).
|
||||
.TP
|
||||
.B msg\-buffer\-size: \fI<number>
|
||||
Number of bytes size of the message buffers. Default is 65552 bytes, enough
|
||||
for 64 Kb packets, the maximum DNS message size. No message larger than this
|
||||
@@ -195,6 +208,17 @@ the other 50% are replaced with the new incoming query if they have already
|
||||
spent more than their allowed time. This protects against denial of
|
||||
service by slow queries or high query rates. Default 200 milliseconds.
|
||||
.TP
|
||||
.B so\-rcvbuf: \fI<number>
|
||||
If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
space on UDP port 53 incoming queries. So that short spikes on busy
|
||||
servers do not drop packets (see counter in netstat \-su). Default is
|
||||
0 (use system value). Otherwise, the number of bytes to ask for, try
|
||||
"4m" on a busy server. The OS caps it at a maximum, on linux unbound
|
||||
needs root permission to bypass the limit, or the admin can use sysctl
|
||||
net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf.
|
||||
On OpenBSD change header and recompile kernel. On Solaris ndd \-set
|
||||
/dev/udp udp_max_buf 8388608.
|
||||
.TP
|
||||
.B rrset\-cache\-size: \fI<number>
|
||||
Number of bytes size of the RRset cache. Default is 4 megabytes.
|
||||
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
@@ -212,6 +236,14 @@ When the internal TTL expires, the cache item has expired.
|
||||
Can be set lower to force the resolver to query for data often, and not
|
||||
trust (very large) TTL values.
|
||||
.TP
|
||||
.B cache\-min\-ttl: \fI<seconds>
|
||||
Time to live minimum for RRsets and messages in the cache. Default is 0.
|
||||
If the the minimum kicks in, the data is cached for longer than the domain
|
||||
owner intended, and thus less queries are made to look up the data.
|
||||
Zero makes sure the data in the cache is as the domain owner intended,
|
||||
higher values, especially more than an hour or so, can lead to trouble as
|
||||
the data in the cache does not match up with the actual data any more.
|
||||
.TP
|
||||
.B infra\-host\-ttl: \fI<seconds>
|
||||
Time to live for entries in the host cache. The host cache contains
|
||||
roundtrip timing and EDNS support information. Default is 900.
|
||||
@@ -335,6 +367,11 @@ The log facility LOG_DAEMON is used, with identity "unbound".
|
||||
The logfile setting is overridden when use\-syslog is turned on.
|
||||
The default is to log to syslog.
|
||||
.TP
|
||||
.B log\-time\-ascii: \fI<yes or no>
|
||||
Sets logfile lines to use a timestamp in UTC ascii. Default is no, which
|
||||
prints the seconds since 1970 in brackets. No effect if using syslog, in
|
||||
that case syslog formats the timestamp printed into the log files.
|
||||
.TP
|
||||
.B pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
@@ -417,7 +454,7 @@ not RFC standard, and could lead to performance problems because of the
|
||||
extra query load that is generated. Experimental option.
|
||||
.TP
|
||||
.B use\-caps\-for\-id: \fI<yes or no>
|
||||
Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
Use 0x20\-encoded random bits in the query to foil spoof attempts.
|
||||
This perturbs the lowercase and uppercase of query names sent to
|
||||
authority servers and checks if the reply still has the correct casing.
|
||||
Disabled by default.
|
||||
@@ -428,7 +465,7 @@ Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for public
|
||||
internet names. Any occurence of such addresses are removed from
|
||||
DNS answers. Additionally, the DNSSEC validator may mark the answers
|
||||
bogus. This protects against so-called DNS Rebinding, where a user browser
|
||||
bogus. This protects against so\-called DNS Rebinding, where a user browser
|
||||
is turned into a network proxy, allowing remote access through the browser
|
||||
to other parts of your private network. Some names can be allowed to
|
||||
contain your private addresses, by default all the \fBlocal\-data\fR
|
||||
@@ -468,6 +505,7 @@ Module configuration, a list of module names separated by spaces, surround
|
||||
the string with quotes (""). The modules can be validator, iterator.
|
||||
Setting this to "iterator" will result in a non\-validating server.
|
||||
Setting this to "validator iterator" will turn on DNSSEC validation.
|
||||
The ordering of the modules is important.
|
||||
You must also set trust\-anchors for validation to be useful.
|
||||
.TP
|
||||
.B trust\-anchor\-file: \fI<filename>
|
||||
@@ -475,6 +513,13 @@ File with trusted keys for validation. Both DS and DNSKEY entries can appear
|
||||
in the file. The format of the file is the standard DNS Zone file format.
|
||||
Default is "", or no trust anchor file.
|
||||
.TP
|
||||
.B auto\-trust\-anchor\-file: \fI<filename>
|
||||
File with trust anchor for one zone, which is tracked with RFC5011 probes.
|
||||
The probes are several times per month, thus the machine must be online
|
||||
frequently. The initial file can be one with contents as described in
|
||||
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
|
||||
so the unbound user must have write permission.
|
||||
.TP
|
||||
.B trust\-anchor: \fI<"Resource Record">
|
||||
A DS or DNSKEY RR for a key to use for validation. Multiple entries can be
|
||||
given to specify multiple trusted keys, in addition to the trust\-anchor\-files.
|
||||
@@ -488,6 +533,8 @@ File with trusted keys for validation. Specify more than one file
|
||||
with several entries, one file per entry. Like \fBtrust\-anchor\-file\fR
|
||||
but has a different file format. Format is BIND\-9 style format,
|
||||
the trusted\-keys { name flag proto algo "key"; }; clauses are read.
|
||||
It is possible to use wildcards with this statement, the wildcard is
|
||||
expanded on start and on reload.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
File with trusted keys for DLV (DNSSEC Lookaside Validation). Both DS and
|
||||
@@ -499,12 +546,39 @@ means that it is a lookaside for the root. Default is "", or no dlv anchor file.
|
||||
.B dlv\-anchor: \fI<"Resource Record">
|
||||
Much like trust\-anchor, this is a DLV anchor with the DS or DNSKEY inline.
|
||||
.TP
|
||||
.B domain\-insecure: \fI<domain name>
|
||||
Sets domain name to be insecure, DNSSEC chain of trust is ignored towards
|
||||
the domain name. So a trust anchor above the domain name can not make the
|
||||
domain secure with a DS record, such a DS record is then ignored.
|
||||
Also keys from DLV are ignored for the domain. Can be given multiple times
|
||||
to specify multiple domains that are treated as if unsigned. If you set
|
||||
trust anchors for the domain they override this setting (and the domain
|
||||
is secured).
|
||||
.IP
|
||||
This can be useful if you want to make sure a trust anchor for external
|
||||
lookups does not affect an (unsigned) internal domain. A DS record
|
||||
externally can create validation failures for that internal domain.
|
||||
.TP
|
||||
.B val\-override\-date: \fI<rrsig\-style date spec>
|
||||
Default is "" or "0", which disables this debugging feature. If enabled by
|
||||
giving a RRSIG style date, that date is used for verifying RRSIG inception
|
||||
and expiration dates, instead of the current date. Do not set this unless
|
||||
you are debugging signature inception and expiration.
|
||||
.TP
|
||||
.B val\-sig\-skew\-min: \fI<seconds>
|
||||
Minimum number of seconds of clock skew to apply to validated signatures.
|
||||
A value of 10% of the signature lifetime is used, capped by this setting.
|
||||
Default is 3600 (1 hour) which allows for daylight savings differences.
|
||||
Lower this value for more strict checking of short lived signatures.
|
||||
.TP
|
||||
.B val\-sig\-skew\-max: \fI<seconds>
|
||||
Maximum number of seconds of clock skew to apply to validated signatures.
|
||||
A value of 10% of the signature lifetime is used, capped by this setting.
|
||||
Default is 86400 (24 hours) which allows for timezone setting problems in
|
||||
stable domains. Setting both min and max very low disables the clock skew
|
||||
allowances. Setting both min and max very high makes the validator check
|
||||
the signature timestamps less strictly.
|
||||
.TP
|
||||
.B val\-bogus\-ttl: \fI<number>
|
||||
The time to live for bogus data. This is data that has failed validation;
|
||||
due to invalid signatures or other checks. The TTL from that data cannot be
|
||||
@@ -518,6 +592,13 @@ indeterminate or unchecked are not affected. Default is yes. Use this setting
|
||||
to protect the users that rely on this validator for authentication from
|
||||
protentially bad data in the additional section.
|
||||
.TP
|
||||
.B val\-log\-level: \fI<number>
|
||||
Have the validator print validation failures to the log. Regardless of the
|
||||
verbosity setting. Default is 0, off. At 1, for every user query that fails
|
||||
a line is printed to the logs. This way you can monitor what happens with
|
||||
validation. Use a diagnosis tool, such as dig or drill, to find out why
|
||||
validation is failing for these queries.
|
||||
.TP
|
||||
.B val\-permissive\-mode: \fI<yes or no>
|
||||
Instruct the validator to mark bogus messages as indeterminate. The security
|
||||
checks are performed, but if the result is bogus (failed security), the
|
||||
@@ -535,6 +616,26 @@ be in ascending order and have at least one entry. If you set it to
|
||||
"1024 65535" there is no restriction to NSEC3 iteration values.
|
||||
This table must be kept short; a very long list could cause slower operation.
|
||||
.TP
|
||||
.B add\-holddown: \fI<seconds>
|
||||
Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011
|
||||
autotrust updates to add new trust anchors only after they have been
|
||||
visible for this time. Default is 30 days as per the RFC.
|
||||
.TP
|
||||
.B del\-holddown: \fI<seconds>
|
||||
Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011
|
||||
autotrust updates to remove revoked trust anchors after they have been
|
||||
kept in the revoked list for this long. Default is 30 days as per
|
||||
the RFC.
|
||||
.TP
|
||||
.B keep\-missing: \fI<seconds>
|
||||
Instruct the \fBauto\-trust\-anchor\-file\fR probe mechanism for RFC5011
|
||||
autotrust updates to remove missing trust anchors after they have been
|
||||
unseen for this long. This cleans up the state file if the target zone
|
||||
does not perform trust anchor revocation, so this makes the auto probe
|
||||
mechanism work with zones that perform regular (non\-5011) rollovers.
|
||||
The default is 366 days. The value 0 does not remove missing anchors,
|
||||
as per the RFC.
|
||||
.TP
|
||||
.B key\-cache\-size: \fI<number>
|
||||
Number of bytes size of the key cache. Default is 4 megabytes.
|
||||
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
@@ -577,19 +678,23 @@ as local\-data for the zone apex domain.
|
||||
.TP 10
|
||||
\h'5'\fItransparent\fR
|
||||
If there is a match from local data, the query is answered.
|
||||
Otherwise, the query is resolved normally.
|
||||
Otherwise if the query has a different name, the query is resolved normally.
|
||||
If the query is for a name given in localdata but no such type of data is
|
||||
given in localdata, then a noerror nodata answer is returned.
|
||||
If no local\-zone is given local\-data causes a transparent zone
|
||||
to be created by default.
|
||||
.TP 10
|
||||
\h'5'\fIredirect\fR
|
||||
The query is answered from the local data for the zone name.
|
||||
The query is answered from the local data for the zone name.
|
||||
There may be no local data beneath the zone name.
|
||||
This answers queries for the zone, and all subdomains of the zone
|
||||
with the local data for the zone.
|
||||
It can be used to redirect a domain to a different address, with
|
||||
It can be used to redirect a domain to return a different address record
|
||||
to the end user, with
|
||||
local\-zone: "example.com." redirect and
|
||||
local\-data: "example.com. A 127.0.0.1"
|
||||
queries for www.example.com and www.foo.example.com are redirected.
|
||||
queries for www.example.com and www.foo.example.com are redirected, so
|
||||
that users with web browsers cannot access sites with suffix example.com.
|
||||
.TP 10
|
||||
\h'5'\fInodefault\fR
|
||||
Used to turn off default contents for AS112 zones. The other types
|
||||
@@ -671,7 +776,7 @@ Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa.
|
||||
Reverse data for zone 8.B.D.0.1.0.0.2.ip6.arpa. This zone is used for
|
||||
tutorials and examples. You can remove the block on this zone with:
|
||||
.nf
|
||||
local-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault
|
||||
local\-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault
|
||||
.fi
|
||||
This also works with the other default zones.
|
||||
.\" End of local-zone listing.
|
||||
@@ -701,7 +806,7 @@ enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
to setup SSLv3 / TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self-signed certificates use the
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup\fR(8) utility.
|
||||
.TP 5
|
||||
.B control\-enable: \fI<yes or no>
|
||||
@@ -745,6 +850,8 @@ There may be multiple
|
||||
.B stub\-zone:
|
||||
clauses. Each with a name: and zero or more hostnames or IP addresses.
|
||||
For the stub zone this list of nameservers is used. Class IN is assumed.
|
||||
The servers should be authority servers, not recursors; unbound performs
|
||||
the recursive processing itself for stub zones.
|
||||
.P
|
||||
The stub zone can be used to configure authoritative data to be used
|
||||
by the resolver that cannot be accessed using the public internet servers.
|
||||
@@ -783,11 +890,16 @@ the resolver picks up a correct list online.
|
||||
.LP
|
||||
There may be multiple
|
||||
.B forward\-zone:
|
||||
clauses. Each with a name: and zero or more hostnames or IP addresses.
|
||||
For the forward zone this list of nameservers is used to forward the queries
|
||||
to. The servers have to handle further recursion for the query. Class IN is
|
||||
assumed. A forward\-zone entry with name "." and a forward\-addr target will
|
||||
forward all queries to that other server (unless it can answer from the cache).
|
||||
clauses. Each with a \fBname:\fR and zero or more hostnames or IP
|
||||
addresses. For the forward zone this list of nameservers is used to
|
||||
forward the queries to. The servers listed as \fBforward\-host:\fR and
|
||||
\fBforward\-addr:\fR have to handle further recursion for the query. Thus,
|
||||
those servers are not authority servers, but are (just like unbound is)
|
||||
recursive servers too; unbound does not perform recursion itself for the
|
||||
forward zone, it lets the remote server do it. Class IN is assumed.
|
||||
A forward\-zone entry with name "." and a forward\-addr target will
|
||||
forward all queries to that other server (unless it can answer from
|
||||
the cache).
|
||||
.TP
|
||||
.B name: \fI<domain name>
|
||||
Name of the forward zone.
|
||||
@@ -798,6 +910,18 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||
.B forward\-addr: \fI<IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
.SS "Python Module Options"
|
||||
.LP
|
||||
The
|
||||
.B python:
|
||||
clause gives the settings for the \fIpython\fR(1) script module. This module
|
||||
acts like the iterator and validator modules do, on queries and answers.
|
||||
To enable the script module it has to be compiled into the daemon,
|
||||
and the word "python" has to be put in the \fBmodule\-conf:\fR option
|
||||
(usually first, or between the validator and iterator).
|
||||
.TP
|
||||
.B python\-script: \fI<python file>\fR
|
||||
The script file to load.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
@@ -805,7 +929,7 @@ supported. Very large data and high TCP loads are exceptional for the DNS.
|
||||
DNSSEC validation is enabled, just add trust anchors.
|
||||
If you do not have to worry about programs using more than 3 Mb of memory,
|
||||
the below example is not for you. Use the defaults to receive full service,
|
||||
which on BSD-32bit tops out at 30-40 Mb after heavy usage.
|
||||
which on BSD\-32bit tops out at 30\-40 Mb after heavy usage.
|
||||
.P
|
||||
.nf
|
||||
# example settings that reduce memory usage
|
||||
|
||||
+9
-3
@@ -150,8 +150,7 @@ MULTILINE_CPP_IS_BRIEF = NO
|
||||
# will output the detailed description near the top, like JavaDoc.
|
||||
# If set to NO, the detailed description appears after the member
|
||||
# documentation.
|
||||
|
||||
DETAILS_AT_TOP = NO
|
||||
#DETAILS_AT_TOP = NO
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||
# member inherits the documentation from any documented member that it
|
||||
@@ -496,6 +495,13 @@ EXCLUDE = ./build \
|
||||
util/configparser.h \
|
||||
util/configlexer.c \
|
||||
util/locks.h \
|
||||
pythonmod/unboundmodule.py \
|
||||
pythonmod/interface.h \
|
||||
pythonmod/examples/resgen.py \
|
||||
pythonmod/examples/resmod.py \
|
||||
pythonmod/examples/resip.py \
|
||||
libunbound/python/unbound.py \
|
||||
libunbound/python/libunbound_wrap.c \
|
||||
./ldns-src
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
|
||||
@@ -914,7 +920,7 @@ MAN_LINKS = NO
|
||||
# generate an XML file that captures the structure of
|
||||
# the code including all documentation.
|
||||
|
||||
GENERATE_XML = NO
|
||||
GENERATE_XML = YES
|
||||
|
||||
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
|
||||
+468
-200
@@ -1,251 +1,519 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
|
||||
scriptversion=2006-12-25.00
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
true
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
chmodcmd=""
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
posix_mkdir=
|
||||
|
||||
pathcomp=''
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
if test -z "$dir_arg"; then
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
true
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
fi &&
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
|
||||
@@ -68,6 +68,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||
return NULL;
|
||||
if(!delegpt_set_name(copy, region, dp->name))
|
||||
return NULL;
|
||||
copy->bogus = dp->bogus;
|
||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||
if(!delegpt_add_ns(copy, region, ns->name))
|
||||
return NULL;
|
||||
@@ -423,3 +424,23 @@ delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
||||
log_warn("Unknown rrset type added to delegpt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
|
||||
{
|
||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||
if(!rep) return;
|
||||
|
||||
/* if error or no answers */
|
||||
if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
|
||||
struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname,
|
||||
msg->key.qname_len);
|
||||
if(ns) {
|
||||
if(msg->key.qtype == LDNS_RR_TYPE_A)
|
||||
ns->got4 = 1;
|
||||
else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
|
||||
ns->got6 = 1;
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ struct delegpt_ns;
|
||||
struct delegpt_addr;
|
||||
struct dns_msg;
|
||||
struct ub_packed_rrset_key;
|
||||
struct msgreply_entry;
|
||||
|
||||
/**
|
||||
* Delegation Point.
|
||||
@@ -299,4 +300,11 @@ size_t delegpt_count_missing_targets(struct delegpt* dp);
|
||||
struct delegpt* delegpt_from_message(struct dns_msg* msg,
|
||||
struct regional* regional);
|
||||
|
||||
/**
|
||||
* Add negative message to delegation point.
|
||||
* @param dp: delegation point.
|
||||
* @param msg: the message added, marks off A or AAAA from an NS entry.
|
||||
*/
|
||||
void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg);
|
||||
|
||||
#endif /* ITERATOR_ITER_DELEGPT_H */
|
||||
|
||||
+100
-6
@@ -88,9 +88,10 @@ forwards_delete(struct iter_forwards* fwd)
|
||||
free(fwd);
|
||||
}
|
||||
|
||||
/** insert new info into forward structure */
|
||||
/** insert info into forward structure */
|
||||
static int
|
||||
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
|
||||
size_t nmlen, int nmlabs, struct delegpt* dp)
|
||||
{
|
||||
struct iter_forward_zone* node = regional_alloc(fwd->region,
|
||||
sizeof(struct iter_forward_zone));
|
||||
@@ -98,11 +99,11 @@ forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
return 0;
|
||||
node->node.key = node;
|
||||
node->dclass = c;
|
||||
node->name = regional_alloc_init(fwd->region, dp->name, dp->namelen);
|
||||
node->name = regional_alloc_init(fwd->region, nm, nmlen);
|
||||
if(!node->name)
|
||||
return 0;
|
||||
node->namelen = dp->namelen;
|
||||
node->namelabs = dp->namelabs;
|
||||
node->namelen = nmlen;
|
||||
node->namelabs = nmlabs;
|
||||
node->dp = dp;
|
||||
if(!rbtree_insert(fwd->tree, &node->node)) {
|
||||
log_err("duplicate forward zone ignored.");
|
||||
@@ -110,6 +111,14 @@ forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** insert new info into forward structure given dp */
|
||||
static int
|
||||
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
{
|
||||
return forwards_insert_data(fwd, c, dp->name, dp->namelen,
|
||||
dp->namelabs, dp);
|
||||
}
|
||||
|
||||
/** initialise parent pointers in the tree */
|
||||
static void
|
||||
fwd_init_parents(struct iter_forwards* fwd)
|
||||
@@ -234,10 +243,61 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if zone needs to have a hole inserted */
|
||||
static int
|
||||
need_hole_insert(rbtree_t* tree, struct iter_forward_zone* zone)
|
||||
{
|
||||
struct iter_forward_zone k;
|
||||
if(rbtree_search(tree, zone))
|
||||
return 0; /* exact match exists */
|
||||
k = *zone;
|
||||
k.node.key = &k;
|
||||
/* search up the tree */
|
||||
do {
|
||||
dname_remove_label(&k.name, &k.namelen);
|
||||
k.namelabs --;
|
||||
if(rbtree_search(tree, &k))
|
||||
return 1; /* found an upper forward zone, need hole */
|
||||
} while(k.namelabs > 1);
|
||||
return 0; /* no forwards above, no holes needed */
|
||||
}
|
||||
|
||||
/** make NULL entries for stubs */
|
||||
static int
|
||||
make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
{
|
||||
struct config_stub* s;
|
||||
struct iter_forward_zone key;
|
||||
key.node.key = &key;
|
||||
key.dclass = LDNS_RR_CLASS_IN;
|
||||
for(s = cfg->stubs; s; s = s->next) {
|
||||
ldns_rdf* rdf = ldns_dname_new_frm_str(s->name);
|
||||
if(!rdf) {
|
||||
log_err("cannot parse stub name '%s'", s->name);
|
||||
return 0;
|
||||
}
|
||||
key.name = ldns_rdf_data(rdf);
|
||||
key.namelabs = dname_count_size_labels(key.name, &key.namelen);
|
||||
if(!need_hole_insert(fwd->tree, &key)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
continue;
|
||||
}
|
||||
if(!forwards_insert_data(fwd, key.dclass, key.name,
|
||||
key.namelen, key.namelabs, NULL)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
{
|
||||
free(fwd->tree);
|
||||
regional_free_all(fwd->region);
|
||||
fwd->tree = rbtree_create(fwd_cmp);
|
||||
if(!fwd->tree)
|
||||
return 0;
|
||||
@@ -245,6 +305,8 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
/* read forward zones */
|
||||
if(!read_forwards(fwd, cfg))
|
||||
return 0;
|
||||
if(!make_stub_holes(fwd, cfg))
|
||||
return 0;
|
||||
fwd_init_parents(fwd);
|
||||
return 1;
|
||||
}
|
||||
@@ -283,10 +345,42 @@ forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct delegpt*
|
||||
forwards_lookup_root(struct iter_forwards* fwd, uint16_t qclass)
|
||||
{
|
||||
uint8_t root = 0;
|
||||
return forwards_lookup(fwd, &root, qclass);
|
||||
}
|
||||
|
||||
size_t
|
||||
forwards_get_mem(struct iter_forwards* fwd)
|
||||
{
|
||||
if(!fwd)
|
||||
return 0;
|
||||
return sizeof(*fwd) + regional_get_mem(fwd->region);
|
||||
return sizeof(*fwd) + sizeof(*fwd->tree) +
|
||||
regional_get_mem(fwd->region);
|
||||
}
|
||||
|
||||
int
|
||||
forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
|
||||
{
|
||||
if(!forwards_insert(fwd, c, dp))
|
||||
return 0;
|
||||
fwd_init_parents(fwd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
|
||||
{
|
||||
struct iter_forward_zone key;
|
||||
key.node.key = &key;
|
||||
key.dclass = c;
|
||||
key.name = nm;
|
||||
key.namelabs = dname_count_size_labels(nm, &key.namelen);
|
||||
if(!rbtree_search(fwd->tree, &key))
|
||||
return; /* nothing to do */
|
||||
(void)rbtree_delete(fwd->tree, &key);
|
||||
fwd_init_parents(fwd);
|
||||
}
|
||||
|
||||
|
||||
+36
-2
@@ -43,7 +43,6 @@
|
||||
#ifndef ITERATOR_ITER_FWD_H
|
||||
#define ITERATOR_ITER_FWD_H
|
||||
#include "util/rbtree.h"
|
||||
struct iter_env;
|
||||
struct config_file;
|
||||
struct delegpt;
|
||||
struct regional;
|
||||
@@ -76,7 +75,9 @@ struct iter_forward_zone {
|
||||
size_t namelen;
|
||||
/** number of labels in name */
|
||||
int namelabs;
|
||||
/** delegation point with forward server information for this zone. */
|
||||
/** delegation point with forward server information for this zone.
|
||||
* If NULL then this forward entry is used to indicate that a
|
||||
* stub-zone with the same name exists, and should be used. */
|
||||
struct delegpt* dp;
|
||||
/** pointer to parent in tree (or NULL if none) */
|
||||
struct iter_forward_zone* parent;
|
||||
@@ -118,6 +119,15 @@ int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
|
||||
struct delegpt* forwards_lookup(struct iter_forwards* fwd,
|
||||
uint8_t* qname, uint16_t qclass);
|
||||
|
||||
/**
|
||||
* Same as forwards_lookup, but for the root only
|
||||
* @param fwd: forward storage.
|
||||
* @param qclass: The qclass of the query.
|
||||
* @return: A delegation point if root forward exists, otherwise null.
|
||||
*/
|
||||
struct delegpt* forwards_lookup_root(struct iter_forwards* fwd,
|
||||
uint16_t qclass);
|
||||
|
||||
/**
|
||||
* Get memory in use by forward storage
|
||||
* @param fwd: forward storage.
|
||||
@@ -128,4 +138,28 @@ size_t forwards_get_mem(struct iter_forwards* fwd);
|
||||
/** compare two fwd entries */
|
||||
int fwd_cmp(const void* k1, const void* k2);
|
||||
|
||||
/**
|
||||
* Add zone to forward structure. For external use since it recalcs
|
||||
* the tree parents.
|
||||
* @param fwd: the forward data structure
|
||||
* @param c: class of zone
|
||||
* @param dp: delegation point with name and target nameservers for new
|
||||
* forward zone. This delegation point and all its data must be
|
||||
* malloced in the fwd->region. (then it is freed when the fwd is
|
||||
* deleted).
|
||||
* @return false on failure (out of memory);
|
||||
*/
|
||||
int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
|
||||
struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* Remove zone from forward structure. For external use since it
|
||||
* recalcs the tree parents. Does not actually release any memory, the region
|
||||
* is unchanged.
|
||||
* @param fwd: the forward data structure
|
||||
* @param c: class of zone
|
||||
* @param nm: name of zone (in uncompressed wireformat).
|
||||
*/
|
||||
void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm);
|
||||
|
||||
#endif /* ITERATOR_ITER_FWD_H */
|
||||
|
||||
@@ -133,6 +133,7 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||
if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) return 0;
|
||||
if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) return 0;
|
||||
if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "2001:7fd::1")) return 0;
|
||||
if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "2001:500:3::42")) return 0;
|
||||
if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "2001:dc3::35")) return 0;
|
||||
}
|
||||
return dp;
|
||||
|
||||
+21
-14
@@ -210,43 +210,50 @@ size_t priv_get_mem(struct iter_priv* priv)
|
||||
int priv_rrset_bad(struct iter_priv* priv, ldns_buffer* pkt,
|
||||
struct rrset_parse* rrset)
|
||||
{
|
||||
if(priv->a.count == 0)
|
||||
return 0; /* there are no blocked addresses */
|
||||
|
||||
/* see if it is a private name, that is allowed to have any */
|
||||
if(priv_lookup_name(priv, pkt, rrset->dname, rrset->dname_len,
|
||||
ntohs(rrset->rrset_class))) {
|
||||
return 0;
|
||||
} else {
|
||||
/* so its a public name, check the address */
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
struct rr_parse* rr;
|
||||
if(rrset->type == LDNS_RR_TYPE_A) {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)&addr;
|
||||
len = (socklen_t)sizeof(*sa);
|
||||
memset(sa, 0, len);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in sa;
|
||||
|
||||
len = (socklen_t)sizeof(sa);
|
||||
memset(&sa, 0, len);
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
for(rr = rrset->rr_first; rr; rr = rr->next) {
|
||||
if(ldns_read_uint16(rr->ttl_data+4)
|
||||
!= INET_SIZE)
|
||||
continue;
|
||||
memmove(&sa->sin_addr, rr->ttl_data+4+2,
|
||||
memmove(&sa.sin_addr, rr->ttl_data+4+2,
|
||||
INET_SIZE);
|
||||
memmove(&addr, &sa, len);
|
||||
if(priv_lookup_addr(priv, &addr, len))
|
||||
return 1;
|
||||
}
|
||||
} else if(rrset->type == LDNS_RR_TYPE_AAAA) {
|
||||
struct sockaddr_in6* sa = (struct sockaddr_in6*)&addr;
|
||||
len = (socklen_t)sizeof(*sa);
|
||||
memset(sa, 0, len);
|
||||
sa->sin6_family = AF_INET6;
|
||||
sa->sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in6 sa;
|
||||
len = (socklen_t)sizeof(sa);
|
||||
memset(&sa, 0, len);
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
for(rr = rrset->rr_first; rr; rr = rr->next) {
|
||||
if(ldns_read_uint16(rr->ttl_data+4)
|
||||
!= INET6_SIZE)
|
||||
continue;
|
||||
memmove(&sa->sin6_addr, rr->ttl_data+4+2,
|
||||
memmove(&sa.sin6_addr, rr->ttl_data+4+2,
|
||||
INET6_SIZE);
|
||||
if(priv_lookup_addr(priv, &addr, len))
|
||||
memmove(&addr, &sa, len);
|
||||
if(priv_lookup_addr(priv, &addr, len))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,8 +101,6 @@ has_additional(uint16_t t)
|
||||
case LDNS_RR_TYPE_NAPTR:
|
||||
/* TODO: NAPTR not supported, glue stripped off */
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+148
-25
@@ -61,6 +61,11 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "validator/val_anchor.h"
|
||||
|
||||
/** time when nameserver glue is said to be 'recent' */
|
||||
#define SUSPICION_RECENT_EXPIRY 86400
|
||||
/** penalty to validation failed blacklisted IPs */
|
||||
#define BLACKLIST_PENALTY (USEFUL_SERVER_TOP_TIMEOUT*3)
|
||||
|
||||
/** fillup fetch policy array */
|
||||
static void
|
||||
fetch_fill(struct iter_env* ie, const char* str)
|
||||
@@ -112,12 +117,6 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
log_err("Could not set root or stub hints");
|
||||
return 0;
|
||||
}
|
||||
if(!iter_env->fwds)
|
||||
iter_env->fwds = forwards_create();
|
||||
if(!iter_env->fwds || !forwards_apply_cfg(iter_env->fwds, cfg)) {
|
||||
log_err("Could not set forward zones");
|
||||
return 0;
|
||||
}
|
||||
if(!iter_env->donotq)
|
||||
iter_env->donotq = donotq_create();
|
||||
if(!iter_env->donotq || !donotq_apply_cfg(iter_env->donotq, cfg)) {
|
||||
@@ -134,13 +133,52 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** filter out unsuitable targets, return rtt or -1 */
|
||||
/** filter out unsuitable targets
|
||||
* @param iter_env: iterator environment with ipv6-support flag.
|
||||
* @param env: module environment with infra cache.
|
||||
* @param name: zone name
|
||||
* @param namelen: length of name
|
||||
* @param qtype: query type (host order).
|
||||
* @param now: current time
|
||||
* @param a: address in delegation point we are examining.
|
||||
* @return an integer that signals the target suitability.
|
||||
* as follows:
|
||||
* -1: The address should be omitted from the list.
|
||||
* Because:
|
||||
* o The address is bogus (DNSSEC validation failure).
|
||||
* o Listed as donotquery
|
||||
* o is ipv6 but no ipv6 support (in operating system).
|
||||
* o is lame
|
||||
* Otherwise, an rtt in milliseconds.
|
||||
* 0 .. USEFUL_SERVER_TOP_TIMEOUT-1
|
||||
* The roundtrip time timeout estimate. less than 2 minutes.
|
||||
* Note that util/rtt.c has a MIN_TIMEOUT of 50 msec, thus
|
||||
* values 0 .. 49 are not used, unless that is changed.
|
||||
* USEFUL_SERVER_TOP_TIMEOUT
|
||||
* This value exactly is given for unresponsive blacklisted.
|
||||
* USEFUL_SERVER_TOP_TIMEOUT+1
|
||||
* For non-blacklisted servers: huge timeout, but has traffic.
|
||||
* USEFUL_SERVER_TOP_TIMEOUT ..
|
||||
* dnsseclame servers get penalty
|
||||
* USEFUL_SERVER_TOP_TIMEOUT*2 ..
|
||||
* recursion lame servers get penalty
|
||||
* UNKNOWN_SERVER_NICENESS
|
||||
* If no information is known about the server, this is
|
||||
* returned. 376 msec or so.
|
||||
* +BLACKLIST_PENALTY (of USEFUL_TOP_TIMEOUT*3) for dnssec failed IPs.
|
||||
*
|
||||
* When a final value is chosen that is dnsseclame ; dnsseclameness checking
|
||||
* is turned off (so we do not discard the reply).
|
||||
* When a final value is chosen that is recursionlame; RD bit is set on query.
|
||||
* Because of the numbers this means recursionlame also have dnssec lameness
|
||||
* checking turned off.
|
||||
*/
|
||||
static int
|
||||
iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt_addr* a)
|
||||
{
|
||||
int rtt, lame, reclame, dnsseclame;
|
||||
int rtt, lame, reclame, dnsseclame, lost;
|
||||
if(a->bogus)
|
||||
return -1; /* address of server is bogus */
|
||||
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
|
||||
@@ -152,11 +190,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||
&rtt, now)) {
|
||||
&rtt, &lost, now)) {
|
||||
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
|
||||
verbose(VERB_ALGO, " rtt=%d%s%s%s", rtt,
|
||||
lame?" LAME":"",
|
||||
dnsseclame?" DNSSEC_LAME":"",
|
||||
reclame?" REC_LAME":"");
|
||||
if(lame)
|
||||
return -1; /* server is lame */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
return -1; /* server is unresponsive */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
|
||||
lost >= USEFUL_SERVER_MAX_LOST)
|
||||
/* server is unresponsive */
|
||||
return USEFUL_SERVER_TOP_TIMEOUT;
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT) /* not blacklisted*/
|
||||
return USEFUL_SERVER_TOP_TIMEOUT+1;
|
||||
else if(reclame)
|
||||
return rtt+USEFUL_SERVER_TOP_TIMEOUT*2; /* nonpref */
|
||||
else if(dnsseclame )
|
||||
@@ -171,7 +218,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
static int
|
||||
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt* dp, int* best_rtt)
|
||||
struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
|
||||
{
|
||||
int got_it = 0;
|
||||
struct delegpt_addr* a;
|
||||
@@ -181,6 +228,9 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
a->sel_rtt = iter_filter_unsuitable(iter_env, env,
|
||||
name, namelen, qtype, now, a);
|
||||
if(a->sel_rtt != -1) {
|
||||
if(sock_list_find(blacklist, &a->addr, a->addrlen))
|
||||
a->sel_rtt += BLACKLIST_PENALTY;
|
||||
|
||||
if(!got_it) {
|
||||
*best_rtt = a->sel_rtt;
|
||||
got_it = 1;
|
||||
@@ -197,20 +247,23 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
static int
|
||||
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt* dp, int* selected_rtt)
|
||||
struct delegpt* dp, int* selected_rtt, int open_target,
|
||||
struct sock_list* blacklist)
|
||||
{
|
||||
int got_num = 0, low_rtt = 0, swap_to_front;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
|
||||
&low_rtt);
|
||||
&low_rtt, blacklist);
|
||||
if(got_num == 0)
|
||||
return 0;
|
||||
if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
|
||||
delegpt_count_missing_targets(dp) > 0)
|
||||
(delegpt_count_missing_targets(dp) > 0 || open_target > 0)) {
|
||||
verbose(VERB_ALGO, "Bad choices, trying to get more choice");
|
||||
return 0; /* we want more choice. The best choice is a bad one.
|
||||
return 0 to force the caller to fetch more */
|
||||
}
|
||||
|
||||
got_num = 0;
|
||||
a = dp->result_list;
|
||||
@@ -250,22 +303,35 @@ struct delegpt_addr*
|
||||
iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_expected,
|
||||
int* chase_to_rd)
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist)
|
||||
{
|
||||
int sel;
|
||||
int selrtt;
|
||||
struct delegpt_addr* a, *prev;
|
||||
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
|
||||
*env->now, dp, &selrtt);
|
||||
*env->now, dp, &selrtt, open_target, blacklist);
|
||||
|
||||
if(num == 0)
|
||||
return NULL;
|
||||
if(selrtt >= USEFUL_SERVER_TOP_TIMEOUT*2) {
|
||||
verbose(VERB_ALGO, "selrtt %d", selrtt);
|
||||
if(selrtt > USEFUL_SERVER_TOP_TIMEOUT*2) {
|
||||
verbose(VERB_ALGO, "chase to recursion lame server");
|
||||
*chase_to_rd = 1;
|
||||
}
|
||||
if(selrtt >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(selrtt > USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
verbose(VERB_ALGO, "chase to dnssec lame server");
|
||||
*dnssec_expected = 0;
|
||||
}
|
||||
if(selrtt == USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
verbose(VERB_ALGO, "chase to blacklisted lame server");
|
||||
/* the best choice is a blacklisted, unresponsive server,
|
||||
* we need to throttle down our traffic towards it */
|
||||
if(ub_random(env->rnd) % 100 != 1) {
|
||||
/* 99% of the time, drop query */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(num == 1) {
|
||||
a = dp->result_list;
|
||||
if(++a->attempts < OUTBOUND_MSG_RETRY)
|
||||
@@ -273,6 +339,7 @@ iter_server_selection(struct iter_env* iter_env,
|
||||
dp->result_list = a->next_result;
|
||||
return a;
|
||||
}
|
||||
|
||||
/* randomly select a target from the list */
|
||||
log_assert(num > 1);
|
||||
/* we do not need secure random numbers here, but
|
||||
@@ -347,6 +414,54 @@ iter_ns_probability(struct ub_randstate* rnd, int n, int m)
|
||||
return (sel < n);
|
||||
}
|
||||
|
||||
int iter_suspect_exists(struct query_info* qinfo, struct delegpt* dp,
|
||||
struct module_env* env)
|
||||
{
|
||||
struct ub_packed_rrset_key* r;
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_A && qinfo->qtype != LDNS_RR_TYPE_AAAA)
|
||||
return 0; /* not glue type */
|
||||
if(!dname_subdomain_c(qinfo->qname, dp->name))
|
||||
return 0; /* not in-zone */
|
||||
if(!delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len))
|
||||
return 0; /* not glue */
|
||||
|
||||
/* do we suspect that it exists? lookup with time=0 */
|
||||
r = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qtype, qinfo->qclass, 0, 0, 0);
|
||||
if(r) {
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
r->entry.data;
|
||||
/* if it is valid, no need for queries to parent zone */
|
||||
if(*env->now <= d->ttl) {
|
||||
lock_rw_unlock(&r->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
/* was it recently expired? */
|
||||
if( (*env->now - d->ttl) <= SUSPICION_RECENT_EXPIRY) {
|
||||
verbose(VERB_ALGO, "suspect glue at parent: "
|
||||
"rrset recently expired");
|
||||
lock_rw_unlock(&r->entry.lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&r->entry.lock);
|
||||
}
|
||||
|
||||
/* so, qinfo not there, does the other A/AAAA type exist in cache? */
|
||||
r=rrset_cache_lookup(env->rrset_cache, qinfo->qname, qinfo->qname_len,
|
||||
(qinfo->qtype==LDNS_RR_TYPE_A)?LDNS_RR_TYPE_AAAA:LDNS_RR_TYPE_A,
|
||||
qinfo->qclass, 0, *env->now, 0);
|
||||
if(r) {
|
||||
/* it exists and explains why the glue is there */
|
||||
lock_rw_unlock(&r->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* neither exist, so logically, one should exist for a nameserver */
|
||||
verbose(VERB_ALGO, "suspect glue at parent: "
|
||||
"neither A nor AAAA exist in cache");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** detect dependency cycle for query and target */
|
||||
static int
|
||||
causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
||||
@@ -391,19 +506,19 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
{
|
||||
struct delegpt_ns* ns;
|
||||
/* check:
|
||||
* o RD qflag is off.
|
||||
* o no addresses are provided.
|
||||
* o all NS items are required glue.
|
||||
* o no addresses are provided.
|
||||
* o RD qflag is on.
|
||||
* OR
|
||||
* o RD qflag is off.
|
||||
* o no addresses are provided.
|
||||
* o RD qflag is on.
|
||||
* o the query is for one of the nameservers in dp,
|
||||
* and that nameserver is a glue-name for this dp.
|
||||
*/
|
||||
if(!(qflags&BIT_RD))
|
||||
return 0;
|
||||
/* either available or unused targets */
|
||||
if(dp->usable_list || dp->result_list)
|
||||
if(dp->usable_list || dp->result_list)
|
||||
return 0;
|
||||
|
||||
/* see if query is for one of the nameservers, which is glue */
|
||||
@@ -426,13 +541,16 @@ int
|
||||
iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
|
||||
struct dns_msg* msg, uint16_t dclass)
|
||||
{
|
||||
struct trust_anchor* a;
|
||||
/* information not available, !env->anchors can be common */
|
||||
if(!env || !env->anchors || !dp || !dp->name)
|
||||
return 0;
|
||||
/* a trust anchor exists with this name, RRSIGs expected */
|
||||
if(anchor_find(env->anchors, dp->name, dp->namelabs, dp->namelen,
|
||||
dclass))
|
||||
if((a=anchor_find(env->anchors, dp->name, dp->namelabs, dp->namelen,
|
||||
dclass))) {
|
||||
lock_basic_unlock(&a->lock);
|
||||
return 1;
|
||||
}
|
||||
/* see if DS rrset was given, in AUTH section */
|
||||
if(msg && msg->rep &&
|
||||
reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
|
||||
@@ -496,6 +614,11 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
|
||||
reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen,
|
||||
LDNS_RR_TYPE_NS, dclass))
|
||||
return 1;
|
||||
/* a DNSKEY set is expected at the zone apex as well */
|
||||
/* this is for 'minimal responses' for DNSKEYs */
|
||||
if(reply_find_rrset_section_an(msg->rep, dp->name, dp->namelen,
|
||||
LDNS_RR_TYPE_DNSKEY, dclass))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+18
-1
@@ -54,6 +54,7 @@ struct ub_randstate;
|
||||
struct query_info;
|
||||
struct reply_info;
|
||||
struct module_qstate;
|
||||
struct sock_list;
|
||||
|
||||
/**
|
||||
* Process config options and set iterator module state.
|
||||
@@ -79,13 +80,16 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
* these are not preferred, but are used as a last resort.
|
||||
* @param chase_to_rd: set to 1 if a known recursion lame server is selected
|
||||
* these are not preferred, but are used as a last resort.
|
||||
* @param open_target: number of currently outstanding target queries.
|
||||
* If we wait for these, perhaps more server addresses become available.
|
||||
* @param blacklist: the IP blacklist to use.
|
||||
* @return best target or NULL if no target.
|
||||
* if not null, that target is removed from the result list in the dp.
|
||||
*/
|
||||
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp, uint8_t* name,
|
||||
size_t namelen, uint16_t qtype, int* dnssec_expected,
|
||||
int* chase_to_rd);
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist);
|
||||
|
||||
/**
|
||||
* Allocate dns_msg from parsed msg, in regional.
|
||||
@@ -135,6 +139,19 @@ int iter_ns_probability(struct ub_randstate* rnd, int n, int m);
|
||||
*/
|
||||
void iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* See if query is in-zone glue and we suspect that it exists.
|
||||
* Suspicion that it exists, is if there is no A or AAAA in cache (since
|
||||
* one of them is expected for an NS record) or the qtype is in cache but
|
||||
* was recently expired (so we have seen this data recently).
|
||||
* @param qinfo: query info.
|
||||
* @param dp: delegation point we are at.
|
||||
* @param env: environment with rrset cache.
|
||||
* @return true if suspect that this glue exists.
|
||||
*/
|
||||
int iter_suspect_exists(struct query_info* qinfo, struct delegpt* dp,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* See if delegation is useful or offers immediately no targets for
|
||||
* further recursion.
|
||||
|
||||
+217
-66
@@ -89,7 +89,6 @@ iter_deinit(struct module_env* env, int id)
|
||||
free(iter_env->target_fetch_policy);
|
||||
priv_delete(iter_env->priv);
|
||||
hints_delete(iter_env->hints);
|
||||
forwards_delete(iter_env->fwds);
|
||||
donotq_delete(iter_env->donotq);
|
||||
free(iter_env);
|
||||
env->modinfo[id] = NULL;
|
||||
@@ -229,6 +228,34 @@ error_response(struct module_qstate* qstate, int id, int rcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error to the client and cache the error code in the
|
||||
* message cache (so per qname, qtype, qclass).
|
||||
* @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_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
{
|
||||
/* store in cache */
|
||||
struct reply_info err;
|
||||
memset(&err, 0, sizeof(err));
|
||||
err.flags = (uint16_t)(BIT_QR | BIT_RA);
|
||||
FLAGS_SET_RCODE(err.flags, rcode);
|
||||
err.qdcount = 1;
|
||||
err.ttl = NORR_TTL;
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0)) {
|
||||
log_err("error_response_cache: could not store error (nomem)");
|
||||
}
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
|
||||
/** check if prepend item is duplicate item */
|
||||
static int
|
||||
prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to,
|
||||
@@ -460,6 +487,13 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
* path. */
|
||||
if(!v)
|
||||
qflags |= BIT_CD;
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_detect_cycle(
|
||||
qstate->env->detect_cycle));
|
||||
if((*qstate->env->detect_cycle)(qstate, &qinf, qflags, prime)){
|
||||
log_query_info(VERB_DETAIL, "cycle detected", &qinf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* attach subquery, lookup existing or make a new one */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
@@ -517,25 +551,28 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
verbose(VERB_ALGO, "Cannot prime due to lack of hints");
|
||||
return 0;
|
||||
}
|
||||
/* copy dp; to avoid messing up available list for other thr/queries */
|
||||
dp = delegpt_copy(dp, qstate->region);
|
||||
if(!dp) {
|
||||
log_err("out of memory priming root, copydp");
|
||||
return 0;
|
||||
}
|
||||
/* Priming requests start at the QUERYTARGETS state, skipping
|
||||
* the normal INIT state logic (which would cause an infloop). */
|
||||
if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS,
|
||||
qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,
|
||||
&subq, 0)) {
|
||||
log_err("out of memory priming root");
|
||||
verbose(VERB_ALGO, "could not prime root");
|
||||
return 0;
|
||||
}
|
||||
if(subq) {
|
||||
struct iter_qstate* subiq =
|
||||
(struct iter_qstate*)subq->minfo[id];
|
||||
/* Set the initial delegation point to the hint. */
|
||||
subiq->dp = dp;
|
||||
/* Set the initial delegation point to the hint.
|
||||
* copy dp, it is now part of the root prime query.
|
||||
* dp was part of in the fixed hints structure. */
|
||||
subiq->dp = delegpt_copy(dp, subq->region);
|
||||
if(!subiq->dp) {
|
||||
log_err("out of memory priming root, copydp");
|
||||
fptr_ok(fptr_whitelist_modenv_kill_sub(
|
||||
qstate->env->kill_sub));
|
||||
(*qstate->env->kill_sub)(subq);
|
||||
return 0;
|
||||
}
|
||||
/* there should not be any target queries. */
|
||||
subiq->num_target_queries = 0;
|
||||
subiq->dnssec_expected = iter_indicates_dnssec(
|
||||
@@ -555,21 +592,27 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* @param iq: iterator query state.
|
||||
* @param ie: iterator global state.
|
||||
* @param id: module id.
|
||||
* @param qname: request name.
|
||||
* @param qclass: the class to prime.
|
||||
* @param q: request name.
|
||||
* @return true if a priming subrequest was made, false if not. The will only
|
||||
* issue a priming request if it detects an unprimed stub.
|
||||
*/
|
||||
static int
|
||||
prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct iter_env* ie, int id, uint8_t* qname, uint16_t qclass)
|
||||
struct iter_env* ie, int id, struct query_info* q)
|
||||
{
|
||||
/* Lookup the stub hint. This will return null if the stub doesn't
|
||||
* need to be re-primed. */
|
||||
struct iter_hints_stub* stub = hints_lookup_stub(ie->hints,
|
||||
qname, qclass, iq->dp);
|
||||
struct iter_hints_stub* stub;
|
||||
struct delegpt* stub_dp;
|
||||
struct module_qstate* subq;
|
||||
uint8_t* delname = q->qname;
|
||||
size_t delnamelen = q->qname_len;
|
||||
|
||||
if(q->qtype == LDNS_RR_TYPE_DS && !dname_is_root(q->qname))
|
||||
/* remove first label, but not for root */
|
||||
dname_remove_label(&delname, &delnamelen);
|
||||
|
||||
stub = hints_lookup_stub(ie->hints, delname, q->qclass, iq->dp);
|
||||
/* The stub (if there is one) does not need priming. */
|
||||
if(!stub)
|
||||
return 0;
|
||||
@@ -577,6 +620,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* is it a noprime stub (always use) */
|
||||
if(stub->noprime) {
|
||||
/* copy the dp out of the fixed hints structure, so that
|
||||
* it can be changed when servicing this query */
|
||||
iq->dp = delegpt_copy(stub_dp, qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory priming stub");
|
||||
@@ -584,20 +629,20 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 1; /* return 1 to make module stop, with error */
|
||||
}
|
||||
log_nametypeclass(VERB_DETAIL, "use stub", stub_dp->name,
|
||||
LDNS_RR_TYPE_NS, qclass);
|
||||
LDNS_RR_TYPE_NS, q->qclass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, we need to (re)prime the stub. */
|
||||
log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
|
||||
LDNS_RR_TYPE_NS, qclass);
|
||||
LDNS_RR_TYPE_NS, q->qclass);
|
||||
|
||||
/* Stub priming events start at the QUERYTARGETS state to avoid the
|
||||
* redundant INIT state processing. */
|
||||
if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
|
||||
LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
|
||||
LDNS_RR_TYPE_NS, q->qclass, qstate, id, iq,
|
||||
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
||||
log_err("out of memory priming stub");
|
||||
verbose(VERB_ALGO, "could not prime stub");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return 1; /* return 1 to make module stop, with error */
|
||||
}
|
||||
@@ -675,7 +720,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class),
|
||||
qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
log_err("out of memory generating ns check");
|
||||
verbose(VERB_ALGO, "could not generate addr check");
|
||||
return;
|
||||
}
|
||||
/* ignore subq - not need for more init */
|
||||
@@ -710,7 +755,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
log_err("out of memory generating ns check");
|
||||
verbose(VERB_ALGO, "could not generate ns check");
|
||||
return;
|
||||
}
|
||||
if(subq) {
|
||||
@@ -736,16 +781,20 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
*
|
||||
* @param qstate: query state.
|
||||
* @param iq: iterator query state.
|
||||
* @param ie: iterator shared global environment.
|
||||
* @return true if the request is forwarded, false if not.
|
||||
* If returns true but, iq->dp is NULL then a malloc failure occurred.
|
||||
*/
|
||||
static int
|
||||
forward_request(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct iter_env* ie)
|
||||
forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
{
|
||||
struct delegpt* dp = forwards_lookup(ie->fwds, iq->qchase.qname,
|
||||
iq->qchase.qclass);
|
||||
struct delegpt* dp;
|
||||
uint8_t* delname = iq->qchase.qname;
|
||||
size_t delnamelen = iq->qchase.qname_len;
|
||||
/* strip one label off of DS query to lookup higher for it */
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS
|
||||
&& !dname_is_root(iq->qchase.qname))
|
||||
dname_remove_label(&delname, &delnamelen);
|
||||
dp = forwards_lookup(qstate->env->fwds, delname, iq->qchase.qclass);
|
||||
if(!dp)
|
||||
return 0;
|
||||
/* send recursion desired to forward addr */
|
||||
@@ -809,23 +858,32 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* This either results in a query restart (CNAME cache response), a
|
||||
* terminating response (ANSWER), or a cache miss (null). */
|
||||
|
||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer, *qstate->env->now);
|
||||
if(qstate->blacklist) {
|
||||
/* if cache, or anything else, was blacklisted then
|
||||
* getting older results from cache is a bad idea, no cache */
|
||||
verbose(VERB_ALGO, "cache blacklisted, going to the network");
|
||||
msg = NULL;
|
||||
} else {
|
||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer, *qstate->env->now);
|
||||
}
|
||||
}
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
enum response_type type = response_type_from_cache(msg,
|
||||
&iq->qchase);
|
||||
if(verbosity >= VERB_ALGO)
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_dns_msg("msg from cache lookup", &msg->qinfo,
|
||||
msg->rep);
|
||||
verbose(VERB_ALGO, "msg ttl is %d", (int)msg->rep->ttl);
|
||||
}
|
||||
|
||||
if(type == RESPONSE_TYPE_CNAME) {
|
||||
uint8_t* sname = 0;
|
||||
@@ -840,10 +898,16 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qname_len = slen;
|
||||
/* This *is* a query restart, even if it is a cheap
|
||||
* one. */
|
||||
iq->dp = NULL;
|
||||
iq->refetch_glue = 0;
|
||||
iq->query_restart_count++;
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
}
|
||||
|
||||
/* if from cache, NULL, else insert 'cache IP' len=0 */
|
||||
if(qstate->reply_origin)
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
/* it is an answer, response, to final state */
|
||||
verbose(VERB_ALGO, "returning answer from cache.");
|
||||
iq->response = msg;
|
||||
@@ -851,12 +915,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
|
||||
/* attempt to forward the request */
|
||||
if(forward_request(qstate, iq, ie))
|
||||
if(forward_request(qstate, iq))
|
||||
{
|
||||
if(!iq->dp) {
|
||||
log_err("alloc failure for forward dp");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->refetch_glue = 0;
|
||||
/* the request has been forwarded.
|
||||
* forwarded requests need to be immediately sent to the
|
||||
* next state, QUERYTARGETS. */
|
||||
@@ -880,23 +945,47 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delname = iq->qchase.qname;
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
if((iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue)
|
||||
&& !dname_is_root(delname)) {
|
||||
/* do not adjust root label, remove first label from delname */
|
||||
dname_remove_label(&delname, &delnamelen);
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue) {
|
||||
/* remove first label from delname, root goes to hints,
|
||||
* but only to fetch glue, not for qtype=DS. */
|
||||
if(dname_is_root(delname) && iq->refetch_glue)
|
||||
delname = NULL; /* go to root priming */
|
||||
else dname_remove_label(&delname, &delnamelen);
|
||||
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
|
||||
}
|
||||
/* delname is the name to lookup a delegation for. If NULL rootprime */
|
||||
while(1) {
|
||||
|
||||
/* Lookup the delegation in the cache. If null, then the
|
||||
* cache needs to be primed for the qclass. */
|
||||
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
||||
if(delname)
|
||||
iq->dp = dns_cache_find_delegation(qstate->env, delname,
|
||||
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
|
||||
qstate->region, &iq->deleg_msg, *qstate->env->now);
|
||||
else iq->dp = NULL;
|
||||
|
||||
/* If the cache has returned nothing, then we have a
|
||||
* root priming situation. */
|
||||
if(iq->dp == NULL) {
|
||||
if(forwards_lookup_root(qstate->env->fwds,
|
||||
iq->qchase.qclass)) {
|
||||
/* forward zone root, no root prime needed */
|
||||
/* fill in some dp - safety belt */
|
||||
iq->dp = hints_lookup_root(ie->hints,
|
||||
iq->qchase.qclass);
|
||||
if(!iq->dp) {
|
||||
log_err("internal error: no hints dp");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->dp = delegpt_copy(iq->dp, qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory in safety belt");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
return next_state(iq, INIT_REQUEST_2_STATE);
|
||||
}
|
||||
/* Note that the result of this will set a new
|
||||
* DelegationPoint based on the result of priming. */
|
||||
if(!prime_root(qstate, iq, ie, id, iq->qchase.qclass))
|
||||
@@ -988,8 +1077,7 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
&qstate->qinfo);
|
||||
|
||||
/* Check to see if we need to prime a stub zone. */
|
||||
if(prime_stub(qstate, iq, ie, id, iq->qchase.qname,
|
||||
iq->qchase.qclass)) {
|
||||
if(prime_stub(qstate, iq, ie, id, &iq->qchase)) {
|
||||
/* A priming sub request was made */
|
||||
return 0;
|
||||
}
|
||||
@@ -1025,6 +1113,8 @@ processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("no RD requested, using delegation msg",
|
||||
&iq->response->qinfo, iq->response->rep);
|
||||
if(qstate->reply_origin)
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
return final_state(iq);
|
||||
}
|
||||
|
||||
@@ -1216,7 +1306,10 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
|
||||
tf_policy = 0;
|
||||
if(iq->depth <= ie->max_dependency_depth) {
|
||||
/* < not <=, because although the array is large enough for <=, the
|
||||
* generated query will immediately be discarded due to depth and
|
||||
* that servfail is cached, which is not good as opportunism goes. */
|
||||
if(iq->depth < ie->max_dependency_depth) {
|
||||
tf_policy = ie->target_fetch_policy[iq->depth];
|
||||
}
|
||||
|
||||
@@ -1253,14 +1346,14 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* if there is a policy to fetch missing targets
|
||||
* opportunistically, do it. we rely on the fact that once a
|
||||
* query (or queries) for a missing name have been issued,
|
||||
* they will not be show up again. */
|
||||
* they will not show up again. */
|
||||
} else if(tf_policy != 0) {
|
||||
int extra = 0;
|
||||
verbose(VERB_ALGO, "attempt to get extra %d targets",
|
||||
tf_policy);
|
||||
if(!query_for_targets(qstate, iq, ie, id, tf_policy, &extra)) {
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
(void)query_for_targets(qstate, iq, ie, id, tf_policy, &extra);
|
||||
/* errors ignored, these targets are not strictly necessary for
|
||||
* this result, we do not have to reply with SERVFAIL */
|
||||
iq->num_target_queries += extra;
|
||||
}
|
||||
|
||||
@@ -1270,7 +1363,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Select the next usable target, filtering out unsuitable targets. */
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
&iq->dnssec_expected, &iq->chase_to_rd);
|
||||
&iq->dnssec_expected, &iq->chase_to_rd, iq->num_target_queries,
|
||||
qstate->blacklist);
|
||||
|
||||
/* If no usable target was selected... */
|
||||
if(!target) {
|
||||
@@ -1301,11 +1395,22 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Since a target query might have been made, we
|
||||
* need to check again. */
|
||||
if(iq->num_target_queries == 0) {
|
||||
/* is it glue and we suspect that it exists?*/
|
||||
if(iter_suspect_exists(&iq->qchase, iq->dp,
|
||||
qstate->env)) {
|
||||
/* try at parent */
|
||||
iq->deleg_msg = NULL;
|
||||
iq->refetch_glue = 1;
|
||||
iq->query_restart_count++;
|
||||
return next_state(iq,
|
||||
INIT_REQUEST_STATE);
|
||||
}
|
||||
|
||||
verbose(VERB_QUERY, "out of query targets -- "
|
||||
"returning SERVFAIL");
|
||||
/* fail -- no more targets, no more hope
|
||||
* of targets, no hope of a response. */
|
||||
return error_response(qstate, id,
|
||||
return error_response_cache(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
}
|
||||
@@ -1328,6 +1433,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
|
||||
/* We have a valid target. */
|
||||
if(iq->dnssec_expected) verbose(VERB_ALGO, "dnssec is expected");
|
||||
log_query_info(VERB_QUERY, "sending query:", &iq->qchase);
|
||||
log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name,
|
||||
&target->addr, target->addrlen);
|
||||
@@ -1338,9 +1444,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD,
|
||||
&target->addr, target->addrlen, qstate);
|
||||
if(!outq) {
|
||||
verbose(VERB_OPS, "error sending query to auth server; "
|
||||
"skip this address");
|
||||
log_addr(VERB_OPS, "error for address:",
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
@@ -1351,6 +1455,19 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** find NS rrset in given list */
|
||||
static struct ub_packed_rrset_key*
|
||||
find_NS(struct reply_info* rep, size_t from, size_t to)
|
||||
{
|
||||
size_t i;
|
||||
for(i=from; i<to; i++) {
|
||||
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS)
|
||||
return rep->rrsets[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process the query response. All queries end up at this state first. This
|
||||
* process generally consists of analyzing the response and routing the
|
||||
@@ -1402,6 +1519,20 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
dnsseclame = 1;
|
||||
}
|
||||
}
|
||||
/* see if referral brings us close to the target */
|
||||
if(type == RESPONSE_TYPE_REFERRAL) {
|
||||
struct ub_packed_rrset_key* ns = find_NS(
|
||||
iq->response->rep, iq->response->rep->an_numrrsets,
|
||||
iq->response->rep->an_numrrsets
|
||||
+ iq->response->rep->ns_numrrsets);
|
||||
if(!ns) ns = find_NS(iq->response->rep, 0,
|
||||
iq->response->rep->an_numrrsets);
|
||||
if(!ns || !dname_strict_subdomain_c(ns->rk.dname, iq->dp->name)
|
||||
|| !dname_subdomain_c(iq->qchase.qname, ns->rk.dname)){
|
||||
verbose(VERB_ALGO, "bad referral, throwaway");
|
||||
type = RESPONSE_TYPE_THROWAWAY;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle each of the type cases */
|
||||
if(type == RESPONSE_TYPE_ANSWER) {
|
||||
@@ -1418,6 +1549,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
qstate->env->detach_subs));
|
||||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
if(qstate->reply)
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
return final_state(iq);
|
||||
} else if(type == RESPONSE_TYPE_REFERRAL) {
|
||||
/* REFERRAL type responses get a reset of the
|
||||
@@ -1432,9 +1567,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* we know that all other NS rrsets are scrubbed
|
||||
* away, thus on referral only one is left.
|
||||
* see if that equals the query name... */
|
||||
&& reply_find_rrset_section_ns(iq->response->rep,
|
||||
&& ( /* auth section, but sometimes in answer section*/
|
||||
reply_find_rrset_section_ns(iq->response->rep,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
|
||||
|| reply_find_rrset_section_an(iq->response->rep,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
|
||||
)
|
||||
)) {
|
||||
/* Store the referral under the current query */
|
||||
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
@@ -1522,6 +1662,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
qstate->env->detach_subs));
|
||||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
if(qstate->reply)
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
verbose(VERB_ALGO, "cleared outbound list for query restart");
|
||||
/* go to INIT_REQUEST_STATE for new qname. */
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
@@ -1529,7 +1673,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Cache the LAMEness. */
|
||||
verbose(VERB_DETAIL, "query response was %sLAME",
|
||||
dnsseclame?"DNSSEC ":"");
|
||||
if(qstate->reply) {
|
||||
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
|
||||
log_err("mark lame: mismatch in qname and dpname");
|
||||
/* throwaway this reply below */
|
||||
} else if(qstate->reply) {
|
||||
/* need addr for lameness cache, but we may have
|
||||
* gotten this from cache, so test to be sure */
|
||||
if(!infra_set_lame(qstate->env->infra_cache,
|
||||
@@ -1544,9 +1691,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Cache the LAMEness. */
|
||||
verbose(VERB_DETAIL, "query response REC_LAME: "
|
||||
"recursive but not authoritative server");
|
||||
if(qstate->reply) {
|
||||
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
|
||||
log_err("mark rec_lame: mismatch in qname and dpname");
|
||||
/* throwaway this reply below */
|
||||
} else if(qstate->reply) {
|
||||
/* need addr for lameness cache, but we may have
|
||||
* gotten this from cache, so test to be sure */
|
||||
verbose(VERB_DETAIL, "mark as REC_LAME");
|
||||
if(!infra_set_lame(qstate->env->infra_cache,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
@@ -1659,7 +1810,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
log_err("out of memory generating prime check");
|
||||
verbose(VERB_ALGO, "could not generate prime check");
|
||||
}
|
||||
generate_a_aaaa_check(qstate, iq, id);
|
||||
}
|
||||
@@ -1697,16 +1848,17 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||
log_query_info(VERB_ALGO, "processTargetResponse super", &forq->qinfo);
|
||||
|
||||
/* check to see if parent event is still interested (in orig name). */
|
||||
if(!foriq->dp) {
|
||||
verbose(VERB_ALGO, "subq: parent not interested, was reset");
|
||||
return; /* not interested anymore */
|
||||
}
|
||||
dpns = delegpt_find_ns(foriq->dp, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len);
|
||||
if(!dpns) {
|
||||
/* FIXME: maybe store this nameserver address in the cache
|
||||
* anyways? */
|
||||
/* If not, just stop processing this event */
|
||||
/* If not interested, just stop processing this event */
|
||||
verbose(VERB_ALGO, "subq: parent not interested anymore");
|
||||
/* this is an error, and will cause parent to be reactivated
|
||||
* even though nothing has happened */
|
||||
log_assert(0);
|
||||
/* could be because parent was jostled out of the cache,
|
||||
and a new identical query arrived, that does not want it*/
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2055,8 +2207,7 @@ iter_get_mem(struct module_env* env, int id)
|
||||
if(!ie)
|
||||
return 0;
|
||||
return sizeof(*ie) + sizeof(int)*((size_t)ie->max_dependency_depth+1)
|
||||
+ hints_get_mem(ie->hints) + forwards_get_mem(ie->fwds)
|
||||
+ donotq_get_mem(ie->donotq);
|
||||
+ hints_get_mem(ie->hints) + donotq_get_mem(ie->donotq);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-4
@@ -65,8 +65,12 @@ struct iter_priv;
|
||||
* Equals RTT_MAX_TIMEOUT
|
||||
*/
|
||||
#define USEFUL_SERVER_TOP_TIMEOUT 120000
|
||||
/** Number of lost messages in a row that get a host blacklisted.
|
||||
* With 16, a couple different queries have to time out and no working
|
||||
* queries are happening */
|
||||
#define USEFUL_SERVER_MAX_LOST 16
|
||||
/** number of retries on outgoing queries */
|
||||
#define OUTBOUND_MSG_RETRY 4
|
||||
#define OUTBOUND_MSG_RETRY 5
|
||||
/** RTT band, within this amount from the best, servers are chosen randomly.
|
||||
* Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a
|
||||
* fast server, this causes server exploration as a side benefit. msec. */
|
||||
@@ -87,9 +91,6 @@ struct iter_env {
|
||||
/** A flag to indicate whether or not we have an IPv6 route */
|
||||
int supports_ipv6;
|
||||
|
||||
/** Mapping of forwarding zones to targets. */
|
||||
struct iter_forwards* fwds;
|
||||
|
||||
/** A set of inetaddrs that should never be queried. */
|
||||
struct iter_donotq* donotq;
|
||||
|
||||
|
||||
Binary file not shown.
+28
-6
@@ -288,20 +288,27 @@ context_serialize_answer(struct ctx_query* q, int err, ldns_buffer* pkt,
|
||||
* o uint32 id
|
||||
* o uint32 error_code
|
||||
* o uint32 msg_security
|
||||
* o uint32 length of why_bogus string (+1 for eos); 0 absent.
|
||||
* o why_bogus_string
|
||||
* o the remainder is the answer msg from resolver lookup.
|
||||
* remainder can be length 0.
|
||||
*/
|
||||
size_t pkt_len = pkt?ldns_buffer_remaining(pkt):0;
|
||||
size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0;
|
||||
uint8_t* p;
|
||||
*len = sizeof(uint32_t)*4 + pkt_len;
|
||||
*len = sizeof(uint32_t)*5 + pkt_len + wlen;
|
||||
p = (uint8_t*)malloc(*len);
|
||||
if(!p) return NULL;
|
||||
ldns_write_uint32(p, UB_LIBCMD_ANSWER);
|
||||
ldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum);
|
||||
ldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err);
|
||||
ldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security);
|
||||
ldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen);
|
||||
if(wlen > 0)
|
||||
memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen);
|
||||
if(pkt_len > 0)
|
||||
memmove(p+4*sizeof(uint32_t), ldns_buffer_begin(pkt), pkt_len);
|
||||
memmove(p+5*sizeof(uint32_t)+wlen,
|
||||
ldns_buffer_begin(pkt), pkt_len);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -311,16 +318,31 @@ context_deserialize_answer(struct ub_ctx* ctx,
|
||||
{
|
||||
struct ctx_query* q = NULL ;
|
||||
int id;
|
||||
if(len < 4*sizeof(uint32_t)) return NULL;
|
||||
size_t wlen;
|
||||
if(len < 5*sizeof(uint32_t)) return NULL;
|
||||
log_assert( ldns_read_uint32(p) == UB_LIBCMD_ANSWER);
|
||||
id = (int)ldns_read_uint32(p+sizeof(uint32_t));
|
||||
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
|
||||
if(!q) return NULL;
|
||||
*err = (int)ldns_read_uint32(p+2*sizeof(uint32_t));
|
||||
q->msg_security = ldns_read_uint32(p+3*sizeof(uint32_t));
|
||||
if(len > 4*sizeof(uint32_t)) {
|
||||
q->msg_len = len - 4*sizeof(uint32_t);
|
||||
q->msg = (uint8_t*)memdup(p+4*sizeof(uint32_t), q->msg_len);
|
||||
wlen = (size_t)ldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
if(len > 5*sizeof(uint32_t) && wlen > 0) {
|
||||
if(len >= 5*sizeof(uint32_t)+wlen)
|
||||
q->res->why_bogus = (char*)memdup(
|
||||
p+5*sizeof(uint32_t), wlen);
|
||||
if(!q->res->why_bogus) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
*err = UB_NOMEM;
|
||||
return q;
|
||||
}
|
||||
q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
|
||||
}
|
||||
if(len > 5*sizeof(uint32_t)+wlen) {
|
||||
q->msg_len = len - 5*sizeof(uint32_t) - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen,
|
||||
q->msg_len);
|
||||
if(!q->msg) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
|
||||
@@ -184,7 +184,9 @@ enum ub_ctx_err {
|
||||
/** error in pipe communication with async bg worker */
|
||||
UB_PIPE = -8,
|
||||
/** error reading from file (resolv.conf) */
|
||||
UB_READFILE = -9
|
||||
UB_READFILE = -9,
|
||||
/** error async_id does not exist or result already been delivered */
|
||||
UB_NOID = -10
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+203
-5
@@ -60,6 +60,11 @@
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/rrset.h"
|
||||
|
||||
#if defined(UB_ON_WINDOWS) && defined (HAVE_WINDOWS_H)
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
struct ub_ctx*
|
||||
ub_ctx_create()
|
||||
{
|
||||
@@ -246,7 +251,7 @@ ub_ctx_config(struct ub_ctx* ctx, char* fname)
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!config_read(ctx->env->cfg, fname)) {
|
||||
if(!config_read(ctx->env->cfg, fname, NULL)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
@@ -262,6 +267,7 @@ ub_ctx_add_ta(struct ub_ctx* ctx, char* ta)
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
|
||||
@@ -281,6 +287,7 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname)
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) {
|
||||
@@ -300,6 +307,7 @@ ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname)
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(ctx->finalized) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
|
||||
@@ -460,7 +468,7 @@ ub_process(struct ub_ctx* ctx)
|
||||
if(r == 0)
|
||||
return UB_PIPE;
|
||||
else if(r == -1)
|
||||
return UB_NOERROR;
|
||||
break;
|
||||
if(!process_answer(ctx, msg, len)) {
|
||||
free(msg);
|
||||
return UB_PIPE;
|
||||
@@ -642,7 +650,7 @@ ub_cancel(struct ub_ctx* ctx, int async_id)
|
||||
if(!q || !q->async) {
|
||||
/* it is not there, so nothing to do */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return UB_NOERROR;
|
||||
return UB_NOID;
|
||||
}
|
||||
log_assert(q->async);
|
||||
q->cancelled = 1;
|
||||
@@ -686,6 +694,7 @@ ub_resolve_free(struct ub_result* result)
|
||||
free(result->data);
|
||||
free(result->len);
|
||||
free(result->answer_packet);
|
||||
free(result->why_bogus);
|
||||
free(result);
|
||||
}
|
||||
|
||||
@@ -703,6 +712,7 @@ ub_strerror(int err)
|
||||
case UB_AFTERFINAL: return "setting change after finalize";
|
||||
case UB_PIPE: return "error in pipe communication with async";
|
||||
case UB_READFILE: return "error reading file";
|
||||
case UB_NOID: return "error async_id does not exist";
|
||||
default: return "unknown error";
|
||||
}
|
||||
}
|
||||
@@ -787,8 +797,47 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname)
|
||||
char buf[1024];
|
||||
char* parse, *addr;
|
||||
int r;
|
||||
if(fname == NULL)
|
||||
|
||||
if(fname == NULL) {
|
||||
#if !defined(UB_ON_WINDOWS) || !defined(HAVE_WINDOWS_H)
|
||||
fname = "/etc/resolv.conf";
|
||||
#else
|
||||
FIXED_INFO *info;
|
||||
ULONG buflen = sizeof(*info);
|
||||
IP_ADDR_STRING *ptr;
|
||||
|
||||
info = (FIXED_INFO *) malloc(sizeof (FIXED_INFO));
|
||||
if (info == NULL)
|
||||
return UB_READFILE;
|
||||
|
||||
if (GetNetworkParams(info, &buflen) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(info);
|
||||
info = (FIXED_INFO *) malloc(buflen);
|
||||
if (info == NULL)
|
||||
return UB_READFILE;
|
||||
}
|
||||
|
||||
if (GetNetworkParams(info, &buflen) == NO_ERROR) {
|
||||
int retval=0;
|
||||
ptr = &(info->DnsServerList);
|
||||
while (ptr) {
|
||||
numserv++;
|
||||
if((retval=ub_ctx_set_fwd(ctx,
|
||||
ptr->IpAddress.String)!=0)) {
|
||||
free(info);
|
||||
return retval;
|
||||
}
|
||||
ptr = ptr->Next;
|
||||
}
|
||||
free(info);
|
||||
if (numserv==0)
|
||||
return UB_READFILE;
|
||||
return UB_NOERROR;
|
||||
}
|
||||
free(info);
|
||||
return UB_READFILE;
|
||||
#endif /* WINDOWS */
|
||||
}
|
||||
in = fopen(fname, "r");
|
||||
if(!in) {
|
||||
/* error in errno! perror(fname) */
|
||||
@@ -839,8 +888,31 @@ ub_ctx_hosts(struct ub_ctx* ctx, char* fname)
|
||||
return UB_AFTERFINAL;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
if(fname == NULL)
|
||||
if(fname == NULL) {
|
||||
#if defined(UB_ON_WINDOWS) && defined(HAVE_WINDOWS_H)
|
||||
/*
|
||||
* If this is Windows NT/XP/2K it's in
|
||||
* %WINDIR%\system32\drivers\etc\hosts.
|
||||
* If this is Windows 95/98/Me it's in %WINDIR%\hosts.
|
||||
*/
|
||||
name = getenv("WINDIR");
|
||||
if (name != NULL) {
|
||||
int retval=0;
|
||||
snprintf(buf, sizeof(buf), "%s%s", name,
|
||||
"\\system32\\drivers\\etc\\hosts");
|
||||
if((retval=ub_ctx_hosts(ctx, buf)) !=0 ) {
|
||||
snprintf(buf, sizeof(buf), "%s%s", name,
|
||||
"\\hosts");
|
||||
retval=ub_ctx_hosts(ctx, buf);
|
||||
}
|
||||
free(name);
|
||||
return retval;
|
||||
}
|
||||
return UB_READFILE;
|
||||
#else
|
||||
fname = "/etc/hosts";
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
in = fopen(fname, "r");
|
||||
if(!in) {
|
||||
/* error in errno! perror(fname) */
|
||||
@@ -905,3 +977,129 @@ ub_ctx_hosts(struct ub_ctx* ctx, char* fname)
|
||||
fclose(in);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/** finalize the context, if not already finalized */
|
||||
static int ub_ctx_finalize(struct ub_ctx* ctx)
|
||||
{
|
||||
int res = 0;
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if (!ctx->finalized) {
|
||||
res = context_finalize(ctx);
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Print local zones and RR data */
|
||||
int ub_ctx_print_local_zones(struct ub_ctx* ctx)
|
||||
{
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
local_zones_print(ctx->local_zones);
|
||||
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/* Add a new zone */
|
||||
int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type)
|
||||
{
|
||||
enum localzone_type t;
|
||||
struct local_zone* z;
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!local_zone_str2type(zone_type, &t)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN))) {
|
||||
/* already present in tree */
|
||||
lock_rw_wrlock(&z->lock);
|
||||
z->type = t; /* update type anyway */
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN, t)) {
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/* Remove zone */
|
||||
int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name)
|
||||
{
|
||||
struct local_zone* z;
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
|
||||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN))) {
|
||||
/* present in tree */
|
||||
local_zones_del_zone(ctx->local_zones, z);
|
||||
}
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
/* Add new RR data */
|
||||
int ub_ctx_data_add(struct ub_ctx* ctx, char *data)
|
||||
{
|
||||
ldns_buffer* buf;
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
if(!buf) return UB_NOMEM;
|
||||
|
||||
res = local_zones_add_RR(ctx->local_zones, data, buf);
|
||||
|
||||
ldns_buffer_free(buf);
|
||||
return (!res) ? UB_NOMEM : UB_NOERROR;
|
||||
}
|
||||
|
||||
/* Remove RR data */
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
int res = ub_ctx_finalize(ctx);
|
||||
if (res) return res;
|
||||
|
||||
if(!parse_dname(data, &nm, &nmlen, &nmlabs))
|
||||
return UB_SYNTAX;
|
||||
|
||||
local_zones_del_data(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN);
|
||||
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
+67
-22
@@ -61,6 +61,7 @@
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/tube.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
|
||||
/** handle new query command for bg worker */
|
||||
static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
|
||||
@@ -71,11 +72,13 @@ libworker_delete(struct libworker* w)
|
||||
{
|
||||
if(!w) return;
|
||||
if(w->env) {
|
||||
outside_network_quit_prepare(w->back);
|
||||
mesh_delete(w->env->mesh);
|
||||
context_release_alloc(w->ctx, w->env->alloc,
|
||||
!w->is_bg || w->is_bg_thread);
|
||||
ldns_buffer_free(w->env->scratch_buffer);
|
||||
regional_destroy(w->env->scratch);
|
||||
forwards_delete(w->env->fwds);
|
||||
ub_randfree(w->env->rnd);
|
||||
free(w->env);
|
||||
}
|
||||
@@ -114,14 +117,20 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
}
|
||||
w->env->scratch = regional_create_custom(cfg->msg_buffer_size);
|
||||
w->env->scratch_buffer = ldns_buffer_new(cfg->msg_buffer_size);
|
||||
w->env->fwds = forwards_create();
|
||||
if(w->env->fwds && !forwards_apply_cfg(w->env->fwds, cfg)) {
|
||||
forwards_delete(w->env->fwds);
|
||||
w->env->fwds = NULL;
|
||||
}
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
if(!w->env->scratch || !w->env->scratch_buffer) {
|
||||
if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds) {
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->env->worker = (struct worker*)w;
|
||||
w->env->probe_timer = NULL;
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((unsigned int)w->thread_num)<<17);
|
||||
seed ^= (unsigned int)w->env->alloc->next_id;
|
||||
@@ -141,7 +150,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
}
|
||||
seed = 0;
|
||||
|
||||
w->base = comm_base_create();
|
||||
w->base = comm_base_create(0);
|
||||
if(!w->base) {
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
@@ -160,7 +169,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
|
||||
ports, numports, cfg->unwanted_threshold,
|
||||
&libworker_alloc_cleanup, w);
|
||||
&libworker_alloc_cleanup, w, cfg->do_udp);
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
@@ -429,8 +438,10 @@ libworker_enter_result(struct ub_result* res, ldns_buffer* buf,
|
||||
/** fillup fg results */
|
||||
static void
|
||||
libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s)
|
||||
enum sec_status s, char* why_bogus)
|
||||
{
|
||||
if(why_bogus)
|
||||
q->res->why_bogus = strdup(why_bogus);
|
||||
if(rcode != 0) {
|
||||
q->res->rcode = rcode;
|
||||
q->msg_security = s;
|
||||
@@ -450,15 +461,15 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, ldns_buffer* buf,
|
||||
libworker_enter_result(q->res, buf, q->w->env->scratch, s);
|
||||
}
|
||||
|
||||
/** callback with fg results */
|
||||
static void
|
||||
libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
void
|
||||
libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
/* fg query is done; exit comm base */
|
||||
comm_base_exit(q->w->base);
|
||||
|
||||
libworker_fillup_fg(q, rcode, buf, s);
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus);
|
||||
}
|
||||
|
||||
/** setup qinfo and edns */
|
||||
@@ -507,8 +518,9 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
ldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
|
||||
w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure);
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
@@ -531,7 +543,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
/** add result to the bg worker result queue */
|
||||
static void
|
||||
add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
||||
int err)
|
||||
int err, char* reason)
|
||||
{
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
@@ -539,13 +551,21 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
||||
/* serialize and delete unneeded q */
|
||||
if(w->is_bg_thread) {
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
q->msg_len = ldns_buffer_remaining(pkt);
|
||||
q->msg = memdup(ldns_buffer_begin(pkt), q->msg_len);
|
||||
if(!q->msg)
|
||||
msg = context_serialize_answer(q, UB_NOMEM, NULL, &len);
|
||||
else msg = context_serialize_answer(q, err, NULL, &len);
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
if(pkt) {
|
||||
q->msg_len = ldns_buffer_remaining(pkt);
|
||||
q->msg = memdup(ldns_buffer_begin(pkt), q->msg_len);
|
||||
if(!q->msg)
|
||||
msg = context_serialize_answer(q, UB_NOMEM,
|
||||
NULL, &len);
|
||||
else msg = context_serialize_answer(q, err,
|
||||
NULL, &len);
|
||||
} else msg = context_serialize_answer(q, err, NULL, &len);
|
||||
lock_basic_unlock(&w->ctx->cfglock);
|
||||
} else {
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
msg = context_serialize_answer(q, err, pkt, &len);
|
||||
(void)rbtree_delete(&w->ctx->queries, q->node.key);
|
||||
w->ctx->num_async--;
|
||||
@@ -562,9 +582,9 @@ add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,
|
||||
}
|
||||
}
|
||||
|
||||
/** callback with bg results */
|
||||
static void
|
||||
libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
void
|
||||
libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
|
||||
@@ -585,7 +605,7 @@ libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf, enum sec_status s)
|
||||
if(rcode != 0) {
|
||||
error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
|
||||
}
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR);
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus);
|
||||
}
|
||||
|
||||
|
||||
@@ -610,7 +630,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
return;
|
||||
}
|
||||
if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX);
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL);
|
||||
return;
|
||||
}
|
||||
qid = 0;
|
||||
@@ -620,8 +640,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
ldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
|
||||
if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns,
|
||||
w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
@@ -629,7 +650,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
|
||||
add_bg_result(w, q, NULL, UB_NOMEM);
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL);
|
||||
}
|
||||
free(qinfo.qname);
|
||||
}
|
||||
@@ -823,6 +844,11 @@ void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void worker_probe_timer_cb(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
@@ -836,3 +862,22 @@ codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
void
|
||||
worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void*
|
||||
ATTR_UNUSED(arg)) {
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
wsvc_cron_cb(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
@@ -156,6 +156,14 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
|
||||
void libworker_handle_result_write(struct tube* tube, uint8_t* msg, size_t len,
|
||||
int err, void* arg);
|
||||
|
||||
/** mesh callback with fg results */
|
||||
void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/** mesh callback with bg results */
|
||||
void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
|
||||
/**
|
||||
* fill result from parsed message, on error fills servfail
|
||||
* @param res: is clear at start, filled in at end.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
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 the organization nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
|
||||
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# Makefile: compilation of pyUnbound and documentation, testing
|
||||
#
|
||||
# Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
# Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
#
|
||||
# This software is open source.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the organization nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " testenv to make test environment and run bash "
|
||||
@echo " usefull in case you don't want to install unbound but want to test examples"
|
||||
@echo " doc to make documentation"
|
||||
@echo " clean clean all"
|
||||
|
||||
.PHONY: testenv clean doc swig
|
||||
|
||||
#_unbound.so: ../../Makefile
|
||||
#$(MAKE) -C ../..
|
||||
|
||||
#../../.libs/libunbound.so.0: ../../Makefile
|
||||
#$(MAKE) -C ../..
|
||||
|
||||
#../../ldns-src/lib/libldns.so: ../../ldns-src/Makefile
|
||||
#$(MAKE) -C ../../ldns-src
|
||||
|
||||
clean:
|
||||
rm -rdf examples/unbound
|
||||
rm -f _unbound.so libunbound_wrap.o
|
||||
$(MAKE) -C ../.. clean
|
||||
|
||||
testenv: ../../.libs/libunbound.so.1 ../../ldns-src/lib/libldns.so ../../.libs/_unbound.so
|
||||
rm -rdf examples/unbound
|
||||
cd examples && mkdir unbound && ln -s ../../unbound.py unbound/__init__.py && ln -s ../../_unbound.so unbound/_unbound.so && ln -s ../../../../.libs/libunbound.so.1 unbound/libunbound.so.1 && ln -s ../../../../ldns-src/lib/libldns.so.1 unbound/libldns.so.1 && ls -la
|
||||
cd examples && if test -f ../../../.libs/_unbound.so; then cp ../../../.libs/_unbound.so . ; fi
|
||||
@echo "Run a script by typing ./script_name.py"
|
||||
cd examples && LD_LIBRARY_PATH=unbound bash
|
||||
rm -rdf examples/unbound examples/_unbound.so
|
||||
|
||||
doc: ../../.libs/libunbound.so.0 _unbound.so
|
||||
$(MAKE) -C docs html
|
||||
|
||||
#for development only
|
||||
swig: libunbound.i
|
||||
swig -python -o libunbound_wrap.c -I../.. libunbound.i
|
||||
gcc -c libunbound_wrap.c -O9 -fPIC -I../.. -I/usr/include/python2.5 -I. -o libunbound_wrap.o
|
||||
gcc -shared libunbound_wrap.o -L../../.libs -lunbound -o _unbound.so
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
this directory exists to pacify sphinx-build.
|
||||
@@ -0,0 +1,181 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Unbound documentation build configuration file
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# The contents of this file are pickled, so don't put values in the namespace
|
||||
# that aren't pickleable (module imports are okay, they're removed automatically).
|
||||
#
|
||||
# All configuration values have a default value; values that are commented out
|
||||
# serve to show the default value.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If your extensions are in another directory, add it here. If the directory
|
||||
# is relative to the documentation root, use os.path.abspath to make it
|
||||
# absolute, like shown here.
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../')))
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../../../')))
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),'../../../.libs/')))
|
||||
#print sys.path
|
||||
|
||||
# General configuration
|
||||
# ---------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General substitutions.
|
||||
project = 'pyUnbound'
|
||||
copyright = '2009, Zdenek Vasicek, Marek Vavrusa'
|
||||
|
||||
# The default replacements for |version| and |release|, also used in various
|
||||
# other places throughout the built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0.0'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directories, that shouldn't be searched
|
||||
# for source files.
|
||||
#exclude_dirs = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# Options for HTML output
|
||||
# -----------------------
|
||||
|
||||
# The style sheet to use for HTML and HTML Help pages. A file of that name
|
||||
# must exist either in Sphinx' static/ path, or in one of the custom paths
|
||||
# given in html_static_path.
|
||||
html_style = 'default.css'
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (within the static path) to place at the top of
|
||||
# the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
html_use_modindex = False
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, the reST sources are included in the HTML build as _sources/<name>.
|
||||
html_copy_source = False
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Unbounddoc'
|
||||
|
||||
|
||||
# Options for LaTeX output
|
||||
# ------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, document class [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'Unbound.tex', 'Unbound Documentation',
|
||||
'Zdenek Vasicek, Marek Vavrusa', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _example_resolve_name:
|
||||
|
||||
==============================
|
||||
Resolve a name
|
||||
==============================
|
||||
|
||||
This basic example shows how to create a context and resolve a host address (DNS record of A type).
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.google.com")
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data.address_list
|
||||
elif status != 0:
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
In contrast with C API, the source code is more compact while the performance of C implementation is preserved.
|
||||
The main advantage is that you need not take care about the deallocation and allocation of context and result structures; pyUnbound module do it automatically for you.
|
||||
|
||||
If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for A records in IN class.
|
||||
@@ -0,0 +1,33 @@
|
||||
.. _example_reverse_lookup:
|
||||
|
||||
==============================
|
||||
Reverse DNS lookup
|
||||
==============================
|
||||
|
||||
Reverse DNS lookup involves determining the hostname associated with a given IP address.
|
||||
This example shows how reverse lookup can be done using unbound module.
|
||||
|
||||
For the reverse DNS records, the special domain in-addr.arpa is reserved.
|
||||
For example, a host name for the IP address 74.125.43.147 can be obtained by issuing a DNS query for the PTR record for address 147.43.125.74.in-addr.arpa.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data.domain_list
|
||||
elif status != 0:
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
In order to simplify the python code, unbound module contains function which reverses the hostname components.
|
||||
This function is defined as follows::
|
||||
|
||||
def reverse(domain):
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
.. _example_setup_ctx:
|
||||
|
||||
==============================
|
||||
Lookup from threads
|
||||
==============================
|
||||
|
||||
This example shows how to use unbound module from a threaded program.
|
||||
In this example, three lookup threads are created which work in background.
|
||||
Each thread resolves different DNS record.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
from unbound import ub_ctx, RR_TYPE_A, RR_CLASS_IN
|
||||
from threading import Thread
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
class LookupThread(Thread):
|
||||
def __init__(self,ctx, name):
|
||||
Thread.__init__(self)
|
||||
self.ctx = ctx
|
||||
self.name = name
|
||||
|
||||
def run(self):
|
||||
print "Thread lookup started:",self.name
|
||||
status, result = self.ctx.resolve(self.name, RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print " Result:",self.name,":", result.data.address_list
|
||||
|
||||
threads = []
|
||||
for name in ["www.fit.vutbr.cz","www.vutbr.cz","www.google.com"]:
|
||||
thread = LookupThread(ctx, name)
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
.. _example_asynch:
|
||||
|
||||
==============================
|
||||
Asynchronous lookup
|
||||
==============================
|
||||
|
||||
This example performs the name lookup in the background.
|
||||
The main program keeps running while the name is resolved.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import time
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
def call_back(my_data,status,result):
|
||||
print "Call_back:", my_data
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
my_data['done_flag'] = True
|
||||
|
||||
|
||||
my_data = {'done_flag':False,'arbitrary':"object"}
|
||||
status, async_id = ctx.resolve_async("www.seznam.cz", my_data, call_back, unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
|
||||
while (status == 0) and (not my_data['done_flag']):
|
||||
status = ctx.process()
|
||||
time.sleep(0.1)
|
||||
|
||||
if (status != 0):
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
|
||||
The :meth:`unbound.ub_ctx.resolve_async` method is able to pass on any Python object. In this example, we used a dictionary object `my_data`.
|
||||
@@ -0,0 +1,34 @@
|
||||
.. _example_examine:
|
||||
|
||||
==============================
|
||||
DNSSEC validator
|
||||
==============================
|
||||
|
||||
This example program performs DNSSEC validation of a DNS lookup.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
if (os.path.isfile("keys")):
|
||||
ctx.add_ta_file("keys") #read public keys for DNSSEC verification
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
if result.secure:
|
||||
print "Result is secure"
|
||||
elif result.bogus:
|
||||
print "Result is bogus"
|
||||
else:
|
||||
print "Result is insecure"
|
||||
|
||||
More detailed informations can be seen in libUnbound DNSSEC tutorial `here`_.
|
||||
|
||||
.. _here: http://www.unbound.net/documentation/libunbound-tutorial-6.html
|
||||
@@ -0,0 +1,29 @@
|
||||
.. _example_resolver_only:
|
||||
|
||||
==============================
|
||||
Resolver only
|
||||
==============================
|
||||
|
||||
This example program shows how to perform DNS resolution only.
|
||||
Unbound contains two basic modules: resolver and validator.
|
||||
In case, the validator is not necessary, the validator module can be turned off using "module-config" option.
|
||||
This option contains a list of module names separated by the space char. This list determined which modules should be employed and in what order.
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.set_option("module-config:","iterator")
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.google.com", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
.. note::
|
||||
The :meth:`unbound.ub_ctx.set_option` method must be used before the first resolution (i.e. before :meth:`unbound.ub_ctx.resolve` or :meth:`unbound.ub_ctx.resolve_async` call).
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/python
|
||||
from unbound import ub_ctx,ub_strerror,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("test.record.xxx", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
else:
|
||||
print "No record found"
|
||||
|
||||
#define new local zone
|
||||
status = ctx.zone_add("xxx.","static")
|
||||
if (status != 0): print "Error zone_add:",status, ub_strerror(status)
|
||||
|
||||
#add RR to the zone
|
||||
status = ctx.data_add("test.record.xxx. IN A 1.2.3.4")
|
||||
if (status != 0): print "Error data_add:",status, ub_strerror(status)
|
||||
|
||||
#lookup for an A record
|
||||
status, result = ctx.resolve("test.record.xxx", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.as_address_list()
|
||||
else:
|
||||
print "No record found"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
.. _example_localzone:
|
||||
|
||||
==============================
|
||||
Local zone manipulation
|
||||
==============================
|
||||
|
||||
This example program shows how to define local zone containing custom DNS records.
|
||||
|
||||
.. literalinclude:: example6-1.py
|
||||
:language: python
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# IDN (Internationalized Domain Name) lookup support
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(u"www.háčkyčárky.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# IDN (Internationalized Domain Name) lookup support (lookup for MX)
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(u"háčkyčárky.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list_idn:
|
||||
print " priority:%d address:%s" % k
|
||||
@@ -0,0 +1,18 @@
|
||||
.. _example_idna:
|
||||
|
||||
=================================================
|
||||
Internationalized domain name support
|
||||
=================================================
|
||||
|
||||
Unlike the libUnbound, pyUnbound is able to handle IDN queries.
|
||||
|
||||
.. literalinclude:: example7-1.py
|
||||
:language: python
|
||||
|
||||
If we use unicode string in :meth:`unbound.ub_ctx.resolve` method, the IDN DNAME conversion (if it is necessary) is performed on background.
|
||||
|
||||
.. literalinclude:: example7-2.py
|
||||
:language: python
|
||||
|
||||
The :class:`unbound.ub_data` class contains attributes suffix which converts the dname to UTF string. These attributes have the '_idn' suffix.
|
||||
Apart from this aproach, two conversion functions exist (:func:`unbound.idn2dname` and :func:`unbound.dname2idn`).
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
#
|
||||
# Lookup for MX and NS records
|
||||
#
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
.. _example_mxlookup:
|
||||
|
||||
=================================================
|
||||
Lookup for MX and NS records
|
||||
=================================================
|
||||
|
||||
The pyUnbound extension provides functions which are able to encode RAW RDATA produces by unbound resolver (see :class:`unbound.ub_data`).
|
||||
|
||||
.. literalinclude:: example8-1.py
|
||||
:language: python
|
||||
|
||||
Previous example produces following output::
|
||||
|
||||
Result:
|
||||
raw data: 00 0F 05 6D 61 69 6C 34 03 6E 69 63 02 63 7A 00;00 14 02 6D 78 05 63 7A 6E 69 63 03 6F 72 67 00;00 0A 04 6D 61 69 6C 03 6E 69 63 02 63 7A 00
|
||||
priority:15 address: mail4.nic.cz.
|
||||
priority:20 address: mx.cznic.org.
|
||||
priority:10 address: mail.nic.cz.
|
||||
|
||||
Result:
|
||||
raw data: D9 1F CD 32
|
||||
address: 217.31.205.50
|
||||
|
||||
Result:
|
||||
raw data: 01 61 02 6E 73 03 6E 69 63 02 63 7A 00;01 65 02 6E 73 03 6E 69 63 02 63 7A 00;01 63 02 6E 73 03 6E 69 63 02 63 7A 00
|
||||
host: a.ns.nic.cz.
|
||||
host: e.ns.nic.cz.
|
||||
host: c.ns.nic.cz.
|
||||
@@ -0,0 +1,14 @@
|
||||
Examples
|
||||
==============================
|
||||
|
||||
Here you can find several examples which utilizes the unbound library in Python environment.
|
||||
Unbound is a caching validator and resolver and can be linked into an application, as a library where can answer DNS queries for the application.
|
||||
This set of examples shows how to use the functions from Python environment.
|
||||
|
||||
`Tutorials`
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
example*
|
||||
@@ -0,0 +1,27 @@
|
||||
PyUnbound documentation
|
||||
=======================================
|
||||
|
||||
This project contains an Unbound wrapper providing the thinnest layer over the library possible.
|
||||
Everything you can do from the libUnbound C API, you can do from Python, even more.
|
||||
|
||||
Contents
|
||||
----------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro.rst
|
||||
install.rst
|
||||
examples/index.rst
|
||||
modules/unbound
|
||||
|
||||
Module Documentation
|
||||
-----------------------
|
||||
|
||||
* Module :mod:`unbound`
|
||||
|
||||
Indices and tables
|
||||
-------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
Installation
|
||||
===================================
|
||||
|
||||
**Prerequisites**
|
||||
|
||||
Python 2.4 or higher, SWIG 1.3 or higher, GNU make
|
||||
|
||||
**Download**
|
||||
|
||||
You can download the source codes `here`_.
|
||||
The latest release is 1.1.1, Jan 15, 2009.
|
||||
|
||||
.. _here: unbound-1.1.1-py.tar.gz
|
||||
|
||||
**Compiling**
|
||||
|
||||
After downloading, you can compile the pyUnbound library by doing::
|
||||
|
||||
> tar -xzf unbound-1.1.1-py.tar.gz
|
||||
> cd unbound-1.1.1
|
||||
> ./configure --with-pyunbound
|
||||
> make
|
||||
|
||||
You need GNU make to compile sources; SWIG and Python devel libraries to compile extension module.
|
||||
|
||||
|
||||
**Testing**
|
||||
|
||||
If the compilation is successfull, you can test the python LDNS extension module by::
|
||||
|
||||
> cd contrib/python
|
||||
> make testenv
|
||||
> ./dns-lookup.py
|
||||
|
||||
In contrib/examples you can find simple applications written in Python using the Unbound extension.
|
||||
@@ -0,0 +1,39 @@
|
||||
Introduction
|
||||
===================================
|
||||
|
||||
**Unbound**
|
||||
|
||||
`Unbound`_ is an implementation of a DNS resolver, that performs caching and DNSSEC validation.
|
||||
Together with unbound, the libunbound library is provided.
|
||||
This library can be used to convert hostnames to ip addresses, and back, as well as obtain other information.
|
||||
Since the resolver allows to specify the class and type of a query (A record, NS, MX, ...), this library offers powerful resolving tool.
|
||||
The library also performs public-key validation of results with DNSSEC.
|
||||
|
||||
.. _Unbound: http://www.unbound.net/documentation
|
||||
|
||||
**pyUnbound**
|
||||
|
||||
The pyUnbound is an extension module for Python which provides an object-oriented interface to libunbound.
|
||||
It is the first Python module which offers thread-safe caching resolver.
|
||||
|
||||
The interface was designed with the emphasis on the simplicity of use.
|
||||
There are two main classes :class:`unbound.ub_ctx` (a validation and resolution context) and :class:`unbound.ub_result` which contains the validation and resolution results.
|
||||
The objects are thread-safe, and a context can be used in non-threaded as well as threaded environment.
|
||||
Resolution can be performed blocking and non-blocking (i.e. asynchronous).
|
||||
The asynchronous method returns from the call immediately, so that processing can go on, while the results become available later.
|
||||
|
||||
**Features**
|
||||
* customizable caching validation resolver for synchronous and asynchronous lookups
|
||||
* easy to use object interface
|
||||
* easy to integrate extension module
|
||||
* designed for thread environment (i.e. thread-safe)
|
||||
* allows define and customize of local zone and its RR's during the operation (i.e. without restart)
|
||||
* includes encoding functions to simplify the results retrieval
|
||||
* Internationalized domain name (`IDN`_) support
|
||||
|
||||
.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name
|
||||
|
||||
**Application area**
|
||||
* DNS-based applications performing DNS lookups; the caching resolver can reduce overhead
|
||||
* Applications where the validation of DNS records is required
|
||||
* Great solution for customizable and dynamic DNS-based white/blacklists (spam rejection, connection rejection, ...) using the dynamic local zone manipulation
|
||||
@@ -0,0 +1,167 @@
|
||||
Unbound module documentation
|
||||
================================
|
||||
|
||||
.. automodule:: unbound
|
||||
|
||||
Class ub_ctx
|
||||
--------------
|
||||
.. autoclass:: ub_ctx
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. automethod:: __init__
|
||||
|
||||
Class ub_result
|
||||
----------------------
|
||||
.. autoclass:: ub_result
|
||||
:members:
|
||||
|
||||
.. attribute:: qname
|
||||
|
||||
The original question, name text string.
|
||||
|
||||
.. attribute:: qtype
|
||||
|
||||
The class asked for.
|
||||
|
||||
.. attribute:: canonname
|
||||
|
||||
Canonical name for the result (the final cname). May be empty if no canonical name exists.
|
||||
|
||||
.. attribute:: answer_packet
|
||||
|
||||
The DNS answer packet. Network formatted. Can contain DNSSEC types.
|
||||
|
||||
.. attribute:: havedata
|
||||
|
||||
If there is any data, this property is true. If false, there was no data (nxdomain may be true, rcode can be set).
|
||||
|
||||
.. attribute:: secure
|
||||
|
||||
True, if the result is validated securely.
|
||||
False, if validation failed or domain queried has no security info.
|
||||
|
||||
It is possible to get a result with no data (havedata is false),
|
||||
and secure is true. This means that the non-existance of the data
|
||||
was cryptographically proven (with signatures).
|
||||
|
||||
.. attribute:: bogus
|
||||
|
||||
If the result was not secure (secure==0), and this result is due to a security failure, bogus is true.
|
||||
This means the data has been actively tampered with, signatures
|
||||
failed, expected signatures were not present, timestamps on
|
||||
signatures were out of date and so on.
|
||||
|
||||
If secure==0 and bogus==0, this can happen if the data is not secure
|
||||
because security is disabled for that domain name.
|
||||
This means the data is from a domain where data is not signed.
|
||||
|
||||
.. attribute:: nxdomain
|
||||
|
||||
If there was no data, and the domain did not exist, this is true.
|
||||
If it is false, and there was no data, then the domain name is purported to exist, but the requested data type is not available.
|
||||
|
||||
.. attribute:: rcode
|
||||
|
||||
DNS RCODE for the result. May contain additional error code if there was no data due to an error.
|
||||
0 (RCODE_NOERROR) if okay. See predefined `RCODE_` constants.
|
||||
|
||||
RCODE can be represented in display representation form (string) using :attr:`rcode_str` attribute.
|
||||
|
||||
Class ub_data
|
||||
----------------------
|
||||
.. autoclass:: ub_data
|
||||
:members:
|
||||
|
||||
Functions
|
||||
----------------------
|
||||
.. autofunction:: reverse
|
||||
.. autofunction:: idn2dname
|
||||
.. autofunction:: dname2idn
|
||||
|
||||
Predefined constants
|
||||
-----------------------
|
||||
|
||||
**RCODE**
|
||||
* RCODE_FORMERR = 1
|
||||
* RCODE_NOERROR = 0
|
||||
* RCODE_NOTAUTH = 9
|
||||
* RCODE_NOTIMPL = 4
|
||||
* RCODE_NOTZONE = 10
|
||||
* RCODE_NXDOMAIN = 3
|
||||
* RCODE_NXRRSET = 8
|
||||
* RCODE_REFUSED = 5
|
||||
* RCODE_SERVFAIL = 2
|
||||
* RCODE_YXDOMAIN = 6
|
||||
* RCODE_YXRRSET = 7
|
||||
|
||||
**RR_CLASS**
|
||||
* RR_CLASS_ANY = 255
|
||||
* RR_CLASS_CH = 3
|
||||
* RR_CLASS_HS = 4
|
||||
* RR_CLASS_IN = 1
|
||||
* RR_CLASS_NONE = 254
|
||||
|
||||
**RR_TYPE**
|
||||
* RR_TYPE_A = 1
|
||||
* RR_TYPE_A6 = 38
|
||||
* RR_TYPE_AAAA = 28
|
||||
* RR_TYPE_AFSDB = 18
|
||||
* RR_TYPE_ANY = 255
|
||||
* RR_TYPE_APL = 42
|
||||
* RR_TYPE_ATMA = 34
|
||||
* RR_TYPE_AXFR = 252
|
||||
* RR_TYPE_CERT = 37
|
||||
* RR_TYPE_CNAME = 5
|
||||
* RR_TYPE_DHCID = 49
|
||||
* RR_TYPE_DLV = 32769
|
||||
* RR_TYPE_DNAME = 39
|
||||
* RR_TYPE_DNSKEY = 48
|
||||
* RR_TYPE_DS = 43
|
||||
* RR_TYPE_EID = 31
|
||||
* RR_TYPE_GID = 102
|
||||
* RR_TYPE_GPOS = 27
|
||||
* RR_TYPE_HINFO = 13
|
||||
* RR_TYPE_IPSECKEY = 45
|
||||
* RR_TYPE_ISDN = 20
|
||||
* RR_TYPE_IXFR = 251
|
||||
* RR_TYPE_KEY = 25
|
||||
* RR_TYPE_KX = 36
|
||||
* RR_TYPE_LOC = 29
|
||||
* RR_TYPE_MAILA = 254
|
||||
* RR_TYPE_MAILB = 253
|
||||
* RR_TYPE_MB = 7
|
||||
* RR_TYPE_MD = 3
|
||||
* RR_TYPE_MF = 4
|
||||
* RR_TYPE_MG = 8
|
||||
* RR_TYPE_MINFO = 14
|
||||
* RR_TYPE_MR = 9
|
||||
* RR_TYPE_MX = 15
|
||||
* RR_TYPE_NAPTR = 35
|
||||
* RR_TYPE_NIMLOC = 32
|
||||
* RR_TYPE_NS = 2
|
||||
* RR_TYPE_NSAP = 22
|
||||
* RR_TYPE_NSAP_PTR = 23
|
||||
* RR_TYPE_NSEC = 47
|
||||
* RR_TYPE_NSEC3 = 50
|
||||
* RR_TYPE_NSEC3PARAMS = 51
|
||||
* RR_TYPE_NULL = 10
|
||||
* RR_TYPE_NXT = 30
|
||||
* RR_TYPE_OPT = 41
|
||||
* RR_TYPE_PTR = 12
|
||||
* RR_TYPE_PX = 26
|
||||
* RR_TYPE_RP = 17
|
||||
* RR_TYPE_RRSIG = 46
|
||||
* RR_TYPE_RT = 21
|
||||
* RR_TYPE_SIG = 24
|
||||
* RR_TYPE_SINK = 40
|
||||
* RR_TYPE_SOA = 6
|
||||
* RR_TYPE_SRV = 33
|
||||
* RR_TYPE_SSHFP = 44
|
||||
* RR_TYPE_TSIG = 250
|
||||
* RR_TYPE_TXT = 16
|
||||
* RR_TYPE_UID = 101
|
||||
* RR_TYPE_UINFO = 100
|
||||
* RR_TYPE_UNSPEC = 103
|
||||
* RR_TYPE_WKS = 11
|
||||
* RR_TYPE_X25 = 19
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
async-lookup.py : This example shows how to use asynchronous lookups
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
import time
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
def call_back(my_data,status,result):
|
||||
print "Call_back:", my_data
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
my_data['done_flag'] = True
|
||||
|
||||
|
||||
my_data = {'done_flag':False,'arbitrary':"object"}
|
||||
status, async_id = ctx.resolve_async("www.nic.cz", my_data, call_back, unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
|
||||
while (status == 0) and (not my_data['done_flag']):
|
||||
status = ctx.process()
|
||||
time.sleep(0.1)
|
||||
|
||||
if (status != 0):
|
||||
print "Resolve error:", unbound.ub_strerror(status)
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
dns-lookup.py : This example shows how to resolve IP address
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:", result.data.address_list
|
||||
elif status != 0:
|
||||
print "Error:", unbound.ub_strerror(status)
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
dnssec-valid.py: DNSSEC validation
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import os
|
||||
from unbound import ub_ctx,RR_TYPE_A,RR_CLASS_IN
|
||||
|
||||
ctx = ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
fw = open("dnssec-valid.txt","wb")
|
||||
ctx.debugout(fw)
|
||||
ctx.debuglevel(2)
|
||||
|
||||
if os.path.isfile("keys"):
|
||||
ctx.add_ta_file("keys") #read public keys for DNSSEC verificatio
|
||||
|
||||
status, result = ctx.resolve("www.nic.cz", RR_TYPE_A, RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
|
||||
print "Result:", result.data.address_list
|
||||
|
||||
if result.secure:
|
||||
print "Result is secure"
|
||||
elif result.bogus:
|
||||
print "Result is bogus"
|
||||
else:
|
||||
print "Result is insecure"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
example8-1.py: Example shows how to lookup for MX and NS records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
idn-lookup.py: IDN (Internationalized Domain Name) lookup support
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
import locale
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.set_option("module-config:","iterator") #We don't need validation
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
#The unicode IDN string is automatically converted (if necessary)
|
||||
status, result = ctx.resolve(u"www.háčkyčárky.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
|
||||
status, result = ctx.resolve(u"háčkyčárky.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list_idn:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse('217.31.204.66')+'.in-addr.arpa', unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data
|
||||
for k in result.data.domain_list_idn:
|
||||
print " dname:%s" % k
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
mx-lookup.py: Lookup for MX records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_MX, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.mx_list:
|
||||
print " priority:%d address:%s" % k
|
||||
|
||||
status, result = ctx.resolve("nic.cz", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.address_list:
|
||||
print " address:%s" % k
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python
|
||||
# vim:fileencoding=utf-8
|
||||
'''
|
||||
ns-lookup.py: Example shows how to lookup for NS records
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve("vutbr.cz", unbound.RR_TYPE_NS, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result:"
|
||||
print " raw data:", result.data
|
||||
for k in result.data.domain_list:
|
||||
print " host: %s" % k
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
'''
|
||||
reverse-lookup.py: Example shows how to resolve reverse record
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
'''
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
status, result = ctx.resolve(unbound.reverse("74.125.43.147") + ".in-addr.arpa.", unbound.RR_TYPE_PTR, unbound.RR_CLASS_IN)
|
||||
if status == 0 and result.havedata:
|
||||
print "Result.data:", result.data, result.data.domain_list
|
||||
|
||||
@@ -0,0 +1,936 @@
|
||||
/*
|
||||
* libounbound.i: pyUnbound module (libunbound wrapper for Python)
|
||||
*
|
||||
* Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
* Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the organization nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
%module unbound
|
||||
%{
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "libunbound/unbound.h"
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
import encodings.idna
|
||||
%}
|
||||
|
||||
//%include "doc.i"
|
||||
%include "file.i"
|
||||
|
||||
%feature("docstring") strerror "Convert error value to a human readable string."
|
||||
|
||||
// ================================================================================
|
||||
// ub_resolve - perform resolution and validation
|
||||
// ================================================================================
|
||||
%typemap(in,numinputs=0,noblock=1) (struct ub_result** result)
|
||||
{
|
||||
struct ub_result* newubr;
|
||||
$1 = &newubr;
|
||||
}
|
||||
|
||||
/* result generation */
|
||||
%typemap(argout,noblock=1) (struct ub_result** result)
|
||||
{
|
||||
if(1) { /* new code block for variable on stack */
|
||||
PyObject* tuple;
|
||||
tuple = PyTuple_New(2);
|
||||
PyTuple_SetItem(tuple, 0, $result);
|
||||
if (result == 0) {
|
||||
PyTuple_SetItem(tuple, 1, SWIG_NewPointerObj(SWIG_as_voidptr(newubr), SWIGTYPE_p_ub_result, SWIG_POINTER_OWN | 0 ));
|
||||
} else {
|
||||
PyTuple_SetItem(tuple, 1, Py_None);
|
||||
}
|
||||
$result = tuple;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================
|
||||
// ub_ctx - validation context
|
||||
// ================================================================================
|
||||
%nodefaultctor ub_ctx; //no default constructor & destructor
|
||||
%nodefaultdtor ub_ctx;
|
||||
|
||||
%newobject ub_ctx_create;
|
||||
%delobject ub_ctx_delete;
|
||||
%rename(_ub_ctx_delete) ub_ctx_delete;
|
||||
|
||||
%newobject ub_resolve;
|
||||
|
||||
%inline %{
|
||||
void ub_ctx_free_dbg (struct ub_ctx* c) {
|
||||
printf("******** UB_CTX free 0x%lX ************\n", (long unsigned int)c);
|
||||
ub_ctx_delete(c);
|
||||
}
|
||||
|
||||
//RR types
|
||||
enum enum_rr_type
|
||||
{
|
||||
/** a host address */
|
||||
RR_TYPE_A = 1,
|
||||
/** an authoritative name server */
|
||||
RR_TYPE_NS = 2,
|
||||
/** a mail destination (Obsolete - use MX) */
|
||||
RR_TYPE_MD = 3,
|
||||
/** a mail forwarder (Obsolete - use MX) */
|
||||
RR_TYPE_MF = 4,
|
||||
/** the canonical name for an alias */
|
||||
RR_TYPE_CNAME = 5,
|
||||
/** marks the start of a zone of authority */
|
||||
RR_TYPE_SOA = 6,
|
||||
/** a mailbox domain name (EXPERIMENTAL) */
|
||||
RR_TYPE_MB = 7,
|
||||
/** a mail group member (EXPERIMENTAL) */
|
||||
RR_TYPE_MG = 8,
|
||||
/** a mail rename domain name (EXPERIMENTAL) */
|
||||
RR_TYPE_MR = 9,
|
||||
/** a null RR (EXPERIMENTAL) */
|
||||
RR_TYPE_NULL = 10,
|
||||
/** a well known service description */
|
||||
RR_TYPE_WKS = 11,
|
||||
/** a domain name pointer */
|
||||
RR_TYPE_PTR = 12,
|
||||
/** host information */
|
||||
RR_TYPE_HINFO = 13,
|
||||
/** mailbox or mail list information */
|
||||
RR_TYPE_MINFO = 14,
|
||||
/** mail exchange */
|
||||
RR_TYPE_MX = 15,
|
||||
/** text strings */
|
||||
RR_TYPE_TXT = 16,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_RP = 17,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_AFSDB = 18,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_X25 = 19,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_ISDN = 20,
|
||||
/** RFC1183 */
|
||||
RR_TYPE_RT = 21,
|
||||
/** RFC1706 */
|
||||
RR_TYPE_NSAP = 22,
|
||||
/** RFC1348 */
|
||||
RR_TYPE_NSAP_PTR = 23,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_SIG = 24,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_KEY = 25,
|
||||
/** RFC2163 */
|
||||
RR_TYPE_PX = 26,
|
||||
/** RFC1712 */
|
||||
RR_TYPE_GPOS = 27,
|
||||
/** ipv6 address */
|
||||
RR_TYPE_AAAA = 28,
|
||||
/** LOC record RFC1876 */
|
||||
RR_TYPE_LOC = 29,
|
||||
/** 2535typecode */
|
||||
RR_TYPE_NXT = 30,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
RR_TYPE_EID = 31,
|
||||
/** draft-ietf-nimrod-dns-01.txt */
|
||||
RR_TYPE_NIMLOC = 32,
|
||||
/** SRV record RFC2782 */
|
||||
RR_TYPE_SRV = 33,
|
||||
/** http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
|
||||
RR_TYPE_ATMA = 34,
|
||||
/** RFC2915 */
|
||||
RR_TYPE_NAPTR = 35,
|
||||
/** RFC2230 */
|
||||
RR_TYPE_KX = 36,
|
||||
/** RFC2538 */
|
||||
RR_TYPE_CERT = 37,
|
||||
/** RFC2874 */
|
||||
RR_TYPE_A6 = 38,
|
||||
/** RFC2672 */
|
||||
RR_TYPE_DNAME = 39,
|
||||
/** dnsind-kitchen-sink-02.txt */
|
||||
RR_TYPE_SINK = 40,
|
||||
/** Pseudo OPT record... */
|
||||
RR_TYPE_OPT = 41,
|
||||
/** RFC3123 */
|
||||
RR_TYPE_APL = 42,
|
||||
/** draft-ietf-dnsext-delegation */
|
||||
RR_TYPE_DS = 43,
|
||||
/** SSH Key Fingerprint */
|
||||
RR_TYPE_SSHFP = 44,
|
||||
/** draft-richardson-ipseckey-rr-11.txt */
|
||||
RR_TYPE_IPSECKEY = 45,
|
||||
/** draft-ietf-dnsext-dnssec-25 */
|
||||
RR_TYPE_RRSIG = 46,
|
||||
RR_TYPE_NSEC = 47,
|
||||
RR_TYPE_DNSKEY = 48,
|
||||
RR_TYPE_DHCID = 49,
|
||||
|
||||
RR_TYPE_NSEC3 = 50,
|
||||
RR_TYPE_NSEC3PARAMS = 51,
|
||||
|
||||
RR_TYPE_UINFO = 100,
|
||||
RR_TYPE_UID = 101,
|
||||
RR_TYPE_GID = 102,
|
||||
RR_TYPE_UNSPEC = 103,
|
||||
|
||||
RR_TYPE_TSIG = 250,
|
||||
RR_TYPE_IXFR = 251,
|
||||
RR_TYPE_AXFR = 252,
|
||||
/** A request for mailbox-related records (MB, MG or MR) */
|
||||
RR_TYPE_MAILB = 253,
|
||||
/** A request for mail agent RRs (Obsolete - see MX) */
|
||||
RR_TYPE_MAILA = 254,
|
||||
/** any type (wildcard) */
|
||||
RR_TYPE_ANY = 255,
|
||||
|
||||
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
|
||||
RR_TYPE_DLV = 32769,
|
||||
};
|
||||
|
||||
// RR classes
|
||||
enum enum_rr_class
|
||||
{
|
||||
/** the Internet */
|
||||
RR_CLASS_IN = 1,
|
||||
/** Chaos class */
|
||||
RR_CLASS_CH = 3,
|
||||
/** Hesiod (Dyer 87) */
|
||||
RR_CLASS_HS = 4,
|
||||
/** None class, dynamic update */
|
||||
RR_CLASS_NONE = 254,
|
||||
/** Any class */
|
||||
RR_CLASS_ANY = 255,
|
||||
};
|
||||
%}
|
||||
|
||||
%feature("docstring") ub_ctx "Unbound resolving and validation context.
|
||||
|
||||
The validation context is created to hold the resolver status, validation keys and a small cache (containing messages, rrsets, roundtrip times, trusted keys, lameness information).
|
||||
|
||||
**Usage**
|
||||
|
||||
>>> import unbound
|
||||
>>> ctx = unbound.ub_ctx()
|
||||
>>> ctx.resolvconf(\"/etc/resolv.conf\")
|
||||
>>> status, result = ctx.resolve(\"www.google.com\", unbound.RR_TYPE_A, unbound.RR_CLASS_IN)
|
||||
>>> if status==0 and result.havedata:
|
||||
>>> print \"Result:\",result.data.address_list
|
||||
Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
"
|
||||
|
||||
%extend ub_ctx
|
||||
{
|
||||
%pythoncode %{
|
||||
def __init__(self):
|
||||
"""Creates a resolving and validation context.
|
||||
|
||||
An exception is invoked if the process of creation an ub_ctx instance fails.
|
||||
"""
|
||||
self.this = _unbound.ub_ctx_create()
|
||||
if not self.this:
|
||||
raise Exception("Fatal error: unbound context initialization failed")
|
||||
|
||||
#__swig_destroy__ = _unbound.ub_ctx_free_dbg
|
||||
__swig_destroy__ = _unbound._ub_ctx_delete
|
||||
|
||||
#UB_CTX_METHODS_#
|
||||
def add_ta(self,ta):
|
||||
"""Add a trust anchor to the given context.
|
||||
|
||||
The trust anchor is a string, on one line, that holds a valid DNSKEY or DS RR.
|
||||
|
||||
:param ta:
|
||||
string, with zone-format RR on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_add_ta(self,ta)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def add_ta_file(self,fname):
|
||||
"""Add trust anchors to the given context.
|
||||
|
||||
Pass name of a file with DS and DNSKEY records (like from dig or drill).
|
||||
|
||||
:param fname:
|
||||
filename of file with keyfile with trust anchors.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_add_ta_file(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def config(self,fname):
|
||||
"""setup configuration for the given context.
|
||||
|
||||
:param fname:
|
||||
unbound config file (not all settings applicable). This is a power-users interface that lets you specify all sorts of options. For some specific options, such as adding trust anchors, special routines exist.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_config(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def debuglevel(self,d):
|
||||
"""Set debug verbosity for the context Output is directed to stderr.
|
||||
|
||||
:param d:
|
||||
debug level, 0 is off, 1 is very minimal, 2 is detailed, and 3 is lots.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_debuglevel(self,d)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def debugout(self,out):
|
||||
"""Set debug output (and error output) to the specified stream.
|
||||
|
||||
Pass None to disable. Default is stderr.
|
||||
|
||||
:param out:
|
||||
File stream to log to.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
|
||||
**Usage:**
|
||||
|
||||
In order to log into file, use
|
||||
|
||||
::
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
fw = fopen("debug.log")
|
||||
ctx.debuglevel(3)
|
||||
ctx.debugout(fw)
|
||||
|
||||
Another option is to print the debug informations to stderr output
|
||||
|
||||
::
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.debuglevel(10)
|
||||
ctx.debugout(sys.stderr)
|
||||
"""
|
||||
return _unbound.ub_ctx_debugout(self,out)
|
||||
#parameters: struct ub_ctx *,void *,
|
||||
#retvals: int
|
||||
|
||||
def hosts(self,fname="/etc/hosts"):
|
||||
"""Read list of hosts from the filename given.
|
||||
|
||||
Usually "/etc/hosts". These addresses are not flagged as DNSSEC secure when queried for.
|
||||
|
||||
:param fname:
|
||||
file name string. If None "/etc/hosts" is used.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_hosts(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def print_local_zones(self):
|
||||
"""Print the local zones and their content (RR data) to the debug output.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_print_local_zones(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def resolvconf(self,fname="/etc/resolv.conf"):
|
||||
"""Read list of nameservers to use from the filename given.
|
||||
|
||||
Usually "/etc/resolv.conf". Uses those nameservers as caching proxies. If they do not support DNSSEC, validation may fail.
|
||||
|
||||
Only nameservers are picked up, the searchdomain, ndots and other settings from resolv.conf(5) are ignored.
|
||||
|
||||
:param fname:
|
||||
file name string. If None "/etc/resolv.conf" is used.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_resolvconf(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def set_async(self,dothread):
|
||||
"""Set a context behaviour for asynchronous action.
|
||||
|
||||
:param dothread:
|
||||
if True, enables threading and a call to :meth:`resolve_async` creates a thread to handle work in the background.
|
||||
If False, a process is forked to handle work in the background.
|
||||
Changes to this setting after :meth:`async` calls have been made have no effect (delete and re-create the context to change).
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_async(self,dothread)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def set_fwd(self,addr):
|
||||
"""Set machine to forward DNS queries to, the caching resolver to use.
|
||||
|
||||
IP4 or IP6 address. Forwards all DNS requests to that machine, which is expected to run a recursive resolver. If the is not DNSSEC-capable, validation may fail. Can be called several times, in that case the addresses are used as backup servers.
|
||||
|
||||
To read the list of nameservers from /etc/resolv.conf (from DHCP or so), use the call :meth:`resolvconf`.
|
||||
|
||||
:param addr:
|
||||
address, IP4 or IP6 in string format. If the addr is None, forwarding is disabled.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_set_fwd(self,addr)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
|
||||
def set_option(self,opt,val):
|
||||
"""Set an option for the context.
|
||||
|
||||
Changes to the options after :meth:`resolve`, :meth:`resolve_async`, :meth:`zone_add`, :meth:`zone_remove`, :meth:`data_add` or :meth:`data_remove` have no effect (you have to delete and re-create the context).
|
||||
|
||||
:param opt:
|
||||
option name from the unbound.conf config file format. (not all settings applicable). The name includes the trailing ':' for example set_option("logfile:", "mylog.txt"); This is a power-users interface that lets you specify all sorts of options. For some specific options, such as adding trust anchors, special routines exist.
|
||||
:param val:
|
||||
value of the option.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_set_option(self,opt,val)
|
||||
#parameters: struct ub_ctx *,char *,char *,
|
||||
#retvals: int
|
||||
|
||||
def trustedkeys(self,fname):
|
||||
"""Add trust anchors to the given context.
|
||||
|
||||
Pass the name of a bind-style config file with trusted-keys{}.
|
||||
|
||||
:param fname:
|
||||
filename of file with bind-style config entries with trust anchors.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_trustedkeys(self,fname)
|
||||
#parameters: struct ub_ctx *,char *,
|
||||
#retvals: int
|
||||
#_UB_CTX_METHODS#
|
||||
|
||||
def zone_print(self):
|
||||
"""Print local zones using debougout"""
|
||||
_unbound.ub_ctx_print_local_zones(self)
|
||||
|
||||
def zone_add(self,zonename,zonetype):
|
||||
"""Add new local zone
|
||||
|
||||
:param zonename: zone domain name (e.g. myzone.)
|
||||
:param zonetype: type of the zone ("static",...)
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_zone_add(self,zonename, zonetype)
|
||||
#parameters: struct ub_ctx *,char*, char*
|
||||
#retvals: int
|
||||
|
||||
def zone_remove(self,zonename):
|
||||
"""Remove local zone
|
||||
|
||||
If exists, removes local zone with all the RRs.
|
||||
|
||||
:param zonename: zone domain name
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_zone_remove(self,zonename)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
def data_add(self,rrdata):
|
||||
"""Add new local RR data
|
||||
|
||||
:param rrdata: string, in zone-format on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
|
||||
**Usage**
|
||||
The local data ...
|
||||
|
||||
::
|
||||
|
||||
>>> ctx = unbound.ub_ctx()
|
||||
>>> ctx.zone_add("mydomain.net.","static")
|
||||
0
|
||||
>>> status = ctx.data_add("test.mydomain.net. IN A 192.168.1.1")
|
||||
0
|
||||
>>> status, result = ctx.resolve("test.mydomain.net")
|
||||
>>> if status==0 and result.havedata:
|
||||
>>> print \"Result:\",result.data.address_list
|
||||
Result: ['192.168.1.1']
|
||||
|
||||
"""
|
||||
return _unbound.ub_ctx_data_add(self,rrdata)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
def data_remove(self,rrdata):
|
||||
"""Remove local RR data
|
||||
|
||||
If exists, remove resource record from local zone
|
||||
|
||||
:param rrdata: string, in zone-format on one line. [domainname] [TTL optional] [type] [class optional] [rdata contents]
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_ctx_data_remove(self,rrdata)
|
||||
#parameters: struct ub_ctx *,char*
|
||||
#retvals: int
|
||||
|
||||
#UB_METHODS_#
|
||||
def cancel(self,async_id):
|
||||
"""Cancel an async query in progress.
|
||||
|
||||
Its callback will not be called.
|
||||
|
||||
:param async_id:
|
||||
which query to cancel.
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_cancel(self,async_id)
|
||||
#parameters: struct ub_ctx *,int,
|
||||
#retvals: int
|
||||
|
||||
def get_fd(self):
|
||||
"""Get file descriptor.
|
||||
|
||||
Wait for it to become readable, at this point answers are returned from the asynchronous validating resolver. Then call the ub_process to continue processing. This routine works immediately after context creation, the fd does not change.
|
||||
|
||||
:returns: (int) -1 on error, or file descriptor to use select(2) with.
|
||||
"""
|
||||
return _unbound.ub_fd(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def poll(self):
|
||||
"""Poll a context to see if it has any new results Do not poll in a loop, instead extract the fd below to poll for readiness, and then check, or wait using the wait routine.
|
||||
|
||||
:returns: (int) 0 if nothing to read, or nonzero if a result is available. If nonzero, call ctx_process() to do callbacks.
|
||||
"""
|
||||
return _unbound.ub_poll(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def process(self):
|
||||
"""Call this routine to continue processing results from the validating resolver (when the fd becomes readable).
|
||||
|
||||
Will perform necessary callbacks.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_process(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
def resolve(self,name,rrtype=RR_TYPE_A,rrclass=RR_CLASS_IN):
|
||||
"""Perform resolution and validation of the target name.
|
||||
|
||||
:param name:
|
||||
domain name in text format (a string or unicode string). IDN domain name have to be passed as a unicode string.
|
||||
:param rrtype:
|
||||
type of RR in host order (optional argument). Default value is RR_TYPE_A (A class).
|
||||
:param rrclass:
|
||||
class of RR in host order (optional argument). Default value is RR_CLASS_IN (for internet).
|
||||
:returns: * (int) 0 if OK, else error.
|
||||
* (:class:`ub_result`) the result data is returned in a newly allocated result structure. May be None on return, return value is set to an error in that case (out of memory).
|
||||
"""
|
||||
if isinstance(name, unicode): #probably IDN
|
||||
return _unbound.ub_resolve(self,idn2dname(name),rrtype,rrclass)
|
||||
else:
|
||||
return _unbound.ub_resolve(self,name,rrtype,rrclass)
|
||||
#parameters: struct ub_ctx *,char *,int,int,
|
||||
#retvals: int,struct ub_result **
|
||||
|
||||
def resolve_async(self,name,mydata,callback,rrtype=RR_TYPE_A,rrclass=RR_CLASS_IN):
|
||||
"""Perform resolution and validation of the target name.
|
||||
|
||||
Asynchronous, after a while, the callback will be called with your data and the result.
|
||||
If an error happens during processing, your callback will be called with error set to a nonzero value (and result==None).
|
||||
|
||||
:param name:
|
||||
domain name in text format (a string or unicode string). IDN domain name have to be passed as a unicode string.
|
||||
:param mydata:
|
||||
this data is your own data (you can pass arbitrary python object or None) which are passed on to the callback function.
|
||||
:param callback:
|
||||
call-back function which is called on completion of the resolution.
|
||||
:param rrtype:
|
||||
type of RR in host order (optional argument). Default value is RR_TYPE_A (A class).
|
||||
:param rrclass:
|
||||
class of RR in host order (optional argument). Default value is RR_CLASS_IN (for internet).
|
||||
:returns: * (int) 0 if OK, else error.
|
||||
* (int) async_id, an identifier number is returned for the query as it is in progress. It can be used to cancel the query.
|
||||
|
||||
**Call-back function:**
|
||||
The call-back function looks as the follows::
|
||||
|
||||
def call_back(mydata, status, result):
|
||||
pass
|
||||
|
||||
**Parameters:**
|
||||
* `mydata` - mydata object
|
||||
* `status` - 0 when a result has been found
|
||||
* `result` - the result structure. The result may be None, in that case err is set.
|
||||
|
||||
"""
|
||||
if isinstance(name, unicode): #probably IDN
|
||||
return _unbound._ub_resolve_async(self,idn2dname(name),rrtype,rrclass,mydata,callback)
|
||||
else:
|
||||
return _unbound._ub_resolve_async(self,name,rrtype,rrclass,mydata,callback)
|
||||
#parameters: struct ub_ctx *,char *,int,int,void *,ub_callback_t,
|
||||
#retvals: int, int
|
||||
|
||||
def wait(self):
|
||||
"""Wait for a context to finish with results.
|
||||
|
||||
Calls after the wait for you. After the wait, there are no more outstanding asynchronous queries.
|
||||
|
||||
:returns: (int) 0 if OK, else error.
|
||||
"""
|
||||
return _unbound.ub_wait(self)
|
||||
#parameters: struct ub_ctx *,
|
||||
#retvals: int
|
||||
|
||||
#_UB_METHODS#
|
||||
%}
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================
|
||||
// ub_result - validation and resolution results
|
||||
// ================================================================================
|
||||
%nodefaultctor ub_result; //no default constructor & destructor
|
||||
%nodefaultdtor ub_result;
|
||||
|
||||
%delobject ub_resolve_free;
|
||||
%rename(_ub_resolve_free) ub_resolve_free;
|
||||
|
||||
%inline %{
|
||||
void ub_resolve_free_dbg (struct ub_result* r) {
|
||||
printf("******** UB_RESOLVE free 0x%lX ************\n", (long unsigned int)r);
|
||||
ub_resolve_free(r);
|
||||
}
|
||||
%}
|
||||
|
||||
%feature("docstring") ub_result "The validation and resolution results."
|
||||
|
||||
//ub_result.rcode
|
||||
%inline %{
|
||||
enum result_enum_rcode {
|
||||
RCODE_NOERROR = 0,
|
||||
RCODE_FORMERR = 1,
|
||||
RCODE_SERVFAIL = 2,
|
||||
RCODE_NXDOMAIN = 3,
|
||||
RCODE_NOTIMPL = 4,
|
||||
RCODE_REFUSED = 5,
|
||||
RCODE_YXDOMAIN = 6,
|
||||
RCODE_YXRRSET = 7,
|
||||
RCODE_NXRRSET = 8,
|
||||
RCODE_NOTAUTH = 9,
|
||||
RCODE_NOTZONE = 10
|
||||
};
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
class ub_data:
|
||||
"""Class which makes the resolution results accessible"""
|
||||
def __init__(self, data):
|
||||
"""Creates ub_data class
|
||||
:param data: a list of the result data in RAW format
|
||||
"""
|
||||
if data == None:
|
||||
raise Exception("ub_data init: No data")
|
||||
self.data = data
|
||||
|
||||
def __str__(self):
|
||||
"""Represents data as string"""
|
||||
return ';'.join([' '.join(map(lambda x:"%02X" % ord(x),a)) for a in self.data])
|
||||
|
||||
@staticmethod
|
||||
def dname2str(s, ofs=0, maxlen=0):
|
||||
"""Parses DNAME and produces a list of labels
|
||||
|
||||
:param ofs: where the conversion should start to parse data
|
||||
:param maxlen: maximum length (0 means parse to the end)
|
||||
:returns: list of labels (string)
|
||||
"""
|
||||
if not s:
|
||||
return []
|
||||
|
||||
res = []
|
||||
slen = len(s)
|
||||
if maxlen > 0:
|
||||
slen = min(slen, maxlen)
|
||||
|
||||
idx = ofs
|
||||
while (idx < slen):
|
||||
complen = ord(s[idx])
|
||||
res.append(s[idx+1:idx+1+complen])
|
||||
idx += complen + 1
|
||||
|
||||
return res
|
||||
|
||||
def as_raw_data(self):
|
||||
"""Returns a list of RAW strings"""
|
||||
return self.data
|
||||
|
||||
raw = property(as_raw_data, doc="Returns RAW data (a list of binary encoded strings). See :meth:`as_raw_data`")
|
||||
|
||||
def as_mx_list(self):
|
||||
"""Represents data as a list of MX records (query for RR_TYPE_MX)
|
||||
|
||||
:returns: list of tuples (priority, dname)
|
||||
"""
|
||||
return [(256*ord(rdf[0])+ord(rdf[1]),'.'.join([a for a in self.dname2str(rdf,2)])) for rdf in self.data]
|
||||
|
||||
mx_list = property(as_mx_list, doc="Returns a list of tuples containing priority and domain names. See :meth:`as_mx_list`")
|
||||
|
||||
def as_idn_mx_list(self):
|
||||
"""Represents data as a list of MX records (query for RR_TYPE_MX)
|
||||
|
||||
:returns: list of tuples (priority, unicode dname)
|
||||
"""
|
||||
return [(256*ord(rdf[0])+ord(rdf[1]),'.'.join([encodings.idna.ToUnicode(a) for a in self.dname2str(rdf,2)])) for rdf in self.data]
|
||||
|
||||
mx_list_idn = property(as_idn_mx_list, doc="Returns a list of tuples containing priority and IDN domain names. See :meth:`as_idn_mx_list`")
|
||||
|
||||
def as_address_list(self):
|
||||
"""Represents data as a list of IP addresses (query for RR_TYPE_PTR)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return ['.'.join(map(lambda x:str(ord(x)),a)) for a in self.data]
|
||||
|
||||
address_list = property(as_address_list, doc="Returns a list of IP addresses. See :meth:`as_address_list`")
|
||||
|
||||
def as_domain_list(self):
|
||||
"""Represents data as a list of domain names (query for RR_TYPE_A)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return map(lambda x:'.'.join(self.dname2str(x)), self.data)
|
||||
|
||||
domain_list = property(as_domain_list, doc="Returns a list of domain names. See :meth:`as_domain_list`")
|
||||
|
||||
def as_idn_domain_list(self):
|
||||
"""Represents data as a list of unicode domain names (query for RR_TYPE_A)
|
||||
|
||||
:returns: list of strings
|
||||
"""
|
||||
return map(lambda x: '.'.join([encodings.idna.ToUnicode(a) for a in self.dname2str(x)]), self.data)
|
||||
|
||||
domain_list_idn = property(as_idn_domain_list, doc="Returns a list of IDN domain names. See :meth:`as_idn_domain_list`")
|
||||
%}
|
||||
|
||||
%extend ub_result
|
||||
{
|
||||
|
||||
%rename(_data) data;
|
||||
|
||||
PyObject* _ub_result_data(struct ub_result* result) {
|
||||
PyObject *list;
|
||||
int i,cnt;
|
||||
(void)self;
|
||||
if ((result == 0) || (!result->havedata) || (result->data == 0))
|
||||
return Py_None;
|
||||
|
||||
for (cnt=0,i=0;;i++,cnt++)
|
||||
if (result->data[i] == 0)
|
||||
break;
|
||||
|
||||
list = PyList_New(cnt);
|
||||
for (i=0;i<cnt;i++)
|
||||
PyList_SetItem(list, i, PyString_FromStringAndSize(result->data[i],result->len[i]));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
%pythoncode %{
|
||||
def __init__(self):
|
||||
raise Exception("This class can't be created directly.")
|
||||
|
||||
#__swig_destroy__ = _unbound.ub_resolve_free_dbg
|
||||
__swig_destroy__ = _unbound._ub_resolve_free
|
||||
|
||||
#havedata = property(_unbound.ub_result_havedata_get, _unbound.ub_result_havedata_set, "Havedata property")
|
||||
|
||||
rcode2str = {RCODE_NOERROR:'no error', RCODE_FORMERR:'form error', RCODE_SERVFAIL:'serv fail', RCODE_NXDOMAIN:'nx domain', RCODE_NOTIMPL:'not implemented', RCODE_REFUSED:'refused', RCODE_YXDOMAIN:'yxdomain', RCODE_YXRRSET:'yxrrset', RCODE_NXRRSET:'nxrrset', RCODE_NOTAUTH:'not auth', RCODE_NOTZONE:'not zone'}
|
||||
|
||||
def _get_rcode_str(self):
|
||||
"""Returns rcode in display representation form
|
||||
|
||||
:returns: string
|
||||
"""
|
||||
return self.rcode2str[self.rcode]
|
||||
|
||||
__swig_getmethods__["rcode_str"] = _get_rcode_str
|
||||
if _newclass:rcode_str = _swig_property(_get_rcode_str)
|
||||
|
||||
def _get_raw_data(self):
|
||||
"""Result data, a list of network order DNS rdata items.
|
||||
|
||||
Data are represented as a list of strings. To decode RAW data to the list of IP addresses use :attr:`data` attribute which returns an :class:`ub_data` instance containing conversion function.
|
||||
"""
|
||||
return self._ub_result_data(self)
|
||||
|
||||
__swig_getmethods__["rawdata"] = _get_raw_data
|
||||
rawdata = property(_get_raw_data, doc="Returns raw data, a list of rdata items. To decode RAW data use the :attr:`data` attribute which returns an instance of :class:`ub_data` containing the conversion functions.")
|
||||
|
||||
def _get_data(self):
|
||||
if not self.havedata: return None
|
||||
return ub_data(self._ub_result_data(self))
|
||||
|
||||
__swig_getmethods__["data"] = _get_data
|
||||
data = property(_get_data, doc="Returns :class:`ub_data` instance containing various decoding functions or None")
|
||||
|
||||
%}
|
||||
|
||||
}
|
||||
|
||||
%exception ub_resolve
|
||||
%{
|
||||
//printf("resolve_start(%lX)\n",(long unsigned int)arg1);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
$function
|
||||
Py_END_ALLOW_THREADS
|
||||
//printf("resolve_stop()\n");
|
||||
%}
|
||||
|
||||
%include "libunbound/unbound.h"
|
||||
|
||||
%inline %{
|
||||
//SWIG will see the ub_ctx as a class
|
||||
struct ub_ctx {
|
||||
};
|
||||
%}
|
||||
|
||||
//ub_ctx_debugout void* parameter correction
|
||||
int ub_ctx_debugout(struct ub_ctx* ctx, FILE* out);
|
||||
|
||||
// ================================================================================
|
||||
// ub_resolve_async - perform asynchronous resolution and validation
|
||||
// ================================================================================
|
||||
|
||||
%typemap(in,numinputs=0,noblock=1) (int* async_id)
|
||||
{
|
||||
int asyncid = -1;
|
||||
$1 = &asyncid;
|
||||
}
|
||||
|
||||
%apply PyObject* {void* mydata}
|
||||
|
||||
/* result generation */
|
||||
%typemap(argout,noblock=1) (int* async_id)
|
||||
{
|
||||
if(1) { /* new code block for variable on stack */
|
||||
PyObject* tuple;
|
||||
tuple = PyTuple_New(2);
|
||||
PyTuple_SetItem(tuple, 0, $result);
|
||||
PyTuple_SetItem(tuple, 1, SWIG_From_int(asyncid));
|
||||
$result = tuple;
|
||||
}
|
||||
}
|
||||
|
||||
// Grab a Python function object as a Python object.
|
||||
%typemap(in) (PyObject *pyfunc) {
|
||||
if (!PyCallable_Check($input))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Need a callable object!");
|
||||
return NULL;
|
||||
}
|
||||
$1 = $input;
|
||||
}
|
||||
|
||||
// Python callback workaround
|
||||
int _ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, void* mydata, PyObject *pyfunc, int* async_id);
|
||||
|
||||
%{
|
||||
struct cb_data {
|
||||
PyObject* data;
|
||||
PyObject* func;
|
||||
};
|
||||
|
||||
static void PythonCallBack(void* iddata, int status, struct ub_result* result)
|
||||
{
|
||||
PyObject *arglist;
|
||||
PyObject *fresult;
|
||||
struct cb_data* id;
|
||||
id = (struct cb_data*) iddata;
|
||||
arglist = Py_BuildValue("(OiO)",id->data,status, SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_ub_result, 0 | 0 )); // Build argument list
|
||||
fresult = PyEval_CallObject(id->func,arglist); // Call Python
|
||||
Py_DECREF(id->func);
|
||||
Py_DECREF(id->data);
|
||||
free(id);
|
||||
ub_resolve_free(result); //free ub_result
|
||||
//ub_resolve_free_dbg(result); //free ub_result
|
||||
Py_DECREF(arglist); // Trash arglist
|
||||
Py_XDECREF(fresult);
|
||||
}
|
||||
|
||||
int _ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, PyObject* mydata, PyObject *pyfunc, int* async_id) {
|
||||
int r;
|
||||
struct cb_data* id;
|
||||
id = (struct cb_data*) malloc(sizeof(struct cb_data));
|
||||
id->data = mydata;
|
||||
id->func = pyfunc;
|
||||
|
||||
r = ub_resolve_async(ctx,name,rrtype,rrclass, (void *) id, PythonCallBack, async_id);
|
||||
Py_INCREF(mydata);
|
||||
Py_INCREF(pyfunc);
|
||||
return r;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
ub_resolve_async = _unbound._ub_resolve_async
|
||||
|
||||
def reverse(domain):
|
||||
"""Reverse domain name
|
||||
|
||||
Usable for reverse lookups when the IP address should be reversed
|
||||
"""
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
def idn2dname(idnname):
|
||||
"""Converts domain name in IDN format to canonic domain name
|
||||
|
||||
:param idnname: (unicode string) IDN name
|
||||
:returns: (string) domain name
|
||||
"""
|
||||
return '.'.join([encodings.idna.ToASCII(a) for a in idnname.split('.')])
|
||||
|
||||
def dname2idn(name):
|
||||
"""Converts canonic domain name in IDN format to unicode string
|
||||
|
||||
:param name: (string) domain name
|
||||
:returns: (unicode string) domain name
|
||||
"""
|
||||
return '.'.join([encodings.idna.ToUnicode(a) for a in name.split('.')])
|
||||
|
||||
%}
|
||||
|
||||
@@ -20,3 +20,8 @@ ub_resolve_async
|
||||
ub_cancel
|
||||
ub_resolve_free
|
||||
ub_strerror
|
||||
ub_ctx_print_local_zones
|
||||
ub_ctx_zone_add
|
||||
ub_ctx_zone_remove
|
||||
ub_ctx_data_add
|
||||
ub_ctx_data_remove
|
||||
|
||||
@@ -181,6 +181,14 @@ struct ub_result {
|
||||
* This means the data is from a domain where data is not signed.
|
||||
*/
|
||||
int bogus;
|
||||
|
||||
/**
|
||||
* If the result is bogus this contains a string (zero terminated)
|
||||
* that describes the failure. There may be other errors as well
|
||||
* as the one described, the description may not be perfectly accurate.
|
||||
* Is NULL if the result is not bogus.
|
||||
*/
|
||||
char* why_bogus;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -449,6 +457,11 @@ int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
* @param ctx: context.
|
||||
* @param async_id: which query to cancel.
|
||||
* @return 0 if OK, else error.
|
||||
* This routine can return an error if the async_id passed does not exist
|
||||
* or has already been delivered. If another thread is processing results
|
||||
* at the same time, the result may be delivered at the same time and the
|
||||
* cancel fails with an error. Also the cancel can fail due to a system
|
||||
* error, no memory or socket failures.
|
||||
*/
|
||||
int ub_cancel(struct ub_ctx* ctx, int async_id);
|
||||
|
||||
@@ -465,4 +478,49 @@ void ub_resolve_free(struct ub_result* result);
|
||||
*/
|
||||
const char* ub_strerror(int err);
|
||||
|
||||
/**
|
||||
* Debug routine. Print the local zone information to debug output.
|
||||
* @param ctx: context. Is finalized by the routine.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_print_local_zones(struct ub_ctx* ctx);
|
||||
|
||||
/**
|
||||
* Add a new zone with the zonetype to the local authority info of the
|
||||
* library.
|
||||
* @param ctx: context. Is finalized by the routine.
|
||||
* @param zone_name: name of the zone in text, "example.com"
|
||||
* If it already exists, the type is updated.
|
||||
* @param zone_type: type of the zone (like for unbound.conf) in text.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type);
|
||||
|
||||
/**
|
||||
* Remove zone from local authority info of the library.
|
||||
* @param ctx: context. Is finalized by the routine.
|
||||
* @param zone_name: name of the zone in text, "example.com"
|
||||
* If it does not exist, nothing happens.
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name);
|
||||
|
||||
/**
|
||||
* Add localdata to the library local authority info.
|
||||
* Similar to local-data config statement.
|
||||
* @param ctx: context. Is finalized by the routine.
|
||||
* @param data: the resource record in text format, for example
|
||||
* "www.example.com IN A 127.0.0.1"
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
|
||||
|
||||
/**
|
||||
* Remove localdata from the library local authority info.
|
||||
* @param ctx: context. Is finalized by the routine.
|
||||
* @param data: the name to delete all data from, like "www.example.com".
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
|
||||
+171
-22
@@ -42,15 +42,19 @@ cwd=`pwd`
|
||||
# Utility functions.
|
||||
usage () {
|
||||
cat >&2 <<EOF
|
||||
Usage $0: [-h] [-s] [-d SVN_root] [-l ldns_path]
|
||||
Generate a distribution tar file for NSD.
|
||||
Usage $0: [-h] [-s] [-d SVN_root] [-l ldns_path] [-w ...args...]
|
||||
Generate a distribution tar file for unbound.
|
||||
|
||||
-h This usage information.
|
||||
-s Build a snapshot distribution file. The current date is
|
||||
automatically appended to the current NSD version number.
|
||||
-d SVN_root Retrieve the NSD source from the specified repository.
|
||||
automatically appended to the current unbound version number.
|
||||
-rc <nr> Build a release candidate, the given string will be added
|
||||
to the version number
|
||||
(which will then be unbound-<version>rc<number>)
|
||||
-d SVN_root Retrieve the unbound source from the specified repository.
|
||||
Detected from svn working copy if not specified.
|
||||
-l ldnsdir Directory where ldns resides. Detected from Makefile.
|
||||
-w ... Build windows binary dist. last args passed to configure.
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
@@ -103,9 +107,32 @@ replace_all () {
|
||||
replace_text "$1" "@date@" "`date +'%b %e, %Y'`"
|
||||
}
|
||||
|
||||
check_svn_root () {
|
||||
# Check if SVNROOT is specified.
|
||||
if [ -z "$SVNROOT" ]; then
|
||||
if test -f .svn/entries; then
|
||||
eval `svn info | grep 'URL:' | sed -e 's/URL: /url=/' | head -1`
|
||||
SVNROOT="$url"
|
||||
fi
|
||||
if test -z "$SVNROOT"; then
|
||||
error "SVNROOT must be specified (using -d)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
create_temp_dir () {
|
||||
# Creating temp directory
|
||||
info "Creating temporary working directory"
|
||||
temp_dir=`mktemp -d unbound-dist-XXXXXX`
|
||||
info "Directory '$temp_dir' created."
|
||||
cd $temp_dir
|
||||
}
|
||||
|
||||
|
||||
SNAPSHOT="no"
|
||||
RC="no"
|
||||
LDNSDIR=""
|
||||
DOWIN="no"
|
||||
|
||||
# Parse the command line arguments.
|
||||
while [ "$1" ]; do
|
||||
@@ -120,10 +147,19 @@ while [ "$1" ]; do
|
||||
"-s")
|
||||
SNAPSHOT="yes"
|
||||
;;
|
||||
"-w")
|
||||
DOWIN="yes"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
"-l")
|
||||
LDNSDIR="$2"
|
||||
shift
|
||||
;;
|
||||
"-rc")
|
||||
RC="$2"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
error "Unrecognized argument -- $1"
|
||||
;;
|
||||
@@ -131,16 +167,99 @@ while [ "$1" ]; do
|
||||
shift
|
||||
done
|
||||
|
||||
# Check if SVNROOT is specified.
|
||||
if [ -z "$SVNROOT" ]; then
|
||||
if test -f .svn/entries; then
|
||||
eval `svn info | grep 'URL:' | sed -e 's/URL: /url=/' | head -1`
|
||||
SVNROOT="$url"
|
||||
if [ "$DOWIN" = "yes" ]; then
|
||||
# detect crosscompile, from Fedora11 at this point.
|
||||
if test "`uname`" = "Linux"; then
|
||||
info "Crosscompile windows dist"
|
||||
cross="yes"
|
||||
configure="mingw32-configure"
|
||||
strip="i686-pc-mingw32-strip"
|
||||
makensis="makensis" # from mingw32-nsis package
|
||||
|
||||
check_svn_root
|
||||
create_temp_dir
|
||||
info "Exporting source from SVN."
|
||||
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
|
||||
|
||||
# on a re-configure the cache may no longer be valid...
|
||||
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
|
||||
else
|
||||
cross="no" # mingw and msys
|
||||
configure="./configure"
|
||||
strip="strip"
|
||||
makensis="c:/Program Files/NSIS/makensis.exe" # http://nsis.sf.net
|
||||
fi
|
||||
if test -z "$SVNROOT"; then
|
||||
error "SVNROOT must be specified (using -d)"
|
||||
|
||||
# version gets compiled into source, edit the configure to set it
|
||||
version=`./configure --version | head -1 | awk '{ print $3 }'` \
|
||||
|| error_cleanup "Cannot determine version number."
|
||||
if [ "$RC" != "no" -o "$SNAPSHOT" != "no" ]; then
|
||||
if [ "$RC" != "no" ]; then
|
||||
version2=`echo $version | sed -e 's/rc.*$//' -e 's/_20.*$//'`
|
||||
version2=`echo $version2 | sed -e 's/rc.*//'`"rc$RC"
|
||||
fi
|
||||
if [ "$SNAPSHOT" != "no" ]; then
|
||||
version2=`echo $version | sed -e 's/rc.*$//' -e 's/_20.*$//'`
|
||||
version2="${version2}_`date +%Y%m%d`"
|
||||
fi
|
||||
replace_text "configure.ac" "AC_INIT(unbound, $version" "AC_INIT(unbound, $version2"
|
||||
version="$version2"
|
||||
info "Rebuilding configure script (autoconf) snapshot."
|
||||
autoconf || autoheader || error_cleanup "Autoconf failed."
|
||||
rm -r autom4te* || echo "ignored"
|
||||
fi
|
||||
|
||||
# procedure for making unbound installer on mingw.
|
||||
info "Creating windows dist unbound $version"
|
||||
info "Calling configure"
|
||||
echo "$configure"' --enable-debug --enable-static-exe '"$*"
|
||||
$configure --enable-debug --enable-static-exe $* \
|
||||
|| error_cleanup "Could not configure"
|
||||
info "Calling make"
|
||||
make || error_cleanup "Could not make"
|
||||
info "Make complete"
|
||||
|
||||
info "Unbound version: $version"
|
||||
file="unbound-$version.zip"
|
||||
rm -f $file
|
||||
info "Creating $file"
|
||||
mkdir tmp.$$
|
||||
$strip unbound.exe
|
||||
$strip anchor-update.exe
|
||||
$strip unbound-control.exe
|
||||
$strip unbound-host.exe
|
||||
$strip unbound-checkconf.exe
|
||||
$strip unbound-service-install.exe
|
||||
$strip unbound-service-remove.exe
|
||||
cd tmp.$$
|
||||
cp ../doc/example.conf example.conf
|
||||
cp ../unbound.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt .
|
||||
# zipfile
|
||||
zip ../$file LICENSE README.txt unbound.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe example.conf service.conf unbound-website.url
|
||||
info "Testing $file"
|
||||
(cd .. ; zip -T $file )
|
||||
# installer
|
||||
info "Creating installer"
|
||||
quadversion=`cat ../config.h | grep RSRC_PACKAGE_VERSION | sed -e 's/#define RSRC_PACKAGE_VERSION //' -e 's/,/\\./g'`
|
||||
cat ../winrc/setup.nsi | sed -e 's/define VERSION.*$/define VERSION "'$version'"/' -e 's/define QUADVERSION.*$/define QUADVERSION "'$quadversion'"/' > ../winrc/setup_ed.nsi
|
||||
"$makensis" ../winrc/setup_ed.nsi
|
||||
info "Created installer"
|
||||
cd ..
|
||||
rm -rf tmp.$$
|
||||
mv winrc/unbound_setup_$version.exe .
|
||||
if test "$cross" = "yes"; then
|
||||
mv unbound_setup_$version.exe $cwd/.
|
||||
mv unbound-$version.zip $cwd/.
|
||||
cleanup
|
||||
fi
|
||||
ls -lG unbound_setup_$version.exe
|
||||
ls -lG unbound-$version.zip
|
||||
info "Done"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_svn_root
|
||||
# Check if LDNSDIR is specified.
|
||||
if test -z "$LDNSDIR"; then
|
||||
# try to autodetect from Makefile (if present)
|
||||
@@ -158,12 +277,7 @@ info "SNAPSHOT is $SNAPSHOT"
|
||||
|
||||
#question "Do you wish to continue with these settings?" || error "User abort."
|
||||
|
||||
|
||||
# Creating temp directory
|
||||
info "Creating temporary working directory"
|
||||
temp_dir=`mktemp -d unbound-dist-XXXXXX`
|
||||
info "Directory '$temp_dir' created."
|
||||
cd $temp_dir
|
||||
create_temp_dir
|
||||
|
||||
info "Exporting source from SVN."
|
||||
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
@@ -171,7 +285,7 @@ svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
|
||||
|
||||
info "Adding libtool utils (libtoolize)."
|
||||
libtoolize -c || error_cleanup "libtoolize failed"
|
||||
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
|
||||
|
||||
info "Building configure script (autoreconf)."
|
||||
autoreconf || error_cleanup "Autoconf failed."
|
||||
@@ -205,10 +319,32 @@ version=`./configure --version | head -1 | awk '{ print $3 }'` || \
|
||||
|
||||
info "Unbound version: $version"
|
||||
|
||||
RECONFIGURE="no"
|
||||
|
||||
if [ "$RC" != "no" ]; then
|
||||
info "Building Unbound release candidate $RC."
|
||||
version2="${version}rc$RC"
|
||||
info "Version number: $version2"
|
||||
|
||||
replace_text "configure.ac" "AC_INIT(unbound, $version" "AC_INIT(unbound, $version2"
|
||||
version="$version2"
|
||||
RECONFIGURE="yes"
|
||||
fi
|
||||
|
||||
if [ "$SNAPSHOT" = "yes" ]; then
|
||||
info "Building Unbound snapshot."
|
||||
version="$version-`date +%Y%m%d`"
|
||||
info "Snapshot version number: $version"
|
||||
version2="${version}_`date +%Y%m%d`"
|
||||
info "Snapshot version number: $version2"
|
||||
|
||||
replace_text "configure.ac" "AC_INIT(unbound, $version" "AC_INIT(unbound, $version2"
|
||||
version="$version2"
|
||||
RECONFIGURE="yes"
|
||||
fi
|
||||
|
||||
if [ "$RECONFIGURE" = "yes" ]; then
|
||||
info "Rebuilding configure script (autoconf) snapshot."
|
||||
autoreconf || error_cleanup "Autoconf failed."
|
||||
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
|
||||
fi
|
||||
|
||||
replace_all doc/README
|
||||
@@ -245,8 +381,21 @@ case $OSTYPE in
|
||||
sha256=`sha256 unbound-$version.tar.gz | awk '{ print $5 }'`
|
||||
;;
|
||||
*)
|
||||
sha=`sha1sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
sha256=`sha256sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
# in case $OSTYPE is gone.
|
||||
case `uname` in
|
||||
Linux*)
|
||||
sha=`sha1sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
sha256=`sha256sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
;;
|
||||
FreeBSD*)
|
||||
sha=`sha1 unbound-$version.tar.gz | awk '{ print $5 }'`
|
||||
sha256=`sha256 unbound-$version.tar.gz | awk '{ print $5 }'`
|
||||
;;
|
||||
*)
|
||||
sha=`sha1sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
sha256=`sha256sum unbound-$version.tar.gz | awk '{ print $1 }'`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
echo $sha > unbound-$version.tar.gz.sha1
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
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 the organization nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user