localzone.c revision 307729
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 "sldns/sbuffer.h"
45#include "util/regional.h"
46#include "util/config_file.h"
47#include "util/data/dname.h"
48#include "util/data/packed_rrset.h"
49#include "util/data/msgencode.h"
50#include "util/net_help.h"
51#include "util/netevent.h"
52#include "util/data/msgreply.h"
53#include "util/data/msgparse.h"
54#include "util/as112.h"
55
56struct local_zones*
57local_zones_create(void)
58{
59	struct local_zones* zones = (struct local_zones*)calloc(1,
60		sizeof(*zones));
61	if(!zones)
62		return NULL;
63	rbtree_init(&zones->ztree, &local_zone_cmp);
64	lock_rw_init(&zones->lock);
65	lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree));
66	/* also lock protects the rbnode's in struct local_zone */
67	return zones;
68}
69
70/** helper traverse to delete zones */
71static void
72lzdel(rbnode_t* n, void* ATTR_UNUSED(arg))
73{
74	struct local_zone* z = (struct local_zone*)n->key;
75	local_zone_delete(z);
76}
77
78void
79local_zones_delete(struct local_zones* zones)
80{
81	if(!zones)
82		return;
83	lock_rw_destroy(&zones->lock);
84	/* walk through zones and delete them all */
85	traverse_postorder(&zones->ztree, lzdel, NULL);
86	free(zones);
87}
88
89void
90local_zone_delete(struct local_zone* z)
91{
92	if(!z)
93		return;
94	lock_rw_destroy(&z->lock);
95	regional_destroy(z->region);
96	free(z->name);
97	free(z->taglist);
98	free(z);
99}
100
101int
102local_zone_cmp(const void* z1, const void* z2)
103{
104	/* first sort on class, so that hierarchy can be maintained within
105	 * a class */
106	struct local_zone* a = (struct local_zone*)z1;
107	struct local_zone* b = (struct local_zone*)z2;
108	int m;
109	if(a->dclass != b->dclass) {
110		if(a->dclass < b->dclass)
111			return -1;
112		return 1;
113	}
114	return dname_lab_cmp(a->name, a->namelabs, b->name, b->namelabs, &m);
115}
116
117int
118local_data_cmp(const void* d1, const void* d2)
119{
120	struct local_data* a = (struct local_data*)d1;
121	struct local_data* b = (struct local_data*)d2;
122	int m;
123	return dname_canon_lab_cmp(a->name, a->namelabs, b->name,
124		b->namelabs, &m);
125}
126
127/* form wireformat from text format domain name */
128int
129parse_dname(const char* str, uint8_t** res, size_t* len, int* labs)
130{
131	*res = sldns_str2wire_dname(str, len);
132	*labs = 0;
133	if(!*res) {
134		log_err("cannot parse name %s", str);
135		return 0;
136	}
137	*labs = dname_count_size_labels(*res, len);
138	return 1;
139}
140
141/** create a new localzone */
142static struct local_zone*
143local_zone_create(uint8_t* nm, size_t len, int labs,
144	enum localzone_type t, uint16_t dclass)
145{
146	struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z));
147	if(!z) {
148		return NULL;
149	}
150	z->node.key = z;
151	z->dclass = dclass;
152	z->type = t;
153	z->name = nm;
154	z->namelen = len;
155	z->namelabs = labs;
156	lock_rw_init(&z->lock);
157	z->region = regional_create();
158	if(!z->region) {
159		free(z);
160		return NULL;
161	}
162	rbtree_init(&z->data, &local_data_cmp);
163	lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_t));
164	/* also the zones->lock protects node, parent, name*, class */
165	return z;
166}
167
168/** enter a new zone with allocated dname returns with WRlock */
169static struct local_zone*
170lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
171	int labs, enum localzone_type t, uint16_t c)
172{
173	struct local_zone* z = local_zone_create(nm, len, labs, t, c);
174	if(!z) {
175		free(nm);
176		log_err("out of memory");
177		return NULL;
178	}
179
180	/* add to rbtree */
181	lock_rw_wrlock(&zones->lock);
182	lock_rw_wrlock(&z->lock);
183	if(!rbtree_insert(&zones->ztree, &z->node)) {
184		log_warn("duplicate local-zone");
185		lock_rw_unlock(&z->lock);
186		local_zone_delete(z);
187		/* find the correct zone, so not an error for duplicate */
188		z = local_zones_find(zones, nm, len, labs, c);
189		lock_rw_wrlock(&z->lock);
190		lock_rw_unlock(&zones->lock);
191		return z;
192	}
193	lock_rw_unlock(&zones->lock);
194	return z;
195}
196
197/** enter a new zone */
198static struct local_zone*
199lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
200	uint16_t dclass)
201{
202	struct local_zone* z;
203	enum localzone_type t;
204	uint8_t* nm;
205	size_t len;
206	int labs;
207	if(!parse_dname(name, &nm, &len, &labs)) {
208		log_err("bad zone name %s %s", name, type);
209		return NULL;
210	}
211	if(!local_zone_str2type(type, &t)) {
212		log_err("bad lz_enter_zone type %s %s", name, type);
213		free(nm);
214		return NULL;
215	}
216	if(!(z=lz_enter_zone_dname(zones, nm, len, labs, t, dclass))) {
217		log_err("could not enter zone %s %s", name, type);
218		return NULL;
219	}
220	return z;
221}
222
223/** return name and class and rdata of rr; parses string */
224static int
225get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
226	uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len,
227	uint8_t** rdata, size_t* rdata_len)
228{
229	size_t dname_len = 0;
230	int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
231		NULL, 0, NULL, 0);
232	if(e) {
233		log_err("error parsing local-data at %d: '%s': %s",
234			LDNS_WIREPARSE_OFFSET(e), str,
235			sldns_get_errorstr_parse(e));
236		return 0;
237	}
238	*nm = memdup(rr, dname_len);
239	if(!*nm) {
240		log_err("out of memory");
241		return 0;
242	}
243	*dclass = sldns_wirerr_get_class(rr, len, dname_len);
244	*type = sldns_wirerr_get_type(rr, len, dname_len);
245	*ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len);
246	*rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len);
247	*rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2;
248	return 1;
249}
250
251/** return name and class of rr; parses string */
252static int
253get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
254{
255	uint8_t rr[LDNS_RR_BUF_SIZE];
256	size_t len = sizeof(rr), dname_len = 0;
257	int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600,
258		NULL, 0, NULL, 0);
259	if(s != 0) {
260		log_err("error parsing local-data at %d '%s': %s",
261			LDNS_WIREPARSE_OFFSET(s), str,
262			sldns_get_errorstr_parse(s));
263		return 0;
264	}
265	*nm = memdup(rr, dname_len);
266	*dclass = sldns_wirerr_get_class(rr, len, dname_len);
267	if(!*nm) {
268		log_err("out of memory");
269		return 0;
270	}
271	return 1;
272}
273
274/**
275 * Find an rrset in local data structure.
276 * @param data: local data domain name structure.
277 * @param type: type to look for (host order).
278 * @return rrset pointer or NULL if not found.
279 */
280static struct local_rrset*
281local_data_find_type(struct local_data* data, uint16_t type)
282{
283	struct local_rrset* p;
284	type = htons(type);
285	for(p = data->rrsets; p; p = p->next) {
286		if(p->rrset->rk.type == type)
287			return p;
288	}
289	return NULL;
290}
291
292/** check for RR duplicates */
293static int
294rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
295{
296	size_t i;
297	for(i=0; i<pd->count; i++) {
298		if(pd->rr_len[i] == rdata_len &&
299			memcmp(pd->rr_data[i], rdata, rdata_len) == 0)
300			return 1;
301	}
302	return 0;
303}
304
305/** new local_rrset */
306static struct local_rrset*
307new_local_rrset(struct regional* region, struct local_data* node,
308	uint16_t rrtype, uint16_t rrclass)
309{
310	struct packed_rrset_data* pd;
311	struct local_rrset* rrset = (struct local_rrset*)
312		regional_alloc_zero(region, sizeof(*rrset));
313	if(!rrset) {
314		log_err("out of memory");
315		return NULL;
316	}
317	rrset->next = node->rrsets;
318	node->rrsets = rrset;
319	rrset->rrset = (struct ub_packed_rrset_key*)
320		regional_alloc_zero(region, sizeof(*rrset->rrset));
321	if(!rrset->rrset) {
322		log_err("out of memory");
323		return NULL;
324	}
325	rrset->rrset->entry.key = rrset->rrset;
326	pd = (struct packed_rrset_data*)regional_alloc_zero(region,
327		sizeof(*pd));
328	if(!pd) {
329		log_err("out of memory");
330		return NULL;
331	}
332	pd->trust = rrset_trust_prim_noglue;
333	pd->security = sec_status_insecure;
334	rrset->rrset->entry.data = pd;
335	rrset->rrset->rk.dname = node->name;
336	rrset->rrset->rk.dname_len = node->namelen;
337	rrset->rrset->rk.type = htons(rrtype);
338	rrset->rrset->rk.rrset_class = htons(rrclass);
339	return rrset;
340}
341
342/** insert RR into RRset data structure; Wastes a couple of bytes */
343static int
344insert_rr(struct regional* region, struct packed_rrset_data* pd,
345	uint8_t* rdata, size_t rdata_len, time_t ttl)
346{
347	size_t* oldlen = pd->rr_len;
348	time_t* oldttl = pd->rr_ttl;
349	uint8_t** olddata = pd->rr_data;
350
351	/* add RR to rrset */
352	pd->count++;
353	pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
354	pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
355	pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count);
356	if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
357		log_err("out of memory");
358		return 0;
359	}
360	if(pd->count > 1) {
361		memcpy(pd->rr_len+1, oldlen,
362			sizeof(*pd->rr_len)*(pd->count-1));
363		memcpy(pd->rr_ttl+1, oldttl,
364			sizeof(*pd->rr_ttl)*(pd->count-1));
365		memcpy(pd->rr_data+1, olddata,
366			sizeof(*pd->rr_data)*(pd->count-1));
367	}
368	pd->rr_len[0] = rdata_len;
369	pd->rr_ttl[0] = ttl;
370	pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len);
371	if(!pd->rr_data[0]) {
372		log_err("out of memory");
373		return 0;
374	}
375	return 1;
376}
377
378/** find a data node by exact name */
379static struct local_data*
380lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
381{
382	struct local_data key;
383	key.node.key = &key;
384	key.name = nm;
385	key.namelen = nmlen;
386	key.namelabs = nmlabs;
387	return (struct local_data*)rbtree_search(&z->data, &key.node);
388}
389
390/** find a node, create it if not and all its empty nonterminal parents */
391static int
392lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
393	int nmlabs, struct local_data** res)
394{
395	struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs);
396	if(!ld) {
397		/* create a domain name to store rr. */
398		ld = (struct local_data*)regional_alloc_zero(z->region,
399			sizeof(*ld));
400		if(!ld) {
401			log_err("out of memory adding local data");
402			return 0;
403		}
404		ld->node.key = ld;
405		ld->name = regional_alloc_init(z->region, nm, nmlen);
406		if(!ld->name) {
407			log_err("out of memory");
408			return 0;
409		}
410		ld->namelen = nmlen;
411		ld->namelabs = nmlabs;
412		if(!rbtree_insert(&z->data, &ld->node)) {
413			log_assert(0); /* duplicate name */
414		}
415		/* see if empty nonterminals need to be created */
416		if(nmlabs > z->namelabs) {
417			dname_remove_label(&nm, &nmlen);
418			if(!lz_find_create_node(z, nm, nmlen, nmlabs-1, res))
419				return 0;
420		}
421	}
422	*res = ld;
423	return 1;
424}
425
426/** enter data RR into auth zone */
427static int
428lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
429{
430	uint8_t* nm;
431	size_t nmlen;
432	int nmlabs;
433	struct local_data* node;
434	struct local_rrset* rrset;
435	struct packed_rrset_data* pd;
436	uint16_t rrtype = 0, rrclass = 0;
437	time_t ttl = 0;
438	uint8_t rr[LDNS_RR_BUF_SIZE];
439	uint8_t* rdata;
440	size_t rdata_len;
441	if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr),
442		&rdata, &rdata_len)) {
443		log_err("bad local-data: %s", rrstr);
444		return 0;
445	}
446	log_assert(z->dclass == rrclass);
447	if(z->type == local_zone_redirect &&
448		query_dname_compare(z->name, nm) != 0) {
449		log_err("local-data in redirect zone must reside at top of zone"
450			", not at %s", rrstr);
451		free(nm);
452		return 0;
453	}
454	nmlabs = dname_count_size_labels(nm, &nmlen);
455	if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
456		free(nm);
457		return 0;
458	}
459	log_assert(node);
460	free(nm);
461
462	rrset = local_data_find_type(node, rrtype);
463	if(!rrset) {
464		rrset = new_local_rrset(z->region, node, rrtype, rrclass);
465		if(!rrset)
466			return 0;
467		if(query_dname_compare(node->name, z->name) == 0) {
468			if(rrtype == LDNS_RR_TYPE_NSEC)
469			  rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
470			if(rrtype == LDNS_RR_TYPE_SOA)
471				z->soa = rrset->rrset;
472		}
473	}
474	pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
475	log_assert(rrset && pd);
476
477	/* check for duplicate RR */
478	if(rr_is_duplicate(pd, rdata, rdata_len)) {
479		verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr);
480		return 1;
481	}
482	return insert_rr(z->region, pd, rdata, rdata_len, ttl);
483}
484
485/** enter a data RR into auth data; a zone for it must exist */
486static int
487lz_enter_rr_str(struct local_zones* zones, const char* rr)
488{
489	uint8_t* rr_name;
490	uint16_t rr_class;
491	size_t len;
492	int labs;
493	struct local_zone* z;
494	int r;
495	if(!get_rr_nameclass(rr, &rr_name, &rr_class)) {
496		log_err("bad rr %s", rr);
497		return 0;
498	}
499	labs = dname_count_size_labels(rr_name, &len);
500	lock_rw_rdlock(&zones->lock);
501	z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
502	if(!z) {
503		lock_rw_unlock(&zones->lock);
504		fatal_exit("internal error: no zone for rr %s", rr);
505	}
506	lock_rw_wrlock(&z->lock);
507	lock_rw_unlock(&zones->lock);
508	free(rr_name);
509	r = lz_enter_rr_into_zone(z, rr);
510	lock_rw_unlock(&z->lock);
511	return r;
512}
513
514/** enter tagstring into zone */
515static int
516lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list,
517	size_t len, uint16_t rr_class)
518{
519	uint8_t dname[LDNS_MAX_DOMAINLEN+1];
520	size_t dname_len = sizeof(dname);
521	int dname_labs, r = 0;
522	struct local_zone* z;
523
524	if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
525		log_err("cannot parse zone name in local-zone-tag: %s", zname);
526		return 0;
527	}
528	dname_labs = dname_count_labels(dname);
529
530	lock_rw_rdlock(&zones->lock);
531	z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class);
532	if(!z) {
533		lock_rw_unlock(&zones->lock);
534		log_err("no local-zone for tag %s", zname);
535		return 0;
536	}
537	lock_rw_wrlock(&z->lock);
538	lock_rw_unlock(&zones->lock);
539	free(z->taglist);
540	z->taglist = memdup(list, len);
541	z->taglen = len;
542	if(z->taglist)
543		r = 1;
544	lock_rw_unlock(&z->lock);
545	return r;
546}
547
548/** enter override into zone */
549static int
550lz_enter_override(struct local_zones* zones, char* zname, char* netblock,
551	char* type, uint16_t rr_class)
552{
553	uint8_t dname[LDNS_MAX_DOMAINLEN+1];
554	size_t dname_len = sizeof(dname);
555	int dname_labs;
556	struct sockaddr_storage addr;
557	int net;
558	socklen_t addrlen;
559	struct local_zone* z;
560	enum localzone_type t;
561
562	/* parse zone name */
563	if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
564		log_err("cannot parse zone name in local-zone-override: %s %s",
565			zname, netblock);
566		return 0;
567	}
568	dname_labs = dname_count_labels(dname);
569
570	/* parse netblock */
571	if(!netblockstrtoaddr(netblock, UNBOUND_DNS_PORT, &addr, &addrlen,
572		&net)) {
573		log_err("cannot parse netblock in local-zone-override: %s %s",
574			zname, netblock);
575		return 0;
576	}
577
578	/* parse zone type */
579	if(!local_zone_str2type(type, &t)) {
580		log_err("cannot parse type in local-zone-override: %s %s %s",
581			zname, netblock, type);
582		return 0;
583	}
584
585	/* find localzone entry */
586	lock_rw_rdlock(&zones->lock);
587	z = local_zones_find(zones, dname, dname_len, dname_labs, rr_class);
588	if(!z) {
589		lock_rw_unlock(&zones->lock);
590		log_err("no local-zone for local-zone-override %s", zname);
591		return 0;
592	}
593	lock_rw_wrlock(&z->lock);
594	lock_rw_unlock(&zones->lock);
595
596	/* create netblock addr_tree if not present yet */
597	if(!z->override_tree) {
598		z->override_tree = (struct rbtree_t*)regional_alloc_zero(
599			z->region, sizeof(*z->override_tree));
600		if(!z->override_tree) {
601			lock_rw_unlock(&z->lock);
602			log_err("out of memory");
603			return 0;
604		}
605		addr_tree_init(z->override_tree);
606	}
607	/* add new elem to tree */
608	if(z->override_tree) {
609		struct local_zone_override* n;
610		n = (struct local_zone_override*)regional_alloc_zero(
611			z->region, sizeof(*n));
612		if(!n) {
613			lock_rw_unlock(&z->lock);
614			log_err("out of memory");
615			return 0;
616		}
617		n->type = t;
618		if(!addr_tree_insert(z->override_tree,
619			(struct addr_tree_node*)n, &addr, addrlen, net)) {
620			lock_rw_unlock(&z->lock);
621			log_err("duplicate local-zone-override %s %s",
622				zname, netblock);
623			return 1;
624		}
625	}
626
627	lock_rw_unlock(&z->lock);
628	return 1;
629}
630
631/** parse local-zone: statements */
632static int
633lz_enter_zones(struct local_zones* zones, struct config_file* cfg)
634{
635	struct config_str2list* p;
636	struct local_zone* z;
637	for(p = cfg->local_zones; p; p = p->next) {
638		if(!(z=lz_enter_zone(zones, p->str, p->str2,
639			LDNS_RR_CLASS_IN)))
640			return 0;
641		lock_rw_unlock(&z->lock);
642	}
643	return 1;
644}
645
646/** lookup a zone in rbtree; exact match only; SLOW due to parse */
647static int
648lz_exists(struct local_zones* zones, const char* name)
649{
650	struct local_zone z;
651	z.node.key = &z;
652	z.dclass = LDNS_RR_CLASS_IN;
653	if(!parse_dname(name, &z.name, &z.namelen, &z.namelabs)) {
654		log_err("bad name %s", name);
655		return 0;
656	}
657	lock_rw_rdlock(&zones->lock);
658	if(rbtree_search(&zones->ztree, &z.node)) {
659		lock_rw_unlock(&zones->lock);
660		free(z.name);
661		return 1;
662	}
663	lock_rw_unlock(&zones->lock);
664	free(z.name);
665	return 0;
666}
667
668/** lookup a zone in cfg->nodefault list */
669static int
670lz_nodefault(struct config_file* cfg, const char* name)
671{
672	struct config_strlist* p;
673	size_t len = strlen(name);
674	if(len == 0) return 0;
675	if(name[len-1] == '.') len--;
676
677	for(p = cfg->local_zones_nodefault; p; p = p->next) {
678		/* compare zone name, lowercase, compare without ending . */
679		if(strncasecmp(p->str, name, len) == 0 &&
680			(strlen(p->str) == len || (strlen(p->str)==len+1 &&
681			p->str[len] == '.')))
682			return 1;
683	}
684	return 0;
685}
686
687/** enter AS112 default zone */
688static int
689add_as112_default(struct local_zones* zones, struct config_file* cfg,
690        const char* name)
691{
692	struct local_zone* z;
693	char str[1024]; /* known long enough */
694	if(lz_exists(zones, name) || lz_nodefault(cfg, name))
695		return 1; /* do not enter default content */
696	if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN)))
697		return 0;
698	snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
699		"nobody.invalid. 1 3600 1200 604800 10800", name);
700	if(!lz_enter_rr_into_zone(z, str)) {
701		lock_rw_unlock(&z->lock);
702		return 0;
703	}
704	snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
705	if(!lz_enter_rr_into_zone(z, str)) {
706		lock_rw_unlock(&z->lock);
707		return 0;
708	}
709	lock_rw_unlock(&z->lock);
710	return 1;
711}
712
713/** enter default zones */
714static int
715lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
716{
717	struct local_zone* z;
718	const char** zstr;
719
720	/* this list of zones is from RFC 6303 and RFC 7686 */
721
722	/* block localhost level zones first, then onion and later the LAN zones */
723
724	/* localhost. zone */
725	if(!lz_exists(zones, "localhost.") &&
726		!lz_nodefault(cfg, "localhost.")) {
727		if(!(z=lz_enter_zone(zones, "localhost.", "static",
728			LDNS_RR_CLASS_IN)) ||
729		   !lz_enter_rr_into_zone(z,
730			"localhost. 10800 IN NS localhost.") ||
731		   !lz_enter_rr_into_zone(z,
732			"localhost. 10800 IN SOA localhost. nobody.invalid. "
733			"1 3600 1200 604800 10800") ||
734		   !lz_enter_rr_into_zone(z,
735			"localhost. 10800 IN A 127.0.0.1") ||
736		   !lz_enter_rr_into_zone(z,
737			"localhost. 10800 IN AAAA ::1")) {
738			log_err("out of memory adding default zone");
739			if(z) { lock_rw_unlock(&z->lock); }
740			return 0;
741		}
742		lock_rw_unlock(&z->lock);
743	}
744	/* reverse ip4 zone */
745	if(!lz_exists(zones, "127.in-addr.arpa.") &&
746		!lz_nodefault(cfg, "127.in-addr.arpa.")) {
747		if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
748			LDNS_RR_CLASS_IN)) ||
749		   !lz_enter_rr_into_zone(z,
750			"127.in-addr.arpa. 10800 IN NS localhost.") ||
751		   !lz_enter_rr_into_zone(z,
752			"127.in-addr.arpa. 10800 IN SOA localhost. "
753			"nobody.invalid. 1 3600 1200 604800 10800") ||
754		   !lz_enter_rr_into_zone(z,
755			"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
756			log_err("out of memory adding default zone");
757			if(z) { lock_rw_unlock(&z->lock); }
758			return 0;
759		}
760		lock_rw_unlock(&z->lock);
761	}
762	/* reverse ip6 zone */
763	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.") &&
764		!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.")) {
765		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",
766			LDNS_RR_CLASS_IN)) ||
767		   !lz_enter_rr_into_zone(z,
768			"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.") ||
769		   !lz_enter_rr_into_zone(z,
770			"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. "
771			"nobody.invalid. 1 3600 1200 604800 10800") ||
772		   !lz_enter_rr_into_zone(z,
773			"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.")) {
774			log_err("out of memory adding default zone");
775			if(z) { lock_rw_unlock(&z->lock); }
776			return 0;
777		}
778		lock_rw_unlock(&z->lock);
779	}
780	/* onion. zone (RFC 7686) */
781	if(!lz_exists(zones, "onion.") &&
782		!lz_nodefault(cfg, "onion.")) {
783		if(!(z=lz_enter_zone(zones, "onion.", "static",
784			LDNS_RR_CLASS_IN)) ||
785		   !lz_enter_rr_into_zone(z,
786			"onion. 10800 IN NS localhost.") ||
787		   !lz_enter_rr_into_zone(z,
788			"onion. 10800 IN SOA localhost. nobody.invalid. "
789			"1 3600 1200 604800 10800")) {
790			log_err("out of memory adding default zone");
791			if(z) { lock_rw_unlock(&z->lock); }
792			return 0;
793		}
794		lock_rw_unlock(&z->lock);
795	}
796
797	/* block AS112 zones, unless asked not to */
798	if(!cfg->unblock_lan_zones) {
799		for(zstr = as112_zones; *zstr; zstr++) {
800			if(!add_as112_default(zones, cfg, *zstr)) {
801				log_err("out of memory adding default zone");
802				return 0;
803			}
804		}
805	}
806	return 1;
807}
808
809/** parse local-zone-override: statements */
810static int
811lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
812{
813	struct config_str3list* p;
814	for(p = cfg->local_zone_overrides; p; p = p->next) {
815		if(!lz_enter_override(zones, p->str, p->str2, p->str3,
816			LDNS_RR_CLASS_IN))
817			return 0;
818	}
819	return 1;
820}
821
822/** setup parent pointers, so that a lookup can be done for closest match */
823static void
824init_parents(struct local_zones* zones)
825{
826        struct local_zone* node, *prev = NULL, *p;
827        int m;
828	lock_rw_wrlock(&zones->lock);
829        RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
830		lock_rw_wrlock(&node->lock);
831                node->parent = NULL;
832                if(!prev || prev->dclass != node->dclass) {
833                        prev = node;
834			lock_rw_unlock(&node->lock);
835                        continue;
836                }
837                (void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
838                        node->namelabs, &m); /* we know prev is smaller */
839                /* sort order like: . com. bla.com. zwb.com. net. */
840                /* find the previous, or parent-parent-parent */
841                for(p = prev; p; p = p->parent)
842                        /* looking for name with few labels, a parent */
843                        if(p->namelabs <= m) {
844                                /* ==: since prev matched m, this is closest*/
845                                /* <: prev matches more, but is not a parent,
846                                 * this one is a (grand)parent */
847                                node->parent = p;
848                                break;
849                        }
850                prev = node;
851
852		if(node->override_tree)
853			addr_tree_init_parents(node->override_tree);
854		lock_rw_unlock(&node->lock);
855        }
856	lock_rw_unlock(&zones->lock);
857}
858
859/** enter implicit transparent zone for local-data: without local-zone: */
860static int
861lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
862{
863	/* walk over all items that have no parent zone and find
864	 * the name that covers them all (could be the root) and
865	 * add that as a transparent zone */
866	struct config_strlist* p;
867	int have_name = 0;
868	int have_other_classes = 0;
869	uint16_t dclass = 0;
870	uint8_t* nm = 0;
871	size_t nmlen = 0;
872	int nmlabs = 0;
873	int match = 0; /* number of labels match count */
874
875	init_parents(zones); /* to enable local_zones_lookup() */
876	for(p = cfg->local_data; p; p = p->next) {
877		uint8_t* rr_name;
878		uint16_t rr_class;
879		size_t len;
880		int labs;
881		if(!get_rr_nameclass(p->str, &rr_name, &rr_class)) {
882			log_err("Bad local-data RR %s", p->str);
883			return 0;
884		}
885		labs = dname_count_size_labels(rr_name, &len);
886		lock_rw_rdlock(&zones->lock);
887		if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) {
888			if(!have_name) {
889				dclass = rr_class;
890				nm = rr_name;
891				nmlen = len;
892				nmlabs = labs;
893				match = labs;
894				have_name = 1;
895			} else {
896				int m;
897				if(rr_class != dclass) {
898					/* process other classes later */
899					free(rr_name);
900					have_other_classes = 1;
901					lock_rw_unlock(&zones->lock);
902					continue;
903				}
904				/* find smallest shared topdomain */
905				(void)dname_lab_cmp(nm, nmlabs,
906					rr_name, labs, &m);
907				free(rr_name);
908				if(m < match)
909					match = m;
910			}
911		} else free(rr_name);
912		lock_rw_unlock(&zones->lock);
913	}
914	if(have_name) {
915		uint8_t* n2;
916		struct local_zone* z;
917		/* allocate zone of smallest shared topdomain to contain em */
918		n2 = nm;
919		dname_remove_labels(&n2, &nmlen, nmlabs - match);
920		n2 = memdup(n2, nmlen);
921		free(nm);
922		if(!n2) {
923			log_err("out of memory");
924			return 0;
925		}
926		log_nametypeclass(VERB_ALGO, "implicit transparent local-zone",
927			n2, 0, dclass);
928		if(!(z=lz_enter_zone_dname(zones, n2, nmlen, match,
929			local_zone_transparent, dclass))) {
930			return 0;
931		}
932		lock_rw_unlock(&z->lock);
933	}
934	if(have_other_classes) {
935		/* restart to setup other class */
936		return lz_setup_implicit(zones, cfg);
937	}
938	return 1;
939}
940
941/** enter local-zone-tag info */
942static int
943lz_enter_zone_tags(struct local_zones* zones, struct config_file* cfg)
944{
945	struct config_strbytelist* p;
946	int c = 0;
947	for(p = cfg->local_zone_tags; p; p = p->next) {
948		if(!lz_enter_zone_tag(zones, p->str, p->str2, p->str2len,
949			LDNS_RR_CLASS_IN))
950			return 0;
951		c++;
952	}
953	if(c) verbose(VERB_ALGO, "applied tags to %d local zones", c);
954	return 1;
955}
956
957/** enter auth data */
958static int
959lz_enter_data(struct local_zones* zones, struct config_file* cfg)
960{
961	struct config_strlist* p;
962	for(p = cfg->local_data; p; p = p->next) {
963		if(!lz_enter_rr_str(zones, p->str))
964			return 0;
965	}
966	return 1;
967}
968
969/** free memory from config */
970static void
971lz_freeup_cfg(struct config_file* cfg)
972{
973	config_deldblstrlist(cfg->local_zones);
974	cfg->local_zones = NULL;
975	config_delstrlist(cfg->local_zones_nodefault);
976	cfg->local_zones_nodefault = NULL;
977	config_delstrlist(cfg->local_data);
978	cfg->local_data = NULL;
979}
980
981int
982local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
983{
984	/* create zones from zone statements. */
985	if(!lz_enter_zones(zones, cfg)) {
986		return 0;
987	}
988	/* apply default zones+content (unless disabled, or overridden) */
989	if(!lz_enter_defaults(zones, cfg)) {
990		return 0;
991	}
992	/* enter local zone overrides */
993	if(!lz_enter_overrides(zones, cfg)) {
994		return 0;
995	}
996	/* create implicit transparent zone from data. */
997	if(!lz_setup_implicit(zones, cfg)) {
998		return 0;
999	}
1000
1001	/* setup parent ptrs for lookup during data entry */
1002	init_parents(zones);
1003	/* insert local zone tags */
1004	if(!lz_enter_zone_tags(zones, cfg)) {
1005		return 0;
1006	}
1007	/* insert local data */
1008	if(!lz_enter_data(zones, cfg)) {
1009		return 0;
1010	}
1011	/* freeup memory from cfg struct. */
1012	lz_freeup_cfg(cfg);
1013	return 1;
1014}
1015
1016struct local_zone*
1017local_zones_lookup(struct local_zones* zones,
1018        uint8_t* name, size_t len, int labs, uint16_t dclass)
1019{
1020	return local_zones_tags_lookup(zones, name, len, labs,
1021		dclass, NULL, 0, 1);
1022}
1023
1024struct local_zone*
1025local_zones_tags_lookup(struct local_zones* zones,
1026        uint8_t* name, size_t len, int labs, uint16_t dclass,
1027	uint8_t* taglist, size_t taglen, int ignoretags)
1028{
1029	rbnode_t* res = NULL;
1030	struct local_zone *result;
1031	struct local_zone key;
1032	int m;
1033	key.node.key = &key;
1034	key.dclass = dclass;
1035	key.name = name;
1036	key.namelen = len;
1037	key.namelabs = labs;
1038	rbtree_find_less_equal(&zones->ztree, &key, &res);
1039	result = (struct local_zone*)res;
1040	/* exact or smaller element (or no element) */
1041	if(!result || result->dclass != dclass)
1042		return NULL;
1043	/* count number of labels matched */
1044	(void)dname_lab_cmp(result->name, result->namelabs, key.name,
1045		key.namelabs, &m);
1046	while(result) { /* go up until qname is zone or subdomain of zone */
1047		if(result->namelabs <= m)
1048			if(ignoretags || !result->taglist ||
1049				taglist_intersect(result->taglist,
1050				result->taglen, taglist, taglen))
1051				break;
1052		result = result->parent;
1053	}
1054	return result;
1055}
1056
1057struct local_zone*
1058local_zones_find(struct local_zones* zones,
1059        uint8_t* name, size_t len, int labs, uint16_t dclass)
1060{
1061	struct local_zone key;
1062	key.node.key = &key;
1063	key.dclass = dclass;
1064	key.name = name;
1065	key.namelen = len;
1066	key.namelabs = labs;
1067	/* exact */
1068	return (struct local_zone*)rbtree_search(&zones->ztree, &key);
1069}
1070
1071/** print all RRsets in local zone */
1072static void
1073local_zone_out(struct local_zone* z)
1074{
1075	struct local_data* d;
1076	struct local_rrset* p;
1077	RBTREE_FOR(d, struct local_data*, &z->data) {
1078		for(p = d->rrsets; p; p = p->next) {
1079			log_nametypeclass(0, "rrset", d->name,
1080				ntohs(p->rrset->rk.type),
1081				ntohs(p->rrset->rk.rrset_class));
1082		}
1083	}
1084}
1085
1086void local_zones_print(struct local_zones* zones)
1087{
1088	struct local_zone* z;
1089	lock_rw_rdlock(&zones->lock);
1090	log_info("number of auth zones %u", (unsigned)zones->ztree.count);
1091	RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
1092		lock_rw_rdlock(&z->lock);
1093		switch(z->type) {
1094		case local_zone_deny:
1095			log_nametypeclass(0, "deny zone",
1096				z->name, 0, z->dclass);
1097			break;
1098		case local_zone_refuse:
1099			log_nametypeclass(0, "refuse zone",
1100				z->name, 0, z->dclass);
1101			break;
1102		case local_zone_redirect:
1103			log_nametypeclass(0, "redirect zone",
1104				z->name, 0, z->dclass);
1105			break;
1106		case local_zone_transparent:
1107			log_nametypeclass(0, "transparent zone",
1108				z->name, 0, z->dclass);
1109			break;
1110		case local_zone_typetransparent:
1111			log_nametypeclass(0, "typetransparent zone",
1112				z->name, 0, z->dclass);
1113			break;
1114		case local_zone_static:
1115			log_nametypeclass(0, "static zone",
1116				z->name, 0, z->dclass);
1117			break;
1118		case local_zone_inform:
1119			log_nametypeclass(0, "inform zone",
1120				z->name, 0, z->dclass);
1121			break;
1122		case local_zone_inform_deny:
1123			log_nametypeclass(0, "inform_deny zone",
1124				z->name, 0, z->dclass);
1125			break;
1126		case local_zone_always_transparent:
1127			log_nametypeclass(0, "always_transparent zone",
1128				z->name, 0, z->dclass);
1129			break;
1130		case local_zone_always_refuse:
1131			log_nametypeclass(0, "always_refuse zone",
1132				z->name, 0, z->dclass);
1133			break;
1134		case local_zone_always_nxdomain:
1135			log_nametypeclass(0, "always_nxdomain zone",
1136				z->name, 0, z->dclass);
1137			break;
1138		default:
1139			log_nametypeclass(0, "badtyped zone",
1140				z->name, 0, z->dclass);
1141			break;
1142		}
1143		local_zone_out(z);
1144		lock_rw_unlock(&z->lock);
1145	}
1146	lock_rw_unlock(&zones->lock);
1147}
1148
1149/** encode answer consisting of 1 rrset */
1150static int
1151local_encode(struct query_info* qinfo, struct edns_data* edns,
1152	sldns_buffer* buf, struct regional* temp,
1153	struct ub_packed_rrset_key* rrset, int ansec, int rcode)
1154{
1155	struct reply_info rep;
1156	uint16_t udpsize;
1157	/* make answer with time=0 for fixed TTL values */
1158	memset(&rep, 0, sizeof(rep));
1159	rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
1160	rep.qdcount = 1;
1161	if(ansec)
1162		rep.an_numrrsets = 1;
1163	else	rep.ns_numrrsets = 1;
1164	rep.rrset_count = 1;
1165	rep.rrsets = &rrset;
1166	udpsize = edns->udp_size;
1167	edns->edns_version = EDNS_ADVERTISED_VERSION;
1168	edns->udp_size = EDNS_ADVERTISED_SIZE;
1169	edns->ext_rcode = 0;
1170	edns->bits &= EDNS_DO;
1171	if(!edns_opt_inplace_reply(edns, temp) ||
1172	   !reply_info_answer_encode(qinfo, &rep,
1173		*(uint16_t*)sldns_buffer_begin(buf),
1174		sldns_buffer_read_u16_at(buf, 2),
1175		buf, 0, 0, temp, udpsize, edns,
1176		(int)(edns->bits&EDNS_DO), 0))
1177		error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
1178			*(uint16_t*)sldns_buffer_begin(buf),
1179		       sldns_buffer_read_u16_at(buf, 2), edns);
1180	return 1;
1181}
1182
1183/** find local data tag string match for the given type in the list */
1184static int
1185find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
1186	struct ub_packed_rrset_key* r, struct regional* temp,
1187	uint8_t* zname, size_t zlen)
1188{
1189	struct config_strlist* p;
1190	char buf[65536];
1191	uint8_t rr[LDNS_RR_BUF_SIZE];
1192	size_t len;
1193	int res;
1194	struct packed_rrset_data* d;
1195	for(p=list; p; p=p->next) {
1196		len = sizeof(rr);
1197		/* does this element match the type? */
1198		snprintf(buf, sizeof(buf), ". %s", p->str);
1199		res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
1200			zname, zlen, NULL, 0);
1201		if(res != 0)
1202			/* parse errors are already checked before, in
1203			 * acllist check_data, skip this for robustness */
1204			continue;
1205		if(len < 1 /* . */ + 8 /* typeclassttl*/ + 2 /*rdatalen*/)
1206			continue;
1207		if(sldns_wirerr_get_type(rr, len, 1) != qinfo->qtype)
1208			continue;
1209
1210		/* do we have entries already? if not setup key */
1211		if(r->rk.dname == NULL) {
1212			r->entry.key = r;
1213			r->rk.dname = qinfo->qname;
1214			r->rk.dname_len = qinfo->qname_len;
1215			r->rk.type = htons(qinfo->qtype);
1216			r->rk.rrset_class = htons(qinfo->qclass);
1217			r->rk.flags = 0;
1218			d = (struct packed_rrset_data*)regional_alloc_zero(
1219				temp, sizeof(struct packed_rrset_data)
1220				+ sizeof(size_t) + sizeof(uint8_t*) +
1221				sizeof(time_t));
1222			if(!d) return 0; /* out of memory */
1223			r->entry.data = d;
1224			d->ttl = sldns_wirerr_get_ttl(rr, len, 1);
1225			d->rr_len = (size_t*)((uint8_t*)d +
1226				sizeof(struct packed_rrset_data));
1227			d->rr_data = (uint8_t**)&(d->rr_len[1]);
1228			d->rr_ttl = (time_t*)&(d->rr_data[1]);
1229		}
1230		d = (struct packed_rrset_data*)r->entry.data;
1231		/* add entry to the data */
1232		if(d->count != 0) {
1233			size_t* oldlen = d->rr_len;
1234			uint8_t** olddata = d->rr_data;
1235			time_t* oldttl = d->rr_ttl;
1236			/* increase arrays for lookup */
1237			/* this is of course slow for very many records,
1238			 * but most redirects are expected with few records */
1239			d->rr_len = (size_t*)regional_alloc_zero(temp,
1240				(d->count+1)*sizeof(size_t));
1241			d->rr_data = (uint8_t**)regional_alloc_zero(temp,
1242				(d->count+1)*sizeof(uint8_t*));
1243			d->rr_ttl = (time_t*)regional_alloc_zero(temp,
1244				(d->count+1)*sizeof(time_t));
1245			if(!d->rr_len || !d->rr_data || !d->rr_ttl)
1246				return 0; /* out of memory */
1247			/* first one was allocated after struct d, but new
1248			 * ones get their own array increment alloc, so
1249			 * copy old content */
1250			memmove(d->rr_len, oldlen, d->count*sizeof(size_t));
1251			memmove(d->rr_data, olddata, d->count*sizeof(uint8_t*));
1252			memmove(d->rr_ttl, oldttl, d->count*sizeof(time_t));
1253		}
1254
1255		d->rr_len[d->count] = sldns_wirerr_get_rdatalen(rr, len, 1)+2;
1256		d->rr_ttl[d->count] = sldns_wirerr_get_ttl(rr, len, 1);
1257		d->rr_data[d->count] = regional_alloc_init(temp,
1258			sldns_wirerr_get_rdatawl(rr, len, 1),
1259			d->rr_len[d->count]);
1260		if(!d->rr_data[d->count])
1261			if(!d) return 0; /* out of memory */
1262		d->count++;
1263	}
1264	if(r->rk.dname)
1265		return 1;
1266	return 0;
1267}
1268
1269/** answer local data match */
1270static int
1271local_data_answer(struct local_zone* z, struct query_info* qinfo,
1272	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
1273	int labs, struct local_data** ldp, enum localzone_type lz_type,
1274	int tag, struct config_strlist** tag_datas, size_t tag_datas_size,
1275	char** tagname, int num_tags)
1276{
1277	struct local_data key;
1278	struct local_data* ld;
1279	struct local_rrset* lr;
1280	key.node.key = &key;
1281	key.name = qinfo->qname;
1282	key.namelen = qinfo->qname_len;
1283	key.namelabs = labs;
1284	if(lz_type == local_zone_redirect) {
1285		key.name = z->name;
1286		key.namelen = z->namelen;
1287		key.namelabs = z->namelabs;
1288		if(tag != -1 && (size_t)tag<tag_datas_size && tag_datas[tag]) {
1289			struct ub_packed_rrset_key r;
1290			memset(&r, 0, sizeof(r));
1291			if(find_tag_datas(qinfo, tag_datas[tag], &r, temp,
1292				z->name, z->namelen)) {
1293				verbose(VERB_ALGO, "redirect with tag data [%d] %s",
1294					tag, (tag<num_tags?tagname[tag]:"null"));
1295				return local_encode(qinfo, edns, buf, temp,
1296					&r, 1, LDNS_RCODE_NOERROR);
1297			}
1298		}
1299	}
1300	ld = (struct local_data*)rbtree_search(&z->data, &key.node);
1301	*ldp = ld;
1302	if(!ld) {
1303		return 0;
1304	}
1305	lr = local_data_find_type(ld, qinfo->qtype);
1306	if(!lr)
1307		return 0;
1308	if(lz_type == local_zone_redirect) {
1309		/* convert rrset name to query name; like a wildcard */
1310		struct ub_packed_rrset_key r = *lr->rrset;
1311		r.rk.dname = qinfo->qname;
1312		r.rk.dname_len = qinfo->qname_len;
1313		return local_encode(qinfo, edns, buf, temp, &r, 1,
1314			LDNS_RCODE_NOERROR);
1315	}
1316	return local_encode(qinfo, edns, buf, temp, lr->rrset, 1,
1317		LDNS_RCODE_NOERROR);
1318}
1319
1320/**
1321 * answer in case where no exact match is found
1322 * @param z: zone for query
1323 * @param qinfo: query
1324 * @param edns: edns from query
1325 * @param buf: buffer for answer.
1326 * @param temp: temp region for encoding
1327 * @param ld: local data, if NULL, no such name exists in localdata.
1328 * @param lz_type: type of the local zone
1329 * @return 1 if a reply is to be sent, 0 if not.
1330 */
1331static int
1332lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
1333	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
1334	struct local_data* ld, enum localzone_type lz_type)
1335{
1336	if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
1337		/** no reply at all, signal caller by clearing buffer. */
1338		sldns_buffer_clear(buf);
1339		sldns_buffer_flip(buf);
1340		return 1;
1341	} else if(lz_type == local_zone_refuse
1342		|| lz_type == local_zone_always_refuse) {
1343		error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo,
1344			*(uint16_t*)sldns_buffer_begin(buf),
1345		       sldns_buffer_read_u16_at(buf, 2), edns);
1346		return 1;
1347	} else if(lz_type == local_zone_static ||
1348		lz_type == local_zone_redirect ||
1349		lz_type == local_zone_always_nxdomain) {
1350		/* for static, reply nodata or nxdomain
1351		 * for redirect, reply nodata */
1352		/* no additional section processing,
1353		 * cname, dname or wildcard processing,
1354		 * or using closest match for NSEC.
1355		 * or using closest match for returning delegation downwards
1356		 */
1357		int rcode = (ld || lz_type == local_zone_redirect)?
1358			LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
1359		if(z->soa)
1360			return local_encode(qinfo, edns, buf, temp,
1361				z->soa, 0, rcode);
1362		error_encode(buf, (rcode|BIT_AA), qinfo,
1363			*(uint16_t*)sldns_buffer_begin(buf),
1364			sldns_buffer_read_u16_at(buf, 2), edns);
1365		return 1;
1366	} else if(lz_type == local_zone_typetransparent
1367		|| lz_type == local_zone_always_transparent) {
1368		/* no NODATA or NXDOMAINS for this zone type */
1369		return 0;
1370	}
1371	/* else lz_type == local_zone_transparent */
1372
1373	/* if the zone is transparent and the name exists, but the type
1374	 * does not, then we should make this noerror/nodata */
1375	if(ld && ld->rrsets) {
1376		int rcode = LDNS_RCODE_NOERROR;
1377		if(z->soa)
1378			return local_encode(qinfo, edns, buf, temp,
1379				z->soa, 0, rcode);
1380		error_encode(buf, (rcode|BIT_AA), qinfo,
1381			*(uint16_t*)sldns_buffer_begin(buf),
1382			sldns_buffer_read_u16_at(buf, 2), edns);
1383		return 1;
1384	}
1385
1386	/* stop here, and resolve further on */
1387	return 0;
1388}
1389
1390/** print log information for an inform zone query */
1391static void
1392lz_inform_print(struct local_zone* z, struct query_info* qinfo,
1393	struct comm_reply* repinfo)
1394{
1395	char ip[128], txt[512];
1396	char zname[LDNS_MAX_DOMAINLEN+1];
1397	uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
1398	dname_str(z->name, zname);
1399	addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
1400	snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip,
1401		(unsigned)port);
1402	log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
1403}
1404
1405static enum localzone_type
1406lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
1407	uint8_t *tagactions, size_t tagactionssize, enum localzone_type lzt,
1408	struct comm_reply* repinfo, struct rbtree_t* override_tree, int* tag,
1409	char** tagname, int num_tags)
1410{
1411	size_t i, j;
1412	uint8_t tagmatch;
1413	struct local_zone_override* lzo;
1414	if(repinfo && override_tree) {
1415		lzo = (struct local_zone_override*)addr_tree_lookup(
1416			override_tree, &repinfo->addr, repinfo->addrlen);
1417		if(lzo && lzo->type) {
1418			verbose(VERB_ALGO, "local zone override to type %s",
1419				local_zone_type2str(lzo->type));
1420			return lzo->type;
1421		}
1422	}
1423	if(!taglist || !taglist2)
1424		return lzt;
1425	for(i=0; i<taglen && i<taglen2; i++) {
1426		tagmatch = (taglist[i] & taglist2[i]);
1427		for(j=0; j<8 && tagmatch>0; j++) {
1428			if((tagmatch & 0x1)) {
1429				*tag = (int)(i*8+j);
1430				verbose(VERB_ALGO, "matched tag [%d] %s",
1431					*tag, (*tag<num_tags?tagname[*tag]:"null"));
1432				/* does this tag have a tag action? */
1433				if(i*8+j < tagactionssize && tagactions
1434				   && tagactions[i*8+j] != 0) {
1435				  verbose(VERB_ALGO, "tag action [%d] %s to type %s",
1436					*tag, (*tag<num_tags?tagname[*tag]:"null"),
1437				  	local_zone_type2str(
1438					(enum localzone_type)
1439					tagactions[i*8+j]));
1440				  return (enum localzone_type)tagactions[i*8+j];
1441				}
1442				return lzt;
1443			}
1444			tagmatch >>= 1;
1445		}
1446	}
1447	return lzt;
1448}
1449
1450int
1451local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
1452	struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
1453	struct comm_reply* repinfo, uint8_t* taglist, size_t taglen,
1454	uint8_t* tagactions, size_t tagactionssize,
1455	struct config_strlist** tag_datas, size_t tag_datas_size,
1456	char** tagname, int num_tags)
1457{
1458	/* see if query is covered by a zone,
1459	 * 	if so:	- try to match (exact) local data
1460	 * 		- look at zone type for negative response. */
1461	int labs = dname_count_labels(qinfo->qname);
1462	struct local_data* ld = NULL;
1463	struct local_zone* z;
1464	enum localzone_type lzt;
1465	int r, tag = -1;
1466	lock_rw_rdlock(&zones->lock);
1467	z = local_zones_tags_lookup(zones, qinfo->qname,
1468		qinfo->qname_len, labs, qinfo->qclass, taglist, taglen, 0);
1469	if(!z) {
1470		lock_rw_unlock(&zones->lock);
1471		return 0;
1472	}
1473	lock_rw_rdlock(&z->lock);
1474	lock_rw_unlock(&zones->lock);
1475
1476	lzt = lz_type(taglist, taglen, z->taglist, z->taglen, tagactions,
1477		tagactionssize, z->type, repinfo, z->override_tree, &tag,
1478		tagname, num_tags);
1479
1480	if((lzt == local_zone_inform || lzt == local_zone_inform_deny)
1481		&& repinfo)
1482		lz_inform_print(z, qinfo, repinfo);
1483
1484	if(lzt != local_zone_always_refuse && lzt != local_zone_always_transparent
1485		&& lzt != local_zone_always_nxdomain
1486		&& local_data_answer(z, qinfo, edns, buf, temp, labs, &ld, lzt,
1487		tag, tag_datas, tag_datas_size, tagname, num_tags)) {
1488		lock_rw_unlock(&z->lock);
1489		return 1;
1490	}
1491	r = lz_zone_answer(z, qinfo, edns, buf, temp, ld, lzt);
1492	lock_rw_unlock(&z->lock);
1493	return r;
1494}
1495
1496const char* local_zone_type2str(enum localzone_type t)
1497{
1498	switch(t) {
1499		case local_zone_deny: return "deny";
1500		case local_zone_refuse: return "refuse";
1501		case local_zone_redirect: return "redirect";
1502		case local_zone_transparent: return "transparent";
1503		case local_zone_typetransparent: return "typetransparent";
1504		case local_zone_static: return "static";
1505		case local_zone_nodefault: return "nodefault";
1506		case local_zone_inform: return "inform";
1507		case local_zone_inform_deny: return "inform_deny";
1508		case local_zone_always_transparent: return "always_transparent";
1509		case local_zone_always_refuse: return "always_refuse";
1510		case local_zone_always_nxdomain: return "always_nxdomain";
1511	}
1512	return "badtyped";
1513}
1514
1515int local_zone_str2type(const char* type, enum localzone_type* t)
1516{
1517	if(strcmp(type, "deny") == 0)
1518		*t = local_zone_deny;
1519	else if(strcmp(type, "refuse") == 0)
1520		*t = local_zone_refuse;
1521	else if(strcmp(type, "static") == 0)
1522		*t = local_zone_static;
1523	else if(strcmp(type, "transparent") == 0)
1524		*t = local_zone_transparent;
1525	else if(strcmp(type, "typetransparent") == 0)
1526		*t = local_zone_typetransparent;
1527	else if(strcmp(type, "redirect") == 0)
1528		*t = local_zone_redirect;
1529	else if(strcmp(type, "inform") == 0)
1530		*t = local_zone_inform;
1531	else if(strcmp(type, "inform_deny") == 0)
1532		*t = local_zone_inform_deny;
1533	else if(strcmp(type, "always_transparent") == 0)
1534		*t = local_zone_always_transparent;
1535	else if(strcmp(type, "always_refuse") == 0)
1536		*t = local_zone_always_refuse;
1537	else if(strcmp(type, "always_nxdomain") == 0)
1538		*t = local_zone_always_nxdomain;
1539	else return 0;
1540	return 1;
1541}
1542
1543/** iterate over the kiddies of the given name and set their parent ptr */
1544static void
1545set_kiddo_parents(struct local_zone* z, struct local_zone* match,
1546	struct local_zone* newp)
1547{
1548	/* both zones and z are locked already */
1549	/* in the sorted rbtree, the kiddies of z are located after z */
1550	/* z must be present in the tree */
1551	struct local_zone* p = z;
1552	p = (struct local_zone*)rbtree_next(&p->node);
1553	while(p!=(struct local_zone*)RBTREE_NULL &&
1554		p->dclass == z->dclass && dname_strict_subdomain(p->name,
1555		p->namelabs, z->name, z->namelabs)) {
1556		/* update parent ptr */
1557		/* only when matches with existing parent pointer, so that
1558		 * deeper child structures are not touched, i.e.
1559		 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y
1560		 * gets to update a.x, b.x and c.x */
1561		lock_rw_wrlock(&p->lock);
1562		if(p->parent == match)
1563			p->parent = newp;
1564		lock_rw_unlock(&p->lock);
1565		p = (struct local_zone*)rbtree_next(&p->node);
1566	}
1567}
1568
1569struct local_zone* local_zones_add_zone(struct local_zones* zones,
1570	uint8_t* name, size_t len, int labs, uint16_t dclass,
1571	enum localzone_type tp)
1572{
1573	/* create */
1574	struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
1575	if(!z) {
1576		free(name);
1577		return NULL;
1578	}
1579	lock_rw_wrlock(&z->lock);
1580
1581	/* find the closest parent */
1582	z->parent = local_zones_find(zones, name, len, labs, dclass);
1583
1584	/* insert into the tree */
1585	if(!rbtree_insert(&zones->ztree, &z->node)) {
1586		/* duplicate entry! */
1587		lock_rw_unlock(&z->lock);
1588		local_zone_delete(z);
1589		log_err("internal: duplicate entry in local_zones_add_zone");
1590		return NULL;
1591	}
1592
1593	/* set parent pointers right */
1594	set_kiddo_parents(z, z->parent, z);
1595
1596	lock_rw_unlock(&z->lock);
1597	return z;
1598}
1599
1600void local_zones_del_zone(struct local_zones* zones, struct local_zone* z)
1601{
1602	/* fix up parents in tree */
1603	lock_rw_wrlock(&z->lock);
1604	set_kiddo_parents(z, z, z->parent);
1605
1606	/* remove from tree */
1607	(void)rbtree_delete(&zones->ztree, z);
1608
1609	/* delete the zone */
1610	lock_rw_unlock(&z->lock);
1611	local_zone_delete(z);
1612}
1613
1614int
1615local_zones_add_RR(struct local_zones* zones, const char* rr)
1616{
1617	uint8_t* rr_name;
1618	uint16_t rr_class;
1619	size_t len;
1620	int labs;
1621	struct local_zone* z;
1622	int r;
1623	if(!get_rr_nameclass(rr, &rr_name, &rr_class)) {
1624		return 0;
1625	}
1626	labs = dname_count_size_labels(rr_name, &len);
1627	/* could first try readlock then get writelock if zone does not exist,
1628	 * but we do not add enough RRs (from multiple threads) to optimize */
1629	lock_rw_wrlock(&zones->lock);
1630	z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
1631	if(!z) {
1632		z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
1633			local_zone_transparent);
1634		if(!z) {
1635			lock_rw_unlock(&zones->lock);
1636			return 0;
1637		}
1638	} else {
1639		free(rr_name);
1640	}
1641	lock_rw_wrlock(&z->lock);
1642	lock_rw_unlock(&zones->lock);
1643	r = lz_enter_rr_into_zone(z, rr);
1644	lock_rw_unlock(&z->lock);
1645	return r;
1646}
1647
1648/** returns true if the node is terminal so no deeper domain names exist */
1649static int
1650is_terminal(struct local_data* d)
1651{
1652	/* for empty nonterminals, the deeper domain names are sorted
1653	 * right after them, so simply check the next name in the tree
1654	 */
1655	struct local_data* n = (struct local_data*)rbtree_next(&d->node);
1656	if(n == (struct local_data*)RBTREE_NULL)
1657		return 1; /* last in tree, no deeper node */
1658	if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs))
1659		return 0; /* there is a deeper node */
1660	return 1;
1661}
1662
1663/** delete empty terminals from tree when final data is deleted */
1664static void
1665del_empty_term(struct local_zone* z, struct local_data* d,
1666	uint8_t* name, size_t len, int labs)
1667{
1668	while(d && d->rrsets == NULL && is_terminal(d)) {
1669		/* is this empty nonterminal? delete */
1670		/* note, no memory recycling in zone region */
1671		(void)rbtree_delete(&z->data, d);
1672
1673		/* go up and to the next label */
1674		if(dname_is_root(name))
1675			return;
1676		dname_remove_label(&name, &len);
1677		labs--;
1678		d = lz_find_node(z, name, len, labs);
1679	}
1680}
1681
1682void local_zones_del_data(struct local_zones* zones,
1683	uint8_t* name, size_t len, int labs, uint16_t dclass)
1684{
1685	/* find zone */
1686	struct local_zone* z;
1687	struct local_data* d;
1688	lock_rw_rdlock(&zones->lock);
1689	z = local_zones_lookup(zones, name, len, labs, dclass);
1690	if(!z) {
1691		/* no such zone, we're done */
1692		lock_rw_unlock(&zones->lock);
1693		return;
1694	}
1695	lock_rw_wrlock(&z->lock);
1696	lock_rw_unlock(&zones->lock);
1697
1698	/* find the domain */
1699	d = lz_find_node(z, name, len, labs);
1700	if(d) {
1701		/* no memory recycling for zone deletions ... */
1702		d->rrsets = NULL;
1703		/* did we delete the soa record ? */
1704		if(query_dname_compare(d->name, z->name) == 0)
1705			z->soa = NULL;
1706
1707		/* cleanup the empty nonterminals for this name */
1708		del_empty_term(z, d, name, len, labs);
1709	}
1710
1711	lock_rw_unlock(&z->lock);
1712}
1713