xref: /freebsd/contrib/unbound/services/rpz.c (revision 024248c933c5741a21c17eda63092f330dd98337)
1 /*
2  * services/rpz.c - rpz service
3  *
4  * Copyright (c) 2019, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file contains functions to enable RPZ service.
40  */
41 
42 #include "config.h"
43 #include "services/rpz.h"
44 #include "util/config_file.h"
45 #include "sldns/wire2str.h"
46 #include "sldns/str2wire.h"
47 #include "util/data/dname.h"
48 #include "util/net_help.h"
49 #include "util/log.h"
50 #include "util/data/dname.h"
51 #include "util/locks.h"
52 #include "util/regional.h"
53 #include "util/data/msgencode.h"
54 #include "services/cache/dns.h"
55 #include "iterator/iterator.h"
56 #include "iterator/iter_delegpt.h"
57 #include "daemon/worker.h"
58 
59 typedef struct resp_addr rpz_aclnode_type;
60 
61 struct matched_delegation_point {
62 	uint8_t* dname;
63 	size_t dname_len;
64 };
65 
66 /** string for RPZ action enum */
67 const char*
68 rpz_action_to_string(enum rpz_action a)
69 {
70 	switch(a) {
71 	case RPZ_NXDOMAIN_ACTION: return "rpz-nxdomain";
72 	case RPZ_NODATA_ACTION: return "rpz-nodata";
73 	case RPZ_PASSTHRU_ACTION: return "rpz-passthru";
74 	case RPZ_DROP_ACTION: return "rpz-drop";
75 	case RPZ_TCP_ONLY_ACTION: return "rpz-tcp-only";
76 	case RPZ_INVALID_ACTION: return "rpz-invalid";
77 	case RPZ_LOCAL_DATA_ACTION: return "rpz-local-data";
78 	case RPZ_DISABLED_ACTION: return "rpz-disabled";
79 	case RPZ_CNAME_OVERRIDE_ACTION: return "rpz-cname-override";
80 	case RPZ_NO_OVERRIDE_ACTION: return "rpz-no-override";
81 	default: return "rpz-unknown-action";
82 	}
83 }
84 
85 /** RPZ action enum for config string */
86 static enum rpz_action
87 rpz_config_to_action(char* a)
88 {
89 	if(strcmp(a, "nxdomain") == 0) return RPZ_NXDOMAIN_ACTION;
90 	else if(strcmp(a, "nodata") == 0) return RPZ_NODATA_ACTION;
91 	else if(strcmp(a, "passthru") == 0) return RPZ_PASSTHRU_ACTION;
92 	else if(strcmp(a, "drop") == 0) return RPZ_DROP_ACTION;
93 	else if(strcmp(a, "tcp_only") == 0) return RPZ_TCP_ONLY_ACTION;
94 	else if(strcmp(a, "cname") == 0) return RPZ_CNAME_OVERRIDE_ACTION;
95 	else if(strcmp(a, "disabled") == 0) return RPZ_DISABLED_ACTION;
96 	else return RPZ_INVALID_ACTION;
97 }
98 
99 /** string for RPZ trigger enum */
100 static const char*
101 rpz_trigger_to_string(enum rpz_trigger r)
102 {
103 	switch(r) {
104 	case RPZ_QNAME_TRIGGER: return "rpz-qname";
105 	case RPZ_CLIENT_IP_TRIGGER: return "rpz-client-ip";
106 	case RPZ_RESPONSE_IP_TRIGGER: return "rpz-response-ip";
107 	case RPZ_NSDNAME_TRIGGER: return "rpz-nsdname";
108 	case RPZ_NSIP_TRIGGER: return "rpz-nsip";
109 	case RPZ_INVALID_TRIGGER: return "rpz-invalid";
110 	default: return "rpz-unknown-trigger";
111 	}
112 }
113 
114 /**
115  * Get the label that is just before the root label.
116  * @param dname: dname to work on
117  * @param maxdnamelen: maximum length of the dname
118  * @return: pointer to TLD label, NULL if not found or invalid dname
119  */
120 static uint8_t*
121 get_tld_label(uint8_t* dname, size_t maxdnamelen)
122 {
123 	uint8_t* prevlab = dname;
124 	size_t dnamelen = 0;
125 
126 	/* one byte needed for label length */
127 	if(dnamelen+1 > maxdnamelen)
128 		return NULL;
129 
130 	/* only root label */
131 	if(*dname == 0)
132 		return NULL;
133 
134 	while(*dname) {
135 		dnamelen += ((size_t)*dname)+1;
136 		if(dnamelen+1 > maxdnamelen)
137 			return NULL;
138 		dname = dname+((size_t)*dname)+1;
139 		if(*dname != 0)
140 			prevlab = dname;
141 	}
142 	return prevlab;
143 }
144 
145 /**
146  * The RR types that are to be ignored.
147  * DNSSEC RRs at the apex, and SOA and NS are ignored.
148  */
149 static int
150 rpz_type_ignored(uint16_t rr_type)
151 {
152 	switch(rr_type) {
153 		case LDNS_RR_TYPE_SOA:
154 		case LDNS_RR_TYPE_NS:
155 		case LDNS_RR_TYPE_DNAME:
156 		/* all DNSSEC-related RRs must be ignored */
157 		case LDNS_RR_TYPE_DNSKEY:
158 		case LDNS_RR_TYPE_DS:
159 		case LDNS_RR_TYPE_RRSIG:
160 		case LDNS_RR_TYPE_NSEC:
161 		case LDNS_RR_TYPE_NSEC3:
162 		case LDNS_RR_TYPE_NSEC3PARAM:
163 			return 1;
164 		default:
165 			break;
166 	}
167 	return 0;
168 }
169 
170 /**
171  * Classify RPZ action for RR type/rdata
172  * @param rr_type: the RR type
173  * @param rdatawl: RDATA with 2 bytes length
174  * @param rdatalen: the length of rdatawl (including its 2 bytes length)
175  * @return: the RPZ action
176  */
177 static enum rpz_action
178 rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
179 {
180 	char* endptr;
181 	uint8_t* rdata;
182 	int rdatalabs;
183 	uint8_t* tldlab = NULL;
184 
185 	switch(rr_type) {
186 		case LDNS_RR_TYPE_SOA:
187 		case LDNS_RR_TYPE_NS:
188 		case LDNS_RR_TYPE_DNAME:
189 		/* all DNSSEC-related RRs must be ignored */
190 		case LDNS_RR_TYPE_DNSKEY:
191 		case LDNS_RR_TYPE_DS:
192 		case LDNS_RR_TYPE_RRSIG:
193 		case LDNS_RR_TYPE_NSEC:
194 		case LDNS_RR_TYPE_NSEC3:
195 		case LDNS_RR_TYPE_NSEC3PARAM:
196 			return RPZ_INVALID_ACTION;
197 		case LDNS_RR_TYPE_CNAME:
198 			break;
199 		default:
200 			return RPZ_LOCAL_DATA_ACTION;
201 	}
202 
203 	/* use CNAME target to determine RPZ action */
204 	log_assert(rr_type == LDNS_RR_TYPE_CNAME);
205 	if(rdatalen < 3)
206 		return RPZ_INVALID_ACTION;
207 
208 	rdata = rdatawl + 2; /* 2 bytes of rdata length */
209 	if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
210 		return RPZ_INVALID_ACTION;
211 
212 	rdatalabs = dname_count_labels(rdata);
213 	if(rdatalabs == 1)
214 		return RPZ_NXDOMAIN_ACTION;
215 	else if(rdatalabs == 2) {
216 		if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000"))
217 			return RPZ_NODATA_ACTION;
218 		else if(dname_subdomain_c(rdata,
219 			(uint8_t*)&"\014rpz-passthru\000"))
220 			return RPZ_PASSTHRU_ACTION;
221 		else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000"))
222 			return RPZ_DROP_ACTION;
223 		else if(dname_subdomain_c(rdata,
224 			(uint8_t*)&"\014rpz-tcp-only\000"))
225 			return RPZ_TCP_ONLY_ACTION;
226 	}
227 
228 	/* all other TLDs starting with "rpz-" are invalid */
229 	tldlab = get_tld_label(rdata, rdatalen-2);
230 	if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
231 		return RPZ_INVALID_ACTION;
232 
233 	/* no special label found */
234 	return RPZ_LOCAL_DATA_ACTION;
235 }
236 
237 static enum localzone_type
238 rpz_action_to_localzone_type(enum rpz_action a)
239 {
240 	switch(a) {
241 	case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain;
242 	case RPZ_NODATA_ACTION: return local_zone_always_nodata;
243 	case RPZ_DROP_ACTION: return local_zone_always_deny;
244 	case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
245 	case RPZ_LOCAL_DATA_ACTION:
246 		ATTR_FALLTHROUGH
247 		/* fallthrough */
248 	case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
249 	case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
250 	case RPZ_INVALID_ACTION:
251 		ATTR_FALLTHROUGH
252 		/* fallthrough */
253 	default: return local_zone_invalid;
254 	}
255 }
256 
257 enum respip_action
258 rpz_action_to_respip_action(enum rpz_action a)
259 {
260 	switch(a) {
261 	case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
262 	case RPZ_NODATA_ACTION: return respip_always_nodata;
263 	case RPZ_DROP_ACTION: return respip_always_deny;
264 	case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
265 	case RPZ_LOCAL_DATA_ACTION:
266 		ATTR_FALLTHROUGH
267 		/* fallthrough */
268 	case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
269 	case RPZ_TCP_ONLY_ACTION: return respip_truncate;
270 	case RPZ_INVALID_ACTION:
271 		ATTR_FALLTHROUGH
272 		/* fallthrough */
273 	default: return respip_invalid;
274 	}
275 }
276 
277 static enum rpz_action
278 localzone_type_to_rpz_action(enum localzone_type lzt)
279 {
280 	switch(lzt) {
281 	case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
282 	case local_zone_always_nodata: return RPZ_NODATA_ACTION;
283 	case local_zone_always_deny: return RPZ_DROP_ACTION;
284 	case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
285 	case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
286 	case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
287 	case local_zone_invalid:
288 		ATTR_FALLTHROUGH
289 		/* fallthrough */
290 	default: return RPZ_INVALID_ACTION;
291 	}
292 }
293 
294 enum rpz_action
295 respip_action_to_rpz_action(enum respip_action a)
296 {
297 	switch(a) {
298 	case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
299 	case respip_always_nodata: return RPZ_NODATA_ACTION;
300 	case respip_always_deny: return RPZ_DROP_ACTION;
301 	case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
302 	case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
303 	case respip_truncate: return RPZ_TCP_ONLY_ACTION;
304 	case respip_invalid:
305 		ATTR_FALLTHROUGH
306 		/* fallthrough */
307 	default: return RPZ_INVALID_ACTION;
308 	}
309 }
310 
311 /**
312  * Get RPZ trigger for dname
313  * @param dname: dname containing RPZ trigger
314  * @param dname_len: length of the dname
315  * @return: RPZ trigger enum
316  */
317 static enum rpz_trigger
318 rpz_dname_to_trigger(uint8_t* dname, size_t dname_len)
319 {
320 	uint8_t* tldlab;
321 	char* endptr;
322 
323 	if(dname_valid(dname, dname_len) != dname_len)
324 		return RPZ_INVALID_TRIGGER;
325 
326 	tldlab = get_tld_label(dname, dname_len);
327 	if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr))
328 		return RPZ_QNAME_TRIGGER;
329 
330 	if(dname_subdomain_c(tldlab,
331 		(uint8_t*)&"\015rpz-client-ip\000"))
332 		return RPZ_CLIENT_IP_TRIGGER;
333 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000"))
334 		return RPZ_RESPONSE_IP_TRIGGER;
335 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000"))
336 		return RPZ_NSDNAME_TRIGGER;
337 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000"))
338 		return RPZ_NSIP_TRIGGER;
339 
340 	return RPZ_QNAME_TRIGGER;
341 }
342 
343 static inline struct clientip_synthesized_rrset*
344 rpz_clientip_synthesized_set_create(void)
345 {
346 	struct clientip_synthesized_rrset* set = calloc(1, sizeof(*set));
347 	if(set == NULL) {
348 		return NULL;
349 	}
350 	set->region = regional_create();
351 	if(set->region == NULL) {
352 		free(set);
353 		return NULL;
354 	}
355 	addr_tree_init(&set->entries);
356 	lock_rw_init(&set->lock);
357 	return set;
358 }
359 
360 static void
361 rpz_clientip_synthesized_rr_delete(rbnode_type* n, void* ATTR_UNUSED(arg))
362 {
363 	struct clientip_synthesized_rr* r = (struct clientip_synthesized_rr*)n->key;
364 	lock_rw_destroy(&r->lock);
365 #ifdef THREADS_DISABLED
366 	(void)r;
367 #endif
368 }
369 
370 static inline void
371 rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset* set)
372 {
373 	if(set == NULL) {
374 		return;
375 	}
376 	lock_rw_destroy(&set->lock);
377 	traverse_postorder(&set->entries, rpz_clientip_synthesized_rr_delete, NULL);
378 	regional_destroy(set->region);
379 	free(set);
380 }
381 
382 void
383 rpz_delete(struct rpz* r)
384 {
385 	if(!r)
386 		return;
387 	local_zones_delete(r->local_zones);
388 	local_zones_delete(r->nsdname_zones);
389 	respip_set_delete(r->respip_set);
390 	rpz_clientip_synthesized_set_delete(r->client_set);
391 	rpz_clientip_synthesized_set_delete(r->ns_set);
392 	regional_destroy(r->region);
393 	free(r->taglist);
394 	free(r->log_name);
395 	free(r);
396 }
397 
398 int
399 rpz_clear(struct rpz* r)
400 {
401 	/* must hold write lock on auth_zone */
402 	local_zones_delete(r->local_zones);
403 	r->local_zones = NULL;
404 	local_zones_delete(r->nsdname_zones);
405 	r->nsdname_zones = NULL;
406 	respip_set_delete(r->respip_set);
407 	r->respip_set = NULL;
408 	rpz_clientip_synthesized_set_delete(r->client_set);
409 	r->client_set = NULL;
410 	rpz_clientip_synthesized_set_delete(r->ns_set);
411 	r->ns_set = NULL;
412 	if(!(r->local_zones = local_zones_create())){
413 		return 0;
414 	}
415 	r->nsdname_zones = local_zones_create();
416 	if(r->nsdname_zones == NULL) {
417 		return 0;
418 	}
419 	if(!(r->respip_set = respip_set_create())) {
420 		return 0;
421 	}
422 	if(!(r->client_set = rpz_clientip_synthesized_set_create())) {
423 		return 0;
424 	}
425 	if(!(r->ns_set = rpz_clientip_synthesized_set_create())) {
426 		return 0;
427 	}
428 	return 1;
429 }
430 
431 void
432 rpz_finish_config(struct rpz* r)
433 {
434 	lock_rw_wrlock(&r->respip_set->lock);
435 	addr_tree_init_parents(&r->respip_set->ip_tree);
436 	lock_rw_unlock(&r->respip_set->lock);
437 
438 	lock_rw_wrlock(&r->client_set->lock);
439 	addr_tree_init_parents(&r->client_set->entries);
440 	lock_rw_unlock(&r->client_set->lock);
441 
442 	lock_rw_wrlock(&r->ns_set->lock);
443 	addr_tree_init_parents(&r->ns_set->entries);
444 	lock_rw_unlock(&r->ns_set->lock);
445 }
446 
447 /** new rrset containing CNAME override, does not yet contain a dname */
448 static struct ub_packed_rrset_key*
449 new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen)
450 {
451 	struct ub_packed_rrset_key* rrset;
452 	struct packed_rrset_data* pd;
453 	uint16_t rdlength = htons(ctlen);
454 	rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
455 		sizeof(*rrset));
456 	if(!rrset) {
457 		log_err("out of memory");
458 		return NULL;
459 	}
460 	rrset->entry.key = rrset;
461 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
462 	if(!pd) {
463 		log_err("out of memory");
464 		return NULL;
465 	}
466 	pd->trust = rrset_trust_prim_noglue;
467 	pd->security = sec_status_insecure;
468 
469 	pd->count = 1;
470 	pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len));
471 	pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl));
472 	pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data));
473 	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
474 		log_err("out of memory");
475 		return NULL;
476 	}
477 	pd->rr_len[0] = ctlen+2;
478 	pd->rr_ttl[0] = 3600;
479 	pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen);
480 	if(!pd->rr_data[0]) {
481 		log_err("out of memory");
482 		return NULL;
483 	}
484 	memmove(pd->rr_data[0], &rdlength, 2);
485 	memmove(pd->rr_data[0]+2, ct, ctlen);
486 
487 	rrset->entry.data = pd;
488 	rrset->rk.type = htons(LDNS_RR_TYPE_CNAME);
489 	rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN);
490 	return rrset;
491 }
492 
493 /** delete the cname override */
494 static void
495 delete_cname_override(struct rpz* r)
496 {
497 	if(r->cname_override) {
498 		/* The cname override is what is allocated in the region. */
499 		regional_free_all(r->region);
500 		r->cname_override = NULL;
501 	}
502 }
503 
504 /** Apply rpz config elements to the rpz structure, false on failure. */
505 static int
506 rpz_apply_cfg_elements(struct rpz* r, struct config_auth* p)
507 {
508 	if(p->rpz_taglist && p->rpz_taglistlen) {
509 		r->taglistlen = p->rpz_taglistlen;
510 		r->taglist = memdup(p->rpz_taglist, r->taglistlen);
511 		if(!r->taglist) {
512 			log_err("malloc failure on RPZ taglist alloc");
513 			return 0;
514 		}
515 	}
516 
517 	if(p->rpz_action_override) {
518 		r->action_override = rpz_config_to_action(p->rpz_action_override);
519 	}
520 	else
521 		r->action_override = RPZ_NO_OVERRIDE_ACTION;
522 
523 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
524 		uint8_t nm[LDNS_MAX_DOMAINLEN+1];
525 		size_t nmlen = sizeof(nm);
526 
527 		if(!p->rpz_cname) {
528 			log_err("rpz: override with cname action found, but no "
529 				"rpz-cname-override configured");
530 			return 0;
531 		}
532 
533 		if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
534 			log_err("rpz: cannot parse cname override: %s",
535 				p->rpz_cname);
536 			return 0;
537 		}
538 		r->cname_override = new_cname_override(r->region, nm, nmlen);
539 		if(!r->cname_override) {
540 			return 0;
541 		}
542 	}
543 	r->log = p->rpz_log;
544 	r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra;
545 	if(p->rpz_log_name) {
546 		if(!(r->log_name = strdup(p->rpz_log_name))) {
547 			log_err("malloc failure on RPZ log_name strdup");
548 			return 0;
549 		}
550 	}
551 	return 1;
552 }
553 
554 struct rpz*
555 rpz_create(struct config_auth* p)
556 {
557 	struct rpz* r = calloc(1, sizeof(*r));
558 	if(!r)
559 		goto err;
560 
561 	r->region = regional_create_custom(sizeof(struct regional));
562 	if(!r->region) {
563 		goto err;
564 	}
565 
566 	if(!(r->local_zones = local_zones_create())){
567 		goto err;
568 	}
569 
570 	r->nsdname_zones = local_zones_create();
571 	if(r->local_zones == NULL){
572 		goto err;
573 	}
574 
575 	if(!(r->respip_set = respip_set_create())) {
576 		goto err;
577 	}
578 
579 	r->client_set = rpz_clientip_synthesized_set_create();
580 	if(r->client_set == NULL) {
581 		goto err;
582 	}
583 
584 	r->ns_set = rpz_clientip_synthesized_set_create();
585 	if(r->ns_set == NULL) {
586 		goto err;
587 	}
588 
589 	if(!rpz_apply_cfg_elements(r, p))
590 		goto err;
591 	return r;
592 err:
593 	if(r) {
594 		if(r->local_zones)
595 			local_zones_delete(r->local_zones);
596 		if(r->nsdname_zones)
597 			local_zones_delete(r->nsdname_zones);
598 		if(r->respip_set)
599 			respip_set_delete(r->respip_set);
600 		if(r->client_set != NULL)
601 			rpz_clientip_synthesized_set_delete(r->client_set);
602 		if(r->ns_set != NULL)
603 			rpz_clientip_synthesized_set_delete(r->ns_set);
604 		if(r->taglist)
605 			free(r->taglist);
606 		if(r->region)
607 			regional_destroy(r->region);
608 		free(r);
609 	}
610 	return NULL;
611 }
612 
613 int
614 rpz_config(struct rpz* r, struct config_auth* p)
615 {
616 	/* If the zonefile changes, it is read later, after which
617 	 * rpz_clear and rpz_finish_config is called. */
618 
619 	/* free taglist, if any */
620 	if(r->taglist) {
621 		free(r->taglist);
622 		r->taglist = NULL;
623 		r->taglistlen = 0;
624 	}
625 
626 	/* free logname, if any */
627 	if(r->log_name) {
628 		free(r->log_name);
629 		r->log_name = NULL;
630 	}
631 
632 	delete_cname_override(r);
633 
634 	if(!rpz_apply_cfg_elements(r, p))
635 		return 0;
636 	return 1;
637 }
638 
639 /**
640  * Remove RPZ zone name from dname
641  * Copy dname to newdname, without the originlen number of trailing bytes
642  */
643 static size_t
644 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
645 	uint8_t* newdname, size_t maxnewdnamelen)
646 {
647 	size_t newdnamelen;
648 	if(dnamelen < originlen)
649 		return 0;
650 	newdnamelen = dnamelen - originlen;
651 	if(newdnamelen+1 > maxnewdnamelen)
652 		return 0;
653 	memmove(newdname, dname, newdnamelen);
654 	newdname[newdnamelen] = 0;
655 	return newdnamelen + 1;	/* + 1 for root label */
656 }
657 
658 static void
659 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
660 	size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
661 	uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
662 {
663 	struct local_zone* z;
664 	enum localzone_type tp = local_zone_always_transparent;
665 	int dnamelabs = dname_count_labels(dname);
666 	int newzone = 0;
667 
668 	if(a == RPZ_INVALID_ACTION) {
669 		char str[255+1];
670 		if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS ||
671 			rrtype == LDNS_RR_TYPE_DNAME ||
672 			rrtype == LDNS_RR_TYPE_DNSKEY ||
673 			rrtype == LDNS_RR_TYPE_RRSIG ||
674 			rrtype == LDNS_RR_TYPE_NSEC ||
675 			rrtype == LDNS_RR_TYPE_NSEC3PARAM ||
676 			rrtype == LDNS_RR_TYPE_NSEC3 ||
677 			rrtype == LDNS_RR_TYPE_DS) {
678 			free(dname);
679 			return; /* no need to log these types as unsupported */
680 		}
681 		dname_str(dname, str);
682 		verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s",
683 			str, rpz_action_to_string(a));
684 		free(dname);
685 		return;
686 	}
687 
688 	lock_rw_wrlock(&lz->lock);
689 	/* exact match */
690 	z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
691 	if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
692 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
693 		if(rrstr == NULL) {
694 			log_err("malloc error while inserting rpz nsdname trigger");
695 			free(dname);
696 			lock_rw_unlock(&lz->lock);
697 			return;
698 		}
699 		if(rrstr[0])
700 			rrstr[strlen(rrstr)-1]=0; /* remove newline */
701 		verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
702 		free(rrstr);
703 		free(dname);
704 		lock_rw_unlock(&lz->lock);
705 		return;
706 	}
707 	if(z == NULL) {
708 		tp = rpz_action_to_localzone_type(a);
709 		z = local_zones_add_zone(lz, dname, dnamelen,
710 					 dnamelabs, rrclass, tp);
711 		if(z == NULL) {
712 			log_warn("rpz: create failed");
713 			lock_rw_unlock(&lz->lock);
714 			/* dname will be free'd in failed local_zone_create() */
715 			return;
716 		}
717 		newzone = 1;
718 	}
719 	if(a == RPZ_LOCAL_DATA_ACTION) {
720 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
721 		if(rrstr == NULL) {
722 			log_err("malloc error while inserting rpz nsdname trigger");
723 			free(dname);
724 			lock_rw_unlock(&lz->lock);
725 			return;
726 		}
727 		lock_rw_wrlock(&z->lock);
728 		local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
729 				    rrclass, ttl, rdata, rdata_len, rrstr);
730 		lock_rw_unlock(&z->lock);
731 		free(rrstr);
732 	}
733 	if(!newzone) {
734 		free(dname);
735 	}
736 	lock_rw_unlock(&lz->lock);
737 }
738 
739 static void
740 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
741 {
742 	char buf[LDNS_MAX_DOMAINLEN+1];
743 	(void)dname_len;
744 	dname_str(dname, buf);
745 	verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf);
746 }
747 
748 static void
749 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
750 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
751 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
752 {
753 	if(a == RPZ_INVALID_ACTION) {
754 		verbose(VERB_ALGO, "rpz: skipping invalid action");
755 		free(dname);
756 		return;
757 	}
758 
759 	rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
760 				       rrclass, ttl, rdata, rdata_len, rr, rr_len);
761 }
762 
763 static int
764 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
765 	uint8_t** stripdname, size_t* stripdnamelen)
766 {
767 	uint8_t* tldstart = get_tld_label(dname, maxdnamelen);
768 	uint8_t swap;
769 	if(tldstart == NULL) {
770 		if(dname == NULL) {
771 			*stripdname = NULL;
772 			*stripdnamelen = 0;
773 			return 0;
774 		}
775 		*stripdname = memdup(dname, maxdnamelen);
776 		if(!*stripdname) {
777 			*stripdnamelen = 0;
778 			log_err("malloc failure for rpz strip suffix");
779 			return 0;
780 		}
781 		*stripdnamelen = maxdnamelen;
782 		return 1;
783 	}
784 	/* shorten the domain name briefly,
785 	 * then we allocate a new name with the correct length */
786 	swap = *tldstart;
787 	*tldstart = 0;
788 	(void)dname_count_size_labels(dname, stripdnamelen);
789 	*stripdname = memdup(dname, *stripdnamelen);
790 	*tldstart = swap;
791 	if(!*stripdname) {
792 		*stripdnamelen = 0;
793 		log_err("malloc failure for rpz strip suffix");
794 		return 0;
795 	}
796 	return 1;
797 }
798 
799 static void
800 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
801 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
802 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
803 {
804 	uint8_t* dname_stripped = NULL;
805 	size_t dnamelen_stripped = 0;
806 
807 	rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
808 		&dnamelen_stripped);
809 	if(a == RPZ_INVALID_ACTION) {
810 		verbose(VERB_ALGO, "rpz: skipping invalid action");
811 		free(dname_stripped);
812 		return;
813 	}
814 
815 	/* dname_stripped is consumed or freed by the insert routine */
816 	rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
817 		dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
818 		rr, rr_len);
819 }
820 
821 static int
822 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
823 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
824 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
825 	uint8_t* rr, size_t rr_len)
826 {
827 	struct resp_addr* node;
828 	char* rrstr;
829 	enum respip_action respa = rpz_action_to_respip_action(a);
830 
831 	lock_rw_wrlock(&set->lock);
832 	rrstr = sldns_wire2str_rr(rr, rr_len);
833 	if(rrstr == NULL) {
834 		log_err("malloc error while inserting rpz ipaddr based trigger");
835 		lock_rw_unlock(&set->lock);
836 		return 0;
837 	}
838 
839 	node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
840 	if(node == NULL) {
841 		lock_rw_unlock(&set->lock);
842 		free(rrstr);
843 		return 0;
844 	}
845 
846 	lock_rw_wrlock(&node->lock);
847 	lock_rw_unlock(&set->lock);
848 
849 	node->action = respa;
850 
851 	if(a == RPZ_LOCAL_DATA_ACTION) {
852 		respip_enter_rr(set->region, node, rrtype,
853 				rrclass, ttl, rdata, rdata_len, rrstr, "");
854 	}
855 
856 	lock_rw_unlock(&node->lock);
857 	free(rrstr);
858 	return 1;
859 }
860 
861 static inline struct clientip_synthesized_rr*
862 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
863 	struct sockaddr_storage* addr, socklen_t addrlen, int net)
864 {
865 	int insert_ok;
866 	struct clientip_synthesized_rr* node =
867 		(struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
868 								addr, addrlen, net);
869 
870 	if(node != NULL) { return node; }
871 
872 	/* node does not yet exist => allocate one */
873 	node = regional_alloc_zero(set->region, sizeof(*node));
874 	if(node == NULL) {
875 		log_err("out of memory");
876 		return NULL;
877 	}
878 
879 	lock_rw_init(&node->lock);
880 	node->action = RPZ_INVALID_ACTION;
881 	insert_ok = addr_tree_insert(&set->entries, &node->node,
882 				     addr, addrlen, net);
883 	if (!insert_ok) {
884 		log_warn("rpz: unexpected: unable to insert clientip address node");
885 		/* we can not free the just allocated node.
886 		 * theoretically a memleak */
887 		return NULL;
888 	}
889 
890 	return node;
891 }
892 
893 static void
894 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
895 	char* rrstr = sldns_wire2str_rr(rr, rr_len);
896 	if(rrstr == NULL) {
897 		log_err("malloc error while inserting rpz clientip based record");
898 		return;
899 	}
900 	log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
901 	free(rrstr);
902 }
903 
904 /* from localzone.c; difference is we don't have a dname */
905 static struct local_rrset*
906 rpz_clientip_new_rrset(struct regional* region,
907 	struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass)
908 {
909 	struct packed_rrset_data* pd;
910 	struct local_rrset* rrset = (struct local_rrset*)
911 		regional_alloc_zero(region, sizeof(*rrset));
912 	if(rrset == NULL) {
913 		log_err("out of memory");
914 		return NULL;
915 	}
916 	rrset->next = raddr->data;
917 	raddr->data = rrset;
918 	rrset->rrset = (struct ub_packed_rrset_key*)
919 		regional_alloc_zero(region, sizeof(*rrset->rrset));
920 	if(rrset->rrset == NULL) {
921 		log_err("out of memory");
922 		return NULL;
923 	}
924 	rrset->rrset->entry.key = rrset->rrset;
925 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
926 	if(pd == NULL) {
927 		log_err("out of memory");
928 		return NULL;
929 	}
930 	pd->trust = rrset_trust_prim_noglue;
931 	pd->security = sec_status_insecure;
932 	rrset->rrset->entry.data = pd;
933 	rrset->rrset->rk.type = htons(rrtype);
934 	rrset->rrset->rk.rrset_class = htons(rrclass);
935 	rrset->rrset->rk.dname = regional_alloc_zero(region, 1);
936 	if(rrset->rrset->rk.dname == NULL) {
937 		log_err("out of memory");
938 		return NULL;
939 	}
940 	rrset->rrset->rk.dname_len = 1;
941 	return rrset;
942 }
943 
944 static int
945 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr,
946 	uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
947 	size_t rdata_len)
948 {
949 	struct local_rrset* rrset;
950 	if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) {
951 		log_err("CNAME response-ip data can not co-exist with other "
952 			"client-ip data");
953 		return 0;
954 	}
955 
956 	rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass);
957 	if(raddr->data == NULL) {
958 		return 0;
959 	}
960 
961 	return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
962 }
963 
964 static int
965 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
966 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
967 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
968 	uint8_t* rr, size_t rr_len)
969 {
970 	struct clientip_synthesized_rr* node;
971 
972 	lock_rw_wrlock(&set->lock);
973 
974 	node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
975 	if(node == NULL) {
976 		lock_rw_unlock(&set->lock);
977 		rpz_report_rrset_error("client ip address", rr, rr_len);
978 		return 0;
979 	}
980 
981 	lock_rw_wrlock(&node->lock);
982 	lock_rw_unlock(&set->lock);
983 
984 	node->action = a;
985 	if(a == RPZ_LOCAL_DATA_ACTION) {
986 		if(!rpz_clientip_enter_rr(set->region, node, rrtype,
987 			rrclass, ttl, rdata, rdata_len)) {
988 			verbose(VERB_ALGO, "rpz: unable to insert clientip rr");
989 			lock_rw_unlock(&node->lock);
990 			return 0;
991 		}
992 
993 	}
994 
995 	lock_rw_unlock(&node->lock);
996 
997 	return 1;
998 }
999 
1000 static int
1001 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1002 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
1003 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
1004 {
1005 	struct sockaddr_storage addr;
1006 	socklen_t addrlen;
1007 	int net, af;
1008 
1009 	if(a == RPZ_INVALID_ACTION) {
1010 		return 0;
1011 	}
1012 
1013 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1014 		verbose(VERB_ALGO, "rpz: unable to parse client ip");
1015 		return 0;
1016 	}
1017 
1018 	return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
1019 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1020 }
1021 
1022 static int
1023 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1024 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
1025 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
1026 {
1027 	struct sockaddr_storage addr;
1028 	socklen_t addrlen;
1029 	int net, af;
1030 
1031 	if(a == RPZ_INVALID_ACTION) {
1032 		return 0;
1033 	}
1034 
1035 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1036 		verbose(VERB_ALGO, "rpz: unable to parse ns ip");
1037 		return 0;
1038 	}
1039 
1040 	return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
1041 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1042 }
1043 
1044 /** Insert RR into RPZ's respip_set */
1045 static int
1046 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1047 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
1048 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
1049 {
1050 	struct sockaddr_storage addr;
1051 	socklen_t addrlen;
1052 	int net, af;
1053 
1054 	if(a == RPZ_INVALID_ACTION) {
1055 		return 0;
1056 	}
1057 
1058 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
1059 		verbose(VERB_ALGO, "rpz: unable to parse response ip");
1060 		return 0;
1061 	}
1062 
1063 	if(a == RPZ_INVALID_ACTION ||
1064 		rpz_action_to_respip_action(a) == respip_invalid) {
1065 		char str[255+1];
1066 		dname_str(dname, str);
1067 		verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s",
1068 			str, rpz_action_to_string(a));
1069 		return 0;
1070 	}
1071 
1072 	return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
1073 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1074 }
1075 
1076 int
1077 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
1078 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
1079 	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
1080 {
1081 	size_t policydnamelen;
1082 	/* name is free'd in local_zone delete */
1083 	enum rpz_trigger t;
1084 	enum rpz_action a;
1085 	uint8_t* policydname;
1086 
1087 	if(rpz_type_ignored(rr_type)) {
1088 		/* this rpz action is not valid, eg. this is the SOA or NS RR */
1089 		return 1;
1090 	}
1091 	if(!dname_subdomain_c(dname, azname)) {
1092 		char* dname_str = sldns_wire2str_dname(dname, dnamelen);
1093 		char* azname_str = sldns_wire2str_dname(azname, aznamelen);
1094 		if(dname_str && azname_str) {
1095 			log_err("rpz: name of record (%s) to insert into RPZ is not a "
1096 				"subdomain of the configured name of the RPZ zone (%s)",
1097 				dname_str, azname_str);
1098 		} else {
1099 			log_err("rpz: name of record to insert into RPZ is not a "
1100 				"subdomain of the configured name of the RPZ zone");
1101 		}
1102 		free(dname_str);
1103 		free(azname_str);
1104 		return 0;
1105 	}
1106 
1107 	log_assert(dnamelen >= aznamelen);
1108 	if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) {
1109 		log_err("malloc error while inserting RPZ RR");
1110 		return 0;
1111 	}
1112 
1113 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1114 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1115 		policydname, (dnamelen-aznamelen)+1))) {
1116 		free(policydname);
1117 		return 0;
1118 	}
1119 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1120 	if(t == RPZ_INVALID_TRIGGER) {
1121 		free(policydname);
1122 		verbose(VERB_ALGO, "rpz: skipping invalid trigger");
1123 		return 1;
1124 	}
1125 	if(t == RPZ_QNAME_TRIGGER) {
1126 		/* policydname will be consumed, no free */
1127 		rpz_insert_qname_trigger(r, policydname, policydnamelen,
1128 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1129 			rr_len);
1130 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1131 		rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
1132 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1133 			rr_len);
1134 		free(policydname);
1135 	} else if(t == RPZ_CLIENT_IP_TRIGGER) {
1136 		rpz_insert_clientip_trigger(r, policydname, policydnamelen,
1137 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1138 			rr_len);
1139 		free(policydname);
1140 	} else if(t == RPZ_NSIP_TRIGGER) {
1141 		rpz_insert_nsip_trigger(r, policydname, policydnamelen,
1142 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1143 			rr_len);
1144 		free(policydname);
1145 	} else if(t == RPZ_NSDNAME_TRIGGER) {
1146 		rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
1147 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1148 			rr_len);
1149 		free(policydname);
1150 	} else {
1151 		free(policydname);
1152 		verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s",
1153 			rpz_trigger_to_string(t));
1154 	}
1155 	return 1;
1156 }
1157 
1158 /**
1159  * Find RPZ local-zone by qname.
1160  * @param zones: local-zone tree
1161  * @param qname: qname
1162  * @param qname_len: length of qname
1163  * @param qclass: qclass
1164  * @param only_exact: if 1 only exact (non wildcard) matches are returned
1165  * @param wr: get write lock for local-zone if 1, read lock if 0
1166  * @param zones_keep_lock: if set do not release the r->local_zones lock, this
1167  * 	  makes the caller of this function responsible for releasing the lock.
1168  * @return: NULL or local-zone holding rd or wr lock
1169  */
1170 static struct local_zone*
1171 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass,
1172 	int only_exact, int wr, int zones_keep_lock)
1173 {
1174 	uint8_t* ce;
1175 	size_t ce_len;
1176 	int ce_labs;
1177 	uint8_t wc[LDNS_MAX_DOMAINLEN+1];
1178 	int exact;
1179 	struct local_zone* z = NULL;
1180 
1181 	if(wr) {
1182 		lock_rw_wrlock(&zones->lock);
1183 	} else {
1184 		lock_rw_rdlock(&zones->lock);
1185 	}
1186 	z = local_zones_find_le(zones, qname, qname_len,
1187 		dname_count_labels(qname),
1188 		LDNS_RR_CLASS_IN, &exact);
1189 	if(!z || (only_exact && !exact)) {
1190 		if(!zones_keep_lock) {
1191 			lock_rw_unlock(&zones->lock);
1192 		}
1193 		return NULL;
1194 	}
1195 	if(wr) {
1196 		lock_rw_wrlock(&z->lock);
1197 	} else {
1198 		lock_rw_rdlock(&z->lock);
1199 	}
1200 	if(!zones_keep_lock) {
1201 		lock_rw_unlock(&zones->lock);
1202 	}
1203 
1204 	if(exact)
1205 		return z;
1206 
1207 	/* No exact match found, lookup wildcard. closest encloser must
1208 	 * be the shared parent between the qname and the best local
1209 	 * zone match, append '*' to that and do another lookup. */
1210 
1211 	ce = dname_get_shared_topdomain(z->name, qname);
1212 	if(!ce /* should not happen */) {
1213 		lock_rw_unlock(&z->lock);
1214 		if(zones_keep_lock) {
1215 			lock_rw_unlock(&zones->lock);
1216 		}
1217 		return NULL;
1218 	}
1219 	ce_labs = dname_count_size_labels(ce, &ce_len);
1220 	if(ce_len+2 > sizeof(wc)) {
1221 		lock_rw_unlock(&z->lock);
1222 		if(zones_keep_lock) {
1223 			lock_rw_unlock(&zones->lock);
1224 		}
1225 		return NULL;
1226 	}
1227 	wc[0] = 1; /* length of wildcard label */
1228 	wc[1] = (uint8_t)'*'; /* wildcard label */
1229 	memmove(wc+2, ce, ce_len);
1230 	lock_rw_unlock(&z->lock);
1231 
1232 	if(!zones_keep_lock) {
1233 		if(wr) {
1234 			lock_rw_wrlock(&zones->lock);
1235 		} else {
1236 			lock_rw_rdlock(&zones->lock);
1237 		}
1238 	}
1239 	z = local_zones_find_le(zones, wc,
1240 		ce_len+2, ce_labs+1, qclass, &exact);
1241 	if(!z || !exact) {
1242 		lock_rw_unlock(&zones->lock);
1243 		return NULL;
1244 	}
1245 	if(wr) {
1246 		lock_rw_wrlock(&z->lock);
1247 	} else {
1248 		lock_rw_rdlock(&z->lock);
1249 	}
1250 	if(!zones_keep_lock) {
1251 		lock_rw_unlock(&zones->lock);
1252 	}
1253 	return z;
1254 }
1255 
1256 /** Find entry for RR type in the list of rrsets for the clientip. */
1257 static struct local_rrset*
1258 rpz_find_synthesized_rrset(uint16_t qtype,
1259 	struct clientip_synthesized_rr* data, int alias_ok)
1260 {
1261 	struct local_rrset* cursor = data->data, *cname = NULL;
1262 	while( cursor != NULL) {
1263 		struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
1264 		if(htons(qtype) == packed_rrset->type) {
1265 			return cursor;
1266 		}
1267 		if(ntohs(packed_rrset->type) == LDNS_RR_TYPE_CNAME && alias_ok)
1268 			cname = cursor;
1269 		cursor = cursor->next;
1270 	}
1271 	if(alias_ok)
1272 		return cname;
1273 	return NULL;
1274 }
1275 
1276 /**
1277  * Remove RR from RPZ's local-data
1278  * @param z: local-zone for RPZ, holding write lock
1279  * @param policydname: dname of RR to remove
1280  * @param policydnamelen: length of policydname
1281  * @param rr_type: RR type of RR to remove
1282  * @param rdata: rdata of RR to remove
1283  * @param rdatalen: length of rdata
1284  * @return: 1 if zone must be removed after RR deletion
1285  */
1286 static int
1287 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
1288 	size_t policydnamelen, uint16_t rr_type, uint8_t* rdata,
1289 	size_t rdatalen)
1290 {
1291 	struct local_data* ld;
1292 	struct packed_rrset_data* d;
1293 	size_t index;
1294 	ld = local_zone_find_data(z, policydname, policydnamelen,
1295 		dname_count_labels(policydname));
1296 	if(ld) {
1297 		struct local_rrset* prev=NULL, *p=ld->rrsets;
1298 		while(p && ntohs(p->rrset->rk.type) != rr_type) {
1299 			prev = p;
1300 			p = p->next;
1301 		}
1302 		if(!p)
1303 			return 0;
1304 		d = (struct packed_rrset_data*)p->rrset->entry.data;
1305 		if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1306 			if(d->count == 1) {
1307 				/* no memory recycling for zone deletions ... */
1308 				if(prev) prev->next = p->next;
1309 				else ld->rrsets = p->next;
1310 			}
1311 			if(d->count > 1) {
1312 				if(!local_rrset_remove_rr(d, index))
1313 					return 0;
1314 			}
1315 		}
1316 	}
1317 	if(ld && ld->rrsets)
1318 		return 0;
1319 	return 1;
1320 }
1321 
1322 /**
1323  * Remove RR from RPZ's respip set
1324  * @param raddr: respip node
1325  * @param rr_type: RR type of RR to remove
1326  * @param rdata: rdata of RR to remove
1327  * @param rdatalen: length of rdata
1328  * @return: 1 if zone must be removed after RR deletion
1329  */
1330 static int
1331 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
1332 	size_t rdatalen)
1333 {
1334 	size_t index;
1335 	struct packed_rrset_data* d;
1336 	if(!raddr->data)
1337 		return 1;
1338 	d = raddr->data->entry.data;
1339 	if(ntohs(raddr->data->rk.type) != rr_type) {
1340 		return 0;
1341 	}
1342 	if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1343 		if(d->count == 1) {
1344 			/* regional alloc'd */
1345 			raddr->data->entry.data = NULL;
1346 			raddr->data = NULL;
1347 			return 1;
1348 		}
1349 		if(d->count > 1) {
1350 			if(!local_rrset_remove_rr(d, index))
1351 				return 0;
1352 		}
1353 	}
1354 	return 0;
1355 
1356 }
1357 
1358 /** Remove RR from rpz localzones structure */
1359 static void
1360 rpz_remove_local_zones_trigger(struct local_zones* zones, uint8_t* dname,
1361 	size_t dnamelen, enum rpz_action a, uint16_t rr_type,
1362 	uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
1363 {
1364 	struct local_zone* z;
1365 	int delete_zone = 1;
1366 	z = rpz_find_zone(zones, dname, dnamelen, rr_class,
1367 		1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/);
1368 	if(!z) {
1369 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1370 			"RPZ domain not found");
1371 		return;
1372 	}
1373 	if(a == RPZ_LOCAL_DATA_ACTION)
1374 		delete_zone = rpz_data_delete_rr(z, dname,
1375 			dnamelen, rr_type, rdatawl, rdatalen);
1376 	else if(a != localzone_type_to_rpz_action(z->type)) {
1377 		lock_rw_unlock(&z->lock);
1378 		lock_rw_unlock(&zones->lock);
1379 		return;
1380 	}
1381 	lock_rw_unlock(&z->lock);
1382 	if(delete_zone) {
1383 		local_zones_del_zone(zones, z);
1384 	}
1385 	lock_rw_unlock(&zones->lock);
1386 }
1387 
1388 /** Remove RR from RPZ's local-zone */
1389 static void
1390 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1391 	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
1392 	uint8_t* rdatawl, size_t rdatalen)
1393 {
1394 	rpz_remove_local_zones_trigger(r->local_zones, dname, dnamelen,
1395 		a, rr_type, rr_class, rdatawl, rdatalen);
1396 }
1397 
1398 static void
1399 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1400 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1401 {
1402 	struct resp_addr* node;
1403 	struct sockaddr_storage addr;
1404 	socklen_t addrlen;
1405 	int net, af;
1406 	int delete_respip = 1;
1407 
1408 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1409 		return;
1410 
1411 	lock_rw_wrlock(&r->respip_set->lock);
1412 	if(!(node = (struct resp_addr*)addr_tree_find(
1413 		&r->respip_set->ip_tree, &addr, addrlen, net))) {
1414 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1415 			"RPZ domain not found");
1416 		lock_rw_unlock(&r->respip_set->lock);
1417 		return;
1418 	}
1419 
1420 	lock_rw_wrlock(&node->lock);
1421 	if(a == RPZ_LOCAL_DATA_ACTION) {
1422 		/* remove RR, signal whether RR can be removed */
1423 		delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
1424 			rdatalen);
1425 	}
1426 	lock_rw_unlock(&node->lock);
1427 	if(delete_respip)
1428 		respip_sockaddr_delete(r->respip_set, node);
1429 	lock_rw_unlock(&r->respip_set->lock);
1430 }
1431 
1432 /** find and remove type from list of local_rrset entries*/
1433 static void
1434 del_local_rrset_from_list(struct local_rrset** list_head, uint16_t dtype)
1435 {
1436 	struct local_rrset* prev=NULL, *p=*list_head;
1437 	while(p && ntohs(p->rrset->rk.type) != dtype) {
1438 		prev = p;
1439 		p = p->next;
1440 	}
1441 	if(!p)
1442 		return; /* rrset type not found */
1443 	/* unlink it */
1444 	if(prev) prev->next = p->next;
1445 	else *list_head = p->next;
1446 	/* no memory recycling for zone deletions ... */
1447 }
1448 
1449 /** Delete client-ip trigger RR from its RRset and perhaps also the rrset
1450  * from the linked list. Returns if the local data is empty and the node can
1451  * be deleted too, or not. */
1452 static int rpz_remove_clientip_rr(struct clientip_synthesized_rr* node,
1453 	uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1454 {
1455 	struct local_rrset* rrset;
1456 	struct packed_rrset_data* d;
1457 	size_t index;
1458 	rrset = rpz_find_synthesized_rrset(rr_type, node, 0);
1459 	if(rrset == NULL)
1460 		return 0; /* type not found, ignore */
1461 	d = (struct packed_rrset_data*)rrset->rrset->entry.data;
1462 	if(!packed_rrset_find_rr(d, rdatawl, rdatalen, &index))
1463 		return 0; /* RR not found, ignore */
1464 	if(d->count == 1) {
1465 		/* regional alloc'd */
1466 		/* delete the type entry from the list */
1467 		del_local_rrset_from_list(&node->data, rr_type);
1468 		/* if the list is empty, the node can be removed too */
1469 		if(node->data == NULL)
1470 			return 1;
1471 	} else if (d->count > 1) {
1472 		if(!local_rrset_remove_rr(d, index))
1473 			return 0;
1474 	}
1475 	return 0;
1476 }
1477 
1478 /** remove trigger RR from clientip_syntheized set tree. */
1479 static void
1480 rpz_clientip_remove_trigger_rr(struct clientip_synthesized_rrset* set,
1481 	struct sockaddr_storage* addr, socklen_t addrlen, int net,
1482 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1483 {
1484 	struct clientip_synthesized_rr* node;
1485 	int delete_node = 1;
1486 
1487 	lock_rw_wrlock(&set->lock);
1488 	node = (struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
1489 		addr, addrlen, net);
1490 	if(node == NULL) {
1491 		/* netblock not found */
1492 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1493 			"RPZ address, netblock not found");
1494 		lock_rw_unlock(&set->lock);
1495 		return;
1496 	}
1497 	lock_rw_wrlock(&node->lock);
1498 	if(a == RPZ_LOCAL_DATA_ACTION) {
1499 		/* remove RR, signal whether entry can be removed */
1500 		delete_node = rpz_remove_clientip_rr(node, rr_type, rdatawl,
1501 			rdatalen);
1502 	} else if(a != node->action) {
1503 		/* ignore the RR with different action specification */
1504 		delete_node = 0;
1505 	}
1506 	if(delete_node) {
1507 		rbtree_delete(&set->entries, node->node.node.key);
1508 	}
1509 	lock_rw_unlock(&set->lock);
1510 	lock_rw_unlock(&node->lock);
1511 	if(delete_node) {
1512 		lock_rw_destroy(&node->lock);
1513 	}
1514 }
1515 
1516 /** Remove clientip trigger RR from RPZ. */
1517 static void
1518 rpz_remove_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1519 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1520 {
1521 	struct sockaddr_storage addr;
1522 	socklen_t addrlen;
1523 	int net, af;
1524 	if(a == RPZ_INVALID_ACTION)
1525 		return;
1526 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1527 		return;
1528 	rpz_clientip_remove_trigger_rr(r->client_set, &addr, addrlen, net,
1529 		a, rr_type, rdatawl, rdatalen);
1530 }
1531 
1532 /** Remove nsip trigger RR from RPZ. */
1533 static void
1534 rpz_remove_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1535 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1536 {
1537 	struct sockaddr_storage addr;
1538 	socklen_t addrlen;
1539 	int net, af;
1540 	if(a == RPZ_INVALID_ACTION)
1541 		return;
1542 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1543 		return;
1544 	rpz_clientip_remove_trigger_rr(r->ns_set, &addr, addrlen, net,
1545 		a, rr_type, rdatawl, rdatalen);
1546 }
1547 
1548 /** Remove nsdname trigger RR from RPZ. */
1549 static void
1550 rpz_remove_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1551 	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
1552 	uint8_t* rdatawl, size_t rdatalen)
1553 {
1554 	uint8_t* dname_stripped = NULL;
1555 	size_t dnamelen_stripped = 0;
1556 	if(a == RPZ_INVALID_ACTION)
1557 		return;
1558 	if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
1559 		&dnamelen_stripped))
1560 		return;
1561 	rpz_remove_local_zones_trigger(r->nsdname_zones, dname_stripped,
1562 		dnamelen_stripped, a, rr_type, rr_class, rdatawl, rdatalen);
1563 	free(dname_stripped);
1564 }
1565 
1566 void
1567 rpz_remove_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
1568 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
1569 	size_t rdatalen)
1570 {
1571 	size_t policydnamelen;
1572 	enum rpz_trigger t;
1573 	enum rpz_action a;
1574 	uint8_t* policydname;
1575 
1576 	if(rpz_type_ignored(rr_type)) {
1577 		/* this rpz action is not valid, eg. this is the SOA or NS RR */
1578 		return;
1579 	}
1580 	if(!dname_subdomain_c(dname, azname)) {
1581 		/* not subdomain of the RPZ zone. */
1582 		return;
1583 	}
1584 
1585 	if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
1586 		return;
1587 
1588 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1589 	if(a == RPZ_INVALID_ACTION) {
1590 		free(policydname);
1591 		return;
1592 	}
1593 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1594 		policydname, LDNS_MAX_DOMAINLEN + 1))) {
1595 		free(policydname);
1596 		return;
1597 	}
1598 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1599 	if(t == RPZ_INVALID_TRIGGER) {
1600 		/* skipping invalid trigger */
1601 		free(policydname);
1602 		return;
1603 	}
1604 	if(t == RPZ_QNAME_TRIGGER) {
1605 		rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
1606 			rr_type, rr_class, rdatawl, rdatalen);
1607 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1608 		rpz_remove_response_ip_trigger(r, policydname, policydnamelen,
1609 			a, rr_type, rdatawl, rdatalen);
1610 	} else if(t == RPZ_CLIENT_IP_TRIGGER) {
1611 		rpz_remove_clientip_trigger(r, policydname, policydnamelen, a,
1612 			rr_type, rdatawl, rdatalen);
1613 	} else if(t == RPZ_NSIP_TRIGGER) {
1614 		rpz_remove_nsip_trigger(r, policydname, policydnamelen, a,
1615 			rr_type, rdatawl, rdatalen);
1616 	} else if(t == RPZ_NSDNAME_TRIGGER) {
1617 		rpz_remove_nsdname_trigger(r, policydname, policydnamelen, a,
1618 			rr_type, rr_class, rdatawl, rdatalen);
1619 	}
1620 	/* else it was an unsupported trigger, also skipped. */
1621 	free(policydname);
1622 }
1623 
1624 /** print log information for an applied RPZ policy. Based on local-zone's
1625  * lz_inform_print().
1626  * The repinfo contains the reply address. If it is NULL, the module
1627  * state is used to report the first IP address (if any).
1628  * The dname is used, for the applied rpz, if NULL, addrnode is used.
1629  */
1630 static void
1631 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
1632 	enum rpz_action a, struct query_info* qinfo,
1633 	struct comm_reply* repinfo, struct module_qstate* ms, char* log_name)
1634 {
1635 	char ip[128], txt[512], portstr[32];
1636 	char dnamestr[LDNS_MAX_DOMAINLEN+1];
1637 	uint16_t port = 0;
1638 	if(dname) {
1639 		dname_str(dname, dnamestr);
1640 	} else if(addrnode) {
1641 		char addrbuf[128];
1642 		addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf));
1643 		snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net);
1644 	} else {
1645 		dnamestr[0]=0;
1646 	}
1647 	if(repinfo) {
1648 		addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip));
1649 		port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port);
1650 	} else if(ms && ms->mesh_info && ms->mesh_info->reply_list) {
1651 		addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr,
1652 			ms->mesh_info->reply_list->query_reply.client_addrlen,
1653 			ip, sizeof(ip));
1654 		port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port);
1655 	} else {
1656 		ip[0]=0;
1657 		port = 0;
1658 	}
1659 	snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port);
1660 	snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s",
1661 		(log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""),
1662 		(strcmp(trigger,"qname")==0?"":trigger),
1663 		(strcmp(trigger,"qname")==0?"":" "),
1664 		dnamestr, rpz_action_to_string(a),
1665 		(ip[0]?ip:""), (ip[0]?portstr:""));
1666 	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
1667 }
1668 
1669 static struct clientip_synthesized_rr*
1670 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set,
1671 	struct sockaddr_storage* addr, socklen_t addrlen, char* triggername)
1672 {
1673 	struct clientip_synthesized_rr* raddr = NULL;
1674 	enum rpz_action action = RPZ_INVALID_ACTION;
1675 
1676 	lock_rw_rdlock(&set->lock);
1677 
1678 	raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries,
1679 			addr, addrlen);
1680 	if(raddr != NULL) {
1681 		lock_rw_rdlock(&raddr->lock);
1682 		action = raddr->action;
1683 		if(verbosity >= VERB_ALGO) {
1684 			char ip[256], net[256];
1685 			addr_to_str(addr, addrlen, ip, sizeof(ip));
1686 			addr_to_str(&raddr->node.addr, raddr->node.addrlen,
1687 				net, sizeof(net));
1688 			verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s",
1689 				triggername, net, raddr->node.net, ip, rpz_action_to_string(action));
1690 		}
1691 	}
1692 	lock_rw_unlock(&set->lock);
1693 
1694 	return raddr;
1695 }
1696 
1697 static inline
1698 struct clientip_synthesized_rr*
1699 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo,
1700 	struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
1701 	struct ub_server_stats* stats,
1702 	/* output parameters */
1703 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out)
1704 {
1705 	struct clientip_synthesized_rr* node = NULL;
1706 	struct auth_zone* a = NULL;
1707 	struct rpz* r = NULL;
1708 	struct local_zone* z = NULL;
1709 
1710 	lock_rw_rdlock(&az->rpz_lock);
1711 
1712 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
1713 		lock_rw_rdlock(&a->lock);
1714 		r = a->rpz;
1715 		if(r->disabled) {
1716 			lock_rw_unlock(&a->lock);
1717 			continue;
1718 		}
1719 		if(r->taglist && !taglist_intersect(r->taglist,
1720 					r->taglistlen, taglist, taglen)) {
1721 			lock_rw_unlock(&a->lock);
1722 			continue;
1723 		}
1724 		z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len,
1725 			qinfo->qclass, 0, 0, 0);
1726 		node = rpz_ipbased_trigger_lookup(r->client_set,
1727 			&repinfo->client_addr, repinfo->client_addrlen,
1728 			"clientip");
1729 		if((z || node) && r->action_override == RPZ_DISABLED_ACTION) {
1730 			if(r->log)
1731 				log_rpz_apply((node?"clientip":"qname"),
1732 					(z?z->name:NULL),
1733 					(node?&node->node:NULL),
1734 					r->action_override,
1735 					qinfo, repinfo, NULL, r->log_name);
1736 			stats->rpz_action[r->action_override]++;
1737 			if(z != NULL) {
1738 				lock_rw_unlock(&z->lock);
1739 				z = NULL;
1740 			}
1741 			if(node != NULL) {
1742 				lock_rw_unlock(&node->lock);
1743 				node = NULL;
1744 			}
1745 		}
1746 		if(z || node) {
1747 			break;
1748 		}
1749 		/* not found in this auth_zone */
1750 		lock_rw_unlock(&a->lock);
1751 	}
1752 
1753 	lock_rw_unlock(&az->rpz_lock);
1754 
1755 	*r_out = r;
1756 	*a_out = a;
1757 	*z_out = z;
1758 
1759 	return node;
1760 }
1761 
1762 static inline int
1763 rpz_is_udp_query(struct comm_reply* repinfo) {
1764 	return repinfo != NULL
1765 			? (repinfo->c != NULL
1766 				? repinfo->c->type == comm_udp
1767 				: 0)
1768 			: 0;
1769 }
1770 
1771 /** encode answer consisting of 1 rrset */
1772 static int
1773 rpz_local_encode(struct module_env* env, struct query_info* qinfo,
1774 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1775 	struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
1776 	int rcode, struct ub_packed_rrset_key* soa_rrset)
1777 {
1778 	struct reply_info rep;
1779 	uint16_t udpsize;
1780 	struct ub_packed_rrset_key* rrsetlist[3];
1781 
1782 	memset(&rep, 0, sizeof(rep));
1783 	rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
1784 	rep.qdcount = 1;
1785 	rep.rrset_count = ansec;
1786 	rep.rrsets = rrsetlist;
1787 	if(ansec > 0) {
1788 		rep.an_numrrsets = 1;
1789 		rep.rrsets[0] = rrset;
1790 		rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0];
1791 	}
1792 	if(soa_rrset != NULL) {
1793 		rep.ar_numrrsets = 1;
1794 		rep.rrsets[rep.rrset_count] = soa_rrset;
1795 		rep.rrset_count ++;
1796 		if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) {
1797 			rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0];
1798 		}
1799 	}
1800 
1801 	udpsize = edns->udp_size;
1802 	edns->edns_version = EDNS_ADVERTISED_VERSION;
1803 	edns->udp_size = EDNS_ADVERTISED_SIZE;
1804 	edns->ext_rcode = 0;
1805 	edns->bits &= EDNS_DO;
1806 	if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
1807 		repinfo, temp, env->now_tv) ||
1808 	  !reply_info_answer_encode(qinfo, &rep,
1809 		*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
1810 		buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
1811 		error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
1812 			*(uint16_t*)sldns_buffer_begin(buf),
1813 			sldns_buffer_read_u16_at(buf, 2), edns);
1814 	}
1815 
1816 	return 1;
1817 }
1818 
1819 /** allocate SOA record ubrrsetkey in region */
1820 static struct ub_packed_rrset_key*
1821 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa,
1822 	struct regional* temp)
1823 {
1824 	struct ub_packed_rrset_key csoa;
1825 	if(!soa)
1826 		return NULL;
1827 	memset(&csoa, 0, sizeof(csoa));
1828 	csoa.entry.key = &csoa;
1829 	csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN);
1830 	csoa.rk.type = htons(LDNS_RR_TYPE_SOA);
1831 	csoa.rk.flags |= PACKED_RRSET_FIXEDTTL
1832 		| PACKED_RRSET_RPZ;
1833 	csoa.rk.dname = auth_zone->name;
1834 	csoa.rk.dname_len = auth_zone->namelen;
1835 	csoa.entry.hash = rrset_key_hash(&csoa.rk);
1836 	csoa.entry.data = soa->data;
1837 	return respip_copy_rrset(&csoa, temp);
1838 }
1839 
1840 static void
1841 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr,
1842 	struct module_env* env, struct query_info* qinfo,
1843 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1844 	struct regional* temp, struct auth_zone* auth_zone)
1845 {
1846 	struct local_rrset* rrset;
1847 	enum rpz_action action = RPZ_INVALID_ACTION;
1848 	struct ub_packed_rrset_key* rp = NULL;
1849 	struct ub_packed_rrset_key* rsoa = NULL;
1850 	int rcode = LDNS_RCODE_NOERROR|BIT_AA;
1851 	int rrset_count = 1;
1852 
1853 	/* prepare synthesized answer for client */
1854 	action = raddr->action;
1855 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) {
1856 		verbose(VERB_ALGO, "rpz: bug: local-data action but no local data");
1857 		return;
1858 	}
1859 
1860 	/* check query type / rr type */
1861 	rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr, 1);
1862 	if(rrset == NULL) {
1863 		verbose(VERB_ALGO, "rpz: unable to find local-data for query");
1864 		rrset_count = 0;
1865 		goto nodata;
1866 	}
1867 
1868 	rp = respip_copy_rrset(rrset->rrset, temp);
1869 	if(!rp) {
1870 		verbose(VERB_ALGO, "rpz: local data action: out of memory");
1871 		return;
1872 	}
1873 
1874 	rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ;
1875 	rp->rk.dname = qinfo->qname;
1876 	rp->rk.dname_len = qinfo->qname_len;
1877 	rp->entry.hash = rrset_key_hash(&rp->rk);
1878 nodata:
1879 	if(auth_zone) {
1880 		struct auth_rrset* soa = NULL;
1881 		soa = auth_zone_get_soa_rrset(auth_zone);
1882 		if(soa) {
1883 			rsoa = make_soa_ubrrset(auth_zone, soa, temp);
1884 			if(!rsoa) {
1885 				verbose(VERB_ALGO, "rpz: local data action soa: out of memory");
1886 				return;
1887 			}
1888 		}
1889 	}
1890 
1891 	rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp,
1892 		rrset_count, rcode, rsoa);
1893 }
1894 
1895 /** Apply the cname override action, during worker request callback.
1896  * false on failure. */
1897 static int
1898 rpz_apply_cname_override_action(struct rpz* r,
1899 	struct query_info* qinfo, struct regional* temp)
1900 {
1901 	if(!r)
1902 		return 0;
1903 	qinfo->local_alias = regional_alloc_zero(temp,
1904 		sizeof(struct local_rrset));
1905 	if(qinfo->local_alias == NULL)
1906 		return 0; /* out of memory */
1907 	qinfo->local_alias->rrset = respip_copy_rrset(r->cname_override, temp);
1908 	if(qinfo->local_alias->rrset == NULL) {
1909 		qinfo->local_alias = NULL;
1910 		return 0; /* out of memory */
1911 	}
1912 	qinfo->local_alias->rrset->rk.dname = qinfo->qname;
1913 	qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
1914 	return 1;
1915 }
1916 
1917 /** add additional section SOA record to the reply.
1918  * Since this gets fed into the normal iterator answer creation, it
1919  * gets minimal-responses applied to it, that can remove the additional SOA
1920  * again. */
1921 static int
1922 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms,
1923 	struct auth_zone* az)
1924 {
1925 	struct auth_rrset* soa = NULL;
1926 	struct ub_packed_rrset_key* rsoa = NULL;
1927 	struct ub_packed_rrset_key** prevrrsets;
1928 	if(!az) return 1;
1929 	soa = auth_zone_get_soa_rrset(az);
1930 	if(!soa) return 1;
1931 	if(!rep) return 0;
1932 	rsoa = make_soa_ubrrset(az, soa, ms->region);
1933 	if(!rsoa) return 0;
1934 	prevrrsets = rep->rrsets;
1935 	rep->rrsets = regional_alloc_zero(ms->region,
1936 		sizeof(*rep->rrsets)*(rep->rrset_count+1));
1937 	if(!rep->rrsets)
1938 		return 0;
1939 	if(prevrrsets && rep->rrset_count > 0)
1940 		memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets));
1941 	rep->rrset_count++;
1942 	rep->ar_numrrsets++;
1943 	rep->rrsets[rep->rrset_count-1] = rsoa;
1944 	return 1;
1945 }
1946 
1947 static inline struct dns_msg*
1948 rpz_dns_msg_new(struct regional* region)
1949 {
1950 	struct dns_msg* msg =
1951 			(struct dns_msg*)regional_alloc(region,
1952 							sizeof(struct dns_msg));
1953 	if(msg == NULL) { return NULL; }
1954 	memset(msg, 0, sizeof(struct dns_msg));
1955 
1956 	return msg;
1957 }
1958 
1959 static inline struct dns_msg*
1960 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
1961 	struct query_info* qinfo, struct auth_zone* az)
1962 {
1963 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1964 	if(msg == NULL) { return msg; }
1965 	msg->qinfo = *qinfo;
1966 	msg->rep = construct_reply_info_base(ms->region,
1967 					     LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1968 					     1, /* qd */
1969 					     0, /* ttl */
1970 					     0, /* prettl */
1971 					     0, /* expttl */
1972 					     0, /* an */
1973 					     0, /* ns */
1974 					     0, /* ar */
1975 					     0, /* total */
1976 					     sec_status_insecure,
1977 					     LDNS_EDE_NONE);
1978 	if(msg->rep)
1979 		msg->rep->authoritative = 1;
1980 	if(!rpz_add_soa(msg->rep, ms, az))
1981 		return NULL;
1982 	return msg;
1983 }
1984 
1985 static inline struct dns_msg*
1986 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
1987 	struct query_info* qinfo, struct auth_zone* az)
1988 {
1989 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1990 	uint16_t flags;
1991 	if(msg == NULL) { return msg; }
1992 	msg->qinfo = *qinfo;
1993 	flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA;
1994 	if(r->signal_nxdomain_ra)
1995 		flags &= ~BIT_RA;
1996 	msg->rep = construct_reply_info_base(ms->region,
1997 					     flags,
1998 					     1, /* qd */
1999 					     0, /* ttl */
2000 					     0, /* prettl */
2001 					     0, /* expttl */
2002 					     0, /* an */
2003 					     0, /* ns */
2004 					     0, /* ar */
2005 					     0, /* total */
2006 					     sec_status_insecure,
2007 					     LDNS_EDE_NONE);
2008 	if(msg->rep)
2009 		msg->rep->authoritative = 1;
2010 	if(!rpz_add_soa(msg->rep, ms, az))
2011 		return NULL;
2012 	return msg;
2013 }
2014 
2015 static inline struct dns_msg*
2016 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
2017 	struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az)
2018 {
2019 	struct dns_msg* msg = NULL;
2020 	struct reply_info* new_reply_info;
2021 	struct ub_packed_rrset_key* rp;
2022 
2023 
2024 	msg = rpz_dns_msg_new(ms->region);
2025 	if(msg == NULL) { return NULL; }
2026 
2027 	msg->qinfo = *qi;
2028         new_reply_info = construct_reply_info_base(ms->region,
2029                                                    LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
2030                                                    1, /* qd */
2031                                                    0, /* ttl */
2032                                                    0, /* prettl */
2033                                                    0, /* expttl */
2034                                                    1, /* an */
2035                                                    0, /* ns */
2036                                                    0, /* ar */
2037                                                    1, /* total */
2038                                                    sec_status_insecure,
2039                                                    LDNS_EDE_NONE);
2040 	if(new_reply_info == NULL) {
2041 		log_err("out of memory");
2042 		return NULL;
2043 	}
2044 	new_reply_info->authoritative = 1;
2045 	rp = respip_copy_rrset(rrset->rrset, ms->region);
2046 	if(rp == NULL) {
2047 		log_err("out of memory");
2048 		return NULL;
2049 	}
2050 	rp->rk.dname = qi->qname;
2051 	rp->rk.dname_len = qi->qname_len;
2052 	/* this rrset is from the rpz data, or synthesized.
2053 	 * It is not actually from the network, so we flag it with this
2054 	 * flags as a fake RRset. If later the cache is used to look up
2055 	 * rrsets, then the fake ones are not returned (if you look without
2056 	 * the flag). For like CNAME lookups from the iterator or A, AAAA
2057 	 * lookups for nameserver targets, it would use the without flag
2058 	 * actual data. So that the actual network data and fake data
2059 	 * are kept track of separately. */
2060 	rp->rk.flags |= PACKED_RRSET_RPZ;
2061 	new_reply_info->rrsets[0] = rp;
2062 	msg->rep = new_reply_info;
2063 	if(!rpz_add_soa(msg->rep, ms, az))
2064 		return NULL;
2065 	return msg;
2066 }
2067 
2068 static inline struct dns_msg*
2069 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms,
2070 	struct query_info* qi, struct clientip_synthesized_rr* data,
2071 	struct auth_zone* az)
2072 {
2073 	struct local_rrset* rrset;
2074 
2075 	rrset = rpz_find_synthesized_rrset(qi->qtype, data, 1);
2076 	if(rrset == NULL) {
2077 		verbose(VERB_ALGO, "rpz: nsip: no matching local data found");
2078 		return NULL;
2079 	}
2080 
2081 	return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az);
2082 }
2083 
2084 /* copy'n'paste from localzone.c */
2085 static struct local_rrset*
2086 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok)
2087 {
2088 	struct local_rrset* p, *cname = NULL;
2089 	type = htons(type);
2090 	for(p = data->rrsets; p; p = p->next) {
2091 		if(p->rrset->rk.type == type)
2092 			return p;
2093 		if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME))
2094 			cname = p;
2095 	}
2096 	if(alias_ok)
2097 		return cname;
2098 	return NULL;
2099 }
2100 
2101 /* based on localzone.c:local_data_answer() */
2102 static inline struct dns_msg*
2103 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
2104 	struct query_info* qi, struct local_zone* z,
2105 	struct matched_delegation_point const* match, struct auth_zone* az)
2106 {
2107 	struct local_data key;
2108 	struct local_data* ld;
2109 	struct local_rrset* rrset;
2110 
2111 	if(match->dname == NULL) { return NULL; }
2112 
2113 	key.node.key = &key;
2114 	key.name = match->dname;
2115 	key.namelen = match->dname_len;
2116 	key.namelabs = dname_count_labels(match->dname);
2117 
2118 	rpz_log_dname("nsdname local data", key.name, key.namelen);
2119 
2120 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
2121 	if(ld == NULL) {
2122 		verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
2123 		return NULL;
2124 	}
2125 
2126 	rrset = local_data_find_type(ld, qi->qtype, 1);
2127 	if(rrset == NULL) {
2128 		verbose(VERB_ALGO, "rpz: nsdname: no matching local data found");
2129 		return NULL;
2130 	}
2131 
2132 	return rpz_synthesize_localdata_from_rrset(r, ms, qi, rrset, az);
2133 }
2134 
2135 /* like local_data_answer for qname triggers after a cname */
2136 static struct dns_msg*
2137 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
2138 	struct query_info* qinfo, struct local_zone* z, struct auth_zone* az)
2139 {
2140 	struct local_data key;
2141 	struct local_data* ld;
2142 	struct local_rrset* rrset;
2143 	key.node.key = &key;
2144 	key.name = qinfo->qname;
2145 	key.namelen = qinfo->qname_len;
2146 	key.namelabs = dname_count_labels(qinfo->qname);
2147 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
2148 	if(ld == NULL) {
2149 		verbose(VERB_ALGO, "rpz: qname: name not found");
2150 		return NULL;
2151 	}
2152 	rrset = local_data_find_type(ld, qinfo->qtype, 1);
2153 	if(rrset == NULL) {
2154 		verbose(VERB_ALGO, "rpz: qname: type not found");
2155 		return NULL;
2156 	}
2157 	return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az);
2158 }
2159 
2160 /** Synthesize a CNAME message for RPZ action override */
2161 static struct dns_msg*
2162 rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms,
2163 	struct query_info* qinfo)
2164 {
2165 	struct dns_msg* msg = NULL;
2166 	struct reply_info* new_reply_info;
2167 	struct ub_packed_rrset_key* rp;
2168 
2169 	msg = rpz_dns_msg_new(ms->region);
2170 	if(msg == NULL) { return NULL; }
2171 
2172 	msg->qinfo = *qinfo;
2173         new_reply_info = construct_reply_info_base(ms->region,
2174                                                    LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
2175                                                    1, /* qd */
2176                                                    0, /* ttl */
2177                                                    0, /* prettl */
2178                                                    0, /* expttl */
2179                                                    1, /* an */
2180                                                    0, /* ns */
2181                                                    0, /* ar */
2182                                                    1, /* total */
2183                                                    sec_status_insecure,
2184                                                    LDNS_EDE_NONE);
2185 	if(new_reply_info == NULL) {
2186 		log_err("out of memory");
2187 		return NULL;
2188 	}
2189 	new_reply_info->authoritative = 1;
2190 
2191 	rp = respip_copy_rrset(r->cname_override, ms->region);
2192 	if(rp == NULL) {
2193 		log_err("out of memory");
2194 		return NULL;
2195 	}
2196 	rp->rk.dname = qinfo->qname;
2197 	rp->rk.dname_len = qinfo->qname_len;
2198 	/* this rrset is from the rpz data, or synthesized.
2199 	 * It is not actually from the network, so we flag it with this
2200 	 * flags as a fake RRset. If later the cache is used to look up
2201 	 * rrsets, then the fake ones are not returned (if you look without
2202 	 * the flag). For like CNAME lookups from the iterator or A, AAAA
2203 	 * lookups for nameserver targets, it would use the without flag
2204 	 * actual data. So that the actual network data and fake data
2205 	 * are kept track of separately. */
2206 	rp->rk.flags |= PACKED_RRSET_RPZ;
2207 	new_reply_info->rrsets[0] = rp;
2208 
2209 	msg->rep = new_reply_info;
2210 	return msg;
2211 }
2212 
2213 static int
2214 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
2215 	struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo,
2216 	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
2217 	struct comm_reply* repinfo, struct ub_server_stats* stats)
2218 {
2219 	struct local_data* ld = NULL;
2220 	int ret = 0;
2221 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
2222 		if(!rpz_apply_cname_override_action(r, qinfo, temp))
2223 			return 0;
2224 		if(r->log) {
2225 			log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION,
2226 				      qinfo, repinfo, NULL, r->log_name);
2227 		}
2228 		stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
2229 		return 0;
2230 	}
2231 
2232 	if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
2233 		edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
2234 		&ld, lzt, -1, NULL, 0, NULL, 0)) {
2235 		if(r->log) {
2236 			log_rpz_apply("qname", z->name, NULL,
2237 				localzone_type_to_rpz_action(lzt), qinfo,
2238 				repinfo, NULL, r->log_name);
2239 		}
2240 		stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
2241 		return !qinfo->local_alias;
2242 	}
2243 
2244 	ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
2245 		0 /* no local data used */, lzt);
2246 	if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
2247 		== LDNS_RCODE_NXDOMAIN)
2248 		LDNS_RA_CLR(sldns_buffer_begin(buf));
2249 	if(r->log) {
2250 		log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt),
2251 			      qinfo, repinfo, NULL, r->log_name);
2252 	}
2253 	stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
2254 	return ret;
2255 }
2256 
2257 static struct clientip_synthesized_rr*
2258 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is)
2259 {
2260 	struct delegpt_addr* cursor;
2261 	struct clientip_synthesized_rr* action = NULL;
2262 	if(is->dp == NULL) { return NULL; }
2263 	for(cursor = is->dp->target_list;
2264 	    cursor != NULL;
2265 	    cursor = cursor->next_target) {
2266 		if(cursor->bogus) { continue; }
2267 		action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr,
2268 						    cursor->addrlen, "nsip");
2269 		if(action != NULL) { return action; }
2270 	}
2271 	return NULL;
2272 }
2273 
2274 static struct dns_msg*
2275 rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
2276 	struct rpz* r, struct clientip_synthesized_rr* raddr,
2277 	struct auth_zone* az)
2278 {
2279 	enum rpz_action action = raddr->action;
2280 	struct dns_msg* ret = NULL;
2281 
2282 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
2283 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
2284 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
2285 		action = r->action_override;
2286 	}
2287 
2288 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) {
2289 		verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data");
2290 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2291 		goto done;
2292 	}
2293 
2294 	switch(action) {
2295 	case RPZ_NXDOMAIN_ACTION:
2296 		ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
2297 		break;
2298 	case RPZ_NODATA_ACTION:
2299 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2300 		break;
2301 	case RPZ_TCP_ONLY_ACTION:
2302 		/* basically a passthru here but the tcp-only will be
2303 		 * honored before the query gets sent. */
2304 		ms->tcp_required = 1;
2305 		ret = NULL;
2306 		break;
2307 	case RPZ_DROP_ACTION:
2308 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2309 		ms->is_drop = 1;
2310 		break;
2311 	case RPZ_LOCAL_DATA_ACTION:
2312 		ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az);
2313 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
2314 		break;
2315 	case RPZ_PASSTHRU_ACTION:
2316 		ret = NULL;
2317 		ms->rpz_passthru = 1;
2318 		break;
2319 	case RPZ_CNAME_OVERRIDE_ACTION:
2320 		ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
2321 		break;
2322 	default:
2323 		verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
2324 			rpz_action_to_string(action));
2325 		ret = NULL;
2326 	}
2327 
2328 done:
2329 	if(r->log)
2330 		log_rpz_apply("nsip", NULL, &raddr->node,
2331 			action, &ms->qinfo, NULL, ms, r->log_name);
2332 	if(ms->env->worker)
2333 		ms->env->worker->stats.rpz_action[action]++;
2334 	lock_rw_unlock(&raddr->lock);
2335 	return ret;
2336 }
2337 
2338 static struct dns_msg*
2339 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
2340 	struct rpz* r, struct local_zone* z,
2341 	struct matched_delegation_point const* match, struct auth_zone* az)
2342 {
2343 	struct dns_msg* ret = NULL;
2344 	enum rpz_action action = localzone_type_to_rpz_action(z->type);
2345 
2346 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
2347 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
2348 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
2349 		action = r->action_override;
2350 	}
2351 
2352 	switch(action) {
2353 	case RPZ_NXDOMAIN_ACTION:
2354 		ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
2355 		break;
2356 	case RPZ_NODATA_ACTION:
2357 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2358 		break;
2359 	case RPZ_TCP_ONLY_ACTION:
2360 		/* basically a passthru here but the tcp-only will be
2361 		 * honored before the query gets sent. */
2362 		ms->tcp_required = 1;
2363 		ret = NULL;
2364 		break;
2365 	case RPZ_DROP_ACTION:
2366 		ret = rpz_synthesize_nodata(r, ms, qchase, az);
2367 		ms->is_drop = 1;
2368 		break;
2369 	case RPZ_LOCAL_DATA_ACTION:
2370 		ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az);
2371 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
2372 		break;
2373 	case RPZ_PASSTHRU_ACTION:
2374 		ret = NULL;
2375 		ms->rpz_passthru = 1;
2376 		break;
2377 	case RPZ_CNAME_OVERRIDE_ACTION:
2378 		ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
2379 		break;
2380 	default:
2381 		verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'",
2382 			rpz_action_to_string(action));
2383 		ret = NULL;
2384 	}
2385 
2386 	if(r->log)
2387 		log_rpz_apply("nsdname", match->dname, NULL,
2388 			action, &ms->qinfo, NULL, ms, r->log_name);
2389 	if(ms->env->worker)
2390 		ms->env->worker->stats.rpz_action[action]++;
2391 	lock_rw_unlock(&z->lock);
2392 	return ret;
2393 }
2394 
2395 static struct local_zone*
2396 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones,
2397 	uint16_t qclass,
2398 	/* output parameter */
2399 	struct matched_delegation_point* match)
2400 {
2401 	struct delegpt_ns* nameserver;
2402 	struct local_zone* z = NULL;
2403 
2404 	/* the rpz specs match the nameserver names (NS records), not the
2405 	 * name of the delegation point itself, to the nsdname triggers */
2406 	for(nameserver = dp->nslist;
2407 	    nameserver != NULL;
2408 	    nameserver = nameserver->next) {
2409 		z = rpz_find_zone(zones, nameserver->name, nameserver->namelen,
2410 				  qclass, 0, 0, 0);
2411 		if(z != NULL) {
2412 			match->dname = nameserver->name;
2413 			match->dname_len = nameserver->namelen;
2414 			if(verbosity >= VERB_ALGO) {
2415 				char nm[255+1], zn[255+1];
2416 				dname_str(match->dname, nm);
2417 				dname_str(z->name, zn);
2418 				if(strcmp(nm, zn) != 0)
2419 					verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s",
2420 						zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2421 				else
2422 					verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s",
2423 						nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2424 			}
2425 			break;
2426 		}
2427 	}
2428 
2429 	return z;
2430 }
2431 
2432 struct dns_msg*
2433 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is)
2434 {
2435 	struct auth_zones* az;
2436 	struct auth_zone* a;
2437 	struct clientip_synthesized_rr* raddr = NULL;
2438 	struct rpz* r = NULL;
2439 	struct local_zone* z = NULL;
2440 	struct matched_delegation_point match = {0};
2441 
2442 	if(ms->rpz_passthru) {
2443 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2444 		return NULL;
2445 	}
2446 
2447 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2448 
2449 	az = ms->env->auth_zones;
2450 	lock_rw_rdlock(&az->rpz_lock);
2451 
2452 	verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
2453 
2454 	/* precedence of RPZ works, loosely, like this:
2455 	 * CNAMEs in order of the CNAME chain. rpzs in the order they are
2456 	 * configured. In an RPZ: first client-IP addr, then QNAME, then
2457 	 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest
2458 	 * one from a set. */
2459 	/* we use the precedence rules for the topics and triggers that
2460 	 * are pertinent at this stage of the resolve processing */
2461 	for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) {
2462 		lock_rw_rdlock(&a->lock);
2463 		r = a->rpz;
2464 		if(r->disabled) {
2465 			lock_rw_unlock(&a->lock);
2466 			continue;
2467 		}
2468 		if(r->taglist && (!ms->client_info ||
2469 			!taglist_intersect(r->taglist, r->taglistlen,
2470 				ms->client_info->taglist,
2471 				ms->client_info->taglen))) {
2472 			lock_rw_unlock(&a->lock);
2473 			continue;
2474 		}
2475 
2476 		/* the nsdname has precedence over the nsip triggers */
2477 		z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
2478 						     is->qchase.qclass, &match);
2479 		if(z != NULL) {
2480 			lock_rw_unlock(&a->lock);
2481 			break;
2482 		}
2483 
2484 		raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is);
2485 		if(raddr != NULL) {
2486 			lock_rw_unlock(&a->lock);
2487 			break;
2488 		}
2489 		lock_rw_unlock(&a->lock);
2490 	}
2491 
2492 	lock_rw_unlock(&az->rpz_lock);
2493 
2494 	if(raddr == NULL && z == NULL)
2495 		return NULL;
2496 
2497 	if(raddr != NULL) {
2498 		if(z) {
2499 			lock_rw_unlock(&z->lock);
2500 		}
2501 		return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
2502 	}
2503 	return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
2504 }
2505 
2506 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
2507 	struct iter_qstate* is)
2508 {
2509 	struct auth_zones* az;
2510 	struct auth_zone* a = NULL;
2511 	struct rpz* r = NULL;
2512 	struct local_zone* z = NULL;
2513 	enum localzone_type lzt;
2514 	struct dns_msg* ret = NULL;
2515 
2516 	if(ms->rpz_passthru) {
2517 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2518 		return NULL;
2519 	}
2520 
2521 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2522 	az = ms->env->auth_zones;
2523 
2524 	lock_rw_rdlock(&az->rpz_lock);
2525 
2526 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
2527 		lock_rw_rdlock(&a->lock);
2528 		r = a->rpz;
2529 		if(r->disabled) {
2530 			lock_rw_unlock(&a->lock);
2531 			continue;
2532 		}
2533 		if(r->taglist && (!ms->client_info ||
2534 			!taglist_intersect(r->taglist, r->taglistlen,
2535 				ms->client_info->taglist,
2536 				ms->client_info->taglen))) {
2537 			lock_rw_unlock(&a->lock);
2538 			continue;
2539 		}
2540 		z = rpz_find_zone(r->local_zones, is->qchase.qname,
2541 			is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
2542 		if(z && r->action_override == RPZ_DISABLED_ACTION) {
2543 			if(r->log)
2544 				log_rpz_apply("qname", z->name, NULL,
2545 					r->action_override,
2546 					&ms->qinfo, NULL, ms, r->log_name);
2547 			if(ms->env->worker)
2548 				ms->env->worker->stats.rpz_action[r->action_override]++;
2549 			lock_rw_unlock(&z->lock);
2550 			z = NULL;
2551 		}
2552 		if(z) {
2553 			break;
2554 		}
2555 		/* not found in this auth_zone */
2556 		lock_rw_unlock(&a->lock);
2557 	}
2558 	lock_rw_unlock(&az->rpz_lock);
2559 
2560 	if(z == NULL)
2561 		return NULL;
2562 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2563 		lzt = z->type;
2564 	} else {
2565 		lzt = rpz_action_to_localzone_type(r->action_override);
2566 	}
2567 
2568 	if(verbosity >= VERB_ALGO) {
2569 		char nm[255+1], zn[255+1];
2570 		dname_str(is->qchase.qname, nm);
2571 		dname_str(z->name, zn);
2572 		if(strcmp(zn, nm) != 0)
2573 			verbose(VERB_ALGO, "rpz: qname trigger %s on %s, with action=%s",
2574 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2575 		else
2576 			verbose(VERB_ALGO, "rpz: qname trigger %s, with action=%s",
2577 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2578 	}
2579 	switch(localzone_type_to_rpz_action(lzt)) {
2580 	case RPZ_NXDOMAIN_ACTION:
2581 		ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a);
2582 		break;
2583 	case RPZ_NODATA_ACTION:
2584 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2585 		break;
2586 	case RPZ_TCP_ONLY_ACTION:
2587 		/* basically a passthru here but the tcp-only will be
2588 		 * honored before the query gets sent. */
2589 		ms->tcp_required = 1;
2590 		ret = NULL;
2591 		break;
2592 	case RPZ_DROP_ACTION:
2593 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2594 		ms->is_drop = 1;
2595 		break;
2596 	case RPZ_LOCAL_DATA_ACTION:
2597 		ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a);
2598 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); }
2599 		break;
2600 	case RPZ_PASSTHRU_ACTION:
2601 		ret = NULL;
2602 		ms->rpz_passthru = 1;
2603 		break;
2604 	default:
2605 		verbose(VERB_ALGO, "rpz: qname trigger: bug: unhandled or invalid action: '%s'",
2606 			rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2607 		ret = NULL;
2608 	}
2609 	if(r->log)
2610 		log_rpz_apply("qname", (z?z->name:NULL), NULL,
2611 			localzone_type_to_rpz_action(lzt),
2612 			&is->qchase, NULL, ms, r->log_name);
2613 	lock_rw_unlock(&z->lock);
2614 	lock_rw_unlock(&a->lock);
2615 	return ret;
2616 }
2617 
2618 static int
2619 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
2620 	struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo,
2621 	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
2622 	sldns_buffer* buf, struct regional* temp,
2623 	/* output parameters */
2624 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out,
2625 	int* passthru)
2626 {
2627 	int ret = 0;
2628 	enum rpz_action client_action;
2629 	struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone(
2630 		az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
2631 
2632 	client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
2633 	if(node != NULL && *r_out &&
2634 		(*r_out)->action_override != RPZ_NO_OVERRIDE_ACTION) {
2635 		client_action = (*r_out)->action_override;
2636 	}
2637 	if(client_action == RPZ_PASSTHRU_ACTION) {
2638 		if(*r_out && (*r_out)->log)
2639 			log_rpz_apply(
2640 				(node?"clientip":"qname"),
2641 				((*z_out)?(*z_out)->name:NULL),
2642 				(node?&node->node:NULL),
2643 				client_action, qinfo, repinfo, NULL,
2644 				(*r_out)->log_name);
2645 		*passthru = 1;
2646 		ret = 0;
2647 		goto done;
2648 	}
2649 	if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION &&
2650 			      client_action != RPZ_PASSTHRU_ACTION)) {
2651 		if(client_action == RPZ_PASSTHRU_ACTION
2652 			|| client_action == RPZ_INVALID_ACTION
2653 			|| (client_action == RPZ_TCP_ONLY_ACTION
2654 				&& !rpz_is_udp_query(repinfo))) {
2655 			ret = 0;
2656 			goto done;
2657 		}
2658 		stats->rpz_action[client_action]++;
2659 		if(client_action == RPZ_LOCAL_DATA_ACTION) {
2660 			rpz_apply_clientip_localdata_action(node, env, qinfo,
2661 				edns, repinfo, buf, temp, *a_out);
2662 			ret = 1;
2663 		} else if(client_action == RPZ_CNAME_OVERRIDE_ACTION) {
2664 			if(!rpz_apply_cname_override_action(*r_out, qinfo,
2665 				temp)) {
2666 				ret = 0;
2667 				goto done;
2668 			}
2669 			ret = 0;
2670 		} else {
2671 			local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns,
2672 				repinfo, buf, temp, 0 /* no local data used */,
2673 				rpz_action_to_localzone_type(client_action));
2674 			if(*r_out && (*r_out)->signal_nxdomain_ra &&
2675 				LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
2676 				== LDNS_RCODE_NXDOMAIN)
2677 				LDNS_RA_CLR(sldns_buffer_begin(buf));
2678 			ret = 1;
2679 		}
2680 		if(*r_out && (*r_out)->log)
2681 			log_rpz_apply(
2682 				(node?"clientip":"qname"),
2683 				((*z_out)?(*z_out)->name:NULL),
2684 				(node?&node->node:NULL),
2685 				client_action, qinfo, repinfo, NULL,
2686 				(*r_out)->log_name);
2687 		goto done;
2688 	}
2689 	ret = -1;
2690 done:
2691 	if(node != NULL) {
2692 		lock_rw_unlock(&node->lock);
2693 	}
2694 	return ret;
2695 }
2696 
2697 int
2698 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
2699 	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
2700 	struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
2701 	size_t taglen, struct ub_server_stats* stats, int* passthru)
2702 {
2703 	struct rpz* r = NULL;
2704 	struct auth_zone* a = NULL;
2705 	struct local_zone* z = NULL;
2706 	int ret;
2707 	enum localzone_type lzt;
2708 
2709 	int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
2710 		edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r,
2711 		passthru);
2712 	if(clientip_trigger >= 0) {
2713 		if(a) {
2714 			lock_rw_unlock(&a->lock);
2715 		}
2716 		if(z) {
2717 			lock_rw_unlock(&z->lock);
2718 		}
2719 		return clientip_trigger;
2720 	}
2721 
2722 	if(z == NULL) {
2723 		if(a) {
2724 			lock_rw_unlock(&a->lock);
2725 		}
2726 		return 0;
2727 	}
2728 
2729 	log_assert(r);
2730 
2731 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2732 		lzt = z->type;
2733 	} else {
2734 		lzt = rpz_action_to_localzone_type(r->action_override);
2735 	}
2736 	if(r->action_override == RPZ_PASSTHRU_ACTION ||
2737 		lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) {
2738 		*passthru = 1;
2739 	}
2740 
2741 	if(verbosity >= VERB_ALGO) {
2742 		char nm[255+1], zn[255+1];
2743 		dname_str(qinfo->qname, nm);
2744 		dname_str(z->name, zn);
2745 		if(strcmp(zn, nm) != 0)
2746 			verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s",
2747 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2748 		else
2749 			verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s",
2750 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2751 	}
2752 
2753 	ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp,
2754 					     repinfo, stats);
2755 
2756 	lock_rw_unlock(&z->lock);
2757 	lock_rw_unlock(&a->lock);
2758 
2759 	return ret;
2760 }
2761 
2762 void rpz_enable(struct rpz* r)
2763 {
2764     if(!r)
2765         return;
2766     r->disabled = 0;
2767 }
2768 
2769 void rpz_disable(struct rpz* r)
2770 {
2771     if(!r)
2772         return;
2773     r->disabled = 1;
2774 }
2775