xref: /freebsd/contrib/unbound/services/rpz.c (revision 7ef62cebc2f965b0f640263e179276928885e33d)
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:	/* fallthrough */
246 	case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
247 	case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
248 	case RPZ_INVALID_ACTION: /* fallthrough */
249 	default: return local_zone_invalid;
250 	}
251 }
252 
253 enum respip_action
254 rpz_action_to_respip_action(enum rpz_action a)
255 {
256 	switch(a) {
257 	case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
258 	case RPZ_NODATA_ACTION: return respip_always_nodata;
259 	case RPZ_DROP_ACTION: return respip_always_deny;
260 	case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
261 	case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
262 	case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
263 	case RPZ_TCP_ONLY_ACTION: return respip_truncate;
264 	case RPZ_INVALID_ACTION: /* fallthrough */
265 	default: return respip_invalid;
266 	}
267 }
268 
269 static enum rpz_action
270 localzone_type_to_rpz_action(enum localzone_type lzt)
271 {
272 	switch(lzt) {
273 	case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
274 	case local_zone_always_nodata: return RPZ_NODATA_ACTION;
275 	case local_zone_always_deny: return RPZ_DROP_ACTION;
276 	case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
277 	case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
278 	case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
279 	case local_zone_invalid: /* fallthrough */
280 	default: return RPZ_INVALID_ACTION;
281 	}
282 }
283 
284 enum rpz_action
285 respip_action_to_rpz_action(enum respip_action a)
286 {
287 	switch(a) {
288 	case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
289 	case respip_always_nodata: return RPZ_NODATA_ACTION;
290 	case respip_always_deny: return RPZ_DROP_ACTION;
291 	case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
292 	case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
293 	case respip_truncate: return RPZ_TCP_ONLY_ACTION;
294 	case respip_invalid: /* fallthrough */
295 	default: return RPZ_INVALID_ACTION;
296 	}
297 }
298 
299 /**
300  * Get RPZ trigger for dname
301  * @param dname: dname containing RPZ trigger
302  * @param dname_len: length of the dname
303  * @return: RPZ trigger enum
304  */
305 static enum rpz_trigger
306 rpz_dname_to_trigger(uint8_t* dname, size_t dname_len)
307 {
308 	uint8_t* tldlab;
309 	char* endptr;
310 
311 	if(dname_valid(dname, dname_len) != dname_len)
312 		return RPZ_INVALID_TRIGGER;
313 
314 	tldlab = get_tld_label(dname, dname_len);
315 	if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr))
316 		return RPZ_QNAME_TRIGGER;
317 
318 	if(dname_subdomain_c(tldlab,
319 		(uint8_t*)&"\015rpz-client-ip\000"))
320 		return RPZ_CLIENT_IP_TRIGGER;
321 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000"))
322 		return RPZ_RESPONSE_IP_TRIGGER;
323 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000"))
324 		return RPZ_NSDNAME_TRIGGER;
325 	else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000"))
326 		return RPZ_NSIP_TRIGGER;
327 
328 	return RPZ_QNAME_TRIGGER;
329 }
330 
331 static inline struct clientip_synthesized_rrset*
332 rpz_clientip_synthesized_set_create(void)
333 {
334 	struct clientip_synthesized_rrset* set = calloc(1, sizeof(*set));
335 	if(set == NULL) {
336 		return NULL;
337 	}
338 	set->region = regional_create();
339 	if(set->region == NULL) {
340 		free(set);
341 		return NULL;
342 	}
343 	addr_tree_init(&set->entries);
344 	lock_rw_init(&set->lock);
345 	return set;
346 }
347 
348 static void
349 rpz_clientip_synthesized_rr_delete(rbnode_type* n, void* ATTR_UNUSED(arg))
350 {
351 	struct clientip_synthesized_rr* r = (struct clientip_synthesized_rr*)n->key;
352 	lock_rw_destroy(&r->lock);
353 #ifdef THREADS_DISABLED
354 	(void)r;
355 #endif
356 }
357 
358 static inline void
359 rpz_clientip_synthesized_set_delete(struct clientip_synthesized_rrset* set)
360 {
361 	if(set == NULL) {
362 		return;
363 	}
364 	lock_rw_destroy(&set->lock);
365 	traverse_postorder(&set->entries, rpz_clientip_synthesized_rr_delete, NULL);
366 	regional_destroy(set->region);
367 	free(set);
368 }
369 
370 void
371 rpz_delete(struct rpz* r)
372 {
373 	if(!r)
374 		return;
375 	local_zones_delete(r->local_zones);
376 	local_zones_delete(r->nsdname_zones);
377 	respip_set_delete(r->respip_set);
378 	rpz_clientip_synthesized_set_delete(r->client_set);
379 	rpz_clientip_synthesized_set_delete(r->ns_set);
380 	regional_destroy(r->region);
381 	free(r->taglist);
382 	free(r->log_name);
383 	free(r);
384 }
385 
386 int
387 rpz_clear(struct rpz* r)
388 {
389 	/* must hold write lock on auth_zone */
390 	local_zones_delete(r->local_zones);
391 	r->local_zones = NULL;
392 	local_zones_delete(r->nsdname_zones);
393 	r->nsdname_zones = NULL;
394 	respip_set_delete(r->respip_set);
395 	r->respip_set = NULL;
396 	rpz_clientip_synthesized_set_delete(r->client_set);
397 	r->client_set = NULL;
398 	rpz_clientip_synthesized_set_delete(r->ns_set);
399 	r->ns_set = NULL;
400 	if(!(r->local_zones = local_zones_create())){
401 		return 0;
402 	}
403 	r->nsdname_zones = local_zones_create();
404 	if(r->nsdname_zones == NULL) {
405 		return 0;
406 	}
407 	if(!(r->respip_set = respip_set_create())) {
408 		return 0;
409 	}
410 	if(!(r->client_set = rpz_clientip_synthesized_set_create())) {
411 		return 0;
412 	}
413 	if(!(r->ns_set = rpz_clientip_synthesized_set_create())) {
414 		return 0;
415 	}
416 	return 1;
417 }
418 
419 void
420 rpz_finish_config(struct rpz* r)
421 {
422 	lock_rw_wrlock(&r->respip_set->lock);
423 	addr_tree_init_parents(&r->respip_set->ip_tree);
424 	lock_rw_unlock(&r->respip_set->lock);
425 
426 	lock_rw_wrlock(&r->client_set->lock);
427 	addr_tree_init_parents(&r->client_set->entries);
428 	lock_rw_unlock(&r->client_set->lock);
429 
430 	lock_rw_wrlock(&r->ns_set->lock);
431 	addr_tree_init_parents(&r->ns_set->entries);
432 	lock_rw_unlock(&r->ns_set->lock);
433 }
434 
435 /** new rrset containing CNAME override, does not yet contain a dname */
436 static struct ub_packed_rrset_key*
437 new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen)
438 {
439 	struct ub_packed_rrset_key* rrset;
440 	struct packed_rrset_data* pd;
441 	uint16_t rdlength = htons(ctlen);
442 	rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
443 		sizeof(*rrset));
444 	if(!rrset) {
445 		log_err("out of memory");
446 		return NULL;
447 	}
448 	rrset->entry.key = rrset;
449 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
450 	if(!pd) {
451 		log_err("out of memory");
452 		return NULL;
453 	}
454 	pd->trust = rrset_trust_prim_noglue;
455 	pd->security = sec_status_insecure;
456 
457 	pd->count = 1;
458 	pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len));
459 	pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl));
460 	pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data));
461 	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
462 		log_err("out of memory");
463 		return NULL;
464 	}
465 	pd->rr_len[0] = ctlen+2;
466 	pd->rr_ttl[0] = 3600;
467 	pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen);
468 	if(!pd->rr_data[0]) {
469 		log_err("out of memory");
470 		return NULL;
471 	}
472 	memmove(pd->rr_data[0], &rdlength, 2);
473 	memmove(pd->rr_data[0]+2, ct, ctlen);
474 
475 	rrset->entry.data = pd;
476 	rrset->rk.type = htons(LDNS_RR_TYPE_CNAME);
477 	rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN);
478 	return rrset;
479 }
480 
481 struct rpz*
482 rpz_create(struct config_auth* p)
483 {
484 	struct rpz* r = calloc(1, sizeof(*r));
485 	if(!r)
486 		goto err;
487 
488 	r->region = regional_create_custom(sizeof(struct regional));
489 	if(!r->region) {
490 		goto err;
491 	}
492 
493 	if(!(r->local_zones = local_zones_create())){
494 		goto err;
495 	}
496 
497 	r->nsdname_zones = local_zones_create();
498 	if(r->local_zones == NULL){
499 		goto err;
500 	}
501 
502 	if(!(r->respip_set = respip_set_create())) {
503 		goto err;
504 	}
505 
506 	r->client_set = rpz_clientip_synthesized_set_create();
507 	if(r->client_set == NULL) {
508 		goto err;
509 	}
510 
511 	r->ns_set = rpz_clientip_synthesized_set_create();
512 	if(r->ns_set == NULL) {
513 		goto err;
514 	}
515 
516 	r->taglistlen = p->rpz_taglistlen;
517 	r->taglist = memdup(p->rpz_taglist, r->taglistlen);
518 	if(p->rpz_action_override) {
519 		r->action_override = rpz_config_to_action(p->rpz_action_override);
520 	}
521 	else
522 		r->action_override = RPZ_NO_OVERRIDE_ACTION;
523 
524 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
525 		uint8_t nm[LDNS_MAX_DOMAINLEN+1];
526 		size_t nmlen = sizeof(nm);
527 
528 		if(!p->rpz_cname) {
529 			log_err("rpz: override with cname action found, but no "
530 				"rpz-cname-override configured");
531 			goto err;
532 		}
533 
534 		if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
535 			log_err("rpz: cannot parse cname override: %s",
536 				p->rpz_cname);
537 			goto err;
538 		}
539 		r->cname_override = new_cname_override(r->region, nm, nmlen);
540 		if(!r->cname_override) {
541 			goto err;
542 		}
543 	}
544 	r->log = p->rpz_log;
545 	r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra;
546 	if(p->rpz_log_name) {
547 		if(!(r->log_name = strdup(p->rpz_log_name))) {
548 			log_err("malloc failure on RPZ log_name strdup");
549 			goto err;
550 		}
551 	}
552 	return r;
553 err:
554 	if(r) {
555 		if(r->local_zones)
556 			local_zones_delete(r->local_zones);
557 		if(r->nsdname_zones)
558 			local_zones_delete(r->nsdname_zones);
559 		if(r->respip_set)
560 			respip_set_delete(r->respip_set);
561 		if(r->client_set != NULL)
562 			rpz_clientip_synthesized_set_delete(r->client_set);
563 		if(r->ns_set != NULL)
564 			rpz_clientip_synthesized_set_delete(r->ns_set);
565 		if(r->taglist)
566 			free(r->taglist);
567 		if(r->region)
568 			regional_destroy(r->region);
569 		free(r);
570 	}
571 	return NULL;
572 }
573 
574 /**
575  * Remove RPZ zone name from dname
576  * Copy dname to newdname, without the originlen number of trailing bytes
577  */
578 static size_t
579 strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
580 	uint8_t* newdname, size_t maxnewdnamelen)
581 {
582 	size_t newdnamelen;
583 	if(dnamelen < originlen)
584 		return 0;
585 	newdnamelen = dnamelen - originlen;
586 	if(newdnamelen+1 > maxnewdnamelen)
587 		return 0;
588 	memmove(newdname, dname, newdnamelen);
589 	newdname[newdnamelen] = 0;
590 	return newdnamelen + 1;	/* + 1 for root label */
591 }
592 
593 static void
594 rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
595 	size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
596 	uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
597 {
598 	struct local_zone* z;
599 	enum localzone_type tp = local_zone_always_transparent;
600 	int dnamelabs = dname_count_labels(dname);
601 	int newzone = 0;
602 
603 	if(a == RPZ_INVALID_ACTION) {
604 		char str[255+1];
605 		if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS ||
606 			rrtype == LDNS_RR_TYPE_DNAME ||
607 			rrtype == LDNS_RR_TYPE_DNSKEY ||
608 			rrtype == LDNS_RR_TYPE_RRSIG ||
609 			rrtype == LDNS_RR_TYPE_NSEC ||
610 			rrtype == LDNS_RR_TYPE_NSEC3PARAM ||
611 			rrtype == LDNS_RR_TYPE_NSEC3 ||
612 			rrtype == LDNS_RR_TYPE_DS) {
613 			free(dname);
614 			return; /* no need to log these types as unsupported */
615 		}
616 		dname_str(dname, str);
617 		verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s",
618 			str, rpz_action_to_string(a));
619 		free(dname);
620 		return;
621 	}
622 
623 	lock_rw_wrlock(&lz->lock);
624 	/* exact match */
625 	z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
626 	if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
627 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
628 		if(rrstr == NULL) {
629 			log_err("malloc error while inserting rpz nsdname trigger");
630 			free(dname);
631 			lock_rw_unlock(&lz->lock);
632 			return;
633 		}
634 		if(rrstr[0])
635 			rrstr[strlen(rrstr)-1]=0; /* remove newline */
636 		verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
637 		free(rrstr);
638 		free(dname);
639 		lock_rw_unlock(&lz->lock);
640 		return;
641 	}
642 	if(z == NULL) {
643 		tp = rpz_action_to_localzone_type(a);
644 		z = local_zones_add_zone(lz, dname, dnamelen,
645 					 dnamelabs, rrclass, tp);
646 		if(z == NULL) {
647 			log_warn("rpz: create failed");
648 			lock_rw_unlock(&lz->lock);
649 			/* dname will be free'd in failed local_zone_create() */
650 			return;
651 		}
652 		newzone = 1;
653 	}
654 	if(a == RPZ_LOCAL_DATA_ACTION) {
655 		char* rrstr = sldns_wire2str_rr(rr, rr_len);
656 		if(rrstr == NULL) {
657 			log_err("malloc error while inserting rpz nsdname trigger");
658 			free(dname);
659 			lock_rw_unlock(&lz->lock);
660 			return;
661 		}
662 		lock_rw_wrlock(&z->lock);
663 		local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
664 				    rrclass, ttl, rdata, rdata_len, rrstr);
665 		lock_rw_unlock(&z->lock);
666 		free(rrstr);
667 	}
668 	if(!newzone) {
669 		free(dname);
670 	}
671 	lock_rw_unlock(&lz->lock);
672 }
673 
674 static void
675 rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
676 {
677 	char buf[LDNS_MAX_DOMAINLEN+1];
678 	(void)dname_len;
679 	dname_str(dname, buf);
680 	verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf);
681 }
682 
683 static void
684 rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
685 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
686 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
687 {
688 	if(a == RPZ_INVALID_ACTION) {
689 		verbose(VERB_ALGO, "rpz: skipping invalid action");
690 		free(dname);
691 		return;
692 	}
693 
694 	rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
695 				       rrclass, ttl, rdata, rdata_len, rr, rr_len);
696 }
697 
698 static int
699 rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
700 	uint8_t** stripdname, size_t* stripdnamelen)
701 {
702 	uint8_t* tldstart = get_tld_label(dname, maxdnamelen);
703 	uint8_t swap;
704 	if(tldstart == NULL) {
705 		if(dname == NULL) {
706 			*stripdname = NULL;
707 			*stripdnamelen = 0;
708 			return 0;
709 		}
710 		*stripdname = memdup(dname, maxdnamelen);
711 		if(!*stripdname) {
712 			*stripdnamelen = 0;
713 			log_err("malloc failure for rpz strip suffix");
714 			return 0;
715 		}
716 		*stripdnamelen = maxdnamelen;
717 		return 1;
718 	}
719 	/* shorten the domain name briefly,
720 	 * then we allocate a new name with the correct length */
721 	swap = *tldstart;
722 	*tldstart = 0;
723 	(void)dname_count_size_labels(dname, stripdnamelen);
724 	*stripdname = memdup(dname, *stripdnamelen);
725 	*tldstart = swap;
726 	if(!*stripdname) {
727 		*stripdnamelen = 0;
728 		log_err("malloc failure for rpz strip suffix");
729 		return 0;
730 	}
731 	return 1;
732 }
733 
734 static void
735 rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
736 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
737 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
738 {
739 	uint8_t* dname_stripped = NULL;
740 	size_t dnamelen_stripped = 0;
741 
742 	rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped,
743 		&dnamelen_stripped);
744 	if(a == RPZ_INVALID_ACTION) {
745 		verbose(VERB_ALGO, "rpz: skipping invalid action");
746 		free(dname_stripped);
747 		return;
748 	}
749 
750 	/* dname_stripped is consumed or freed by the insert routine */
751 	rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
752 		dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
753 		rr, rr_len);
754 }
755 
756 static int
757 rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
758 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
759 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
760 	uint8_t* rr, size_t rr_len)
761 {
762 	struct resp_addr* node;
763 	char* rrstr;
764 	enum respip_action respa = rpz_action_to_respip_action(a);
765 
766 	lock_rw_wrlock(&set->lock);
767 	rrstr = sldns_wire2str_rr(rr, rr_len);
768 	if(rrstr == NULL) {
769 		log_err("malloc error while inserting rpz ipaddr based trigger");
770 		lock_rw_unlock(&set->lock);
771 		return 0;
772 	}
773 
774 	node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
775 	if(node == NULL) {
776 		lock_rw_unlock(&set->lock);
777 		free(rrstr);
778 		return 0;
779 	}
780 
781 	lock_rw_wrlock(&node->lock);
782 	lock_rw_unlock(&set->lock);
783 
784 	node->action = respa;
785 
786 	if(a == RPZ_LOCAL_DATA_ACTION) {
787 		respip_enter_rr(set->region, node, rrtype,
788 				rrclass, ttl, rdata, rdata_len, rrstr, "");
789 	}
790 
791 	lock_rw_unlock(&node->lock);
792 	free(rrstr);
793 	return 1;
794 }
795 
796 static inline struct clientip_synthesized_rr*
797 rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
798 	struct sockaddr_storage* addr, socklen_t addrlen, int net)
799 {
800 	int insert_ok;
801 	struct clientip_synthesized_rr* node =
802 		(struct clientip_synthesized_rr*)addr_tree_find(&set->entries,
803 								addr, addrlen, net);
804 
805 	if(node != NULL) { return node; }
806 
807 	/* node does not yet exist => allocate one */
808 	node = regional_alloc_zero(set->region, sizeof(*node));
809 	if(node == NULL) {
810 		log_err("out of memory");
811 		return NULL;
812 	}
813 
814 	lock_rw_init(&node->lock);
815 	node->action = RPZ_INVALID_ACTION;
816 	insert_ok = addr_tree_insert(&set->entries, &node->node,
817 				     addr, addrlen, net);
818 	if (!insert_ok) {
819 		log_warn("rpz: unexpected: unable to insert clientip address node");
820 		/* we can not free the just allocated node.
821 		 * theoretically a memleak */
822 		return NULL;
823 	}
824 
825 	return node;
826 }
827 
828 static void
829 rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
830 	char* rrstr = sldns_wire2str_rr(rr, rr_len);
831 	if(rrstr == NULL) {
832 		log_err("malloc error while inserting rpz clientip based record");
833 		return;
834 	}
835 	log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
836 	free(rrstr);
837 }
838 
839 /* from localzone.c; difference is we don't have a dname */
840 static struct local_rrset*
841 rpz_clientip_new_rrset(struct regional* region,
842 	struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass)
843 {
844 	struct packed_rrset_data* pd;
845 	struct local_rrset* rrset = (struct local_rrset*)
846 		regional_alloc_zero(region, sizeof(*rrset));
847 	if(rrset == NULL) {
848 		log_err("out of memory");
849 		return NULL;
850 	}
851 	rrset->next = raddr->data;
852 	raddr->data = rrset;
853 	rrset->rrset = (struct ub_packed_rrset_key*)
854 		regional_alloc_zero(region, sizeof(*rrset->rrset));
855 	if(rrset->rrset == NULL) {
856 		log_err("out of memory");
857 		return NULL;
858 	}
859 	rrset->rrset->entry.key = rrset->rrset;
860 	pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
861 	if(pd == NULL) {
862 		log_err("out of memory");
863 		return NULL;
864 	}
865 	pd->trust = rrset_trust_prim_noglue;
866 	pd->security = sec_status_insecure;
867 	rrset->rrset->entry.data = pd;
868 	rrset->rrset->rk.type = htons(rrtype);
869 	rrset->rrset->rk.rrset_class = htons(rrclass);
870 	rrset->rrset->rk.dname = regional_alloc_zero(region, 1);
871 	if(rrset->rrset->rk.dname == NULL) {
872 		log_err("out of memory");
873 		return NULL;
874 	}
875 	rrset->rrset->rk.dname_len = 1;
876 	return rrset;
877 }
878 
879 static int
880 rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* raddr,
881 	uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
882 	size_t rdata_len)
883 {
884 	struct local_rrset* rrset;
885 	if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data != NULL) {
886 		log_err("CNAME response-ip data can not co-exist with other "
887 			"client-ip data");
888 		return 0;
889 	}
890 
891 	rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass);
892 	if(raddr->data == NULL) {
893 		return 0;
894 	}
895 
896 	return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
897 }
898 
899 static int
900 rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
901 	socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
902 	uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
903 	uint8_t* rr, size_t rr_len)
904 {
905 	struct clientip_synthesized_rr* node;
906 
907 	lock_rw_wrlock(&set->lock);
908 
909 	node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
910 	if(node == NULL) {
911 		lock_rw_unlock(&set->lock);
912 		rpz_report_rrset_error("client ip address", rr, rr_len);
913 		return 0;
914 	}
915 
916 	lock_rw_wrlock(&node->lock);
917 	lock_rw_unlock(&set->lock);
918 
919 	node->action = a;
920 	if(a == RPZ_LOCAL_DATA_ACTION) {
921 		if(!rpz_clientip_enter_rr(set->region, node, rrtype,
922 			rrclass, ttl, rdata, rdata_len)) {
923 			verbose(VERB_ALGO, "rpz: unable to insert clientip rr");
924 			lock_rw_unlock(&node->lock);
925 			return 0;
926 		}
927 
928 	}
929 
930 	lock_rw_unlock(&node->lock);
931 
932 	return 1;
933 }
934 
935 static int
936 rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
937 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
938 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
939 {
940 	struct sockaddr_storage addr;
941 	socklen_t addrlen;
942 	int net, af;
943 
944 	if(a == RPZ_INVALID_ACTION) {
945 		return 0;
946 	}
947 
948 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
949 		verbose(VERB_ALGO, "rpz: unable to parse client ip");
950 		return 0;
951 	}
952 
953 	return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
954 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
955 }
956 
957 static int
958 rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
959 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
960 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
961 {
962 	struct sockaddr_storage addr;
963 	socklen_t addrlen;
964 	int net, af;
965 
966 	if(a == RPZ_INVALID_ACTION) {
967 		return 0;
968 	}
969 
970 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
971 		verbose(VERB_ALGO, "rpz: unable to parse ns ip");
972 		return 0;
973 	}
974 
975 	return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
976 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
977 }
978 
979 /** Insert RR into RPZ's respip_set */
980 static int
981 rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
982 	enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
983 	uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
984 {
985 	struct sockaddr_storage addr;
986 	socklen_t addrlen;
987 	int net, af;
988 
989 	if(a == RPZ_INVALID_ACTION) {
990 		return 0;
991 	}
992 
993 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af)) {
994 		verbose(VERB_ALGO, "rpz: unable to parse response ip");
995 		return 0;
996 	}
997 
998 	if(a == RPZ_INVALID_ACTION ||
999 		rpz_action_to_respip_action(a) == respip_invalid) {
1000 		char str[255+1];
1001 		dname_str(dname, str);
1002 		verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s",
1003 			str, rpz_action_to_string(a));
1004 		return 0;
1005 	}
1006 
1007 	return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
1008 			a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
1009 }
1010 
1011 int
1012 rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
1013 	size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
1014 	uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
1015 {
1016 	size_t policydnamelen;
1017 	/* name is free'd in local_zone delete */
1018 	enum rpz_trigger t;
1019 	enum rpz_action a;
1020 	uint8_t* policydname;
1021 
1022 	if(rpz_type_ignored(rr_type)) {
1023 		/* this rpz action is not valid, eg. this is the SOA or NS RR */
1024 		return 1;
1025 	}
1026 	if(!dname_subdomain_c(dname, azname)) {
1027 		char* dname_str = sldns_wire2str_dname(dname, dnamelen);
1028 		char* azname_str = sldns_wire2str_dname(azname, aznamelen);
1029 		if(dname_str && azname_str) {
1030 			log_err("rpz: name of record (%s) to insert into RPZ is not a "
1031 				"subdomain of the configured name of the RPZ zone (%s)",
1032 				dname_str, azname_str);
1033 		} else {
1034 			log_err("rpz: name of record to insert into RPZ is not a "
1035 				"subdomain of the configured name of the RPZ zone");
1036 		}
1037 		free(dname_str);
1038 		free(azname_str);
1039 		return 0;
1040 	}
1041 
1042 	log_assert(dnamelen >= aznamelen);
1043 	if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) {
1044 		log_err("malloc error while inserting RPZ RR");
1045 		return 0;
1046 	}
1047 
1048 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1049 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1050 		policydname, (dnamelen-aznamelen)+1))) {
1051 		free(policydname);
1052 		return 0;
1053 	}
1054 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1055 	if(t == RPZ_INVALID_TRIGGER) {
1056 		free(policydname);
1057 		verbose(VERB_ALGO, "rpz: skipping invalid trigger");
1058 		return 1;
1059 	}
1060 	if(t == RPZ_QNAME_TRIGGER) {
1061 		/* policydname will be consumed, no free */
1062 		rpz_insert_qname_trigger(r, policydname, policydnamelen,
1063 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1064 			rr_len);
1065 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1066 		rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
1067 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1068 			rr_len);
1069 		free(policydname);
1070 	} else if(t == RPZ_CLIENT_IP_TRIGGER) {
1071 		rpz_insert_clientip_trigger(r, policydname, policydnamelen,
1072 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1073 			rr_len);
1074 		free(policydname);
1075 	} else if(t == RPZ_NSIP_TRIGGER) {
1076 		rpz_insert_nsip_trigger(r, policydname, policydnamelen,
1077 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1078 			rr_len);
1079 		free(policydname);
1080 	} else if(t == RPZ_NSDNAME_TRIGGER) {
1081 		rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
1082 			a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
1083 			rr_len);
1084 		free(policydname);
1085 	} else {
1086 		free(policydname);
1087 		verbose(VERB_ALGO, "rpz: skipping unsupported trigger: %s",
1088 			rpz_trigger_to_string(t));
1089 	}
1090 	return 1;
1091 }
1092 
1093 /**
1094  * Find RPZ local-zone by qname.
1095  * @param zones: local-zone tree
1096  * @param qname: qname
1097  * @param qname_len: length of qname
1098  * @param qclass: qclass
1099  * @param only_exact: if 1 only exact (non wildcard) matches are returned
1100  * @param wr: get write lock for local-zone if 1, read lock if 0
1101  * @param zones_keep_lock: if set do not release the r->local_zones lock, this
1102  * 	  makes the caller of this function responsible for releasing the lock.
1103  * @return: NULL or local-zone holding rd or wr lock
1104  */
1105 static struct local_zone*
1106 rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint16_t qclass,
1107 	int only_exact, int wr, int zones_keep_lock)
1108 {
1109 	uint8_t* ce;
1110 	size_t ce_len;
1111 	int ce_labs;
1112 	uint8_t wc[LDNS_MAX_DOMAINLEN+1];
1113 	int exact;
1114 	struct local_zone* z = NULL;
1115 
1116 	if(wr) {
1117 		lock_rw_wrlock(&zones->lock);
1118 	} else {
1119 		lock_rw_rdlock(&zones->lock);
1120 	}
1121 	z = local_zones_find_le(zones, qname, qname_len,
1122 		dname_count_labels(qname),
1123 		LDNS_RR_CLASS_IN, &exact);
1124 	if(!z || (only_exact && !exact)) {
1125 		if(!zones_keep_lock) {
1126 			lock_rw_unlock(&zones->lock);
1127 		}
1128 		return NULL;
1129 	}
1130 	if(wr) {
1131 		lock_rw_wrlock(&z->lock);
1132 	} else {
1133 		lock_rw_rdlock(&z->lock);
1134 	}
1135 	if(!zones_keep_lock) {
1136 		lock_rw_unlock(&zones->lock);
1137 	}
1138 
1139 	if(exact)
1140 		return z;
1141 
1142 	/* No exact match found, lookup wildcard. closest encloser must
1143 	 * be the shared parent between the qname and the best local
1144 	 * zone match, append '*' to that and do another lookup. */
1145 
1146 	ce = dname_get_shared_topdomain(z->name, qname);
1147 	if(!ce /* should not happen */) {
1148 		lock_rw_unlock(&z->lock);
1149 		if(zones_keep_lock) {
1150 			lock_rw_unlock(&zones->lock);
1151 		}
1152 		return NULL;
1153 	}
1154 	ce_labs = dname_count_size_labels(ce, &ce_len);
1155 	if(ce_len+2 > sizeof(wc)) {
1156 		lock_rw_unlock(&z->lock);
1157 		if(zones_keep_lock) {
1158 			lock_rw_unlock(&zones->lock);
1159 		}
1160 		return NULL;
1161 	}
1162 	wc[0] = 1; /* length of wildcard label */
1163 	wc[1] = (uint8_t)'*'; /* wildcard label */
1164 	memmove(wc+2, ce, ce_len);
1165 	lock_rw_unlock(&z->lock);
1166 
1167 	if(!zones_keep_lock) {
1168 		if(wr) {
1169 			lock_rw_wrlock(&zones->lock);
1170 		} else {
1171 			lock_rw_rdlock(&zones->lock);
1172 		}
1173 	}
1174 	z = local_zones_find_le(zones, wc,
1175 		ce_len+2, ce_labs+1, qclass, &exact);
1176 	if(!z || !exact) {
1177 		lock_rw_unlock(&zones->lock);
1178 		return NULL;
1179 	}
1180 	if(wr) {
1181 		lock_rw_wrlock(&z->lock);
1182 	} else {
1183 		lock_rw_rdlock(&z->lock);
1184 	}
1185 	if(!zones_keep_lock) {
1186 		lock_rw_unlock(&zones->lock);
1187 	}
1188 	return z;
1189 }
1190 
1191 /**
1192  * Remove RR from RPZ's local-data
1193  * @param z: local-zone for RPZ, holding write lock
1194  * @param policydname: dname of RR to remove
1195  * @param policydnamelen: length of policydname
1196  * @param rr_type: RR type of RR to remove
1197  * @param rdata: rdata of RR to remove
1198  * @param rdatalen: length of rdata
1199  * @return: 1 if zone must be removed after RR deletion
1200  */
1201 static int
1202 rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
1203 	size_t policydnamelen, uint16_t rr_type, uint8_t* rdata,
1204 	size_t rdatalen)
1205 {
1206 	struct local_data* ld;
1207 	struct packed_rrset_data* d;
1208 	size_t index;
1209 	ld = local_zone_find_data(z, policydname, policydnamelen,
1210 		dname_count_labels(policydname));
1211 	if(ld) {
1212 		struct local_rrset* prev=NULL, *p=ld->rrsets;
1213 		while(p && ntohs(p->rrset->rk.type) != rr_type) {
1214 			prev = p;
1215 			p = p->next;
1216 		}
1217 		if(!p)
1218 			return 0;
1219 		d = (struct packed_rrset_data*)p->rrset->entry.data;
1220 		if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1221 			if(d->count == 1) {
1222 				/* no memory recycling for zone deletions ... */
1223 				if(prev) prev->next = p->next;
1224 				else ld->rrsets = p->next;
1225 			}
1226 			if(d->count > 1) {
1227 				if(!local_rrset_remove_rr(d, index))
1228 					return 0;
1229 			}
1230 		}
1231 	}
1232 	if(ld && ld->rrsets)
1233 		return 0;
1234 	return 1;
1235 }
1236 
1237 /**
1238  * Remove RR from RPZ's respip set
1239  * @param raddr: respip node
1240  * @param rr_type: RR type of RR to remove
1241  * @param rdata: rdata of RR to remove
1242  * @param rdatalen: length of rdata
1243  * @return: 1 if zone must be removed after RR deletion
1244  */
1245 static int
1246 rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
1247 	size_t rdatalen)
1248 {
1249 	size_t index;
1250 	struct packed_rrset_data* d;
1251 	if(!raddr->data)
1252 		return 1;
1253 	d = raddr->data->entry.data;
1254 	if(ntohs(raddr->data->rk.type) != rr_type) {
1255 		return 0;
1256 	}
1257 	if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
1258 		if(d->count == 1) {
1259 			/* regional alloc'd */
1260 			raddr->data->entry.data = NULL;
1261 			raddr->data = NULL;
1262 			return 1;
1263 		}
1264 		if(d->count > 1) {
1265 			if(!local_rrset_remove_rr(d, index))
1266 				return 0;
1267 		}
1268 	}
1269 	return 0;
1270 
1271 }
1272 
1273 /** Remove RR from RPZ's local-zone */
1274 static void
1275 rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1276 	enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
1277 	uint8_t* rdatawl, size_t rdatalen)
1278 {
1279 	struct local_zone* z;
1280 	int delete_zone = 1;
1281 	z = rpz_find_zone(r->local_zones, dname, dnamelen, rr_class,
1282 		1 /* only exact */, 1 /* wr lock */, 1 /* keep lock*/);
1283 	if(!z) {
1284 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1285 			"RPZ domain not found");
1286 		return;
1287 	}
1288 	if(a == RPZ_LOCAL_DATA_ACTION)
1289 		delete_zone = rpz_data_delete_rr(z, dname,
1290 			dnamelen, rr_type, rdatawl, rdatalen);
1291 	else if(a != localzone_type_to_rpz_action(z->type)) {
1292 		lock_rw_unlock(&z->lock);
1293 		lock_rw_unlock(&r->local_zones->lock);
1294 		return;
1295 	}
1296 	lock_rw_unlock(&z->lock);
1297 	if(delete_zone) {
1298 		local_zones_del_zone(r->local_zones, z);
1299 	}
1300 	lock_rw_unlock(&r->local_zones->lock);
1301 	return;
1302 }
1303 
1304 static void
1305 rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
1306 	enum rpz_action a, uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
1307 {
1308 	struct resp_addr* node;
1309 	struct sockaddr_storage addr;
1310 	socklen_t addrlen;
1311 	int net, af;
1312 	int delete_respip = 1;
1313 
1314 	if(!netblockdnametoaddr(dname, dnamelen, &addr, &addrlen, &net, &af))
1315 		return;
1316 
1317 	lock_rw_wrlock(&r->respip_set->lock);
1318 	if(!(node = (struct resp_addr*)addr_tree_find(
1319 		&r->respip_set->ip_tree, &addr, addrlen, net))) {
1320 		verbose(VERB_ALGO, "rpz: cannot remove RR from IXFR, "
1321 			"RPZ domain not found");
1322 		lock_rw_unlock(&r->respip_set->lock);
1323 		return;
1324 	}
1325 
1326 	lock_rw_wrlock(&node->lock);
1327 	if(a == RPZ_LOCAL_DATA_ACTION) {
1328 		/* remove RR, signal whether RR can be removed */
1329 		delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
1330 			rdatalen);
1331 	}
1332 	lock_rw_unlock(&node->lock);
1333 	if(delete_respip)
1334 		respip_sockaddr_delete(r->respip_set, node);
1335 	lock_rw_unlock(&r->respip_set->lock);
1336 }
1337 
1338 void
1339 rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen,
1340 	uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
1341 {
1342 	size_t policydnamelen;
1343 	enum rpz_trigger t;
1344 	enum rpz_action a;
1345 	uint8_t* policydname;
1346 
1347 	if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
1348 		return;
1349 
1350 	a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
1351 	if(a == RPZ_INVALID_ACTION) {
1352 		free(policydname);
1353 		return;
1354 	}
1355 	if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
1356 		policydname, LDNS_MAX_DOMAINLEN + 1))) {
1357 		free(policydname);
1358 		return;
1359 	}
1360 	t = rpz_dname_to_trigger(policydname, policydnamelen);
1361 	if(t == RPZ_QNAME_TRIGGER) {
1362 		rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
1363 			rr_type, rr_class, rdatawl, rdatalen);
1364 	} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
1365 		rpz_remove_response_ip_trigger(r, policydname, policydnamelen,
1366 			a, rr_type, rdatawl, rdatalen);
1367 	}
1368 	free(policydname);
1369 }
1370 
1371 /** print log information for an applied RPZ policy. Based on local-zone's
1372  * lz_inform_print().
1373  * The repinfo contains the reply address. If it is NULL, the module
1374  * state is used to report the first IP address (if any).
1375  * The dname is used, for the applied rpz, if NULL, addrnode is used.
1376  */
1377 static void
1378 log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
1379 	enum rpz_action a, struct query_info* qinfo,
1380 	struct comm_reply* repinfo, struct module_qstate* ms, char* log_name)
1381 {
1382 	char ip[128], txt[512], portstr[32];
1383 	char dnamestr[LDNS_MAX_DOMAINLEN+1];
1384 	uint16_t port = 0;
1385 	if(dname) {
1386 		dname_str(dname, dnamestr);
1387 	} else if(addrnode) {
1388 		char addrbuf[128];
1389 		addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf));
1390 		snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net);
1391 	} else {
1392 		dnamestr[0]=0;
1393 	}
1394 	if(repinfo) {
1395 		addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip));
1396 		port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port);
1397 	} else if(ms && ms->mesh_info && ms->mesh_info->reply_list) {
1398 		addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr,
1399 			ms->mesh_info->reply_list->query_reply.client_addrlen,
1400 			ip, sizeof(ip));
1401 		port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port);
1402 	} else {
1403 		ip[0]=0;
1404 		port = 0;
1405 	}
1406 	snprintf(portstr, sizeof(portstr), "@%u", (unsigned)port);
1407 	snprintf(txt, sizeof(txt), "rpz: applied %s%s%s%s%s%s %s %s%s",
1408 		(log_name?"[":""), (log_name?log_name:""), (log_name?"] ":""),
1409 		(strcmp(trigger,"qname")==0?"":trigger),
1410 		(strcmp(trigger,"qname")==0?"":" "),
1411 		dnamestr, rpz_action_to_string(a),
1412 		(ip[0]?ip:""), (ip[0]?portstr:""));
1413 	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
1414 }
1415 
1416 static struct clientip_synthesized_rr*
1417 rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set,
1418 	struct sockaddr_storage* addr, socklen_t addrlen, char* triggername)
1419 {
1420 	struct clientip_synthesized_rr* raddr = NULL;
1421 	enum rpz_action action = RPZ_INVALID_ACTION;
1422 
1423 	lock_rw_rdlock(&set->lock);
1424 
1425 	raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries,
1426 			addr, addrlen);
1427 	if(raddr != NULL) {
1428 		lock_rw_rdlock(&raddr->lock);
1429 		action = raddr->action;
1430 		if(verbosity >= VERB_ALGO) {
1431 			char ip[256], net[256];
1432 			addr_to_str(addr, addrlen, ip, sizeof(ip));
1433 			addr_to_str(&raddr->node.addr, raddr->node.addrlen,
1434 				net, sizeof(net));
1435 			verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s",
1436 				triggername, net, raddr->node.net, ip, rpz_action_to_string(action));
1437 		}
1438 	}
1439 	lock_rw_unlock(&set->lock);
1440 
1441 	return raddr;
1442 }
1443 
1444 static inline
1445 struct clientip_synthesized_rr*
1446 rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qinfo,
1447 	struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
1448 	struct ub_server_stats* stats,
1449 	/* output parameters */
1450 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out)
1451 {
1452 	struct clientip_synthesized_rr* node = NULL;
1453 	struct auth_zone* a = NULL;
1454 	struct rpz* r = NULL;
1455 	struct local_zone* z = NULL;
1456 
1457 	lock_rw_rdlock(&az->rpz_lock);
1458 
1459 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
1460 		lock_rw_rdlock(&a->lock);
1461 		r = a->rpz;
1462 		if(r->disabled) {
1463 			lock_rw_unlock(&a->lock);
1464 			continue;
1465 		}
1466 		if(r->taglist && !taglist_intersect(r->taglist,
1467 					r->taglistlen, taglist, taglen)) {
1468 			lock_rw_unlock(&a->lock);
1469 			continue;
1470 		}
1471 		z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len,
1472 			qinfo->qclass, 0, 0, 0);
1473 		node = rpz_ipbased_trigger_lookup(r->client_set,
1474 			&repinfo->client_addr, repinfo->client_addrlen,
1475 			"clientip");
1476 		if((z || node) && r->action_override == RPZ_DISABLED_ACTION) {
1477 			if(r->log)
1478 				log_rpz_apply((node?"clientip":"qname"),
1479 					(z?z->name:NULL),
1480 					(node?&node->node:NULL),
1481 					r->action_override,
1482 					qinfo, repinfo, NULL, r->log_name);
1483 			stats->rpz_action[r->action_override]++;
1484 			if(z != NULL) {
1485 				lock_rw_unlock(&z->lock);
1486 				z = NULL;
1487 			}
1488 			if(node != NULL) {
1489 				lock_rw_unlock(&node->lock);
1490 				node = NULL;
1491 			}
1492 		}
1493 		if(z || node) {
1494 			break;
1495 		}
1496 		/* not found in this auth_zone */
1497 		lock_rw_unlock(&a->lock);
1498 	}
1499 
1500 	lock_rw_unlock(&az->rpz_lock);
1501 
1502 	*r_out = r;
1503 	*a_out = a;
1504 	*z_out = z;
1505 
1506 	return node;
1507 }
1508 
1509 static inline int
1510 rpz_is_udp_query(struct comm_reply* repinfo) {
1511 	return repinfo != NULL
1512 			? (repinfo->c != NULL
1513 				? repinfo->c->type == comm_udp
1514 				: 0)
1515 			: 0;
1516 }
1517 
1518 /** encode answer consisting of 1 rrset */
1519 static int
1520 rpz_local_encode(struct module_env* env, struct query_info* qinfo,
1521 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1522 	struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
1523 	int rcode, struct ub_packed_rrset_key* soa_rrset)
1524 {
1525 	struct reply_info rep;
1526 	uint16_t udpsize;
1527 	struct ub_packed_rrset_key* rrsetlist[3];
1528 
1529 	memset(&rep, 0, sizeof(rep));
1530 	rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
1531 	rep.qdcount = 1;
1532 	rep.rrset_count = ansec;
1533 	rep.rrsets = rrsetlist;
1534 	if(ansec > 0) {
1535 		rep.an_numrrsets = 1;
1536 		rep.rrsets[0] = rrset;
1537 		rep.ttl = ((struct packed_rrset_data*)rrset->entry.data)->rr_ttl[0];
1538 	}
1539 	if(soa_rrset != NULL) {
1540 		rep.ar_numrrsets = 1;
1541 		rep.rrsets[rep.rrset_count] = soa_rrset;
1542 		rep.rrset_count ++;
1543 		if(rep.ttl < ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0]) {
1544 			rep.ttl = ((struct packed_rrset_data*)soa_rrset->entry.data)->rr_ttl[0];
1545 		}
1546 	}
1547 
1548 	udpsize = edns->udp_size;
1549 	edns->edns_version = EDNS_ADVERTISED_VERSION;
1550 	edns->udp_size = EDNS_ADVERTISED_SIZE;
1551 	edns->ext_rcode = 0;
1552 	edns->bits &= EDNS_DO;
1553 	if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
1554 		repinfo, temp, env->now_tv) ||
1555 	  !reply_info_answer_encode(qinfo, &rep,
1556 		*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
1557 		buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
1558 		error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
1559 			*(uint16_t*)sldns_buffer_begin(buf),
1560 			sldns_buffer_read_u16_at(buf, 2), edns);
1561 	}
1562 
1563 	return 1;
1564 }
1565 
1566 static struct local_rrset*
1567 rpz_find_synthesized_rrset(uint16_t qtype,
1568 	struct clientip_synthesized_rr* data)
1569 {
1570 	struct local_rrset* cursor = data->data;
1571 	while( cursor != NULL) {
1572 		struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
1573 		if(htons(qtype) == packed_rrset->type) {
1574 			return cursor;
1575 		}
1576 		cursor = cursor->next;
1577 	}
1578 	return NULL;
1579 }
1580 
1581 /** allocate SOA record ubrrsetkey in region */
1582 static struct ub_packed_rrset_key*
1583 make_soa_ubrrset(struct auth_zone* auth_zone, struct auth_rrset* soa,
1584 	struct regional* temp)
1585 {
1586 	struct ub_packed_rrset_key csoa;
1587 	if(!soa)
1588 		return NULL;
1589 	memset(&csoa, 0, sizeof(csoa));
1590 	csoa.entry.key = &csoa;
1591 	csoa.rk.rrset_class = htons(LDNS_RR_CLASS_IN);
1592 	csoa.rk.type = htons(LDNS_RR_TYPE_SOA);
1593 	csoa.rk.flags |= PACKED_RRSET_FIXEDTTL
1594 		| PACKED_RRSET_RPZ;
1595 	csoa.rk.dname = auth_zone->name;
1596 	csoa.rk.dname_len = auth_zone->namelen;
1597 	csoa.entry.hash = rrset_key_hash(&csoa.rk);
1598 	csoa.entry.data = soa->data;
1599 	return respip_copy_rrset(&csoa, temp);
1600 }
1601 
1602 static void
1603 rpz_apply_clientip_localdata_action(struct clientip_synthesized_rr* raddr,
1604 	struct module_env* env, struct query_info* qinfo,
1605 	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1606 	struct regional* temp, struct auth_zone* auth_zone)
1607 {
1608 	struct local_rrset* rrset;
1609 	enum rpz_action action = RPZ_INVALID_ACTION;
1610 	struct ub_packed_rrset_key* rp = NULL;
1611 	struct ub_packed_rrset_key* rsoa = NULL;
1612 	int rcode = LDNS_RCODE_NOERROR|BIT_AA;
1613 	int rrset_count = 1;
1614 
1615 	/* prepare synthesized answer for client */
1616 	action = raddr->action;
1617 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL ) {
1618 		verbose(VERB_ALGO, "rpz: bug: local-data action but no local data");
1619 		return;
1620 	}
1621 
1622 	/* check query type / rr type */
1623 	rrset = rpz_find_synthesized_rrset(qinfo->qtype, raddr);
1624 	if(rrset == NULL) {
1625 		verbose(VERB_ALGO, "rpz: unable to find local-data for query");
1626 		rrset_count = 0;
1627 		goto nodata;
1628 	}
1629 
1630 	rp = respip_copy_rrset(rrset->rrset, temp);
1631 	if(!rp) {
1632 		verbose(VERB_ALGO, "rpz: local data action: out of memory");
1633 		return;
1634 	}
1635 
1636 	rp->rk.flags |= PACKED_RRSET_FIXEDTTL | PACKED_RRSET_RPZ;
1637 	rp->rk.dname = qinfo->qname;
1638 	rp->rk.dname_len = qinfo->qname_len;
1639 	rp->entry.hash = rrset_key_hash(&rp->rk);
1640 nodata:
1641 	if(auth_zone) {
1642 		struct auth_rrset* soa = NULL;
1643 		soa = auth_zone_get_soa_rrset(auth_zone);
1644 		if(soa) {
1645 			rsoa = make_soa_ubrrset(auth_zone, soa, temp);
1646 			if(!rsoa) {
1647 				verbose(VERB_ALGO, "rpz: local data action soa: out of memory");
1648 				return;
1649 			}
1650 		}
1651 	}
1652 
1653 	rpz_local_encode(env, qinfo, edns, repinfo, buf, temp, rp,
1654 		rrset_count, rcode, rsoa);
1655 }
1656 
1657 /** add additional section SOA record to the reply.
1658  * Since this gets fed into the normal iterator answer creation, it
1659  * gets minimal-responses applied to it, that can remove the additional SOA
1660  * again. */
1661 static int
1662 rpz_add_soa(struct reply_info* rep, struct module_qstate* ms,
1663 	struct auth_zone* az)
1664 {
1665 	struct auth_rrset* soa = NULL;
1666 	struct ub_packed_rrset_key* rsoa = NULL;
1667 	struct ub_packed_rrset_key** prevrrsets;
1668 	if(!az) return 1;
1669 	soa = auth_zone_get_soa_rrset(az);
1670 	if(!soa) return 1;
1671 	if(!rep) return 0;
1672 	rsoa = make_soa_ubrrset(az, soa, ms->region);
1673 	if(!rsoa) return 0;
1674 	prevrrsets = rep->rrsets;
1675 	rep->rrsets = regional_alloc_zero(ms->region,
1676 		sizeof(*rep->rrsets)*(rep->rrset_count+1));
1677 	if(!rep->rrsets)
1678 		return 0;
1679 	if(prevrrsets && rep->rrset_count > 0)
1680 		memcpy(rep->rrsets, prevrrsets, rep->rrset_count*sizeof(*rep->rrsets));
1681 	rep->rrset_count++;
1682 	rep->ar_numrrsets++;
1683 	rep->rrsets[rep->rrset_count-1] = rsoa;
1684 	return 1;
1685 }
1686 
1687 static inline struct dns_msg*
1688 rpz_dns_msg_new(struct regional* region)
1689 {
1690 	struct dns_msg* msg =
1691 			(struct dns_msg*)regional_alloc(region,
1692 							sizeof(struct dns_msg));
1693 	if(msg == NULL) { return NULL; }
1694 	memset(msg, 0, sizeof(struct dns_msg));
1695 
1696 	return msg;
1697 }
1698 
1699 static inline struct dns_msg*
1700 rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
1701 	struct query_info* qinfo, struct auth_zone* az)
1702 {
1703 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1704 	if(msg == NULL) { return msg; }
1705 	msg->qinfo = *qinfo;
1706 	msg->rep = construct_reply_info_base(ms->region,
1707 					     LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1708 					     1, /* qd */
1709 					     0, /* ttl */
1710 					     0, /* prettl */
1711 					     0, /* expttl */
1712 					     0, /* an */
1713 					     0, /* ns */
1714 					     0, /* ar */
1715 					     0, /* total */
1716 					     sec_status_insecure);
1717 	if(msg->rep)
1718 		msg->rep->authoritative = 1;
1719 	if(!rpz_add_soa(msg->rep, ms, az))
1720 		return NULL;
1721 	return msg;
1722 }
1723 
1724 static inline struct dns_msg*
1725 rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
1726 	struct query_info* qinfo, struct auth_zone* az)
1727 {
1728 	struct dns_msg* msg = rpz_dns_msg_new(ms->region);
1729 	uint16_t flags;
1730 	if(msg == NULL) { return msg; }
1731 	msg->qinfo = *qinfo;
1732 	flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA;
1733 	if(r->signal_nxdomain_ra)
1734 		flags &= ~BIT_RA;
1735 	msg->rep = construct_reply_info_base(ms->region,
1736 					     flags,
1737 					     1, /* qd */
1738 					     0, /* ttl */
1739 					     0, /* prettl */
1740 					     0, /* expttl */
1741 					     0, /* an */
1742 					     0, /* ns */
1743 					     0, /* ar */
1744 					     0, /* total */
1745 					     sec_status_insecure);
1746 	if(msg->rep)
1747 		msg->rep->authoritative = 1;
1748 	if(!rpz_add_soa(msg->rep, ms, az))
1749 		return NULL;
1750 	return msg;
1751 }
1752 
1753 static inline struct dns_msg*
1754 rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
1755 	struct query_info* qi, struct local_rrset* rrset, struct auth_zone* az)
1756 {
1757 	struct dns_msg* msg = NULL;
1758 	struct reply_info* new_reply_info;
1759 	struct ub_packed_rrset_key* rp;
1760 
1761 
1762 	msg = rpz_dns_msg_new(ms->region);
1763 	if(msg == NULL) { return NULL; }
1764 
1765         new_reply_info = construct_reply_info_base(ms->region,
1766                                                    LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1767                                                    1, /* qd */
1768                                                    0, /* ttl */
1769                                                    0, /* prettl */
1770                                                    0, /* expttl */
1771                                                    1, /* an */
1772                                                    0, /* ns */
1773                                                    0, /* ar */
1774                                                    1, /* total */
1775                                                    sec_status_insecure);
1776 	if(new_reply_info == NULL) {
1777 		log_err("out of memory");
1778 		return NULL;
1779 	}
1780 	new_reply_info->authoritative = 1;
1781 	rp = respip_copy_rrset(rrset->rrset, ms->region);
1782 	if(rp == NULL) {
1783 		log_err("out of memory");
1784 		return NULL;
1785 	}
1786 	rp->rk.dname = qi->qname;
1787 	rp->rk.dname_len = qi->qname_len;
1788 	/* this rrset is from the rpz data, or synthesized.
1789 	 * It is not actually from the network, so we flag it with this
1790 	 * flags as a fake RRset. If later the cache is used to look up
1791 	 * rrsets, then the fake ones are not returned (if you look without
1792 	 * the flag). For like CNAME lookups from the iterator or A, AAAA
1793 	 * lookups for nameserver targets, it would use the without flag
1794 	 * actual data. So that the actual network data and fake data
1795 	 * are kept track of separately. */
1796 	rp->rk.flags |= PACKED_RRSET_RPZ;
1797 	new_reply_info->rrsets[0] = rp;
1798 	msg->rep = new_reply_info;
1799 	if(!rpz_add_soa(msg->rep, ms, az))
1800 		return NULL;
1801 	return msg;
1802 }
1803 
1804 static inline struct dns_msg*
1805 rpz_synthesize_nsip_localdata(struct rpz* r, struct module_qstate* ms,
1806 	struct clientip_synthesized_rr* data, struct auth_zone* az)
1807 {
1808 	struct query_info* qi = &ms->qinfo;
1809 	struct local_rrset* rrset;
1810 
1811 	rrset = rpz_find_synthesized_rrset(qi->qtype, data);
1812 	if(rrset == NULL) {
1813 		verbose(VERB_ALGO, "rpz: nsip: no matching local data found");
1814 		return NULL;
1815 	}
1816 
1817 	return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az);
1818 }
1819 
1820 /* copy'n'paste from localzone.c */
1821 static struct local_rrset*
1822 local_data_find_type(struct local_data* data, uint16_t type, int alias_ok)
1823 {
1824 	struct local_rrset* p;
1825 	type = htons(type);
1826 	for(p = data->rrsets; p; p = p->next) {
1827 		if(p->rrset->rk.type == type)
1828 			return p;
1829 		if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME))
1830 			return p;
1831 	}
1832 	return NULL;
1833 }
1834 
1835 /* based on localzone.c:local_data_answer() */
1836 static inline struct dns_msg*
1837 rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
1838 	struct local_zone* z, struct matched_delegation_point const* match,
1839 	struct auth_zone* az)
1840 {
1841 	struct local_data key;
1842 	struct local_data* ld;
1843 	struct local_rrset* rrset;
1844 
1845 	if(match->dname == NULL) { return NULL; }
1846 
1847 	key.node.key = &key;
1848 	key.name = match->dname;
1849 	key.namelen = match->dname_len;
1850 	key.namelabs = dname_count_labels(match->dname);
1851 
1852 	rpz_log_dname("nsdname local data", key.name, key.namelen);
1853 
1854 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
1855 	if(ld == NULL) {
1856 		verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
1857 		return NULL;
1858 	}
1859 
1860 	rrset = local_data_find_type(ld, ms->qinfo.qtype, 1);
1861 	if(rrset == NULL) {
1862 		verbose(VERB_ALGO, "rpz: nsdname: no matching local data found");
1863 		return NULL;
1864 	}
1865 
1866 	return rpz_synthesize_localdata_from_rrset(r, ms, &ms->qinfo, rrset, az);
1867 }
1868 
1869 /* like local_data_answer for qname triggers after a cname */
1870 static struct dns_msg*
1871 rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
1872 	struct query_info* qinfo, struct local_zone* z, struct auth_zone* az)
1873 {
1874 	struct local_data key;
1875 	struct local_data* ld;
1876 	struct local_rrset* rrset;
1877 	key.node.key = &key;
1878 	key.name = qinfo->qname;
1879 	key.namelen = qinfo->qname_len;
1880 	key.namelabs = dname_count_labels(qinfo->qname);
1881 	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
1882 	if(ld == NULL) {
1883 		verbose(VERB_ALGO, "rpz: qname after cname: name not found");
1884 		return NULL;
1885 	}
1886 	rrset = local_data_find_type(ld, qinfo->qtype, 1);
1887 	if(rrset == NULL) {
1888 		verbose(VERB_ALGO, "rpz: qname after cname: type not found");
1889 		return NULL;
1890 	}
1891 	return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az);
1892 }
1893 
1894 static int
1895 rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
1896 	struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo,
1897 	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
1898 	struct comm_reply* repinfo, struct ub_server_stats* stats)
1899 {
1900 	struct local_data* ld = NULL;
1901 	int ret = 0;
1902 	if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
1903 		qinfo->local_alias = regional_alloc_zero(temp, sizeof(struct local_rrset));
1904 		if(qinfo->local_alias == NULL) {
1905 			return 0; /* out of memory */
1906 		}
1907 		qinfo->local_alias->rrset = regional_alloc_init(temp, r->cname_override,
1908 								sizeof(*r->cname_override));
1909 		if(qinfo->local_alias->rrset == 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 		if(r->log) {
1915 			log_rpz_apply("qname", z->name, NULL, RPZ_CNAME_OVERRIDE_ACTION,
1916 				      qinfo, repinfo, NULL, r->log_name);
1917 		}
1918 		stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
1919 		return 0;
1920 	}
1921 
1922 	if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
1923 		edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
1924 		&ld, lzt, -1, NULL, 0, NULL, 0)) {
1925 		if(r->log) {
1926 			log_rpz_apply("qname", z->name, NULL,
1927 				localzone_type_to_rpz_action(lzt), qinfo,
1928 				repinfo, NULL, r->log_name);
1929 		}
1930 		stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
1931 		return !qinfo->local_alias;
1932 	}
1933 
1934 	ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
1935 		0 /* no local data used */, lzt);
1936 	if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
1937 		== LDNS_RCODE_NXDOMAIN)
1938 		LDNS_RA_CLR(sldns_buffer_begin(buf));
1939 	if(r->log) {
1940 		log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt),
1941 			      qinfo, repinfo, NULL, r->log_name);
1942 	}
1943 	stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
1944 	return ret;
1945 }
1946 
1947 static struct clientip_synthesized_rr*
1948 rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is)
1949 {
1950 	struct delegpt_addr* cursor;
1951 	struct clientip_synthesized_rr* action = NULL;
1952 	if(is->dp == NULL) { return NULL; }
1953 	for(cursor = is->dp->target_list;
1954 	    cursor != NULL;
1955 	    cursor = cursor->next_target) {
1956 		if(cursor->bogus) { continue; }
1957 		action = rpz_ipbased_trigger_lookup(rpz->ns_set, &cursor->addr,
1958 						    cursor->addrlen, "nsip");
1959 		if(action != NULL) { return action; }
1960 	}
1961 	return NULL;
1962 }
1963 
1964 static struct dns_msg*
1965 rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
1966 	struct clientip_synthesized_rr* raddr, struct auth_zone* az)
1967 {
1968 	enum rpz_action action = raddr->action;
1969 	struct dns_msg* ret = NULL;
1970 
1971 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
1972 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
1973 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
1974 		action = r->action_override;
1975 	}
1976 
1977 	if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) {
1978 		verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data");
1979 		ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az);
1980 		goto done;
1981 	}
1982 
1983 	switch(action) {
1984 	case RPZ_NXDOMAIN_ACTION:
1985 		ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az);
1986 		break;
1987 	case RPZ_NODATA_ACTION:
1988 		ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az);
1989 		break;
1990 	case RPZ_TCP_ONLY_ACTION:
1991 		/* basically a passthru here but the tcp-only will be
1992 		 * honored before the query gets sent. */
1993 		ms->respip_action_info->action = respip_truncate;
1994 		ret = NULL;
1995 		break;
1996 	case RPZ_DROP_ACTION:
1997 		ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az);
1998 		ms->is_drop = 1;
1999 		break;
2000 	case RPZ_LOCAL_DATA_ACTION:
2001 		ret = rpz_synthesize_nsip_localdata(r, ms, raddr, az);
2002 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); }
2003 		break;
2004 	case RPZ_PASSTHRU_ACTION:
2005 		ret = NULL;
2006 		ms->rpz_passthru = 1;
2007 		break;
2008 	default:
2009 		verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
2010 			rpz_action_to_string(action));
2011 		ret = NULL;
2012 	}
2013 
2014 done:
2015 	if(r->log)
2016 		log_rpz_apply("nsip", NULL, &raddr->node,
2017 			action, &ms->qinfo, NULL, ms, r->log_name);
2018 	if(ms->env->worker)
2019 		ms->env->worker->stats.rpz_action[action]++;
2020 	lock_rw_unlock(&raddr->lock);
2021 	return ret;
2022 }
2023 
2024 static struct dns_msg*
2025 rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
2026 	struct local_zone* z, struct matched_delegation_point const* match,
2027 	struct auth_zone* az)
2028 {
2029 	struct dns_msg* ret = NULL;
2030 	enum rpz_action action = localzone_type_to_rpz_action(z->type);
2031 
2032 	if(r->action_override != RPZ_NO_OVERRIDE_ACTION) {
2033 		verbose(VERB_ALGO, "rpz: using override action=%s (replaces=%s)",
2034 			rpz_action_to_string(r->action_override), rpz_action_to_string(action));
2035 		action = r->action_override;
2036 	}
2037 
2038 	switch(action) {
2039 	case RPZ_NXDOMAIN_ACTION:
2040 		ret = rpz_synthesize_nxdomain(r, ms, &ms->qinfo, az);
2041 		break;
2042 	case RPZ_NODATA_ACTION:
2043 		ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az);
2044 		break;
2045 	case RPZ_TCP_ONLY_ACTION:
2046 		/* basically a passthru here but the tcp-only will be
2047 		 * honored before the query gets sent. */
2048 		ms->respip_action_info->action = respip_truncate;
2049 		ret = NULL;
2050 		break;
2051 	case RPZ_DROP_ACTION:
2052 		ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az);
2053 		ms->is_drop = 1;
2054 		break;
2055 	case RPZ_LOCAL_DATA_ACTION:
2056 		ret = rpz_synthesize_nsdname_localdata(r, ms, z, match, az);
2057 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &ms->qinfo, az); }
2058 		break;
2059 	case RPZ_PASSTHRU_ACTION:
2060 		ret = NULL;
2061 		ms->rpz_passthru = 1;
2062 		break;
2063 	default:
2064 		verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
2065 			rpz_action_to_string(action));
2066 		ret = NULL;
2067 	}
2068 
2069 	if(r->log)
2070 		log_rpz_apply("nsdname", match->dname, NULL,
2071 			action, &ms->qinfo, NULL, ms, r->log_name);
2072 	if(ms->env->worker)
2073 		ms->env->worker->stats.rpz_action[action]++;
2074 	lock_rw_unlock(&z->lock);
2075 	return ret;
2076 }
2077 
2078 static struct local_zone*
2079 rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones,
2080 	uint16_t qclass,
2081 	/* output parameter */
2082 	struct matched_delegation_point* match)
2083 {
2084 	struct delegpt_ns* nameserver;
2085 	struct local_zone* z = NULL;
2086 
2087 	/* the rpz specs match the nameserver names (NS records), not the
2088 	 * name of the delegation point itself, to the nsdname triggers */
2089 	for(nameserver = dp->nslist;
2090 	    nameserver != NULL;
2091 	    nameserver = nameserver->next) {
2092 		z = rpz_find_zone(zones, nameserver->name, nameserver->namelen,
2093 				  qclass, 0, 0, 0);
2094 		if(z != NULL) {
2095 			match->dname = nameserver->name;
2096 			match->dname_len = nameserver->namelen;
2097 			if(verbosity >= VERB_ALGO) {
2098 				char nm[255+1], zn[255+1];
2099 				dname_str(match->dname, nm);
2100 				dname_str(z->name, zn);
2101 				if(strcmp(nm, zn) != 0)
2102 					verbose(VERB_ALGO, "rpz: trigger nsdname %s on %s action=%s",
2103 						zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2104 				else
2105 					verbose(VERB_ALGO, "rpz: trigger nsdname %s action=%s",
2106 						nm, rpz_action_to_string(localzone_type_to_rpz_action(z->type)));
2107 			}
2108 			break;
2109 		}
2110 	}
2111 
2112 	return z;
2113 }
2114 
2115 struct dns_msg*
2116 rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate* is)
2117 {
2118 	struct auth_zones* az;
2119 	struct auth_zone* a;
2120 	struct clientip_synthesized_rr* raddr = NULL;
2121 	struct rpz* r = NULL;
2122 	struct local_zone* z = NULL;
2123 	struct matched_delegation_point match = {0};
2124 
2125 	if(ms->rpz_passthru) {
2126 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2127 		return NULL;
2128 	}
2129 
2130 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2131 
2132 	az = ms->env->auth_zones;
2133 
2134 	verbose(VERB_ALGO, "rpz: iterator module callback: have_rpz=%d", az->rpz_first != NULL);
2135 
2136 	lock_rw_rdlock(&az->rpz_lock);
2137 
2138 	/* precedence of RPZ works, loosely, like this:
2139 	 * CNAMEs in order of the CNAME chain. rpzs in the order they are
2140 	 * configured. In an RPZ: first client-IP addr, then QNAME, then
2141 	 * response IP, then NSDNAME, then NSIP. Longest match first. Smallest
2142 	 * one from a set. */
2143 	/* we use the precedence rules for the topics and triggers that
2144 	 * are pertinent at this stage of the resolve processing */
2145 	for(a = az->rpz_first; a != NULL; a = a->rpz_az_next) {
2146 		lock_rw_rdlock(&a->lock);
2147 		r = a->rpz;
2148 		if(r->disabled) {
2149 			lock_rw_unlock(&a->lock);
2150 			continue;
2151 		}
2152 
2153 		/* the nsdname has precedence over the nsip triggers */
2154 		z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
2155 						     ms->qinfo.qclass, &match);
2156 		if(z != NULL) {
2157 			lock_rw_unlock(&a->lock);
2158 			break;
2159 		}
2160 
2161 		raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is);
2162 		if(raddr != NULL) {
2163 			lock_rw_unlock(&a->lock);
2164 			break;
2165 		}
2166 		lock_rw_unlock(&a->lock);
2167 	}
2168 
2169 	lock_rw_unlock(&az->rpz_lock);
2170 
2171 	if(raddr == NULL && z == NULL)
2172 		return NULL;
2173 
2174 	if(raddr != NULL) {
2175 		if(z) {
2176 			lock_rw_unlock(&z->lock);
2177 		}
2178 		return rpz_apply_nsip_trigger(ms, r, raddr, a);
2179 	}
2180 	return rpz_apply_nsdname_trigger(ms, r, z, &match, a);
2181 }
2182 
2183 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
2184 	struct iter_qstate* is)
2185 {
2186 	struct auth_zones* az;
2187 	struct auth_zone* a = NULL;
2188 	struct rpz* r = NULL;
2189 	struct local_zone* z = NULL;
2190 	enum localzone_type lzt;
2191 	struct dns_msg* ret = NULL;
2192 
2193 	if(ms->rpz_passthru) {
2194 		verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
2195 		return NULL;
2196 	}
2197 
2198 	if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
2199 	az = ms->env->auth_zones;
2200 
2201 	lock_rw_rdlock(&az->rpz_lock);
2202 
2203 	for(a = az->rpz_first; a; a = a->rpz_az_next) {
2204 		lock_rw_rdlock(&a->lock);
2205 		r = a->rpz;
2206 		if(r->disabled) {
2207 			lock_rw_unlock(&a->lock);
2208 			continue;
2209 		}
2210 		z = rpz_find_zone(r->local_zones, is->qchase.qname,
2211 			is->qchase.qname_len, is->qchase.qclass, 0, 0, 0);
2212 		if(z && r->action_override == RPZ_DISABLED_ACTION) {
2213 			if(r->log)
2214 				log_rpz_apply("qname", z->name, NULL,
2215 					r->action_override,
2216 					&ms->qinfo, NULL, ms, r->log_name);
2217 			if(ms->env->worker)
2218 				ms->env->worker->stats.rpz_action[r->action_override]++;
2219 			lock_rw_unlock(&z->lock);
2220 			z = NULL;
2221 		}
2222 		if(z) {
2223 			break;
2224 		}
2225 		/* not found in this auth_zone */
2226 		lock_rw_unlock(&a->lock);
2227 	}
2228 	lock_rw_unlock(&az->rpz_lock);
2229 
2230 	if(z == NULL)
2231 		return NULL;
2232 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2233 		lzt = z->type;
2234 	} else {
2235 		lzt = rpz_action_to_localzone_type(r->action_override);
2236 	}
2237 
2238 	if(verbosity >= VERB_ALGO) {
2239 		char nm[255+1], zn[255+1];
2240 		dname_str(is->qchase.qname, nm);
2241 		dname_str(z->name, zn);
2242 		if(strcmp(zn, nm) != 0)
2243 			verbose(VERB_ALGO, "rpz: qname trigger after cname %s on %s, with action=%s",
2244 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2245 		else
2246 			verbose(VERB_ALGO, "rpz: qname trigger after cname %s, with action=%s",
2247 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2248 	}
2249 	switch(localzone_type_to_rpz_action(lzt)) {
2250 	case RPZ_NXDOMAIN_ACTION:
2251 		ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a);
2252 		break;
2253 	case RPZ_NODATA_ACTION:
2254 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2255 		break;
2256 	case RPZ_TCP_ONLY_ACTION:
2257 		/* basically a passthru here but the tcp-only will be
2258 		 * honored before the query gets sent. */
2259 		ms->respip_action_info->action = respip_truncate;
2260 		ret = NULL;
2261 		break;
2262 	case RPZ_DROP_ACTION:
2263 		ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
2264 		ms->is_drop = 1;
2265 		break;
2266 	case RPZ_LOCAL_DATA_ACTION:
2267 		ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a);
2268 		if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); }
2269 		break;
2270 	case RPZ_PASSTHRU_ACTION:
2271 		ret = NULL;
2272 		ms->rpz_passthru = 1;
2273 		break;
2274 	default:
2275 		verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'",
2276 			rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2277 		ret = NULL;
2278 	}
2279 	lock_rw_unlock(&z->lock);
2280 	lock_rw_unlock(&a->lock);
2281 	return ret;
2282 }
2283 
2284 static int
2285 rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
2286 	struct query_info* qinfo, struct edns_data* edns, struct comm_reply* repinfo,
2287 	uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
2288 	sldns_buffer* buf, struct regional* temp,
2289 	/* output parameters */
2290 	struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out,
2291 	int* passthru)
2292 {
2293 	int ret = 0;
2294 	enum rpz_action client_action;
2295 	struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone(
2296 		az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
2297 
2298 	client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
2299 	if(client_action == RPZ_PASSTHRU_ACTION) {
2300 		*passthru = 1;
2301 	}
2302 	if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION &&
2303 			      client_action != RPZ_PASSTHRU_ACTION)) {
2304 		if(client_action == RPZ_PASSTHRU_ACTION
2305 			|| client_action == RPZ_INVALID_ACTION
2306 			|| (client_action == RPZ_TCP_ONLY_ACTION
2307 				&& !rpz_is_udp_query(repinfo))) {
2308 			ret = 0;
2309 			goto done;
2310 		}
2311 		stats->rpz_action[client_action]++;
2312 		if(client_action == RPZ_LOCAL_DATA_ACTION) {
2313 			rpz_apply_clientip_localdata_action(node, env, qinfo,
2314 				edns, repinfo, buf, temp, *a_out);
2315 		} else {
2316 			if(*r_out && (*r_out)->log)
2317 				log_rpz_apply(
2318 					(node?"clientip":"qname"),
2319 					((*z_out)?(*z_out)->name:NULL),
2320 					(node?&node->node:NULL),
2321 					client_action, qinfo, repinfo, NULL,
2322 					(*r_out)->log_name);
2323 			local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns,
2324 				repinfo, buf, temp, 0 /* no local data used */,
2325 				rpz_action_to_localzone_type(client_action));
2326 			if(*r_out && (*r_out)->signal_nxdomain_ra &&
2327 				LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
2328 				== LDNS_RCODE_NXDOMAIN)
2329 				LDNS_RA_CLR(sldns_buffer_begin(buf));
2330 		}
2331 		ret = 1;
2332 		goto done;
2333 	}
2334 	ret = -1;
2335 done:
2336 	if(node != NULL) {
2337 		lock_rw_unlock(&node->lock);
2338 	}
2339 	return ret;
2340 }
2341 
2342 int
2343 rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
2344 	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
2345 	struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
2346 	size_t taglen, struct ub_server_stats* stats, int* passthru)
2347 {
2348 	struct rpz* r = NULL;
2349 	struct auth_zone* a = NULL;
2350 	struct local_zone* z = NULL;
2351 	int ret;
2352 	enum localzone_type lzt;
2353 
2354 	int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
2355 		edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r,
2356 		passthru);
2357 	if(clientip_trigger >= 0) {
2358 		if(a) {
2359 			lock_rw_unlock(&a->lock);
2360 		}
2361 		if(z) {
2362 			lock_rw_unlock(&z->lock);
2363 		}
2364 		return clientip_trigger;
2365 	}
2366 
2367 	if(z == NULL) {
2368 		if(a) {
2369 			lock_rw_unlock(&a->lock);
2370 		}
2371 		return 0;
2372 	}
2373 
2374 	log_assert(r);
2375 
2376 	if(r->action_override == RPZ_NO_OVERRIDE_ACTION) {
2377 		lzt = z->type;
2378 	} else {
2379 		lzt = rpz_action_to_localzone_type(r->action_override);
2380 	}
2381 	if(r->action_override == RPZ_PASSTHRU_ACTION ||
2382 		lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) {
2383 		*passthru = 1;
2384 	}
2385 
2386 	if(verbosity >= VERB_ALGO) {
2387 		char nm[255+1], zn[255+1];
2388 		dname_str(qinfo->qname, nm);
2389 		dname_str(z->name, zn);
2390 		if(strcmp(zn, nm) != 0)
2391 			verbose(VERB_ALGO, "rpz: qname trigger %s on %s with action=%s",
2392 				zn, nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2393 		else
2394 			verbose(VERB_ALGO, "rpz: qname trigger %s with action=%s",
2395 				nm, rpz_action_to_string(localzone_type_to_rpz_action(lzt)));
2396 	}
2397 
2398 	ret = rpz_synthesize_qname_localdata(env, r, z, lzt, qinfo, edns, buf, temp,
2399 					     repinfo, stats);
2400 
2401 	lock_rw_unlock(&z->lock);
2402 	lock_rw_unlock(&a->lock);
2403 
2404 	return ret;
2405 }
2406 
2407 void rpz_enable(struct rpz* r)
2408 {
2409     if(!r)
2410         return;
2411     r->disabled = 0;
2412 }
2413 
2414 void rpz_disable(struct rpz* r)
2415 {
2416     if(!r)
2417         return;
2418     r->disabled = 1;
2419 }
2420