1/*
2 * services/localzone.c - local zones authority service.
3 *
4 * Copyright (c) 2007, 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 local zone authority service.
40 */
41#include "config.h"
42#include "services/localzone.h"
43#include "sldns/str2wire.h"
44#include "util/regional.h"
45#include "util/config_file.h"
46#include "util/data/dname.h"
47#include "util/data/packed_rrset.h"
48#include "util/data/msgencode.h"
49#include "util/net_help.h"
50#include "util/netevent.h"
51#include "util/data/msgreply.h"
52#include "util/data/msgparse.h"
53#include "util/as112.h"
54
55/* maximum RRs in an RRset, to cap possible 'endless' list RRs.
56 * with 16 bytes for an A record, a 64K packet has about 4000 max */
57#define LOCALZONE_RRSET_COUNT_MAX 4096
58
59/** print all RRsets in local zone */
60static void
61local_zone_out(struct local_zone* z)
62{
63	struct local_data* d;
64	struct local_rrset* p;
65	RBTREE_FOR(d, struct local_data*, &z->data) {
66		for(p = d->rrsets; p; p = p->next) {
67			log_nametypeclass(NO_VERBOSE, "rrset", d->name,
68				ntohs(p->rrset->rk.type),
69				ntohs(p->rrset->rk.rrset_class));
70		}
71	}
72}
73
74static void
75local_zone_print(struct local_zone* z)
76{
77	char buf[64];
78	lock_rw_rdlock(&z->lock);
79	snprintf(buf, sizeof(buf), "%s zone",
80		local_zone_type2str(z->type));
81	log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
82	local_zone_out(z);
83	lock_rw_unlock(&z->lock);
84}
85
86void local_zones_print(struct local_zones* zones)
87{
88	struct local_zone* z;
89	lock_rw_rdlock(&zones->lock);
90	log_info("number of auth zones %u", (unsigned)zones->ztree.count);
91	RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
92		local_zone_print(z);
93	}
94	lock_rw_unlock(&zones->lock);
95}
96
97struct local_zones*
98local_zones_create(void)
99{
100	struct local_zones* zones = (struct local_zones*)calloc(1,
101		sizeof(*zones));
102	if(!zones)
103		return NULL;
104	rbtree_init(&zones->ztree, &local_zone_cmp);
105	lock_rw_init(&zones->lock);
106	lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree));
107	/* also lock protects the rbnode's in struct local_zone */
108	return zones;
109}
110
111/** helper traverse to delete zones */
112static void
113lzdel(rbnode_type* n, void* ATTR_UNUSED(arg))
114{
115	struct local_zone* z = (struct local_zone*)n->key;
116	local_zone_delete(z);
117}
118
119void
120local_zones_delete(struct local_zones* zones)
121{
122	if(!zones)
123		return;
124	lock_rw_destroy(&zones->lock);
125	/* walk through zones and delete them all */
126	traverse_postorder(&zones->ztree, lzdel, NULL);
127	free(zones);
128}
129
130void
131local_zone_delete(struct local_zone* z)
132{
133	if(!z)
134		return;
135	lock_rw_destroy(&z->lock);
136	regional_destroy(z->region);
137	free(z->name);
138	free(z->taglist);
139	free(z);
140}
141
142int
143local_zone_cmp(const void* z1, const void* z2)
144{
145	/* first sort on class, so that hierarchy can be maintained within
146	 * a class */
147	struct local_zone* a = (struct local_zone*)z1;
148	struct local_zone* b = (struct local_zone*)z2;
149	int m;
150	if(a->dclass != b->dclass) {
151		if(a->dclass < b->dclass)
152			return -1;
153		return 1;
154	}
155	return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m);
156}
157
158int
159local_data_cmp(const void* d1, const void* d2)
160{
161	struct local_data* a = (struct local_data*)d1;
162	struct local_data* b = (struct local_data*)d2;
163	int m;
164	return dname_canon_lab_cmp(a->name, a->namelabs, b->name,
165		b->namelabs, &m);
166}
167
168/* form wireformat from text format domain name */
169int
170parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
171{
172	*res = sldns_str2wire_dname(str, len);
173	*labs = 0;
174	if(!*res) {
175		log_err("cannot parse name %s", str);
176		return 0;
177	}
178	*labs = dname_count_size_labels(*res, len);
179	return 1;
180}
181
182/** create a new localzone */
183static struct local_zone*
184local_zone_create(uint8_t* nm, size_t len, int labs,
185	enum localzone_type t, uint16_t dclass)
186{
187	struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z));
188	if(!z) {
189		return NULL;
190	}
191	z->node.key = z;
192	z->dclass = dclass;
193	z->type = t;
194	z->name = nm;
195	z->namelen = len;
196	z->namelabs = labs;
197	lock_rw_init(&z->lock);
198	z->region = regional_create_nochunk(sizeof(struct regional));
199	if(!z->region) {
200		free(z);
201		return NULL;
202	}
203	rbtree_init(&z->data, &local_data_cmp);
204	lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_type));
205	/* also the zones->lock protects node, parent, name*, class */
206	return z;
207}
208
209/** enter a new zone with allocated dname returns with WRlock */
210static struct local_zone*
211lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
212	int labs, enum localzone_type t, uint16_t c)
213{
214	struct local_zone* z = local_zone_create(nm, len, labs, t, c);
215	if(!z) {
216		free(nm);
217		log_err("out of memory");
218		return NULL;
219	}
220
221	/* add to rbtree */
222	lock_rw_wrlock(&zones->lock);
223	lock_rw_wrlock(&z->lock);
224	if(!rbtree_insert(&zones->ztree, &z->node)) {
225		struct local_zone* oldz;
226		char str[256];
227		dname_str(nm, str);
228		log_warn("duplicate local-zone %s", str);
229		lock_rw_unlock(&z->lock);
230		/* save zone name locally before deallocation,
231		 * otherwise, nm is gone if we zone_delete now. */
232		oldz = z;
233		/* find the correct zone, so not an error for duplicate */
234		z = local_zones_find(zones, nm, len, labs, c);
235		lock_rw_wrlock(&z->lock);
236		lock_rw_unlock(&zones->lock);
237		local_zone_delete(oldz);
238		return z;
239	}
240	lock_rw_unlock(&zones->lock);
241	return z;
242}
243
244/** enter a new zone */
245static struct local_zone*
246lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
247	uint16_t dclass)
248{
249	struct local_zone* z;
250	enum localzone_type t;
251	uint8_t* nm;
252	size_t len;
253	int labs;
254	if(!parse_dname(name, &nm, &len, &labs)) {
255		log_err("bad zone name %s %s", name, type);
256		return NULL;
257	}
258	if(!local_zone_str2type(type, &t)) {
259		log_err("bad lz_enter_zone type %s %s", name, type);
260		free(nm);
261		return NULL;
262	}
263	if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) {
264		log_err("could not enter zone %s %s", name, type);
265		return NULL;
266	}
267	return z;
268}
269
270int
271rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
272	uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
273	uint8_t** rdata, size_t* rdata_len)
274{
275	size_t dname_len = 0;
276	int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
277		NULL, 0, NULL, 0);
278	if(e) {
279		log_err("error parsing local-data at %d: '%s': %s",
280			LDNS_WIREPARSE_OFFSET(e), str,
281			sldns_get_errorstr_parse(e));
282		return 0;
283	}
284	*nm = memdup(rr, dname_len);
285	if(!*nm) {
286		log_err("out of memory");
287		return 0;
288	}
289	*dclass = sldns_wirerr_get_class(rr, len, dname_len);
290	*type = sldns_wirerr_get_type(rr, len, dname_len);
291	*ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len);
292	*rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len);
293	*rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2;
294	return 1;
295}
296
297/** return name and class of rr; parses string */
298static int
299get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass,
300	uint16_t* dtype)
301{
302	uint8_t rr[LDNS_RR_BUF_SIZE];
303	size_t len = sizeof(rr), dname_len = 0;
304	int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
305		NULL, 0, NULL, 0);
306	if(s != 0) {
307		log_err("error parsing local-data at %d '%s': %s",
308			LDNS_WIREPARSE_OFFSET(s), str,
309			sldns_get_errorstr_parse(s));
310		return 0;
311	}
312	*nm = memdup(rr, dname_len);
313	*dclass = sldns_wirerr_get_class(rr, len, dname_len);
314	*dtype = sldns_wirerr_get_type(rr, len, dname_len);
315	if(!*nm) {
316		log_err("out of memory");
317		return 0;
318	}
319	return 1;
320}
321
322/**
323 * Find an rrset in local data structure.
324 * @param data: local data domain name structure.
325 * @param type: type to look for (host order).
326 * @param alias_ok: 1 if matching a non-exact, alias type such as CNAME is
327 * allowed.  otherwise 0.
328 * @return rrset pointer or NULL if not found.
329 */
330static struct local_rrset*
331local_data_find_type(struct local_data* data, uint16_t type, int alias_ok)
332{
333	struct local_rrset* p;
334	type = htons(type);
335	for(p = data->rrsets; p; p = p->next) {
336		if(p->rrset->rk.type == type)
337			return p;
338		if(alias_ok && p->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME))
339			return p;
340	}
341	return NULL;
342}
343
344/** check for RR duplicates */
345static int
346rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
347{
348	size_t i;
349	for(i=0; i<pd->count; i++) {
350		if(pd->rr_len[i] == rdata_len &&
351			memcmp(pd->rr_data[i], rdata, rdata_len) == 0)
352			return 1;
353	}
354	return 0;
355}
356
357/** new local_rrset */
358static struct local_rrset*
359new_local_rrset(struct regional* region, struct local_data* node,
360	uint16_t rrtype, uint16_t rrclass)
361{
362	struct packed_rrset_data* pd;
363	struct local_rrset* rrset = (struct local_rrset*)
364		regional_alloc_zero(region, sizeof(*rrset));
365	if(!rrset) {
366		log_err("out of memory");
367		return NULL;
368	}
369	rrset->next = node->rrsets;
370	node->rrsets = rrset;
371	rrset->rrset = (struct ub_packed_rrset_key*)
372		regional_alloc_zero(region, sizeof(*rrset->rrset));
373	if(!rrset->rrset) {
374		log_err("out of memory");
375		return NULL;
376	}
377	rrset->rrset->entry.key = rrset->rrset;
378	pd = (struct packed_rrset_data*)regional_alloc_zero(region,
379		sizeof(*pd));
380	if(!pd) {
381		log_err("out of memory");
382		return NULL;
383	}
384	pd->trust = rrset_trust_prim_noglue;
385	pd->security = sec_status_insecure;
386	rrset->rrset->entry.data = pd;
387	rrset->rrset->rk.dname = node->name;
388	rrset->rrset->rk.dname_len = node->namelen;
389	rrset->rrset->rk.type = htons(rrtype);
390	rrset->rrset->rk.rrset_class = htons(rrclass);
391	return rrset;
392}
393
394/** insert RR into RRset data structure; Wastes a couple of bytes */
395int
396rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
397	uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr)
398{
399	size_t* oldlen = pd->rr_len;
400	time_t* oldttl = pd->rr_ttl;
401	uint8_t** olddata = pd->rr_data;
402
403	/* add RR to rrset */
404	if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
405		log_warn("RRset '%s' has more than %d records, record ignored",
406			rrstr, LOCALZONE_RRSET_COUNT_MAX);
407		return 1;
408	}
409	pd->count++;
410	pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
411	pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
412	pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count);
413	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
414		log_err("out of memory");
415		return 0;
416	}
417	if(pd->count > 1) {
418		memcpy(pd->rr_len+1, oldlen,
419			sizeof(*pd->rr_len)*(pd->count-1));
420		memcpy(pd->rr_ttl+1, oldttl,
421			sizeof(*pd->rr_ttl)*(pd->count-1));
422		memcpy(pd->rr_data+1, olddata,
423			sizeof(*pd->rr_data)*(pd->count-1));
424	}
425	pd->rr_len[0] = rdata_len;
426	pd->rr_ttl[0] = ttl;
427	pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len);
428	if(!pd->rr_data[0]) {
429		log_err("out of memory");
430		return 0;
431	}
432	return 1;
433}
434
435/** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be
436 * free'd (regionally alloc'd) */
437int
438local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index)
439{
440	log_assert(pd->count > 0);
441	if(index >= pd->count) {
442		log_warn("Trying to remove RR with out of bound index");
443		return 0;
444	}
445	if(index + 1 < pd->count) {
446		/* not removing last element */
447		size_t nexti = index + 1;
448		size_t num = pd->count - nexti;
449		memmove(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num);
450		memmove(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num);
451		memmove(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num);
452	}
453	pd->count--;
454	return 1;
455}
456
457struct local_data*
458local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
459{
460	struct local_data key;
461	key.node.key = &key;
462	key.name = nm;
463	key.namelen = nmlen;
464	key.namelabs = nmlabs;
465	return (struct local_data*)rbtree_search(&z->data, &key.node);
466}
467
468/** find a node, create it if not and all its empty nonterminal parents */
469static int
470lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
471	int nmlabs, struct local_data** res)
472{
473	struct local_data* ld = local_zone_find_data(z, nm, nmlen, nmlabs);
474	if(!ld) {
475		/* create a domain name to store rr. */
476		ld = (struct local_data*)regional_alloc_zero(z->region,
477			sizeof(*ld));
478		if(!ld) {
479			log_err("out of memory adding local data");
480			return 0;
481		}
482		ld->node.key = ld;
483		ld->name = regional_alloc_init(z->region, nm, nmlen);
484		if(!ld->name) {
485			log_err("out of memory");
486			return 0;
487		}
488		ld->namelen = nmlen;
489		ld->namelabs = nmlabs;
490		if(!rbtree_insert(&z->data, &ld->node)) {
491			log_assert(0); /* duplicate name */
492		}
493		/* see if empty nonterminals need to be created */
494		if(nmlabs > z->namelabs) {
495			dname_remove_label(&nm, &nmlen);
496			if(!lz_find_create_node(z, nm, nmlen, nmlabs-1, res))
497				return 0;
498		}
499	}
500	*res = ld;
501	return 1;
502}
503
504/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
505 * for the RR is entered later on local_zone_enter_rr() as with the other
506 * records. An artificial soa_negative record with a modified TTL (minimum of
507 * the TTL and the SOA.MINIMUM) is also created and marked for usage with
508 * negative answers and to avoid allocations during those answers. */
509static int
510lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset,
511	uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr)
512{
513	struct packed_rrset_data* pd = (struct packed_rrset_data*)
514		regional_alloc_zero(z->region, sizeof(*pd));
515	struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*)
516		regional_alloc_zero(z->region, sizeof(*rrset_negative));
517	time_t minimum;
518	if(!rrset_negative||!pd) {
519		log_err("out of memory");
520		return 0;
521	}
522	/* Mark the original SOA record and then continue with the negative one. */
523	z->soa = soa_rrset;
524	rrset_negative->entry.key = rrset_negative;
525	pd->trust = rrset_trust_prim_noglue;
526	pd->security = sec_status_insecure;
527	rrset_negative->entry.data = pd;
528	rrset_negative->rk.dname = soa_rrset->rk.dname;
529	rrset_negative->rk.dname_len = soa_rrset->rk.dname_len;
530	rrset_negative->rk.type = soa_rrset->rk.type;
531	rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class;
532	if(!rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr))
533		return 0;
534	/* last 4 bytes are minimum ttl in network format */
535	if(pd->count == 0 || pd->rr_len[0] < 2+4)
536		return 0;
537	minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4));
538	minimum = ttl<minimum?ttl:minimum;
539	pd->ttl = minimum;
540	pd->rr_ttl[0] = minimum;
541
542	z->soa_negative = rrset_negative;
543	return 1;
544}
545
546int
547local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
548	int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
549	uint8_t* rdata, size_t rdata_len, const char* rrstr)
550{
551	struct local_data* node;
552	struct local_rrset* rrset;
553	struct packed_rrset_data* pd;
554
555	if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
556		return 0;
557	}
558	log_assert(node);
559
560	/* Reject it if we would end up having CNAME and other data (including
561	 * another CNAME) for a redirect zone. */
562	if((z->type == local_zone_redirect ||
563		z->type == local_zone_inform_redirect) && node->rrsets) {
564		const char* othertype = NULL;
565		if (rrtype == LDNS_RR_TYPE_CNAME)
566			othertype = "other";
567		else if (node->rrsets->rrset->rk.type ==
568			 htons(LDNS_RR_TYPE_CNAME)) {
569			othertype = "CNAME";
570		}
571		if(othertype) {
572			log_err("local-data '%s' in redirect zone must not "
573				"coexist with %s local-data", rrstr, othertype);
574			return 0;
575		}
576	}
577	rrset = local_data_find_type(node, rrtype, 0);
578	if(!rrset) {
579		rrset = new_local_rrset(z->region, node, rrtype, rrclass);
580		if(!rrset)
581			return 0;
582		if(query_dname_compare(node->name, z->name) == 0) {
583			if(rrtype == LDNS_RR_TYPE_NSEC)
584			  rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
585			if(rrtype == LDNS_RR_TYPE_SOA &&
586				!lz_mark_soa_for_zone(z, rrset->rrset, rdata, rdata_len, ttl,
587					rrstr))
588				return 0;
589		}
590	}
591	pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
592	log_assert(rrset && pd);
593
594	/* check for duplicate RR */
595	if(rr_is_duplicate(pd, rdata, rdata_len)) {
596		verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
597		return 1;
598	}
599	return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
600}
601
602/** enter data RR into auth zone */
603static int
604lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
605{
606	uint8_t* nm;
607	size_t nmlen;
608	int nmlabs, ret;
609	uint16_t rrtype = 0, rrclass = 0;
610	time_t ttl = 0;
611	uint8_t rr[LDNS_RR_BUF_SIZE];
612	uint8_t* rdata;
613	size_t rdata_len;
614	if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
615		sizeof(rr), &rdata, &rdata_len)) {
616		log_err("bad local-data: %s", rrstr);
617		return 0;
618	}
619	log_assert(z->dclass == rrclass);
620	if((z->type == local_zone_redirect ||
621		z->type == local_zone_inform_redirect) &&
622		query_dname_compare(z->name, nm) != 0) {
623		log_err("local-data in redirect zone must reside at top of zone"
624			", not at %s", rrstr);
625		free(nm);
626		return 0;
627	}
628	nmlabs = dname_count_size_labels(nm, &nmlen);
629	ret = local_zone_enter_rr(z, nm, nmlen, nmlabs, rrtype, rrclass, ttl,
630		rdata, rdata_len, rrstr);
631	free(nm);
632	return ret;
633}
634
635/** enter a data RR into auth data; a zone for it must exist */
636static int
637lz_enter_rr_str(struct local_zones* zones, const char* rr)
638{
639	uint8_t* rr_name;
640	uint16_t rr_class, rr_type;
641	size_t len;
642	int labs;
643	struct local_zone* z;
644	int r;
645	if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) {
646		log_err("bad rr %s", rr);
647		return 0;
648	}
649	labs = dname_count_size_labels(rr_name, &len);
650	lock_rw_rdlock(&zones->lock);
651	z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
652	if(!z) {
653		lock_rw_unlock(&zones->lock);
654		fatal_exit("internal error: no zone for rr %s", rr);
655	}
656	lock_rw_wrlock(&z->lock);
657	lock_rw_unlock(&zones->lock);
658	free(rr_name);
659	r = lz_enter_rr_into_zone(z, rr);
660	lock_rw_unlock(&z->lock);
661	return r;
662}
663
664/** enter tagstring into zone */
665static int
666lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list,
667	size_t len, uint16_t rr_class)
668{
669	uint8_t dname[LDNS_MAX_DOMAINLEN+1];
670	size_t dname_len = sizeof(dname);
671	int dname_labs, r = 0;
672	struct local_zone* z;
673
674	if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
675		log_err("cannot parse zone name in local-zone-tag: %s", zname);
676		return 0;
677	}
678	dname_labs = dname_count_labels(dname);
679
680	lock_rw_rdlock(&zones->lock);
681	z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class);
682	if(!z) {
683		lock_rw_unlock(&zones->lock);
684		log_err("no local-zone for tag %s", zname);
685		return 0;
686	}
687	lock_rw_wrlock(&z->lock);
688	lock_rw_unlock(&zones->lock);
689	free(z->taglist);
690	z->taglist = memdup(list, len);
691	z->taglen = len;
692	if(z->taglist)
693		r = 1;
694	lock_rw_unlock(&z->lock);
695	return r;
696}
697
698/** enter override into zone */
699static int
700lz_enter_override(struct local_zones* zones, char* zname, char* netblock,
701	char* type, uint16_t rr_class)
702{
703	uint8_t dname[LDNS_MAX_DOMAINLEN+1];
704	size_t dname_len = sizeof(dname);
705	int dname_labs;
706	struct sockaddr_storage addr;
707	int net;
708	socklen_t addrlen;
709	struct local_zone* z;
710	enum localzone_type t;
711
712	/* parse zone name */
713	if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
714		log_err("cannot parse zone name in local-zone-override: %s %s",
715			zname, netblock);
716		return 0;
717	}
718	dname_labs = dname_count_labels(dname);
719
720	/* parse netblock */
721	if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen,
722		&net)) {
723		log_err("cannot parse netblock in local-zone-override: %s %s",
724			zname, netblock);
725		return 0;
726	}
727
728	/* parse zone type */
729	if(!local_zone_str2type(type, &t)) {
730		log_err("cannot parse type in local-zone-override: %s %s %s",
731			zname, netblock, type);
732		return 0;
733	}
734
735	/* find localzone entry */
736	lock_rw_rdlock(&zones->lock);
737	z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class);
738	if(!z) {
739		lock_rw_unlock(&zones->lock);
740		log_err("no local-zone for local-zone-override %s", zname);
741		return 0;
742	}
743	lock_rw_wrlock(&z->lock);
744	lock_rw_unlock(&zones->lock);
745
746	/* create netblock addr_tree if not present yet */
747	if(!z->override_tree) {
748		z->override_tree = (struct rbtree_type*)regional_alloc_zero(
749			z->region, sizeof(*z->override_tree));
750		if(!z->override_tree) {
751			lock_rw_unlock(&z->lock);
752			log_err("out of memory");
753			return 0;
754		}
755		addr_tree_init(z->override_tree);
756	}
757	/* add new elem to tree */
758	if(z->override_tree) {
759		struct local_zone_override* n;
760		n = (struct local_zone_override*)regional_alloc_zero(
761			z->region, sizeof(*n));
762		if(!n) {
763			lock_rw_unlock(&z->lock);
764			log_err("out of memory");
765			return 0;
766		}
767		n->type = t;
768		if(!addr_tree_insert(z->override_tree,
769			(struct addr_tree_node*)n, &addr, addrlen, net)) {
770			lock_rw_unlock(&z->lock);
771			log_err("duplicate local-zone-override %s %s",
772				zname, netblock);
773			return 1;
774		}
775	}
776
777	lock_rw_unlock(&z->lock);
778	return 1;
779}
780
781/** parse local-zone: statements */
782static int
783lz_enter_zones(struct local_zones* zones, struct config_file* cfg)
784{
785	struct config_str2list* p;
786#ifndef THREADS_DISABLED
787	struct local_zone* z;
788#endif
789	for(p = cfg->local_zones; p; p = p->next) {
790		if(!(
791#ifndef THREADS_DISABLED
792			z=
793#endif
794			lz_enter_zone(zones, p->str, p->str2,
795			LDNS_RR_CLASS_IN)))
796			return 0;
797		lock_rw_unlock(&z->lock);
798	}
799	return 1;
800}
801
802/** lookup a zone in rbtree; exact match only; SLOW due to parse */
803static int
804lz_exists(struct local_zones* zones, const char* name)
805{
806	struct local_zone z;
807	z.node.key = &z;
808	z.dclass = LDNS_RR_CLASS_IN;
809	if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) {
810		log_err("bad name %s", name);
811		return 0;
812	}
813	lock_rw_rdlock(&zones->lock);
814	if(rbtree_search(&zones->ztree, &z.node)) {
815		lock_rw_unlock(&zones->lock);
816		free(z.name);
817		return 1;
818	}
819	lock_rw_unlock(&zones->lock);
820	free(z.name);
821	return 0;
822}
823
824/** lookup a zone in cfg->nodefault list */
825static int
826lz_nodefault(struct config_file* cfg, const char* name)
827{
828	struct config_strlist* p;
829	size_t len = strlen(name);
830	if(len == 0) return 0;
831	if(name[len-1] == '.') len--;
832
833	for(p = cfg->local_zones_nodefault; p; p = p->next) {
834		/* compare zone name, lowercase, compare without ending . */
835		if(strncasecmp(p->str, name, len) == 0 &&
836			(strlen(p->str) == len || (strlen(p->str)==len+1 &&
837			p->str[len] == '.')))
838			return 1;
839	}
840	return 0;
841}
842
843/** enter (AS112) empty default zone */
844static int
845add_empty_default(struct local_zones* zones, struct config_file* cfg,
846        const char* name)
847{
848	struct local_zone* z;
849	char str[1024]; /* known long enough */
850	if(lz_exists(zones, name) || lz_nodefault(cfg, name))
851		return 1; /* do not enter default content */
852	if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN)))
853		return 0;
854	snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
855		"nobody.invalid. 1 3600 1200 604800 10800", name);
856	if(!lz_enter_rr_into_zone(z, str)) {
857		lock_rw_unlock(&z->lock);
858		return 0;
859	}
860	snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
861	if(!lz_enter_rr_into_zone(z, str)) {
862		lock_rw_unlock(&z->lock);
863		return 0;
864	}
865	lock_rw_unlock(&z->lock);
866	return 1;
867}
868
869/** enter default zones */
870int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg)
871{
872	struct local_zone* z;
873	const char** zstr;
874
875	/* Do not add any default */
876	if(cfg->local_zones_disable_default)
877		return 1;
878
879	/* this list of zones is from RFC 6303 and RFC 7686 */
880
881	/* block localhost level zones first, then onion and later the LAN zones */
882
883	/* localhost. zone */
884	if(!lz_exists(zones, "localhost.") &&
885		!lz_nodefault(cfg, "localhost.")) {
886		if(!(z=lz_enter_zone(zones, "localhost.", "redirect",
887			LDNS_RR_CLASS_IN)) ||
888		   !lz_enter_rr_into_zone(z,
889			"localhost. 10800 IN NS localhost.") ||
890		   !lz_enter_rr_into_zone(z,
891			"localhost. 10800 IN SOA localhost. nobody.invalid. "
892			"1 3600 1200 604800 10800") ||
893		   !lz_enter_rr_into_zone(z,
894			"localhost. 10800 IN A 127.0.0.1") ||
895		   !lz_enter_rr_into_zone(z,
896			"localhost. 10800 IN AAAA ::1")) {
897			log_err("out of memory adding default zone");
898			if(z) { lock_rw_unlock(&z->lock); }
899			return 0;
900		}
901		lock_rw_unlock(&z->lock);
902	}
903	/* reverse ip4 zone */
904	if(!lz_exists(zones, "127.in-addr.arpa.") &&
905		!lz_nodefault(cfg, "127.in-addr.arpa.")) {
906		if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
907			LDNS_RR_CLASS_IN)) ||
908		   !lz_enter_rr_into_zone(z,
909			"127.in-addr.arpa. 10800 IN NS localhost.") ||
910		   !lz_enter_rr_into_zone(z,
911			"127.in-addr.arpa. 10800 IN SOA localhost. "
912			"nobody.invalid. 1 3600 1200 604800 10800") ||
913		   !lz_enter_rr_into_zone(z,
914			"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
915			log_err("out of memory adding default zone");
916			if(z) { lock_rw_unlock(&z->lock); }
917			return 0;
918		}
919		lock_rw_unlock(&z->lock);
920	}
921	/* reverse ip6 zone */
922	if(!lz_exists(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") &&
923		!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
924		if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
925			LDNS_RR_CLASS_IN)) ||
926		   !lz_enter_rr_into_zone(z,
927			"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
928		   !lz_enter_rr_into_zone(z,
929			"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
930			"nobody.invalid. 1 3600 1200 604800 10800") ||
931		   !lz_enter_rr_into_zone(z,
932			"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
933			log_err("out of memory adding default zone");
934			if(z) { lock_rw_unlock(&z->lock); }
935			return 0;
936		}
937		lock_rw_unlock(&z->lock);
938	}
939	/* home.arpa. zone (RFC 8375) */
940	if(!add_empty_default(zones, cfg, "home.arpa.")) {
941		log_err("out of memory adding default zone");
942		return 0;
943	}
944	/* onion. zone (RFC 7686) */
945	if(!add_empty_default(zones, cfg, "onion.")) {
946		log_err("out of memory adding default zone");
947		return 0;
948	}
949	/* test. zone (RFC 6761) */
950	if(!add_empty_default(zones, cfg, "test.")) {
951		log_err("out of memory adding default zone");
952		return 0;
953	}
954	/* invalid. zone (RFC 6761) */
955	if(!add_empty_default(zones, cfg, "invalid.")) {
956		log_err("out of memory adding default zone");
957		return 0;
958	}
959	/* block AS112 zones, unless asked not to */
960	if(!cfg->unblock_lan_zones) {
961		for(zstr = as112_zones; *zstr; zstr++) {
962			if(!add_empty_default(zones, cfg, *zstr)) {
963				log_err("out of memory adding default zone");
964				return 0;
965			}
966		}
967	}
968	return 1;
969}
970
971/** parse local-zone-override: statements */
972static int
973lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
974{
975	struct config_str3list* p;
976	for(p = cfg->local_zone_overrides; p; p = p->next) {
977		if(!lz_enter_override(zones, p->str, p->str2, p->str3,
978			LDNS_RR_CLASS_IN))
979			return 0;
980	}
981	return 1;
982}
983
984/** setup parent pointers, so that a lookup can be done for closest match */
985static void
986init_parents(struct local_zones* zones)
987{
988        struct local_zone* node, *prev = NULL, *p;
989        int m;
990	lock_rw_wrlock(&zones->lock);
991        RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
992		lock_rw_wrlock(&node->lock);
993                node->parent = NULL;
994                if(!prev || prev->dclass != node->dclass) {
995                        prev = node;
996			lock_rw_unlock(&node->lock);
997                        continue;
998                }
999                (void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
1000                        node->namelabs, &m); /* we know prev is smaller */
1001                /* sort order like: . com. bla.com. zwb.com. net. */
1002                /* find the previous, or parent-parent-parent */
1003                for(p = prev; p; p = p->parent)
1004                        /* looking for name with few labels, a parent */
1005                        if(p->namelabs <= m) {
1006                                /* ==: since prev matched m, this is closest*/
1007                                /* <: prev matches more, but is not a parent,
1008                                 * this one is a (grand)parent */
1009                                node->parent = p;
1010                                break;
1011                        }
1012                prev = node;
1013
1014		if(node->override_tree)
1015			addr_tree_init_parents(node->override_tree);
1016		lock_rw_unlock(&node->lock);
1017        }
1018	lock_rw_unlock(&zones->lock);
1019}
1020
1021/** enter implicit transparent zone for local-data: without local-zone: */
1022static int
1023lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
1024{
1025	/* walk over all items that have no parent zone and find
1026	 * the name that covers them all (could be the root) and
1027	 * add that as a transparent zone */
1028	struct config_strlist* p;
1029	int have_name = 0;
1030	int have_other_classes = 0;
1031	uint16_t dclass = 0;
1032	uint8_t* nm = 0;
1033	size_t nmlen = 0;
1034	int nmlabs = 0;
1035	int match = 0; /* number of labels match count */
1036
1037	init_parents(zones); /* to enable local_zones_lookup() */
1038	for(p = cfg->local_data; p; p = p->next) {
1039		uint8_t* rr_name;
1040		uint16_t rr_class, rr_type;
1041		size_t len;
1042		int labs;
1043		if(!get_rr_nameclass(p->str, &rr_name, &rr_class, &rr_type)) {
1044			log_err("Bad local-data RR %s", p->str);
1045			return 0;
1046		}
1047		labs = dname_count_size_labels(rr_name, &len);
1048		lock_rw_rdlock(&zones->lock);
1049		if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
1050			rr_type)) {
1051			/* Check if there is a zone that this could go
1052			 * under but for different class; created zones are
1053			 * always for LDNS_RR_CLASS_IN. Create the zone with
1054			 * a different class but the same configured
1055			 * local_zone_type. */
1056			struct local_zone* z = local_zones_lookup(zones,
1057				rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
1058			if(z) {
1059				uint8_t* name = memdup(z->name, z->namelen);
1060				size_t znamelen = z->namelen;
1061				int znamelabs = z->namelabs;
1062				enum localzone_type ztype = z->type;
1063				lock_rw_unlock(&zones->lock);
1064				if(!name) {
1065					log_err("out of memory");
1066					free(rr_name);
1067					return 0;
1068				}
1069				if(!(
1070#ifndef THREADS_DISABLED
1071					z =
1072#endif
1073					lz_enter_zone_dname(zones, name,
1074						znamelen, znamelabs,
1075						ztype, rr_class))) {
1076					free(rr_name);
1077					return 0;
1078				}
1079				lock_rw_unlock(&z->lock);
1080				free(rr_name);
1081				continue;
1082			}
1083			if(!have_name) {
1084				dclass = rr_class;
1085				nm = rr_name;
1086				nmlen = len;
1087				nmlabs = labs;
1088				match = labs;
1089				have_name = 1;
1090			} else {
1091				int m;
1092				if(rr_class != dclass) {
1093					/* process other classes later */
1094					free(rr_name);
1095					have_other_classes = 1;
1096					lock_rw_unlock(&zones->lock);
1097					continue;
1098				}
1099				/* find smallest shared topdomain */
1100				(void)dname_lab_cmp(nm, nmlabs,
1101					rr_name, labs, &m);
1102				free(rr_name);
1103				if(m < match)
1104					match = m;
1105			}
1106		} else free(rr_name);
1107		lock_rw_unlock(&zones->lock);
1108	}
1109	if(have_name) {
1110		uint8_t* n2;
1111#ifndef THREADS_DISABLED
1112		struct local_zone* z;
1113#endif
1114		/* allocate zone of smallest shared topdomain to contain em */
1115		n2 = nm;
1116		dname_remove_labels(&n2, &nmlen, nmlabs - match);
1117		n2 = memdup(n2, nmlen);
1118		free(nm);
1119		if(!n2) {
1120			log_err("out of memory");
1121			return 0;
1122		}
1123		log_nametypeclass(VERB_ALGO, "implicit transparent local-zone",
1124			n2, 0, dclass);
1125		if(!(
1126#ifndef THREADS_DISABLED
1127			z=
1128#endif
1129			lz_enter_zone_dname(zones, n2, nmlen, match,
1130			local_zone_transparent, dclass))) {
1131			return 0;
1132		}
1133		lock_rw_unlock(&z->lock);
1134	}
1135	if(have_other_classes) {
1136		/* restart to setup other class */
1137		return lz_setup_implicit(zones, cfg);
1138	}
1139	return 1;
1140}
1141
1142/** enter local-zone-tag info */
1143static int
1144lz_enter_zone_tags(struct local_zones* zones, struct config_file* cfg)
1145{
1146	struct config_strbytelist* p;
1147	int c = 0;
1148	for(p = cfg->local_zone_tags; p; p = p->next) {
1149		if(!lz_enter_zone_tag(zones, p->str, p->str2, p->str2len,
1150			LDNS_RR_CLASS_IN))
1151			return 0;
1152		c++;
1153	}
1154	if(c) verbose(VERB_ALGO, "applied tags to %d local zones", c);
1155	return 1;
1156}
1157
1158/** enter auth data */
1159static int
1160lz_enter_data(struct local_zones* zones, struct config_file* cfg)
1161{
1162	struct config_strlist* p;
1163	for(p = cfg->local_data; p; p = p->next) {
1164		if(!lz_enter_rr_str(zones, p->str))
1165			return 0;
1166	}
1167	return 1;
1168}
1169
1170/** free memory from config */
1171static void
1172lz_freeup_cfg(struct config_file* cfg)
1173{
1174	config_deldblstrlist(cfg->local_zones);
1175	cfg->local_zones = NULL;
1176	config_delstrlist(cfg->local_zones_nodefault);
1177	cfg->local_zones_nodefault = NULL;
1178	config_delstrlist(cfg->local_data);
1179	cfg->local_data = NULL;
1180}
1181
1182int
1183local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
1184{
1185	/* create zones from zone statements. */
1186	if(!lz_enter_zones(zones, cfg)) {
1187		return 0;
1188	}
1189	/* apply default zones+content (unless disabled, or overridden) */
1190	if(!local_zone_enter_defaults(zones, cfg)) {
1191		return 0;
1192	}
1193	/* enter local zone overrides */
1194	if(!lz_enter_overrides(zones, cfg)) {
1195		return 0;
1196	}
1197	/* create implicit transparent zone from data. */
1198	if(!lz_setup_implicit(zones, cfg)) {
1199		return 0;
1200	}
1201
1202	/* setup parent ptrs for lookup during data entry */
1203	init_parents(zones);
1204	/* insert local zone tags */
1205	if(!lz_enter_zone_tags(zones, cfg)) {
1206		return 0;
1207	}
1208	/* insert local data */
1209	if(!lz_enter_data(zones, cfg)) {
1210		return 0;
1211	}
1212	/* freeup memory from cfg struct. */
1213	lz_freeup_cfg(cfg);
1214	return 1;
1215}
1216
1217struct local_zone*
1218local_zones_lookup(struct local_zones* zones,
1219        uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype)
1220{
1221	return local_zones_tags_lookup(zones, name, len, labs,
1222		dclass, dtype, NULL, 0, 1);
1223}
1224
1225struct local_zone*
1226local_zones_tags_lookup(struct local_zones* zones,
1227        uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
1228	uint8_t* taglist, size_t taglen, int ignoretags)
1229{
1230	rbnode_type* res = NULL;
1231	struct local_zone *result;
1232	struct local_zone key;
1233	int m;
1234	/* for type DS use a zone higher when on a zonecut */
1235	if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
1236		dname_remove_label(&name, &len);
1237		labs--;
1238	}
1239	key.node.key = &key;
1240	key.dclass = dclass;
1241	key.name = name;
1242	key.namelen = len;
1243	key.namelabs = labs;
1244	rbtree_find_less_equal(&zones->ztree, &key, &res);
1245	result = (struct local_zone*)res;
1246	/* exact or smaller element (or no element) */
1247	if(!result || result->dclass != dclass)
1248		return NULL;
1249	/* count number of labels matched */
1250	(void)dname_lab_cmp(result->name, result->namelabs, key.name,
1251		key.namelabs, &m);
1252	while(result) { /* go up until qname is zone or subdomain of zone */
1253		if(result->namelabs <= m)
1254			if(ignoretags || !result->taglist ||
1255				taglist_intersect(result->taglist,
1256				result->taglen, taglist, taglen))
1257				break;
1258		result = result->parent;
1259	}
1260	return result;
1261}
1262
1263struct local_zone*
1264local_zones_find(struct local_zones* zones,
1265        uint8_t* name, size_t len, int labs, uint16_t dclass)
1266{
1267	struct local_zone key;
1268	key.node.key = &key;
1269	key.dclass = dclass;
1270	key.name = name;
1271	key.namelen = len;
1272	key.namelabs = labs;
1273	/* exact */
1274	return (struct local_zone*)rbtree_search(&zones->ztree, &key);
1275}
1276
1277struct local_zone*
1278local_zones_find_le(struct local_zones* zones,
1279        uint8_t* name, size_t len, int labs, uint16_t dclass,
1280	int* exact)
1281{
1282	struct local_zone key;
1283	rbnode_type *node;
1284	key.node.key = &key;
1285	key.dclass = dclass;
1286	key.name = name;
1287	key.namelen = len;
1288	key.namelabs = labs;
1289	*exact = rbtree_find_less_equal(&zones->ztree, &key, &node);
1290	return (struct local_zone*)node;
1291}
1292
1293/** encode answer consisting of 1 rrset */
1294static int
1295local_encode(struct query_info* qinfo, struct module_env* env,
1296	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1297	struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
1298	int rcode)
1299{
1300	struct reply_info rep;
1301	uint16_t udpsize;
1302	/* make answer with time=0 for fixed TTL values */
1303	memset(&rep, 0, sizeof(rep));
1304	rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
1305	rep.qdcount = 1;
1306	if(ansec)
1307		rep.an_numrrsets = 1;
1308	else	rep.ns_numrrsets = 1;
1309	rep.rrset_count = 1;
1310	rep.rrsets = &rrset;
1311	rep.reason_bogus = LDNS_EDE_NONE;
1312	udpsize = edns->udp_size;
1313	edns->edns_version = EDNS_ADVERTISED_VERSION;
1314	edns->udp_size = EDNS_ADVERTISED_SIZE;
1315	edns->ext_rcode = 0;
1316	edns->bits &= EDNS_DO;
1317	if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
1318		repinfo, temp, env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
1319		*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
1320		buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
1321		error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
1322			*(uint16_t*)sldns_buffer_begin(buf),
1323			sldns_buffer_read_u16_at(buf, 2), edns);
1324	}
1325	return 1;
1326}
1327
1328/** encode local error answer */
1329static void
1330local_error_encode(struct query_info* qinfo, struct module_env* env,
1331	struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
1332	struct regional* temp, int rcode, int r, int ede_code,
1333	const char* ede_txt)
1334{
1335	edns->edns_version = EDNS_ADVERTISED_VERSION;
1336	edns->udp_size = EDNS_ADVERTISED_SIZE;
1337	edns->ext_rcode = 0;
1338	edns->bits &= EDNS_DO;
1339
1340	if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
1341		rcode, edns, repinfo, temp, env->now_tv))
1342		edns->opt_list_inplace_cb_out = NULL;
1343
1344	if(ede_code != LDNS_EDE_NONE && env->cfg->ede) {
1345		edns_opt_list_append_ede(&edns->opt_list_out, temp,
1346			ede_code, ede_txt);
1347	}
1348
1349	error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
1350		sldns_buffer_read_u16_at(buf, 2), edns);
1351}
1352
1353/** find local data tag string match for the given type in the list */
1354int
1355local_data_find_tag_datas(const struct query_info* qinfo,
1356	struct config_strlist* list, struct ub_packed_rrset_key* r,
1357	struct regional* temp)
1358{
1359	struct config_strlist* p;
1360	char buf[65536];
1361	uint8_t rr[LDNS_RR_BUF_SIZE];
1362	size_t len;
1363	int res;
1364	struct packed_rrset_data* d;
1365	for(p=list; p; p=p->next) {
1366		uint16_t rdr_type;
1367
1368		len = sizeof(rr);
1369		/* does this element match the type? */
1370		snprintf(buf, sizeof(buf), ". %s", p->str);
1371		res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
1372			NULL, 0, NULL, 0);
1373		if(res != 0)
1374			/* parse errors are already checked before, in
1375			 * acllist check_data, skip this for robustness */
1376			continue;
1377		if(len < 1 /* . */ + 8 /* typeclassttl*/ + 2 /*rdatalen*/)
1378			continue;
1379		rdr_type = sldns_wirerr_get_type(rr, len, 1);
1380		if(rdr_type != qinfo->qtype && rdr_type != LDNS_RR_TYPE_CNAME)
1381			continue;
1382
1383		/* do we have entries already? if not setup key */
1384		if(r->rk.dname == NULL) {
1385			r->entry.key = r;
1386			r->rk.dname = qinfo->qname;
1387			r->rk.dname_len = qinfo->qname_len;
1388			r->rk.type = htons(rdr_type);
1389			r->rk.rrset_class = htons(qinfo->qclass);
1390			r->rk.flags = 0;
1391			d = (struct packed_rrset_data*)regional_alloc_zero(
1392				temp, sizeof(struct packed_rrset_data)
1393				+ sizeof(size_t) + sizeof(uint8_t*) +
1394				sizeof(time_t));
1395			if(!d) return 0; /* out of memory */
1396			r->entry.data = d;
1397			d->ttl = sldns_wirerr_get_ttl(rr, len, 1);
1398			d->rr_len = (size_t*)((uint8_t*)d +
1399				sizeof(struct packed_rrset_data));
1400			d->rr_data = (uint8_t**)&(d->rr_len[1]);
1401			d->rr_ttl = (time_t*)&(d->rr_data[1]);
1402		}
1403		d = (struct packed_rrset_data*)r->entry.data;
1404		/* add entry to the data */
1405		if(d->count != 0) {
1406			size_t* oldlen = d->rr_len;
1407			uint8_t** olddata = d->rr_data;
1408			time_t* oldttl = d->rr_ttl;
1409			/* increase arrays for lookup */
1410			/* this is of course slow for very many records,
1411			 * but most redirects are expected with few records */
1412			d->rr_len = (size_t*)regional_alloc_zero(temp,
1413				(d->count+1)*sizeof(size_t));
1414			d->rr_data = (uint8_t**)regional_alloc_zero(temp,
1415				(d->count+1)*sizeof(uint8_t*));
1416			d->rr_ttl = (time_t*)regional_alloc_zero(temp,
1417				(d->count+1)*sizeof(time_t));
1418			if(!d->rr_len || !d->rr_data || !d->rr_ttl)
1419				return 0; /* out of memory */
1420			/* first one was allocated after struct d, but new
1421			 * ones get their own array increment alloc, so
1422			 * copy old content */
1423			memmove(d->rr_len, oldlen, d->count*sizeof(size_t));
1424			memmove(d->rr_data, olddata, d->count*sizeof(uint8_t*));
1425			memmove(d->rr_ttl, oldttl, d->count*sizeof(time_t));
1426		}
1427
1428		d->rr_len[d->count] = sldns_wirerr_get_rdatalen(rr, len, 1)+2;
1429		d->rr_ttl[d->count] = sldns_wirerr_get_ttl(rr, len, 1);
1430		d->rr_data[d->count] = regional_alloc_init(temp,
1431			sldns_wirerr_get_rdatawl(rr, len, 1),
1432			d->rr_len[d->count]);
1433		if(!d->rr_data[d->count])
1434			return 0; /* out of memory */
1435		d->count++;
1436	}
1437	if(r->rk.dname)
1438		return 1;
1439	return 0;
1440}
1441
1442static int
1443find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
1444	struct ub_packed_rrset_key* r, struct regional* temp)
1445{
1446	int result = local_data_find_tag_datas(qinfo, list, r, temp);
1447
1448	/* If we've found a non-exact alias type of local data, make a shallow
1449	 * copy of the RRset and remember it in qinfo to complete the alias
1450	 * chain later. */
1451	if(result && qinfo->qtype != LDNS_RR_TYPE_CNAME &&
1452		r->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
1453		qinfo->local_alias =
1454			regional_alloc_zero(temp, sizeof(struct local_rrset));
1455		if(!qinfo->local_alias)
1456			return 0; /* out of memory */
1457		qinfo->local_alias->rrset =
1458			regional_alloc_init(temp, r, sizeof(*r));
1459		if(!qinfo->local_alias->rrset)
1460			return 0; /* out of memory */
1461	}
1462	return result;
1463}
1464
1465int
1466local_data_answer(struct local_zone* z, struct module_env* env,
1467	struct query_info* qinfo, struct edns_data* edns,
1468	struct comm_reply* repinfo, sldns_buffer* buf,
1469	struct regional* temp, int labs, struct local_data** ldp,
1470	enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
1471	size_t tag_datas_size, char** tagname, int num_tags)
1472{
1473	struct local_data key;
1474	struct local_data* ld;
1475	struct local_rrset* lr;
1476	key.node.key = &key;
1477	key.name = qinfo->qname;
1478	key.namelen = qinfo->qname_len;
1479	key.namelabs = labs;
1480	if(lz_type == local_zone_redirect ||
1481		lz_type == local_zone_inform_redirect) {
1482		key.name = z->name;
1483		key.namelen = z->namelen;
1484		key.namelabs = z->namelabs;
1485		if(tag != -1 && (size_t)tag<tag_datas_size && tag_datas[tag]) {
1486			struct ub_packed_rrset_key r;
1487			memset(&r, 0, sizeof(r));
1488			if(find_tag_datas(qinfo, tag_datas[tag], &r, temp)) {
1489				verbose(VERB_ALGO, "redirect with tag data [%d] %s",
1490					tag, (tag<num_tags?tagname[tag]:"null"));
1491
1492				/* If we found a matching alias, we should
1493				 * use it as part of the answer, but we can't
1494				 * encode it until we complete the alias
1495				 * chain. */
1496				if(qinfo->local_alias)
1497					return 1;
1498				return local_encode(qinfo, env, edns, repinfo, buf, temp,
1499					&r, 1, LDNS_RCODE_NOERROR);
1500			}
1501		}
1502	}
1503	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
1504	*ldp = ld;
1505	if(!ld) {
1506		return 0;
1507	}
1508	lr = local_data_find_type(ld, qinfo->qtype, 1);
1509	if(!lr)
1510		return 0;
1511
1512	/* Special case for alias matching.  See local_data_answer(). */
1513	if((lz_type == local_zone_redirect ||
1514		lz_type == local_zone_inform_redirect) &&
1515		qinfo->qtype != LDNS_RR_TYPE_CNAME &&
1516		lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
1517		uint8_t* ctarget;
1518		size_t ctargetlen = 0;
1519
1520		qinfo->local_alias =
1521			regional_alloc_zero(temp, sizeof(struct local_rrset));
1522		if(!qinfo->local_alias)
1523			return 0; /* out of memory */
1524		qinfo->local_alias->rrset = regional_alloc_init(
1525			temp, lr->rrset, sizeof(*lr->rrset));
1526		if(!qinfo->local_alias->rrset)
1527			return 0; /* out of memory */
1528		qinfo->local_alias->rrset->rk.dname = qinfo->qname;
1529		qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
1530		get_cname_target(lr->rrset, &ctarget, &ctargetlen);
1531		if(!ctargetlen)
1532			return 0; /* invalid cname */
1533		if(dname_is_wild(ctarget)) {
1534			/* synthesize cname target */
1535			struct packed_rrset_data* d, *lr_d;
1536			/* -3 for wildcard label and root label from qname */
1537			size_t newtargetlen = qinfo->qname_len + ctargetlen - 3;
1538
1539			log_assert(ctargetlen >= 3);
1540			log_assert(qinfo->qname_len >= 1);
1541
1542			if(newtargetlen > LDNS_MAX_DOMAINLEN) {
1543				qinfo->local_alias = NULL;
1544				local_error_encode(qinfo, env, edns, repinfo,
1545					buf, temp, LDNS_RCODE_YXDOMAIN,
1546					(LDNS_RCODE_YXDOMAIN|BIT_AA),
1547					LDNS_EDE_OTHER,
1548					"DNAME expansion became too large");
1549				return 1;
1550			}
1551			memset(&qinfo->local_alias->rrset->entry, 0,
1552				sizeof(qinfo->local_alias->rrset->entry));
1553			qinfo->local_alias->rrset->entry.key =
1554				qinfo->local_alias->rrset;
1555			qinfo->local_alias->rrset->entry.hash =
1556				rrset_key_hash(&qinfo->local_alias->rrset->rk);
1557			d = (struct packed_rrset_data*)regional_alloc_zero(temp,
1558				sizeof(struct packed_rrset_data) + sizeof(size_t) +
1559				sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t)
1560				+ newtargetlen);
1561			if(!d)
1562				return 0; /* out of memory */
1563			lr_d = (struct packed_rrset_data*)lr->rrset->entry.data;
1564			qinfo->local_alias->rrset->entry.data = d;
1565			d->ttl = lr_d->rr_ttl[0]; /* RFC6672-like behavior:
1566					    synth CNAME TTL uses original TTL*/
1567			d->count = 1;
1568			d->rrsig_count = 0;
1569			d->trust = rrset_trust_ans_noAA;
1570			d->rr_len = (size_t*)((uint8_t*)d +
1571				sizeof(struct packed_rrset_data));
1572			d->rr_len[0] = newtargetlen + sizeof(uint16_t);
1573			packed_rrset_ptr_fixup(d);
1574			d->rr_ttl[0] = d->ttl;
1575			sldns_write_uint16(d->rr_data[0], newtargetlen);
1576			/* write qname */
1577			memmove(d->rr_data[0] + sizeof(uint16_t), qinfo->qname,
1578				qinfo->qname_len - 1);
1579			/* write cname target wildcard label */
1580			memmove(d->rr_data[0] + sizeof(uint16_t) +
1581				qinfo->qname_len - 1, ctarget + 2,
1582				ctargetlen - 2);
1583		}
1584		return 1;
1585	}
1586	if(lz_type == local_zone_redirect ||
1587		lz_type == local_zone_inform_redirect) {
1588		/* convert rrset name to query name; like a wildcard */
1589		struct ub_packed_rrset_key r = *lr->rrset;
1590		r.rk.dname = qinfo->qname;
1591		r.rk.dname_len = qinfo->qname_len;
1592		return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1,
1593			LDNS_RCODE_NOERROR);
1594	}
1595	return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1,
1596		LDNS_RCODE_NOERROR);
1597}
1598
1599/**
1600 * See if the local zone does not cover the name, eg. the name is not
1601 * in the zone and the zone is transparent */
1602static int
1603local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
1604	int labs)
1605{
1606	struct local_data key;
1607	struct local_data* ld = NULL;
1608	struct local_rrset* lr = NULL;
1609	if(z->type == local_zone_always_transparent || z->type == local_zone_block_a)
1610		return 1;
1611	if(z->type != local_zone_transparent
1612		&& z->type != local_zone_typetransparent
1613		&& z->type != local_zone_inform)
1614		return 0;
1615	key.node.key = &key;
1616	key.name = qinfo->qname;
1617	key.namelen = qinfo->qname_len;
1618	key.namelabs = labs;
1619	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
1620	if(z->type == local_zone_transparent || z->type == local_zone_inform)
1621		return (ld == NULL);
1622	if(ld)
1623		lr = local_data_find_type(ld, qinfo->qtype, 1);
1624	/* local_zone_typetransparent */
1625	return (lr == NULL);
1626}
1627
1628static inline int
1629local_zone_is_udp_query(struct comm_reply* repinfo) {
1630	return repinfo != NULL
1631			? (repinfo->c != NULL
1632				? repinfo->c->type == comm_udp
1633				: 0)
1634			: 0;
1635}
1636
1637int
1638local_zones_zone_answer(struct local_zone* z, struct module_env* env,
1639	struct query_info* qinfo, struct edns_data* edns,
1640	struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
1641	struct local_data* ld, enum localzone_type lz_type)
1642{
1643	if(lz_type == local_zone_deny ||
1644		lz_type == local_zone_always_deny ||
1645		lz_type == local_zone_inform_deny) {
1646		/** no reply at all, signal caller by clearing buffer. */
1647		sldns_buffer_clear(buf);
1648		sldns_buffer_flip(buf);
1649		return 1;
1650	} else if(lz_type == local_zone_refuse
1651		|| lz_type == local_zone_always_refuse) {
1652		local_error_encode(qinfo, env, edns, repinfo, buf, temp,
1653			LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA),
1654			LDNS_EDE_NONE, NULL);
1655		return 1;
1656	} else if(lz_type == local_zone_static ||
1657		lz_type == local_zone_redirect ||
1658		lz_type == local_zone_inform_redirect ||
1659		lz_type == local_zone_always_nxdomain ||
1660		lz_type == local_zone_always_nodata ||
1661		(lz_type == local_zone_truncate
1662			&& local_zone_is_udp_query(repinfo))) {
1663		/* for static, reply nodata or nxdomain
1664		 * for redirect, reply nodata */
1665		/* no additional section processing,
1666		 * cname, dname or wildcard processing,
1667		 * or using closest match for NSEC.
1668		 * or using closest match for returning delegation downwards
1669		 */
1670		int rcode = (ld || lz_type == local_zone_redirect ||
1671			lz_type == local_zone_inform_redirect ||
1672			lz_type == local_zone_always_nodata ||
1673			lz_type == local_zone_truncate)?
1674			LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
1675		rcode = (lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode);
1676		if(z != NULL && z->soa && z->soa_negative)
1677			return local_encode(qinfo, env, edns, repinfo, buf, temp,
1678				z->soa_negative, 0, rcode);
1679		local_error_encode(qinfo, env, edns, repinfo, buf, temp,
1680			rcode, (rcode|BIT_AA), LDNS_EDE_NONE, NULL);
1681		return 1;
1682	} else if(lz_type == local_zone_typetransparent
1683		|| lz_type == local_zone_always_transparent) {
1684		/* no NODATA or NXDOMAINS for this zone type */
1685		return 0;
1686	} else if(lz_type == local_zone_block_a) {
1687		/* Return NODATA for all A queries */
1688		if(qinfo->qtype == LDNS_RR_TYPE_A) {
1689			local_error_encode(qinfo, env, edns, repinfo, buf, temp,
1690				LDNS_RCODE_NOERROR, (LDNS_RCODE_NOERROR|BIT_AA),
1691				LDNS_EDE_NONE, NULL);
1692				return 1;
1693		}
1694
1695		return 0;
1696	} else if(lz_type == local_zone_always_null) {
1697		/* 0.0.0.0 or ::0 or noerror/nodata for this zone type,
1698		 * used for blocklists. */
1699		if(qinfo->qtype == LDNS_RR_TYPE_A ||
1700			qinfo->qtype == LDNS_RR_TYPE_AAAA) {
1701			struct ub_packed_rrset_key lrr;
1702			struct packed_rrset_data d;
1703			time_t rr_ttl = 3600;
1704			size_t rr_len = 0;
1705			uint8_t rr_data[2+16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1706			uint8_t* rr_datas = rr_data;
1707			memset(&lrr, 0, sizeof(lrr));
1708			memset(&d, 0, sizeof(d));
1709			lrr.entry.data = &d;
1710			lrr.rk.dname = qinfo->qname;
1711			lrr.rk.dname_len = qinfo->qname_len;
1712			lrr.rk.type = htons(qinfo->qtype);
1713			lrr.rk.rrset_class = htons(qinfo->qclass);
1714			if(qinfo->qtype == LDNS_RR_TYPE_A) {
1715				rr_len = 4;
1716				sldns_write_uint16(rr_data, rr_len);
1717				rr_len += 2;
1718			} else {
1719				rr_len = 16;
1720				sldns_write_uint16(rr_data, rr_len);
1721				rr_len += 2;
1722			}
1723			d.ttl = rr_ttl;
1724			d.count = 1;
1725			d.rr_len = &rr_len;
1726			d.rr_data = &rr_datas;
1727			d.rr_ttl = &rr_ttl;
1728			return local_encode(qinfo, env, edns, repinfo, buf, temp,
1729				&lrr, 1, LDNS_RCODE_NOERROR);
1730		} else {
1731			/* NODATA: No EDE needed */
1732			local_error_encode(qinfo, env, edns, repinfo, buf,
1733				temp, LDNS_RCODE_NOERROR,
1734				(LDNS_RCODE_NOERROR|BIT_AA), -1, NULL);
1735		}
1736		return 1;
1737	}
1738	/* else lz_type == local_zone_transparent */
1739
1740	/* if the zone is transparent and the name exists, but the type
1741	 * does not, then we should make this noerror/nodata */
1742	if(ld && ld->rrsets) {
1743		int rcode = LDNS_RCODE_NOERROR;
1744		if(z != NULL && z->soa && z->soa_negative)
1745			return local_encode(qinfo, env, edns, repinfo, buf, temp,
1746				z->soa_negative, 0, rcode);
1747		/* NODATA: No EDE needed */
1748		local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
1749			(rcode|BIT_AA), LDNS_EDE_NONE, NULL);
1750		return 1;
1751	}
1752
1753	/* stop here, and resolve further on */
1754	return 0;
1755}
1756
1757/** print log information for an inform zone query */
1758static void
1759lz_inform_print(struct local_zone* z, struct query_info* qinfo,
1760	struct sockaddr_storage* addr, socklen_t addrlen)
1761{
1762	char ip[128], txt[512];
1763	char zname[LDNS_MAX_DOMAINLEN+1];
1764	uint16_t port = ntohs(((struct sockaddr_in*)addr)->sin_port);
1765	dname_str(z->name, zname);
1766	addr_to_str(addr, addrlen, ip, sizeof(ip));
1767	snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
1768		(unsigned)port);
1769	log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
1770}
1771
1772static enum localzone_type
1773lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
1774	uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt,
1775	struct comm_reply* repinfo, struct rbtree_type* override_tree,
1776	int* tag, char** tagname, int num_tags)
1777{
1778	struct local_zone_override* lzo;
1779	if(repinfo && override_tree) {
1780		lzo = (struct local_zone_override*)addr_tree_lookup(
1781			override_tree, &repinfo->client_addr,
1782			repinfo->client_addrlen);
1783		if(lzo && lzo->type) {
1784			verbose(VERB_ALGO, "local zone override to type %s",
1785				local_zone_type2str(lzo->type));
1786			return lzo->type;
1787		}
1788	}
1789	if(!taglist || !taglist2)
1790		return lzt;
1791	return local_data_find_tag_action(taglist, taglen, taglist2, taglen2,
1792		tagactions, tagactionssize, lzt, tag, tagname, num_tags);
1793}
1794
1795enum localzone_type
1796local_data_find_tag_action(const uint8_t* taglist, size_t taglen,
1797	const uint8_t* taglist2, size_t taglen2, const uint8_t* tagactions,
1798	size_t tagactionssize, enum localzone_type lzt, int* tag,
1799	char* const* tagname, int num_tags)
1800{
1801	size_t i, j;
1802	uint8_t tagmatch;
1803
1804	for(i=0; i<taglen && i<taglen2; i++) {
1805		tagmatch = (taglist[i] & taglist2[i]);
1806		for(j=0; j<8 && tagmatch>0; j++) {
1807			if((tagmatch & 0x1)) {
1808				*tag = (int)(i*8+j);
1809				verbose(VERB_ALGO, "matched tag [%d] %s",
1810					*tag, (*tag<num_tags?tagname[*tag]:"null"));
1811				/* does this tag have a tag action? */
1812				if(i*8+j < tagactionssize && tagactions
1813				   && tagactions[i*8+j] != 0) {
1814				  verbose(VERB_ALGO, "tag action [%d] %s to type %s",
1815					*tag, (*tag<num_tags?tagname[*tag]:"null"),
1816				  	local_zone_type2str(
1817					(enum localzone_type)
1818					tagactions[i*8+j]));
1819				  return (enum localzone_type)tagactions[i*8+j];
1820				}
1821				return lzt;
1822			}
1823			tagmatch >>= 1;
1824		}
1825	}
1826	return lzt;
1827}
1828
1829int
1830local_zones_answer(struct local_zones* zones, struct module_env* env,
1831	struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
1832	struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
1833	size_t taglen, uint8_t* tagactions, size_t tagactionssize,
1834	struct config_strlist** tag_datas, size_t tag_datas_size,
1835	char** tagname, int num_tags, struct view* view)
1836{
1837	/* see if query is covered by a zone,
1838	 * 	if so:	- try to match (exact) local data
1839	 * 		- look at zone type for negative response. */
1840	int labs = dname_count_labels(qinfo->qname);
1841	struct local_data* ld = NULL;
1842	struct local_zone* z = NULL;
1843	enum localzone_type lzt = local_zone_transparent;
1844	int r, tag = -1;
1845
1846	if(view) {
1847		lock_rw_rdlock(&view->lock);
1848		if(view->local_zones &&
1849			(z = local_zones_lookup(view->local_zones,
1850			qinfo->qname, qinfo->qname_len, labs,
1851			qinfo->qclass, qinfo->qtype))) {
1852			lock_rw_rdlock(&z->lock);
1853			lzt = z->type;
1854		}
1855		if(lzt == local_zone_noview) {
1856			lock_rw_unlock(&z->lock);
1857			z = NULL;
1858		}
1859		if(z && (lzt == local_zone_transparent ||
1860			lzt == local_zone_typetransparent ||
1861			lzt == local_zone_inform ||
1862			lzt == local_zone_always_transparent ||
1863			lzt == local_zone_block_a) &&
1864			local_zone_does_not_cover(z, qinfo, labs)) {
1865			lock_rw_unlock(&z->lock);
1866			z = NULL;
1867		}
1868		if(view->local_zones && !z && !view->isfirst){
1869			lock_rw_unlock(&view->lock);
1870			return 0;
1871		}
1872		if(z && verbosity >= VERB_ALGO) {
1873			char zname[255+1];
1874			dname_str(z->name, zname);
1875			verbose(VERB_ALGO, "using localzone %s %s from view %s",
1876				zname, local_zone_type2str(lzt), view->name);
1877		}
1878		lock_rw_unlock(&view->lock);
1879	}
1880	if(!z) {
1881		/* try global local_zones tree */
1882		lock_rw_rdlock(&zones->lock);
1883		if(!(z = local_zones_tags_lookup(zones, qinfo->qname,
1884			qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype,
1885			taglist, taglen, 0))) {
1886			lock_rw_unlock(&zones->lock);
1887			return 0;
1888		}
1889		lock_rw_rdlock(&z->lock);
1890		lzt = lz_type(taglist, taglen, z->taglist, z->taglen,
1891			tagactions, tagactionssize, z->type, repinfo,
1892			z->override_tree, &tag, tagname, num_tags);
1893		lock_rw_unlock(&zones->lock);
1894		if(z && verbosity >= VERB_ALGO) {
1895			char zname[255+1];
1896			dname_str(z->name, zname);
1897			verbose(VERB_ALGO, "using localzone %s %s", zname,
1898				local_zone_type2str(lzt));
1899		}
1900	}
1901	if((env->cfg->log_local_actions ||
1902			lzt == local_zone_inform ||
1903			lzt == local_zone_inform_deny ||
1904			lzt == local_zone_inform_redirect)
1905			&& repinfo)
1906		lz_inform_print(z, qinfo, &repinfo->client_addr,
1907			repinfo->client_addrlen);
1908
1909	if(lzt != local_zone_always_refuse
1910		&& lzt != local_zone_always_transparent
1911		&& lzt != local_zone_block_a
1912		&& lzt != local_zone_always_nxdomain
1913		&& lzt != local_zone_always_nodata
1914		&& lzt != local_zone_always_deny
1915		&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
1916			&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
1917		lock_rw_unlock(&z->lock);
1918		/* We should tell the caller that encode is deferred if we found
1919		 * a local alias. */
1920		return !qinfo->local_alias;
1921	}
1922	r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
1923	lock_rw_unlock(&z->lock);
1924	return r && !qinfo->local_alias; /* see above */
1925}
1926
1927const char* local_zone_type2str(enum localzone_type t)
1928{
1929	switch(t) {
1930		case local_zone_unset: return "unset";
1931		case local_zone_deny: return "deny";
1932		case local_zone_refuse: return "refuse";
1933		case local_zone_redirect: return "redirect";
1934		case local_zone_transparent: return "transparent";
1935		case local_zone_typetransparent: return "typetransparent";
1936		case local_zone_static: return "static";
1937		case local_zone_nodefault: return "nodefault";
1938		case local_zone_inform: return "inform";
1939		case local_zone_inform_deny: return "inform_deny";
1940		case local_zone_inform_redirect: return "inform_redirect";
1941		case local_zone_always_transparent: return "always_transparent";
1942		case local_zone_block_a: return "block_a";
1943		case local_zone_always_refuse: return "always_refuse";
1944		case local_zone_always_nxdomain: return "always_nxdomain";
1945		case local_zone_always_nodata: return "always_nodata";
1946		case local_zone_always_deny: return "always_deny";
1947		case local_zone_always_null: return "always_null";
1948		case local_zone_noview: return "noview";
1949		case local_zone_truncate: return "truncate";
1950		case local_zone_invalid: return "invalid";
1951	}
1952	return "badtyped";
1953}
1954
1955int local_zone_str2type(const char* type, enum localzone_type* t)
1956{
1957	if(strcmp(type, "deny") == 0)
1958		*t = local_zone_deny;
1959	else if(strcmp(type, "refuse") == 0)
1960		*t = local_zone_refuse;
1961	else if(strcmp(type, "static") == 0)
1962		*t = local_zone_static;
1963	else if(strcmp(type, "transparent") == 0)
1964		*t = local_zone_transparent;
1965	else if(strcmp(type, "typetransparent") == 0)
1966		*t = local_zone_typetransparent;
1967	else if(strcmp(type, "redirect") == 0)
1968		*t = local_zone_redirect;
1969	else if(strcmp(type, "inform") == 0)
1970		*t = local_zone_inform;
1971	else if(strcmp(type, "inform_deny") == 0)
1972		*t = local_zone_inform_deny;
1973	else if(strcmp(type, "inform_redirect") == 0)
1974		*t = local_zone_inform_redirect;
1975	else if(strcmp(type, "always_transparent") == 0)
1976		*t = local_zone_always_transparent;
1977	else if(strcmp(type, "block_a") == 0)
1978		*t = local_zone_block_a;
1979	else if(strcmp(type, "always_refuse") == 0)
1980		*t = local_zone_always_refuse;
1981	else if(strcmp(type, "always_nxdomain") == 0)
1982		*t = local_zone_always_nxdomain;
1983	else if(strcmp(type, "always_nodata") == 0)
1984		*t = local_zone_always_nodata;
1985	else if(strcmp(type, "always_deny") == 0)
1986		*t = local_zone_always_deny;
1987	else if(strcmp(type, "always_null") == 0)
1988		*t = local_zone_always_null;
1989	else if(strcmp(type, "noview") == 0)
1990		*t = local_zone_noview;
1991	else if(strcmp(type, "truncate") == 0)
1992		*t = local_zone_truncate;
1993	else if(strcmp(type, "nodefault") == 0)
1994		*t = local_zone_nodefault;
1995	else return 0;
1996	return 1;
1997}
1998
1999/** iterate over the kiddies of the given name and set their parent ptr */
2000static void
2001set_kiddo_parents(struct local_zone* z, struct local_zone* match,
2002	struct local_zone* newp)
2003{
2004	/* both zones and z are locked already */
2005	/* in the sorted rbtree, the kiddies of z are located after z */
2006	/* z must be present in the tree */
2007	struct local_zone* p = z;
2008	p = (struct local_zone*)rbtree_next(&p->node);
2009	while(p!=(struct local_zone*)RBTREE_NULL &&
2010		p->dclass == z->dclass && dname_strict_subdomain(p->name,
2011		p->namelabs, z->name, z->namelabs)) {
2012		/* update parent ptr */
2013		/* only when matches with existing parent pointer, so that
2014		 * deeper child structures are not touched, i.e.
2015		 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y
2016		 * gets to update a.x, b.x and c.x */
2017		lock_rw_wrlock(&p->lock);
2018		if(p->parent == match)
2019			p->parent = newp;
2020		lock_rw_unlock(&p->lock);
2021		p = (struct local_zone*)rbtree_next(&p->node);
2022	}
2023}
2024
2025struct local_zone* local_zones_add_zone(struct local_zones* zones,
2026	uint8_t* name, size_t len, int labs, uint16_t dclass,
2027	enum localzone_type tp)
2028{
2029	/* create */
2030	struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
2031	if(!z) {
2032		free(name);
2033		return NULL;
2034	}
2035	lock_rw_wrlock(&z->lock);
2036
2037	/* find the closest parent */
2038	z->parent = local_zones_find(zones, name, len, labs, dclass);
2039
2040	/* insert into the tree */
2041	if(!rbtree_insert(&zones->ztree, &z->node)) {
2042		/* duplicate entry! */
2043		lock_rw_unlock(&z->lock);
2044		local_zone_delete(z);
2045		log_err("internal: duplicate entry in local_zones_add_zone");
2046		return NULL;
2047	}
2048
2049	/* set parent pointers right */
2050	set_kiddo_parents(z, z->parent, z);
2051
2052	lock_rw_unlock(&z->lock);
2053	return z;
2054}
2055
2056void local_zones_del_zone(struct local_zones* zones, struct local_zone* z)
2057{
2058	/* fix up parents in tree */
2059	lock_rw_wrlock(&z->lock);
2060	set_kiddo_parents(z, z, z->parent);
2061
2062	/* remove from tree */
2063	(void)rbtree_delete(&zones->ztree, z);
2064
2065	/* delete the zone */
2066	lock_rw_unlock(&z->lock);
2067	local_zone_delete(z);
2068}
2069
2070int
2071local_zones_add_RR(struct local_zones* zones, const char* rr)
2072{
2073	uint8_t* rr_name;
2074	uint16_t rr_class, rr_type;
2075	size_t len;
2076	int labs;
2077	struct local_zone* z;
2078	int r;
2079	if(!get_rr_nameclass(rr, &rr_name, &rr_class, &rr_type)) {
2080		return 0;
2081	}
2082	labs = dname_count_size_labels(rr_name, &len);
2083	/* could first try readlock then get writelock if zone does not exist,
2084	 * but we do not add enough RRs (from multiple threads) to optimize */
2085	lock_rw_wrlock(&zones->lock);
2086	z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
2087	if(!z) {
2088		z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
2089			local_zone_transparent);
2090		if(!z) {
2091			lock_rw_unlock(&zones->lock);
2092			return 0;
2093		}
2094	} else {
2095		free(rr_name);
2096	}
2097	lock_rw_wrlock(&z->lock);
2098	lock_rw_unlock(&zones->lock);
2099	r = lz_enter_rr_into_zone(z, rr);
2100	lock_rw_unlock(&z->lock);
2101	return r;
2102}
2103
2104/** returns true if the node is terminal so no deeper domain names exist */
2105static int
2106is_terminal(struct local_data* d)
2107{
2108	/* for empty nonterminals, the deeper domain names are sorted
2109	 * right after them, so simply check the next name in the tree
2110	 */
2111	struct local_data* n = (struct local_data*)rbtree_next(&d->node);
2112	if(n == (struct local_data*)RBTREE_NULL)
2113		return 1; /* last in tree, no deeper node */
2114	if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs))
2115		return 0; /* there is a deeper node */
2116	return 1;
2117}
2118
2119/** delete empty terminals from tree when final data is deleted */
2120static void
2121del_empty_term(struct local_zone* z, struct local_data* d,
2122	uint8_t* name, size_t len, int labs)
2123{
2124	while(d && d->rrsets == NULL && is_terminal(d)) {
2125		/* is this empty nonterminal? delete */
2126		/* note, no memory recycling in zone region */
2127		(void)rbtree_delete(&z->data, d);
2128
2129		/* go up and to the next label */
2130		if(dname_is_root(name))
2131			return;
2132		dname_remove_label(&name, &len);
2133		labs--;
2134		d = local_zone_find_data(z, name, len, labs);
2135	}
2136}
2137
2138/** find and remove type from list in domain struct */
2139static void
2140del_local_rrset(struct local_data* d, uint16_t dtype)
2141{
2142	struct local_rrset* prev=NULL, *p=d->rrsets;
2143	while(p && ntohs(p->rrset->rk.type) != dtype) {
2144		prev = p;
2145		p = p->next;
2146	}
2147	if(!p)
2148		return; /* rrset type not found */
2149	/* unlink it */
2150	if(prev) prev->next = p->next;
2151	else d->rrsets = p->next;
2152	/* no memory recycling for zone deletions ... */
2153}
2154
2155void local_zones_del_data(struct local_zones* zones,
2156	uint8_t* name, size_t len, int labs, uint16_t dclass)
2157{
2158	/* find zone */
2159	struct local_zone* z;
2160	struct local_data* d;
2161
2162	/* remove DS */
2163	lock_rw_rdlock(&zones->lock);
2164	z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
2165	if(z) {
2166		lock_rw_wrlock(&z->lock);
2167		d = local_zone_find_data(z, name, len, labs);
2168		if(d) {
2169			del_local_rrset(d, LDNS_RR_TYPE_DS);
2170			del_empty_term(z, d, name, len, labs);
2171		}
2172		lock_rw_unlock(&z->lock);
2173	}
2174	lock_rw_unlock(&zones->lock);
2175
2176	/* remove other types */
2177	lock_rw_rdlock(&zones->lock);
2178	z = local_zones_lookup(zones, name, len, labs, dclass, 0);
2179	if(!z) {
2180		/* no such zone, we're done */
2181		lock_rw_unlock(&zones->lock);
2182		return;
2183	}
2184	lock_rw_wrlock(&z->lock);
2185	lock_rw_unlock(&zones->lock);
2186
2187	/* find the domain */
2188	d = local_zone_find_data(z, name, len, labs);
2189	if(d) {
2190		/* no memory recycling for zone deletions ... */
2191		d->rrsets = NULL;
2192		/* did we delete the soa record ? */
2193		if(query_dname_compare(d->name, z->name) == 0) {
2194			z->soa = NULL;
2195			z->soa_negative = NULL;
2196		}
2197
2198		/* cleanup the empty nonterminals for this name */
2199		del_empty_term(z, d, name, len, labs);
2200	}
2201
2202	lock_rw_unlock(&z->lock);
2203}
2204