mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
257
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eceaad3bd1 | ||
|
|
37799b8560 | ||
|
|
64adf68436 | ||
|
|
f97dcc8e40 | ||
|
|
86dcdaae33 | ||
|
|
9fb526d554 | ||
|
|
e338cb00f3 | ||
|
|
d3edcc3fab | ||
|
|
e6a54f732e | ||
|
|
2e7c9ad2f3 | ||
|
|
367c3f034e | ||
|
|
901d83fcff | ||
|
|
4b22dcb7ad | ||
|
|
86c28f2d57 | ||
|
|
41fccf9fe4 | ||
|
|
4c17395deb | ||
|
|
240a012bd8 | ||
|
|
929b623e59 | ||
|
|
709d8223f5 | ||
|
|
8746283787 | ||
|
|
ff1b857f90 | ||
|
|
c010e93d4a | ||
|
|
5d522b0017 | ||
|
|
42c2282f12 | ||
|
|
8e23542b85 | ||
|
|
ef80a99397 | ||
|
|
ba11247f93 | ||
|
|
e5431ca7e5 | ||
|
|
b019a6aad9 | ||
|
|
3a1ffe4c69 | ||
|
|
9b4b0de746 | ||
|
|
a3441215f1 | ||
|
|
5adb2dc4cf | ||
|
|
3f7248fa11 | ||
|
|
5839981255 | ||
|
|
cd7db58ce3 | ||
|
|
3d74d8e95b | ||
|
|
3869421258 | ||
|
|
b4b2c18909 | ||
|
|
95d5334783 | ||
|
|
6f757b28f3 | ||
|
|
db2cf53e7b | ||
|
|
33ba1f38d6 | ||
|
|
3d680a6d82 | ||
|
|
c9bcf1b3f7 | ||
|
|
242b255aac | ||
|
|
5351f69e49 | ||
|
|
631d2b4214 | ||
|
|
235e1399eb | ||
|
|
163e7046cb | ||
|
|
41d174b7f6 | ||
|
|
07bbd6c95a | ||
|
|
f761bc3cdd | ||
|
|
e28903cb6d | ||
|
|
4f487cf746 | ||
|
|
87fd7da6d7 | ||
|
|
f15350b776 | ||
|
|
3ac8cf0380 | ||
|
|
9323fa7688 | ||
|
|
c879fa1e79 | ||
|
|
ba448fbd54 | ||
|
|
7b948b0647 | ||
|
|
3e1ff464f1 | ||
|
|
3b96c4c9cd | ||
|
|
b7a314a7dc | ||
|
|
3044b805b3 | ||
|
|
e500340621 | ||
|
|
61b23e3811 | ||
|
|
c604b9c6a9 | ||
|
|
6450a5b191 | ||
|
|
e502757963 | ||
|
|
3815009cf1 | ||
|
|
92bff79d3d | ||
|
|
2dce3856cd | ||
|
|
a6e3ed1025 | ||
|
|
d3b85ed7d8 | ||
|
|
9581c39dcc | ||
|
|
88e8fb1029 | ||
|
|
3e5cf4da0b | ||
|
|
632e60eccd | ||
|
|
f4673d87ce | ||
|
|
3132937112 | ||
|
|
e6678abba6 | ||
|
|
ba274dd312 | ||
|
|
11031a7d36 | ||
|
|
efe248c46a | ||
|
|
68e4ef21db | ||
|
|
fa81710d16 | ||
|
|
3b4cbcf631 | ||
|
|
589eabc0cb | ||
|
|
c22f958152 | ||
|
|
680e14cb65 | ||
|
|
b8cd36af89 | ||
|
|
680a504652 | ||
|
|
0e79c3ddc0 | ||
|
|
20888cfa59 | ||
|
|
d2548b25f2 | ||
|
|
705e3e8d1c | ||
|
|
96961081b0 | ||
|
|
27182d614b | ||
|
|
b76d5dfc5b | ||
|
|
147a6c8548 | ||
|
|
6e2e8c047f | ||
|
|
58cb15c52a | ||
|
|
a4fae019de | ||
|
|
a9a65800b8 | ||
|
|
f8ba15e8dd | ||
|
|
2785225a43 | ||
|
|
f22a9f2762 | ||
|
|
4cd296a3f3 | ||
|
|
cfef4ba047 | ||
|
|
304f1bb457 | ||
|
|
44ab21485d | ||
|
|
3d62b46073 | ||
|
|
4621d209ca | ||
|
|
8c1ecf875e | ||
|
|
9b43579c03 | ||
|
|
ae2263d165 | ||
|
|
db72f77581 | ||
|
|
63d4bcde56 | ||
|
|
365a5666f3 | ||
|
|
5935cf1c41 | ||
|
|
9d2b5ca345 | ||
|
|
503df095b2 | ||
|
|
70dbd1c382 | ||
|
|
223c7c0080 | ||
|
|
dd2711d78c | ||
|
|
840142397d | ||
|
|
de7bc9f96e | ||
|
|
750ead5be2 | ||
|
|
9c0944ec1e | ||
|
|
0b3138e1bf | ||
|
|
b587c7f72d | ||
|
|
145bdd7466 | ||
|
|
51652cf8d5 | ||
|
|
db82fbadc1 | ||
|
|
3334ab389c | ||
|
|
52dbaa4ac1 | ||
|
|
8a19ff3baf | ||
|
|
2127c65561 | ||
|
|
b3a7ec4f56 | ||
|
|
23545a077c | ||
|
|
cd842fafb9 | ||
|
|
9996021d34 | ||
|
|
5a56d54086 | ||
|
|
e5a6403b81 | ||
|
|
42d2190343 | ||
|
|
ac5ba1b8ec | ||
|
|
10e6b1ed99 | ||
|
|
c879d6824b | ||
|
|
e2e34ad273 | ||
|
|
1fe24566ad | ||
|
|
9d4eb4cac5 | ||
|
|
d77901e8ed | ||
|
|
0c954d99c3 | ||
|
|
2db3851430 | ||
|
|
843300dec5 | ||
|
|
19ebdbf6a6 | ||
|
|
1508a5bb2c | ||
|
|
f4bf45d809 | ||
|
|
db4645fc65 | ||
|
|
7ef6c46aaf | ||
|
|
3514843818 | ||
|
|
5a80c71607 | ||
|
|
35e1120341 | ||
|
|
0143885a41 | ||
|
|
d57f06e3d8 | ||
|
|
a03a3d1d55 | ||
|
|
56928896b8 | ||
|
|
ca5eca9567 | ||
|
|
536cf2364d | ||
|
|
189ad71ac0 | ||
|
|
bc8435c736 | ||
|
|
658dde3b9f | ||
|
|
3bf062aa2d | ||
|
|
9bc918fa7b | ||
|
|
d2dee3d5a4 | ||
|
|
c389329878 | ||
|
|
9c88c4a164 | ||
|
|
bf46530c5a | ||
|
|
df4b4e6902 | ||
|
|
ab4be7357f | ||
|
|
29ada8b41a | ||
|
|
42f14e7c4d | ||
|
|
6b7e0676b9 | ||
|
|
36f1332181 | ||
|
|
ef38c58e5f | ||
|
|
e71f0b2f34 | ||
|
|
3cbc01e51f | ||
|
|
596f8701ab | ||
|
|
5a03642d50 | ||
|
|
7169b484b1 | ||
|
|
95e9dff362 | ||
|
|
48ca4dc880 | ||
|
|
1e77fb2630 | ||
|
|
17023457a9 | ||
|
|
eaa6e239f7 | ||
|
|
2a39f48deb | ||
|
|
941b31f90b | ||
|
|
a758f2370a | ||
|
|
72f2fe3399 | ||
|
|
fe80669639 | ||
|
|
1394dcba69 | ||
|
|
b6b3e2b914 | ||
|
|
3e54a83820 | ||
|
|
b9282f12b1 | ||
|
|
ed4aefc59e | ||
|
|
c697604224 | ||
|
|
13c1c11623 | ||
|
|
54b820773c | ||
|
|
dfe52a0de5 | ||
|
|
61b9ea24a8 | ||
|
|
c9495c33a7 | ||
|
|
2121961929 | ||
|
|
568dc57186 | ||
|
|
43e975b10d | ||
|
|
e7030b6b87 | ||
|
|
5a478514ee | ||
|
|
68d0253d64 | ||
|
|
86aa83e46f | ||
|
|
96f8d17f4f | ||
|
|
e47f0ca8f4 | ||
|
|
034febc8e3 | ||
|
|
2fffe65332 | ||
|
|
5b63c08c72 | ||
|
|
48acd0bf4d | ||
|
|
68f6a22d75 | ||
|
|
5d2dc481ef | ||
|
|
2b14eb5b4a | ||
|
|
b5b5d7bf84 | ||
|
|
6ff2a2e407 | ||
|
|
12f96dc321 | ||
|
|
2cd83d1b58 | ||
|
|
c2c82f60f8 | ||
|
|
af75a61f69 | ||
|
|
81c9d10596 | ||
|
|
db98d1a664 | ||
|
|
68d797e322 | ||
|
|
2d69c5d879 | ||
|
|
230ef2110b | ||
|
|
2fc81904c6 | ||
|
|
ff091efe7b | ||
|
|
7ea03d9ee2 | ||
|
|
a2555b39d7 | ||
|
|
2cc017981b | ||
|
|
886a4fb7f1 | ||
|
|
0e97374466 | ||
|
|
65bcb9b0ca | ||
|
|
44889af074 | ||
|
|
f7ed002f66 | ||
|
|
c6e54c4b1f | ||
|
|
415fc52b08 | ||
|
|
17302c0e23 | ||
|
|
73704e9ed5 | ||
|
|
1618b3c040 | ||
|
|
08899f2224 | ||
|
|
a0ac8fd214 |
@@ -0,0 +1 @@
|
||||
testdata/*.[0-9] linguist-documentation
|
||||
+76
-64
@@ -81,7 +81,7 @@ LINTFLAGS+=@NETBSD_LINTFLAGS@
|
||||
# compat with OpenBSD
|
||||
LINTFLAGS+="-Dsigset_t=long"
|
||||
# FreeBSD
|
||||
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list"
|
||||
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t"
|
||||
|
||||
INSTALL=$(SHELL) $(srcdir)/install-sh
|
||||
|
||||
@@ -101,7 +101,7 @@ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
|
||||
iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
|
||||
iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
|
||||
iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
|
||||
services/localzone.c services/mesh.c services/modstack.c \
|
||||
services/localzone.c services/mesh.c services/modstack.c services/view.c \
|
||||
services/outbound_list.c services/outside_network.c util/alloc.c \
|
||||
util/config_file.c util/configlexer.c util/configparser.c \
|
||||
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
||||
@@ -117,7 +117,7 @@ $(DNSTAP_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo \
|
||||
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
|
||||
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
|
||||
fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
||||
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
||||
@@ -228,7 +228,7 @@ SVCUNINST_OBJ_LINK=$(SVCUNINST_OBJ) w_inst.lo rsrc_svcuninst.o \
|
||||
$(COMPAT_OBJ_WITHOUT_CTIMEARC4)
|
||||
ANCHORUPD_SRC=winrc/anchor-update.c
|
||||
ANCHORUPD_OBJ=anchor-update.lo
|
||||
ANCHORUPD_OBJ_LINK=$(ANCHORUPD_OBJ) rsrc_anchorupd.o $(COMPAT_OBJ_WITHOUT_CTIMEARC4)
|
||||
ANCHORUPD_OBJ_LINK=$(ANCHORUPD_OBJ) rsrc_anchorupd.o $(COMPAT_OBJ_WITHOUT_CTIMEARC4) wire2str.lo str2wire.lo parseutil.lo sbuffer.lo rrdef.lo keyraw.lo parse.lo
|
||||
RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
|
||||
rsrc_unbound_host.o rsrc_unbound_anchor.o rsrc_unbound_control.o \
|
||||
rsrc_unbound_checkconf.o
|
||||
@@ -625,7 +625,8 @@ msgencode.lo msgencode.o: $(srcdir)/util/data/msgencode.c config.h $(srcdir)/uti
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/services/view.h
|
||||
msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
@@ -635,7 +636,9 @@ msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/d
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
|
||||
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
|
||||
@@ -704,25 +707,33 @@ listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h
|
||||
localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/as112.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/util/as112.h
|
||||
mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/services/view.h $(srcdir)/util/data/dname.h
|
||||
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
|
||||
$(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
|
||||
$(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER)
|
||||
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h
|
||||
outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/netevent.h
|
||||
@@ -759,15 +770,15 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
|
||||
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
|
||||
$(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
|
||||
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
|
||||
$(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
|
||||
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
|
||||
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/config_file.h $(PYTHONMOD_HEADER)
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
|
||||
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
|
||||
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
|
||||
@@ -777,7 +788,7 @@ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
|
||||
module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/ub_event.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
@@ -901,14 +912,7 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(src
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
|
||||
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \
|
||||
$(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/sldns/sbuffer.h
|
||||
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h
|
||||
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h
|
||||
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
|
||||
@@ -955,8 +959,11 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
|
||||
unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
|
||||
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -976,10 +983,10 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
|
||||
@@ -990,12 +997,12 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h
|
||||
$(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
|
||||
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
|
||||
$(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
|
||||
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -1023,8 +1030,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||
@@ -1052,8 +1059,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||
@@ -1062,8 +1069,11 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/libworker.h
|
||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
|
||||
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
@@ -1071,10 +1081,10 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -1122,7 +1132,7 @@ unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
|
||||
$(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
|
||||
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
@@ -1134,8 +1144,9 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/sldns/sbuffer.h
|
||||
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
@@ -1143,9 +1154,9 @@ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbou
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/sldns/sbuffer.h
|
||||
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
@@ -1153,11 +1164,12 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/li
|
||||
$(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/random.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h
|
||||
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
|
||||
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
@@ -1225,7 +1237,6 @@ snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c config.h
|
||||
strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
|
||||
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
|
||||
strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
|
||||
strsep.lo strsep.o: $(srcdir)/compat/strsep.c config.h
|
||||
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
|
||||
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
|
||||
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
|
||||
@@ -1237,3 +1248,4 @@ arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h $(srcdir)/util/l
|
||||
sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
|
||||
reallocarray.lo reallocarray.o: $(srcdir)/compat/reallocarray.c config.h
|
||||
isblank.lo isblank.o: $(srcdir)/compat/isblank.c config.h
|
||||
strsep.lo strsep.o: $(srcdir)/compat/strsep.c config.h
|
||||
|
||||
Vendored
+326
@@ -9044,3 +9044,329 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
|
||||
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
dnl serial 11 (pkg-config-0.29.1)
|
||||
dnl
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful, but
|
||||
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
dnl General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl As a special exception to the GNU General Public License, if you
|
||||
dnl distribute this file as part of a program that contains a
|
||||
dnl configuration script generated by Autoconf, you may include it under
|
||||
dnl the same distribution terms that you use for the rest of that
|
||||
dnl program.
|
||||
|
||||
dnl PKG_PREREQ(MIN-VERSION)
|
||||
dnl -----------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Verify that the version of the pkg-config macros are at least
|
||||
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
|
||||
dnl installed version of pkg-config, this checks the developer's version
|
||||
dnl of pkg.m4 when generating configure.
|
||||
dnl
|
||||
dnl To ensure that this macro is defined, also add:
|
||||
dnl m4_ifndef([PKG_PREREQ],
|
||||
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
|
||||
dnl
|
||||
dnl See the "Since" comment for each macro you use to see what version
|
||||
dnl of the macros you require.
|
||||
m4_defun([PKG_PREREQ],
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
|
||||
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
dnl ----------------------------------
|
||||
dnl Since: 0.16
|
||||
dnl
|
||||
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
|
||||
dnl first found in the path. Checks that the version of pkg-config found
|
||||
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
|
||||
dnl used since that's the first version where most current features of
|
||||
dnl pkg-config existed.
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])dnl PKG_PROG_PKG_CONFIG
|
||||
|
||||
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------------------------------
|
||||
dnl Since: 0.18
|
||||
dnl
|
||||
dnl Check to see whether a particular set of modules exists. Similar to
|
||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
dnl
|
||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
dnl only at the first occurence in configure.ac, so if the first place
|
||||
dnl it's called might be skipped (such as if it is within an "if", you
|
||||
dnl have to call PKG_CHECK_EXISTS manually
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
dnl ---------------------------------------------
|
||||
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
|
||||
dnl pkg_failed based on the result.
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])dnl _PKG_CONFIG
|
||||
|
||||
dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
dnl ---------------------------
|
||||
dnl Internal check to see if pkg-config supports short errors.
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])dnl _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl --------------------------------------------------------------
|
||||
dnl Since: 0.4.0
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
|
||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])dnl PKG_CHECK_MODULES
|
||||
|
||||
|
||||
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
dnl [ACTION-IF-NOT-FOUND])
|
||||
dnl ---------------------------------------------------------------------
|
||||
dnl Since: 0.29
|
||||
dnl
|
||||
dnl Checks for existence of MODULES and gathers its build flags with
|
||||
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
|
||||
dnl and VARIABLE-PREFIX_LIBS from --libs.
|
||||
dnl
|
||||
dnl Note that if there is a possibility the first call to
|
||||
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
|
||||
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
|
||||
dnl configure.ac.
|
||||
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
_save_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES($@)
|
||||
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
|
||||
])dnl PKG_CHECK_MODULES_STATIC
|
||||
|
||||
|
||||
dnl PKG_INSTALLDIR([DIRECTORY])
|
||||
dnl -------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable pkgconfigdir as the location where a module
|
||||
dnl should install pkg-config .pc files. By default the directory is
|
||||
dnl $libdir/pkgconfig, but the default can be changed by passing
|
||||
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
dnl parameter.
|
||||
AC_DEFUN([PKG_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
|
||||
[with_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
])dnl PKG_INSTALLDIR
|
||||
|
||||
|
||||
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
|
||||
dnl --------------------------------
|
||||
dnl Since: 0.27
|
||||
dnl
|
||||
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
dnl module should install arch-independent pkg-config .pc files. By
|
||||
dnl default the directory is $datadir/pkgconfig, but the default can be
|
||||
dnl changed by passing DIRECTORY. The user can override through the
|
||||
dnl --with-noarch-pkgconfigdir parameter.
|
||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([noarch-pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
|
||||
[with_noarch_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
])dnl PKG_NOARCH_INSTALLDIR
|
||||
|
||||
|
||||
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
dnl -------------------------------------------
|
||||
dnl Since: 0.28
|
||||
dnl
|
||||
dnl Retrieves the value of the pkg-config variable for the given module.
|
||||
AC_DEFUN([PKG_CHECK_VAR],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
||||
|
||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
||||
AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])dnl PKG_CHECK_VAR
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ([2.52])dnl
|
||||
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# --------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ $ac_distutils_result])
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print(get_config_var('BLDLIBRARY'));"`
|
||||
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
+18
-8
@@ -547,8 +547,8 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
return;
|
||||
}
|
||||
|
||||
if(qstate->blacklist) {
|
||||
/* cache is blacklisted */
|
||||
if(qstate->blacklist || qstate->no_cache_lookup) {
|
||||
/* cache is blacklisted or we are instructed from edns to not look */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
@@ -556,10 +556,15 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
|
||||
/* lookup inside unbound's internal cache */
|
||||
if(cachedb_intcache_lookup(qstate)) {
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("cachedb internal cache lookup",
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(qstate->return_msg->rep)
|
||||
log_dns_msg("cachedb internal cache lookup",
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
else log_info("cachedb internal cache lookup: rcode %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
@@ -595,8 +600,8 @@ static void
|
||||
cachedb_handle_response(struct module_qstate* qstate,
|
||||
struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
|
||||
{
|
||||
/* check if we are enabled, and skip if not */
|
||||
if(!ie->enabled) {
|
||||
/* check if we are not enabled or instructed to not cache, and skip */
|
||||
if(!ie->enabled || qstate->no_cache_store) {
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
@@ -649,6 +654,11 @@ cachedb_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
if(!iq && (event == module_event_moddone)) {
|
||||
/* during priming, module done but we never started */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
log_err("bad event for cachedb");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ void _ARC4_UNLOCK(void)
|
||||
}
|
||||
#else /* !THREADS_DISABLED */
|
||||
|
||||
static lock_quick_t arc4lock;
|
||||
static lock_quick_type arc4lock;
|
||||
static int arc4lockinit = 0;
|
||||
|
||||
void _ARC4_LOCK(void)
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define KEYSZ 32
|
||||
#define IVSZ 8
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "util/locks.h"
|
||||
|
||||
/** the lock for ctime buffer */
|
||||
static lock_basic_t ctime_lock;
|
||||
static lock_basic_type ctime_lock;
|
||||
/** has it been inited */
|
||||
static int ctime_r_init = 0;
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#include <sys/vfs.h>
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define REPEAT 5
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
+79
-3
@@ -51,6 +51,9 @@
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
|
||||
/* Define to 1 if you have the `ctime_r' function. */
|
||||
#undef HAVE_CTIME_R
|
||||
|
||||
@@ -65,6 +68,14 @@
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_NTOP
|
||||
|
||||
/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_INET_PTON
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
@@ -104,15 +115,27 @@
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `DSA_SIG_set0' function. */
|
||||
#undef HAVE_DSA_SIG_SET0
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#undef HAVE_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the `endprotoent' function. */
|
||||
#undef HAVE_ENDPROTOENT
|
||||
|
||||
/* Define to 1 if you have the `endpwent' function. */
|
||||
#undef HAVE_ENDPWENT
|
||||
|
||||
/* Define to 1 if you have the `endservent' function. */
|
||||
#undef HAVE_ENDSERVENT
|
||||
|
||||
/* Define to 1 if you have the `ERR_free_strings' function. */
|
||||
#undef HAVE_ERR_FREE_STRINGS
|
||||
|
||||
/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
|
||||
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
|
||||
/* Define to 1 if you have the `event_base_free' function. */
|
||||
#undef HAVE_EVENT_BASE_FREE
|
||||
|
||||
@@ -128,6 +151,12 @@
|
||||
/* Define to 1 if you have the <event.h> header file. */
|
||||
#undef HAVE_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the `EVP_cleanup' function. */
|
||||
#undef HAVE_EVP_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `EVP_dss1' function. */
|
||||
#undef HAVE_EVP_DSS1
|
||||
|
||||
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
|
||||
#undef HAVE_EVP_MD_CTX_NEW
|
||||
|
||||
@@ -254,24 +283,48 @@
|
||||
/* Use libnettle for crypto */
|
||||
#undef HAVE_NETTLE
|
||||
|
||||
/* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
|
||||
#undef HAVE_NETTLE_DSA_COMPAT_H
|
||||
|
||||
/* Use libnss for crypto */
|
||||
#undef HAVE_NSS
|
||||
|
||||
/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
|
||||
#undef HAVE_OPENSSL_ADD_ALL_DIGESTS
|
||||
|
||||
/* Define to 1 if you have the <openssl/bn.h> header file. */
|
||||
#undef HAVE_OPENSSL_BN_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_config' function. */
|
||||
#undef HAVE_OPENSSL_CONFIG
|
||||
|
||||
/* Define to 1 if you have the <openssl/conf.h> header file. */
|
||||
#undef HAVE_OPENSSL_CONF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/dh.h> header file. */
|
||||
#undef HAVE_OPENSSL_DH_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/dsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_DSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#undef HAVE_OPENSSL_ENGINE_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#undef HAVE_OPENSSL_ERR_H
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
|
||||
#undef HAVE_OPENSSL_INIT_CRYPTO
|
||||
|
||||
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
|
||||
#undef HAVE_OPENSSL_INIT_SSL
|
||||
|
||||
/* Define to 1 if you have the <openssl/rand.h> header file. */
|
||||
#undef HAVE_OPENSSL_RAND_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#undef HAVE_OPENSSL_RSA_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#undef HAVE_OPENSSL_SSL_H
|
||||
|
||||
@@ -296,15 +349,15 @@
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define to 1 if you have the `RAND_cleanup' function. */
|
||||
#undef HAVE_RAND_CLEANUP
|
||||
|
||||
/* Define to 1 if you have the `reallocarray' function. */
|
||||
#undef HAVE_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the `recvmsg' function. */
|
||||
#undef HAVE_RECVMSG
|
||||
|
||||
/* define if you have the sbrk() call */
|
||||
#undef HAVE_SBRK
|
||||
|
||||
/* Define to 1 if you have the `sendmsg' function. */
|
||||
#undef HAVE_SENDMSG
|
||||
|
||||
@@ -353,6 +406,9 @@
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
@@ -398,6 +454,9 @@
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if systemd should be used */
|
||||
#undef HAVE_SYSTEMD
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
@@ -610,6 +669,12 @@
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_MSG_FASTOPEN
|
||||
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
/* Define this to enable SHA256 and SHA512 support. */
|
||||
#undef USE_SHA2
|
||||
|
||||
@@ -635,6 +700,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define this to enable server TCP Fast Open. */
|
||||
#undef USE_TCP_FASTOPEN
|
||||
|
||||
/* Whether the windows socket API is used */
|
||||
#undef USE_WINSOCK
|
||||
|
||||
@@ -1004,6 +1072,14 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
struct tm;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.5.9.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.6.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
|
||||
#
|
||||
@@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.5.9'
|
||||
PACKAGE_STRING='unbound 1.5.9'
|
||||
PACKAGE_VERSION='1.6.1'
|
||||
PACKAGE_STRING='unbound 1.6.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -658,7 +658,17 @@ WIN_DAEMON_SRC
|
||||
WINAPPS
|
||||
WINDRES
|
||||
CHECKLOCK_OBJ
|
||||
USE_SYSTEMD_FALSE
|
||||
USE_SYSTEMD_TRUE
|
||||
SYSTEMD_DAEMON_LIBS
|
||||
SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
SYSTEMD_CFLAGS
|
||||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
staticexe
|
||||
PC_LIBEVENT_DEPENDENCY
|
||||
UNBOUND_EVENT_UNINSTALL
|
||||
UNBOUND_EVENT_INSTALL
|
||||
SSLLIB
|
||||
@@ -678,6 +688,7 @@ WITH_PYTHONMODULE
|
||||
swig
|
||||
SWIG_LIB
|
||||
SWIG
|
||||
PC_PY_DEPENDENCY
|
||||
PY_MAJOR_VERSION
|
||||
PYTHON_SITE_PKG
|
||||
PYTHON_LDFLAGS
|
||||
@@ -834,9 +845,12 @@ enable_gost
|
||||
enable_ecdsa
|
||||
enable_dsa
|
||||
enable_event_api
|
||||
enable_tfo_client
|
||||
enable_tfo_server
|
||||
with_libevent
|
||||
with_libexpat
|
||||
enable_static_exe
|
||||
enable_systemd
|
||||
enable_lock_checks
|
||||
enable_allsymbols
|
||||
enable_dnstap
|
||||
@@ -858,7 +872,14 @@ CPP
|
||||
YACC
|
||||
YFLAGS
|
||||
LT_SYS_LIBRARY_PATH
|
||||
PYTHON_VERSION'
|
||||
PYTHON_VERSION
|
||||
PKG_CONFIG
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG_LIBDIR
|
||||
SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_DAEMON_LIBS'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1399,7 +1420,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.5.9 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.6.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1464,7 +1485,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.5.9:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.6.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1500,8 +1521,11 @@ Optional Features:
|
||||
--disable-dsa Disable DSA support
|
||||
--enable-event-api Enable (experimental) pluggable event base
|
||||
libunbound API installed to unbound-event.h
|
||||
--enable-tfo-client Enable TCP Fast Open for client mode
|
||||
--enable-tfo-server Enable TCP Fast Open for server mode
|
||||
--enable-static-exe enable to compile executables statically against
|
||||
(event) libs, for debug purposes
|
||||
--enable-systemd compile with systemd support
|
||||
--enable-lock-checks enable to check lock and unlock calls, for debug
|
||||
purposes
|
||||
--enable-allsymbols export all symbols from libunbound and link binaries
|
||||
@@ -1585,6 +1609,19 @@ Some influential environment variables:
|
||||
The installed Python version to use, for example '2.3'. This
|
||||
string will be appended to the Python interpreter canonical
|
||||
name.
|
||||
PKG_CONFIG path to pkg-config utility
|
||||
PKG_CONFIG_PATH
|
||||
directories to add to pkg-config's search path
|
||||
PKG_CONFIG_LIBDIR
|
||||
path overriding pkg-config's built-in search path
|
||||
SYSTEMD_CFLAGS
|
||||
C compiler flags for SYSTEMD, overriding pkg-config
|
||||
SYSTEMD_LIBS
|
||||
linker flags for SYSTEMD, overriding pkg-config
|
||||
SYSTEMD_DAEMON_CFLAGS
|
||||
C compiler flags for SYSTEMD_DAEMON, overriding pkg-config
|
||||
SYSTEMD_DAEMON_LIBS
|
||||
linker flags for SYSTEMD_DAEMON, overriding pkg-config
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@@ -1652,7 +1689,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.5.9
|
||||
unbound configure 1.6.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2361,7 +2398,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.5.9, which was
|
||||
It was created by unbound $as_me 1.6.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2711,13 +2748,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=5
|
||||
UNBOUND_VERSION_MINOR=6
|
||||
|
||||
UNBOUND_VERSION_MICRO=9
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=6
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_REVISION=4
|
||||
LIBUNBOUND_AGE=4
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2766,6 +2803,9 @@ LIBUNBOUND_AGE=4
|
||||
# 1.5.7 had 5:10:3
|
||||
# 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
|
||||
# 1.5.9 had 6:1:4
|
||||
# 1.5.10 had 6:2:4
|
||||
# 1.6.0 had 6:3:4
|
||||
# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -4054,7 +4094,7 @@ esac
|
||||
# are we on MinGW?
|
||||
if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
|
||||
else
|
||||
if echo $target | grep mingw32 >/dev/null; then on_mingw="yes"
|
||||
if echo $host $target | grep mingw32 >/dev/null; then on_mingw="yes"
|
||||
else on_mingw="no"; fi
|
||||
fi
|
||||
|
||||
@@ -4064,7 +4104,7 @@ fi
|
||||
if test $on_mingw = "no"; then
|
||||
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
|
||||
else
|
||||
ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
|
||||
ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
|
||||
fi
|
||||
|
||||
# Check whether --with-conf_file was given.
|
||||
@@ -4195,7 +4235,7 @@ else
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
|
||||
else
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -4217,7 +4257,7 @@ else
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
|
||||
else
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
|
||||
fi
|
||||
|
||||
fi
|
||||
@@ -16714,7 +16754,7 @@ $as_echo "$PYTHON_CPPFLAGS" >&6; }
|
||||
$as_echo_n "checking for Python library path... " >&6; }
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print(get_config_var('BLDLIBRARY'));"`
|
||||
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5
|
||||
$as_echo "$PYTHON_LDFLAGS" >&6; }
|
||||
@@ -16818,6 +16858,8 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
|
||||
LIBS="$PYTHON_LDFLAGS $LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
ub_have_python=yes
|
||||
PC_PY_DEPENDENCY="python"
|
||||
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
@@ -17033,6 +17075,19 @@ if test "${with_nettle+set}" = set; then :
|
||||
|
||||
$as_echo "#define HAVE_NETTLE 1" >>confdefs.h
|
||||
|
||||
for ac_header in nettle/dsa-compat.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "nettle/dsa-compat.h" "ac_cv_header_nettle_dsa_compat_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_nettle_dsa_compat_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_NETTLE_DSA_COMPAT_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
@@ -17397,6 +17452,47 @@ fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
SSLLIB="-lssl"
|
||||
|
||||
# check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if libssl needs -lcrypt32" >&5
|
||||
$as_echo_n "checking if libssl needs -lcrypt32... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char HMAC_Update ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return HMAC_Update ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
else
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
LIBS="$BAKLIBS"
|
||||
LIBS="$LIBS -lcrypt32"
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LibreSSL" >&5
|
||||
$as_echo_n "checking for LibreSSL... " >&6; }
|
||||
if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/null; then
|
||||
@@ -17462,33 +17558,21 @@ else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
for ac_header in openssl/conf.h
|
||||
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "openssl/conf.h" "ac_cv_header_openssl_conf_h" "$ac_includes_default
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_openssl_conf_h" = xyes; then :
|
||||
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_OPENSSL_CONF_H 1
|
||||
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in openssl/engine.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_openssl_engine_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_OPENSSL_ENGINE_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new
|
||||
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@@ -17500,6 +17584,24 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
done
|
||||
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "SSL_COMP_get_compression_methods" "ac_cv_have_decl_SSL_COMP_get_compression_methods" "
|
||||
$ac_includes_default
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
@@ -17861,13 +17963,13 @@ if test "${enable_dsa+set}" = set; then :
|
||||
fi
|
||||
|
||||
use_dsa="no"
|
||||
case "$enable_ecdsa" in
|
||||
case "$enable_dsa" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
# detect if DSA is supported, and turn it off if not.
|
||||
ac_fn_c_check_func "$LINENO" "EVP_dss1" "ac_cv_func_EVP_dss1"
|
||||
if test "x$ac_cv_func_EVP_dss1" = xyes; then :
|
||||
ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
|
||||
if test "x$ac_cv_func_DSA_SIG_new" = xyes; then :
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@@ -17900,6 +18002,82 @@ case "$enable_event_api" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-tfo-client was given.
|
||||
if test "${enable_tfo_client+set}" = set; then :
|
||||
enableval=$enable_tfo_client;
|
||||
fi
|
||||
|
||||
case "$enable_tfo_client" in
|
||||
yes)
|
||||
case `uname` in
|
||||
Linux) ac_fn_c_check_decl "$LINENO" "MSG_FASTOPEN" "ac_cv_have_decl_MSG_FASTOPEN" "$ac_includes_default
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_MSG_FASTOPEN" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO" >&5
|
||||
$as_echo "$as_me: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO" >&2;}
|
||||
else
|
||||
as_fn_error $? "TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_MSG_FASTOPEN 1
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
Darwin) ac_fn_c_check_decl "$LINENO" "CONNECT_RESUME_ON_READ_WRITE" "ac_cv_have_decl_CONNECT_RESUME_ON_READ_WRITE" "$ac_includes_default
|
||||
#include <sys/socket.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_CONNECT_RESUME_ON_READ_WRITE" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO" >&5
|
||||
$as_echo "$as_me: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO" >&2;}
|
||||
else
|
||||
as_fn_error $? "TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_OSX_MSG_FASTOPEN 1
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-tfo-server was given.
|
||||
if test "${enable_tfo_server+set}" = set; then :
|
||||
enableval=$enable_tfo_server;
|
||||
fi
|
||||
|
||||
case "$enable_tfo_server" in
|
||||
yes)
|
||||
ac_fn_c_check_decl "$LINENO" "TCP_FASTOPEN" "ac_cv_have_decl_TCP_FASTOPEN" "$ac_includes_default
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_TCP_FASTOPEN" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support server mode TFO" >&5
|
||||
$as_echo "$as_me: WARNING: Check the platform specific TFO kernel parameters are correctly configured to support server mode TFO" >&2;}
|
||||
else
|
||||
as_fn_error $? "TCP Fast Open is not available for server mode: please rerun without --enable-tfo-server" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_TCP_FASTOPEN 1
|
||||
_ACEOF
|
||||
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for libevent
|
||||
|
||||
# Check whether --with-libevent was given.
|
||||
@@ -18238,6 +18416,8 @@ _ACEOF
|
||||
fi
|
||||
done
|
||||
# only in libev. (tested on 4.00)
|
||||
PC_LIBEVENT_DEPENDENCY="libevent"
|
||||
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
LDFLAGS="$BAK_LDFLAGS"
|
||||
fi
|
||||
@@ -18314,13 +18494,322 @@ if test x_$enable_static_exe = x_yes; then
|
||||
staticexe="-static"
|
||||
if test "$on_mingw" = yes; then
|
||||
staticexe="-all-static"
|
||||
# for static crosscompile, include gdi32 and zlib here.
|
||||
if test "`uname`" = "Linux"; then
|
||||
LIBS="$LIBS -lgdi32 -lz"
|
||||
fi
|
||||
# for static compile, include gdi32 and zlib here.
|
||||
LIBS="$LIBS -lgdi32 -lz"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Include systemd.m4 - begin
|
||||
# macros for configuring systemd
|
||||
# Copyright 2015, Sami Kerola, CloudFlare.
|
||||
# BSD licensed.
|
||||
# Check whether --enable-systemd was given.
|
||||
if test "${enable_systemd+set}" = set; then :
|
||||
enableval=$enable_systemd;
|
||||
else
|
||||
enable_systemd=no
|
||||
fi
|
||||
|
||||
have_systemd=no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
|
||||
$as_echo "$PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_PKG_CONFIG"; then
|
||||
ac_pt_PKG_CONFIG=$PKG_CONFIG
|
||||
# Extract the first word of "pkg-config", so it can be a program name with args.
|
||||
set dummy pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
|
||||
if test -n "$ac_pt_PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
|
||||
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_PKG_CONFIG" = x; then
|
||||
PKG_CONFIG=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
PKG_CONFIG=$ac_pt_PKG_CONFIG
|
||||
fi
|
||||
else
|
||||
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
|
||||
fi
|
||||
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=0.9.0
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
|
||||
$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_systemd" != xno; then :
|
||||
|
||||
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
|
||||
$as_echo_n "checking for SYSTEMD... " >&6; }
|
||||
|
||||
if test -n "$SYSTEMD_CFLAGS"; then
|
||||
pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$SYSTEMD_LIBS"; then
|
||||
pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
|
||||
else
|
||||
SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd=no
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
have_systemd=no
|
||||
else
|
||||
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
have_systemd=yes
|
||||
fi
|
||||
if test "x$have_systemd" != "xyes"; then :
|
||||
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
|
||||
$as_echo_n "checking for SYSTEMD_DAEMON... " >&6; }
|
||||
|
||||
if test -n "$SYSTEMD_DAEMON_CFLAGS"; then
|
||||
pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_SYSTEMD_DAEMON_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
if test -n "$SYSTEMD_DAEMON_LIBS"; then
|
||||
pkg_cv_SYSTEMD_DAEMON_LIBS="$SYSTEMD_DAEMON_LIBS"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
pkg_cv_SYSTEMD_DAEMON_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes
|
||||
else
|
||||
pkg_failed=yes
|
||||
fi
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
|
||||
else
|
||||
SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd_daemon=no
|
||||
elif test $pkg_failed = untried; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
have_systemd_daemon=no
|
||||
else
|
||||
SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
have_systemd_daemon=yes
|
||||
fi
|
||||
if test "x$have_systemd_daemon" = "xyes"; then :
|
||||
have_systemd=yes
|
||||
fi
|
||||
|
||||
fi
|
||||
case $enable_systemd:$have_systemd in #(
|
||||
yes:no) :
|
||||
as_fn_error $? "systemd enabled but libsystemd not found" "$LINENO" 5 ;; #(
|
||||
*:yes) :
|
||||
|
||||
$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
|
||||
|
||||
LIBS="$LIBS $SYSTEMD_LIBS"
|
||||
|
||||
;; #(
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
fi
|
||||
if test "x$have_systemd" = xyes; then
|
||||
USE_SYSTEMD_TRUE=
|
||||
USE_SYSTEMD_FALSE='#'
|
||||
else
|
||||
USE_SYSTEMD_TRUE='#'
|
||||
USE_SYSTEMD_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
# Include systemd.m4 - end
|
||||
|
||||
# set lock checking if requested
|
||||
# Check whether --enable-lock_checks was given.
|
||||
if test "${enable_lock_checks+set}" = set; then :
|
||||
@@ -18762,7 +19251,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@@ -18821,39 +19310,77 @@ fi
|
||||
done
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sbrk" >&5
|
||||
$as_echo_n "checking for sbrk... " >&6; }
|
||||
# catch the warning of deprecated sbrk
|
||||
old_cflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
|
||||
int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; }
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
|
||||
$as_echo "#define HAVE_SBRK 1" >>confdefs.h
|
||||
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
CFLAGS="$old_cflags"
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
|
||||
$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" "
|
||||
$ac_includes_default
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_inet_pton" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_INET_PTON $ac_have_decl
|
||||
_ACEOF
|
||||
ac_fn_c_check_decl "$LINENO" "inet_ntop" "ac_cv_have_decl_inet_ntop" "
|
||||
$ac_includes_default
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_inet_ntop" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_INET_NTOP $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton"
|
||||
if test "x$ac_cv_func_inet_aton" = xyes; then :
|
||||
$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
|
||||
@@ -19098,8 +19625,8 @@ else
|
||||
esac
|
||||
|
||||
else
|
||||
case `uname` in
|
||||
Darwin)
|
||||
case "$host" in
|
||||
Darwin|*darwin*)
|
||||
case " $LIBOBJS " in
|
||||
*" getentropy_osx.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext"
|
||||
@@ -19107,7 +19634,7 @@ esac
|
||||
esac
|
||||
|
||||
;;
|
||||
SunOS)
|
||||
*solaris*|*sunos*|SunOS)
|
||||
case " $LIBOBJS " in
|
||||
*" getentropy_solaris.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext"
|
||||
@@ -19211,7 +19738,7 @@ if test "$ac_res" != no; then :
|
||||
fi
|
||||
|
||||
;;
|
||||
Linux|*)
|
||||
*linux*|Linux|*)
|
||||
case " $LIBOBJS " in
|
||||
*" getentropy_linux.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS getentropy_linux.$ac_objext"
|
||||
@@ -19801,12 +20328,12 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.5.9
|
||||
version=1.6.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h"
|
||||
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service"
|
||||
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
@@ -19919,6 +20446,10 @@ LIBOBJS=$ac_libobjs
|
||||
LTLIBOBJS=$ac_ltlibobjs
|
||||
|
||||
|
||||
if test -z "${USE_SYSTEMD_TRUE}" && test -z "${USE_SYSTEMD_FALSE}"; then
|
||||
as_fn_error $? "conditional \"USE_SYSTEMD\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
|
||||
: "${CONFIG_STATUS=./config.status}"
|
||||
ac_write_fail=0
|
||||
@@ -20316,7 +20847,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.5.9, which was
|
||||
This file was extended by unbound $as_me 1.6.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -20382,7 +20913,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.5.9
|
||||
unbound config.status 1.6.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@@ -20804,6 +21335,9 @@ do
|
||||
"doc/unbound-host.1") CONFIG_FILES="$CONFIG_FILES doc/unbound-host.1" ;;
|
||||
"smallapp/unbound-control-setup.sh") CONFIG_FILES="$CONFIG_FILES smallapp/unbound-control-setup.sh" ;;
|
||||
"dnstap/dnstap_config.h") CONFIG_FILES="$CONFIG_FILES dnstap/dnstap_config.h" ;;
|
||||
"contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;;
|
||||
"contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;;
|
||||
"contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;;
|
||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
|
||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||
|
||||
+118
-35
@@ -9,15 +9,15 @@ sinclude(dnstap/dnstap.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[5])
|
||||
m4_define([VERSION_MICRO],[9])
|
||||
m4_define([VERSION_MINOR],[6])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=6
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_REVISION=4
|
||||
LIBUNBOUND_AGE=4
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -66,6 +66,9 @@ LIBUNBOUND_AGE=4
|
||||
# 1.5.7 had 5:10:3
|
||||
# 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
|
||||
# 1.5.9 had 6:1:4
|
||||
# 1.5.10 had 6:2:4
|
||||
# 1.6.0 had 6:3:4
|
||||
# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -107,7 +110,7 @@ esac
|
||||
# are we on MinGW?
|
||||
if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
|
||||
else
|
||||
if echo $target | grep mingw32 >/dev/null; then on_mingw="yes"
|
||||
if echo $host $target | grep mingw32 >/dev/null; then on_mingw="yes"
|
||||
else on_mingw="no"; fi
|
||||
fi
|
||||
|
||||
@@ -117,7 +120,7 @@ fi
|
||||
if test $on_mingw = "no"; then
|
||||
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
|
||||
else
|
||||
ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
|
||||
ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
|
||||
fi
|
||||
AC_ARG_WITH([conf_file],
|
||||
AC_HELP_STRING([--with-conf-file=path],
|
||||
@@ -187,7 +190,7 @@ AC_ARG_WITH(rootkey-file,
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
|
||||
else
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTKEY_FILE)
|
||||
@@ -201,7 +204,7 @@ AC_ARG_WITH(rootcert-file,
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
|
||||
else
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTCERT_FILE)
|
||||
@@ -542,6 +545,8 @@ if test x_$ub_test_python != x_no; then
|
||||
LIBS="$PYTHON_LDFLAGS $LIBS"
|
||||
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
ub_have_python=yes
|
||||
PC_PY_DEPENDENCY="python"
|
||||
AC_SUBST(PC_PY_DEPENDENCY)
|
||||
|
||||
# Check for SWIG
|
||||
ub_have_swig=no
|
||||
@@ -629,6 +634,7 @@ AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path],
|
||||
[
|
||||
USE_NETTLE="yes"
|
||||
AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto])
|
||||
AC_CHECK_HEADERS([nettle/dsa-compat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
if test "$withval" != "" -a "$withval" != "yes"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
@@ -646,6 +652,20 @@ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ACX_WITH_SSL
|
||||
ACX_LIB_SSL
|
||||
SSLLIB="-lssl"
|
||||
|
||||
# check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_MSG_CHECKING([if libssl needs -lcrypt32])
|
||||
AC_TRY_LINK_FUNC([HMAC_Update], [
|
||||
AC_MSG_RESULT([no])
|
||||
LIBS="$BAKLIBS"
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
LIBS="$BAKLIBS"
|
||||
LIBS="$LIBS -lcrypt32"
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for LibreSSL])
|
||||
if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/null; then
|
||||
AC_MSG_RESULT([yes])
|
||||
@@ -656,9 +676,15 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new])
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
@@ -842,12 +868,12 @@ esac
|
||||
|
||||
AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
|
||||
use_dsa="no"
|
||||
case "$enable_ecdsa" in
|
||||
case "$enable_dsa" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
# detect if DSA is supported, and turn it off if not.
|
||||
AC_CHECK_FUNC(EVP_dss1, [
|
||||
AC_CHECK_FUNC(DSA_SIG_new, [
|
||||
AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
|
||||
], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
|
||||
fi ])
|
||||
@@ -865,6 +891,42 @@ case "$enable_event_api" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(tfo-client, AC_HELP_STRING([--enable-tfo-client], [Enable TCP Fast Open for client mode]))
|
||||
case "$enable_tfo_client" in
|
||||
yes)
|
||||
case `uname` in
|
||||
Linux) AC_CHECK_DECL([MSG_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
|
||||
[AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <netinet/tcp.h>
|
||||
])
|
||||
AC_DEFINE_UNQUOTED([USE_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
|
||||
;;
|
||||
Darwin) AC_CHECK_DECL([CONNECT_RESUME_ON_READ_WRITE], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support client mode TFO])],
|
||||
[AC_MSG_ERROR([TCP Fast Open is not available for client mode: please rerun without --enable-tfo-client])],
|
||||
[AC_INCLUDES_DEFAULT
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
AC_DEFINE_UNQUOTED([USE_OSX_MSG_FASTOPEN], [1], [Define this to enable client TCP Fast Open.])
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(tfo-server, AC_HELP_STRING([--enable-tfo-server], [Enable TCP Fast Open for server mode]))
|
||||
case "$enable_tfo_server" in
|
||||
yes)
|
||||
AC_CHECK_DECL([TCP_FASTOPEN], [AC_MSG_WARN([Check the platform specific TFO kernel parameters are correctly configured to support server mode TFO])], [AC_MSG_ERROR([TCP Fast Open is not available for server mode: please rerun without --enable-tfo-server])], [AC_INCLUDES_DEFAULT
|
||||
#include <netinet/tcp.h>
|
||||
])
|
||||
AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable server TCP Fast Open.])
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for libevent
|
||||
AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
|
||||
[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
|
||||
@@ -942,6 +1004,8 @@ large outgoing port ranges. ])
|
||||
AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
|
||||
AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
|
||||
AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
|
||||
PC_LIBEVENT_DEPENDENCY="libevent"
|
||||
AC_SUBST(PC_LIBEVENT_DEPENDENCY)
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
LDFLAGS="$BAK_LDFLAGS"
|
||||
fi
|
||||
@@ -985,13 +1049,15 @@ if test x_$enable_static_exe = x_yes; then
|
||||
staticexe="-static"
|
||||
if test "$on_mingw" = yes; then
|
||||
staticexe="-all-static"
|
||||
# for static crosscompile, include gdi32 and zlib here.
|
||||
if test "`uname`" = "Linux"; then
|
||||
LIBS="$LIBS -lgdi32 -lz"
|
||||
fi
|
||||
# for static compile, include gdi32 and zlib here.
|
||||
LIBS="$LIBS -lgdi32 -lz"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Include systemd.m4 - begin
|
||||
sinclude(systemd.m4)
|
||||
# Include systemd.m4 - end
|
||||
|
||||
# set lock checking if requested
|
||||
AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
|
||||
[ enable to check lock and unlock calls, for debug purposes ]),
|
||||
@@ -1082,27 +1148,36 @@ AC_INCLUDES_DEFAULT
|
||||
#endif
|
||||
])
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
AC_MSG_CHECKING([for sbrk])
|
||||
# catch the warning of deprecated sbrk
|
||||
old_cflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
|
||||
[[
|
||||
int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; }
|
||||
]])], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SBRK, 1, [define if you have the sbrk() call])
|
||||
], [AC_MSG_RESULT(no)])
|
||||
CFLAGS="$old_cflags"
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
|
||||
fi
|
||||
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
AC_REPLACE_FUNCS(inet_aton)
|
||||
AC_REPLACE_FUNCS(inet_pton)
|
||||
AC_REPLACE_FUNCS(inet_ntop)
|
||||
@@ -1140,11 +1215,11 @@ if test "$USE_NSS" = "no"; then
|
||||
if test "$USE_WINSOCK" = 1; then
|
||||
AC_LIBOBJ(getentropy_win)
|
||||
else
|
||||
case `uname` in
|
||||
Darwin)
|
||||
case "$host" in
|
||||
Darwin|*darwin*)
|
||||
AC_LIBOBJ(getentropy_osx)
|
||||
;;
|
||||
SunOS)
|
||||
*solaris*|*sunos*|SunOS)
|
||||
AC_LIBOBJ(getentropy_solaris)
|
||||
AC_CHECK_HEADERS([sys/sha2.h],, [
|
||||
AC_CHECK_FUNCS([SHA512_Update],,[
|
||||
@@ -1157,7 +1232,7 @@ if test "$USE_NSS" = "no"; then
|
||||
fi
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
;;
|
||||
Linux|*)
|
||||
*linux*|Linux|*)
|
||||
AC_LIBOBJ(getentropy_linux)
|
||||
AC_CHECK_FUNCS([SHA512_Update],,[
|
||||
AC_DEFINE([COMPAT_SHA512], [1], [Do sha512 definitions in config.h])
|
||||
@@ -1415,6 +1490,14 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
struct tm;
|
||||
@@ -1523,6 +1606,6 @@ dnl if this is a distro tarball, that was already done by makedist.sh
|
||||
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
|
||||
AC_SUBST(date, [`date +'%b %e, %Y'`])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -29,3 +29,5 @@ distribution but may be helpful.
|
||||
Patch from Stephane Lapie for ASAHI Net.
|
||||
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
|
||||
Contributed by Yuri Voinov.
|
||||
* unbound.socket and unbound.service: systemd files for unbound, install them
|
||||
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
@@ -0,0 +1,8 @@
|
||||
[Service]
|
||||
Type=notify
|
||||
NotifyAccess=main
|
||||
ExecStart=/home/vagrant/unbound_systemd/unbound
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,6 @@
|
||||
[Socket]
|
||||
ListenDatagram=127.0.0.1:1153
|
||||
ListenStream=127.0.0.1:1153
|
||||
# ListenStream=@UNBOUND_RUN_DIR@/control
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
+1
-16
@@ -150,7 +150,7 @@ get_state ( ) {
|
||||
fi
|
||||
done
|
||||
# try to get it
|
||||
echo $$ >$lock
|
||||
if echo $$ >$lock ; then : ; else break; fi
|
||||
done
|
||||
# do not refetch if the file exists and only LEE seconds old
|
||||
if test -f $state; then
|
||||
@@ -266,7 +266,6 @@ if test "$1" = "config" ; then
|
||||
echo "graph_args --base 1024 -l 0"
|
||||
echo "graph_vlabel memory used in bytes"
|
||||
echo "graph_category DNS"
|
||||
p_config "mem.total.sbrk" "Total memory" "GAUGE"
|
||||
p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
|
||||
p_config "mem.cache.message" "Message cache memory" "GAUGE"
|
||||
p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
|
||||
@@ -458,20 +457,6 @@ queue)
|
||||
done
|
||||
;;
|
||||
memory)
|
||||
mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
|
||||
get_value 'mem.total.sbrk'
|
||||
if test $value -eq 0; then
|
||||
chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
|
||||
pidf=`$chk -o pidfile $conf 2>&1`
|
||||
pid=`cat $pidf 2>&1`
|
||||
value=`ps -p "$pid" -o rss= 2>&1`
|
||||
if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
|
||||
value=`expr $value \* 1024`
|
||||
else
|
||||
value=0
|
||||
fi
|
||||
fi
|
||||
echo "$mn.value" $value
|
||||
for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
|
||||
mem.mod.validator msg.cache.count rrset.cache.count \
|
||||
infra.cache.count key.cache.count; do
|
||||
|
||||
+316
-9
@@ -45,6 +45,8 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
struct acl_list*
|
||||
acl_list_create(void)
|
||||
@@ -71,21 +73,21 @@ acl_list_delete(struct acl_list* acl)
|
||||
}
|
||||
|
||||
/** insert new address into acl_list structure */
|
||||
static int
|
||||
static struct acl_addr*
|
||||
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum acl_access control,
|
||||
int complain_duplicates)
|
||||
{
|
||||
struct acl_addr* node = regional_alloc(acl->region,
|
||||
struct acl_addr* node = regional_alloc_zero(acl->region,
|
||||
sizeof(struct acl_addr));
|
||||
if(!node)
|
||||
return 0;
|
||||
return NULL;
|
||||
node->control = control;
|
||||
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
|
||||
if(complain_duplicates)
|
||||
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
||||
}
|
||||
return 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
/** apply acl_list string */
|
||||
@@ -125,6 +127,205 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** find or create node (NULL on parse or error) */
|
||||
static struct acl_addr*
|
||||
acl_find_or_create(struct acl_list* acl, const char* str)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
struct sockaddr_storage addr;
|
||||
int net;
|
||||
socklen_t addrlen;
|
||||
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||
log_err("cannot parse netblock: %s", str);
|
||||
return NULL;
|
||||
}
|
||||
/* find or create node */
|
||||
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
||||
addrlen, net))) {
|
||||
/* create node, type 'allow' since otherwise tags are
|
||||
* pointless, can override with specific access-control: cfg */
|
||||
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
|
||||
addrlen, net, acl_allow, 1))) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/** apply acl_tag string */
|
||||
static int
|
||||
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||
size_t bitmaplen)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->taglen = bitmaplen;
|
||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||
if(!node->taglist) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_view string */
|
||||
static int
|
||||
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
||||
struct views* vs)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||
if(!node->view) {
|
||||
log_err("no view with name: %s", str2);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&node->view->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_tag_action string */
|
||||
static int
|
||||
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
const char* str, const char* tag, const char* action)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
enum localzone_type t;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_actions) {
|
||||
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
||||
sizeof(*node->tag_actions)*cfg->num_tags);
|
||||
if(!node->tag_actions) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_actions_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if(!local_zone_str2type(action, &t)) {
|
||||
log_err("cannot parse access control action type: %s %s %s",
|
||||
str, tag, action);
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions[tagid] = (uint8_t)t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check wire data parse */
|
||||
static int
|
||||
check_data(const char* data, const struct config_strlist* head)
|
||||
{
|
||||
char buf[65536];
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t len = sizeof(rr);
|
||||
int res;
|
||||
/* '.' is sufficient for validation, and it makes the call to
|
||||
* sldns_wirerr_get_type() simpler below. */
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", data);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0,
|
||||
NULL, 0);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for the same tag. */
|
||||
if(res == 0 && head) {
|
||||
const char* err_data = NULL;
|
||||
|
||||
if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) {
|
||||
/* adding CNAME while other data already exists. */
|
||||
err_data = data;
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", head->str);
|
||||
len = sizeof(rr);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
if(res != 0) {
|
||||
/* This should be impossible here as head->str
|
||||
* has been validated, but we check it just in
|
||||
* case. */
|
||||
return 0;
|
||||
}
|
||||
if(sldns_wirerr_get_type(rr, len, 1) ==
|
||||
LDNS_RR_TYPE_CNAME) /* already have CNAME */
|
||||
err_data = head->str;
|
||||
}
|
||||
if(err_data) {
|
||||
log_err("redirect tag data '%s' must not coexist with "
|
||||
"other data.", err_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(res == 0)
|
||||
return 1;
|
||||
log_err("rr data [char %d] parse error %s",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-13,
|
||||
sldns_get_errorstr_parse(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** apply acl_tag_data string */
|
||||
static int
|
||||
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
const char* str, const char* tag, const char* data)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
char* dupdata;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_datas) {
|
||||
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
||||
acl->region, sizeof(*node->tag_datas)*cfg->num_tags);
|
||||
if(!node->tag_datas) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_datas_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_datas_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check data? */
|
||||
if(!check_data(data, node->tag_datas[tagid])) {
|
||||
log_err("cannot parse access-control-tag data: %s %s '%s'",
|
||||
str, tag, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dupdata = regional_strdup(acl->region, data);
|
||||
if(!dupdata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!cfg_region_strlist_insert(acl->region,
|
||||
&(node->tag_datas[tagid]), dupdata)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl_list config */
|
||||
static int
|
||||
read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
@@ -138,13 +339,114 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tags config */
|
||||
static int
|
||||
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_strbytelist* np, *p = cfg->acl_tags;
|
||||
cfg->acl_tags = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
|
||||
config_del_strbytelist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl view config */
|
||||
static int
|
||||
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
||||
{
|
||||
struct config_str2list* np, *p = cfg->acl_view;
|
||||
cfg->acl_view = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tag actions config */
|
||||
static int
|
||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = cfg->acl_tag_actions;
|
||||
cfg->acl_tag_actions = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
|
||||
p->str3)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p->str3);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tag datas config */
|
||||
static int
|
||||
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = cfg->acl_tag_datas;
|
||||
cfg->acl_tag_datas = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p->str3);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v)
|
||||
{
|
||||
regional_free_all(acl->region);
|
||||
addr_tree_init(&acl->tree);
|
||||
if(!read_acl_list(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_view(acl, cfg, v))
|
||||
return 0;
|
||||
if(!read_acl_tags(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_actions(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_datas(acl, cfg))
|
||||
return 0;
|
||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
||||
return 0;
|
||||
@@ -163,13 +465,18 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
}
|
||||
|
||||
enum acl_access
|
||||
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
acl_get_control(struct acl_addr* acl)
|
||||
{
|
||||
if(acl) return acl->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
return (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
addr, addrlen);
|
||||
if(r) return r->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
+32
-6
@@ -43,6 +43,7 @@
|
||||
#ifndef DAEMON_ACL_LIST_H
|
||||
#define DAEMON_ACL_LIST_H
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "services/view.h"
|
||||
struct config_file;
|
||||
struct regional;
|
||||
|
||||
@@ -75,7 +76,7 @@ struct acl_list {
|
||||
* Tree of the addresses that are allowed/blocked.
|
||||
* contents of type acl_addr.
|
||||
*/
|
||||
rbtree_t tree;
|
||||
rbtree_type tree;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,6 +88,21 @@ struct acl_addr {
|
||||
struct addr_tree_node node;
|
||||
/** access control on this netblock */
|
||||
enum acl_access control;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** array per tagnumber of localzonetype(in one byte). NULL if none. */
|
||||
uint8_t* tag_actions;
|
||||
/** size of the tag_actions_array */
|
||||
size_t tag_actions_size;
|
||||
/** array per tagnumber, with per tag a list of rdata strings.
|
||||
* NULL if none. strings are like 'A 127.0.0.1' 'AAAA ::1' */
|
||||
struct config_strlist** tag_datas;
|
||||
/** size of the tag_datas array */
|
||||
size_t tag_datas_size;
|
||||
/* view element, NULL if none */
|
||||
struct view* view;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -105,19 +121,29 @@ void acl_list_delete(struct acl_list* acl);
|
||||
* Process access control config.
|
||||
* @param acl: where to store.
|
||||
* @param cfg: config options.
|
||||
* @param v: views structure
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v);
|
||||
|
||||
/**
|
||||
* Lookup address to see its access control status.
|
||||
* Lookup access control status for acl structure.
|
||||
* @param acl: structure for acl storage.
|
||||
* @return: what to do with message from this address.
|
||||
*/
|
||||
enum acl_access acl_get_control(struct acl_addr* acl);
|
||||
|
||||
/**
|
||||
* Lookup address to see its acl structure
|
||||
* @param acl: structure for address storage.
|
||||
* @param addr: address to check
|
||||
* @param addrlen: length of addr.
|
||||
* @return: what to do with message from this address.
|
||||
* @return: acl structure from this address.
|
||||
*/
|
||||
enum acl_access acl_list_lookup(struct acl_list* acl,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Get memory used by acl structure.
|
||||
|
||||
@@ -563,6 +563,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
qinfo->qname_len = dname_len;
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
|
||||
qinfo->local_alias = NULL;
|
||||
if(!qinfo->qname) {
|
||||
log_warn("error out of memory");
|
||||
return NULL;
|
||||
@@ -826,6 +827,7 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
qinfo.qname_len = nmlen;
|
||||
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||
qinfo.qclass = LDNS_RR_CLASS_IN;
|
||||
qinfo.local_alias = NULL;
|
||||
|
||||
dname_str(nm, b);
|
||||
if(!ssl_printf(ssl, "The following name servers are used for lookup "
|
||||
|
||||
+59
-5
@@ -79,6 +79,7 @@
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "services/modstack.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
@@ -87,6 +88,10 @@
|
||||
#include "sldns/keyraw.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
/** How many quit requests happened. */
|
||||
static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
@@ -174,8 +179,15 @@ static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
if(sig_record_reload)
|
||||
if(sig_record_reload) {
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "RELOADING=1");
|
||||
# endif
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
@@ -204,17 +216,29 @@ daemon_init(void)
|
||||
signal_handling_record();
|
||||
checklock_start();
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
# endif
|
||||
ERR_load_SSL_strings();
|
||||
# ifdef USE_GOST
|
||||
(void)sldns_key_EVP_load_gost_id();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
# else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/* grab the COMP method ptr because openssl leaks it */
|
||||
comp_meth = (void*)SSL_COMP_get_compression_methods();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
# else
|
||||
(void)OPENSSL_init_ssl(0, NULL);
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
if(!ub_openssl_lock_init())
|
||||
fatal_exit("could not init openssl locks");
|
||||
@@ -236,9 +260,16 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
/* init edns_known_options */
|
||||
if(!edns_known_options_init(daemon->env)) {
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
alloc_init(&daemon->superalloc, NULL, 0);
|
||||
daemon->acl = acl_list_create();
|
||||
if(!daemon->acl) {
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
@@ -335,6 +366,7 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
}
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,6 +436,8 @@ daemon_create_workers(struct daemon* daemon)
|
||||
}
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
if(!daemon->workers)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
if(daemon->cfg->dnstap) {
|
||||
#ifdef USE_DNSTAP
|
||||
daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path,
|
||||
@@ -528,8 +562,15 @@ void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
|
||||
if(!(daemon->views = views_create()))
|
||||
fatal_exit("Could not create views: out of memory");
|
||||
/* create individual views and their localzone/data trees */
|
||||
if(!views_apply_cfg(daemon->views, daemon->cfg))
|
||||
fatal_exit("Could not set up views");
|
||||
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||
fatal_exit("Could not setup access control list");
|
||||
/* create global local_zones */
|
||||
if(!(daemon->local_zones = local_zones_create()))
|
||||
fatal_exit("Could not create local zones: out of memory");
|
||||
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
|
||||
@@ -565,8 +606,14 @@ daemon_fork(struct daemon* daemon)
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "STOPPING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
/* we exited! a signal happened! Stop other threads */
|
||||
@@ -586,13 +633,14 @@ daemon_cleanup(struct daemon* daemon)
|
||||
log_thread_set(NULL);
|
||||
/* clean up caches because
|
||||
* a) RRset IDs will be recycled after a reload, causing collisions
|
||||
* b) validation config can change, thus rrset, msg, keycache clear
|
||||
* The infra cache is kept, the timing and edns info is still valid */
|
||||
* b) validation config can change, thus rrset, msg, keycache clear */
|
||||
slabhash_clear(&daemon->env->rrset_cache->table);
|
||||
slabhash_clear(daemon->env->msg_cache);
|
||||
local_zones_delete(daemon->local_zones);
|
||||
daemon->local_zones = NULL;
|
||||
/* key cache is cleared by module desetup during next daemon_init() */
|
||||
views_delete(daemon->views);
|
||||
daemon->views = NULL;
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
@@ -621,6 +669,8 @@ daemon_delete(struct daemon* daemon)
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
edns_known_options_delete(daemon->env);
|
||||
inplace_cb_lists_delete(daemon->env);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
@@ -656,8 +706,12 @@ daemon_delete(struct daemon* daemon)
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
# endif
|
||||
# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
|
||||
# endif
|
||||
# ifdef HAVE_ERR_FREE_STRINGS
|
||||
ERR_free_strings();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
RAND_cleanup();
|
||||
# endif
|
||||
|
||||
@@ -53,6 +53,7 @@ struct module_env;
|
||||
struct rrset_cache;
|
||||
struct acl_list;
|
||||
struct local_zones;
|
||||
struct views;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
|
||||
@@ -111,6 +112,8 @@ struct daemon {
|
||||
struct timeval time_last_stat;
|
||||
/** time when daemon started */
|
||||
struct timeval time_boot;
|
||||
/** views structure containing view tree */
|
||||
struct views* views;
|
||||
#ifdef USE_DNSTAP
|
||||
/** the dnstap environment master value, copied and changed by threads*/
|
||||
struct dt_env* dtenv;
|
||||
|
||||
+374
-60
@@ -46,9 +46,12 @@
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#ifndef HEADER_DH_H
|
||||
#ifdef HAVE_OPENSSL_DH_H
|
||||
#include <openssl/dh.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_BN_H
|
||||
#include <openssl/bn.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include "daemon/remote.h"
|
||||
@@ -143,8 +146,9 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
|
||||
* the command : "openssl dhparam -C 2048"
|
||||
* (some openssl versions reject DH that is 'too small', eg. 512).
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
#ifndef S_SPLINT_S
|
||||
DH *get_dh2048()
|
||||
static DH *get_dh2048(void)
|
||||
{
|
||||
static unsigned char dh2048_p[]={
|
||||
0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6,
|
||||
@@ -173,16 +177,34 @@ DH *get_dh2048()
|
||||
static unsigned char dh2048_g[]={
|
||||
0x02,
|
||||
};
|
||||
DH *dh;
|
||||
DH *dh = NULL;
|
||||
BIGNUM *p = NULL, *g = NULL;
|
||||
|
||||
if ((dh=DH_new()) == NULL) return(NULL);
|
||||
dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
|
||||
dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
|
||||
if ((dh->p == NULL) || (dh->g == NULL))
|
||||
{ DH_free(dh); return(NULL); }
|
||||
return(dh);
|
||||
dh = DH_new();
|
||||
p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
||||
g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
||||
if (!dh || !p || !g)
|
||||
goto err;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
dh->p = p;
|
||||
dh->g = g;
|
||||
#else
|
||||
if (!DH_set0_pqg(dh, p, NULL, g))
|
||||
goto err;
|
||||
#endif
|
||||
return dh;
|
||||
err:
|
||||
if (p)
|
||||
BN_free(p);
|
||||
if (g)
|
||||
BN_free(g);
|
||||
if (dh)
|
||||
DH_free(dh);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* SPLINT */
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
|
||||
|
||||
struct daemon_remote*
|
||||
daemon_remote_create(struct config_file* cfg)
|
||||
@@ -223,18 +245,27 @@ daemon_remote_create(struct config_file* cfg)
|
||||
|
||||
if (cfg->remote_control_use_cert == 0) {
|
||||
/* No certificates are requested */
|
||||
if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL")) {
|
||||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(rc->ctx, 0);
|
||||
#endif
|
||||
if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL, eNULL")) {
|
||||
log_crypto_err("Failed to set aNULL cipher list");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* in openssl 1.1, the securitylevel 0 allows eNULL, that
|
||||
* does not need the DH */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
/* Since we have no certificates and hence no source of
|
||||
* DH params, let's generate and set them
|
||||
*/
|
||||
if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) {
|
||||
log_crypto_err("Wanted to set DH param, but failed");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
rc->use_cert = 1;
|
||||
@@ -350,7 +381,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
|
||||
if(ip[0] == '/') {
|
||||
/* This looks like a local socket */
|
||||
fd = create_local_accept_sock(ip, &noproto);
|
||||
fd = create_local_accept_sock(ip, &noproto, cfg->use_systemd);
|
||||
/*
|
||||
* Change socket ownership and permissions so users other
|
||||
* than root can access it provided they are in the same
|
||||
@@ -359,8 +390,12 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
if(fd != -1) {
|
||||
#ifdef HAVE_CHOWN
|
||||
if (cfg->username && cfg->username[0] &&
|
||||
cfg_uid != (uid_t)-1)
|
||||
chown(ip, cfg_uid, cfg_gid);
|
||||
cfg_uid != (uid_t)-1) {
|
||||
if(chown(ip, cfg_uid, cfg_gid) == -1)
|
||||
log_err("cannot chown %u.%u %s: %s",
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
ip, strerror(errno));
|
||||
}
|
||||
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
|
||||
#else
|
||||
(void)cfg;
|
||||
@@ -389,7 +424,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
|
||||
/* open fd */
|
||||
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
|
||||
cfg->ip_transparent, 0, cfg->ip_freebind);
|
||||
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd);
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
@@ -727,6 +762,8 @@ print_stats(SSL* ssl, const char* nm, struct stats_info* s)
|
||||
struct timeval avg;
|
||||
if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_ip_ratelimited"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_ip_ratelimited)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
|
||||
(unsigned long)(s->svr.num_queries
|
||||
- s->svr.num_queries_missed_cache))) return 0;
|
||||
@@ -734,6 +771,8 @@ print_stats(SSL* ssl, const char* nm, struct stats_info* s)
|
||||
(unsigned long)s->svr.num_queries_missed_cache)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.prefetch"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_prefetch)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.zero_ttl"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.zero_ttl_responses)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.recursivereplies"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_replies_sent)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.requestlist.avg"SQ"%g\n", nm,
|
||||
@@ -792,12 +831,6 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
{
|
||||
int m;
|
||||
size_t msg, rrset, val, iter;
|
||||
#ifdef HAVE_SBRK
|
||||
extern void* unbound_start_brk;
|
||||
void* cur = sbrk(0);
|
||||
if(!print_longnum(ssl, "mem.total.sbrk"SQ,
|
||||
(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);
|
||||
val=0;
|
||||
@@ -1097,8 +1130,8 @@ find_arg2(SSL* ssl, char* arg, char** arg2)
|
||||
}
|
||||
|
||||
/** Add a new zone */
|
||||
static void
|
||||
do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
static int
|
||||
perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
@@ -1107,83 +1140,266 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
enum localzone_type t;
|
||||
struct local_zone* z;
|
||||
if(!find_arg2(ssl, arg, &arg2))
|
||||
return;
|
||||
return 0;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
return 0;
|
||||
if(!local_zone_str2type(arg2, &t)) {
|
||||
ssl_printf(ssl, "error not a zone type. %s\n", arg2);
|
||||
free(nm);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
if((z=local_zones_find(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);
|
||||
free(nm);
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
send_ok(ssl);
|
||||
return;
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 1;
|
||||
}
|
||||
if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen,
|
||||
if(!local_zones_add_zone(zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Do the local_zone command */
|
||||
static void
|
||||
do_zone_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!perform_zone_add(ssl, zones, arg))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Remove a zone */
|
||||
/** Do the local_zones command */
|
||||
static void
|
||||
do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||
do_zones_add(SSL* ssl, struct local_zones* zones)
|
||||
{
|
||||
char buf[2048];
|
||||
int num = 0;
|
||||
while(ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
if(buf[0] == 0x04 && buf[1] == 0)
|
||||
break; /* end of transmission */
|
||||
if(!perform_zone_add(ssl, zones, buf)) {
|
||||
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
|
||||
return;
|
||||
}
|
||||
else
|
||||
num++;
|
||||
}
|
||||
(void)ssl_printf(ssl, "added %d zones\n", num);
|
||||
}
|
||||
|
||||
/** Remove a zone */
|
||||
static int
|
||||
perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
struct local_zone* z;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
||||
return 0;
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
if((z=local_zones_find(zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||
/* present in tree */
|
||||
local_zones_del_zone(worker->daemon->local_zones, z);
|
||||
local_zones_del_zone(zones, z);
|
||||
}
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
free(nm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Do the local_zone_remove command */
|
||||
static void
|
||||
do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!perform_zone_remove(ssl, zones, arg))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Do the local_zones_remove command */
|
||||
static void
|
||||
do_zones_remove(SSL* ssl, struct local_zones* zones)
|
||||
{
|
||||
char buf[2048];
|
||||
int num = 0;
|
||||
while(ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
if(buf[0] == 0x04 && buf[1] == 0)
|
||||
break; /* end of transmission */
|
||||
if(!perform_zone_remove(ssl, zones, buf)) {
|
||||
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
|
||||
return;
|
||||
}
|
||||
else
|
||||
num++;
|
||||
}
|
||||
(void)ssl_printf(ssl, "removed %d zones\n", num);
|
||||
}
|
||||
|
||||
/** Add new RR data */
|
||||
static void
|
||||
do_data_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
static int
|
||||
perform_data_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!local_zones_add_RR(worker->daemon->local_zones, arg)) {
|
||||
if(!local_zones_add_RR(zones, arg)) {
|
||||
ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Do the local_data command */
|
||||
static void
|
||||
do_data_add(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!perform_data_add(ssl, zones, arg))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Remove RR data */
|
||||
/** Do the local_datas command */
|
||||
static void
|
||||
do_data_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||
do_datas_add(SSL* ssl, struct local_zones* zones)
|
||||
{
|
||||
char buf[2048];
|
||||
int num = 0;
|
||||
while(ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
if(buf[0] == 0x04 && buf[1] == 0)
|
||||
break; /* end of transmission */
|
||||
if(!perform_data_add(ssl, zones, buf)) {
|
||||
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
|
||||
return;
|
||||
}
|
||||
else
|
||||
num++;
|
||||
}
|
||||
(void)ssl_printf(ssl, "added %d datas\n", num);
|
||||
}
|
||||
|
||||
/** Remove RR data */
|
||||
static int
|
||||
perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
uint8_t* nm;
|
||||
int nmlabs;
|
||||
size_t nmlen;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
local_zones_del_data(worker->daemon->local_zones, nm,
|
||||
return 0;
|
||||
local_zones_del_data(zones, nm,
|
||||
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||
free(nm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Do the local_data_remove command */
|
||||
static void
|
||||
do_data_remove(SSL* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!perform_data_remove(ssl, zones, arg))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Do the local_datas_remove command */
|
||||
static void
|
||||
do_datas_remove(SSL* ssl, struct local_zones* zones)
|
||||
{
|
||||
char buf[2048];
|
||||
int num = 0;
|
||||
while(ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
if(buf[0] == 0x04 && buf[1] == 0)
|
||||
break; /* end of transmission */
|
||||
if(!perform_data_remove(ssl, zones, buf)) {
|
||||
if(!ssl_printf(ssl, "error for input line: %s\n", buf))
|
||||
return;
|
||||
}
|
||||
else
|
||||
num++;
|
||||
}
|
||||
(void)ssl_printf(ssl, "removed %d datas\n", num);
|
||||
}
|
||||
|
||||
/** Add a new zone to view */
|
||||
static void
|
||||
do_view_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
char* arg2;
|
||||
struct view* v;
|
||||
if(!find_arg2(ssl, arg, &arg2))
|
||||
return;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_zone_add(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Remove a zone from view */
|
||||
static void
|
||||
do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
char* arg2;
|
||||
struct view* v;
|
||||
if(!find_arg2(ssl, arg, &arg2))
|
||||
return;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_zone_remove(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Add new RR data to view */
|
||||
static void
|
||||
do_view_data_add(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
char* arg2;
|
||||
struct view* v;
|
||||
if(!find_arg2(ssl, arg, &arg2))
|
||||
return;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_data_add(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** Remove RR data from view */
|
||||
static void
|
||||
do_view_data_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
char* arg2;
|
||||
struct view* v;
|
||||
if(!find_arg2(ssl, arg, &arg2))
|
||||
return;
|
||||
v = views_find_view(worker->daemon->views,
|
||||
arg, 1 /* get write lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_data_remove(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** cache lookup of nameservers */
|
||||
static void
|
||||
do_lookup(SSL* ssl, struct worker* worker, char* arg)
|
||||
@@ -1202,7 +1418,7 @@ static void
|
||||
do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
uint16_t t, uint16_t c)
|
||||
{
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
struct query_info k;
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
|
||||
if(t == LDNS_RR_TYPE_SOA)
|
||||
@@ -1212,6 +1428,7 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
k.qname_len = nmlen;
|
||||
k.qtype = t;
|
||||
k.qclass = c;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, 0);
|
||||
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||
if(t == LDNS_RR_TYPE_AAAA) {
|
||||
@@ -2157,6 +2374,14 @@ do_set_option(SSL* ssl, struct worker* worker, char* arg)
|
||||
(void)ssl_printf(ssl, "error setting option\n");
|
||||
return;
|
||||
}
|
||||
/* effectuate some arguments */
|
||||
if(strcmp(arg, "val-override-date:") == 0) {
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* val_env = NULL;
|
||||
if(m != -1) val_env = (struct val_env*)worker->env.modinfo[m];
|
||||
if(val_env)
|
||||
val_env->date_override = worker->env.cfg->val_date_override;
|
||||
}
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
@@ -2237,9 +2462,8 @@ do_list_stubs(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** do the list_local_zones command */
|
||||
static void
|
||||
do_list_local_zones(SSL* ssl, struct worker* worker)
|
||||
do_list_local_zones(SSL* ssl, struct local_zones* zones)
|
||||
{
|
||||
struct local_zones* zones = worker->daemon->local_zones;
|
||||
struct local_zone* z;
|
||||
char buf[257];
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
@@ -2260,9 +2484,8 @@ do_list_local_zones(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** do the list_local_data command */
|
||||
static void
|
||||
do_list_local_data(SSL* ssl, struct worker* worker)
|
||||
do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones)
|
||||
{
|
||||
struct local_zones* zones = worker->daemon->local_zones;
|
||||
struct local_zone* z;
|
||||
struct local_data* d;
|
||||
struct local_rrset* p;
|
||||
@@ -2298,6 +2521,34 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** do the view_list_local_zones command */
|
||||
static void
|
||||
do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct view* v = views_find_view(worker->daemon->views,
|
||||
arg, 0 /* get read lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_list_local_zones(ssl, v->local_zones);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** do the view_list_local_data command */
|
||||
static void
|
||||
do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct view* v = views_find_view(worker->daemon->views,
|
||||
arg, 0 /* get read lock*/);
|
||||
if(!v) {
|
||||
ssl_printf(ssl,"no view with name: %s\n", arg);
|
||||
return;
|
||||
}
|
||||
do_list_local_data(ssl, worker, v->local_zones);
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/** struct for user arg ratelimit list */
|
||||
struct ratelimit_list_arg {
|
||||
/** the infra cache */
|
||||
@@ -2310,6 +2561,8 @@ struct ratelimit_list_arg {
|
||||
time_t now;
|
||||
};
|
||||
|
||||
#define ip_ratelimit_list_arg ratelimit_list_arg
|
||||
|
||||
/** list items in the ratelimit table */
|
||||
static void
|
||||
rate_list(struct lruhash_entry* e, void* arg)
|
||||
@@ -2328,6 +2581,24 @@ rate_list(struct lruhash_entry* e, void* arg)
|
||||
ssl_printf(a->ssl, "%s %d limit %d\n", buf, max, lim);
|
||||
}
|
||||
|
||||
/** list items in the ip_ratelimit table */
|
||||
static void
|
||||
ip_rate_list(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
char ip[128];
|
||||
struct ip_ratelimit_list_arg* a = (struct ip_ratelimit_list_arg*)arg;
|
||||
struct ip_rate_key* k = (struct ip_rate_key*)e->key;
|
||||
struct ip_rate_data* d = (struct ip_rate_data*)e->data;
|
||||
int lim = infra_ip_ratelimit;
|
||||
int max = infra_rate_max(d, a->now);
|
||||
if(a->all == 0) {
|
||||
if(max < lim)
|
||||
return;
|
||||
}
|
||||
addr_to_str(&k->addr, k->addrlen, ip, sizeof(ip));
|
||||
ssl_printf(a->ssl, "%s %d limit %d\n", ip, max, lim);
|
||||
}
|
||||
|
||||
/** do the ratelimit_list command */
|
||||
static void
|
||||
do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
|
||||
@@ -2346,6 +2617,24 @@ do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
|
||||
slabhash_traverse(a.infra->domain_rates, 0, rate_list, &a);
|
||||
}
|
||||
|
||||
/** do the ip_ratelimit_list command */
|
||||
static void
|
||||
do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct ip_ratelimit_list_arg a;
|
||||
a.all = 0;
|
||||
a.infra = worker->env.infra_cache;
|
||||
a.now = *worker->env.now;
|
||||
a.ssl = ssl;
|
||||
arg = skipwhite(arg);
|
||||
if(strcmp(arg, "+a") == 0)
|
||||
a.all = 1;
|
||||
if(a.infra->client_ip_rates==NULL ||
|
||||
(a.all == 0 && infra_ip_ratelimit == 0))
|
||||
return;
|
||||
slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a);
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
static void
|
||||
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
@@ -2410,14 +2699,23 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
do_insecure_list(ssl, worker);
|
||||
return;
|
||||
} else if(cmdcmp(p, "list_local_zones", 16)) {
|
||||
do_list_local_zones(ssl, worker);
|
||||
do_list_local_zones(ssl, worker->daemon->local_zones);
|
||||
return;
|
||||
} else if(cmdcmp(p, "list_local_data", 15)) {
|
||||
do_list_local_data(ssl, worker);
|
||||
do_list_local_data(ssl, worker, worker->daemon->local_zones);
|
||||
return;
|
||||
} else if(cmdcmp(p, "view_list_local_zones", 21)) {
|
||||
do_view_list_local_zones(ssl, worker, skipwhite(p+21));
|
||||
return;
|
||||
} else if(cmdcmp(p, "view_list_local_data", 20)) {
|
||||
do_view_list_local_data(ssl, worker, skipwhite(p+20));
|
||||
return;
|
||||
} else if(cmdcmp(p, "ratelimit_list", 14)) {
|
||||
do_ratelimit_list(ssl, worker, p+14);
|
||||
return;
|
||||
} else if(cmdcmp(p, "ip_ratelimit_list", 17)) {
|
||||
do_ip_ratelimit_list(ssl, worker, p+17);
|
||||
return;
|
||||
} else if(cmdcmp(p, "stub_add", 8)) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
@@ -2479,13 +2777,29 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
if(cmdcmp(p, "verbosity", 9)) {
|
||||
do_verbosity(ssl, skipwhite(p+9));
|
||||
} else if(cmdcmp(p, "local_zone_remove", 17)) {
|
||||
do_zone_remove(ssl, worker, skipwhite(p+17));
|
||||
do_zone_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "local_zones_remove", 18)) {
|
||||
do_zones_remove(ssl, worker->daemon->local_zones);
|
||||
} else if(cmdcmp(p, "local_zone", 10)) {
|
||||
do_zone_add(ssl, worker, skipwhite(p+10));
|
||||
do_zone_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "local_zones", 11)) {
|
||||
do_zones_add(ssl, worker->daemon->local_zones);
|
||||
} else if(cmdcmp(p, "local_data_remove", 17)) {
|
||||
do_data_remove(ssl, worker, skipwhite(p+17));
|
||||
do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "local_datas_remove", 18)) {
|
||||
do_datas_remove(ssl, worker->daemon->local_zones);
|
||||
} else if(cmdcmp(p, "local_data", 10)) {
|
||||
do_data_add(ssl, worker, skipwhite(p+10));
|
||||
do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "local_datas", 11)) {
|
||||
do_datas_add(ssl, worker->daemon->local_zones);
|
||||
} else if(cmdcmp(p, "view_local_zone_remove", 22)) {
|
||||
do_view_zone_remove(ssl, worker, skipwhite(p+22));
|
||||
} else if(cmdcmp(p, "view_local_zone", 15)) {
|
||||
do_view_zone_add(ssl, worker, skipwhite(p+15));
|
||||
} else if(cmdcmp(p, "view_local_data_remove", 22)) {
|
||||
do_view_data_remove(ssl, worker, skipwhite(p+22));
|
||||
} else if(cmdcmp(p, "view_local_data", 15)) {
|
||||
do_view_data_add(ssl, worker, skipwhite(p+15));
|
||||
} else if(cmdcmp(p, "flush_zone", 10)) {
|
||||
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "flush_type", 10)) {
|
||||
|
||||
+2
-2
@@ -56,8 +56,8 @@ struct comm_reply;
|
||||
struct comm_point;
|
||||
struct daemon_remote;
|
||||
|
||||
/** number of seconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120
|
||||
/** number of milliseconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120000
|
||||
|
||||
/**
|
||||
* a busy control command connection, SSL state
|
||||
|
||||
+6
-2
@@ -102,12 +102,14 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
int threadnum)
|
||||
{
|
||||
log_info("server stats for thread %d: %u queries, "
|
||||
"%u answers from cache, %u recursions, %u prefetch",
|
||||
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
|
||||
"ip ratelimiting",
|
||||
threadnum, (unsigned)stats->num_queries,
|
||||
(unsigned)(stats->num_queries -
|
||||
stats->num_queries_missed_cache),
|
||||
(unsigned)stats->num_queries_missed_cache,
|
||||
(unsigned)stats->num_queries_prefetch);
|
||||
(unsigned)stats->num_queries_prefetch,
|
||||
(unsigned)stats->num_queries_ip_ratelimited);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u jostled %u", threadnum,
|
||||
(unsigned)stats->max_query_list_size,
|
||||
@@ -226,6 +228,7 @@ void server_stats_reply(struct worker* worker, int reset)
|
||||
void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
{
|
||||
total->svr.num_queries += a->svr.num_queries;
|
||||
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
|
||||
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
|
||||
@@ -251,6 +254,7 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.qEDNS += a->svr.qEDNS;
|
||||
total->svr.qEDNS_DO += a->svr.qEDNS_DO;
|
||||
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
|
||||
total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
|
||||
total->svr.ans_secure += a->svr.ans_secure;
|
||||
total->svr.ans_bogus += a->svr.ans_bogus;
|
||||
total->svr.rrset_bogus += a->svr.rrset_bogus;
|
||||
|
||||
+4
-1
@@ -63,6 +63,8 @@ struct sldns_buffer;
|
||||
struct server_stats {
|
||||
/** number of queries from clients received. */
|
||||
size_t num_queries;
|
||||
/** number of queries that have been dropped/ratelimited by ip. */
|
||||
size_t num_queries_ip_ratelimited;
|
||||
/** number of queries that had a cache-miss. */
|
||||
size_t num_queries_missed_cache;
|
||||
/** number of prefetch queries - cachehits with prefetch */
|
||||
@@ -131,7 +133,8 @@ struct server_stats {
|
||||
size_t unwanted_queries;
|
||||
/** usage of tcp accept list */
|
||||
size_t tcp_accept_usage;
|
||||
|
||||
/** answers served from expired cache */
|
||||
size_t zero_ttl_responses;
|
||||
/** histogram data exported to array
|
||||
* if the array is the same size, no data is lost, and
|
||||
* if all histograms are same size (is so by default) then
|
||||
|
||||
+40
-18
@@ -87,16 +87,14 @@
|
||||
# include "nss.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
void* unbound_start_brk = 0;
|
||||
#endif
|
||||
|
||||
/** print usage. */
|
||||
static void usage()
|
||||
static void usage(void)
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
time_t t;
|
||||
struct timeval now;
|
||||
struct ub_event_base* base;
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
@@ -110,11 +108,16 @@ static void usage()
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
ub_get_event_sys(NULL, &evnm, &evsys, &evmethod);
|
||||
base = ub_default_event_base(0,&t,&now);
|
||||
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef SSLEAY_VERSION
|
||||
SSLeay_version(SSLEAY_VERSION)
|
||||
# else
|
||||
OpenSSL_version(OPENSSL_VERSION)
|
||||
# endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_GetVersion()
|
||||
#elif defined(HAVE_NETTLE)
|
||||
@@ -127,6 +130,7 @@ static void usage()
|
||||
printf("\n");
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
ub_event_base_free(base);
|
||||
}
|
||||
|
||||
#ifndef unbound_testbound
|
||||
@@ -235,19 +239,37 @@ checkrlimits(struct config_file* cfg)
|
||||
#endif /* S_SPLINT_S */
|
||||
}
|
||||
|
||||
/** set default logfile identity based on value from argv[0] at startup **/
|
||||
static void
|
||||
log_ident_set_fromdefault(struct config_file* cfg,
|
||||
const char *log_default_identity)
|
||||
{
|
||||
if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
|
||||
log_ident_set(log_default_identity);
|
||||
else
|
||||
log_ident_set(cfg->log_identity);
|
||||
}
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode)
|
||||
int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
if (debug_mode > 1) {
|
||||
cfg->use_syslog = 0;
|
||||
free(cfg->logfile);
|
||||
cfg->logfile = NULL;
|
||||
}
|
||||
daemon_apply_cfg(daemon, cfg);
|
||||
checkrlimits(cfg);
|
||||
|
||||
if (cfg->use_systemd && cfg->do_daemonize) {
|
||||
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
|
||||
}
|
||||
|
||||
log_ident_set_fromdefault(cfg, log_default_identity);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
@@ -539,7 +561,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
log_warn("unable to initgroups %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
# endif /* HAVE_INITGROUPS */
|
||||
# ifdef HAVE_ENDPWENT
|
||||
endpwent();
|
||||
# endif
|
||||
|
||||
#ifdef HAVE_SETRESGID
|
||||
if(setresgid(cfg_gid,cfg_gid,cfg_gid) != 0)
|
||||
@@ -575,9 +599,10 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* @param cmdline_verbose: verbosity resulting from commandline -v.
|
||||
* These increase verbosity as specified in the config file.
|
||||
* @param debug_mode: if set, do not daemonize.
|
||||
* @param log_default_identity: Default identity to report in logs
|
||||
*/
|
||||
static void
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
{
|
||||
struct config_file* cfg = NULL;
|
||||
struct daemon* daemon = NULL;
|
||||
@@ -599,7 +624,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
cfgfile);
|
||||
log_warn("Continuing with default config settings");
|
||||
}
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
|
||||
if(!done_setup)
|
||||
config_lookup_uid(cfg);
|
||||
|
||||
@@ -607,7 +632,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
if(!daemon_open_shared_ports(daemon))
|
||||
fatal_exit("could not open ports");
|
||||
if(!done_setup) {
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
done_setup = 1;
|
||||
} else {
|
||||
/* reopen log after HUP to facilitate log rotation */
|
||||
@@ -654,19 +679,16 @@ main(int argc, char* argv[])
|
||||
int c;
|
||||
const char* cfgfile = CONFIGFILE;
|
||||
const char* winopt = NULL;
|
||||
const char* log_ident_default;
|
||||
int cmdline_verbose = 0;
|
||||
int debug_mode = 0;
|
||||
#ifdef UB_ON_WINDOWS
|
||||
int cmdline_cfg = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/* take debug snapshot of heap */
|
||||
unbound_start_brk = sbrk(0);
|
||||
#endif
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_set(strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0]);
|
||||
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
|
||||
log_ident_set(log_ident_default);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhvw:")) != -1) {
|
||||
switch(c) {
|
||||
@@ -710,7 +732,7 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode);
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default);
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
+189
-122
@@ -101,57 +101,14 @@
|
||||
*/
|
||||
#define PREFETCH_EXPIRY_ADD 60
|
||||
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
/** measure memory leakage */
|
||||
static void
|
||||
debug_memleak(size_t accounted, size_t heap,
|
||||
size_t total_alloc, size_t total_free)
|
||||
{
|
||||
static int init = 0;
|
||||
static size_t base_heap, base_accounted, base_alloc, base_free;
|
||||
size_t base_af, cur_af, grow_af, grow_acc;
|
||||
if(!init) {
|
||||
init = 1;
|
||||
base_heap = heap;
|
||||
base_accounted = accounted;
|
||||
base_alloc = total_alloc;
|
||||
base_free = total_free;
|
||||
}
|
||||
base_af = base_alloc - base_free;
|
||||
cur_af = total_alloc - total_free;
|
||||
grow_af = cur_af - base_af;
|
||||
grow_acc = accounted - base_accounted;
|
||||
log_info("Leakage: %d leaked. growth: %u use, %u acc, %u heap",
|
||||
(int)(grow_af - grow_acc), (unsigned)grow_af,
|
||||
(unsigned)grow_acc, (unsigned)(heap - base_heap));
|
||||
}
|
||||
|
||||
/** give debug heap size indication */
|
||||
static void
|
||||
debug_total_mem(size_t calctotal)
|
||||
{
|
||||
#ifdef HAVE_SBRK
|
||||
extern void* unbound_start_brk;
|
||||
extern size_t unbound_mem_alloc, unbound_mem_freed;
|
||||
void* cur = sbrk(0);
|
||||
int total = cur-unbound_start_brk;
|
||||
log_info("Total heap memory estimate: %u total-alloc: %u "
|
||||
"total-free: %u", (unsigned)total,
|
||||
(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
|
||||
debug_memleak(calctotal, (size_t)total,
|
||||
unbound_mem_alloc, unbound_mem_freed);
|
||||
#else
|
||||
(void)calctotal;
|
||||
#endif /* HAVE_SBRK */
|
||||
}
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
|
||||
/** Report on memory usage by this thread and global */
|
||||
static void
|
||||
worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
struct serviced_query* ATTR_UNUSED(cur_serv))
|
||||
{
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
/* measure memory leakage */
|
||||
extern size_t unbound_mem_alloc, unbound_mem_freed;
|
||||
/* debug func in validator module */
|
||||
size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
|
||||
size_t me, iter, val, anch;
|
||||
@@ -199,7 +156,9 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
(unsigned)mesh, (unsigned)msg, (unsigned)rrset,
|
||||
(unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch,
|
||||
(unsigned)ac, (unsigned)superac, (unsigned)me);
|
||||
debug_total_mem(total);
|
||||
log_info("Total heap memory estimate: %u total-alloc: %u "
|
||||
"total-free: %u", (unsigned)total,
|
||||
(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
|
||||
#else /* no UNBOUND_ALLOC_STATS */
|
||||
size_t val = 0;
|
||||
int i;
|
||||
@@ -485,6 +444,10 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!dp) { /* no delegation, need to reprime */
|
||||
return 0;
|
||||
}
|
||||
/* In case we have a local alias, copy it into the delegation message.
|
||||
* Shallow copy should be fine, as we'll be done with msg in this
|
||||
* function. */
|
||||
msg->qinfo.local_alias = qinfo->local_alias;
|
||||
if(must_validate) {
|
||||
switch(check_delegation_secure(msg->rep)) {
|
||||
case sec_status_unchecked:
|
||||
@@ -497,8 +460,9 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!edns_opt_inplace_reply(edns, worker->scratchpad))
|
||||
return 0;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
return 0;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
if(worker->stats.extended) {
|
||||
@@ -526,12 +490,16 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!edns_opt_inplace_reply(edns, worker->scratchpad))
|
||||
return 0;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
return 0;
|
||||
msg->rep->flags |= BIT_QR|BIT_RA;
|
||||
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
repinfo->c->buffer, 0, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
}
|
||||
@@ -553,17 +521,29 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
int secure;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
* we will refetch the message format from the
|
||||
* authoritative server
|
||||
*/
|
||||
return 0;
|
||||
if(worker->env.cfg->serve_expired) {
|
||||
/* always lock rrsets, rep->ttl is ignored */
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
/* below, rrsets with ttl before timenow become TTL 0 in
|
||||
* the response */
|
||||
/* This response was served with zero TTL */
|
||||
if (timenow >= rep->ttl) {
|
||||
worker->stats.zero_ttl_responses++;
|
||||
}
|
||||
} else {
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
* we will refetch the message format from the
|
||||
* authoritative server
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
||||
return 0;
|
||||
/* locked and ids and ttls are OK. */
|
||||
}
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
||||
return 0;
|
||||
/* locked and ids and ttls are OK. */
|
||||
/* check CNAME chain (if any) */
|
||||
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||
@@ -584,8 +564,9 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!edns_opt_inplace_reply(edns, worker->scratchpad))
|
||||
return 0;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
goto bail_out;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
@@ -616,11 +597,15 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!edns_opt_inplace_reply(edns, worker->scratchpad))
|
||||
return 0;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
goto bail_out;
|
||||
if(!reply_info_answer_encode(qinfo, rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
}
|
||||
@@ -692,8 +677,9 @@ chaos_replystr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!edns_opt_inplace_reply(edns, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
|
||||
LDNS_RCODE_NOERROR, edns, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
attach_edns_record(pkt, edns);
|
||||
}
|
||||
|
||||
@@ -773,6 +759,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -799,11 +787,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int ret;
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
struct lruhash_entry* e;
|
||||
struct query_info qinfo;
|
||||
struct edns_data edns;
|
||||
enum acl_access acl;
|
||||
struct acl_addr* acladdr;
|
||||
int rc = 0;
|
||||
|
||||
if(error != NETEVENT_NOERROR) {
|
||||
@@ -816,8 +805,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
|
||||
c->buffer);
|
||||
#endif
|
||||
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
|
||||
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
|
||||
repinfo->addrlen);
|
||||
acl = acl_get_control(acladdr);
|
||||
if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
|
||||
{
|
||||
if(ret == 1)
|
||||
@@ -835,7 +825,29 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
worker->stats.num_queries++;
|
||||
|
||||
/* check if this query should be dropped based on source ip rate limiting */
|
||||
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
|
||||
*worker->env.now)) {
|
||||
/* See if we are passed through with slip factor */
|
||||
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
|
||||
ub_random_max(worker->env.rnd,
|
||||
worker->env.cfg->ip_ratelimit_factor) == 1) {
|
||||
|
||||
char addrbuf[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen,
|
||||
addrbuf, sizeof(addrbuf));
|
||||
verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
|
||||
addrbuf);
|
||||
} else {
|
||||
worker->stats.num_queries_ip_ratelimited++;
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* see if query is in the cache */
|
||||
if(!query_info_parse(&qinfo, c->buffer)) {
|
||||
verbose(VERB_ALGO, "worker parse request: formerror.");
|
||||
@@ -870,6 +882,28 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
goto send_reply;
|
||||
}
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_OPT ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_TSIG ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_TKEY ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_MAILA ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
|
||||
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
|
||||
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
}
|
||||
goto send_reply;
|
||||
}
|
||||
if((ret=parse_edns_from_pkt(c->buffer, &edns, worker->scratchpad)) != 0) {
|
||||
struct edns_data reply_edns;
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
@@ -940,8 +974,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
|
||||
c->buffer, worker->scratchpad, repinfo)) {
|
||||
if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
|
||||
&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
|
||||
acladdr->taglen, acladdr->tag_actions,
|
||||
acladdr->tag_actions_size, acladdr->tag_datas,
|
||||
acladdr->tag_datas_size, worker->daemon->cfg->tagname,
|
||||
worker->daemon->cfg->num_tags, acladdr->view)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -978,44 +1016,70 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
}
|
||||
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
(struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
/* prefetch it if the prefetch TTL expired */
|
||||
if(worker->env.cfg->prefetch && *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) {
|
||||
time_t leeway = ((struct reply_info*)e->
|
||||
data)->ttl - *worker->env.now;
|
||||
lock_rw_unlock(&e->lock);
|
||||
reply_and_prefetch(worker, &qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway);
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply_rc;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
* target before resolving it. */
|
||||
if(qinfo.local_alias) {
|
||||
struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset;
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
|
||||
/* Sanity check: our current implementation only supports
|
||||
* a single CNAME RRset as a local alias. */
|
||||
if(qinfo.local_alias->next ||
|
||||
rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
|
||||
d->count != 1) {
|
||||
log_err("assumption failure: unexpected local alias");
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
return 0; /* drop it */
|
||||
}
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
qinfo.qname = d->rr_data[0] + 2;
|
||||
qinfo.qname_len = d->rr_len[0] - 2;
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
if(answer_norec_from_cache(worker, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
|
||||
if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
|
||||
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
if(answer_from_cache(worker, &qinfo,
|
||||
(struct reply_info*)e->data,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
/* prefetch it if the prefetch TTL expired */
|
||||
if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
|
||||
&& *worker->env.now >=
|
||||
((struct reply_info*)e->data)->prefetch_ttl) {
|
||||
time_t leeway = ((struct reply_info*)e->
|
||||
data)->ttl - *worker->env.now;
|
||||
if(((struct reply_info*)e->data)->ttl
|
||||
< *worker->env.now)
|
||||
leeway = 0;
|
||||
lock_rw_unlock(&e->lock);
|
||||
reply_and_prefetch(worker, &qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway);
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply_rc;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
if(answer_norec_from_cache(worker, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
|
||||
&edns)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
"need to validate or not primed");
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
"need to validate or not primed");
|
||||
}
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
server_stats_querymiss(&worker->stats, worker);
|
||||
@@ -1044,6 +1108,12 @@ send_reply_rc:
|
||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
|
||||
c->type, c->buffer);
|
||||
#endif
|
||||
if(worker->env.cfg->log_replies)
|
||||
{
|
||||
struct timeval tv = {0, 0};
|
||||
log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
|
||||
tv, 1, c->buffer);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1369,11 +1439,10 @@ worker_delete(struct worker* worker)
|
||||
}
|
||||
|
||||
struct outbound_entry*
|
||||
worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, struct edns_option* opt_list,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q)
|
||||
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -1381,11 +1450,10 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
if(!e)
|
||||
return NULL;
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps,
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, opt_list,
|
||||
addr, addrlen, zone, zonelen, worker_handle_service_reply, e,
|
||||
worker->back->udp_buff);
|
||||
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
|
||||
ssl_upstream, addr, addrlen, zone, zonelen, q,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1425,14 +1493,13 @@ void worker_stop_accept(void* arg)
|
||||
}
|
||||
|
||||
/* --- fake callbacks for fptr_wlist to work --- */
|
||||
struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
int ATTR_UNUSED(nocaps), struct edns_option* ATTR_UNUSED(opt_list),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
struct outbound_entry* libworker_send_query(
|
||||
struct query_info* ATTR_UNUSED(qinfo),
|
||||
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
+2
-1
@@ -61,6 +61,7 @@ struct ub_randstate;
|
||||
struct regional;
|
||||
struct tube;
|
||||
struct daemon_remote;
|
||||
struct query_info;
|
||||
|
||||
/** worker commands */
|
||||
enum worker_commands {
|
||||
@@ -84,7 +85,7 @@ struct worker {
|
||||
/** global shared daemon structure */
|
||||
struct daemon* daemon;
|
||||
/** thread id */
|
||||
ub_thread_t thr_id;
|
||||
ub_thread_type thr_id;
|
||||
/** pipe, for commands for this worker */
|
||||
struct tube* cmd;
|
||||
/** the event base this worker works with */
|
||||
|
||||
+4
-3
@@ -825,8 +825,9 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
}
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
if (!super->no_cache_store &&
|
||||
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
log_err("out of memory");
|
||||
}
|
||||
|
||||
@@ -872,7 +873,7 @@ static struct module_func_block dns64_block = {
|
||||
* Function for returning the above function block.
|
||||
*/
|
||||
struct module_func_block *
|
||||
dns64_get_funcblock()
|
||||
dns64_get_funcblock(void)
|
||||
{
|
||||
return &dns64_block;
|
||||
}
|
||||
|
||||
+8
-1
@@ -121,7 +121,9 @@ dt_msg_init(const struct dt_env *env,
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
{
|
||||
#ifdef UNBOUND_DEBUG
|
||||
fstrm_res res;
|
||||
#endif
|
||||
struct dt_env *env;
|
||||
struct fstrm_iothr_options *fopt;
|
||||
struct fstrm_unix_writer_options *fuwopt;
|
||||
@@ -138,7 +140,12 @@ dt_create(const char *socket_path, unsigned num_workers)
|
||||
return NULL;
|
||||
|
||||
fwopt = fstrm_writer_options_init();
|
||||
res = fstrm_writer_options_add_content_type(fwopt,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
res =
|
||||
#else
|
||||
(void)
|
||||
#endif
|
||||
fstrm_writer_options_add_content_type(fwopt,
|
||||
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
log_assert(res == fstrm_res_success);
|
||||
|
||||
|
||||
Binary file not shown.
+483
@@ -1,8 +1,491 @@
|
||||
14 February 2017: Wouter
|
||||
- tag 1.6.1rc3.
|
||||
|
||||
13 February 2017: Wouter
|
||||
- Fix autoconf of systemd check for lack of pkg-config.
|
||||
|
||||
10 February 2017: Wouter
|
||||
- Fix pythonmod for typedef changes.
|
||||
- Fix dnstap for warning of set but not used.
|
||||
- tag 1.6.1rc2.
|
||||
|
||||
9 February 2017: Wouter
|
||||
- tag 1.6.1rc1.
|
||||
|
||||
8 February 2017: Wouter
|
||||
- Fix for type name change and fix warning on windows compile.
|
||||
|
||||
7 February 2017: Wouter
|
||||
- Include root trust anchor id 20326 in unbound-anchor.
|
||||
|
||||
6 February 2017: Wouter
|
||||
- Fix compile on solaris of the fix to use $host detect.
|
||||
|
||||
4 February 2017: Wouter
|
||||
- fix root_anchor test for updated icannbundle.pem lower certificates.
|
||||
|
||||
26 January 2017: Wouter
|
||||
- Fix 1211: Fix can't enable interface-automatic if no IPv6 with
|
||||
more helpful error message.
|
||||
|
||||
20 January 2017: Wouter
|
||||
- Increase MAX_MODULE to 16.
|
||||
|
||||
19 January 2017: Wouter
|
||||
- Fix to Rename ub_callback_t to ub_callback_type, because POSIX
|
||||
reserves _t typedefs.
|
||||
- Fix to rename internally used types from _t to _type, because _t
|
||||
type names are reserved by POSIX.
|
||||
- iana portlist update
|
||||
|
||||
12 January 2017: Wouter
|
||||
- Fix to also block meta types 128 through to 248 with formerr.
|
||||
- Fix #1206: Some view-related commands are missing from 'unbound-control -h'
|
||||
|
||||
9 January 2017: Wouter
|
||||
- Fix #1202: Fix code comment that packed_rrset_data is not always
|
||||
'packed'.
|
||||
|
||||
6 January 2017: Wouter
|
||||
- Fix #1201: Fix missing unlock in answer_from_cache error condition.
|
||||
|
||||
5 January 2017: Wouter
|
||||
- Fix to return formerr for queries for meta-types, to avoid
|
||||
packet amplification if this meta-type is sent on to upstream.
|
||||
- Fix #1184: Log DNS replies. This includes the same logging
|
||||
information that DNS queries and response code and response size,
|
||||
patch from Larissa Feng.
|
||||
- Fix #1185: Source IP rate limiting, patch from Larissa Feng.
|
||||
|
||||
3 January 2017: Wouter
|
||||
- configure --enable-systemd and lets unbound use systemd sockets if
|
||||
you enable use-systemd: yes in unbound.conf.
|
||||
Also there are contrib/unbound.socket and contrib/unbound.service:
|
||||
systemd files for unbound, install them in /usr/lib/systemd/system.
|
||||
Contributed by Sami Kerola and Pavel Odintsov.
|
||||
- Fix reload chdir failure when also chrooted to that directory.
|
||||
|
||||
2 January 2017: Wouter
|
||||
- Fix #1194: Cross build fails when $host isn't `uname` for getentropy.
|
||||
|
||||
23 December 2016: Ralph
|
||||
- Fix #1190: Do not echo back EDNS options in local-zone error response.
|
||||
- iana portlist update
|
||||
|
||||
21 December 2016: Ralph
|
||||
- Fix #1188: Unresolved symbol 'fake_dsa' in libunbound.so when built
|
||||
with Nettle
|
||||
|
||||
19 December 2016: Ralph
|
||||
- Fix #1191: remove comment about view deletion.
|
||||
|
||||
15 December 2016: Wouter
|
||||
- iana portlist update
|
||||
- 64bit is default for windows builds.
|
||||
- Fix inet_ntop and inet_pton warnings in windows compile.
|
||||
|
||||
14 December 2016: Wouter
|
||||
- Fix #1178: attempt to fix setup error at end, pop result values
|
||||
at end of install.
|
||||
|
||||
13 December 2016: Wouter
|
||||
- Fix #1182: Fix Resource leak (socket), at startup.
|
||||
- Fix unbound-control and ipv6 only.
|
||||
|
||||
9 December 2016: Wouter
|
||||
- Fix #1176: stack size too small for Alpine Linux.
|
||||
|
||||
8 December 2016: Wouter
|
||||
- Fix downcast warnings from visual studio in sldns code.
|
||||
- tag 1.6.0rc1 which became 1.6.0 on 15 dec, and trunk is 1.6.1.
|
||||
|
||||
7 December 2016: Ralph
|
||||
- Add DSA support for OpenSSL 1.1.0
|
||||
- Fix remote control without cert for LibreSSL
|
||||
|
||||
6 December 2016: George
|
||||
- Added generic EDNS code for registering known EDNS option codes,
|
||||
bypassing the cache response stage and uniquifying mesh states. Four EDNS
|
||||
option lists were added to module_qstate (module_qstate.edns_opts_*) to
|
||||
store EDNS options from/to front/back side.
|
||||
- Added two flags to module_qstate (no_cache_lookup, no_cache_store) that
|
||||
control the modules' cache interactions.
|
||||
- Added code for registering inplace callback functions. The registered
|
||||
functions can be called just before replying with local data or Chaos,
|
||||
replying from cache, replying with SERVFAIL, replying with a resolved
|
||||
query, sending a query to a nameserver. The functions can inspect the
|
||||
available data and maybe change response/query related data (i.e. append
|
||||
EDNS options).
|
||||
- Updated Python module for the above.
|
||||
- Updated Python documentation.
|
||||
|
||||
5 December 2016: Ralph
|
||||
- Fix #1173: differ local-zone type deny from unset
|
||||
tag_actions element.
|
||||
|
||||
5 December 2016: Wouter
|
||||
- Fix #1170: document that 'inform' local-zone uses local-data.
|
||||
|
||||
1 December 2016: Ralph
|
||||
- hyphen as minus fix, by Andreas Schulze
|
||||
|
||||
30 November 2016: Ralph
|
||||
- Added local-zones and local-data bulk addition and removal
|
||||
functionality in unbound-control (local_zones, local_zones_remove,
|
||||
local_datas and local_datas_remove).
|
||||
- iana portlist update
|
||||
|
||||
29 November 2016: Wouter
|
||||
- version 1.6.0 is in the development branch.
|
||||
- braces in view.c around lock statements.
|
||||
|
||||
28 November 2016: Wouter
|
||||
- new install-sh.
|
||||
|
||||
25 November 2016: Wouter
|
||||
- Fix that with openssl 1.1 control-use-cert: no uses less cpu, by
|
||||
using no encryption over the unix socket.
|
||||
|
||||
22 Novenber 2016: Ralph
|
||||
- Make access-control-tag-data RDATA absolute. This makes the RDATA
|
||||
origin consistent between local-data and access-control-tag-data.
|
||||
- Fix NSEC ENT wildcard check. Matching wildcard does not have to be a
|
||||
subdomain of the NSEC owner.
|
||||
- QNAME minimisation uses QTYPE=A, therefore always check cache for
|
||||
this type in harden-below-nxdomain functionality.
|
||||
- Added unit test for QNAME minimisation + harden below nxdomain
|
||||
synergy.
|
||||
|
||||
22 November 2016: Wouter
|
||||
- iana portlist update.
|
||||
- Fix unit tests for DS hash processing for fake-dsa test option.
|
||||
- patch from Dag-Erling Smorgrav that removes code that relies
|
||||
on sbrk().
|
||||
|
||||
21 November 2016: Wouter
|
||||
- Fix #1158: reference RFC 8020 "NXDOMAIN: There Really Is Nothing
|
||||
Underneath" for the harden-below-nxdomain option.
|
||||
|
||||
10 November 2016: Ralph
|
||||
- Fix #1155: test status code of unbound-control in 04-checkconf,
|
||||
not the status code from the tee command.
|
||||
|
||||
4 November 2016: Ralph
|
||||
- Added stub-ssl-upstream and forward-ssl-upstream options.
|
||||
|
||||
4 November 2016: Wouter
|
||||
- configure detects ssl security level API function in the autoconf
|
||||
manner. Every function on its own, so that other libraries (eg.
|
||||
LibreSSL) can develop their API without hindrance.
|
||||
- Fix #1154: segfault when reading config with duplicate zones.
|
||||
- Note that for harden-below-nxdomain the nxdomain must be secure,
|
||||
this means nsec3 with optout is insufficient.
|
||||
|
||||
3 November 2016: Ralph
|
||||
- Set OpenSSL security level to 0 when using aNULL ciphers.
|
||||
|
||||
3 November 2016: Wouter
|
||||
- .gitattributes line for githubs code language display.
|
||||
- log-identity: config option to set sys log identity, patch from
|
||||
"Robin H. Johnson" <robbat2@gentoo.org>
|
||||
|
||||
2 November 2016: Wouter
|
||||
- iana portlist update.
|
||||
|
||||
31 October 2016: Wouter
|
||||
- Fix failure to build on arm64 with no sbrk.
|
||||
- iana portlist update.
|
||||
|
||||
28 October 2016: Wouter
|
||||
- Patch for server.num.zero_ttl stats for count of expired replies,
|
||||
from Pavel Odintsov.
|
||||
|
||||
26 October 2016: Wouter
|
||||
- Fix unit tests for openssl 1.1, with no DSA, by faking DSA, enabled
|
||||
with the undocumented switch 'fake-dsa'. It logs a warning.
|
||||
|
||||
25 October 2016: Wouter
|
||||
- Fix #1134: unbound-control set_option -- val-override-date: -1 works
|
||||
immediately to ignore datetime, or back to 0 to enable it again.
|
||||
The -- is to ignore the '-1' as an option flag.
|
||||
|
||||
24 October 2016: Wouter
|
||||
- serve-expired config option: serve expired responses with TTL 0.
|
||||
- g.root-servers.net has AAAA address.
|
||||
|
||||
21 October 2016: Wouter
|
||||
- Ported tests for local_cname unit test to testbound framework.
|
||||
|
||||
20 October 2016: Wouter
|
||||
- suppress compile warning in lex files.
|
||||
- init lzt variable, for older gcc compiler warnings.
|
||||
- fix --enable-dsa to work, instead of copying ecdsa enable.
|
||||
- Fix DNSSEC validation of query type ANY with DNAME answers.
|
||||
- Fixup query_info local_alias init.
|
||||
|
||||
19 October 2016: Wouter
|
||||
- Fix #1130: whitespace in example.conf.in more consistent.
|
||||
|
||||
18 October 2016: Wouter
|
||||
- Patch that resolves CNAMEs entered in local-data conf statements that
|
||||
point to data on the internet, from Jinmei Tatuya (Infoblox).
|
||||
- Removed patch comments from acllist.c and msgencode.c
|
||||
- Added documentation doc/CNAME-basedRedirectionDesignNotes.pdf,
|
||||
from Jinmei Tatuya (Infoblox).
|
||||
- Fix #1125: unbound could reuse an answer packet incorrectly for
|
||||
clients with different EDNS parameters, from Jinmei Tatuya.
|
||||
- Fix #1118: libunbound.pc sets strange Libs, Libs.private values.
|
||||
- Added Requires line to libunbound.pc
|
||||
- Please doxygen by modifying mesh.h
|
||||
|
||||
17 October 2016: Wouter
|
||||
- Re-fix #839 from view commit overwrite.
|
||||
- Fixup const void cast warning.
|
||||
|
||||
12 October 2016: Ralph
|
||||
- Free view config elements.
|
||||
|
||||
11 October 2016: Ralph
|
||||
- Added qname-minimisation-strict config option.
|
||||
- iana portlist update.
|
||||
- fix memoryleak logfile when in debug mode.
|
||||
|
||||
5 October 2016: Ralph
|
||||
- Added views functionality.
|
||||
- Fix #1117: spelling errors, from Robert Edmonds.
|
||||
|
||||
30 September 2016: Wouter
|
||||
- Fix Nits for 1.5.10 reported by Dag-Erling Smorgrav.
|
||||
|
||||
29 September 2016: Wouter
|
||||
- Fix #838: 1.5.10 cannot be built on Solaris, undefined PATH_MAX.
|
||||
- Fix #839: Memory grows unexpectedly with large RPZ files.
|
||||
- Fix #840: infinite loop in unbound_munin_ plugin on unowned lockfile.
|
||||
- Fix #841: big local-zone's make it consume large amounts of memory.
|
||||
|
||||
27 September 2016: Wouter
|
||||
- tag for 1.5.10 release
|
||||
- trunk contains 1.5.11 in development.
|
||||
- Fix dnstap relaying "random" messages instead of resolver/forwarder
|
||||
responses, from Nikolay Edigaryev.
|
||||
- Fix #836: unbound could echo back EDNS options in an error response.
|
||||
|
||||
20 September 2016: Wouter
|
||||
- iana portlist update.
|
||||
- Fix #835: fix --disable-dsa with nettle verify.
|
||||
- tag for 1.5.10rc1 release.
|
||||
|
||||
15 September 2016: Wouter
|
||||
- Fix 883: error for duplicate local zone entry.
|
||||
- Test for openssl init_crypto and init_ssl functions.
|
||||
|
||||
15 September 2016: Ralph
|
||||
- fix potential memory leak in daemon/remote.c and nullpointer
|
||||
dereference in validator/autotrust.
|
||||
- iana portlist update.
|
||||
|
||||
13 September 2016: Wouter
|
||||
- Silenced flex-generated sign-unsigned warning print with gcc
|
||||
diagnostic pragma.
|
||||
- Fix for new splint on FreeBSD. Fix cast for sockaddr_un.sun_len.
|
||||
|
||||
9 September 2016: Wouter
|
||||
- Fix #831: workaround for spurious fread_chk warning against petal.c
|
||||
|
||||
5 September 2016: Ralph
|
||||
- Take configured minimum TTL into consideration when reducing TTL
|
||||
to original TTL from RRSIG.
|
||||
|
||||
5 September 2016: Wouter
|
||||
- Fix #829: doc of sldns_wire2str_rdata_buf() return value has an
|
||||
off-by-one typo, from Jinmei Tatuya (Infoblox).
|
||||
- Fix incomplete prototypes reported by Dag-Erling Smørgrav.
|
||||
- Fix #828: missing type in access-control-tag-action redirect results
|
||||
in NXDOMAIN.
|
||||
|
||||
2 September 2016: Wouter
|
||||
- Fix compile with openssl 1.1.0 with api=1.1.0.
|
||||
|
||||
1 September 2016: Wouter
|
||||
- RFC 7958 is now out, updated docs for unbound-anchor.
|
||||
- Fix for compile without warnings with openssl 1.1.0.
|
||||
- Fix #826: Fix refuse_non_local could result in a broken response.
|
||||
- iana portlist update.
|
||||
|
||||
29 August 2016: Wouter
|
||||
- Fix #777: OpenSSL 1.1.0 compatibility, patch from Sebastian A.
|
||||
Siewior.
|
||||
- Add default root hints for IPv6 E.ROOT-SERVERS.NET, 2001:500:a8::e.
|
||||
|
||||
25 August 2016: Ralph
|
||||
- Clarify local-zone-override entry in unbound.conf.5
|
||||
|
||||
25 August 2016: Wouter
|
||||
- 64bit build option for makedist windows compile, -w64.
|
||||
|
||||
24 August 2016: Ralph
|
||||
- Fix #820: set sldns_str2wire_rr_buf() dual meaning len parameter
|
||||
in each iteration in find_tag_datas().
|
||||
- unbound.conf.5 entries for define-tag, access-control-tag,
|
||||
access-control-tag-action, access-control-tag-data, local-zone-tag,
|
||||
and local-zone-override.
|
||||
|
||||
23 August 2016: Wouter
|
||||
- Fix #804: unbound stops responding after outage. Fixes queries
|
||||
that attempt to wait for an empty list of subqueries.
|
||||
- Fix #804: lower num_target_queries for iterator also for failed
|
||||
lookups.
|
||||
|
||||
8 August 2016: Wouter
|
||||
- Note that OPENPGPKEY type is RFC 7929.
|
||||
|
||||
4 August 2016: Wouter
|
||||
- Fix #807: workaround for possible some "unused" function parameters
|
||||
in test code, from Jinmei Tatuya.
|
||||
|
||||
3 August 2016: Wouter
|
||||
- use sendmsg instead of sendto for TFO.
|
||||
|
||||
28 July 2016: Wouter
|
||||
- Fix #806: wrong comment removed.
|
||||
|
||||
26 July 2016: Wouter
|
||||
- nicer ratelimit-below-domain explanation.
|
||||
|
||||
22 July 2016: Wouter
|
||||
- Fix #801: missing error condition handling in
|
||||
daemon_create_workers().
|
||||
- Fix #802: workaround for function parameters that are "unused"
|
||||
without log_assert.
|
||||
- Fix #803: confusing (and incorrect) code comment in daemon_cleanup().
|
||||
|
||||
20 July 2016: Wouter
|
||||
- Fix typo in unbound.conf.
|
||||
|
||||
18 July 2016: Wouter
|
||||
- Fix #798: Client-side TCP fast open fails (Linux).
|
||||
|
||||
14 July 2016: Wouter
|
||||
- TCP Fast open patch from Sara Dickinson.
|
||||
- Fixed unbound.doxygen for 1.8.11.
|
||||
|
||||
7 July 2016: Wouter
|
||||
- access-control-tag-data implemented. verbose(4) prints tag debug.
|
||||
|
||||
5 July 2016: Wouter
|
||||
- Fix dynamic link of anchor-update.exe on windows.
|
||||
- Fix detect of mingw for MXE package build.
|
||||
- Fixes for 64bit windows compile.
|
||||
- Fix #788 for nettle 3.0: Failed to build with Nettle >= 3.0 and
|
||||
--with-libunbound-only --with-nettle.
|
||||
|
||||
4 July 2016: Wouter
|
||||
- For #787: prefer-ip6 option for unbound.conf prefers to send
|
||||
upstream queries to ipv6 servers.
|
||||
- Fix #787: outgoing-interface netblock/64 ipv6 option to use linux
|
||||
freebind to use 64bits of entropy for every query with random local
|
||||
part.
|
||||
|
||||
30 June 2016: Wouter
|
||||
- Document always_transparent, always_refuse, always_nxdomain types.
|
||||
|
||||
29 June 2016: Wouter
|
||||
- Fix static compile on windows missing gdi32.
|
||||
|
||||
28 June 2016: Wouter
|
||||
- Create a pkg-config file for libunbound in contrib.
|
||||
|
||||
27 June 2016: Wouter
|
||||
- Fix #784: Build configure assumess that having getpwnam means there
|
||||
is endpwent function available.
|
||||
- Updated repository with newer flex and bison output.
|
||||
|
||||
24 June 2016: Ralph
|
||||
- Possibility to specify local-zone type for an acl/tag pair
|
||||
- Possibility to specify (override) local-zone type for a source address
|
||||
block
|
||||
16 June 2016: Ralph
|
||||
- Decrease dp attempts at each QNAME minimisation iteration
|
||||
|
||||
16 June 2016: Wouter
|
||||
- Fix tcp timeouts in tv.usec.
|
||||
|
||||
15 June 2016: Wouter
|
||||
- TCP_TIMEOUT is specified in milliseconds.
|
||||
- If more than half of tcp connections are in use, a shorter timeout
|
||||
is used (200 msec, vs 2 minutes) to pressure tcp for new connects.
|
||||
|
||||
14 June 2016: Ralph
|
||||
- QNAME minimisation unit test for dropped QTYPE=A queries.
|
||||
|
||||
14 June 2016: Wouter
|
||||
- Fix 775: unbound-host and unbound-anchor crash on windows, ignore
|
||||
null delete for wsaevent.
|
||||
- Fix spelling in freebind option man page text.
|
||||
- Fix windows link of ssl with crypt32.
|
||||
- Fix 779: Union casting is non-portable.
|
||||
- Fix 780: MAP_ANON not defined in HP-UX 11.31.
|
||||
- Fix 781: prealloc() is an HP-UX system library call.
|
||||
|
||||
13 June 2016: Ralph
|
||||
- Use QTYPE=A for QNAME minimisation.
|
||||
- Keep track of number of time-outs when performing QNAME minimisation.
|
||||
Stop minimising when number of time-outs for a QNAME/QTYPE pair is
|
||||
more than three.
|
||||
|
||||
13 June 2016: Wouter
|
||||
- Fix #778: unbound 1.5.9: -h segfault (null deref).
|
||||
- Fix directory: fix for unbound-checkconf, it restores cwd.
|
||||
|
||||
10 June 2016: Wouter
|
||||
- And delete service.conf.shipped on uninstall.
|
||||
- In unbound.conf directory: dir immediately changes to that directory,
|
||||
so that include: file below that is relative to that directory.
|
||||
With chroot, make the directory an absolute path inside chroot.
|
||||
- keep debug symbols in windows build.
|
||||
- do not delete service.conf on windows uninstall.
|
||||
- document directory immediate fix and allow EXECUTABLE syntax in it
|
||||
on windows.
|
||||
|
||||
9 June 2016: Wouter
|
||||
- Trunk is called 1.5.10 (with previous fixes already in there to 2
|
||||
june).
|
||||
- Revert fix for NetworkService account on windows due to breakage
|
||||
it causes.
|
||||
- Fix that windows install will not overwrite existing service.conf
|
||||
file (and ignore gui config choices if it exists).
|
||||
|
||||
7 June 2016: Ralph
|
||||
- Lookup localzones by taglist from acl.
|
||||
- Possibility to lookup local_zone, regardless the taglist.
|
||||
- Added local_zone/taglist/acl unit test.
|
||||
|
||||
7 June 2016: Wouter
|
||||
- Fix #773: Non-standard Python location build failure with pyunbound.
|
||||
- Improve threadsafety for openssl 0.9.8 ecdsa dnssec signatures.
|
||||
|
||||
6 June 2016: Wouter
|
||||
- Better help text from -h (from Ray Griffith).
|
||||
- access-control-tag config directive.
|
||||
- local-zone-override config directive.
|
||||
- access-control-tag-action and access-control-tag-data config
|
||||
directives.
|
||||
- free acl-tags, acltag-action and acltag-data config lists during
|
||||
initialisation to free up memory for more entries.
|
||||
|
||||
3 June 2016: Wouter
|
||||
- Fix to not ignore return value of chown() in daemon startup.
|
||||
|
||||
2 June 2016: Wouter
|
||||
- Fix libubound for edns optlist feature.
|
||||
- Fix distinction between free and CRYPTO_free in dsa and ecdsa alloc.
|
||||
- Fix #752: retry resource temporarily unavailable on control pipe.
|
||||
- un-document localzone tags.
|
||||
- tag for release 1.5.9rc1.
|
||||
And this also became release 1.5.9.
|
||||
- Fix (for 1.5.10): Fix unbound-anchor.exe file location defaults to
|
||||
Program Files with (x86) appended.
|
||||
- re-documented localzone tags in example.conf.
|
||||
|
||||
31 May 2016: Wouter
|
||||
- Fix windows service to be created run with limited rights, as a
|
||||
|
||||
+99
-4
@@ -53,6 +53,15 @@ server:
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# Specify a netblock to use remainder 64 bits as random bits for
|
||||
# upstream queries. Uses freebind option (Linux).
|
||||
# outgoing-interface: 2001:DB8::/64
|
||||
# Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
|
||||
# And: ip -6 route add local 2001:db8::/64 dev lo
|
||||
# And set prefer-ip6: yes to use the ip6 randomness from a netblock.
|
||||
# Set this to yes to prefer ipv6 upstream servers over ipv4.
|
||||
# prefer-ip6: no
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously. About double the
|
||||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
@@ -163,6 +172,10 @@ server:
|
||||
# the maximum number of hosts that are cached (roundtrip, EDNS, lame).
|
||||
# infra-cache-numhosts: 10000
|
||||
|
||||
# define a number of tags here, use with local-zone, access-control.
|
||||
# repeat the define-tag statement to add additional tags.
|
||||
# define-tag: "tag1 tag2 tag3"
|
||||
|
||||
# Enable IPv4, "yes" or "no".
|
||||
# do-ip4: yes
|
||||
|
||||
@@ -187,7 +200,11 @@ server:
|
||||
# Default is 0, system default MSS.
|
||||
# outgoing-tcp-mss: 0
|
||||
|
||||
# Use systemd socket activation for UDP, TCP, and control sockets.
|
||||
# use-systemd: no
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
# Set the value to "no" when unbound runs as systemd service.
|
||||
# do-daemonize: yes
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
@@ -203,6 +220,23 @@ server:
|
||||
# access-control: ::1 allow
|
||||
# access-control: ::ffff:127.0.0.1 allow
|
||||
|
||||
# tag access-control with list of tags (in "" with spaces between)
|
||||
# Clients using this access control element use localzones that
|
||||
# are tagged with one of these tags.
|
||||
# access-control-tag: 192.0.2.0/24 "tag2 tag3"
|
||||
|
||||
# set action for particular tag for given access control element
|
||||
# if you have multiple tag values, the tag used to lookup the action
|
||||
# is the first tag match between access-control-tag and local-zone-tag
|
||||
# where "first" comes from the order of the define-tag values.
|
||||
# access-control-tag-action: 192.0.2.0/24 tag3 refuse
|
||||
|
||||
# set redirect data for particular tag for access control element
|
||||
# access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1"
|
||||
|
||||
# Set view for access control element
|
||||
# access-control-view: 192.0.2.0/24 viewname
|
||||
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
@@ -236,6 +270,8 @@ server:
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
# If you give a server: directory: dir before include: file statements
|
||||
# then those includes can be relative to the working directory.
|
||||
# directory: "@UNBOUND_RUN_DIR@"
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
@@ -243,15 +279,23 @@ server:
|
||||
# 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.
|
||||
# log to. If yes, it overrides the logfile.
|
||||
# use-syslog: yes
|
||||
|
||||
# Log identity to report. if empty, defaults to the name of argv[0]
|
||||
# (usually "unbound").
|
||||
# log-identity: ""
|
||||
|
||||
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
|
||||
# log-time-ascii: no
|
||||
|
||||
# print one line with time, IP, name, type, class for every query.
|
||||
# log-queries: no
|
||||
|
||||
# print one line per reply, with time, IP, name, type, class, rcode,
|
||||
# timetoresolve, fromcache and responsesize.
|
||||
# log-replies: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
@@ -299,7 +343,7 @@ server:
|
||||
# Harden against queries that fall under dnssec-signed nxdomain names.
|
||||
# harden-below-nxdomain: no
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
# implementation of draft-wijngaards-dnsext-resolver-side-mitigation.
|
||||
@@ -315,6 +359,12 @@ server:
|
||||
# to NS when possible.
|
||||
# qname-minimisation: no
|
||||
|
||||
# QNAME minimisation in strict mode. Do not fall-back to sending full
|
||||
# QNAME to potentially broken nameservers. A lot of domains will not be
|
||||
# resolvable when this option in enabled.
|
||||
# This option only has effect when qname-minimisation is enabled.
|
||||
# qname-minimisation-strict: no
|
||||
|
||||
# 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
|
||||
@@ -322,6 +372,7 @@ server:
|
||||
# Domains (and domains in them) without support for dns-0x20 and
|
||||
# the fallback fails because they keep sending different answers.
|
||||
# caps-whitelist: "licdn.com"
|
||||
# caps-whitelist: "senderbase.org"
|
||||
|
||||
# Enforce privacy of these addresses. Strips them away from answers.
|
||||
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||
@@ -447,6 +498,10 @@ server:
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
# Serve expired reponses from cache, with TTL 0 in the response,
|
||||
# and then attempt to fetch the data afresh.
|
||||
# serve-expired: no
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
|
||||
# val-log-level: 0
|
||||
@@ -548,8 +603,10 @@ server:
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
# o typetransparent resolves normally for other types and other names
|
||||
# o inform resolves normally, but logs client IP address
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
@@ -576,6 +633,12 @@ server:
|
||||
# you need to do the reverse notation yourself.
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
|
||||
# tag a localzone with a list of tag names (in "" with spaces between)
|
||||
# local-zone-tag: "example.com" "tag2 tag3"
|
||||
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL stream. Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
@@ -609,7 +672,21 @@ server:
|
||||
# ratelimit-for-domain: example.com 1000
|
||||
# override the ratelimits for all domains below a domain name
|
||||
# can give this multiple times, the name closest to the zone is used.
|
||||
# ratelimit-below-domain: example 1000
|
||||
# ratelimit-below-domain: com 1000
|
||||
|
||||
# global query ratelimit for all ip addresses.
|
||||
# feature is experimental.
|
||||
# if 0(default) it is disabled, otherwise states qps allowed per ip address
|
||||
# ip-ratelimit: 0
|
||||
|
||||
# ip ratelimits are tracked in a cache, size in bytes of cache (or k,m).
|
||||
# ip-ratelimit-size: 4m
|
||||
# ip ratelimit cache slabs, reduces lock contention if equal to cpucount.
|
||||
# ip-ratelimit-slabs: 4
|
||||
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
|
||||
# Python config section. To enable:
|
||||
# o use --with-pythonmodule to configure before compiling.
|
||||
@@ -662,6 +739,7 @@ remote-control:
|
||||
# stub-addr: 192.0.2.68
|
||||
# stub-prime: no
|
||||
# stub-first: no
|
||||
# stub-ssl-upstream: no
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
@@ -677,6 +755,23 @@ remote-control:
|
||||
# forward-addr: 192.0.2.68
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-first: no
|
||||
# forward-ssl-upstream: no
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
||||
|
||||
# Views
|
||||
# Create named views. Name must be unique. Map views to requests using
|
||||
# the access-control-view option. Views can contain zero or more local-zone
|
||||
# and local-data options. Options from matching views will override global
|
||||
# options. Global options will be used if no matching view is found.
|
||||
# With view-first yes, it will try to answer using the global local-zone and
|
||||
# local-data elements if there is no view specific match.
|
||||
# view:
|
||||
# name: "viewname"
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
# local-zone: "example.com" refuse
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@
|
||||
.B unbound.h,
|
||||
.B ub_ctx,
|
||||
.B ub_result,
|
||||
.B ub_callback_t,
|
||||
.B ub_callback_type,
|
||||
.B ub_ctx_create,
|
||||
.B ub_ctx_delete,
|
||||
.B ub_ctx_set_option,
|
||||
@@ -120,7 +120,7 @@
|
||||
.br
|
||||
\fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata,
|
||||
.br
|
||||
\fIub_callback_t\fR callback, \fIint*\fR async_id);
|
||||
\fIub_callback_type\fR callback, \fIint*\fR async_id);
|
||||
.LP
|
||||
\fIint\fR
|
||||
\fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id);
|
||||
@@ -180,7 +180,7 @@ and
|
||||
.B ub_ctx_hosts
|
||||
to read them.
|
||||
Before you call this, use the openssl functions CRYPTO_set_id_callback and
|
||||
CRYPTO_set_locking_callback to set up asyncronous operation if you use
|
||||
CRYPTO_set_locking_callback to set up asynchronous operation if you use
|
||||
lib openssl (the application calls these functions once for initialisation).
|
||||
Openssl 1.0.0 or later uses the CRYPTO_THREADID_set_callback function.
|
||||
.TP
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-anchor
|
||||
performs setup or update of the root trust anchor for DNSSEC validation.
|
||||
The program fetches the trust anchor with the method from RFC7958 when
|
||||
regular RFC5011 update fails to bring it up to date.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts. Before you start the \fIunbound\fR(8) DNS server.
|
||||
.P
|
||||
@@ -39,8 +41,8 @@ update certificate files.
|
||||
.P
|
||||
It tests if the root anchor file works, and if not, and an update is possible,
|
||||
attempts to update the root anchor using the root update certificate.
|
||||
It performs a https fetch of root-anchors.xml and checks the results, if
|
||||
all checks are successful, it updates the root anchor file. Otherwise
|
||||
It performs a https fetch of root-anchors.xml and checks the results (RFC7958),
|
||||
if all checks are successful, it updates the root anchor file. Otherwise
|
||||
the root anchor file is unchanged. It performs RFC5011 tracking if the
|
||||
DNSSEC information available via the DNS makes that possible.
|
||||
.P
|
||||
@@ -65,7 +67,7 @@ List the builtin root key and builtin root update certificate on stdout.
|
||||
.B \-u \fIname
|
||||
The server name, it connects to https://name. Specify without https:// prefix.
|
||||
The default is "data.iana.org". It connects to the port specified with \-P.
|
||||
You can pass an IPv4 addres or IPv6 address (no brackets) if you want.
|
||||
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
|
||||
.TP
|
||||
.B \-x \fIpath
|
||||
The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
|
||||
|
||||
@@ -99,6 +99,22 @@ but if the name has become an empty nonterminal (there is still data in
|
||||
domain names below the removed name), NOERROR nodata answers are the
|
||||
result for that name.
|
||||
.TP
|
||||
.B local_zones
|
||||
Add local zones read from stdin of unbound\-control. Input is read per line,
|
||||
with name space type on a line. For bulk additions.
|
||||
.TP
|
||||
.B local_zones_remove
|
||||
Remove local zones read from stdin of unbound\-control. Input is one name per
|
||||
line. For bulk removals.
|
||||
.TP
|
||||
.B local_datas
|
||||
Add local data RRs read from stdin of unbound\-control. Input is one RR per
|
||||
line. For bulk additions.
|
||||
.TP
|
||||
.B local_datas_remove
|
||||
Remove local data RRs read from stdin of unbound\-control. Input is one name per
|
||||
line. For bulk removals.
|
||||
.TP
|
||||
.B dump_cache
|
||||
The contents of the cache is printed in a text format to stdout. You can
|
||||
redirect it to a file to store the cache in a file.
|
||||
@@ -178,7 +194,7 @@ harden\-referral\-path, prefetch, prefetch\-key, log\-queries,
|
||||
hide\-identity, hide\-version, identity, version, val\-log\-level,
|
||||
val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown,
|
||||
keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size, ratelimit,
|
||||
cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl.
|
||||
ip\-ratelimit, cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl.
|
||||
.TP
|
||||
.B get_option \fIopt
|
||||
Get the value of the option. Give the option name without a trailing ':'.
|
||||
@@ -263,6 +279,30 @@ estimated qps and qps limit from config. With +a it prints all domains, not
|
||||
just the ratelimited domains, with their estimated qps. The ratelimited
|
||||
domains return an error for uncached (new) queries, but cached queries work
|
||||
as normal.
|
||||
.TP
|
||||
.B ip_ratelimit_list \fR[\fI+a\fR]
|
||||
List the ip addresses that are ratelimited. Printed one per line with current
|
||||
estimated qps and qps limit from config. With +a it prints all ips, not
|
||||
just the ratelimited ips, with their estimated qps. The ratelimited
|
||||
ips are dropped before checking the cache.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
.B view_local_zone \fIview\fR \fIname\fR \fItype
|
||||
\fIlocal_zone\fR for given view.
|
||||
.TP
|
||||
.B view_local_zone_remove \fIview\fR \fIname
|
||||
\fIlocal_zone_remove\fR for given view.
|
||||
.TP
|
||||
.B view_list_local_data \fIview\fR
|
||||
\fIlist_local_data\fR for given view.
|
||||
.TP
|
||||
.B view_local_data \fIview\fR \fIRR data...
|
||||
\fIlocal_data\fR for given view.
|
||||
.TP
|
||||
.B view_local_data_remove \fIview\fR \fIname
|
||||
\fIlocal_data_remove\fR for given view.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
@@ -288,6 +328,9 @@ The \fIstats\fR command shows a number of statistic counters.
|
||||
.I threadX.num.queries
|
||||
number of queries received by thread
|
||||
.TP
|
||||
.I threadX.num.queries_ip_ratelimited
|
||||
number of queries rate limited by thread
|
||||
.TP
|
||||
.I threadX.num.cachehits
|
||||
number of queries that were successfully answered using a cache lookup
|
||||
.TP
|
||||
@@ -301,6 +344,9 @@ and resulted in recursive processing, taking a slot in the requestlist.
|
||||
Not part of the recursivereplies (or the histogram thereof) or cachemiss,
|
||||
as a cache response was sent.
|
||||
.TP
|
||||
.I threadX.num.zero_ttl
|
||||
number of replies with ttl zero, because they served an expired cache entry.
|
||||
.TP
|
||||
.I threadX.num.recursivereplies
|
||||
The number of replies sent to queries that needed recursive processing. Could be smaller than threadX.num.cachemiss if due to timeouts no replies were sent for some queries.
|
||||
.TP
|
||||
@@ -350,6 +396,9 @@ summed over threads.
|
||||
.I total.num.prefetch
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.zero_ttl
|
||||
summed over threads.
|
||||
.TP
|
||||
.I total.num.recursivereplies
|
||||
summed over threads.
|
||||
.TP
|
||||
@@ -384,9 +433,6 @@ uptime since server boot in seconds.
|
||||
time since last statistics printout, in seconds.
|
||||
.SH EXTENDED STATISTICS
|
||||
.TP
|
||||
.I mem.total.sbrk
|
||||
If sbrk(2) is available, an estimate of the heap size of the program in number of bytes. Close to the total memory used by the program, as reported by top and ps. Could be wrong if the OS allocates memory non\-contiguously.
|
||||
.TP
|
||||
.I mem.cache.rrset
|
||||
Memory in bytes in use by the RRset cache.
|
||||
.TP
|
||||
|
||||
+184
-15
@@ -72,7 +72,8 @@ Processing continues as if the text from the included file was copied into
|
||||
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. Wildcards can be used to include multiple files, see \fIglob\fR(7).
|
||||
directory or is specified before the include statement with directory: dir.
|
||||
Wildcards can be used to include multiple files, see \fIglob\fR(7).
|
||||
.SS "Server Options"
|
||||
These options are part of the
|
||||
.B server:
|
||||
@@ -126,7 +127,7 @@ Detect source interface on UDP queries and copy them to replies. This
|
||||
feature is experimental, and needs support in your OS for particular socket
|
||||
options. Default value is no.
|
||||
.TP
|
||||
.B outgoing\-interface: \fI<ip address>
|
||||
.B outgoing\-interface: \fI<ip address or ip6 netblock>
|
||||
Interface to use to connect to the network. This interface is used to send
|
||||
queries to authoritative servers and receive their replies. Can be given
|
||||
multiple times to work on several interfaces. If none are given the
|
||||
@@ -136,12 +137,28 @@ and
|
||||
.B outgoing\-interface:
|
||||
lines, the interfaces are then used for both purposes. Outgoing queries are
|
||||
sent via a random outgoing interface to counter spoofing.
|
||||
.IP
|
||||
If an IPv6 netblock is specified instead of an individual IPv6 address,
|
||||
outgoing UDP queries will use a randomised source address taken from the
|
||||
netblock to counter spoofing. Requires the IPv6 netblock to be routed to the
|
||||
host running unbound, and requires OS support for unprivileged non-local binds
|
||||
(currently only supported on Linux). Several netblocks may be specified with
|
||||
multiple
|
||||
.B outgoing\-interface:
|
||||
options, but do not specify both an individual IPv6 address and an IPv6
|
||||
netblock, or the randomisation will be compromised. Consider combining with
|
||||
.B prefer\-ip6: yes
|
||||
to increase the likelihood of IPv6 nameservers being selected for queries.
|
||||
On Linux you need these two commands to be able to use the freebind socket
|
||||
option to receive traffic for the ip6 netblock:
|
||||
ip \-6 addr add mynetblock/64 dev lo &&
|
||||
ip \-6 route add local mynetblock/64 dev lo
|
||||
.TP
|
||||
.B outgoing\-range: \fI<number>
|
||||
Number of ports to open. This number of file descriptors can be opened per
|
||||
thread. Must be at least 1. Default depends on compile options. Larger
|
||||
numbers need extra resources from the operating system. For performance a
|
||||
a very large value is best, use libevent to make this possible.
|
||||
very large value is best, use libevent to make this possible.
|
||||
.TP
|
||||
.B outgoing\-port\-permit: \fI<port number or range>
|
||||
Permit unbound to open this port or range of ports for use to send queries.
|
||||
@@ -281,7 +298,7 @@ permissions on some systems. The option uses IP_BINDANY on FreeBSD systems.
|
||||
If yes, then use IP_FREEBIND socket option on sockets where unbound
|
||||
is listening to incoming traffic. Default no. Allows you to bind to
|
||||
IP addresses that are nonlocal or do not exist, like when the network
|
||||
interface or IP adress is down. Exists only on Linux, where the similar
|
||||
interface or IP address is down. Exists only on Linux, where the similar
|
||||
ip\-transparent option is also available.
|
||||
.TP
|
||||
.B rrset\-cache\-size: \fI<number>
|
||||
@@ -329,6 +346,10 @@ Lower limit for dynamic retransmit timeout calculation in infrastructure
|
||||
cache. Default is 50 milliseconds. Increase this value if using forwarders
|
||||
needing more time to do recursive name resolution.
|
||||
.TP
|
||||
.B define\-tag: \fI<"list of tags">
|
||||
Define the tags that can be used with local\-zone and access\-control.
|
||||
Enclose the list between quotes ("") and put spaces between tags.
|
||||
.TP
|
||||
.B do\-ip4: \fI<yes or no>
|
||||
Enable or disable whether ip4 queries are answered or issued. Default is yes.
|
||||
.TP
|
||||
@@ -339,6 +360,10 @@ IPv6 to the internet nameservers. With this option you can disable the
|
||||
ipv6 transport for sending DNS traffic, it does not impact the contents of
|
||||
the DNS traffic, which may have ip4 and ip6 addresses in it.
|
||||
.TP
|
||||
.B prefer\-ip6: \fI<yes or no>
|
||||
If enabled, prefer IPv6 transport for sending DNS queries to internet
|
||||
nameservers. Default is no.
|
||||
.TP
|
||||
.B do\-udp: \fI<yes or no>
|
||||
Enable or disable whether UDP queries are answered or issued. Default is yes.
|
||||
.TP
|
||||
@@ -388,9 +413,14 @@ turned off.
|
||||
The port number on which to provide TCP SSL service, default 853, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
.TP
|
||||
.B do\-daemonize: \fI<yes or no>
|
||||
Enable or disable whether the unbound server forks into the background as
|
||||
a daemon. Default is yes.
|
||||
a daemon. Set the value to \fIno\fR when unbound runs as systemd service.
|
||||
Default is yes.
|
||||
.TP
|
||||
.B access\-control: \fI<IP netblock> <action>
|
||||
The netblock is given as an IP4 or IP6 address with /size appended for a
|
||||
@@ -432,6 +462,26 @@ allowed full recursion but only the static data. With deny_non_local,
|
||||
messages that are disallowed are dropped, with refuse_non_local they
|
||||
receive error code REFUSED.
|
||||
.TP
|
||||
.B access\-control\-tag: \fI<IP netblock> <"list of tags">
|
||||
Assign tags to access-control elements. Clients using this access control
|
||||
element use localzones that are tagged with one of these tags. Tags must be
|
||||
defined in \fIdefine\-tags\fR. Enclose list of tags in quotes ("") and put
|
||||
spaces between tags. If access\-control\-tag is configured for a netblock that
|
||||
does not have an access\-control, an access\-control element with action
|
||||
\fIallow\fR is configured for this netblock.
|
||||
.TP
|
||||
.B access\-control\-tag\-action: \fI<IP netblock> <tag> <action>
|
||||
Set action for particular tag for given access control element. If you have
|
||||
multiple tag values, the tag used to lookup the action is the first tag match
|
||||
between access\-control\-tag and local\-zone\-tag where "first" comes from the
|
||||
order of the define-tag values.
|
||||
.TP
|
||||
.B access\-control\-tag\-data: \fI<IP netblock> <tag> <"resource record string">
|
||||
Set redirect data for particular tag for given access control element.
|
||||
.TP
|
||||
.B access\-control\-view: \fI<IP netblock> <view name>
|
||||
Set view for given access control element.
|
||||
.TP
|
||||
.B chroot: \fI<directory>
|
||||
If chroot is enabled, you should pass the configfile (from the
|
||||
commandline) as a full path from the original root. After the
|
||||
@@ -469,6 +519,8 @@ requires privileges, then a reload will fail; a restart is needed.
|
||||
Sets the working directory for the program. Default is "@UNBOUND_RUN_DIR@".
|
||||
On Windows the string "%EXECUTABLE%" tries to change to the directory
|
||||
that unbound.exe resides in.
|
||||
If you give a server: directory: dir before include: file statements
|
||||
then those includes can be relative to the working directory.
|
||||
.TP
|
||||
.B logfile: \fI<filename>
|
||||
If "" is given, logging goes to stderr, or nowhere once daemonized.
|
||||
@@ -487,6 +539,13 @@ 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\-identity: \fI<string>
|
||||
If "" is given (default), then the name of the executable, usually "unbound"
|
||||
is used to report to the log. Enter a string to override it
|
||||
with that, which is useful on systems that run more than one instance of
|
||||
unbound, with different configurations, so that the logs can be easily
|
||||
distinguished against.
|
||||
.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
|
||||
@@ -498,6 +557,13 @@ name, type and class. Default is no. Note that it takes time to print these
|
||||
lines which makes the server (significantly) slower. Odd (nonprintable)
|
||||
characters in names are printed as '?'.
|
||||
.TP
|
||||
.B log\-replies: \fI<yes or no>
|
||||
Prints one line per reply to the log, with the log timestamp and IP address,
|
||||
name, type, class, return code, time to resolve, from cache and response size.
|
||||
Default is no. Note that it takes time to print these
|
||||
lines which makes the server (significantly) slower. Odd (nonprintable)
|
||||
characters in names are printed as '?'.
|
||||
.TP
|
||||
.B pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
@@ -570,14 +636,15 @@ unsigned to badly signed often. If turned off you run the risk of a
|
||||
downgrade attack that disables security for a zone. Default is on.
|
||||
.TP
|
||||
.B harden\-below\-nxdomain: \fI<yes or no>
|
||||
From draft\-vixie\-dnsext\-resimprove, returns nxdomain to queries for a name
|
||||
From RFC 8020 (with title "NXDOMAIN: There Really Is Nothing Underneath"),
|
||||
returns nxdomain to queries for a name
|
||||
below another name that is already known to be nxdomain. DNSSEC mandates
|
||||
noerror for empty nonterminals, hence this is possible. Very old software
|
||||
might return nxdomain for empty nonterminals (that usually happen for reverse
|
||||
IP address lookups), and thus may be incompatible with this. To try to avoid
|
||||
this only DNSSEC-secure nxdomains are used, because the old software does not
|
||||
have DNSSEC. Default is off.
|
||||
Currently, draft\-ietf\-dnsop\-nxdomain\-cut promotes this technique.
|
||||
The nxdomain must be secure, this means nsec3 with optout is insufficient.
|
||||
.TP
|
||||
.B harden\-referral\-path: \fI<yes or no>
|
||||
Harden the referral path by performing additional queries for
|
||||
@@ -614,8 +681,15 @@ Can be given multiple times, for different domains.
|
||||
.B qname\-minimisation: \fI<yes or no>
|
||||
Send minimum amount of information to upstream servers to enhance privacy.
|
||||
Only sent minimum required labels of the QNAME and set QTYPE to NS when
|
||||
possible. Best effort approach, full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR. Default is off.
|
||||
possible. Best effort approach; full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR, except when receiving
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is off.
|
||||
.TP
|
||||
.B qname\-minimisation\-strict: \fI<yes or no>
|
||||
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
|
||||
potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
@@ -815,6 +889,11 @@ servers that set the CD flag but cannot validate DNSSEC themselves are
|
||||
the clients, and then unbound provides them with DNSSEC protection.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B serve\-expired: \fI<yes or no>
|
||||
If enabled, unbound attempts to serve old responses from cache with a
|
||||
TTL of 0 in the response without waiting for the actual resolution to finish.
|
||||
The actual resolution answer ends up in the cache later on. Default is "no".
|
||||
.TP
|
||||
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
|
||||
List of keysize and iteration count values, separated by spaces, surrounded
|
||||
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
|
||||
@@ -883,6 +962,7 @@ address space are not validated. This is usually required whenever
|
||||
Configure a local zone. The type determines the answer to give if
|
||||
there is no match from local\-data. The types are deny, refuse, static,
|
||||
transparent, redirect, nodefault, typetransparent, inform, inform_deny,
|
||||
always_transparent, always_refuse, always_nxdomain,
|
||||
and are explained below. After that the default settings are listed. Use
|
||||
local\-data: to enter data into the local zone. Answers for local zones
|
||||
are authoritative DNS answers. By default the zones are class IN.
|
||||
@@ -933,16 +1013,25 @@ 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'\fIinform\fR
|
||||
The query is answered normally. The client IP address (@portnumber)
|
||||
is printed to the logfile. The log message is: timestamp, unbound-pid,
|
||||
info: zonename inform IP@port queryname type class. This option can be
|
||||
used for normal resolution, but machines looking up infected names are
|
||||
logged, eg. to run antivirus on them.
|
||||
The query is answered normally, same as transparent. The client IP
|
||||
address (@portnumber) is printed to the logfile. The log message is:
|
||||
timestamp, unbound-pid, info: zonename inform IP@port queryname type
|
||||
class. This option can be used for normal resolution, but machines
|
||||
looking up infected names are logged, eg. to run antivirus on them.
|
||||
.TP 10
|
||||
\h'5'\fIinform_deny\fR
|
||||
The query is dropped, like 'deny', and logged, like 'inform'. Ie. find
|
||||
infected machines without answering the queries.
|
||||
.TP 10
|
||||
\h'5'\fIalways_transparent\fR
|
||||
Like transparent, but ignores local data and resolves normally.
|
||||
.TP 10
|
||||
\h'5'\fIalways_refuse\fR
|
||||
Like refuse, but ignores local data and refuses the query.
|
||||
.TP 10
|
||||
\h'5'\fIalways_nxdomain\fR
|
||||
Like static, but ignores local data and returns nxdomain for the query.
|
||||
.TP 10
|
||||
\h'5'\fInodefault\fR
|
||||
Used to turn off default contents for AS112 zones. The other types
|
||||
also turn off default contents for the zone. The 'nodefault' option
|
||||
@@ -1060,6 +1149,18 @@ Configure local data shorthand for a PTR record with the reversed IPv4 or
|
||||
IPv6 address and the host name. For example "192.0.2.4 www.example.com".
|
||||
TTL can be inserted like this: "2001:DB8::4 7200 www.example.com"
|
||||
.TP 5
|
||||
.B local\-zone\-tag: \fI<zone> <"list of tags">
|
||||
Assign tags to localzones. Tagged localzones will only be applied when the
|
||||
used access-control element has a matching tag. Tags must be defined in
|
||||
\fIdefine\-tags\fR. Enclose list of tags in quotes ("") and put spaces between
|
||||
tags.
|
||||
.TP 5
|
||||
.B local\-zone\-override: \fI<zone> <IP netblock> <type>
|
||||
Override the localzone type for queries from addresses matching netblock.
|
||||
Use this localzone type, regardless the type configured for the local-zone
|
||||
(both tagged and untagged) and regardless the type configured using
|
||||
access\-control\-tag\-action.
|
||||
.TP 5
|
||||
.B ratelimit: \fI<number or 0>
|
||||
Enable ratelimiting of queries sent to nameserver for performing recursion.
|
||||
If 0, the default, it is disabled. This option is experimental at this time.
|
||||
@@ -1104,6 +1205,34 @@ in different parts of the namespace. The closest matching suffix is used
|
||||
to determine the qps limit. The rate for the exact matching domain name
|
||||
is not changed, use ratelimit\-for\-domain to set that, you might want
|
||||
to use different settings for a top\-level\-domain and subdomains.
|
||||
.TP 5
|
||||
.B ip\-ratelimit: \fI<number or 0>
|
||||
Enable global ratelimiting of queries accepted per ip address.
|
||||
If 0, the default, it is disabled. This option is experimental at this time.
|
||||
The ratelimit is in queries per second that are allowed. More queries are
|
||||
completely dropped and will not receive a reply, SERVFAIL or otherwise.
|
||||
IP ratelimiting happens before looking in the cache. This may be useful for
|
||||
mitigating amplification attacks.
|
||||
.TP 5
|
||||
.B ip\-ratelimit\-size: \fI<memory size>
|
||||
Give the size of the data structure in which the current ongoing rates are
|
||||
kept track in. Default 4m. In bytes or use m(mega), k(kilo), g(giga).
|
||||
The ip ratelimit structure is small, so this data structure likely does
|
||||
not need to be large.
|
||||
.TP 5
|
||||
.B ip\-ratelimit\-slabs: \fI<number>
|
||||
Give power of 2 number of slabs, this is used to reduce lock contention
|
||||
in the ip ratelimit tracking data structure. Close to the number of cpus is
|
||||
a fairly good setting.
|
||||
.TP 5
|
||||
.B ip\-ratelimit\-factor: \fI<number>
|
||||
Set the amount of queries to rate limit when the limit is exceeded.
|
||||
If set to 0, all queries are dropped for addresses where the limit is
|
||||
exceeded. If set to another value, 1 in that number is allowed through
|
||||
to complete. Default is 10, allowing 1/10 traffic to flow normally.
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
@@ -1214,6 +1343,10 @@ If enabled, a query is attempted without the stub clause if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because
|
||||
the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use SSL for transport.
|
||||
Default is no.
|
||||
.SS "Forward Zone Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
@@ -1244,6 +1377,36 @@ If enabled, a query is attempted without the forward clause if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because
|
||||
the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use SSL for transport.
|
||||
Default is no.
|
||||
.SS "View Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
.B view:
|
||||
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
|
||||
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the view
|
||||
name in an \fBaccess\-control\-view\fR element. Options from matching views will
|
||||
override global options. Global options will be used if no matching view
|
||||
is found.
|
||||
.TP
|
||||
.B name: \fI<view name>
|
||||
Name of the view. Must be unique. This name is used in access\-control\-view
|
||||
elements.
|
||||
.TP
|
||||
.B local\-zone: \fI<zone> <type>
|
||||
View specific local\-zone elements. Has the same types and behaviour as the
|
||||
global local\-zone elements.
|
||||
.TP
|
||||
.B local\-data: \fI"<resource record string>"
|
||||
View specific local\-data elements. Has the same behaviour as the global
|
||||
local\-data elements.
|
||||
.TP
|
||||
.B view\-first: \fI<yes or no>
|
||||
If enabled, it attempts to use the global local\-zone and local\-data if there
|
||||
is no match in the view specific options.
|
||||
The default is no.
|
||||
.SS "Python Module Options"
|
||||
.LP
|
||||
The
|
||||
@@ -1253,9 +1416,15 @@ acts like the iterator and validator modules do, on queries and answers.
|
||||
To enable the script module it has to be compiled into the daemon,
|
||||
and the word "python" has to be put in the \fBmodule\-config:\fR option
|
||||
(usually first, or between the validator and iterator).
|
||||
.LP
|
||||
If the \fBchroot:\fR option is enabled, you should make sure Python's
|
||||
library directory structure is bind mounted in the new root environment, see
|
||||
\fImount\fR(8). Also the \fBpython\-script:\fR path should be specified as an
|
||||
absolute path relative to the new root, or as a relative path to the working
|
||||
directory.
|
||||
.TP
|
||||
.B python\-script: \fI<python file>\fR
|
||||
The script file to load.
|
||||
The script file to load.
|
||||
.SS "DNS64 Module Options"
|
||||
.LP
|
||||
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
||||
|
||||
+3
-1
@@ -623,7 +623,9 @@ EXCLUDE = ./build \
|
||||
pythonmod/examples/resip.py \
|
||||
libunbound/python/unbound.py \
|
||||
libunbound/python/libunbound_wrap.c \
|
||||
./ldns-src
|
||||
./ldns-src \
|
||||
doc/control_proto_spec.txt \
|
||||
doc/requirements.txt
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
|
||||
# directories that are symbolic links (a Unix filesystem feature) are excluded
|
||||
|
||||
+164
-190
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2011-11-20.07; # UTC
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
@@ -68,17 +64,6 @@ mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
@@ -97,7 +82,7 @@ dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
@@ -137,46 +122,57 @@ while test $# -ne 0; do
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
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.
|
||||
@@ -207,6 +203,15 @@ if test $# -eq 0; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
@@ -223,16 +228,16 @@ if test -z "$dir_arg"; then
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
@@ -269,41 +274,15 @@ do
|
||||
# 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
|
||||
if test "$is_target_a_directory" = never; 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'
|
||||
`
|
||||
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
@@ -314,74 +293,74 @@ do
|
||||
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;;
|
||||
# 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
|
||||
*[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
|
||||
mkdir_mode=
|
||||
fi
|
||||
# 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
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
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
|
||||
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 (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-writable 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;;
|
||||
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-writable 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"
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
@@ -391,53 +370,51 @@ do
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
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/
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
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
|
||||
|
||||
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
|
||||
# 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
|
||||
@@ -472,15 +449,12 @@ do
|
||||
|
||||
# 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` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
@@ -493,24 +467,24 @@ do
|
||||
# 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
|
||||
}
|
||||
} &&
|
||||
# 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
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||
return NULL;
|
||||
copy->bogus = dp->bogus;
|
||||
copy->has_parent_side_NS = dp->has_parent_side_NS;
|
||||
copy->ssl_upstream = dp->ssl_upstream;
|
||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||
if(!delegpt_add_ns(copy, region, ns->name, ns->lame))
|
||||
return NULL;
|
||||
|
||||
@@ -81,6 +81,8 @@ struct delegpt {
|
||||
uint8_t has_parent_side_NS;
|
||||
/** for assertions on type of delegpt */
|
||||
uint8_t dp_type_mlc;
|
||||
/** use SSL for upstream query */
|
||||
uint8_t ssl_upstream;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -355,7 +357,7 @@ void delegpt_no_ipv4(struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* create malloced delegation point, with the given name
|
||||
* @param name: uncompressed wireformat of degegpt name.
|
||||
* @param name: uncompressed wireformat of delegpt name.
|
||||
* @return NULL on alloc failure
|
||||
*/
|
||||
struct delegpt* delegpt_create_mlc(uint8_t* name);
|
||||
|
||||
@@ -58,7 +58,7 @@ struct iter_donotq {
|
||||
* contents of type addr_tree_node. Each node is an address span
|
||||
* that must not be used to send queries to.
|
||||
*/
|
||||
rbtree_t tree;
|
||||
rbtree_type tree;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+6
-4
@@ -82,7 +82,7 @@ static void fwd_zone_free(struct iter_forward_zone* n)
|
||||
free(n);
|
||||
}
|
||||
|
||||
static void delfwdnode(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||
static void delfwdnode(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct iter_forward_zone* node = (struct iter_forward_zone*)n;
|
||||
fwd_zone_free(node);
|
||||
@@ -265,6 +265,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
* last resort will ask for parent-side NS record and thus
|
||||
* fallback to the internet name servers on a failure */
|
||||
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
|
||||
/* use SSL for queries to this forwarder */
|
||||
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
|
||||
verbose(VERB_QUERY, "Forward zone server list:");
|
||||
delegpt_log(VERB_QUERY, dp);
|
||||
if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp))
|
||||
@@ -330,7 +332,7 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
struct delegpt*
|
||||
forwards_find(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
|
||||
{
|
||||
rbnode_t* res = NULL;
|
||||
rbnode_type* res = NULL;
|
||||
struct iter_forward_zone key;
|
||||
key.node.key = &key;
|
||||
key.dclass = qclass;
|
||||
@@ -345,7 +347,7 @@ struct delegpt*
|
||||
forwards_lookup(struct iter_forwards* fwd, uint8_t* qname, uint16_t qclass)
|
||||
{
|
||||
/* lookup the forward zone in the tree */
|
||||
rbnode_t* res = NULL;
|
||||
rbnode_type* res = NULL;
|
||||
struct iter_forward_zone *result;
|
||||
struct iter_forward_zone key;
|
||||
key.node.key = &key;
|
||||
@@ -386,7 +388,7 @@ int
|
||||
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
|
||||
{
|
||||
struct iter_forward_zone key;
|
||||
rbnode_t* n;
|
||||
rbnode_type* n;
|
||||
struct iter_forward_zone* p;
|
||||
if(*dclass == 0) {
|
||||
/* first root item is first item in tree */
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ struct iter_forwards {
|
||||
* match which gives the ancestor needed.
|
||||
* contents of type iter_forward_zone.
|
||||
*/
|
||||
rbtree_t* tree;
|
||||
rbtree_type* tree;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,7 +65,7 @@ struct iter_forwards {
|
||||
*/
|
||||
struct iter_forward_zone {
|
||||
/** redblacktree node, key is this structure: class and name */
|
||||
rbnode_t node;
|
||||
rbnode_type node;
|
||||
/** name */
|
||||
uint8_t* name;
|
||||
/** length of name */
|
||||
|
||||
@@ -67,7 +67,7 @@ static void hints_stub_free(struct iter_hints_stub* s)
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void delhintnode(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||
static void delhintnode(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct iter_hints_stub* node = (struct iter_hints_stub*)n;
|
||||
hints_stub_free(node);
|
||||
@@ -147,7 +147,9 @@ compile_time_root_prime(int do_ip4, int do_ip6)
|
||||
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:84::b")) goto failed;
|
||||
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
|
||||
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
|
||||
if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
|
||||
if(!ah(dp, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) goto failed;
|
||||
if(!ah(dp, "G.ROOT-SERVERS.NET.", "2001:500:12::d0d")) goto failed;
|
||||
if(!ah(dp, "H.ROOT-SERVERS.NET.", "2001:500:1::53")) goto failed;
|
||||
if(!ah(dp, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) goto failed;
|
||||
if(!ah(dp, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) goto failed;
|
||||
@@ -274,6 +276,8 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||
* last resort will ask for parent-side NS record and thus
|
||||
* fallback to the internet name servers on a failure */
|
||||
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
|
||||
/* ssl_upstream */
|
||||
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
|
||||
delegpt_log(VERB_QUERY, dp);
|
||||
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime))
|
||||
return 0;
|
||||
|
||||
@@ -59,7 +59,7 @@ struct iter_hints {
|
||||
* contents of type iter_hints_stub. The class IN root is in here.
|
||||
* uses name_tree_node from dnstree.h.
|
||||
*/
|
||||
rbtree_t tree;
|
||||
rbtree_type tree;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,14 +60,14 @@ struct iter_priv {
|
||||
* contents of type addr_tree_node.
|
||||
* No further data need, only presence or absence.
|
||||
*/
|
||||
rbtree_t a;
|
||||
rbtree_type a;
|
||||
/**
|
||||
* Tree of the domains spans that are allowed to contain
|
||||
* the blocked address spans.
|
||||
* contents of type name_tree_node.
|
||||
* No further data need, only presence or absence.
|
||||
*/
|
||||
rbtree_t n;
|
||||
rbtree_type n;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -161,8 +161,8 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
for(rr = rrset->rr_first; rr; rr = rr->next) {
|
||||
if(get_additional_name(rrset, rr, &nm, &nmlen, pkt)) {
|
||||
/* mark A */
|
||||
hashvalue_t h = pkt_hash_rrset(pkt, nm, LDNS_RR_TYPE_A,
|
||||
rrset->rrset_class, 0);
|
||||
hashvalue_type h = pkt_hash_rrset(pkt, nm,
|
||||
LDNS_RR_TYPE_A, rrset->rrset_class, 0);
|
||||
struct rrset_parse* r = msgparse_hashtable_lookup(
|
||||
msg, pkt, h, 0, nm, nmlen,
|
||||
LDNS_RR_TYPE_A, rrset->rrset_class);
|
||||
|
||||
+35
-1
@@ -108,7 +108,7 @@ read_fetch_policy(struct iter_env* ie, const char* str)
|
||||
|
||||
/** apply config caps whitelist items to name tree */
|
||||
static int
|
||||
caps_white_apply_cfg(rbtree_t* ntree, struct config_file* cfg)
|
||||
caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
for(p=cfg->caps_whitelist; p; p=p->next) {
|
||||
@@ -360,6 +360,39 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
}
|
||||
}
|
||||
*selected_rtt = low_rtt;
|
||||
|
||||
if (env->cfg->prefer_ip6) {
|
||||
int got_num6 = 0;
|
||||
int low_rtt6 = 0;
|
||||
int i;
|
||||
prev = NULL;
|
||||
a = dp->result_list;
|
||||
for(i = 0; i < got_num; i++) {
|
||||
swap_to_front = 0;
|
||||
if(a->addr.ss_family == AF_INET6) {
|
||||
got_num6++;
|
||||
swap_to_front = 1;
|
||||
if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) {
|
||||
low_rtt6 = a->sel_rtt;
|
||||
}
|
||||
}
|
||||
/* swap to front if IPv6, or move to next result */
|
||||
if(swap_to_front && prev) {
|
||||
n = a->next_result;
|
||||
prev->next_result = n;
|
||||
a->next_result = dp->result_list;
|
||||
dp->result_list = a;
|
||||
a = n;
|
||||
} else {
|
||||
prev = a;
|
||||
a = a->next_result;
|
||||
}
|
||||
}
|
||||
if(got_num6 > 0) {
|
||||
got_num = got_num6;
|
||||
*selected_rtt = low_rtt6;
|
||||
}
|
||||
}
|
||||
return got_num;
|
||||
}
|
||||
|
||||
@@ -499,6 +532,7 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
||||
qinf.qname_len = namelen;
|
||||
qinf.qtype = t;
|
||||
qinf.qclass = c;
|
||||
qinf.local_alias = NULL;
|
||||
fptr_ok(fptr_whitelist_modenv_detect_cycle(
|
||||
qstate->env->detect_cycle));
|
||||
return (*qstate->env->detect_cycle)(qstate, &qinf,
|
||||
|
||||
+116
-82
@@ -88,7 +88,7 @@ iter_init(struct module_env* env, int id)
|
||||
|
||||
/** delete caps_whitelist element */
|
||||
static void
|
||||
caps_free(struct rbnode_t* n, void* ATTR_UNUSED(d))
|
||||
caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
|
||||
{
|
||||
if(n) {
|
||||
free(((struct name_tree_node*)n)->name);
|
||||
@@ -148,6 +148,7 @@ iter_new(struct module_qstate* qstate, int id)
|
||||
iq->qchase = qstate->qinfo;
|
||||
outbound_list_init(&iq->outlist);
|
||||
iq->minimise_count = 0;
|
||||
iq->minimise_timeout_count = 0;
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
else
|
||||
@@ -215,6 +216,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
|
||||
/* mark address as failed. */
|
||||
struct delegpt_ns* dpns = NULL;
|
||||
super_iq->num_target_queries--;
|
||||
if(super_iq->dp)
|
||||
dpns = delegpt_find_ns(super_iq->dp,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len);
|
||||
@@ -228,13 +230,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
return;
|
||||
} else {
|
||||
/* see if the failure did get (parent-lame) info */
|
||||
if(!cache_fill_missing(super->env,
|
||||
super_iq->qchase.qclass, super->region,
|
||||
super_iq->dp))
|
||||
if(!cache_fill_missing(super->env, super_iq->qchase.qclass,
|
||||
super->region, super_iq->dp))
|
||||
log_err("out of memory adding missing");
|
||||
}
|
||||
dpns->resolved = 1; /* mark as failed */
|
||||
super_iq->num_target_queries--;
|
||||
}
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
|
||||
/* prime failed to get delegation */
|
||||
@@ -277,27 +277,29 @@ error_response(struct module_qstate* qstate, int id, int rcode)
|
||||
static int
|
||||
error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
{
|
||||
/* store in cache */
|
||||
struct reply_info err;
|
||||
if(qstate->prefetch_leeway > NORR_TTL) {
|
||||
verbose(VERB_ALGO, "error response for prefetch in cache");
|
||||
/* attempt to adjust the cache entry prefetch */
|
||||
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
|
||||
NORR_TTL, qstate->query_flags))
|
||||
return error_response(qstate, id, rcode);
|
||||
/* if that fails (not in cache), fall through to store err */
|
||||
if(!qstate->no_cache_store) {
|
||||
/* store in cache */
|
||||
struct reply_info err;
|
||||
if(qstate->prefetch_leeway > NORR_TTL) {
|
||||
verbose(VERB_ALGO, "error response for prefetch in cache");
|
||||
/* attempt to adjust the cache entry prefetch */
|
||||
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
|
||||
NORR_TTL, qstate->query_flags))
|
||||
return error_response(qstate, id, rcode);
|
||||
/* if that fails (not in cache), fall through to store 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;
|
||||
err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
|
||||
qstate->query_flags);
|
||||
}
|
||||
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;
|
||||
err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
|
||||
qstate->query_flags);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
|
||||
@@ -550,6 +552,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
qinf.qname_len = qnamelen;
|
||||
qinf.qtype = qtype;
|
||||
qinf.qclass = qclass;
|
||||
qinf.local_alias = NULL;
|
||||
|
||||
/* RD should be set only when sending the query back through the INIT
|
||||
* state. */
|
||||
@@ -967,7 +970,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
{
|
||||
uint8_t* delname;
|
||||
size_t delnamelen;
|
||||
struct dns_msg* msg;
|
||||
struct dns_msg* msg = NULL;
|
||||
|
||||
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
|
||||
/* check effort */
|
||||
@@ -1007,13 +1010,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* getting older results from cache is a bad idea, no cache */
|
||||
verbose(VERB_ALGO, "cache blacklisted, going to the network");
|
||||
msg = NULL;
|
||||
} else {
|
||||
} else if(!qstate->no_cache_lookup) {
|
||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
/* lookup in negative cache; may result in
|
||||
/* 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,
|
||||
@@ -1699,10 +1702,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* if this was a parent-side glue query itself, then store that
|
||||
* failure in cache. */
|
||||
if(iq->query_for_pside_glue && !iq->pside_glue)
|
||||
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
if(!qstate->no_cache_store && iq->query_for_pside_glue
|
||||
&& !iq->pside_glue)
|
||||
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
|
||||
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
|
||||
/* fail -- no more targets, no more hope of targets, no hope
|
||||
@@ -1786,8 +1790,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int tf_policy;
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
/* EDNS options to set on outgoing packet */
|
||||
struct edns_option* opt_list = NULL;
|
||||
|
||||
/* NOTE: a request will encounter this state for each target it
|
||||
* needs to send a query to. That is, at least one per referral,
|
||||
@@ -2008,8 +2010,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp->name))) {
|
||||
iq->qinfo_out.qname = iq->dp->name;
|
||||
iq->qinfo_out.qname_len = iq->dp->namelen;
|
||||
iq->qinfo_out.qtype = LDNS_RR_TYPE_NS;
|
||||
iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
|
||||
iq->qinfo_out.qclass = iq->qchase.qclass;
|
||||
iq->qinfo_out.local_alias = NULL;
|
||||
iq->minimise_count = 0;
|
||||
}
|
||||
|
||||
@@ -2023,6 +2026,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qinfo_out.qname = iq->qchase.qname;
|
||||
iq->qinfo_out.qname_len = iq->qchase.qname_len;
|
||||
iq->minimise_count++;
|
||||
iq->minimise_timeout_count = 0;
|
||||
|
||||
iter_dec_attempts(iq->dp, 1);
|
||||
|
||||
/* Limit number of iterations for QNAMEs with more
|
||||
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
|
||||
@@ -2059,11 +2065,12 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
&iq->qinfo_out.qname_len,
|
||||
labdiff-1);
|
||||
}
|
||||
if(labdiff < 1 ||
|
||||
(labdiff < 2 && iq->qchase.qtype == LDNS_RR_TYPE_DS))
|
||||
if(labdiff < 1 || (labdiff < 2
|
||||
&& (iq->qchase.qtype == LDNS_RR_TYPE_DS
|
||||
|| iq->qchase.qtype == LDNS_RR_TYPE_A)))
|
||||
/* Stop minimising this query, resolve "as usual" */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
else {
|
||||
else if(!qstate->no_cache_lookup) {
|
||||
struct dns_msg* msg = dns_cache_lookup(qstate->env,
|
||||
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
|
||||
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
|
||||
@@ -2077,10 +2084,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(iq->minimisation_state == SKIP_MINIMISE_STATE)
|
||||
/* Do not increment qname, continue incrementing next
|
||||
* iteration */
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
|
||||
iq->minimise_timeout_count++;
|
||||
if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
|
||||
/* Do not increment qname, continue incrementing next
|
||||
* iteration */
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
else if(!qstate->env->cfg->qname_minimisation_strict)
|
||||
/* Too many time-outs detected for this QNAME and QTYPE.
|
||||
* We give up, disable QNAME minimisation. */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
}
|
||||
if(iq->minimisation_state == DONOT_MINIMISE_STATE)
|
||||
iq->qinfo_out = iq->qchase;
|
||||
|
||||
@@ -2094,9 +2108,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dnssec_lame_query?" but lame_query anyway": "");
|
||||
}
|
||||
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
|
||||
outq = (*qstate->env->send_query)(
|
||||
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
|
||||
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
|
||||
outq = (*qstate->env->send_query)(&iq->qinfo_out,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
|
||||
/* unset CD if to forwarder(RD set) and not dnssec retry
|
||||
* (blacklist nonempty) and no trust-anchors are configured
|
||||
@@ -2105,8 +2117,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
!qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), opt_list, &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen, qstate);
|
||||
ie, iq), &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
@@ -2158,7 +2171,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->num_current_queries--;
|
||||
if(iq->response == NULL) {
|
||||
/* Don't increment qname when QNAME minimisation is enabled */
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
@@ -2247,10 +2260,11 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->num_target_queries = 0;
|
||||
return processDSNSFind(qstate, iq, id);
|
||||
}
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS,
|
||||
qstate->region, qstate->query_flags);
|
||||
if(!qstate->no_cache_store)
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS,
|
||||
qstate->region, qstate->query_flags);
|
||||
/* close down outstanding requests to be discarded */
|
||||
outbound_list_clear(&iq->outlist);
|
||||
iq->num_current_queries = 0;
|
||||
@@ -2263,12 +2277,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
/* Best effort qname-minimisation.
|
||||
* Stop minimising and send full query when RCODE
|
||||
* is not NOERROR. */
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR)
|
||||
LDNS_RCODE_NOERROR) {
|
||||
if(qstate->env->cfg->qname_minimisation_strict)
|
||||
return final_state(iq);
|
||||
/* Best effort qname-minimisation.
|
||||
* Stop minimising and send full query when
|
||||
* RCODE is not NOERROR. */
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
}
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
/* Stop resolving when NXDOMAIN is DNSSEC
|
||||
@@ -2315,7 +2332,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
|
||||
/* if hardened, only store referral if we asked for it */
|
||||
if(!qstate->env->cfg->harden_referral_path ||
|
||||
if(!qstate->no_cache_store &&
|
||||
(!qstate->env->cfg->harden_referral_path ||
|
||||
( qstate->qinfo.qtype == LDNS_RR_TYPE_NS
|
||||
&& (qstate->query_flags&BIT_RD)
|
||||
&& !(qstate->query_flags&BIT_CD)
|
||||
@@ -2330,7 +2348,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qname, iq->qchase.qname_len,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass)
|
||||
)
|
||||
)) {
|
||||
))) {
|
||||
/* Store the referral under the current query */
|
||||
/* no prefetch-leeway, since its not the answer */
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
@@ -2343,16 +2361,17 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->response->rep, iq->dp->name);
|
||||
}
|
||||
/* store parent-side-in-zone-glue, if directly queried for */
|
||||
if(iq->query_for_pside_glue && !iq->pside_glue) {
|
||||
iq->pside_glue = reply_find_rrset(iq->response->rep,
|
||||
iq->qchase.qname, iq->qchase.qname_len,
|
||||
iq->qchase.qtype, iq->qchase.qclass);
|
||||
if(iq->pside_glue) {
|
||||
log_rrset_key(VERB_ALGO, "found parent-side "
|
||||
"glue", iq->pside_glue);
|
||||
iter_store_parentside_rrset(qstate->env,
|
||||
iq->pside_glue);
|
||||
}
|
||||
if(!qstate->no_cache_store && iq->query_for_pside_glue
|
||||
&& !iq->pside_glue) {
|
||||
iq->pside_glue = reply_find_rrset(iq->response->rep,
|
||||
iq->qchase.qname, iq->qchase.qname_len,
|
||||
iq->qchase.qtype, iq->qchase.qclass);
|
||||
if(iq->pside_glue) {
|
||||
log_rrset_key(VERB_ALGO, "found parent-side "
|
||||
"glue", iq->pside_glue);
|
||||
iter_store_parentside_rrset(qstate->env,
|
||||
iq->pside_glue);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the event state, setting the current delegation
|
||||
@@ -2433,10 +2452,11 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* NOTE : set referral=1, so that rrsets get stored but not
|
||||
* the partial query answer (CNAME only). */
|
||||
/* prefetchleeway applied because this updates answer parts */
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS, NULL,
|
||||
qstate->query_flags);
|
||||
if(!qstate->no_cache_store)
|
||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||
iq->response->rep, 1, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS, NULL,
|
||||
qstate->query_flags);
|
||||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
@@ -2515,7 +2535,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* LAME, THROWAWAY and "unknown" all end up here.
|
||||
* Recycle to the QUERYTARGETS state to hopefully try a
|
||||
* different target. */
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
if (qstate->env->cfg->qname_minimisation &&
|
||||
!qstate->env->cfg->qname_minimisation_strict)
|
||||
iq->minimisation_state = DONOT_MINIMISE_STATE;
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
@@ -2649,6 +2670,10 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||
log_query_info(VERB_ALGO, "processTargetResponse", &qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "processTargetResponse super", &forq->qinfo);
|
||||
|
||||
/* Tell the originating event that this target query has finished
|
||||
* (regardless if it succeeded or not). */
|
||||
foriq->num_target_queries--;
|
||||
|
||||
/* check to see if parent event is still interested (in orig name). */
|
||||
if(!foriq->dp) {
|
||||
verbose(VERB_ALGO, "subq: parent not interested, was reset");
|
||||
@@ -2664,10 +2689,6 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tell the originating event that this target query has finished
|
||||
* (regardless if it succeeded or not). */
|
||||
foriq->num_target_queries--;
|
||||
|
||||
/* if iq->query_for_pside_glue then add the pside_glue (marked lame) */
|
||||
if(iq->pside_glue) {
|
||||
/* if the pside_glue is NULL, then it could not be found,
|
||||
@@ -2915,10 +2936,11 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
&qstate->qinfo);
|
||||
|
||||
/* store negative cache element for parent side glue. */
|
||||
if(iq->query_for_pside_glue && !iq->pside_glue)
|
||||
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
if(!qstate->no_cache_store && iq->query_for_pside_glue
|
||||
&& !iq->pside_glue)
|
||||
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
if(!iq->response) {
|
||||
verbose(VERB_ALGO, "No response is set, servfail");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
@@ -2954,7 +2976,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* store message with the finished prepended items,
|
||||
* but only if we did recursion. The nonrecursion referral
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
if(qstate->query_flags&BIT_RD) {
|
||||
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
|
||||
iter_dns_store(qstate->env, &qstate->qinfo,
|
||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||
iq->dp&&iq->dp->has_parent_side_NS,
|
||||
@@ -3129,6 +3151,18 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
|
||||
LDNS_RCODE_NOERROR)
|
||||
goto handle_it;
|
||||
|
||||
/* Copy the edns options we may got from the back end */
|
||||
if(edns.opt_list) {
|
||||
qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list,
|
||||
qstate->region);
|
||||
if(!qstate->edns_opts_back_in) {
|
||||
log_err("out of memory on incoming message");
|
||||
/* like packet got dropped */
|
||||
goto handle_it;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove CD-bit, we asked for in case we handle validation ourself */
|
||||
prs->flags &= ~BIT_CD;
|
||||
|
||||
|
||||
+10
-2
@@ -51,7 +51,7 @@ struct iter_forwards;
|
||||
struct iter_donotq;
|
||||
struct iter_prep_list;
|
||||
struct iter_priv;
|
||||
struct rbtree_t;
|
||||
struct rbtree_type;
|
||||
|
||||
/** max number of targets spawned for a query and its subqueries */
|
||||
#define MAX_TARGET_COUNT 64
|
||||
@@ -69,6 +69,9 @@ struct rbtree_t;
|
||||
* QNAMEs with a lot of labels.
|
||||
*/
|
||||
#define MAX_MINIMISE_COUNT 10
|
||||
/* max number of time-outs for minimised query. Prevents resolving failures
|
||||
* when the QNAME minimisation QTYPE is blocked. */
|
||||
#define MAX_MINIMISE_TIMEOUT_COUNT 3
|
||||
/**
|
||||
* number of labels from QNAME that are always send individually when using
|
||||
* QNAME minimisation, even when the number of labels of the QNAME is bigger
|
||||
@@ -112,7 +115,7 @@ struct iter_env {
|
||||
struct iter_priv* priv;
|
||||
|
||||
/** whitelist for capsforid names */
|
||||
struct rbtree_t* caps_white;
|
||||
struct rbtree_type* caps_white;
|
||||
|
||||
/** The maximum dependency depth that this resolver will pursue. */
|
||||
int max_dependency_depth;
|
||||
@@ -377,6 +380,11 @@ struct iter_qstate {
|
||||
* outgoing queries when QNAME minimisation is enabled.
|
||||
*/
|
||||
int minimise_count;
|
||||
|
||||
/**
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
int minimise_timeout_count;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,6 +62,7 @@ context_finalize(struct ub_ctx* ctx)
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
ctx->local_zones = local_zones_create();
|
||||
if(!ctx->local_zones)
|
||||
return UB_NOMEM;
|
||||
@@ -126,7 +127,7 @@ find_id(struct ub_ctx* ctx, int* id)
|
||||
|
||||
struct ctx_query*
|
||||
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
ub_callback_t cb, void* cbarg)
|
||||
ub_callback_type cb, void* cbarg)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
if(!q) return NULL;
|
||||
|
||||
@@ -61,17 +61,17 @@ struct ub_event_base;
|
||||
struct ub_ctx {
|
||||
/* --- pipes --- */
|
||||
/** mutex on query write pipe */
|
||||
lock_basic_t qqpipe_lock;
|
||||
lock_basic_type qqpipe_lock;
|
||||
/** the query write pipe */
|
||||
struct tube* qq_pipe;
|
||||
/** mutex on result read pipe */
|
||||
lock_basic_t rrpipe_lock;
|
||||
lock_basic_type rrpipe_lock;
|
||||
/** the result read pipe */
|
||||
struct tube* rr_pipe;
|
||||
|
||||
/* --- shared data --- */
|
||||
/** mutex for access to env.cfg, finalized and dothread */
|
||||
lock_basic_t cfglock;
|
||||
lock_basic_type cfglock;
|
||||
/**
|
||||
* The context has been finalized
|
||||
* This is after config when the first resolve is done.
|
||||
@@ -84,7 +84,7 @@ struct ub_ctx {
|
||||
/** pid of bg worker process */
|
||||
pid_t bg_pid;
|
||||
/** tid of bg worker thread */
|
||||
ub_thread_t bg_tid;
|
||||
ub_thread_type bg_tid;
|
||||
|
||||
/** do threading (instead of forking) for async resolution */
|
||||
int dothread;
|
||||
@@ -129,7 +129,7 @@ struct ub_ctx {
|
||||
* Used to see if querynum is free for use.
|
||||
* Content of type ctx_query.
|
||||
*/
|
||||
rbtree_t queries;
|
||||
rbtree_type queries;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -140,7 +140,7 @@ struct ub_ctx {
|
||||
*/
|
||||
struct ctx_query {
|
||||
/** node in rbtree, must be first entry, key is ptr to the querynum */
|
||||
struct rbnode_t node;
|
||||
struct rbnode_type node;
|
||||
/** query id number, key for node */
|
||||
int querynum;
|
||||
/** was this an async query? */
|
||||
@@ -149,7 +149,7 @@ struct ctx_query {
|
||||
int cancelled;
|
||||
|
||||
/** for async query, the callback function */
|
||||
ub_callback_t cb;
|
||||
ub_callback_type cb;
|
||||
/** for async query, the callback user arg */
|
||||
void* cb_arg;
|
||||
|
||||
@@ -242,7 +242,7 @@ void context_query_delete(struct ctx_query* q);
|
||||
* @return new ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, ub_callback_t cb, void* cbarg);
|
||||
int rrclass, ub_callback_type cb, void* cbarg);
|
||||
|
||||
/**
|
||||
* Get a new alloc. Creates a new one or uses a cached one.
|
||||
|
||||
+21
-7
@@ -132,6 +132,15 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
/* init edns_known_options */
|
||||
if(!edns_known_options_init(ctx->env)) {
|
||||
config_delete(ctx->env->cfg);
|
||||
free(ctx->env);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
free(ctx);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
ctx->env->alloc = &ctx->superalloc;
|
||||
ctx->env->worker = NULL;
|
||||
ctx->env->need_to_validate = 0;
|
||||
@@ -151,6 +160,7 @@ ub_ctx_create(void)
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
edns_known_options_delete(ctx->env);
|
||||
free(ctx->env);
|
||||
free(ctx);
|
||||
errno = e;
|
||||
@@ -162,6 +172,7 @@ ub_ctx_create(void)
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
edns_known_options_delete(ctx->env);
|
||||
free(ctx->env);
|
||||
free(ctx);
|
||||
errno = e;
|
||||
@@ -204,7 +215,7 @@ ub_ctx_create_event(struct event_base* eb)
|
||||
|
||||
/** delete q */
|
||||
static void
|
||||
delq(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||
delq(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)n;
|
||||
context_query_delete(q);
|
||||
@@ -298,6 +309,8 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
rrset_cache_delete(ctx->env->rrset_cache);
|
||||
infra_delete(ctx->env->infra_cache);
|
||||
config_delete(ctx->env->cfg);
|
||||
edns_known_options_delete(ctx->env);
|
||||
inplace_cb_lists_delete(ctx->env);
|
||||
free(ctx->env);
|
||||
}
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
@@ -487,7 +500,7 @@ ub_fd(struct ub_ctx* ctx)
|
||||
/** process answer from bg worker */
|
||||
static int
|
||||
process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
|
||||
ub_callback_t* cb, void** cbarg, int* err,
|
||||
ub_callback_type* cb, void** cbarg, int* err,
|
||||
struct ub_result** res)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
@@ -554,7 +567,7 @@ static int
|
||||
process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len)
|
||||
{
|
||||
int err;
|
||||
ub_callback_t cb;
|
||||
ub_callback_type cb;
|
||||
void* cbarg;
|
||||
struct ub_result* res;
|
||||
int r;
|
||||
@@ -597,7 +610,7 @@ int
|
||||
ub_wait(struct ub_ctx* ctx)
|
||||
{
|
||||
int err;
|
||||
ub_callback_t cb;
|
||||
ub_callback_type cb;
|
||||
void* cbarg;
|
||||
struct ub_result* res;
|
||||
int r;
|
||||
@@ -693,7 +706,8 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
|
||||
int
|
||||
ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id)
|
||||
int rrclass, void* mydata, ub_event_callback_type callback,
|
||||
int* async_id)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
int r;
|
||||
@@ -721,7 +735,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
ub_comm_base_now(ctx->event_worker->base);
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
|
||||
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_type)callback,
|
||||
mydata);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
@@ -735,7 +749,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
|
||||
int
|
||||
ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_callback_t callback, int* async_id)
|
||||
int rrclass, void* mydata, ub_callback_type callback, int* async_id)
|
||||
{
|
||||
struct ctx_query* q;
|
||||
uint8_t* msg = NULL;
|
||||
|
||||
+25
-24
@@ -573,10 +573,12 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
|
||||
{
|
||||
qinfo->qtype = (uint16_t)q->res->qtype;
|
||||
qinfo->qclass = (uint16_t)q->res->qclass;
|
||||
qinfo->local_alias = NULL;
|
||||
qinfo->qname = sldns_str2wire_dname(q->res->qname, &qinfo->qname_len);
|
||||
if(!qinfo->qname) {
|
||||
return 0;
|
||||
}
|
||||
qinfo->local_alias = NULL;
|
||||
edns->edns_present = 1;
|
||||
edns->ext_rcode = 0;
|
||||
edns->edns_version = 0;
|
||||
@@ -607,8 +609,9 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
/* see if there is a fixed answer */
|
||||
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
|
||||
sldns_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, NULL)) {
|
||||
if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns,
|
||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
@@ -636,7 +639,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
ub_event_callback_t cb = (ub_event_callback_t)q->cb;
|
||||
ub_event_callback_type cb = (ub_event_callback_type)q->cb;
|
||||
void* cb_arg = q->cb_arg;
|
||||
int cancelled = q->cancelled;
|
||||
|
||||
@@ -677,8 +680,9 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
/* see if there is a fixed answer */
|
||||
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
|
||||
sldns_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, NULL)) {
|
||||
if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns,
|
||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
@@ -797,8 +801,9 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
/* see if there is a fixed answer */
|
||||
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
|
||||
sldns_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, NULL)) {
|
||||
if(local_zones_answer(w->ctx->local_zones, w->env, &qinfo, &edns,
|
||||
w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
@@ -821,11 +826,10 @@ void libworker_alloc_cleanup(void* arg)
|
||||
slabhash_clear(w->env->msg_cache);
|
||||
}
|
||||
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct edns_option* opt_list,
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q)
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -833,11 +837,10 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
if(!e)
|
||||
return NULL;
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps,
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, opt_list,
|
||||
addr, addrlen, zone, zonelen, libworker_handle_service_reply,
|
||||
e, w->back->udp_buff);
|
||||
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
|
||||
addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
|
||||
e, w->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -952,14 +955,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
int ATTR_UNUSED(nocaps), struct edns_option* ATTR_UNUSED(opt_list),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
|
||||
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* libunbound/worker.h - worker thread or process that resolves
|
||||
* libunbound/libworker.h - worker thread or process that resolves
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
@@ -59,6 +59,7 @@ struct regional;
|
||||
struct tube;
|
||||
struct sldns_buffer;
|
||||
struct ub_event_base;
|
||||
struct query_info;
|
||||
|
||||
/**
|
||||
* The library-worker status structure
|
||||
|
||||
@@ -82,10 +82,13 @@ pygments_style = 'sphinx'
|
||||
# Options for HTML output
|
||||
# -----------------------
|
||||
|
||||
# The theme that the html output should use.
|
||||
html_theme = "classic"
|
||||
|
||||
# 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'
|
||||
#html_style = 'default.css'
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
.. _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).
|
||||
This basic example shows how to create a context and resolve a host address
|
||||
(DNS record of A type).
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
#!/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)
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
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.
|
||||
ctx = unbound.ub_ctx()
|
||||
ctx.resolvconf("/etc/resolv.conf")
|
||||
|
||||
If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for A records in IN class.
|
||||
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 the 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 does it
|
||||
automatically for you.
|
||||
|
||||
If only domain name is given, the :meth:`unbound.ub_ctx.resolve` looks for
|
||||
A records in IN class.
|
||||
|
||||
@@ -1,33 +1,37 @@
|
||||
.. _example_reverse_lookup:
|
||||
|
||||
==============================
|
||||
Reverse DNS lookup
|
||||
==============================
|
||||
==================
|
||||
|
||||
Reverse DNS lookup involves determining the hostname associated with a given IP address.
|
||||
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.
|
||||
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.``
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
#!/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)
|
||||
#!/usr/bin/python
|
||||
import unbound
|
||||
|
||||
In order to simplify the python code, unbound module contains function which reverses the hostname components.
|
||||
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 the
|
||||
:meth:`unbound.reverse` function which reverses the hostname components.
|
||||
This function is defined as follows::
|
||||
|
||||
def reverse(domain):
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
|
||||
def reverse(domain):
|
||||
return '.'.join([a for a in domain.split(".")][::-1])
|
||||
|
||||
@@ -1,41 +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.
|
||||
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.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
#!/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
|
||||
#!/usr/bin/python
|
||||
from unbound import ub_ctx, RR_TYPE_A, RR_CLASS_IN
|
||||
from threading import Thread
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
.. _example_asynch:
|
||||
|
||||
==============================
|
||||
Asynchronous lookup
|
||||
==============================
|
||||
===================
|
||||
|
||||
This example performs the name lookup in the background.
|
||||
The main program keeps running while the name is resolved.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
#!/usr/bin/python
|
||||
@@ -33,4 +35,5 @@ The main program keeps running while the name is resolved.
|
||||
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`.
|
||||
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``.
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
.. _example_examine:
|
||||
|
||||
==============================
|
||||
DNSSEC validator
|
||||
==============================
|
||||
================
|
||||
|
||||
This example program performs DNSSEC validation of a DNS lookup.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
#!/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"
|
||||
#!/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`_.
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
.. _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.
|
||||
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.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
::
|
||||
|
||||
@@ -25,5 +29,6 @@ This option contains a list of module names separated by the space char. This li
|
||||
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).
|
||||
|
||||
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).
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
.. _example_localzone:
|
||||
|
||||
==============================
|
||||
Local zone manipulation
|
||||
==============================
|
||||
=======================
|
||||
|
||||
This example program shows how to define local zone containing custom DNS records.
|
||||
This example program shows how to define local zone containing custom DNS
|
||||
records.
|
||||
|
||||
.. literalinclude:: example6-1.py
|
||||
:language: python
|
||||
Source code
|
||||
-----------
|
||||
|
||||
.. literalinclude:: example6-1.py
|
||||
:language: python
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
.. _example_idna:
|
||||
|
||||
=================================================
|
||||
Internationalized domain name support
|
||||
=================================================
|
||||
=====================================
|
||||
|
||||
Unlike the libUnbound, pyUnbound is able to handle IDN queries.
|
||||
|
||||
.. literalinclude:: example7-1.py
|
||||
:language: python
|
||||
Automatic IDN DNAME conversion
|
||||
-------------------------------
|
||||
|
||||
If we use unicode string in :meth:`unbound.ub_ctx.resolve` method, the IDN DNAME conversion (if it is necessary) is performed on background.
|
||||
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
|
||||
Source code
|
||||
...........
|
||||
|
||||
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`).
|
||||
.. literalinclude:: example7-1.py
|
||||
:language: python
|
||||
|
||||
IDN converted attributes
|
||||
------------------------
|
||||
|
||||
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`).
|
||||
|
||||
Source code
|
||||
...........
|
||||
|
||||
.. literalinclude:: example7-2.py
|
||||
:language: python
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
.. _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`).
|
||||
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
|
||||
Source code
|
||||
-----------
|
||||
|
||||
Previous example produces following output::
|
||||
.. literalinclude:: example8-1.py
|
||||
:language: python
|
||||
|
||||
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.
|
||||
Output
|
||||
------
|
||||
|
||||
Result:
|
||||
raw data: D9 1F CD 32
|
||||
address: 217.31.205.50
|
||||
The previous example produces the following output::
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
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.
|
||||
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`
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
example*
|
||||
example*
|
||||
|
||||
@@ -1,31 +1,38 @@
|
||||
Installation
|
||||
===================================
|
||||
============
|
||||
|
||||
**Prerequisites**
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Python 2.4 or higher, SWIG 1.3 or higher, GNU make
|
||||
|
||||
**Compiling**
|
||||
Compiling
|
||||
---------
|
||||
|
||||
After downloading, you can compile the pyUnbound library by doing::
|
||||
|
||||
> tar -xzf unbound-x.x.x-py.tar.gz
|
||||
> cd unbound-x.x.x
|
||||
> ./configure --with-pyunbound
|
||||
> make
|
||||
> tar -xzf unbound-x.x.x-py.tar.gz
|
||||
> cd unbound-x.x.x
|
||||
> ./configure --with-pyunbound
|
||||
> make
|
||||
|
||||
You may want to --with-pythonmodule as well if you want to use python as
|
||||
a module in the resolver.
|
||||
You may want to enable ``--with-pythonmodule`` as well if you want to use
|
||||
python as a module in the resolver.
|
||||
|
||||
You need GNU make to compile sources; SWIG and Python devel libraries to compile extension module.
|
||||
You need ``GNU make`` to compile sources; ``SWIG`` and ``Python devel``
|
||||
libraries to compile extension module.
|
||||
|
||||
|
||||
**Testing**
|
||||
Testing
|
||||
-------
|
||||
|
||||
If the compilation is successful, you can test the python LDNS extension module by::
|
||||
If the compilation is successful, you can test the python LDNS extension module
|
||||
by::
|
||||
|
||||
> cd contrib/python
|
||||
> make testenv
|
||||
> ./dns-lookup.py
|
||||
> cd contrib/python
|
||||
> make testenv
|
||||
> ./dns-lookup.py
|
||||
|
||||
You may want to make install in the main directory since make testenv is for debugging. In contrib/examples you can find simple applications written in Python using the Unbound extension.
|
||||
You may want to ``make install`` in the main directory since ``make testenv``
|
||||
is for debugging. In contrib/examples you can find simple applications written
|
||||
in Python using the Unbound extension.
|
||||
|
||||
@@ -1,39 +1,58 @@
|
||||
Introduction
|
||||
===================================
|
||||
============
|
||||
|
||||
**Unbound**
|
||||
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
|
||||
`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.
|
||||
|
||||
**pyUnbound**
|
||||
.. _Unbound: http://www.unbound.net/documentation
|
||||
|
||||
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.
|
||||
pyUnbound
|
||||
---------
|
||||
|
||||
**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
|
||||
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.
|
||||
|
||||
.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name
|
||||
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.
|
||||
|
||||
**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
|
||||
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
|
||||
|
||||
@@ -170,7 +170,7 @@ struct ub_event {
|
||||
struct ub_event_vmt* vmt;
|
||||
};
|
||||
|
||||
typedef void (*ub_event_callback_t)(void*, int, void*, int, int, char*);
|
||||
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
|
||||
|
||||
/**
|
||||
* Create a resolving and validation context.
|
||||
@@ -254,7 +254,8 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id);
|
||||
int rrclass, void* mydata, ub_event_callback_type callback,
|
||||
int* async_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ struct ub_result {
|
||||
* This structure is allocated on the heap and needs to be
|
||||
* freed with ub_resolve_free(result);
|
||||
*/
|
||||
typedef void (*ub_callback_t)(void*, int, struct ub_result*);
|
||||
typedef void (*ub_callback_type)(void*, int, struct ub_result*);
|
||||
|
||||
/**
|
||||
* Create a resolving and validation context.
|
||||
@@ -519,7 +519,7 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
* @return 0 if OK, else error.
|
||||
*/
|
||||
int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, void* mydata, ub_callback_t callback, int* async_id);
|
||||
int rrclass, void* mydata, ub_callback_type callback, int* async_id);
|
||||
|
||||
/**
|
||||
* Cancel an async query in progress.
|
||||
|
||||
+11
-18
@@ -49,31 +49,28 @@ struct comm_point;
|
||||
struct module_qstate;
|
||||
struct tube;
|
||||
struct edns_option;
|
||||
struct query_info;
|
||||
|
||||
/**
|
||||
* Worker service routine to send serviced queries to authoritative servers.
|
||||
* @param qname: query name. (host order)
|
||||
* @param qnamelen: length in bytes of qname, including trailing 0.
|
||||
* @param qtype: query type. (host order)
|
||||
* @param qclass: query class. (host order)
|
||||
* @param qinfo: query info.
|
||||
* @param flags: host order flags word, with opcode and CD bit.
|
||||
* @param dnssec: if set, EDNS record will have DO bit set.
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
|
||||
* @param opt_list: EDNS options on outgoing packet.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name wireformat dname.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct edns_option* opt_list,
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
@@ -108,28 +105,24 @@ void worker_sighandler(int sig, void* arg);
|
||||
|
||||
/**
|
||||
* Worker service routine to send serviced queries to authoritative servers.
|
||||
* @param qname: query name. (host order)
|
||||
* @param qnamelen: length in bytes of qname, including trailing 0.
|
||||
* @param qtype: query type. (host order)
|
||||
* @param qclass: query class. (host order)
|
||||
* @param qinfo: query info.
|
||||
* @param flags: host order flags word, with opcode and CD bit.
|
||||
* @param dnssec: if set, EDNS record will have DO bit set.
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
|
||||
* @param opt_list: EDNS options on outgoing packet.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: wireformat dname of the zone.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct edns_option* opt_list,
|
||||
struct outbound_entry* worker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
||||
+31
-13
@@ -55,6 +55,7 @@ Generate a distribution tar file for unbound.
|
||||
Detected from svn working copy if not specified.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
-w32 32bit windows compile.
|
||||
-w ... Build windows binary dist. last args passed to configure.
|
||||
EOF
|
||||
exit 1
|
||||
@@ -177,6 +178,7 @@ storehash () {
|
||||
SNAPSHOT="no"
|
||||
RC="no"
|
||||
DOWIN="no"
|
||||
W64="yes"
|
||||
WINSSL=""
|
||||
WINEXPAT=""
|
||||
|
||||
@@ -201,6 +203,10 @@ while [ "$1" ]; do
|
||||
WINEXPAT="$2"
|
||||
shift
|
||||
;;
|
||||
"-w32")
|
||||
W64="no"
|
||||
shift
|
||||
;;
|
||||
"-w")
|
||||
DOWIN="yes"
|
||||
shift
|
||||
@@ -222,8 +228,15 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
if test "`uname`" = "Linux"; then
|
||||
info "Crosscompile windows dist"
|
||||
cross="yes"
|
||||
configure="mingw32-configure"
|
||||
strip="i686-w64-mingw32-strip"
|
||||
if test "$W64" = "yes"; then
|
||||
warch="x86_64" # i686 for 32bit, or x86_64 for 64bit
|
||||
mw64="mingw64" # mingw32 or mingw64
|
||||
else
|
||||
warch="i686"
|
||||
mw64="mingw32"
|
||||
fi
|
||||
configure="${mw64}-configure" # mingw32-configure, mingw64-configure
|
||||
strip="${warch}-w64-mingw32-strip"
|
||||
makensis="makensis" # from mingw32-nsis package
|
||||
# flags for crosscompiled dependency libraries
|
||||
cross_flag=""
|
||||
@@ -241,9 +254,13 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
# configure for crosscompile, without CAPI because it fails
|
||||
# cross-compilation and it is not used anyway
|
||||
# before 1.0.1i need --cross-compile-prefix=i686-w64-mingw32-
|
||||
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw"
|
||||
if test "$mw64" = "mingw64"; then
|
||||
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw64"
|
||||
else
|
||||
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw"
|
||||
fi
|
||||
info "winssl: Configure $sslflags"
|
||||
CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar RANLIB=i686-w64-mingw32-ranlib ./Configure --prefix="$sslinstall" $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib ./Configure --prefix="$sslinstall" $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
info "winssl: make"
|
||||
make || error_cleanup "OpenSSL crosscompile failed"
|
||||
# only install sw not docs, which take a long time.
|
||||
@@ -260,7 +277,7 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
wxpinstall="`pwd`/wxpinstall"
|
||||
cd expat-* || error_cleanup "no expat-X dir in tarball"
|
||||
info "wxp: configure"
|
||||
mingw32-configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" || error_cleanup "libexpat configure failed"
|
||||
$configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" || error_cleanup "libexpat configure failed"
|
||||
#info "wxp: make"
|
||||
#make || error_cleanup "libexpat crosscompile failed"
|
||||
info "wxp: make installlib"
|
||||
@@ -319,14 +336,15 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
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-anchor.exe
|
||||
$strip unbound-checkconf.exe
|
||||
$strip unbound-service-install.exe
|
||||
$strip unbound-service-remove.exe
|
||||
# keep debug symbols
|
||||
#$strip unbound.exe
|
||||
#$strip anchor-update.exe
|
||||
#$strip unbound-control.exe
|
||||
#$strip unbound-host.exe
|
||||
#$strip unbound-anchor.exe
|
||||
#$strip unbound-checkconf.exe
|
||||
#$strip unbound-service-install.exe
|
||||
#$strip unbound-service-remove.exe
|
||||
cd tmp.$$
|
||||
cp ../doc/example.conf ../doc/Changelog .
|
||||
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd .
|
||||
|
||||
@@ -80,10 +80,13 @@ pygments_style = 'sphinx'
|
||||
# Options for HTML output
|
||||
# -----------------------
|
||||
|
||||
# The theme that the html output should use.
|
||||
html_theme = "classic"
|
||||
|
||||
# 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'
|
||||
#html_style = 'default.css'
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.. _log_handler:
|
||||
|
||||
Packet logger
|
||||
=========================
|
||||
=============
|
||||
|
||||
This example shows how to log and print details about query and response.
|
||||
As soon as the ``iterator`` has finished (event is :data:`module_event_moddone`), ``qstate.return_msg`` contains response packet or ``None``.
|
||||
As soon as the ``iterator`` has finished (event is
|
||||
:data:`module_event_moddone`), ``qstate.return_msg`` contains response packet
|
||||
or ``None``.
|
||||
This packet will be send to a client that asked for it.
|
||||
|
||||
Complete source code
|
||||
@@ -14,14 +16,16 @@ Complete source code
|
||||
:language: python
|
||||
|
||||
Testing
|
||||
------------------
|
||||
-------
|
||||
Run the unbound server:
|
||||
|
||||
``root@localhost>unbound -dv -c ./test-log.conf``
|
||||
|
||||
In case you use own configuration file, don't forget to enable python module: ``module-config: "validator python iterator"`` and use valid script path: ``python-script: "./examples/log.py"``.
|
||||
In case you use own configuration file, don't forget to enable python module:
|
||||
``module-config: "validator python iterator"`` and use valid script path:
|
||||
``python-script: "./examples/log.py"``.
|
||||
|
||||
Example of output::
|
||||
Example of output::
|
||||
|
||||
[1231790168] unbound[7941:0] info: response for <f.gtld-servers.NET. AAAA IN>
|
||||
[1231790168] unbound[7941:0] info: reply from <gtld-servers.NET.> 192.5.6.31#53
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
Response generation
|
||||
=====================
|
||||
===================
|
||||
|
||||
This example shows how to handle queries and generate response packet.
|
||||
|
||||
.. note::
|
||||
If the python module is the first module and validator module is enabled (``module-config: "python validator iterator"``),
|
||||
a return_msg security flag has to be set at least to 2. Leaving security flag untouched causes that the
|
||||
response will be refused by unbound worker as unbound will consider it as non-valid response.
|
||||
If the python module is the first module and validator module is enabled
|
||||
(``module-config: "python validator iterator"``), a return_msg security flag
|
||||
has to be set at least to 2. Leaving security flag untouched causes that the
|
||||
response will be refused by unbound worker as unbound will consider it as
|
||||
non-valid response.
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
@@ -27,20 +29,21 @@ Query for a A record ending with .localdomain
|
||||
|
||||
Dig produces the following output::
|
||||
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48426
|
||||
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;test.xxx.localdomain. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
test.xxx.localdomain. 10 IN A 127.0.0.1
|
||||
|
||||
;; Query time: 2 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 12:46:02 2009
|
||||
;; MSG SIZE rcvd: 54
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48426
|
||||
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
As we handle (override) in python module only queries ending with "localdomain.", the unboud can still resolve host names.
|
||||
;; QUESTION SECTION:
|
||||
;test.xxx.localdomain. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
test.xxx.localdomain. 10 IN A 127.0.0.1
|
||||
|
||||
;; Query time: 2 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 12:46:02 2009
|
||||
;; MSG SIZE rcvd: 54
|
||||
|
||||
As we handle (override) in the python module only queries ending with
|
||||
``localdomain.``, unboud can still resolve host names.
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
DNS-based language dictionary
|
||||
===============================
|
||||
=============================
|
||||
|
||||
This example shows how to create a simple language dictionary based on **DNS**
|
||||
service within 15 minutes. The translation will be performed using TXT resource records.
|
||||
service within 15 minutes. The translation will be performed using TXT resource
|
||||
records.
|
||||
|
||||
Key parts
|
||||
-----------
|
||||
---------
|
||||
|
||||
Initialization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
On **init()** module loads dictionary from a text file containing records in ``word [tab] translation`` format.
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
On **init()** module loads dictionary from a text file containing records in
|
||||
``word [tab] translation`` format.
|
||||
|
||||
::
|
||||
|
||||
def init(id, cfg):
|
||||
@@ -20,11 +24,14 @@ On **init()** module loads dictionary from a text file containing records in ``w
|
||||
The suitable file can be found at http://slovnik.zcu.cz
|
||||
|
||||
DNS query and word lookup
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's define the following format od DNS queries: ``word1[.]word2[.] ... wordN[.]{en,cs}[._dict_.cz.]``.
|
||||
Let's define the following format od DNS queries:
|
||||
``word1[.]word2[.] ... wordN[.]{en,cs}[._dict_.cz.]``.
|
||||
Word lookup is done by simple ``dict`` lookup from broken DNS request.
|
||||
Query name is divided into a list of labels. This list is accessible as qname_list attribute.
|
||||
Query name is divided into a list of labels. This list is accessible as
|
||||
``qname_list`` attribute.
|
||||
|
||||
::
|
||||
|
||||
aword = ' '.join(qstate.qinfo.qname_list[0:-4]) #skip last four labels
|
||||
@@ -37,35 +44,40 @@ Query name is divided into a list of labels. This list is accessible as qname_li
|
||||
if (adict == "cs") and (aword in cz_dict):
|
||||
words = cz_dict[aword] # CS -> EN
|
||||
|
||||
In the first step, we get a string in the form: ``word1[space]word2[space]...word[space]``.
|
||||
In the second assignment, fourth label from the end is obtained. This label should contains *"cs"* or *"en"*.
|
||||
This label determines the direction of translation.
|
||||
|
||||
In the first step, we get a string in the form:
|
||||
``word1[space]word2[space]...word[space]``.
|
||||
In the second assignment, fourth label from the end is obtained. This label
|
||||
should contains *"cs"* or *"en"*. This label determines the direction of
|
||||
translation.
|
||||
|
||||
Forming of a DNS reply
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
DNS reply is formed only on valid match and added as TXT answer.
|
||||
|
||||
::
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_AA)
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_AA)
|
||||
|
||||
for w in words:
|
||||
msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str, w.replace("\"", "\\\"")))
|
||||
for w in words:
|
||||
msg.answer.append("%s 300 IN TXT \"%s\"" % (qstate.qinfo.qname_str, w.replace("\"", "\\\"")))
|
||||
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
In the first step, a :class:`DNSMessage` instance is created for a given query *(type TXT)*.
|
||||
In the first step, a :class:`DNSMessage` instance is created for a given query
|
||||
*(type TXT)*.
|
||||
The fourth argument specifies the flags *(authoritative answer)*.
|
||||
In the second step, we append TXT records containing the translation *(on the right side of RR)*.
|
||||
In the second step, we append TXT records containing the translation *(on the
|
||||
right side of RR)*.
|
||||
Then, the response is finished and ``qstate.return_msg`` contains new response.
|
||||
If no error, the module sets :attr:`module_qstate.return_rcode` and :attr:`module_qstate.ext_state`.
|
||||
If no error, the module sets :attr:`module_qstate.return_rcode` and
|
||||
:attr:`module_qstate.ext_state`.
|
||||
|
||||
**Steps:**
|
||||
|
||||
@@ -82,80 +94,82 @@ Run the Unbound server:
|
||||
|
||||
In case you use own configuration file, don't forget to enable Python module::
|
||||
|
||||
module-config: "validator python iterator"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
and use valid script path::
|
||||
|
||||
python-script: "./examples/dict.py"
|
||||
python-script: "./examples/dict.py"
|
||||
|
||||
The translation from english word *"a bar fly"* to Czech can be done by doing:
|
||||
|
||||
``>>>dig TXT @127.0.0.1 a.bar.fly.en._dict_.cz``
|
||||
|
||||
::
|
||||
::
|
||||
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48691
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;a.bar.fly.en._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
a.bar.fly.en._dict_.cz. 300 IN TXT "barov\253 povale\232"
|
||||
|
||||
;; Query time: 5 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:44:18 2009
|
||||
;; MSG SIZE rcvd: 67
|
||||
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48691
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;a.bar.fly.en._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
a.bar.fly.en._dict_.cz. 300 IN TXT "barov\253 povale\232"
|
||||
|
||||
;; Query time: 5 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:44:18 2009
|
||||
;; MSG SIZE rcvd: 67
|
||||
|
||||
``>>>dig TXT @127.0.0.1 nic.cs._dict_.cz``
|
||||
|
||||
::
|
||||
|
||||
; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 nic.cs._dict_.cz
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58710
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;nic.cs._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nic.cs._dict_.cz. 300 IN TXT "aught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "naught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nihil"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nix"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nothing"
|
||||
nic.cs._dict_.cz. 300 IN TXT "zilch"
|
||||
|
||||
;; Query time: 0 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:45:39 2009
|
||||
;; MSG SIZE rcvd: 143
|
||||
; <<>> DiG 9.5.0-P2 <<>> TXT @127.0.0.1 nic.cs._dict_.cz
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58710
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
Proof that the unbound still works as resolver.
|
||||
;; QUESTION SECTION:
|
||||
;nic.cs._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nic.cs._dict_.cz. 300 IN TXT "aught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "naught"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nihil"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nix"
|
||||
nic.cs._dict_.cz. 300 IN TXT "nothing"
|
||||
nic.cs._dict_.cz. 300 IN TXT "zilch"
|
||||
|
||||
;; Query time: 0 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Jan 01 17:45:39 2009
|
||||
;; MSG SIZE rcvd: 143
|
||||
|
||||
Proof that the unbound still works as resolver.
|
||||
|
||||
``>>>dig A @127.0.0.1 www.nic.cz``
|
||||
|
||||
::
|
||||
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19996
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;www.nic.cz. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
www.nic.cz. 1662 IN A 217.31.205.50
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
...
|
||||
; (1 server found)
|
||||
;; global options: printcmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19996
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;www.nic.cz. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
www.nic.cz. 1662 IN A 217.31.205.50
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
...
|
||||
|
||||
Complete source code
|
||||
--------------------
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
EDNS options
|
||||
============
|
||||
|
||||
This example shows how to interact with EDNS options.
|
||||
|
||||
When quering unbound with the EDNS option ``65001`` and data ``0xc001`` we
|
||||
expect an answer with the same EDNS option code and data ``0xdeadbeef``.
|
||||
|
||||
|
||||
Key parts
|
||||
~~~~~~~~~
|
||||
|
||||
This example relies on the following functionalities:
|
||||
|
||||
|
||||
Registering EDNS options
|
||||
------------------------
|
||||
|
||||
By registering EDNS options we can tune unbound's behavior when encountering a
|
||||
query with a known EDNS option. The two available options are:
|
||||
|
||||
- ``bypass_cache_stage``: If set to ``True`` unbound will not try to answer
|
||||
from cache. Instead execution is passed to the modules
|
||||
- ``no_aggregation``: If set to ``True`` unbound will consider this query
|
||||
unique and will not aggregate it with similar queries
|
||||
|
||||
Both values default to ``False``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not register_edns_option(env, 65001, bypass_cache_stage=True,
|
||||
no_aggregation=True):
|
||||
log_info("python: Could not register EDNS option {}".format(65001))
|
||||
|
||||
|
||||
EDNS option lists
|
||||
-----------------
|
||||
|
||||
EDNS option lists can be found in the :class:`module_qstate` class. There are
|
||||
four available lists in total:
|
||||
|
||||
- :class:`module_qstate.edns_opts_front_in`: options that came from the client
|
||||
side. **Should not** be changed
|
||||
- :class:`module_qstate.edns_opts_back_out`: options that will be sent to the
|
||||
server side. Can be populated by edns literate modules
|
||||
- :class:`module_qstate.edns_opts_back_in`: options that came from the server
|
||||
side. **Should not** be changed
|
||||
- :class:`module_qstate.edns_opts_front_out`: options that will be sent to the
|
||||
client side. Can be populated by edns literate modules
|
||||
|
||||
Each list element has the following members:
|
||||
|
||||
- ``code``: the EDNS option code;
|
||||
- ``data``: the EDNS option data.
|
||||
|
||||
|
||||
Reading an EDNS option list
|
||||
...........................
|
||||
|
||||
The lists' contents can be accessed in python by their ``_iter`` counterpart as
|
||||
an iterator:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
|
||||
for o in qstate.edns_opts_front_in_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
|
||||
|
||||
Writing to an EDNS option list
|
||||
..............................
|
||||
|
||||
By appending to an EDNS option list we can add new EDNS options. The new
|
||||
element is going to be allocated in :class:`module_qstate.region`. The data
|
||||
**must** be represented with a python ``bytearray``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
b = bytearray.fromhex("deadbeef")
|
||||
if not edns_opt_list_append(qstate.edns_opts_front_out,
|
||||
o.code, b, qstate.region):
|
||||
log_info("python: Could not append EDNS option {}".format(o.code))
|
||||
|
||||
We can also remove an EDNS option code from an EDNS option list.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not edns_opt_list_remove(edns_opt_list, code):
|
||||
log_info("python: Option code {} was not found in the "
|
||||
"list.".format(code))
|
||||
|
||||
.. note:: All occurences of the EDNS option code will be removed from the list:
|
||||
|
||||
|
||||
Controlling other modules' cache behavior
|
||||
-----------------------------------------
|
||||
|
||||
During the modules' operation, some modules may interact with the cache
|
||||
(e.g., iterator). This behavior can be controlled by using the following
|
||||
:class:`module_qstate` flags:
|
||||
|
||||
- :class:`module_qstate.no_cache_lookup`: Modules *operating after* this module
|
||||
will not lookup the cache for an answer
|
||||
- :class:`module_qstate.no_cache_store`: Modules *operating after* this module
|
||||
will not store the response in the cache
|
||||
|
||||
Both values default to ``0``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
# Detect if edns option code 56001 is present from the client side. If
|
||||
# so turn on the flags for cache management.
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
|
||||
log_info("python: searching for edns option code 65001 during NEW "
|
||||
"or PASS event ")
|
||||
for o in qstate.edns_opts_front_in_iter:
|
||||
if o.code == 65001:
|
||||
log_info("python: found edns option code 65001")
|
||||
# Instruct other modules to not lookup for an
|
||||
# answer in the cache.
|
||||
qstate.no_cache_lookup = 1
|
||||
log_info("python: enabled no_cache_lookup")
|
||||
|
||||
# Instruct other modules to not store the answer in
|
||||
# the cache.
|
||||
qstate.no_cache_store = 1
|
||||
log_info("python: enabled no_cache_store")
|
||||
|
||||
|
||||
Testing
|
||||
~~~~~~~
|
||||
|
||||
Run the Unbound server: ::
|
||||
|
||||
root@localhost$ unbound -dv -c ./test-edns.conf
|
||||
|
||||
In case you use your own configuration file, don't forget to enable the Python
|
||||
module::
|
||||
|
||||
module-config: "validator python iterator"
|
||||
|
||||
and use a valid script path::
|
||||
|
||||
python-script: "./examples/edns.py"
|
||||
|
||||
Quering with EDNS option ``65001:0xc001``:
|
||||
|
||||
::
|
||||
|
||||
root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65001:c001
|
||||
|
||||
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65001:c001
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33450
|
||||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 4096
|
||||
; OPT=65001: de ad be ef ("....")
|
||||
;; QUESTION SECTION:
|
||||
;nlnetlabs.nl. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nlnetlabs.nl. 10200 IN A 185.49.140.10
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
nlnetlabs.nl. 10200 IN NS anyns.pch.net.
|
||||
nlnetlabs.nl. 10200 IN NS ns.nlnetlabs.nl.
|
||||
nlnetlabs.nl. 10200 IN NS ns-ext1.sidn.nl.
|
||||
nlnetlabs.nl. 10200 IN NS sec2.authdns.ripe.net.
|
||||
|
||||
;; ADDITIONAL SECTION:
|
||||
ns.nlnetlabs.nl. 10200 IN AAAA 2a04:b900::8:0:0:60
|
||||
ns.nlnetlabs.nl. 10200 IN A 185.49.140.60
|
||||
|
||||
;; Query time: 10 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Dec 05 14:50:56 CET 2016
|
||||
;; MSG SIZE rcvd: 212
|
||||
|
||||
|
||||
Complete source code
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. literalinclude:: ../../examples/edns.py
|
||||
:language: python
|
||||
@@ -0,0 +1,299 @@
|
||||
Inplace callbacks
|
||||
=================
|
||||
|
||||
This example shows how to register and use inplace callback functions. These
|
||||
functions are going to be called just before unbound replies back to a client.
|
||||
They can perform certain actions without interrupting unbound's execution flow
|
||||
(e.g. add/remove EDNS options, manipulate the reply).
|
||||
|
||||
Two different scenarios will be shown:
|
||||
|
||||
- If answering from cache and the client used EDNS option code ``65002`` we
|
||||
will answer with the same code but with data ``0xdeadbeef``;
|
||||
- When answering with a SERVFAIL we also add an empty EDNS option code
|
||||
``65003``.
|
||||
|
||||
|
||||
Key parts
|
||||
~~~~~~~~~
|
||||
|
||||
This example relies on the following functionalities:
|
||||
|
||||
|
||||
Registering inplace callback functions
|
||||
--------------------------------------
|
||||
|
||||
There are four types of inplace callback functions:
|
||||
|
||||
- `inplace callback reply functions`_
|
||||
- `inplace callback reply_cache functions`_
|
||||
- `inplace callback reply_local functions`_
|
||||
- `inplace callback reply_servfail functions`_
|
||||
|
||||
|
||||
Inplace callback reply functions
|
||||
................................
|
||||
|
||||
Called when answering with a *resolved* query.
|
||||
|
||||
The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with a resolved query.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. It contains the available opt_lists; It
|
||||
SHOULD NOT be altered;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data to be sent to the client side. It SHOULD NOT be
|
||||
altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
|
||||
We can register such function as:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not register_inplace_cb_reply(inplace_reply_callback, env):
|
||||
log_info("python: Could not register inplace callback function.")
|
||||
|
||||
|
||||
Inplace callback reply_cache functions
|
||||
......................................
|
||||
|
||||
Called when answering *from cache*.
|
||||
|
||||
The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from the cache.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data sent from the client side. The list with the EDNS
|
||||
options is accesible through edns.opt_list. It SHOULD NOT be
|
||||
altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
|
||||
We can register such function as:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not register_inplace_cb_reply_cache(inplace_cache_callback, env):
|
||||
log_info("python: Could not register inplace callback function.")
|
||||
|
||||
|
||||
Inplace callback reply_local functions
|
||||
......................................
|
||||
|
||||
Called when answering with *local data* or a *Chaos(CH) reply*.
|
||||
|
||||
The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from local data.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data sent from the client side. The list with the
|
||||
EDNS options is accesible through edns.opt_list. It
|
||||
SHOULD NOT be altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
|
||||
We can register such function as:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not register_inplace_cb_reply_local(inplace_local_callback, env):
|
||||
log_info("python: Could not register inplace callback function.")
|
||||
|
||||
|
||||
Inplace callback reply_servfail functions
|
||||
.........................................
|
||||
|
||||
Called when answering with *SERVFAIL*.
|
||||
|
||||
The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with SERVFAIL.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. If not None the relevant opt_lists are
|
||||
available here;
|
||||
:param rep: reply_info struct. None;
|
||||
:param rcode: return code for the query. LDNS_RCODE_SERVFAIL;
|
||||
:param edns: edns_data to be sent to the client side. If qstate is None
|
||||
edns.opt_list contains the EDNS options sent from the client
|
||||
side. It SHOULD NOT be altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
|
||||
We can register such function as:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env):
|
||||
log_info("python: Could not register inplace callback function.")
|
||||
|
||||
|
||||
Testing
|
||||
~~~~~~~
|
||||
|
||||
Run the Unbound server: ::
|
||||
|
||||
root@localhost$ unbound -dv -c ./test-inplace_callbacks.conf
|
||||
|
||||
In case you use your own configuration file, don't forget to enable the Python
|
||||
module::
|
||||
|
||||
module-config: "validator python iterator"
|
||||
|
||||
and use a valid script path ::
|
||||
|
||||
python-script: "./examples/inplace_callbacks.py"
|
||||
|
||||
On the first query for the nlnetlabs.nl A record we get no EDNS option back:
|
||||
|
||||
::
|
||||
|
||||
root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65002
|
||||
|
||||
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65002
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48057
|
||||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 4096
|
||||
;; QUESTION SECTION:
|
||||
;nlnetlabs.nl. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nlnetlabs.nl. 10200 IN A 185.49.140.10
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
nlnetlabs.nl. 10200 IN NS ns.nlnetlabs.nl.
|
||||
nlnetlabs.nl. 10200 IN NS sec2.authdns.ripe.net.
|
||||
nlnetlabs.nl. 10200 IN NS anyns.pch.net.
|
||||
nlnetlabs.nl. 10200 IN NS ns-ext1.sidn.nl.
|
||||
|
||||
;; ADDITIONAL SECTION:
|
||||
ns.nlnetlabs.nl. 10200 IN A 185.49.140.60
|
||||
ns.nlnetlabs.nl. 10200 IN AAAA 2a04:b900::8:0:0:60
|
||||
|
||||
;; Query time: 813 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Dec 05 16:15:32 CET 2016
|
||||
;; MSG SIZE rcvd: 204
|
||||
|
||||
When we issue the same query again we get a cached response and the expected
|
||||
``65002: 0xdeadbeef`` EDNS option:
|
||||
|
||||
::
|
||||
|
||||
root@localhost$ dig @localhost nlnetlabs.nl +ednsopt=65002
|
||||
|
||||
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost nlnetlabs.nl +ednsopt=65002
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26489
|
||||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 3
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 4096
|
||||
; OPT=65002: de ad be ef ("....")
|
||||
;; QUESTION SECTION:
|
||||
;nlnetlabs.nl. IN A
|
||||
|
||||
;; ANSWER SECTION:
|
||||
nlnetlabs.nl. 10197 IN A 185.49.140.10
|
||||
|
||||
;; AUTHORITY SECTION:
|
||||
nlnetlabs.nl. 10197 IN NS ns.nlnetlabs.nl.
|
||||
nlnetlabs.nl. 10197 IN NS sec2.authdns.ripe.net.
|
||||
nlnetlabs.nl. 10197 IN NS anyns.pch.net.
|
||||
nlnetlabs.nl. 10197 IN NS ns-ext1.sidn.nl.
|
||||
|
||||
;; ADDITIONAL SECTION:
|
||||
ns.nlnetlabs.nl. 10197 IN AAAA 2a04:b900::8:0:0:60
|
||||
ns.nlnetlabs.nl. 10197 IN A 185.49.140.60
|
||||
|
||||
;; Query time: 0 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Dec 05 16:50:04 CET 2016
|
||||
;; MSG SIZE rcvd: 212
|
||||
|
||||
By issuing a query for a bogus domain unbound replies with SERVFAIL and an
|
||||
empty EDNS option code ``65003``. *For this example to work unbound needs to be
|
||||
validating*:
|
||||
|
||||
::
|
||||
|
||||
root@localhost$ dig @localhost bogus.nlnetlabs.nl txt
|
||||
|
||||
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost bogus.nlnetlabs.nl txt
|
||||
; (1 server found)
|
||||
;; global options: +cmd
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 19865
|
||||
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
|
||||
|
||||
;; OPT PSEUDOSECTION:
|
||||
; EDNS: version: 0, flags:; udp: 4096
|
||||
; OPT=65003
|
||||
;; QUESTION SECTION:
|
||||
;bogus.nlnetlabs.nl. IN TXT
|
||||
|
||||
;; Query time: 11 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Mon Dec 05 17:06:01 CET 2016
|
||||
;; MSG SIZE rcvd: 51
|
||||
|
||||
|
||||
Complete source code
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
.. literalinclude:: ../../examples/inplace_callbacks.py
|
||||
:language: python
|
||||
@@ -1,15 +1,16 @@
|
||||
.. _Tutorials:
|
||||
|
||||
==============================
|
||||
Examples
|
||||
========
|
||||
|
||||
Here you can find several tutorials which clarify the usage and capabilities of
|
||||
the Unbound scriptable interface.
|
||||
|
||||
Tutorials
|
||||
==============================
|
||||
|
||||
Here you can find several tutorials which clarify the usage and capabilities of Unbound scriptable interface.
|
||||
|
||||
`Tutorials`
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
example*
|
||||
example*
|
||||
|
||||
+25
-19
@@ -1,39 +1,44 @@
|
||||
Installation
|
||||
===================================
|
||||
============
|
||||
|
||||
**Prerequisites**
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Python 2.4 or higher, SWIG 1.3 or higher, GNU make
|
||||
|
||||
**Download**
|
||||
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**
|
||||
Compiling
|
||||
---------
|
||||
|
||||
After downloading, you can compile the Unbound library by doing::
|
||||
|
||||
> tar -xzf unbound-1.1.1-py.tar.gz
|
||||
> cd unbound-1.1.1
|
||||
> ./configure --with-pythonmodule
|
||||
> make
|
||||
> tar -xzf unbound-1.1.1-py.tar.gz
|
||||
> cd unbound-1.1.1
|
||||
> ./configure --with-pythonmodule
|
||||
> make
|
||||
|
||||
You need GNU make to compile sources.
|
||||
SWIG and Python devel libraries to compile extension module.
|
||||
|
||||
**Testing**
|
||||
Testing
|
||||
-------
|
||||
|
||||
If the compilation is successful, you can test the extension module by::
|
||||
|
||||
> cd pythonmod
|
||||
> make sudo # or "make test" or "make suexec"
|
||||
> cd pythonmod
|
||||
> make sudo # or "make test" or "make suexec"
|
||||
|
||||
This will start unbound server with language dictionary service (see :ref:`Tutorials`).
|
||||
This will start unbound server with language dictionary service
|
||||
(see :ref:`Tutorials`).
|
||||
In order to test this service, type::
|
||||
|
||||
|
||||
> dig TXT @127.0.0.1 aught.en._dict_.cz
|
||||
|
||||
Dig should print this message (czech equivalent of aught)::
|
||||
@@ -44,16 +49,17 @@ Dig should print this message (czech equivalent of aught)::
|
||||
;; Got answer:
|
||||
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30085
|
||||
;; flags: aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||
|
||||
|
||||
;; QUESTION SECTION:
|
||||
;aught.en._dict_.cz. IN TXT
|
||||
|
||||
;aught.en._dict_.cz. IN TXT
|
||||
|
||||
;; ANSWER SECTION:
|
||||
aught.en._dict_.cz. 300 IN TXT "nic"
|
||||
|
||||
aught.en._dict_.cz. 300 IN TXT "nic"
|
||||
|
||||
;; Query time: 11 msec
|
||||
;; SERVER: 127.0.0.1#53(127.0.0.1)
|
||||
;; WHEN: Thu Jan 10 16:45:58 2009
|
||||
;; MSG SIZE rcvd: 52
|
||||
|
||||
The ``pythonmod/examples`` directory contains simple applications written in Python.
|
||||
The ``pythonmod/examples`` directory contains simple applications written in
|
||||
Python.
|
||||
|
||||
@@ -7,25 +7,26 @@ Network
|
||||
.. function:: ntohs(netshort)
|
||||
|
||||
This subroutine converts values between the host and network byte order.
|
||||
Specifically, **ntohs()** converts 16-bit quantities from network byte order to host byte order.
|
||||
|
||||
Specifically, **ntohs()** converts 16-bit quantities from network byte order
|
||||
to host byte order.
|
||||
|
||||
:param netshort: 16-bit short addr
|
||||
:rtype: converted addr
|
||||
|
||||
|
||||
|
||||
|
||||
Cache
|
||||
-----
|
||||
|
||||
.. function:: storeQueryInCache(qstate, qinfo, msgrep, is_referral)
|
||||
|
||||
Store pending query in local cache.
|
||||
|
||||
|
||||
:param qstate: :class:`module_qstate`
|
||||
:param qinfo: :class:`query_info`
|
||||
:param msgrep: :class:`reply_info`
|
||||
:param is_referal: integer
|
||||
:rtype: boolean
|
||||
|
||||
|
||||
.. function:: invalidateQueryInCache(qstate, qinfo)
|
||||
|
||||
Invalidate record in local cache.
|
||||
@@ -34,6 +35,111 @@ Cache
|
||||
:param qinfo: :class:`query_info`
|
||||
|
||||
|
||||
EDNS options
|
||||
------------
|
||||
|
||||
.. function:: register_edns_option(env, code, bypass_cache_stage=False, no_aggregation=False)
|
||||
|
||||
Register EDNS option code.
|
||||
|
||||
:param env: :class:`module_env`
|
||||
:param code: option code(integer)
|
||||
:param bypass_cache_stage: whether to bypass the cache response stage
|
||||
:param no_aggregation: whether this query should be unique
|
||||
:return: ``1`` if successful, ``0`` otherwise
|
||||
:rtype: integer
|
||||
|
||||
.. function:: edns_opt_list_find(list, code)
|
||||
|
||||
Find the EDNS option code in the EDNS option list.
|
||||
|
||||
:param list: linked list of :class:`edns_option`
|
||||
:param code: option code (integer)
|
||||
:return: the edns option if found or None
|
||||
:rtype: :class:`edns_option` or None
|
||||
|
||||
.. function:: edns_opt_list_remove(list, code);
|
||||
|
||||
Remove an ENDS option code from the list.
|
||||
.. note:: All :class:`edns_option` with the code will be removed
|
||||
|
||||
:param list: linked list of :class:`edns_option`
|
||||
:param code: option code (integer)
|
||||
:return: ``1`` if at least one :class:`edns_option` was removed, ``0`` otherwise
|
||||
:rtype: integer
|
||||
|
||||
.. function:: edns_opt_list_append(list, code, data, region)
|
||||
|
||||
Append given EDNS option code with data to the list.
|
||||
|
||||
:param list: linked list of :class:`edns_option`
|
||||
:param code: option code (integer)
|
||||
:param data: EDNS data. **Must** be a :class:`bytearray`
|
||||
:param region: :class:`regional`
|
||||
|
||||
.. function:: edns_opt_list_is_empty(list)
|
||||
|
||||
Check if an EDNS option list is empty.
|
||||
|
||||
:param list: linked list of :class:`edns_option`
|
||||
:return: ``1`` if list is empty, ``0`` otherwise
|
||||
:rtype: integer
|
||||
|
||||
|
||||
Inplace callbacks
|
||||
-----------------
|
||||
|
||||
.. function:: inplace_cb_reply(qinfo, qstate, rep, rcode, edns, opt_list_out, region)
|
||||
|
||||
Function prototype for callback functions used in
|
||||
`register_inplace_cb_reply`_, `register_inplace_cb_reply_cache`_,
|
||||
`register_inplace_cb_reply_local` and `register_inplace_cb_reply_servfail`.
|
||||
|
||||
:param qinfo: :class:`query_info`
|
||||
:param qstate: :class:`module_qstate`
|
||||
:param rep: :class:`reply_info`
|
||||
:param rcode: return code (integer), check ``RCODE_`` constants.
|
||||
:param edns: :class:`edns_data`
|
||||
:param opt_list_out: :class:`edns_option`. EDNS option list to append options to.
|
||||
:param region: :class:`regional`
|
||||
|
||||
.. function:: register_inplace_cb_reply(py_cb, env)
|
||||
|
||||
Register py_cb as an inplace reply callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_cache(py_cb, env)
|
||||
|
||||
Register py_cb as an inplace reply_cache callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_local(py_cb, env)
|
||||
|
||||
Register py_cb as an inplace reply_local callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
.. function:: register_inplace_cb_reply_servfail(py_cb, env)
|
||||
|
||||
Register py_cb as an inplace reply_servfail callback function.
|
||||
|
||||
:param py_cb: Python function that follows `inplace_cb_reply`_'s prototype. **Must** be callable.
|
||||
:param env: :class:`module_env`
|
||||
:return: True on success, False otherwise
|
||||
:rtype: boolean
|
||||
|
||||
|
||||
Logging
|
||||
-------
|
||||
|
||||
@@ -71,50 +177,51 @@ Logging
|
||||
:param msg: string desc to accompany the hexdump.
|
||||
:param data: data to dump in hex format.
|
||||
:param length: length of data.
|
||||
|
||||
|
||||
.. function:: log_dns_msg(str, qinfo, reply)
|
||||
|
||||
Log DNS message.
|
||||
|
||||
|
||||
:param str: string message
|
||||
:param qinfo: :class:`query_info`
|
||||
:param reply: :class:`reply_info`
|
||||
|
||||
|
||||
.. function:: log_query_info(verbosity_value, str, qinf)
|
||||
|
||||
Log query information.
|
||||
|
||||
|
||||
:param verbosity_value: see constants
|
||||
:param str: string message
|
||||
:param qinf: :class:`query_info`
|
||||
|
||||
|
||||
.. function:: regional_log_stats(r)
|
||||
|
||||
Log regional statistics.
|
||||
|
||||
|
||||
:param r: :class:`regional`
|
||||
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
.. function:: strextstate(module_ext_state)
|
||||
|
||||
Debug utility, module external qstate to string.
|
||||
|
||||
|
||||
:param module_ext_state: the state value.
|
||||
:rtype: descriptive string.
|
||||
|
||||
.. function:: strmodulevent(module_event)
|
||||
|
||||
Debug utility, module event to string.
|
||||
|
||||
|
||||
:param module_event: the module event value.
|
||||
:rtype: descriptive string.
|
||||
|
||||
|
||||
.. function:: ldns_rr_type2str(atype)
|
||||
|
||||
Convert RR type to string.
|
||||
|
||||
|
||||
.. function:: ldns_rr_class2str(aclass)
|
||||
|
||||
Convert RR class to string.
|
||||
|
||||
@@ -6,55 +6,94 @@ module_qstate
|
||||
|
||||
.. class:: module_qstate
|
||||
|
||||
Module state, per query.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: qinfo
|
||||
|
||||
(:class:`query_info`) Informations about query being answered. Name, RR type, RR class.
|
||||
|
||||
.. attribute:: query_flags
|
||||
|
||||
(uint16) Flags for query. See QF_BIT\_ predefined constants.
|
||||
|
||||
.. attribute:: is_priming
|
||||
|
||||
If this is a (stub or root) priming query (with hints).
|
||||
|
||||
.. attribute:: reply
|
||||
|
||||
comm_reply contains server replies.
|
||||
|
||||
.. attribute:: return_msg
|
||||
|
||||
(:class:`dns_msg`) The reply message, with message for client and calling module (read-only attribute).
|
||||
Note that if you want to create of modify return_msg you should use :class:`DNSMessage`.
|
||||
|
||||
.. attribute:: return_rcode
|
||||
|
||||
The rcode, in case of error, instead of a reply message. Determines whether the return_msg contains reply.
|
||||
|
||||
.. attribute:: region
|
||||
|
||||
Region for this query. Cleared when query process finishes.
|
||||
|
||||
.. attribute:: curmod
|
||||
|
||||
Which module is executing.
|
||||
|
||||
.. attribute:: ext_state[]
|
||||
|
||||
Module states.
|
||||
|
||||
.. attribute:: env
|
||||
|
||||
Environment for this query.
|
||||
|
||||
.. attribute:: mesh_info
|
||||
|
||||
Mesh related information for this query.
|
||||
Module state, per query.
|
||||
|
||||
This class provides these data attributes:
|
||||
|
||||
.. attribute:: qinfo
|
||||
|
||||
(:class:`query_info`) Informations about query being answered. Name, RR type, RR class.
|
||||
|
||||
.. attribute:: query_flags
|
||||
|
||||
(uint16) Flags for query. See QF_BIT\_ predefined constants.
|
||||
|
||||
.. attribute:: is_priming
|
||||
|
||||
If this is a (stub or root) priming query (with hints).
|
||||
|
||||
.. attribute:: reply
|
||||
|
||||
comm_reply contains server replies.
|
||||
|
||||
.. attribute:: return_msg
|
||||
|
||||
(:class:`dns_msg`) The reply message, with message for client and calling module (read-only attribute).
|
||||
Note that if you want to create of modify return_msg you should use :class:`DNSMessage`.
|
||||
|
||||
.. attribute:: return_rcode
|
||||
|
||||
The rcode, in case of error, instead of a reply message. Determines whether the return_msg contains reply.
|
||||
|
||||
.. attribute:: region
|
||||
|
||||
Region for this query. Cleared when query process finishes.
|
||||
|
||||
.. attribute:: curmod
|
||||
|
||||
Which module is executing.
|
||||
|
||||
.. attribute:: ext_state[]
|
||||
|
||||
Module states.
|
||||
|
||||
.. attribute:: env
|
||||
|
||||
Environment for this query.
|
||||
|
||||
.. attribute:: mesh_info
|
||||
|
||||
Mesh related information for this query.
|
||||
|
||||
.. attribute:: edns_opts_front_in
|
||||
|
||||
Incoming EDNS options from the front end.
|
||||
|
||||
.. attribute:: edns_opts_front_in_iter
|
||||
|
||||
Iterator for `edns_opts_front_in`.
|
||||
|
||||
.. attribute:: edns_opts_back_out
|
||||
|
||||
Outgoing EDNS options to the back end.
|
||||
|
||||
.. attribute:: edns_opts_back_out_iter
|
||||
|
||||
Iterator for `edns_opts_back_out`.
|
||||
|
||||
.. attribute:: edns_opts_back_in
|
||||
|
||||
Incoming EDNS options from the back end.
|
||||
|
||||
.. attribute:: edns_opts_back_in_iter
|
||||
|
||||
Iterator for `ends_opts_back_in`.
|
||||
|
||||
.. attribute:: edns_opts_front_out
|
||||
|
||||
Outgoing EDNS options to the front end.
|
||||
|
||||
.. attribute:: edns_opts_front_out_iter
|
||||
|
||||
Iterator for `edns_opts_front_out`.
|
||||
|
||||
.. attribute:: no_cache_lookup
|
||||
|
||||
Flag to indicate whether modules should answer from the cache.
|
||||
|
||||
.. attribute:: no_cache_store
|
||||
|
||||
Flag to indicate whether modules should store answer in the cache.
|
||||
|
||||
query_info
|
||||
----------------
|
||||
@@ -94,7 +133,57 @@ query_info
|
||||
.. attribute:: qclass_str
|
||||
|
||||
The ``qclass`` in display presentation format (string).
|
||||
|
||||
|
||||
edns_data
|
||||
---------
|
||||
|
||||
.. class:: edns_data
|
||||
|
||||
This class represents the EDNS information parsed/encoded from/to a packet. It provides these data attributes:
|
||||
|
||||
.. attribute:: edns_present
|
||||
|
||||
If EDNS OPT record is present.
|
||||
|
||||
.. attribute:: ext_rcode
|
||||
|
||||
Extended RCODE.
|
||||
|
||||
.. attribute:: edns_version
|
||||
|
||||
The EDNS version number.
|
||||
|
||||
.. attribute:: bits
|
||||
|
||||
The EDNS bits field from ttl (host order): Z.
|
||||
|
||||
.. attribute:: udp_size
|
||||
|
||||
UDP reassembly size.
|
||||
|
||||
.. attribute:: opt_list
|
||||
|
||||
The EDNS option list.
|
||||
|
||||
.. attribute:: opt_list_iter
|
||||
|
||||
Iterator for `opt_list`.
|
||||
|
||||
edns_option
|
||||
-----------
|
||||
|
||||
.. class:: edns_option
|
||||
|
||||
This class represents an EDNS option (code, data) found in EDNS option lists. It provides these data attributes:
|
||||
|
||||
.. attribute:: code
|
||||
|
||||
The EDNS option code.
|
||||
|
||||
.. attribute:: data
|
||||
|
||||
The EDNS option data.
|
||||
|
||||
reply_info
|
||||
--------------------
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
edns.py: python module showcasing EDNS option functionality.
|
||||
|
||||
Copyright (c) 2016, NLnet Labs.
|
||||
|
||||
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.
|
||||
'''
|
||||
#Try:
|
||||
# - dig @localhost nlnetlabs.nl +ednsopt=65001:c001
|
||||
# This query will always reach the modules stage as EDNS option 65001 is
|
||||
# registered to bypass the cache response stage. It will also be handled
|
||||
# as a unique query because of the no_aggregation flag. This means that
|
||||
# it will not be aggregated with other queries for the same qinfo.
|
||||
# For demonstration purposes when option 65001 with hexdata 'c001' is
|
||||
# sent from the client side this module will reply with the same code and
|
||||
# data 'deadbeef'.
|
||||
|
||||
# Useful functions:
|
||||
# edns_opt_list_is_empty(edns_opt_list):
|
||||
# Check if the option list is empty.
|
||||
# Return True if empty, False otherwise.
|
||||
#
|
||||
# edns_opt_list_append(edns_opt_list, code, data_bytearray, region):
|
||||
# Append the EDNS option with code and data_bytearray to the given
|
||||
# edns_opt_list.
|
||||
# NOTE: data_bytearray MUST be a Python bytearray.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# edns_opt_list_remove(edns_opt_list, code):
|
||||
# Remove all occurences of the given EDNS option code from the
|
||||
# edns_opt_list.
|
||||
# Return True when at least one EDNS option was removed, False otherwise.
|
||||
#
|
||||
# register_edns_option(env, code, bypass_cache_stage=True,
|
||||
# no_aggregation=True):
|
||||
# Register EDNS option code as a known EDNS option.
|
||||
# bypass_cache_stage:
|
||||
# bypasses answering from cache and allows the query to reach the
|
||||
# modules for further EDNS handling.
|
||||
# no_aggregation:
|
||||
# makes every query with the said EDNS option code unique.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# Examples on how to use the functions are given in this file.
|
||||
|
||||
|
||||
def init_standard(id, env):
|
||||
"""New version of the init function.
|
||||
The function's signature is the same as the C counterpart and allows for
|
||||
extra functionality during init.
|
||||
..note:: This function is preferred by unbound over the old init function.
|
||||
..note:: The previously accesible configuration options can now be found in
|
||||
env.cgf.
|
||||
"""
|
||||
log_info("python: inited script {}".format(env.cfg.python_script))
|
||||
|
||||
# Register EDNS option 65001 as a known EDNS option.
|
||||
if not register_edns_option(env, 65001, bypass_cache_stage=True,
|
||||
no_aggregation=True):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def init(id, cfg):
|
||||
"""Previous version init function.
|
||||
..note:: This function is still supported for backwards compatibility when
|
||||
the init_standard function is missing. When init_standard is
|
||||
present this function SHOULD be ommited to avoid confusion to the
|
||||
reader.
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def deinit(id): return True
|
||||
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
# Detect if EDNS option code 56001 is present from the client side. If
|
||||
# so turn on the flags for cache management.
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
|
||||
log_info("python: searching for EDNS option code 65001 during NEW "
|
||||
"or PASS event ")
|
||||
for o in qstate.edns_opts_front_in_iter:
|
||||
if o.code == 65001:
|
||||
log_info("python: found EDNS option code 65001")
|
||||
# Instruct other modules to not lookup for an
|
||||
# answer in the cache.
|
||||
qstate.no_cache_lookup = 1
|
||||
log_info("python: enabled no_cache_lookup")
|
||||
|
||||
# Instruct other modules to not store the answer in
|
||||
# the cache.
|
||||
qstate.no_cache_store = 1
|
||||
log_info("python: enabled no_cache_store")
|
||||
|
||||
#Pass on the query
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
elif event == MODULE_EVENT_MODDONE:
|
||||
# If the client sent EDNS option code 65001 and data 'c001' reply
|
||||
# with the same code and data 'deadbeef'.
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
|
||||
log_info("python: searching for EDNS option code 65001 during "
|
||||
"MODDONE")
|
||||
for o in qstate.edns_opts_front_in_iter:
|
||||
if o.code == 65001 and o.data == bytearray.fromhex("c001"):
|
||||
b = bytearray.fromhex("deadbeef")
|
||||
if not edns_opt_list_append(qstate.edns_opts_front_out,
|
||||
o.code, b, qstate.region):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return False
|
||||
|
||||
# List every EDNS option in all lists.
|
||||
# The available lists are:
|
||||
# - qstate.edns_opts_front_in: EDNS options that came from the
|
||||
# client side. SHOULD NOT be changed;
|
||||
#
|
||||
# - qstate.edns_opts_back_out: EDNS options that will be sent to the
|
||||
# server side. Can be populated by
|
||||
# EDNS literate modules;
|
||||
#
|
||||
# - qstate.edns_opts_back_in: EDNS options that came from the
|
||||
# server side. SHOULD NOT be changed;
|
||||
#
|
||||
# - qstate.edns_opts_front_out: EDNS options that will be sent to the
|
||||
# client side. Can be populated by
|
||||
# EDNS literate modules;
|
||||
#
|
||||
# The lists' contents can be accessed in python by their _iter
|
||||
# counterpart as an iterator.
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_in):
|
||||
log_info("python: EDNS options in edns_opts_front_in:")
|
||||
for o in qstate.edns_opts_front_in_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_back_out):
|
||||
log_info("python: EDNS options in edns_opts_back_out:")
|
||||
for o in qstate.edns_opts_back_out_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_back_in):
|
||||
log_info("python: EDNS options in edns_opts_back_in:")
|
||||
for o in qstate.edns_opts_back_in_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
|
||||
if not edns_opt_list_is_empty(qstate.edns_opts_front_out):
|
||||
log_info("python: EDNS options in edns_opts_front_out:")
|
||||
for o in qstate.edns_opts_front_out_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: Unknown event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
@@ -0,0 +1,244 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
inplace_callbacks.py: python module showcasing inplace callback function
|
||||
registration and functionality.
|
||||
|
||||
Copyright (c) 2016, NLnet Labs.
|
||||
|
||||
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.
|
||||
'''
|
||||
#Try:
|
||||
# - dig @localhost nlnetlabs.nl +ednsopt=65002:
|
||||
# This query *could* be answered from cache. If so, unbound will reply
|
||||
# with the same EDNS option 65002, but with hexdata 'deadbeef' as data.
|
||||
#
|
||||
# - dig @localhost bogus.nlnetlabs.nl txt:
|
||||
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
|
||||
# intentionally bogus. The reply will contain an empty EDNS option
|
||||
# with option code 65003.
|
||||
# (unbound needs to be validating for this example to work)
|
||||
|
||||
# Useful functions:
|
||||
# register_inplace_cb_reply(inplace_reply_callback, env):
|
||||
# Register the reply_callback function as an inplace callback function
|
||||
# when answering with a resolved query.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# register_inplace_cb_reply_cache(inplace_reply_cache_callback, env):
|
||||
# Register the reply_cache_callback function as an inplace callback
|
||||
# function when answering from cache.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# register_inplace_cb_reply_local(inplace_reply_local_callback, env):
|
||||
# Register the reply_local_callback function as an inplace callback
|
||||
# function when answering from local data or chaos reply.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# register_inplace_cb_reply_servfail(inplace_reply_servfail_callback, env):
|
||||
# Register the reply_servfail_callback function as an inplace callback
|
||||
# function when answering with servfail.
|
||||
# Return True on success, False on failure.
|
||||
#
|
||||
# Examples on how to use the functions are given in this file.
|
||||
|
||||
|
||||
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with a resolved query.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. It contains the available opt_lists; It
|
||||
SHOULD NOT be altered;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data to be sent to the client side. It SHOULD NOT be
|
||||
altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
log_info("python: called back while replying.")
|
||||
return True
|
||||
|
||||
|
||||
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from the cache.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data sent from the client side. The list with the EDNS
|
||||
options is accesible through edns.opt_list. It SHOULD NOT be
|
||||
altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demostration purposes we want to see if EDNS option 65002 is present
|
||||
and reply with a new value.
|
||||
"""
|
||||
log_info("python: called back while answering from cache.")
|
||||
# Inspect the incoming EDNS options.
|
||||
if not edns_opt_list_is_empty(edns.opt_list):
|
||||
log_info("python: available EDNS options:")
|
||||
for o in edns.opt_list_iter:
|
||||
log_info("python: Code: {}, Data: '{}'".format(o.code,
|
||||
"".join('{:02x}'.format(x) for x in o.data)))
|
||||
if o.code == 65002:
|
||||
log_info("python: *found option code 65002*")
|
||||
|
||||
# add to opt_list
|
||||
# Data MUST be represented in a bytearray.
|
||||
b = bytearray.fromhex("deadbeef")
|
||||
if edns_opt_list_append(opt_list_out, o.code, b, region):
|
||||
log_info("python: *added new option code 65002*")
|
||||
else:
|
||||
log_info("python: *failed to add new option code 65002*")
|
||||
return False
|
||||
break
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from local data.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
:param rcode: return code for the query;
|
||||
:param edns: edns_data sent from the client side. The list with the
|
||||
EDNS options is accesible through edns.opt_list. It
|
||||
SHOULD NOT be altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
"""
|
||||
log_info("python: called back while replying with local data or chaos"
|
||||
" reply.")
|
||||
return True
|
||||
|
||||
|
||||
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with SERVFAIL.
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. If not None the relevant opt_lists are
|
||||
available here;
|
||||
:param rep: reply_info struct. None;
|
||||
:param rcode: return code for the query. LDNS_RCODE_SERVFAIL;
|
||||
:param edns: edns_data to be sent to the client side. If qstate is None
|
||||
edns.opt_list contains the EDNS options sent from the client
|
||||
side. It SHOULD NOT be altered;
|
||||
:param opt_list_out: the list with the EDNS options that will be sent as a
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demostration purposes we want to reply with an empty EDNS code '65003'.
|
||||
"""
|
||||
log_info("python: called back while servfail.")
|
||||
b = bytearray.fromhex("")
|
||||
edns_opt_list_append(opt_list_out, 65003, b, region)
|
||||
return True
|
||||
|
||||
|
||||
def init_standard(id, env):
|
||||
"""New version of the init function.
|
||||
The function's signature is the same as the C counterpart and allows for
|
||||
extra functionality during init.
|
||||
..note:: This function is preferred by unbound over the old init function.
|
||||
..note:: The previously accesible configuration options can now be found in
|
||||
env.cgf.
|
||||
"""
|
||||
log_info("python: inited script {}".format(env.cfg.python_script))
|
||||
|
||||
# Register the inplace_reply_callback function as an inplace callback
|
||||
# function when answering a resolved query.
|
||||
if not register_inplace_cb_reply(inplace_reply_callback, env):
|
||||
return False
|
||||
|
||||
# Register the inplace_cache_callback function as an inplace callback
|
||||
# function when answering from cache.
|
||||
if not register_inplace_cb_reply_cache(inplace_cache_callback, env):
|
||||
return False
|
||||
|
||||
# Register the inplace_local_callback function as an inplace callback
|
||||
# function when answering from local data.
|
||||
if not register_inplace_cb_reply_local(inplace_local_callback, env):
|
||||
return False
|
||||
|
||||
# Register the inplace_servfail_callback function as an inplace callback
|
||||
# function when answering with SERVFAIL.
|
||||
if not register_inplace_cb_reply_servfail(inplace_servfail_callback, env):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def init(id, cfg):
|
||||
"""Previous version init function.
|
||||
..note:: This function is still supported for backwards compatibility when
|
||||
the init_standard function is missing. When init_standard is
|
||||
present this function SHOULD be ommited to avoid confusion to the
|
||||
reader.
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def deinit(id): return True
|
||||
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
elif event == MODULE_EVENT_MODDONE:
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
log_err("pythonmod: Unknown event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
+401
-38
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* interface.i: unbound python module
|
||||
*/
|
||||
|
||||
%module unboundmodule
|
||||
%{
|
||||
/**
|
||||
@@ -34,10 +33,10 @@
|
||||
#include "sldns/pkthdr.h"
|
||||
%}
|
||||
|
||||
%include "stdint.i" // uint_16_t can be known type now
|
||||
%include "stdint.i" /* uint_16_t can be known type now */
|
||||
|
||||
%inline %{
|
||||
//converts [len][data][len][data][0] string to a List of labels (PyBytes)
|
||||
/* converts [len][data][len][data][0] string to a List of labels (PyBytes) */
|
||||
PyObject* GetNameAsLabelList(const char* name, int len) {
|
||||
PyObject* list;
|
||||
int cnt=0, i;
|
||||
@@ -202,13 +201,16 @@ struct packed_rrset_key {
|
||||
char* dname;
|
||||
size_t dname_len;
|
||||
uint32_t flags;
|
||||
uint16_t type; //rrset type in network format
|
||||
uint16_t rrset_class; //rrset class in network format
|
||||
uint16_t type; /* rrset type in network format */
|
||||
uint16_t rrset_class; /* rrset class in network format */
|
||||
%mutable;
|
||||
};
|
||||
|
||||
//This subroutine converts values between the host and network byte order.
|
||||
//Specifically, ntohs() converts 16-bit quantities from network byte order to host byte order.
|
||||
/**
|
||||
* This subroutine converts values between the host and network byte order.
|
||||
* Specifically, ntohs() converts 16-bit quantities from network byte order to
|
||||
* host byte order.
|
||||
*/
|
||||
uint16_t ntohs(uint16_t netshort);
|
||||
|
||||
%inline %{
|
||||
@@ -243,23 +245,23 @@ uint16_t ntohs(uint16_t netshort);
|
||||
}
|
||||
|
||||
#if defined(SWIGWORDSIZE64)
|
||||
typedef long int rrset_id_t;
|
||||
typedef long int rrset_id_type;
|
||||
#else
|
||||
typedef long long int rrset_id_t;
|
||||
typedef long long int rrset_id_type;
|
||||
#endif
|
||||
|
||||
struct ub_packed_rrset_key {
|
||||
struct lruhash_entry entry;
|
||||
rrset_id_t id;
|
||||
rrset_id_type id;
|
||||
struct packed_rrset_key rk;
|
||||
};
|
||||
|
||||
struct lruhash_entry {
|
||||
lock_rw_t lock;
|
||||
lock_rw_type lock;
|
||||
struct lruhash_entry* overflow_next;
|
||||
struct lruhash_entry* lru_next;
|
||||
struct lruhash_entry* lru_prev;
|
||||
hashvalue_t hash;
|
||||
hashvalue_type hash;
|
||||
void* key;
|
||||
struct packed_rrset_data* data;
|
||||
};
|
||||
@@ -269,17 +271,24 @@ struct lruhash_entry {
|
||||
%ignore packed_rrset_data::rr_data;
|
||||
|
||||
struct packed_rrset_data {
|
||||
uint32_t ttl; //TTL (in seconds like time())
|
||||
/* TTL (in seconds like time()) */
|
||||
uint32_t ttl;
|
||||
|
||||
size_t count; //number of rrs
|
||||
size_t rrsig_count; //number of rrsigs
|
||||
/* number of rrs */
|
||||
size_t count;
|
||||
/* number of rrsigs */
|
||||
size_t rrsig_count;
|
||||
|
||||
enum rrset_trust trust;
|
||||
enum sec_status security;
|
||||
|
||||
size_t* rr_len; //length of every rr's rdata
|
||||
uint32_t *rr_ttl; //ttl of every rr
|
||||
uint8_t** rr_data; //array of pointers to every rr's rdata; The rr_data[i] rdata is stored in uncompressed wireformat.
|
||||
/* length of every rr's rdata */
|
||||
size_t* rr_len;
|
||||
/* ttl of every rr */
|
||||
uint32_t *rr_ttl;
|
||||
/* array of pointers to every rr's rdata. The rr_data[i] rdata is stored in
|
||||
* uncompressed wireformat. */
|
||||
uint8_t** rr_data;
|
||||
};
|
||||
|
||||
%pythoncode %{
|
||||
@@ -359,15 +368,15 @@ struct reply_info {
|
||||
size_t an_numrrsets;
|
||||
size_t ns_numrrsets;
|
||||
size_t ar_numrrsets;
|
||||
size_t rrset_count; // an_numrrsets + ns_numrrsets + ar_numrrsets
|
||||
size_t rrset_count; /* an_numrrsets + ns_numrrsets + ar_numrrsets */
|
||||
|
||||
struct ub_packed_rrset_key** rrsets;
|
||||
struct rrset_ref ref[1]; //?
|
||||
struct rrset_ref ref[1]; /* ? */
|
||||
};
|
||||
|
||||
struct rrset_ref {
|
||||
struct ub_packed_rrset_key* key;
|
||||
rrset_id_t id;
|
||||
rrset_id_type id;
|
||||
};
|
||||
|
||||
struct dns_msg {
|
||||
@@ -396,11 +405,11 @@ struct dns_msg {
|
||||
|
||||
struct rrset_ref* _rrset_ref_get(struct reply_info* r, int idx) {
|
||||
if ((r != NULL) && (idx >= 0) && ((size_t)idx < r->rrset_count)) {
|
||||
//printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key);
|
||||
/* printf("_rrset_ref_get: %lX key:%lX\n", r->ref + idx, r->ref[idx].key); */
|
||||
return &(r->ref[idx]);
|
||||
// return &(r->ref[idx]);
|
||||
/* return &(r->ref[idx]); */
|
||||
}
|
||||
//printf("_rrset_ref_get: NULL\n");
|
||||
/* printf("_rrset_ref_get: NULL\n"); */
|
||||
return NULL;
|
||||
}
|
||||
%}
|
||||
@@ -479,30 +488,166 @@ struct comm_reply {
|
||||
if _newclass:family = _swig_property(_family_get)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure edns_option
|
||||
* ************************************************************************************ */
|
||||
/* Rename the members to follow the python convention of marking them as
|
||||
* private. Access to the opt_code and opt_data members is given by the later
|
||||
* python defined code and data members respectively. */
|
||||
%rename(_next) edns_option::next;
|
||||
%rename(_opt_code) edns_option::opt_code;
|
||||
%rename(_opt_len) edns_option::opt_len;
|
||||
%rename(_opt_data) edns_option::opt_data;
|
||||
struct edns_option {
|
||||
struct edns_option* next;
|
||||
uint16_t opt_code;
|
||||
size_t opt_len;
|
||||
uint8_t* opt_data;
|
||||
};
|
||||
|
||||
%inline %{
|
||||
PyObject* _edns_option_opt_code_get(struct edns_option* option) {
|
||||
uint16_t opt_code = option->opt_code;
|
||||
return PyInt_FromLong(opt_code);
|
||||
}
|
||||
|
||||
PyObject* _edns_option_opt_data_get(struct edns_option* option) {
|
||||
return PyByteArray_FromStringAndSize((void*)option->opt_data,
|
||||
option->opt_len);
|
||||
}
|
||||
%}
|
||||
%extend edns_option {
|
||||
%pythoncode %{
|
||||
def _opt_code_get(self): return _edns_option_opt_code_get(self)
|
||||
__swig_getmethods__["code"] = _opt_code_get
|
||||
if _newclass: opt_code = _swig_property(_opt_code_get)
|
||||
|
||||
def _opt_data_get(self): return _edns_option_opt_data_get(self)
|
||||
__swig_getmethods__["data"] = _opt_data_get
|
||||
if _newclass: opt_data = _swig_property(_opt_data_get)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure edns_data
|
||||
* ************************************************************************************ */
|
||||
/* This is ignored because we will pass a double pointer of this to Python
|
||||
* with custom getmethods. This is done to bypass Swig's behavior to pass NULL
|
||||
* pointers as None. */
|
||||
%ignore edns_data::opt_list;
|
||||
struct edns_data {
|
||||
int edns_present;
|
||||
uint8_t ext_rcode;
|
||||
uint8_t edns_version;
|
||||
uint16_t bits;
|
||||
uint16_t udp_size;
|
||||
struct edns_option* opt_list;
|
||||
};
|
||||
%inline %{
|
||||
struct edns_option** _edns_data_opt_list_get(struct edns_data* edns) {
|
||||
return &edns->opt_list;
|
||||
}
|
||||
%}
|
||||
%extend edns_data {
|
||||
%pythoncode %{
|
||||
def _opt_list_iter(self): return EdnsOptsListIter(self.opt_list)
|
||||
__swig_getmethods__["opt_list_iter"] = _opt_list_iter
|
||||
if _newclass:opt_list_iter = _swig_property(_opt_list_iter)
|
||||
def _opt_list(self): return _edns_data_opt_list_get(self)
|
||||
__swig_getmethods__["opt_list"] = _opt_list
|
||||
if _newclass:opt_list = _swig_property(_opt_list)
|
||||
%}
|
||||
}
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure module_env
|
||||
* ************************************************************************************ */
|
||||
struct module_env {
|
||||
struct config_file* cfg;
|
||||
struct slabhash* msg_cache;
|
||||
struct rrset_cache* rrset_cache;
|
||||
struct infra_cache* infra_cache;
|
||||
struct key_cache* key_cache;
|
||||
|
||||
/* --- services --- */
|
||||
struct outbound_entry* (*send_query)(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q);
|
||||
void (*detach_subs)(struct module_qstate* qstate);
|
||||
int (*attach_sub)(struct module_qstate* qstate,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq);
|
||||
void (*kill_sub)(struct module_qstate* newq);
|
||||
int (*detect_cycle)(struct module_qstate* qstate,
|
||||
struct query_info* qinfo, uint16_t flags, int prime,
|
||||
int valrec);
|
||||
|
||||
struct regional* scratch;
|
||||
struct sldns_buffer* scratch_buffer;
|
||||
struct worker* worker;
|
||||
struct mesh_area* mesh;
|
||||
struct alloc_cache* alloc;
|
||||
struct ub_randstate* rnd;
|
||||
time_t* now;
|
||||
struct timeval* now_tv;
|
||||
int need_to_validate;
|
||||
struct val_anchors* anchors;
|
||||
struct val_neg_cache* neg_cache;
|
||||
struct comm_timer* probe_timer;
|
||||
struct iter_forwards* fwds;
|
||||
struct iter_hints* hints;
|
||||
void* modinfo[MAX_MODULE];
|
||||
|
||||
void* inplace_cb_lists[inplace_cb_types_total];
|
||||
struct edns_known_option* edns_known_options;
|
||||
size_t edns_known_options_num;
|
||||
};
|
||||
|
||||
|
||||
/* ************************************************************************************ *
|
||||
Structure module_qstate
|
||||
* ************************************************************************************ */
|
||||
%ignore module_qstate::ext_state;
|
||||
%ignore module_qstate::minfo;
|
||||
|
||||
/* These are ignored because we will pass a double pointer of them to Python
|
||||
* with custom getmethods. This is done to bypass Swig's behavior to pass NULL
|
||||
* pointers as None. */
|
||||
%ignore module_qstate::edns_opts_front_in;
|
||||
%ignore module_qstate::edns_opts_back_out;
|
||||
%ignore module_qstate::edns_opts_back_in;
|
||||
%ignore module_qstate::edns_opts_front_out;
|
||||
|
||||
/* Query state */
|
||||
struct module_qstate {
|
||||
struct query_info qinfo;
|
||||
uint16_t query_flags; //See QF_BIT_xx constants
|
||||
int is_priming;
|
||||
uint16_t query_flags; /* See QF_BIT_xx constants */
|
||||
int is_priming;
|
||||
int is_valrec;
|
||||
|
||||
struct comm_reply* reply;
|
||||
struct dns_msg* return_msg;
|
||||
int return_rcode;
|
||||
int return_rcode;
|
||||
struct regional* region; /* unwrapped */
|
||||
|
||||
int curmod;
|
||||
int curmod;
|
||||
|
||||
enum module_ext_state ext_state[MAX_MODULE];
|
||||
void* minfo[MAX_MODULE];
|
||||
enum module_ext_state ext_state[MAX_MODULE];
|
||||
void* minfo[MAX_MODULE];
|
||||
time_t prefetch_leeway;
|
||||
|
||||
struct module_env* env; /* unwrapped */
|
||||
struct mesh_state* mesh_info;
|
||||
|
||||
struct edns_option* edns_opts_front_in;
|
||||
struct edns_option* edns_opts_back_out;
|
||||
struct edns_option* edns_opts_back_in;
|
||||
struct edns_option* edns_opts_front_out;
|
||||
int no_cache_lookup;
|
||||
int no_cache_store;
|
||||
};
|
||||
|
||||
%constant int MODULE_COUNT = MAX_MODULE;
|
||||
@@ -540,6 +685,25 @@ struct module_qstate {
|
||||
def __getitem__(self, index): return _unboundmodule._ext_state_get(self.obj, index)
|
||||
def __setitem__(self, index, value): _unboundmodule._ext_state_set(self.obj, index, value)
|
||||
def __len__(self): return _unboundmodule.MODULE_COUNT
|
||||
|
||||
class EdnsOptsListIter:
|
||||
def __init__(self, obj):
|
||||
self._current = obj
|
||||
self._temp = None
|
||||
def __iter__(self): return self
|
||||
def __next__(self):
|
||||
"""Python 3 compatibility"""
|
||||
return self._get_next()
|
||||
def next(self):
|
||||
"""Python 2 compatibility"""
|
||||
return self._get_next()
|
||||
def _get_next(self):
|
||||
if not edns_opt_list_is_empty(self._current):
|
||||
self._temp = self._current
|
||||
self._current = _p_p_edns_option_get_next(self._current)
|
||||
return _dereference_edns_option(self._temp)
|
||||
else:
|
||||
raise StopIteration
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
@@ -549,12 +713,42 @@ struct module_qstate {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void _ext_state_set(struct module_qstate* q, int idx, enum module_ext_state state) {
|
||||
if ((q != NULL) && (idx >= 0) && (idx < MAX_MODULE)) {
|
||||
q->ext_state[idx] = state;
|
||||
}
|
||||
}
|
||||
|
||||
int edns_opt_list_is_empty(struct edns_option** opt) {
|
||||
if (!opt || !(*opt)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct edns_option* _dereference_edns_option(struct edns_option** opt) {
|
||||
if (!opt) return NULL;
|
||||
return *opt;
|
||||
}
|
||||
|
||||
struct edns_option** _p_p_edns_option_get_next(struct edns_option** opt) {
|
||||
return &(*opt)->next;
|
||||
}
|
||||
|
||||
struct edns_option** _edns_opts_front_in_get(struct module_qstate* q) {
|
||||
return &q->edns_opts_front_in;
|
||||
}
|
||||
|
||||
struct edns_option** _edns_opts_back_out_get(struct module_qstate* q) {
|
||||
return &q->edns_opts_back_out;
|
||||
}
|
||||
|
||||
struct edns_option** _edns_opts_back_in_get(struct module_qstate* q) {
|
||||
return &q->edns_opts_back_in;
|
||||
}
|
||||
|
||||
struct edns_option** _edns_opts_front_out_get(struct module_qstate* q) {
|
||||
return &q->edns_opts_front_out;
|
||||
}
|
||||
%}
|
||||
|
||||
%extend module_qstate {
|
||||
@@ -566,6 +760,32 @@ struct module_qstate {
|
||||
def __ext_state_get(self): return ExtState(self)
|
||||
__swig_getmethods__["ext_state"] = __ext_state_get
|
||||
if _newclass:ext_state = _swig_property(__ext_state_get)#, __ext_state_set)
|
||||
|
||||
def _edns_opts_front_in_iter(self): return EdnsOptsListIter(self.edns_opts_front_in)
|
||||
__swig_getmethods__["edns_opts_front_in_iter"] = _edns_opts_front_in_iter
|
||||
if _newclass:edns_opts_front_in_iter = _swig_property(_edns_opts_front_in_iter)
|
||||
def _edns_opts_back_out_iter(self): return EdnsOptsListIter(self.edns_opts_back_out)
|
||||
__swig_getmethods__["edns_opts_back_out_iter"] = _edns_opts_back_out_iter
|
||||
if _newclass:edns_opts_back_out_iter = _swig_property(_edns_opts_back_out_iter)
|
||||
def _edns_opts_back_in_iter(self): return EdnsOptsListIter(self.edns_opts_back_in)
|
||||
__swig_getmethods__["edns_opts_back_in_iter"] = _edns_opts_back_in_iter
|
||||
if _newclass:edns_opts_back_in_iter = _swig_property(_edns_opts_back_in_iter)
|
||||
def _edns_opts_front_out_iter(self): return EdnsOptsListIter(self.edns_opts_front_out)
|
||||
__swig_getmethods__["edns_opts_front_out_iter"] = _edns_opts_front_out_iter
|
||||
if _newclass:edns_opts_front_out_iter = _swig_property(_edns_opts_front_out_iter)
|
||||
|
||||
def _edns_opts_front_in(self): return _edns_opts_front_in_get(self)
|
||||
__swig_getmethods__["edns_opts_front_in"] = _edns_opts_front_in
|
||||
if _newclass:edns_opts_front_in = _swig_property(_edns_opts_front_in)
|
||||
def _edns_opts_back_out(self): return _edns_opts_back_out_get(self)
|
||||
__swig_getmethods__["edns_opts_back_out"] = _edns_opts_back_out
|
||||
if _newclass:edns_opts_back_out = _swig_property(_edns_opts_back_out)
|
||||
def _edns_opts_back_in(self): return _edns_opts_back_in_get(self)
|
||||
__swig_getmethods__["edns_opts_back_in"] = _edns_opts_back_in
|
||||
if _newclass:edns_opts_back_in = _swig_property(_edns_opts_back_in)
|
||||
def _edns_opts_front_out(self): return _edns_opts_front_out_get(self)
|
||||
__swig_getmethods__["edns_opts_front_out"] = _edns_opts_front_out
|
||||
if _newclass:edns_opts_front_out = _swig_property(_edns_opts_front_out)
|
||||
%}
|
||||
}
|
||||
|
||||
@@ -1037,8 +1257,9 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
|
||||
/* ************************************************************************************ *
|
||||
Functions
|
||||
* ************************************************************************************ */
|
||||
|
||||
// Various debuging functions
|
||||
/******************************
|
||||
* Various debuging functions *
|
||||
******************************/
|
||||
void verbose(enum verbosity_value level, const char* format, ...);
|
||||
void log_info(const char* format, ...);
|
||||
void log_err(const char* format, ...);
|
||||
@@ -1048,24 +1269,166 @@ void log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* r
|
||||
void log_query_info(enum verbosity_value v, const char* str, struct query_info* qinf);
|
||||
void regional_log_stats(struct regional *r);
|
||||
|
||||
// Free allocated memory from marked sources returning corresponding types
|
||||
/***************************************************************************
|
||||
* Free allocated memory from marked sources returning corresponding types *
|
||||
***************************************************************************/
|
||||
%typemap(newfree, noblock = 1) char * {
|
||||
free($1);
|
||||
}
|
||||
|
||||
// Mark as source returning newly allocated memory
|
||||
/***************************************************
|
||||
* Mark as source returning newly allocated memory *
|
||||
***************************************************/
|
||||
%newobject sldns_wire2str_type;
|
||||
%newobject sldns_wire2str_class;
|
||||
|
||||
// LDNS functions
|
||||
/******************
|
||||
* LDNS functions *
|
||||
******************/
|
||||
char *sldns_wire2str_type(const uint16_t atype);
|
||||
char *sldns_wire2str_class(const uint16_t aclass);
|
||||
|
||||
// Functions from pythonmod_utils
|
||||
/**********************************
|
||||
* Functions from pythonmod_utils *
|
||||
**********************************/
|
||||
int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral);
|
||||
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo);
|
||||
|
||||
// Module conversion functions
|
||||
/*******************************
|
||||
* Module conversion functions *
|
||||
*******************************/
|
||||
const char* strextstate(enum module_ext_state s);
|
||||
const char* strmodulevent(enum module_ev e);
|
||||
|
||||
/**************************
|
||||
* Edns related functions *
|
||||
**************************/
|
||||
struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
|
||||
int edns_register_option(uint16_t opt_code, int bypass_cache_stage,
|
||||
int no_aggregation, struct module_env* env);
|
||||
|
||||
%pythoncode %{
|
||||
def register_edns_option(env, code, bypass_cache_stage=False,
|
||||
no_aggregation=False):
|
||||
"""Wrapper function to provide keyword attributes."""
|
||||
return edns_register_option(code, bypass_cache_stage,
|
||||
no_aggregation, env)
|
||||
%}
|
||||
|
||||
/******************************
|
||||
* Callback related functions *
|
||||
******************************/
|
||||
/* typemap to check if argument is callable */
|
||||
%typemap(in) PyObject *py_cb {
|
||||
if (!PyCallable_Check($input)) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "Need a callable object!");
|
||||
return NULL;
|
||||
}
|
||||
$1 = $input;
|
||||
}
|
||||
/* typemap to get content/size from a bytearray */
|
||||
%typemap(in) (size_t len, uint8_t* py_bytearray_data) {
|
||||
if (!PyByteArray_CheckExact($input)) {
|
||||
SWIG_exception_fail(SWIG_TypeError, "Expected bytearray!");
|
||||
return NULL;
|
||||
}
|
||||
$2 = (void*)PyByteArray_AsString($input);
|
||||
$1 = PyByteArray_Size($input);
|
||||
}
|
||||
|
||||
int edns_opt_list_remove(struct edns_option** list, uint16_t code);
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* py_bytearray_data, struct regional* region);
|
||||
|
||||
%{
|
||||
/* This function is called by unbound in order to call the python
|
||||
* callback function. */
|
||||
int python_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct regional* region, void* python_callback)
|
||||
{
|
||||
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
|
||||
PyObject *py_rep, *py_region;
|
||||
PyObject *result;
|
||||
int res = 0;
|
||||
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
func = (PyObject *) python_callback;
|
||||
py_edns = SWIG_NewPointerObj((void*) edns, SWIGTYPE_p_edns_data, 0);
|
||||
py_qstate = SWIG_NewPointerObj((void*) qstate,
|
||||
SWIGTYPE_p_module_qstate, 0);
|
||||
py_opt_list_out = SWIG_NewPointerObj((void*) opt_list_out,
|
||||
SWIGTYPE_p_p_edns_option, 0);
|
||||
py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
|
||||
py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
|
||||
py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
|
||||
result = PyObject_CallFunction(func, "OOOiOOO", py_qinfo, py_qstate,
|
||||
py_rep, rcode, py_edns, py_opt_list_out, py_region);
|
||||
Py_XDECREF(py_edns);
|
||||
Py_XDECREF(py_qstate);
|
||||
Py_XDECREF(py_opt_list_out);
|
||||
Py_XDECREF(py_qinfo);
|
||||
Py_XDECREF(py_rep);
|
||||
Py_XDECREF(py_region);
|
||||
if (result) {
|
||||
res = PyInt_AsLong(result);
|
||||
}
|
||||
Py_XDECREF(result);
|
||||
PyGILState_Release(gstate);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Swig implementations for Python */
|
||||
static int register_inplace_cb_reply(PyObject* py_cb,
|
||||
struct module_env* env)
|
||||
{
|
||||
int ret = inplace_cb_reply_register(
|
||||
python_inplace_cb_reply_generic, (void*) py_cb, env);
|
||||
if (ret) Py_INCREF(py_cb);
|
||||
return ret;
|
||||
}
|
||||
static int register_inplace_cb_reply_cache(PyObject* py_cb,
|
||||
struct module_env* env)
|
||||
{
|
||||
int ret = inplace_cb_reply_cache_register(
|
||||
python_inplace_cb_reply_generic, (void*) py_cb, env);
|
||||
if (ret) Py_INCREF(py_cb);
|
||||
return ret;
|
||||
}
|
||||
static int register_inplace_cb_reply_local(PyObject* py_cb,
|
||||
struct module_env* env)
|
||||
{
|
||||
int ret = inplace_cb_reply_local_register(
|
||||
python_inplace_cb_reply_generic, (void*) py_cb, env);
|
||||
if (ret) Py_INCREF(py_cb);
|
||||
return ret;
|
||||
}
|
||||
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
|
||||
struct module_env* env)
|
||||
{
|
||||
int ret = inplace_cb_reply_servfail_register(
|
||||
python_inplace_cb_reply_generic, (void*) py_cb, env);
|
||||
if (ret) Py_INCREF(py_cb);
|
||||
return ret;
|
||||
}
|
||||
%}
|
||||
/* C declarations */
|
||||
int inplace_cb_reply_register(
|
||||
inplace_cb_reply_func_type* cb, void* cb_arg, struct module_env* env);
|
||||
int inplace_cb_reply_cache_register(
|
||||
inplace_cb_reply_func_type* cb, void* cb_arg, struct module_env* env);
|
||||
int inplace_cb_reply_local_register(
|
||||
inplace_cb_reply_func_type* cb, void* cb_arg, struct module_env* env);
|
||||
int inplace_cb_reply_servfail_register(
|
||||
inplace_cb_reply_func_type* cb, void* cb_arg, struct module_env* env);
|
||||
|
||||
/* Swig declarations */
|
||||
static int register_inplace_cb_reply(PyObject* py_cb,
|
||||
struct module_env* env);
|
||||
static int register_inplace_cb_reply_cache(PyObject* py_cb,
|
||||
struct module_env* env);
|
||||
static int register_inplace_cb_reply_local(PyObject* py_cb,
|
||||
struct module_env* env);
|
||||
static int register_inplace_cb_reply_servfail(PyObject* py_cb,
|
||||
struct module_env* env);
|
||||
|
||||
+30
-12
@@ -112,8 +112,10 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
{
|
||||
/* Initialize module */
|
||||
FILE* script_py = NULL;
|
||||
PyObject* py_cfg, *res;
|
||||
PyObject* py_init_arg, *res;
|
||||
PyGILState_STATE gil;
|
||||
int init_standard = 1;
|
||||
|
||||
struct pythonmod_env* pe = (struct pythonmod_env*)calloc(1, sizeof(struct pythonmod_env));
|
||||
if (!pe)
|
||||
{
|
||||
@@ -156,10 +158,10 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
PyRun_SimpleString("import sys \n");
|
||||
PyRun_SimpleString("sys.path.append('.') \n");
|
||||
if(env->cfg->directory && env->cfg->directory[0]) {
|
||||
char wdir[1524];
|
||||
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
|
||||
env->cfg->directory);
|
||||
PyRun_SimpleString(wdir);
|
||||
char wdir[1524];
|
||||
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
|
||||
env->cfg->directory);
|
||||
PyRun_SimpleString(wdir);
|
||||
}
|
||||
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
|
||||
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
|
||||
@@ -198,11 +200,15 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
|
||||
fclose(script_py);
|
||||
|
||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
|
||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init_standard")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function init is missing in %s", pe->fname);
|
||||
PyGILState_Release(gil);
|
||||
return 0;
|
||||
init_standard = 0;
|
||||
if ((pe->func_init = PyDict_GetItemString(pe->dict, "init")) == NULL)
|
||||
{
|
||||
log_err("pythonmod: function init is missing in %s", pe->fname);
|
||||
PyGILState_Release(gil);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((pe->func_deinit = PyDict_GetItemString(pe->dict, "deinit")) == NULL)
|
||||
{
|
||||
@@ -223,16 +229,28 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
py_cfg = SWIG_NewPointerObj((void*) env->cfg, SWIGTYPE_p_config_file, 0);
|
||||
res = PyObject_CallFunction(pe->func_init, "iO", id, py_cfg);
|
||||
if (init_standard)
|
||||
{
|
||||
py_init_arg = SWIG_NewPointerObj((void*) env, SWIGTYPE_p_module_env, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
py_init_arg = SWIG_NewPointerObj((void*) env->cfg,
|
||||
SWIGTYPE_p_config_file, 0);
|
||||
}
|
||||
res = PyObject_CallFunction(pe->func_init, "iO", id, py_init_arg);
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
log_err("pythonmod: Exception occurred in function init");
|
||||
PyErr_Print();
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_init_arg);
|
||||
PyGILState_Release(gil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_XDECREF(res);
|
||||
Py_XDECREF(py_cfg);
|
||||
Py_XDECREF(py_init_arg);
|
||||
PyGILState_Release(gil);
|
||||
|
||||
return 1;
|
||||
|
||||
+10
-2
@@ -55,14 +55,22 @@ int pythonmod_init(struct module_env* env, int id);
|
||||
void pythonmod_deinit(struct module_env* env, int id);
|
||||
|
||||
/** python module operate on a query */
|
||||
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event, int id, struct outbound_entry* outbound);
|
||||
void pythonmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound);
|
||||
|
||||
/** python module */
|
||||
void pythonmod_inform_super(struct module_qstate* qstate, int id, struct module_qstate* super);
|
||||
void pythonmod_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
|
||||
/** python module cleanup query state */
|
||||
void pythonmod_clear(struct module_qstate* qstate, int id);
|
||||
|
||||
/** python module alloc size routine */
|
||||
size_t pythonmod_get_mem(struct module_env* env, int id);
|
||||
|
||||
/** Declared here for fptr_wlist access. The definition is in interface.i. */
|
||||
int python_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct regional* region, void* python_callback);
|
||||
#endif /* PYTHONMOD_H */
|
||||
|
||||
@@ -74,7 +74,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
|
||||
/* Invalidate the message associated with query_info stored in message cache */
|
||||
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo)
|
||||
{
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
struct lruhash_entry* e;
|
||||
struct reply_info *r;
|
||||
size_t i, j;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Example configuration file for edns.py
|
||||
server:
|
||||
verbosity: 1
|
||||
interface: 0.0.0.0
|
||||
do-daemonize: no
|
||||
access-control: 0.0.0.0/0 allow
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
logfile: ""
|
||||
pidfile: "unbound.pid"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/edns.py"
|
||||
@@ -0,0 +1,17 @@
|
||||
# Example configuration file for edns.py
|
||||
server:
|
||||
verbosity: 1
|
||||
interface: 0.0.0.0
|
||||
do-daemonize: no
|
||||
access-control: 0.0.0.0/0 allow
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
logfile: ""
|
||||
pidfile: "unbound.pid"
|
||||
module-config: "validator python iterator"
|
||||
|
||||
# Python config section
|
||||
python:
|
||||
# Script file to load
|
||||
python-script: "./examples/inplace_callbacks.py"
|
||||
Vendored
+10
-7
@@ -106,7 +106,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_t hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
struct reply_info* qrep, struct regional* region)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
@@ -188,12 +188,13 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info k;
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
|
||||
k.qname = qname;
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, wr);
|
||||
|
||||
@@ -361,6 +362,7 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
msg->qinfo.qname_len = qnamelen;
|
||||
msg->qinfo.qtype = qtype;
|
||||
msg->qinfo.qclass = qclass;
|
||||
msg->qinfo.local_alias = NULL;
|
||||
/* non-packed reply_info, because it needs to grow the array */
|
||||
msg->rep = (struct reply_info*)regional_alloc_zero(region,
|
||||
sizeof(struct reply_info)-sizeof(struct rrset_ref));
|
||||
@@ -707,7 +709,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info k;
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
time_t now = *env->now;
|
||||
struct ub_packed_rrset_key* rrset;
|
||||
|
||||
@@ -716,6 +718,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(e) {
|
||||
@@ -795,9 +798,9 @@ dns_cache_lookup(struct module_env* env,
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(!e && k.qtype != LDNS_RR_TYPE_NS &&
|
||||
if(!e && k.qtype != LDNS_RR_TYPE_A &&
|
||||
env->cfg->qname_minimisation) {
|
||||
k.qtype = LDNS_RR_TYPE_NS;
|
||||
k.qtype = LDNS_RR_TYPE_A;
|
||||
h = query_info_hash(&k, flags);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
}
|
||||
@@ -817,7 +820,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
k.qtype = qtype;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill common RR types for ANY response to avoid requery */
|
||||
if(qtype == LDNS_RR_TYPE_ANY) {
|
||||
@@ -862,7 +865,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
} else {
|
||||
/* store msg, and rrsets */
|
||||
struct query_info qinf;
|
||||
hashvalue_t h;
|
||||
hashvalue_type h;
|
||||
|
||||
qinf = *msgqinf;
|
||||
qinf.qname = memdup(msgqinf->qname, msgqinf->qname_len);
|
||||
|
||||
Vendored
+1
-1
@@ -106,7 +106,7 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||
* @param region: to allocate into for qmsg.
|
||||
*/
|
||||
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_t hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
struct reply_info* qrep, struct regional* region);
|
||||
|
||||
/**
|
||||
|
||||
Vendored
+128
-11
@@ -61,6 +61,10 @@
|
||||
/** ratelimit value for delegation point */
|
||||
int infra_dp_ratelimit = 0;
|
||||
|
||||
/** ratelimit value for client ip addresses,
|
||||
* in queries per second. */
|
||||
int infra_ip_ratelimit = 0;
|
||||
|
||||
size_t
|
||||
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
{
|
||||
@@ -244,11 +248,19 @@ infra_create(struct config_file* cfg)
|
||||
}
|
||||
name_tree_init_parents(&infra->domain_limits);
|
||||
}
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
||||
if(!infra->client_ip_rates) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
return infra;
|
||||
}
|
||||
|
||||
/** delete domain_limit entries */
|
||||
static void domain_limit_free(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||
static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
if(n) {
|
||||
free(((struct domain_limit_data*)n)->node.name);
|
||||
@@ -264,6 +276,7 @@ infra_delete(struct infra_cache* infra)
|
||||
slabhash_delete(infra->hosts);
|
||||
slabhash_delete(infra->domain_rates);
|
||||
traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
|
||||
slabhash_delete(infra->client_ip_rates);
|
||||
free(infra);
|
||||
}
|
||||
|
||||
@@ -284,31 +297,38 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
return infra;
|
||||
}
|
||||
|
||||
/** calculate the hash value for a host key */
|
||||
static hashvalue_t
|
||||
hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
/** calculate the hash value for a host key
|
||||
* set use_port to a non-0 number to use the port in
|
||||
* the hash calculation; 0 to ignore the port.*/
|
||||
static hashvalue_type
|
||||
hash_addr(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
int use_port)
|
||||
{
|
||||
hashvalue_t h = 0xab;
|
||||
hashvalue_type h = 0xab;
|
||||
/* select the pieces to hash, some OS have changing data inside */
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
|
||||
h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h);
|
||||
h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
|
||||
if(use_port){
|
||||
h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
|
||||
}
|
||||
h = hashlittle(&in6->sin6_addr, INET6_SIZE, h);
|
||||
} else {
|
||||
struct sockaddr_in* in = (struct sockaddr_in*)addr;
|
||||
h = hashlittle(&in->sin_family, sizeof(in->sin_family), h);
|
||||
h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
|
||||
if(use_port){
|
||||
h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
|
||||
}
|
||||
h = hashlittle(&in->sin_addr, INET_SIZE, h);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/** calculate infra hash for a key */
|
||||
static hashvalue_t
|
||||
static hashvalue_type
|
||||
hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
|
||||
{
|
||||
return dname_query_hash(name, hash_addr(addr, addrlen));
|
||||
return dname_query_hash(name, hash_addr(addr, addrlen, 1));
|
||||
}
|
||||
|
||||
/** lookup version that does not check host ttl (you check it) */
|
||||
@@ -726,12 +746,36 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
|
||||
return infra_dp_ratelimit;
|
||||
}
|
||||
|
||||
size_t ip_rate_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
{
|
||||
struct ip_rate_key* key = (struct ip_rate_key*)k;
|
||||
return sizeof(*key) + sizeof(struct ip_rate_data)
|
||||
+ lock_get_mem(&key->entry.lock);
|
||||
}
|
||||
|
||||
int ip_rate_compfunc(void* key1, void* key2)
|
||||
{
|
||||
struct ip_rate_key* k1 = (struct ip_rate_key*)key1;
|
||||
struct ip_rate_key* k2 = (struct ip_rate_key*)key2;
|
||||
return sockaddr_cmp_addr(&k1->addr, k1->addrlen,
|
||||
&k2->addr, k2->addrlen);
|
||||
}
|
||||
|
||||
void ip_rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct ip_rate_key* key = (struct ip_rate_key*)k;
|
||||
if(!key)
|
||||
return;
|
||||
lock_rw_destroy(&key->entry.lock);
|
||||
free(key);
|
||||
}
|
||||
|
||||
/** find data item in array, for write access, caller unlocks */
|
||||
static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
|
||||
uint8_t* name, size_t namelen, int wr)
|
||||
{
|
||||
struct rate_key key;
|
||||
hashvalue_t h = dname_query_hash(name, 0xab);
|
||||
hashvalue_type h = dname_query_hash(name, 0xab);
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.name = name;
|
||||
key.namelen = namelen;
|
||||
@@ -739,11 +783,25 @@ static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
|
||||
return slabhash_lookup(infra->domain_rates, h, &key, wr);
|
||||
}
|
||||
|
||||
/** find data item in array for ip addresses */
|
||||
struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, int wr)
|
||||
{
|
||||
struct ip_rate_key key;
|
||||
hashvalue_type h = hash_addr(&(repinfo->addr),
|
||||
repinfo->addrlen, 0);
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.addr = repinfo->addr;
|
||||
key.addrlen = repinfo->addrlen;
|
||||
key.entry.hash = h;
|
||||
return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
|
||||
}
|
||||
|
||||
/** create rate data item for name, number 1 in now */
|
||||
static void infra_create_ratedata(struct infra_cache* infra,
|
||||
uint8_t* name, size_t namelen, time_t timenow)
|
||||
{
|
||||
hashvalue_t h = dname_query_hash(name, 0xab);
|
||||
hashvalue_type h = dname_query_hash(name, 0xab);
|
||||
struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k));
|
||||
struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d));
|
||||
if(!k || !d) {
|
||||
@@ -767,6 +825,30 @@ static void infra_create_ratedata(struct infra_cache* infra,
|
||||
slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL);
|
||||
}
|
||||
|
||||
/** create rate data item for ip address */
|
||||
static void infra_ip_create_ratedata(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, time_t timenow)
|
||||
{
|
||||
hashvalue_type h = hash_addr(&(repinfo->addr),
|
||||
repinfo->addrlen, 0);
|
||||
struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
|
||||
struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
|
||||
if(!k || !d) {
|
||||
free(k);
|
||||
free(d);
|
||||
return; /* alloc failure */
|
||||
}
|
||||
k->addr = repinfo->addr;
|
||||
k->addrlen = repinfo->addrlen;
|
||||
lock_rw_init(&k->entry.lock);
|
||||
k->entry.hash = h;
|
||||
k->entry.key = k;
|
||||
k->entry.data = d;
|
||||
d->qps[0] = 1;
|
||||
d->timestamp[0] = timenow;
|
||||
slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
|
||||
}
|
||||
|
||||
/** find the second and return its rate counter, if none, remove oldest */
|
||||
static int* infra_rate_find_second(void* data, time_t t)
|
||||
{
|
||||
@@ -875,6 +957,41 @@ infra_get_mem(struct infra_cache* infra)
|
||||
{
|
||||
size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts);
|
||||
if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates);
|
||||
if(infra->client_ip_rates) s += slabhash_get_mem(infra->client_ip_rates);
|
||||
/* ignore domain_limits because walk through tree is big */
|
||||
return s;
|
||||
}
|
||||
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, time_t timenow)
|
||||
{
|
||||
int max;
|
||||
struct lruhash_entry* entry;
|
||||
|
||||
/* not enabled */
|
||||
if(!infra_ip_ratelimit) {
|
||||
return 1;
|
||||
}
|
||||
/* find or insert ratedata */
|
||||
entry = infra_find_ip_ratedata(infra, repinfo, 1);
|
||||
if(entry) {
|
||||
int premax = infra_rate_max(entry->data, timenow);
|
||||
int* cur = infra_rate_find_second(entry->data, timenow);
|
||||
(*cur)++;
|
||||
max = infra_rate_max(entry->data, timenow);
|
||||
lock_rw_unlock(&entry->lock);
|
||||
|
||||
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
|
||||
char client_ip[128];
|
||||
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
|
||||
repinfo->addrlen, client_ip, sizeof(client_ip));
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip,
|
||||
infra_ip_ratelimit);
|
||||
}
|
||||
return (max <= infra_ip_ratelimit);
|
||||
}
|
||||
|
||||
/* create */
|
||||
infra_ip_create_ratedata(infra, repinfo, timenow);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Vendored
+48
-2
@@ -36,7 +36,10 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains the infrastructure cache.
|
||||
* This file contains the infrastructure cache, as well as rate limiting.
|
||||
* Note that there are two sorts of rate-limiting here:
|
||||
* - Pre-cache, per-query rate limiting (query ratelimits)
|
||||
* - Post-cache, per-domain name rate limiting (infra-ratelimits)
|
||||
*/
|
||||
|
||||
#ifndef SERVICES_CACHE_INFRA_H
|
||||
@@ -44,6 +47,8 @@
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/rtt.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/data/msgreply.h"
|
||||
struct slabhash;
|
||||
struct config_file;
|
||||
|
||||
@@ -112,7 +117,9 @@ struct infra_cache {
|
||||
/** hash table with query rates per name: rate_key, rate_data */
|
||||
struct slabhash* domain_rates;
|
||||
/** ratelimit settings for domains, struct domain_limit_data */
|
||||
rbtree_t domain_limits;
|
||||
rbtree_type domain_limits;
|
||||
/** hash table with query rates per client ip: ip_rate_key, ip_rate_data */
|
||||
struct slabhash* client_ip_rates;
|
||||
};
|
||||
|
||||
/** ratelimit, unless overridden by domain_limits, 0 is off */
|
||||
@@ -142,6 +149,21 @@ struct rate_key {
|
||||
size_t namelen;
|
||||
};
|
||||
|
||||
/** ip ratelimit, 0 is off */
|
||||
extern int infra_ip_ratelimit;
|
||||
|
||||
/**
|
||||
* key for ip_ratelimit lookups, a source IP.
|
||||
*/
|
||||
struct ip_rate_key {
|
||||
/** lruhash key entry */
|
||||
struct lruhash_entry entry;
|
||||
/** client ip information */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of address */
|
||||
socklen_t addrlen;
|
||||
};
|
||||
|
||||
/** number of seconds to track qps rate */
|
||||
#define RATE_WINDOW 2
|
||||
|
||||
@@ -160,6 +182,8 @@ struct rate_data {
|
||||
time_t timestamp[RATE_WINDOW];
|
||||
};
|
||||
|
||||
#define ip_rate_data rate_data
|
||||
|
||||
/** infra host cache default hash lookup size */
|
||||
#define INFRA_HOST_STARTSIZE 32
|
||||
/** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */
|
||||
@@ -381,6 +405,16 @@ int infra_rate_max(void* data, time_t now);
|
||||
int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
|
||||
size_t namelen);
|
||||
|
||||
/** Update query ratelimit hash and decide
|
||||
* whether or not a query should be dropped.
|
||||
* @param infra: infra cache
|
||||
* @param repinfo: information about client
|
||||
* @param timenow: what time it is now.
|
||||
* @return 1 if it could be incremented. 0 if the increment overshot the
|
||||
* ratelimit and the query should be dropped. */
|
||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
struct comm_reply* repinfo, time_t timenow);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
* @param infra: infrastructure cache.
|
||||
@@ -413,4 +447,16 @@ void rate_delkeyfunc(void* k, void* arg);
|
||||
/** delete data */
|
||||
void rate_deldatafunc(void* d, void* arg);
|
||||
|
||||
/* calculate size for the client ip hashtable */
|
||||
size_t ip_rate_sizefunc(void* k, void* d);
|
||||
|
||||
/* compare two addresses */
|
||||
int ip_rate_compfunc(void* key1, void* key2);
|
||||
|
||||
/* delete key, and destroy the lock */
|
||||
void ip_rate_delkeyfunc(void* d, void* arg);
|
||||
|
||||
/* delete data */
|
||||
#define ip_rate_deldatafunc rate_deldatafunc
|
||||
|
||||
#endif /* SERVICES_CACHE_INFRA_H */
|
||||
|
||||
Vendored
+5
-5
@@ -91,7 +91,7 @@ struct rrset_cache* rrset_cache_adjust(struct rrset_cache *r,
|
||||
|
||||
void
|
||||
rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
hashvalue_t hash, rrset_id_t id)
|
||||
hashvalue_type hash, rrset_id_type id)
|
||||
{
|
||||
struct lruhash* table = slabhash_gettable(&r->table, hash);
|
||||
/*
|
||||
@@ -186,7 +186,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct ub_packed_rrset_key* k = ref->key;
|
||||
hashvalue_t h = k->entry.hash;
|
||||
hashvalue_type h = k->entry.hash;
|
||||
uint16_t rrset_type = ntohs(k->rk.type);
|
||||
int equal = 0;
|
||||
log_assert(ref->id != 0 && k->id != 0);
|
||||
@@ -303,10 +303,10 @@ void
|
||||
rrset_array_unlock_touch(struct rrset_cache* r, struct regional* scratch,
|
||||
struct rrset_ref* ref, size_t count)
|
||||
{
|
||||
hashvalue_t* h;
|
||||
hashvalue_type* h;
|
||||
size_t i;
|
||||
if(count > RR_COUNT_MAX || !(h = (hashvalue_t*)regional_alloc(scratch,
|
||||
sizeof(hashvalue_t)*count))) {
|
||||
if(count > RR_COUNT_MAX || !(h = (hashvalue_type*)regional_alloc(
|
||||
scratch, sizeof(hashvalue_type)*count))) {
|
||||
log_warn("rrset LRU: memory allocation failed");
|
||||
h = NULL;
|
||||
} else /* store hash values */
|
||||
|
||||
Vendored
+1
-1
@@ -102,7 +102,7 @@ struct rrset_cache* rrset_cache_adjust(struct rrset_cache* r,
|
||||
* @param id: used to check that the item is unchanged and not deleted.
|
||||
*/
|
||||
void rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
hashvalue_t hash, rrset_id_t id);
|
||||
hashvalue_type hash, rrset_id_type id);
|
||||
|
||||
/**
|
||||
* Update an rrset in the rrset cache. Stores the information for later use.
|
||||
|
||||
+186
-36
@@ -43,6 +43,9 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "util/netevent.h"
|
||||
@@ -60,6 +63,10 @@
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
/** number of queued TCP connections for listen() */
|
||||
#define TCP_BACKLOG 256
|
||||
|
||||
@@ -93,11 +100,71 @@ verbose_print_addr(struct addrinfo *addr)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
static int
|
||||
systemd_get_activated(int family, int socktype, int listen,
|
||||
struct sockaddr *addr, socklen_t addrlen,
|
||||
const char *path)
|
||||
{
|
||||
int i = 0;
|
||||
int r = 0;
|
||||
int s = -1;
|
||||
const char* listen_pid, *listen_fds;
|
||||
|
||||
/* We should use "listen" option only for stream protocols. For UDP it should be -1 */
|
||||
|
||||
if((r = sd_booted()) < 1) {
|
||||
if(r == 0)
|
||||
log_warn("systemd is not running");
|
||||
else
|
||||
log_err("systemd sd_booted(): %s", strerror(-r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
listen_pid = getenv("LISTEN_PID");
|
||||
listen_fds = getenv("LISTEN_FDS");
|
||||
|
||||
if (!listen_pid) {
|
||||
log_warn("Systemd mandatory ENV variable is not defined: LISTEN_PID");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!listen_fds) {
|
||||
log_warn("Systemd mandatory ENV variable is not defined: LISTEN_FDS");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((r = sd_listen_fds(0)) < 1) {
|
||||
if(r == 0)
|
||||
log_warn("systemd: did not return socket, check unit configuration");
|
||||
else
|
||||
log_err("systemd sd_listen_fds(): %s", strerror(-r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < r; i++) {
|
||||
if(sd_is_socket(SD_LISTEN_FDS_START + i, family, socktype, listen)) {
|
||||
s = SD_LISTEN_FDS_START + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (s == -1) {
|
||||
if (addr)
|
||||
log_err_addr("systemd sd_listen_fds()",
|
||||
"no such socket",
|
||||
(struct sockaddr_storage *)addr, addrlen);
|
||||
else
|
||||
log_err("systemd sd_listen_fds(): %s", path);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto,
|
||||
int rcv, int snd, int listen, int* reuseport, int transparent,
|
||||
int freebind)
|
||||
int freebind, int use_systemd)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
|
||||
@@ -120,6 +187,16 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
#endif
|
||||
#if !defined(IP_FREEBIND)
|
||||
(void)freebind;
|
||||
#endif
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int got_fd_from_systemd = 0;
|
||||
|
||||
if (!use_systemd
|
||||
|| (use_systemd
|
||||
&& (s = systemd_get_activated(family, socktype, -1, addr,
|
||||
addrlen, NULL)) == -1)) {
|
||||
#else
|
||||
(void)use_systemd;
|
||||
#endif
|
||||
if((s = socket(family, socktype, 0)) == -1) {
|
||||
*inuse = 0;
|
||||
@@ -141,6 +218,11 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
*noproto = 0;
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_SYSTEMD
|
||||
} else {
|
||||
got_fd_from_systemd = 1;
|
||||
}
|
||||
#endif
|
||||
if(listen) {
|
||||
#ifdef SO_REUSEADDR
|
||||
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
|
||||
@@ -184,14 +266,6 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
#else
|
||||
(void)reuseport;
|
||||
#endif /* defined(SO_REUSEPORT) */
|
||||
#ifdef IP_FREEBIND
|
||||
if (freebind &&
|
||||
setsockopt(s, IPPROTO_IP, IP_FREEBIND, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
log_warn("setsockopt(.. IP_FREEBIND ..) failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* IP_FREEBIND */
|
||||
#ifdef IP_TRANSPARENT
|
||||
if (transparent &&
|
||||
setsockopt(s, IPPROTO_IP, IP_TRANSPARENT, (void*)&on,
|
||||
@@ -209,6 +283,14 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY */
|
||||
}
|
||||
#ifdef IP_FREEBIND
|
||||
if(freebind &&
|
||||
setsockopt(s, IPPROTO_IP, IP_FREEBIND, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
log_warn("setsockopt(.. IP_FREEBIND ..) failed: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* IP_FREEBIND */
|
||||
if(rcv) {
|
||||
#ifdef SO_RCVBUF
|
||||
int got;
|
||||
@@ -462,7 +544,11 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
}
|
||||
# endif /* IPv4 MTU */
|
||||
}
|
||||
if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
|
||||
if(
|
||||
#ifdef HAVE_SYSTEMD
|
||||
!got_fd_from_systemd &&
|
||||
#endif
|
||||
bind(s, (struct sockaddr*)addr, addrlen) != 0) {
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
@@ -485,7 +571,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
}
|
||||
closesocket(s);
|
||||
#endif
|
||||
#endif /* USE_WINSOCK */
|
||||
return -1;
|
||||
}
|
||||
if(!fd_set_nonblock(s)) {
|
||||
@@ -503,12 +589,18 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
|
||||
int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind)
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND)
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int got_fd_from_systemd = 0;
|
||||
#endif
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
int qlen;
|
||||
#endif
|
||||
#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY)
|
||||
(void)transparent;
|
||||
#endif
|
||||
@@ -517,6 +609,15 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
#endif
|
||||
verbose_print_addr(addr);
|
||||
*noproto = 0;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (!use_systemd ||
|
||||
(use_systemd
|
||||
&& (s = systemd_get_activated(addr->ai_family, addr->ai_socktype, 1,
|
||||
addr->ai_addr, addr->ai_addrlen,
|
||||
NULL)) == -1)) {
|
||||
#else
|
||||
(void)use_systemd;
|
||||
#endif
|
||||
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
|
||||
@@ -554,6 +655,11 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
log_warn(" setsockopt(TCP_MAXSEG) unsupported");
|
||||
#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
|
||||
}
|
||||
#ifdef HAVE_SYSTEMD
|
||||
} else {
|
||||
got_fd_from_systemd = 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef SO_REUSEADDR
|
||||
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
@@ -631,7 +737,11 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
(addr->ai_family==AF_INET6?"V6":""), strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY */
|
||||
if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
|
||||
if(
|
||||
#ifdef HAVE_SYSTEMD
|
||||
!got_fd_from_systemd &&
|
||||
#endif
|
||||
bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
/* detect freebsd jail with no ipv6 permission */
|
||||
if(addr->ai_family==AF_INET6 && errno==EINVAL)
|
||||
@@ -669,20 +779,46 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
/* qlen specifies how many outstanding TFO requests to allow. Limit is a defense
|
||||
against IP spoofing attacks as suggested in RFC7413 */
|
||||
#ifdef __APPLE__
|
||||
/* OS X implementation only supports qlen of 1 via this call. Actual
|
||||
value is configured by the net.inet.tcp.fastopen_backlog kernel parm. */
|
||||
qlen = 1;
|
||||
#else
|
||||
/* 5 is recommended on linux */
|
||||
qlen = 5;
|
||||
#endif
|
||||
if ((setsockopt(s, IPPROTO_TCP, TCP_FASTOPEN, &qlen,
|
||||
sizeof(qlen))) == -1 ) {
|
||||
log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
create_local_accept_sock(const char *path, int* noproto)
|
||||
create_local_accept_sock(const char *path, int* noproto, int use_systemd)
|
||||
{
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int ret;
|
||||
|
||||
if (use_systemd && (ret = systemd_get_activated(AF_LOCAL, SOCK_STREAM, 1, NULL, 0, path)) != -1)
|
||||
return ret;
|
||||
else {
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
int s;
|
||||
struct sockaddr_un usock;
|
||||
#ifndef HAVE_SYSTEMD
|
||||
(void)use_systemd;
|
||||
#endif
|
||||
|
||||
verbose(VERB_ALGO, "creating unix socket %s", path);
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||
/* this member exists on BSDs, not Linux */
|
||||
usock.sun_len = (socklen_t)sizeof(usock);
|
||||
usock.sun_len = (unsigned)sizeof(usock);
|
||||
#endif
|
||||
usock.sun_family = AF_LOCAL;
|
||||
/* length is 92-108, 104 on FreeBSD */
|
||||
@@ -698,29 +834,42 @@ create_local_accept_sock(const char *path, int* noproto)
|
||||
/* The socket already exists and cannot be removed */
|
||||
log_err("Cannot remove old local socket %s (%s)",
|
||||
path, strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (bind(s, (struct sockaddr *)&usock,
|
||||
(socklen_t)sizeof(struct sockaddr_un)) == -1) {
|
||||
log_err("Cannot bind local socket %s (%s)",
|
||||
path, strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!fd_set_nonblock(s)) {
|
||||
log_err("Cannot set non-blocking mode");
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (listen(s, TCP_BACKLOG) == -1) {
|
||||
log_err("can't listen: %s", strerror(errno));
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
(void)noproto; /*unused*/
|
||||
return s;
|
||||
|
||||
err:
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
closesocket(s);
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
(void)use_systemd;
|
||||
(void)path;
|
||||
log_err("Local sockets are not supported");
|
||||
*noproto = 1;
|
||||
@@ -735,7 +884,7 @@ create_local_accept_sock(const char *path, int* noproto)
|
||||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind)
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s, inuse, noproto;
|
||||
@@ -763,7 +912,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
s = create_udp_sock(res->ai_family, res->ai_socktype,
|
||||
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
|
||||
v6only, &inuse, &noproto, (int)rcv, (int)snd, 1,
|
||||
reuseport, transparent, freebind);
|
||||
reuseport, transparent, freebind, use_systemd);
|
||||
if(s == -1 && inuse) {
|
||||
log_err("bind: address already in use");
|
||||
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
@@ -771,7 +920,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
}
|
||||
} else {
|
||||
s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
|
||||
transparent, tcp_mss, freebind);
|
||||
transparent, tcp_mss, freebind, use_systemd);
|
||||
if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
@@ -784,7 +933,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
static int
|
||||
make_sock_port(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind)
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
{
|
||||
char* s = strchr(ifname, '@');
|
||||
if(s) {
|
||||
@@ -806,10 +955,10 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
||||
(void)strlcpy(p, s+1, sizeof(p));
|
||||
p[strlen(s+1)]=0;
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6,
|
||||
rcv, snd, reuseport, transparent, tcp_mss, freebind);
|
||||
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
}
|
||||
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
|
||||
reuseport, transparent, tcp_mss, freebind);
|
||||
reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -859,7 +1008,7 @@ set_recvpktinfo(int s, int family)
|
||||
}
|
||||
# else
|
||||
log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please "
|
||||
"disable interface-automatic in config");
|
||||
"disable interface-automatic or do-ip6 in config");
|
||||
return 0;
|
||||
# endif /* defined IPV6_RECVPKTINFO */
|
||||
|
||||
@@ -880,7 +1029,7 @@ set_recvpktinfo(int s, int family)
|
||||
}
|
||||
# else
|
||||
log_err("no IP_SENDSRCADDR or IP_PKTINFO option, please disable "
|
||||
"interface-automatic in config");
|
||||
"interface-automatic or do-ip4 in config");
|
||||
return 0;
|
||||
# endif /* IP_PKTINFO */
|
||||
|
||||
@@ -906,13 +1055,14 @@ set_recvpktinfo(int s, int family)
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
* @param tcp_mss: maximum segment size of tcp socket. default if zero.
|
||||
* @param freebind: set IP_FREEBIND socket option.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
static int
|
||||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
|
||||
int tcp_mss, int freebind)
|
||||
int tcp_mss, int freebind, int use_systemd)
|
||||
{
|
||||
int s, noip6=0;
|
||||
if(!do_udp && !do_tcp)
|
||||
@@ -920,7 +1070,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
if(do_auto) {
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind)) == -1) {
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@@ -948,7 +1098,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
/* regular udp socket */
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind)) == -1) {
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@@ -970,7 +1120,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
(!strchr(ifname, '@') && atoi(port) == ssl_port));
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
freebind)) == -1) {
|
||||
freebind, use_systemd)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
return 1;
|
||||
@@ -1014,7 +1164,7 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
size_t bufsize, int tcp_accept_count, void* sslctx,
|
||||
struct dt_env* dtenv, comm_point_callback_t* cb, void *cb_arg)
|
||||
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
|
||||
{
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
malloc(sizeof(struct listen_dnsport));
|
||||
@@ -1128,7 +1278,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind)) {
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1141,7 +1291,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind)) {
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1156,7 +1306,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind)) {
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1169,7 +1319,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind)) {
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ void listening_ports_free(struct listen_port* list);
|
||||
*/
|
||||
struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
|
||||
void* sslctx, struct dt_env *dtenv, comm_point_callback_t* cb,
|
||||
void* sslctx, struct dt_env *dtenv, comm_point_callback_type* cb,
|
||||
void* cb_arg);
|
||||
|
||||
/**
|
||||
@@ -191,11 +191,12 @@ void listen_start_accept(struct listen_dnsport* listen);
|
||||
* listening UDP port. Set to false on return if it failed to do so.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
* @param freebind: set IP_FREEBIND socket option.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
|
||||
int snd, int listen, int* reuseport, int transparent, int freebind);
|
||||
int snd, int listen, int* reuseport, int transparent, int freebind, int use_systemd);
|
||||
|
||||
/**
|
||||
* Create and bind TCP listening socket
|
||||
@@ -207,18 +208,20 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
* @param mss: maximum segment size of the socket. if zero, leaves the default.
|
||||
* @param freebind: set IP_FREEBIND socket option.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind);
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd);
|
||||
|
||||
/**
|
||||
* Create and bind local listening socket
|
||||
* @param path: path to the socket.
|
||||
* @param noproto: on error, this is set true if cause is that local sockets
|
||||
* are not supported.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_local_accept_sock(const char* path, int* noproto);
|
||||
int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
|
||||
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user