Deleted Added
full compact
fastrpz.patch (361435) fastrpz.patch (366095)
1Description: based on the included patch contrib/fastrpz.patch
2Author: fastrpz@farsightsecurity.com
3---
4diff --git a/Makefile.in b/Makefile.in
1Description: based on the included patch contrib/fastrpz.patch
2Author: fastrpz@farsightsecurity.com
3---
4diff --git a/Makefile.in b/Makefile.in
5index a20058cc..495779cc 100644
5index bac212df..4824927f 100644
6--- a/Makefile.in
7+++ b/Makefile.in
8@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
9 CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
10 DNSTAP_SRC=@DNSTAP_SRC@
11 DNSTAP_OBJ=@DNSTAP_OBJ@
12+FASTRPZ_SRC=@FASTRPZ_SRC@
13+FASTRPZ_OBJ=@FASTRPZ_OBJ@
14 DNSCRYPT_SRC=@DNSCRYPT_SRC@
15 DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
6--- a/Makefile.in
7+++ b/Makefile.in
8@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
9 CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
10 DNSTAP_SRC=@DNSTAP_SRC@
11 DNSTAP_OBJ=@DNSTAP_OBJ@
12+FASTRPZ_SRC=@FASTRPZ_SRC@
13+FASTRPZ_OBJ=@FASTRPZ_OBJ@
14 DNSCRYPT_SRC=@DNSCRYPT_SRC@
15 DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
16 WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
17@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
16 WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
17@@ -134,7 +136,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
18 edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
19 edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
20 cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
21-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
22+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
23 COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
24 as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
25 iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
18 edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
19 edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
20 cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
21-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
22+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
23 COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
24 as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
25 iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
26@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
26@@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.lo \
27 validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
28 val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
29 $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
27 validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
28 val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
29 $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
30-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
31+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
30-$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
31+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
32 COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
33 outside_network.lo
34 COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
32 COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
33 outside_network.lo
34 COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
35@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
35@@ -428,6 +430,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
36 $(srcdir)/util/config_file.h $(srcdir)/util/log.h \
37 $(srcdir)/util/netevent.h
38
39+# fastrpz
40+rpz.lo rpz.o: $(srcdir)/fastrpz/rpz.c config.h fastrpz/rpz.h fastrpz/librpz.h \
41+ $(srcdir)/util/config_file.h $(srcdir)/daemon/daemon.h \
42+ $(srcdir)/util/log.h
43+
44 # Python Module
45 pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
46 pythonmod/interface.h \
47diff --git a/config.h.in b/config.h.in
36 $(srcdir)/util/config_file.h $(srcdir)/util/log.h \
37 $(srcdir)/util/netevent.h
38
39+# fastrpz
40+rpz.lo rpz.o: $(srcdir)/fastrpz/rpz.c config.h fastrpz/rpz.h fastrpz/librpz.h \
41+ $(srcdir)/util/config_file.h $(srcdir)/daemon/daemon.h \
42+ $(srcdir)/util/log.h
43+
44 # Python Module
45 pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
46 pythonmod/interface.h \
47diff --git a/config.h.in b/config.h.in
48index 78d47fed..e33073e4 100644
48index f7a4095e..d5a4fa01 100644
49--- a/config.h.in
50+++ b/config.h.in
49--- a/config.h.in
50+++ b/config.h.in
51@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
51@@ -1364,4 +1364,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
52 /** the version of unbound-control that this software implements */
53 #define UNBOUND_CONTROL_VERSION 1
54
55-
56+/* have __attribute__s used in librpz.h */
57+#undef LIBRPZ_HAVE_ATTR
58+/** fastrpz librpz.so */
59+#undef FASTRPZ_LIBRPZ_PATH
60+/** 0=no fastrpz 1=static link 2=dlopen() */
61+#undef FASTRPZ_LIB_OPEN
62+/** turn on fastrpz response policy zones */
63+#undef ENABLE_FASTRPZ
64diff --git a/configure.ac b/configure.ac
52 /** the version of unbound-control that this software implements */
53 #define UNBOUND_CONTROL_VERSION 1
54
55-
56+/* have __attribute__s used in librpz.h */
57+#undef LIBRPZ_HAVE_ATTR
58+/** fastrpz librpz.so */
59+#undef FASTRPZ_LIBRPZ_PATH
60+/** 0=no fastrpz 1=static link 2=dlopen() */
61+#undef FASTRPZ_LIB_OPEN
62+/** turn on fastrpz response policy zones */
63+#undef ENABLE_FASTRPZ
64diff --git a/configure.ac b/configure.ac
65index 2b91dd3c..e6063d17 100644
65index 5c373d9d..e45abd89 100644
66--- a/configure.ac
67+++ b/configure.ac
68@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
69 sinclude(acx_python.m4)
70 sinclude(ac_pkg_swig.m4)
71 sinclude(dnstap/dnstap.m4)
72+sinclude(fastrpz/rpz.m4)
73 sinclude(dnscrypt/dnscrypt.m4)
74
75 # must be numbers. ac_defun because of later processing
66--- a/configure.ac
67+++ b/configure.ac
68@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
69 sinclude(acx_python.m4)
70 sinclude(ac_pkg_swig.m4)
71 sinclude(dnstap/dnstap.m4)
72+sinclude(fastrpz/rpz.m4)
73 sinclude(dnscrypt/dnscrypt.m4)
74
75 # must be numbers. ac_defun because of later processing
76@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
77 ;;
76@@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
78 esac
79
77 esac
78
79
80+# check for Fastrpz with fastrpz/rpz.m4
81+ck_FASTRPZ
82+
83 AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
84 # on openBSD, the implicit rule make $< work.
85 # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
86diff --git a/daemon/daemon.c b/daemon/daemon.c
80+# check for Fastrpz with fastrpz/rpz.m4
81+ck_FASTRPZ
82+
83 AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
84 # on openBSD, the implicit rule make $< work.
85 # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
86diff --git a/daemon/daemon.c b/daemon/daemon.c
87index 8b0fc348..7ffb9221 100644
87index 5d427925..f89f1437 100644
88--- a/daemon/daemon.c
89+++ b/daemon/daemon.c
90@@ -91,6 +91,9 @@
91 #include "sldns/keyraw.h"
92 #include "respip/respip.h"
93 #include <signal.h>
94+#ifdef ENABLE_FASTRPZ
95+#include "fastrpz/rpz.h"
96+#endif
97
98 #ifdef HAVE_SYSTEMD
99 #include <systemd/sd-daemon.h>
88--- a/daemon/daemon.c
89+++ b/daemon/daemon.c
90@@ -91,6 +91,9 @@
91 #include "sldns/keyraw.h"
92 #include "respip/respip.h"
93 #include <signal.h>
94+#ifdef ENABLE_FASTRPZ
95+#include "fastrpz/rpz.h"
96+#endif
97
98 #ifdef HAVE_SYSTEMD
99 #include <systemd/sd-daemon.h>
100@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
101 dt_apply_cfg(daemon->dtenv, daemon->cfg);
100@@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
101 fatal_exit("dt_create failed");
102 #else
103 fatal_exit("dnstap enabled in config but not built with dnstap support");
104+#endif
105+ }
106+ if(daemon->cfg->rpz_enable) {
107+#ifdef ENABLE_FASTRPZ
108+ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
109+#else
110+ fatal_exit("fastrpz enabled in config"
111+ " but not built with fastrpz");
112 #endif
113 }
114 for(i=0; i<daemon->num; i++) {
102 #else
103 fatal_exit("dnstap enabled in config but not built with dnstap support");
104+#endif
105+ }
106+ if(daemon->cfg->rpz_enable) {
107+#ifdef ENABLE_FASTRPZ
108+ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
109+#else
110+ fatal_exit("fastrpz enabled in config"
111+ " but not built with fastrpz");
112 #endif
113 }
114 for(i=0; i<daemon->num; i++) {
115@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
115@@ -729,6 +740,9 @@ daemon_cleanup(struct daemon* daemon)
116 #ifdef USE_DNSCRYPT
117 dnsc_delete(daemon->dnscenv);
118 daemon->dnscenv = NULL;
119+#endif
120+#ifdef ENABLE_FASTRPZ
121+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
122 #endif
123 daemon->cfg = NULL;

--- 10 unchanged lines hidden (view full) ---

134+ /** global opaque rpz handles */
135+ struct librpz_clist *rpz_clist;
136+ struct librpz_client *rpz_client;
137+#endif
138 };
139
140 /**
141diff --git a/daemon/worker.c b/daemon/worker.c
116 #ifdef USE_DNSCRYPT
117 dnsc_delete(daemon->dnscenv);
118 daemon->dnscenv = NULL;
119+#endif
120+#ifdef ENABLE_FASTRPZ
121+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
122 #endif
123 daemon->cfg = NULL;

--- 10 unchanged lines hidden (view full) ---

134+ /** global opaque rpz handles */
135+ struct librpz_clist *rpz_clist;
136+ struct librpz_client *rpz_client;
137+#endif
138 };
139
140 /**
141diff --git a/daemon/worker.c b/daemon/worker.c
142index eb7fdf2f..1982228d 100644
142index 23e3244c..b63d49b7 100644
143--- a/daemon/worker.c
144+++ b/daemon/worker.c
145@@ -76,6 +76,9 @@
146 #include "libunbound/context.h"
147 #include "libunbound/libworker.h"
148 #include "sldns/sbuffer.h"
149+#ifdef ENABLE_FASTRPZ
150+#include "fastrpz/rpz.h"
151+#endif
152 #include "sldns/wire2str.h"
153 #include "util/shm_side/shm_main.h"
154 #include "dnscrypt/dnscrypt.h"
143--- a/daemon/worker.c
144+++ b/daemon/worker.c
145@@ -76,6 +76,9 @@
146 #include "libunbound/context.h"
147 #include "libunbound/libworker.h"
148 #include "sldns/sbuffer.h"
149+#ifdef ENABLE_FASTRPZ
150+#include "fastrpz/rpz.h"
151+#endif
152 #include "sldns/wire2str.h"
153 #include "util/shm_side/shm_main.h"
154 #include "dnscrypt/dnscrypt.h"
155@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
155@@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
156 /* not secure */
157 secure = 0;
158 break;
159+#ifdef ENABLE_FASTRPZ
160+ case sec_status_rpz_rewritten:
161+ case sec_status_rpz_drop:
162+ fatal_exit("impossible cached RPZ sec_status");
163+ break;

--- 11 unchanged lines hidden (view full) ---

175+ id, flags, edns, repinfo);
176+ if(ret != 1)
177+ return ret;
178+ }
179+#endif
180 /* return this delegation from the cache */
181 edns_bak = *edns;
182 edns->edns_version = EDNS_ADVERTISED_VERSION;
156 /* not secure */
157 secure = 0;
158 break;
159+#ifdef ENABLE_FASTRPZ
160+ case sec_status_rpz_rewritten:
161+ case sec_status_rpz_drop:
162+ fatal_exit("impossible cached RPZ sec_status");
163+ break;

--- 11 unchanged lines hidden (view full) ---

175+ id, flags, edns, repinfo);
176+ if(ret != 1)
177+ return ret;
178+ }
179+#endif
180 /* return this delegation from the cache */
181 edns_bak = *edns;
182 edns->edns_version = EDNS_ADVERTISED_VERSION;
183@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
183@@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
184 *is_secure_answer = 0;
185 }
186 } else *is_secure_answer = 0;
187+#ifdef ENABLE_FASTRPZ
188+ if(repinfo->rpz) {
189+ /* Scan the cached answer for RPZ hits.
190+ * ret=1 use cache entry
191+ * ret=-1 rewritten response already sent or dropped

--- 7 unchanged lines hidden (view full) ---

199+ rep->rrset_count);
200+ return ret;
201+ }
202+ }
203+#endif
204
205 edns_bak = *edns;
206 edns->edns_version = EDNS_ADVERTISED_VERSION;
184 *is_secure_answer = 0;
185 }
186 } else *is_secure_answer = 0;
187+#ifdef ENABLE_FASTRPZ
188+ if(repinfo->rpz) {
189+ /* Scan the cached answer for RPZ hits.
190+ * ret=1 use cache entry
191+ * ret=-1 rewritten response already sent or dropped

--- 7 unchanged lines hidden (view full) ---

199+ rep->rrset_count);
200+ return ret;
201+ }
202+ }
203+#endif
204
205 edns_bak = *edns;
206 edns->edns_version = EDNS_ADVERTISED_VERSION;
207@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
207@@ -1436,6 +1475,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
208 log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
209 &repinfo->addr, repinfo->addrlen);
210 goto send_reply;
211+#ifdef ENABLE_FASTRPZ
212+ } else {
213+ /* Start to rewrite for response policy zones.
214+ * This can hit a qname trigger and be done. */
215+ if(rpz_start(worker, &qinfo, repinfo, &edns)) {
216+ regional_free_all(worker->scratchpad);
217+ return 0;
218+ }
219+#endif
220 }
221
222 /* If we've found a local alias, replace the qname with the alias
208 log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
209 &repinfo->addr, repinfo->addrlen);
210 goto send_reply;
211+#ifdef ENABLE_FASTRPZ
212+ } else {
213+ /* Start to rewrite for response policy zones.
214+ * This can hit a qname trigger and be done. */
215+ if(rpz_start(worker, &qinfo, repinfo, &edns)) {
216+ regional_free_all(worker->scratchpad);
217+ return 0;
218+ }
219+#endif
220 }
221
222 /* If we've found a local alias, replace the qname with the alias
223@@ -1485,12 +1533,21 @@ lookup_cache:
223@@ -1486,12 +1534,21 @@ lookup_cache:
224 h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
225 if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
226 /* answer from cache - we have acquired a readlock on it */
227- if(answer_from_cache(worker, &qinfo,
228+ ret = answer_from_cache(worker, &qinfo,
229 cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
230 &alias_rrset, &partial_rep, (struct reply_info*)e->data,
231 *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),

--- 7 unchanged lines hidden (view full) ---

239+ regional_free_all(worker->scratchpad);
240+ return 0;
241+ }
242+#endif
243+ if(ret) {
244 /* prefetch it if the prefetch TTL expired.
245 * Note that if there is more than one pass
246 * its qname must be that used for cache
224 h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
225 if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
226 /* answer from cache - we have acquired a readlock on it */
227- if(answer_from_cache(worker, &qinfo,
228+ ret = answer_from_cache(worker, &qinfo,
229 cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
230 &alias_rrset, &partial_rep, (struct reply_info*)e->data,
231 *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),

--- 7 unchanged lines hidden (view full) ---

239+ regional_free_all(worker->scratchpad);
240+ return 0;
241+ }
242+#endif
243+ if(ret) {
244 /* prefetch it if the prefetch TTL expired.
245 * Note that if there is more than one pass
246 * its qname must be that used for cache
247@@ -1547,11 +1604,19 @@ lookup_cache:
247@@ -1548,11 +1605,19 @@ lookup_cache:
248 lock_rw_unlock(&e->lock);
249 }
250 if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
251- if(answer_norec_from_cache(worker, &qinfo,
252+ ret = answer_norec_from_cache(worker, &qinfo,
253 *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
254 sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
255- &edns)) {

--- 6 unchanged lines hidden (view full) ---

262+ * or sent a response. */
263+ return 0;
264+ }
265+#endif
266 goto send_reply;
267 }
268 verbose(VERB_ALGO, "answer norec from cache -- "
269diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
248 lock_rw_unlock(&e->lock);
249 }
250 if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
251- if(answer_norec_from_cache(worker, &qinfo,
252+ ret = answer_norec_from_cache(worker, &qinfo,
253 *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
254 sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
255- &edns)) {

--- 6 unchanged lines hidden (view full) ---

262+ * or sent a response. */
263+ return 0;
264+ }
265+#endif
266 goto send_reply;
267 }
268 verbose(VERB_ALGO, "answer norec from cache -- "
269diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
270index 38c2d298..3b07f392 100644
270index cd43f04e..b92a1af8 100644
271--- a/doc/unbound.conf.5.in
272+++ b/doc/unbound.conf.5.in
271--- a/doc/unbound.conf.5.in
272+++ b/doc/unbound.conf.5.in
273@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
273@@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
274 used by dns64 processing instead. Can be entered multiple times, list a
275 new domain for which it applies, one per line. Applies also to names
276 underneath the name given.
277+.SS "Response Policy Zone Rewriting"
278+.LP
279+Response policy zone rewriting is controlled with the
280+.B rpz
281+clause.

--- 2601 unchanged lines hidden (view full) ---

2883+ # used in Makefile.in
2884+ AC_SUBST([FASTRPZ_SRC], [fastrpz/rpz.c])
2885+ AC_SUBST([FASTRPZ_OBJ], [rpz.lo])
2886+ elif test "x$fastrpz_avail" = "x0"; then
2887+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
2888+ fi
2889+])
2890diff --git a/iterator/iterator.c b/iterator/iterator.c
274 used by dns64 processing instead. Can be entered multiple times, list a
275 new domain for which it applies, one per line. Applies also to names
276 underneath the name given.
277+.SS "Response Policy Zone Rewriting"
278+.LP
279+Response policy zone rewriting is controlled with the
280+.B rpz
281+clause.

--- 2601 unchanged lines hidden (view full) ---

2883+ # used in Makefile.in
2884+ AC_SUBST([FASTRPZ_SRC], [fastrpz/rpz.c])
2885+ AC_SUBST([FASTRPZ_OBJ], [rpz.lo])
2886+ elif test "x$fastrpz_avail" = "x0"; then
2887+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
2888+ fi
2889+])
2890diff --git a/iterator/iterator.c b/iterator/iterator.c
2891index 1e0113a8..2fcbf547 100644
2891index 23b07ea9..c3d31a33 100644
2892--- a/iterator/iterator.c
2893+++ b/iterator/iterator.c
2894@@ -68,6 +68,9 @@
2895 #include "sldns/str2wire.h"
2896 #include "sldns/parseutil.h"
2897 #include "sldns/sbuffer.h"
2898+#ifdef ENABLE_FASTRPZ
2899+#include "fastrpz/rpz.h"
2900+#endif
2901
2902 /* in msec */
2903 int UNKNOWN_SERVER_NICENESS = 376;
2892--- a/iterator/iterator.c
2893+++ b/iterator/iterator.c
2894@@ -68,6 +68,9 @@
2895 #include "sldns/str2wire.h"
2896 #include "sldns/parseutil.h"
2897 #include "sldns/sbuffer.h"
2898+#ifdef ENABLE_FASTRPZ
2899+#include "fastrpz/rpz.h"
2900+#endif
2901
2902 /* in msec */
2903 int UNKNOWN_SERVER_NICENESS = 376;
2904@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
2904@@ -563,6 +566,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
2905 if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
2906 query_dname_compare(*mname, r->rk.dname) == 0 &&
2907 !iter_find_rrset_in_prepend_answer(iq, r)) {
2908+#ifdef ENABLE_FASTRPZ
2909+ /* Stop adding CNAME rrsets to the prepend list
2910+ * before defining an RPZ hit. */
2911+ if(!iq->rpz_rewritten) {
2912+ switch (rpz_cname(qstate, *mname, *mname_len)) {

--- 7 unchanged lines hidden (view full) ---

2920+ /* Pause before adding the CNAME. */
2921+ goto stop_short;
2922+ }
2923+ }
2924+#endif
2925 /* Add this relevant CNAME rrset to the prepend list.*/
2926 if(!iter_add_prepend_answer(qstate, iq, r))
2927 return 0;
2905 if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
2906 query_dname_compare(*mname, r->rk.dname) == 0 &&
2907 !iter_find_rrset_in_prepend_answer(iq, r)) {
2908+#ifdef ENABLE_FASTRPZ
2909+ /* Stop adding CNAME rrsets to the prepend list
2910+ * before defining an RPZ hit. */
2911+ if(!iq->rpz_rewritten) {
2912+ switch (rpz_cname(qstate, *mname, *mname_len)) {

--- 7 unchanged lines hidden (view full) ---

2920+ /* Pause before adding the CNAME. */
2921+ goto stop_short;
2922+ }
2923+ }
2924+#endif
2925 /* Add this relevant CNAME rrset to the prepend list.*/
2926 if(!iter_add_prepend_answer(qstate, iq, r))
2927 return 0;
2928@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
2928@@ -571,6 +591,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
2929
2930 /* Other rrsets in the section are ignored. */
2931 }
2932+#ifdef ENABLE_FASTRPZ
2933+stop_short: ;
2934+#endif
2935 /* add authority rrsets to authority prepend, for wildcarded CNAMEs */
2936 for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
2937 msg->rep->ns_numrrsets; i++) {
2929
2930 /* Other rrsets in the section are ignored. */
2931 }
2932+#ifdef ENABLE_FASTRPZ
2933+stop_short: ;
2934+#endif
2935 /* add authority rrsets to authority prepend, for wildcarded CNAMEs */
2936 for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
2937 msg->rep->ns_numrrsets; i++) {
2938@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2938@@ -1231,6 +1254,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2939 uint8_t* delname;
2940 size_t delnamelen;
2941 struct dns_msg* msg = NULL;
2942+ enum response_type type;
2943
2944 log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
2945 /* check effort */
2939 uint8_t* delname;
2940 size_t delnamelen;
2941 struct dns_msg* msg = NULL;
2942+ enum response_type type;
2943
2944 log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
2945 /* check effort */
2946@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2946@@ -1317,8 +1341,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2947 }
2948 if(msg) {
2949 /* handle positive cache response */
2950- enum response_type type = response_type_from_cache(msg,
2951- &iq->qchase);
2952+ type = response_type_from_cache(msg, &iq->qchase);
2953 if(verbosity >= VERB_ALGO) {
2954 log_dns_msg("msg from cache lookup", &msg->qinfo,
2955 msg->rep);
2947 }
2948 if(msg) {
2949 /* handle positive cache response */
2950- enum response_type type = response_type_from_cache(msg,
2951- &iq->qchase);
2952+ type = response_type_from_cache(msg, &iq->qchase);
2953 if(verbosity >= VERB_ALGO) {
2954 log_dns_msg("msg from cache lookup", &msg->qinfo,
2955 msg->rep);
2956@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2956@@ -1326,7 +1349,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
2957 (int)msg->rep->ttl,
2958 (int)msg->rep->prefetch_ttl);
2959 }
2960+#ifdef ENABLE_FASTRPZ
2961+ }
2962+ /* Check for an RPZ hit in the cached DNS message or an existing
2963+ * RPZ CNAME rewrite that can be resolved now after a hit on the QNAME
2964+ * or client IP address. This can involve a creating a fake cache

--- 6 unchanged lines hidden (view full) ---

2971+ !rpz_iter_cache(&msg, &type, qstate, iq))
2972+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
2973
2974+ if(msg) {
2975+#endif
2976 if(type == RESPONSE_TYPE_CNAME) {
2977 uint8_t* sname = 0;
2978 size_t slen = 0;
2957 (int)msg->rep->ttl,
2958 (int)msg->rep->prefetch_ttl);
2959 }
2960+#ifdef ENABLE_FASTRPZ
2961+ }
2962+ /* Check for an RPZ hit in the cached DNS message or an existing
2963+ * RPZ CNAME rewrite that can be resolved now after a hit on the QNAME
2964+ * or client IP address. This can involve a creating a fake cache

--- 6 unchanged lines hidden (view full) ---

2971+ !rpz_iter_cache(&msg, &type, qstate, iq))
2972+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
2973
2974+ if(msg) {
2975+#endif
2976 if(type == RESPONSE_TYPE_CNAME) {
2977 uint8_t* sname = 0;
2978 size_t slen = 0;
2979@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
2979@@ -2801,6 +2839,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
2980 sock_list_insert(&qstate->reply_origin,
2981 &qstate->reply->addr, qstate->reply->addrlen,
2982 qstate->region);
2983+#ifdef ENABLE_FASTRPZ
2984+ /* Check the response for an RPZ hit. The response has already
2985+ * been saved in the cache. This should have the same effect
2986+ * as finding that response in the cache.
2987+ * We have already used rpz_iter_cache() at least once. */

--- 46 unchanged lines hidden (view full) ---

3034+ case rpz_iter_resp_done:
3035+ break;
3036+ }
3037+ }
3038+#endif
3039 if(iq->minimisation_state != DONOT_MINIMISE_STATE
3040 && !(iq->chase_flags & BIT_RD)) {
3041 if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
2980 sock_list_insert(&qstate->reply_origin,
2981 &qstate->reply->addr, qstate->reply->addrlen,
2982 qstate->region);
2983+#ifdef ENABLE_FASTRPZ
2984+ /* Check the response for an RPZ hit. The response has already
2985+ * been saved in the cache. This should have the same effect
2986+ * as finding that response in the cache.
2987+ * We have already used rpz_iter_cache() at least once. */

--- 46 unchanged lines hidden (view full) ---

3034+ case rpz_iter_resp_done:
3035+ break;
3036+ }
3037+ }
3038+#endif
3039 if(iq->minimisation_state != DONOT_MINIMISE_STATE
3040 && !(iq->chase_flags & BIT_RD)) {
3041 if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
3042@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
3042@@ -3563,12 +3657,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
3043 * but only if we did recursion. The nonrecursion referral
3044 * from cache does not need to be stored in the msg cache. */
3045 if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
3046+#ifdef ENABLE_FASTRPZ
3047+ /* Do not save RPZ rewritten messages. */
3048+ if(!iq->rpz_rewritten)
3049+#endif
3050 iter_dns_store(qstate->env, &qstate->qinfo,

--- 29 unchanged lines hidden (view full) ---

3080+ ++iq->response->rep->ar_numrrsets;
3081+ }
3082+ }
3083+#endif
3084 qstate->return_rcode = LDNS_RCODE_NOERROR;
3085 qstate->return_msg = iq->response;
3086 return 0;
3087diff --git a/iterator/iterator.h b/iterator/iterator.h
3043 * but only if we did recursion. The nonrecursion referral
3044 * from cache does not need to be stored in the msg cache. */
3045 if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
3046+#ifdef ENABLE_FASTRPZ
3047+ /* Do not save RPZ rewritten messages. */
3048+ if(!iq->rpz_rewritten)
3049+#endif
3050 iter_dns_store(qstate->env, &qstate->qinfo,

--- 29 unchanged lines hidden (view full) ---

3080+ ++iq->response->rep->ar_numrrsets;
3081+ }
3082+ }
3083+#endif
3084 qstate->return_rcode = LDNS_RCODE_NOERROR;
3085 qstate->return_msg = iq->response;
3086 return 0;
3087diff --git a/iterator/iterator.h b/iterator/iterator.h
3088index a2f1b570..e1e4a738 100644
3088index 342ac207..49b0ecdd 100644
3089--- a/iterator/iterator.h
3090+++ b/iterator/iterator.h
3089--- a/iterator/iterator.h
3090+++ b/iterator/iterator.h
3091@@ -386,6 +386,16 @@ struct iter_qstate {
3091@@ -396,6 +396,16 @@ struct iter_qstate {
3092 */
3093 int minimise_count;
3094
3095+
3096+#ifdef ENABLE_FASTRPZ
3097+ /** The response has been rewritten by RPZ. */
3098+ int rpz_rewritten;
3099+ /** RPZ SOA RR for the ADDITIONAL section */
3100+ struct ub_packed_rrset_key* rpz_soa;
3101+ /** sec_status_rpz_rewritten or sec_status_rpz_drop if rewritten. */
3102+ enum sec_status rpz_security;
3103+#endif
3104+
3105 /**
3106 * Count number of time-outs. Used to prevent resolving failures when
3092 */
3093 int minimise_count;
3094
3095+
3096+#ifdef ENABLE_FASTRPZ
3097+ /** The response has been rewritten by RPZ. */
3098+ int rpz_rewritten;
3099+ /** RPZ SOA RR for the ADDITIONAL section */
3100+ struct ub_packed_rrset_key* rpz_soa;
3101+ /** sec_status_rpz_rewritten or sec_status_rpz_drop if rewritten. */
3102+ enum sec_status rpz_security;
3103+#endif
3104+
3105 /**
3106 * Count number of time-outs. Used to prevent resolving failures when
3107 * the QNAME minimisation QTYPE is blocked. */
3107 * the QNAME minimisation QTYPE is blocked. Used to determine if
3108diff --git a/services/cache/dns.c b/services/cache/dns.c
3108diff --git a/services/cache/dns.c b/services/cache/dns.c
3109index 2a5bca4a..6de8863a 100644
3109index 7b6e142c..6d7449f5 100644
3110--- a/services/cache/dns.c
3111+++ b/services/cache/dns.c
3110--- a/services/cache/dns.c
3111+++ b/services/cache/dns.c
3112@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
3112@@ -969,6 +969,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
3113 struct regional* region, uint32_t flags)
3114 {
3115 struct reply_info* rep = NULL;
3116+
3117+#ifdef ENABLE_FASTRPZ
3118+ /* Never save RPZ rewritten data. */
3119+ if (msgrep->security == sec_status_rpz_drop ||
3120+ msgrep->security == sec_status_rpz_rewritten)
3121+ return 1;
3122+#endif
3123+
3124 /* alloc, malloc properly (not in region, like msg is) */
3125 rep = reply_info_copy(msgrep, env->alloc, NULL);
3126 if(!rep)
3127diff --git a/services/mesh.c b/services/mesh.c
3113 struct regional* region, uint32_t flags)
3114 {
3115 struct reply_info* rep = NULL;
3116+
3117+#ifdef ENABLE_FASTRPZ
3118+ /* Never save RPZ rewritten data. */
3119+ if (msgrep->security == sec_status_rpz_drop ||
3120+ msgrep->security == sec_status_rpz_rewritten)
3121+ return 1;
3122+#endif
3123+
3124 /* alloc, malloc properly (not in region, like msg is) */
3125 rep = reply_info_copy(msgrep, env->alloc, NULL);
3126 if(!rep)
3127diff --git a/services/mesh.c b/services/mesh.c
3128index 9114ef4c..3dc518e5 100644
3128index 4b0c5db4..eb9cfa5b 100644
3129--- a/services/mesh.c
3130+++ b/services/mesh.c
3131@@ -61,6 +61,9 @@
3132 #include "sldns/wire2str.h"
3133 #include "services/localzone.h"
3134 #include "util/data/dname.h"
3135+#ifdef ENABLE_FASTRPZ
3136+#include "fastrpz/rpz.h"
3137+#endif
3138 #include "respip/respip.h"
3139 #include "services/listen_dnsport.h"
3140
3129--- a/services/mesh.c
3130+++ b/services/mesh.c
3131@@ -61,6 +61,9 @@
3132 #include "sldns/wire2str.h"
3133 #include "services/localzone.h"
3134 #include "util/data/dname.h"
3135+#ifdef ENABLE_FASTRPZ
3136+#include "fastrpz/rpz.h"
3137+#endif
3138 #include "respip/respip.h"
3139 #include "services/listen_dnsport.h"
3140
3141@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
3141@@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
3142 else secure = 0;
3143 if(!rep && rcode == LDNS_RCODE_NOERROR)
3144 rcode = LDNS_RCODE_SERVFAIL;
3145+#ifdef ENABLE_FASTRPZ
3146+ /* Drop the response here for LIBRPZ_POLICY_DROP after iteration. */
3147+ if(rep && rep->security == sec_status_rpz_drop) {
3148+ log_query_info(VERB_QUERY, "rpz drop", &m->s.qinfo);
3149+ secure = 0;
3150+ } else
3151+#endif
3152 /* send the reply */
3153 /* We don't reuse the encoded answer if either the previous or current
3154 * response has a local alias. We could compare the alias records
3142 else secure = 0;
3143 if(!rep && rcode == LDNS_RCODE_NOERROR)
3144 rcode = LDNS_RCODE_SERVFAIL;
3145+#ifdef ENABLE_FASTRPZ
3146+ /* Drop the response here for LIBRPZ_POLICY_DROP after iteration. */
3147+ if(rep && rep->security == sec_status_rpz_drop) {
3148+ log_query_info(VERB_QUERY, "rpz drop", &m->s.qinfo);
3149+ secure = 0;
3150+ } else
3151+#endif
3152 /* send the reply */
3153 /* We don't reuse the encoded answer if either the previous or current
3154 * response has a local alias. We could compare the alias records
3155@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
3155@@ -1434,6 +1444,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
3156 key.s.is_valrec = valrec;
3157 key.s.qinfo = *qinfo;
3158 key.s.query_flags = qflags;
3159+ key.reply_list = NULL;
3160 /* We are searching for a similar mesh state when we DO want to
3161 * aggregate the state. Thus unique is set to NULL. (default when we
3162 * desire aggregation).*/
3156 key.s.is_valrec = valrec;
3157 key.s.qinfo = *qinfo;
3158 key.s.query_flags = qflags;
3159+ key.reply_list = NULL;
3160 /* We are searching for a similar mesh state when we DO want to
3161 * aggregate the state. Thus unique is set to NULL. (default when we
3162 * desire aggregation).*/
3163@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
3163@@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
3164 if(!r)
3165 return 0;
3166 r->query_reply = *rep;
3167+#ifdef ENABLE_FASTRPZ
3168+ /* The new reply structure owns the RPZ state. */
3169+ rep->rpz = NULL;
3170+#endif
3171 r->edns = *edns;
3172 if(edns->opt_list) {
3173 r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
3174diff --git a/util/config_file.c b/util/config_file.c
3164 if(!r)
3165 return 0;
3166 r->query_reply = *rep;
3167+#ifdef ENABLE_FASTRPZ
3168+ /* The new reply structure owns the RPZ state. */
3169+ rep->rpz = NULL;
3170+#endif
3171 r->edns = *edns;
3172 if(edns->opt_list) {
3173 r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
3174diff --git a/util/config_file.c b/util/config_file.c
3175index 52ca5a18..0660248f 100644
3175index 0e9ee471..a5fd72e0 100644
3176--- a/util/config_file.c
3177+++ b/util/config_file.c
3176--- a/util/config_file.c
3177+++ b/util/config_file.c
3178@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
3179 free(cfg->dnstap_socket_path);
3178@@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
3179 free(cfg->dnstap_tls_client_cert_file);
3180 free(cfg->dnstap_identity);
3181 free(cfg->dnstap_version);
3182+ if (cfg->rpz_cstr)
3183+ free(cfg->rpz_cstr);
3184 config_deldblstrlist(cfg->ratelimit_for_domain);
3185 config_deldblstrlist(cfg->ratelimit_below_domain);
3186 config_delstrlist(cfg->python_script);
3187diff --git a/util/config_file.h b/util/config_file.h
3180 free(cfg->dnstap_identity);
3181 free(cfg->dnstap_version);
3182+ if (cfg->rpz_cstr)
3183+ free(cfg->rpz_cstr);
3184 config_deldblstrlist(cfg->ratelimit_for_domain);
3185 config_deldblstrlist(cfg->ratelimit_below_domain);
3186 config_delstrlist(cfg->python_script);
3187diff --git a/util/config_file.h b/util/config_file.h
3188index 8739ca2a..a2dcf215 100644
3188index 66e5025d..504f4f92 100644
3189--- a/util/config_file.h
3190+++ b/util/config_file.h
3189--- a/util/config_file.h
3190+++ b/util/config_file.h
3191@@ -499,6 +499,11 @@ struct config_file {
3191@@ -522,6 +522,11 @@ struct config_file {
3192 /** true to disable DNSSEC lameness check in iterator */
3193 int disable_dnssec_lame_check;
3194
3195+ /** true to enable RPZ */
3196+ int rpz_enable;
3197+ /** RPZ configuration */
3198+ char* rpz_cstr;
3199+
3200 /** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
3201 int ip_ratelimit;
3202 /** number of slabs for ip_ratelimit cache */
3203diff --git a/util/configlexer.lex b/util/configlexer.lex
3192 /** true to disable DNSSEC lameness check in iterator */
3193 int disable_dnssec_lame_check;
3194
3195+ /** true to enable RPZ */
3196+ int rpz_enable;
3197+ /** RPZ configuration */
3198+ char* rpz_cstr;
3199+
3200 /** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
3201 int ip_ratelimit;
3202 /** number of slabs for ip_ratelimit cache */
3203diff --git a/util/configlexer.lex b/util/configlexer.lex
3204index deedffa5..301458a3 100644
3204index 83cea4b9..9a7feea4 100644
3205--- a/util/configlexer.lex
3206+++ b/util/configlexer.lex
3205--- a/util/configlexer.lex
3206+++ b/util/configlexer.lex
3207@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} {
3207@@ -467,6 +467,10 @@ dnstap-log-forwarder-query-messages{COLON} {
3208 YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
3209 dnstap-log-forwarder-response-messages{COLON} {
3210 YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
3211+rpz{COLON} { YDVAR(0, VAR_RPZ) }
3212+rpz-enable{COLON} { YDVAR(1, VAR_RPZ_ENABLE) }
3213+rpz-zone{COLON} { YDVAR(1, VAR_RPZ_ZONE) }
3214+rpz-option{COLON} { YDVAR(1, VAR_RPZ_OPTION) }
3215 disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
3216 ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
3217 ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
3218diff --git a/util/configparser.y b/util/configparser.y
3208 YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
3209 dnstap-log-forwarder-response-messages{COLON} {
3210 YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
3211+rpz{COLON} { YDVAR(0, VAR_RPZ) }
3212+rpz-enable{COLON} { YDVAR(1, VAR_RPZ_ENABLE) }
3213+rpz-zone{COLON} { YDVAR(1, VAR_RPZ_ZONE) }
3214+rpz-option{COLON} { YDVAR(1, VAR_RPZ_OPTION) }
3215 disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
3216 ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
3217 ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
3218diff --git a/util/configparser.y b/util/configparser.y
3219index d471babe..cb6b1d63 100644
3219index fe600a99..ce43390f 100644
3220--- a/util/configparser.y
3221+++ b/util/configparser.y
3220--- a/util/configparser.y
3221+++ b/util/configparser.y
3222@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
3222@@ -128,6 +128,7 @@ extern struct config_parser_state* cfg_parser;
3223 %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
3224 %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
3225 %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
3226+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
3227 %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
3228 %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
3223 %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
3224 %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
3225 %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
3226+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
3227 %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
3228 %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
3229 %token VAR_DISABLE_DNSSEC_LAME_CHECK
3230@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
3229 %token VAR_IP_DSCP
3230@@ -179,7 +180,7 @@ extern struct config_parser_state* cfg_parser;
3231
3232 %%
3233 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
3234-toplevelvar: serverstart contents_server | stubstart contents_stub |
3235+toplevelvar: serverstart contents_server | stubstart contents_stub | rpzstart contents_rpz |
3236 forwardstart contents_forward | pythonstart contents_py |
3237 rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
3238 dnscstart contents_dnsc | cachedbstart contents_cachedb |
3231
3232 %%
3233 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
3234-toplevelvar: serverstart contents_server | stubstart contents_stub |
3235+toplevelvar: serverstart contents_server | stubstart contents_stub | rpzstart contents_rpz |
3236 forwardstart contents_forward | pythonstart contents_py |
3237 rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
3238 dnscstart contents_dnsc | cachedbstart contents_cachedb |
3239@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
3239@@ -2939,6 +2940,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
3240 free($2);
3241 }
3242 ;
3243+rpzstart: VAR_RPZ
3244+ {
3245+ OUTYY(("\nP(rpz:)\n"));
3246+ }
3247+ ;

--- 131 unchanged lines hidden (view full) ---

3379+ /** RPZ_DROP means that the response has been rewritten by rpz
3380+ * as silence. */
3381+ sec_status_rpz_drop
3382+#endif
3383 };
3384
3385 /**
3386diff --git a/util/netevent.c b/util/netevent.c
3240 free($2);
3241 }
3242 ;
3243+rpzstart: VAR_RPZ
3244+ {
3245+ OUTYY(("\nP(rpz:)\n"));
3246+ }
3247+ ;

--- 131 unchanged lines hidden (view full) ---

3379+ /** RPZ_DROP means that the response has been rewritten by rpz
3380+ * as silence. */
3381+ sec_status_rpz_drop
3382+#endif
3383 };
3384
3385 /**
3386diff --git a/util/netevent.c b/util/netevent.c
3387index 9fe5da2d..037e70d1 100644
3387index 3e7a433e..f20d806f 100644
3388--- a/util/netevent.c
3389+++ b/util/netevent.c
3390@@ -57,6 +57,9 @@
3391 #ifdef HAVE_OPENSSL_ERR_H
3392 #include <openssl/err.h>
3393 #endif
3394+#ifdef ENABLE_FASTRPZ
3395+#include "fastrpz/rpz.h"
3396+#endif
3397
3398 /* -------- Start of local definitions -------- */
3399 /** if CMSG_ALIGN is not defined on this platform, a workaround */
3388--- a/util/netevent.c
3389+++ b/util/netevent.c
3390@@ -57,6 +57,9 @@
3391 #ifdef HAVE_OPENSSL_ERR_H
3392 #include <openssl/err.h>
3393 #endif
3394+#ifdef ENABLE_FASTRPZ
3395+#include "fastrpz/rpz.h"
3396+#endif
3397
3398 /* -------- Start of local definitions -------- */
3399 /** if CMSG_ALIGN is not defined on this platform, a workaround */
3400@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
3400@@ -596,6 +599,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
3401 struct cmsghdr* cmsg;
3402 #endif /* S_SPLINT_S */
3403
3404+#ifdef ENABLE_FASTRPZ
3405+ rep.rpz = NULL;
3406+#endif
3407 rep.c = (struct comm_point*)arg;
3408 log_assert(rep.c->type == comm_udp);
3409
3401 struct cmsghdr* cmsg;
3402 #endif /* S_SPLINT_S */
3403
3404+#ifdef ENABLE_FASTRPZ
3405+ rep.rpz = NULL;
3406+#endif
3407 rep.c = (struct comm_point*)arg;
3408 log_assert(rep.c->type == comm_udp);
3409
3410@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
3410@@ -685,6 +691,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
3411 int i;
3412 struct sldns_buffer *buffer;
3413
3414+#ifdef ENABLE_FASTRPZ
3415+ rep.rpz = NULL;
3416+#endif
3417 rep.c = (struct comm_point*)arg;
3418 log_assert(rep.c->type == comm_udp);
3419
3411 int i;
3412 struct sldns_buffer *buffer;
3413
3414+#ifdef ENABLE_FASTRPZ
3415+ rep.rpz = NULL;
3416+#endif
3417 rep.c = (struct comm_point*)arg;
3418 log_assert(rep.c->type == comm_udp);
3419
3420@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
3420@@ -728,6 +737,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
3421 (void)comm_point_send_udp_msg(rep.c, buffer,
3422 (struct sockaddr*)&rep.addr, rep.addrlen);
3423 }
3424+#ifdef ENABLE_FASTRPZ
3425+ rpz_end(&rep);
3426+#endif
3427 if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
3428 another UDP port. Note rep.c cannot be reused with TCP fd. */
3429 break;
3421 (void)comm_point_send_udp_msg(rep.c, buffer,
3422 (struct sockaddr*)&rep.addr, rep.addrlen);
3423 }
3424+#ifdef ENABLE_FASTRPZ
3425+ rpz_end(&rep);
3426+#endif
3427 if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
3428 another UDP port. Note rep.c cannot be reused with TCP fd. */
3429 break;
3430@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
3430@@ -3175,6 +3187,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
3431 repinfo->c->tcp_timeout_msec);
3432 }
3433 }
3434+#ifdef ENABLE_FASTRPZ
3435+ rpz_end(repinfo);
3436+#endif
3437 }
3438
3439 void
3431 repinfo->c->tcp_timeout_msec);
3432 }
3433 }
3434+#ifdef ENABLE_FASTRPZ
3435+ rpz_end(repinfo);
3436+#endif
3437 }
3438
3439 void
3440@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
3440@@ -3184,6 +3199,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
3441 return;
3442 log_assert(repinfo->c);
3443 log_assert(repinfo->c->type != comm_tcp_accept);
3444+#ifdef ENABLE_FASTRPZ
3445+ rpz_end(repinfo);
3446+#endif
3447 if(repinfo->c->type == comm_udp)
3448 return;
3449 if(repinfo->c->tcp_req_info)
3441 return;
3442 log_assert(repinfo->c);
3443 log_assert(repinfo->c->type != comm_tcp_accept);
3444+#ifdef ENABLE_FASTRPZ
3445+ rpz_end(repinfo);
3446+#endif
3447 if(repinfo->c->type == comm_udp)
3448 return;
3449 if(repinfo->c->tcp_req_info)
3450@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
3450@@ -3205,6 +3223,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
3451 {
3452 verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
3453 c->fd==-1?newfd:c->fd, msec);
3454+#ifdef ENABLE_FASTRPZ
3455+ rpz_end(&c->repinfo);
3456+#endif
3457 if(c->type == comm_tcp_accept && !c->tcp_free) {
3458 /* no use to start listening no free slots. */
3459 return;
3460diff --git a/util/netevent.h b/util/netevent.h
3451 {
3452 verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
3453 c->fd==-1?newfd:c->fd, msec);
3454+#ifdef ENABLE_FASTRPZ
3455+ rpz_end(&c->repinfo);
3456+#endif
3457 if(c->type == comm_tcp_accept && !c->tcp_free) {
3458 /* no use to start listening no free slots. */
3459 return;
3460diff --git a/util/netevent.h b/util/netevent.h
3461index d80c72b3..0233292f 100644
3461index bb2cd1e5..666067e8 100644
3462--- a/util/netevent.h
3463+++ b/util/netevent.h
3464@@ -120,6 +120,10 @@ struct comm_reply {
3465 /** return type 0 (none), 4(IP4), 6(IP6) */
3466 int srctype;
3467 /* DnsCrypt context */
3468+#ifdef ENABLE_FASTRPZ
3469+ /** per-request RPZ state */

--- 35 unchanged lines hidden ---
3462--- a/util/netevent.h
3463+++ b/util/netevent.h
3464@@ -120,6 +120,10 @@ struct comm_reply {
3465 /** return type 0 (none), 4(IP4), 6(IP6) */
3466 int srctype;
3467 /* DnsCrypt context */
3468+#ifdef ENABLE_FASTRPZ
3469+ /** per-request RPZ state */

--- 35 unchanged lines hidden ---