xref: /openbsd-src/usr.sbin/nsd/options.c (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 /*
2  * options.c -- options functions.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 #include "config.h"
10 #include <string.h>
11 #include <stdio.h>
12 #include <sys/stat.h>
13 #include <errno.h>
14 #ifdef HAVE_IFADDRS_H
15 #include <ifaddrs.h>
16 #endif
17 #include "options.h"
18 #include "query.h"
19 #include "tsig.h"
20 #include "difffile.h"
21 #include "rrl.h"
22 #include "bitset.h"
23 
24 #include "configparser.h"
25 config_parser_state_type* cfg_parser = 0;
26 extern FILE* c_in, *c_out;
27 int c_parse(void);
28 int c_lex(void);
29 int c_wrap(void);
30 int c_lex_destroy(void);
31 extern char* c_text;
32 
33 static int
34 rbtree_strcmp(const void* p1, const void* p2)
35 {
36 	if(p1 == NULL && p2 == NULL) return 0;
37 	if(p1 == NULL) return -1;
38 	if(p2 == NULL) return 1;
39 	return strcmp((const char*)p1, (const char*)p2);
40 }
41 
42 struct nsd_options*
43 nsd_options_create(region_type* region)
44 {
45 	struct nsd_options* opt;
46 	opt = (struct nsd_options*)region_alloc(region, sizeof(
47 		struct nsd_options));
48 	opt->region = region;
49 	opt->zone_options = rbtree_create(region,
50 		(int (*)(const void *, const void *)) dname_compare);
51 	opt->configfile = NULL;
52 	opt->zonestatnames = rbtree_create(opt->region, rbtree_strcmp);
53 	opt->patterns = rbtree_create(region, rbtree_strcmp);
54 	opt->keys = rbtree_create(region, rbtree_strcmp);
55 	opt->ip_addresses = NULL;
56 	opt->ip_transparent = 0;
57 	opt->ip_freebind = 0;
58 	opt->send_buffer_size = 0;
59 	opt->receive_buffer_size = 0;
60 	opt->debug_mode = 0;
61 	opt->verbosity = 0;
62 	opt->hide_version = 0;
63 	opt->hide_identity = 0;
64 	opt->drop_updates = 0;
65 	opt->do_ip4 = 1;
66 	opt->do_ip6 = 1;
67 	opt->database = DBFILE;
68 	opt->identity = 0;
69 	opt->version = 0;
70 	opt->nsid = 0;
71 	opt->logfile = 0;
72 	opt->log_only_syslog = 0;
73 	opt->log_time_ascii = 1;
74 	opt->round_robin = 0; /* also packet.h::round_robin */
75 	opt->minimal_responses = 1; /* also packet.h::minimal_responses */
76 	opt->confine_to_zone = 0;
77 	opt->refuse_any = 1;
78 	opt->server_count = 1;
79 	opt->cpu_affinity = NULL;
80 	opt->service_cpu_affinity = NULL;
81 	opt->tcp_count = 100;
82 	opt->tcp_reject_overflow = 0;
83 	opt->tcp_query_count = 0;
84 	opt->tcp_timeout = TCP_TIMEOUT;
85 	opt->tcp_mss = 0;
86 	opt->outgoing_tcp_mss = 0;
87 	opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN;
88 	opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN;
89 	opt->pidfile = PIDFILE;
90 	opt->port = UDP_PORT;
91 /* deprecated?	opt->port = TCP_PORT; */
92 	opt->reuseport = 0;
93 	opt->statistics = 0;
94 	opt->chroot = 0;
95 	opt->username = USER;
96 	opt->zonesdir = ZONESDIR;
97 	opt->xfrdfile = XFRDFILE;
98 	opt->xfrdir = XFRDIR;
99 	opt->zonelistfile = ZONELISTFILE;
100 #ifdef RATELIMIT
101 	opt->rrl_size = RRL_BUCKETS;
102 	opt->rrl_slip = RRL_SLIP;
103 	opt->rrl_ipv4_prefix_length = RRL_IPV4_PREFIX_LENGTH;
104 	opt->rrl_ipv6_prefix_length = RRL_IPV6_PREFIX_LENGTH;
105 #  ifdef RATELIMIT_DEFAULT_OFF
106 	opt->rrl_ratelimit = 0;
107 	opt->rrl_whitelist_ratelimit = 0;
108 #  else
109 	opt->rrl_ratelimit = RRL_LIMIT/2;
110 	opt->rrl_whitelist_ratelimit = RRL_WLIST_LIMIT/2;
111 #  endif
112 #endif
113 #ifdef USE_DNSTAP
114 	opt->dnstap_enable = 0;
115 	opt->dnstap_socket_path = DNSTAP_SOCKET_PATH;
116 	opt->dnstap_send_identity = 0;
117 	opt->dnstap_send_version = 0;
118 	opt->dnstap_identity = NULL;
119 	opt->dnstap_version = NULL;
120 	opt->dnstap_log_auth_query_messages = 0;
121 	opt->dnstap_log_auth_response_messages = 0;
122 #endif
123 	opt->zonefiles_check = 1;
124 	if(opt->database == NULL || opt->database[0] == 0)
125 		opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL;
126 	else	opt->zonefiles_write = 0;
127 	opt->xfrd_reload_timeout = 1;
128 	opt->tls_service_key = NULL;
129 	opt->tls_service_ocsp = NULL;
130 	opt->tls_service_pem = NULL;
131 	opt->tls_port = TLS_PORT;
132 	opt->control_enable = 0;
133 	opt->control_interface = NULL;
134 	opt->control_port = NSD_CONTROL_PORT;
135 	opt->server_key_file = CONFIGDIR"/nsd_server.key";
136 	opt->server_cert_file = CONFIGDIR"/nsd_server.pem";
137 	opt->control_key_file = CONFIGDIR"/nsd_control.key";
138 	opt->control_cert_file = CONFIGDIR"/nsd_control.pem";
139 	return opt;
140 }
141 
142 int
143 nsd_options_insert_zone(struct nsd_options* opt, struct zone_options* zone)
144 {
145 	/* create dname for lookup */
146 	const dname_type* dname = dname_parse(opt->region, zone->name);
147 	if(!dname)
148 		return 0;
149 	zone->node.key = dname;
150 	if(!rbtree_insert(opt->zone_options, (rbnode_type*)zone))
151 		return 0;
152 	return 1;
153 }
154 
155 int
156 nsd_options_insert_pattern(struct nsd_options* opt,
157 	struct pattern_options* pat)
158 {
159 	if(!pat->pname)
160 		return 0;
161 	pat->node.key = pat->pname;
162 	if(!rbtree_insert(opt->patterns, (rbnode_type*)pat))
163 		return 0;
164 	return 1;
165 }
166 
167 void
168 warn_if_directory(const char* filetype, FILE* f, const char* fname)
169 {
170 	if(fileno(f) != -1) {
171 		struct stat st;
172 		memset(&st, 0, sizeof(st));
173 		if(fstat(fileno(f), &st) != -1) {
174 			if(S_ISDIR(st.st_mode)) {
175 				log_msg(LOG_WARNING, "trying to read %s but it is a directory: %s", filetype, fname);
176 			}
177 		}
178 	}
179 }
180 
181 int
182 parse_options_file(struct nsd_options* opt, const char* file,
183 	void (*err)(void*,const char*), void* err_arg)
184 {
185 	FILE *in = 0;
186 	struct pattern_options* pat;
187 	struct acl_options* acl;
188 
189 	if(!cfg_parser) {
190 		cfg_parser = (config_parser_state_type*)region_alloc(
191 			opt->region, sizeof(config_parser_state_type));
192 		cfg_parser->chroot = 0;
193 	}
194 	cfg_parser->err = err;
195 	cfg_parser->err_arg = err_arg;
196 	cfg_parser->filename = (char*)file;
197 	cfg_parser->line = 1;
198 	cfg_parser->errors = 0;
199 	cfg_parser->opt = opt;
200 	cfg_parser->pattern = NULL;
201 	cfg_parser->zone = NULL;
202 	cfg_parser->key = NULL;
203 
204 	in = fopen(cfg_parser->filename, "r");
205 	if(!in) {
206 		if(err) {
207 			char m[MAXSYSLOGMSGLEN];
208 			snprintf(m, sizeof(m), "Could not open %s: %s\n",
209 				file, strerror(errno));
210 			err(err_arg, m);
211 		} else {
212 			fprintf(stderr, "Could not open %s: %s\n",
213 				file, strerror(errno));
214 		}
215 		return 0;
216 	}
217 	warn_if_directory("configfile", in, file);
218 	c_in = in;
219 	c_parse();
220 	fclose(in);
221 
222 	opt->configfile = region_strdup(opt->region, file);
223 
224 	RBTREE_FOR(pat, struct pattern_options*, opt->patterns)
225 	{
226 		/* lookup keys for acls */
227 		for(acl=pat->allow_notify; acl; acl=acl->next)
228 		{
229 			if(acl->nokey || acl->blocked)
230 				continue;
231 			acl->key_options = key_options_find(opt, acl->key_name);
232 			if(!acl->key_options)
233 				c_error("key %s in pattern %s could not be found",
234 					acl->key_name, pat->pname);
235 		}
236 		for(acl=pat->notify; acl; acl=acl->next)
237 		{
238 			if(acl->nokey || acl->blocked)
239 				continue;
240 			acl->key_options = key_options_find(opt, acl->key_name);
241 			if(!acl->key_options)
242 				c_error("key %s in pattern %s could not be found",
243 					acl->key_name, pat->pname);
244 		}
245 		for(acl=pat->request_xfr; acl; acl=acl->next)
246 		{
247 			if(acl->nokey || acl->blocked)
248 				continue;
249 			acl->key_options = key_options_find(opt, acl->key_name);
250 			if(!acl->key_options)
251 				c_error("key %s in pattern %s could not be found",
252 					acl->key_name, pat->pname);
253 		}
254 		for(acl=pat->provide_xfr; acl; acl=acl->next)
255 		{
256 			if(acl->nokey || acl->blocked)
257 				continue;
258 			acl->key_options = key_options_find(opt, acl->key_name);
259 			if(!acl->key_options)
260 				c_error("key %s in pattern %s could not be found",
261 					acl->key_name, pat->pname);
262 		}
263 		for(acl=pat->allow_query; acl; acl=acl->next)
264 		{
265 			if(acl->nokey || acl->blocked)
266 				continue;
267 			acl->key_options = key_options_find(opt, acl->key_name);
268 			if(!acl->key_options)
269 				c_error("key %s in pattern %s could not be found",
270 					acl->key_name, pat->pname);
271 		}
272 	}
273 
274 	if(cfg_parser->errors > 0)
275 	{
276 		if(err) {
277 			char m[MAXSYSLOGMSGLEN];
278 			snprintf(m, sizeof(m), "read %s failed: %d errors in "
279 				"configuration file\n", file,
280 				cfg_parser->errors);
281 			err(err_arg, m);
282 		} else {
283 			fprintf(stderr, "read %s failed: %d errors in "
284 				"configuration file\n", file,
285 				cfg_parser->errors);
286 		}
287 		return 0;
288 	}
289 	return 1;
290 }
291 
292 void options_zonestatnames_create(struct nsd_options* opt)
293 {
294 	struct zone_options* zopt;
295 	/* allocate "" as zonestat 0, for zones without a zonestat */
296 	if(!rbtree_search(opt->zonestatnames, "")) {
297 		struct zonestatname* n;
298 		n = (struct zonestatname*)region_alloc_zero(opt->region,
299 			sizeof(*n));
300 		n->node.key = region_strdup(opt->region, "");
301 		if(!n->node.key) {
302 			log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
303 			exit(1);
304 		}
305 		n->id = (unsigned)(opt->zonestatnames->count);
306 		rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
307 	}
308 	RBTREE_FOR(zopt, struct zone_options*, opt->zone_options) {
309 		/* insert into tree, so that when read in later id exists */
310 		(void)getzonestatid(opt, zopt);
311 	}
312 }
313 
314 #define ZONELIST_HEADER "# NSD zone list\n# name pattern\n"
315 static int
316 comp_zonebucket(const void* a, const void* b)
317 {
318 	/* the line size is much smaller than max-int, and positive,
319 	 * so the subtraction works */
320 	return *(const int*)b - *(const int*)a;
321 }
322 
323 /* insert free entry into zonelist free buckets */
324 static void
325 zone_list_free_insert(struct nsd_options* opt, int linesize, off_t off)
326 {
327 	struct zonelist_free* e;
328 	struct zonelist_bucket* b = (struct zonelist_bucket*)rbtree_search(
329 		opt->zonefree, &linesize);
330 	if(!b) {
331 		b = region_alloc_zero(opt->region, sizeof(*b));
332 		b->linesize = linesize;
333 		b->node = *RBTREE_NULL;
334 		b->node.key = &b->linesize;
335 		rbtree_insert(opt->zonefree, &b->node);
336 	}
337 	e = (struct zonelist_free*)region_alloc_zero(opt->region, sizeof(*e));
338 	e->next = b->list;
339 	b->list = e;
340 	e->off = off;
341 	opt->zonefree_number++;
342 }
343 
344 struct zone_options*
345 zone_list_zone_insert(struct nsd_options* opt, const char* nm,
346 	const char* patnm, int linesize, off_t off)
347 {
348 	struct pattern_options* pat = pattern_options_find(opt, patnm);
349 	struct zone_options* zone;
350 	if(!pat) {
351 		log_msg(LOG_ERR, "pattern does not exist for zone %s "
352 			"pattern %s", nm, patnm);
353 		return NULL;
354 	}
355 	zone = zone_options_create(opt->region);
356 	zone->part_of_config = 0;
357 	zone->name = region_strdup(opt->region, nm);
358 	zone->linesize = linesize;
359 	zone->off = off;
360 	zone->pattern = pat;
361 	if(!nsd_options_insert_zone(opt, zone)) {
362 		log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' "
363 			"pattern %s", nm, patnm);
364 		region_recycle(opt->region, (void*)zone->name, strlen(nm)+1);
365 		region_recycle(opt->region, zone, sizeof(*zone));
366 		return NULL;
367 	}
368 	return zone;
369 }
370 
371 int
372 parse_zone_list_file(struct nsd_options* opt)
373 {
374 	/* zonelist looks like this:
375 	# name pattern
376 	add example.com master
377 	del example.net slave
378 	add foo.bar.nl slave
379 	add rutabaga.uk config
380 	*/
381 	char hdr[64];
382 	char buf[1024];
383 
384 	/* create empty data structures */
385 	opt->zonefree = rbtree_create(opt->region, comp_zonebucket);
386 	opt->zonelist = NULL;
387 	opt->zonefree_number = 0;
388 	opt->zonelist_off = 0;
389 
390 	/* try to open the zonelist file, an empty or nonexist file is OK */
391 	opt->zonelist = fopen(opt->zonelistfile, "r+");
392 	if(!opt->zonelist) {
393 		if(errno == ENOENT)
394 			return 1; /* file does not exist, it is created later */
395 		log_msg(LOG_ERR, "could not open zone list %s: %s", opt->zonelistfile,
396 			strerror(errno));
397 		return 0;
398 	}
399 	/* read header */
400 	hdr[strlen(ZONELIST_HEADER)] = 0;
401 	if(fread(hdr, 1, strlen(ZONELIST_HEADER), opt->zonelist) !=
402 		strlen(ZONELIST_HEADER) || strncmp(hdr, ZONELIST_HEADER,
403 		strlen(ZONELIST_HEADER)) != 0) {
404 		log_msg(LOG_ERR, "zone list %s contains bad header\n", opt->zonelistfile);
405 		fclose(opt->zonelist);
406 		opt->zonelist = NULL;
407 		return 0;
408 	}
409 	buf[sizeof(buf)-1]=0;
410 
411 	/* read entries in file */
412 	while(fgets(buf, sizeof(buf), opt->zonelist)) {
413 		/* skip comments and empty lines */
414 		if(buf[0] == 0 || buf[0] == '\n' || buf[0] == '#')
415 			continue;
416 		if(strncmp(buf, "add ", 4) == 0) {
417 			int linesize = strlen(buf);
418 			/* parse the 'add' line */
419 			/* pick last space on the line, so that the domain
420 			 * name can have a space in it (but not the pattern)*/
421 			char* space = strrchr(buf+4, ' ');
422 			char* nm, *patnm;
423 			if(!space) {
424 				/* parse error */
425 				log_msg(LOG_ERR, "parse error in %s: '%s'",
426 					opt->zonelistfile, buf);
427 				continue;
428 			}
429 			nm = buf+4;
430 			*space = 0;
431 			patnm = space+1;
432 			if(linesize && buf[linesize-1] == '\n')
433 				buf[linesize-1] = 0;
434 
435 			/* store offset and line size for zone entry */
436 			/* and create zone entry in zonetree */
437 			(void)zone_list_zone_insert(opt, nm, patnm, linesize,
438 				ftello(opt->zonelist)-linesize);
439 		} else if(strncmp(buf, "del ", 4) == 0) {
440 			/* store offset and line size for deleted entry */
441 			int linesize = strlen(buf);
442 			zone_list_free_insert(opt, linesize,
443 				ftello(opt->zonelist)-linesize);
444 		} else {
445 			log_msg(LOG_WARNING, "bad data in %s, '%s'", opt->zonelistfile,
446 				buf);
447 		}
448 	}
449 	/* store EOF offset */
450 	opt->zonelist_off = ftello(opt->zonelist);
451 	return 1;
452 }
453 
454 void
455 zone_options_delete(struct nsd_options* opt, struct zone_options* zone)
456 {
457 	rbtree_delete(opt->zone_options, zone->node.key);
458 	region_recycle(opt->region, (void*)zone->node.key, dname_total_size(
459 		(dname_type*)zone->node.key));
460 	region_recycle(opt->region, zone, sizeof(*zone));
461 }
462 
463 /* add a new zone to the zonelist */
464 struct zone_options*
465 zone_list_add(struct nsd_options* opt, const char* zname, const char* pname)
466 {
467 	int r;
468 	struct zonelist_free* e;
469 	struct zonelist_bucket* b;
470 	int linesize = 6 + strlen(zname) + strlen(pname);
471 	/* create zone entry */
472 	struct zone_options* zone = zone_list_zone_insert(opt, zname, pname,
473 		linesize, 0);
474 	if(!zone)
475 		return NULL;
476 
477 	/* use free entry or append to file or create new file */
478 	if(!opt->zonelist || opt->zonelist_off == 0) {
479 		/* create new file */
480 		if(opt->zonelist) fclose(opt->zonelist);
481 		opt->zonelist = fopen(opt->zonelistfile, "w+");
482 		if(!opt->zonelist) {
483 			log_msg(LOG_ERR, "could not create zone list %s: %s",
484 				opt->zonelistfile, strerror(errno));
485 			log_msg(LOG_ERR, "zone %s could not be added", zname);
486 			zone_options_delete(opt, zone);
487 			return NULL;
488 		}
489 		r = fprintf(opt->zonelist, ZONELIST_HEADER);
490 		if(r != strlen(ZONELIST_HEADER)) {
491 			if(r == -1)
492 				log_msg(LOG_ERR, "could not write to %s: %s",
493 					opt->zonelistfile, strerror(errno));
494 			else log_msg(LOG_ERR, "partial write to %s: disk full",
495 				opt->zonelistfile);
496 			log_msg(LOG_ERR, "zone %s could not be added", zname);
497 			zone_options_delete(opt, zone);
498 			return NULL;
499 		}
500 		zone->off = ftello(opt->zonelist);
501 		if(zone->off == -1)
502 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
503 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
504 		if(r != zone->linesize) {
505 			if(r == -1)
506 				log_msg(LOG_ERR, "could not write to %s: %s",
507 					opt->zonelistfile, strerror(errno));
508 			else log_msg(LOG_ERR, "partial write to %s: disk full",
509 				opt->zonelistfile);
510 			log_msg(LOG_ERR, "zone %s could not be added", zname);
511 			zone_options_delete(opt, zone);
512 			return NULL;
513 		}
514 		opt->zonelist_off = ftello(opt->zonelist);
515 		if(opt->zonelist_off == -1)
516 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
517 		if(fflush(opt->zonelist) != 0) {
518 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
519 		}
520 		return zone;
521 	}
522 	b = (struct zonelist_bucket*)rbtree_search(opt->zonefree,
523 		&zone->linesize);
524 	if(!b || b->list == NULL) {
525 		/* no empty place, append to file */
526 		zone->off = opt->zonelist_off;
527 		if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
528 			log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
529 			log_msg(LOG_ERR, "zone %s could not be added", zname);
530 			zone_options_delete(opt, zone);
531 			return NULL;
532 		}
533 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
534 		if(r != zone->linesize) {
535 			if(r == -1)
536 				log_msg(LOG_ERR, "could not write to %s: %s",
537 					opt->zonelistfile, strerror(errno));
538 			else log_msg(LOG_ERR, "partial write to %s: disk full",
539 				opt->zonelistfile);
540 			log_msg(LOG_ERR, "zone %s could not be added", zname);
541 			zone_options_delete(opt, zone);
542 			return NULL;
543 		}
544 		opt->zonelist_off += linesize;
545 		if(fflush(opt->zonelist) != 0) {
546 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
547 		}
548 		return zone;
549 	}
550 	/* reuse empty spot */
551 	e = b->list;
552 	zone->off = e->off;
553 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
554 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
555 		log_msg(LOG_ERR, "zone %s could not be added", zname);
556 		zone_options_delete(opt, zone);
557 		return NULL;
558 	}
559 	r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
560 	if(r != zone->linesize) {
561 		if(r == -1)
562 			log_msg(LOG_ERR, "could not write to %s: %s",
563 				opt->zonelistfile, strerror(errno));
564 		else log_msg(LOG_ERR, "partial write to %s: disk full",
565 			opt->zonelistfile);
566 		log_msg(LOG_ERR, "zone %s could not be added", zname);
567 		zone_options_delete(opt, zone);
568 		return NULL;
569 	}
570 	if(fflush(opt->zonelist) != 0) {
571 		log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
572 	}
573 
574 	/* snip off and recycle element */
575 	b->list = e->next;
576 	region_recycle(opt->region, e, sizeof(*e));
577 	if(b->list == NULL) {
578 		rbtree_delete(opt->zonefree, &b->linesize);
579 		region_recycle(opt->region, b, sizeof(*b));
580 	}
581 	opt->zonefree_number--;
582 	return zone;
583 }
584 
585 /* remove a zone on the zonelist */
586 void
587 zone_list_del(struct nsd_options* opt, struct zone_options* zone)
588 {
589 	/* put its space onto the free entry */
590 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
591 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
592 		return;
593 	}
594 	fprintf(opt->zonelist, "del");
595 	zone_list_free_insert(opt, zone->linesize, zone->off);
596 
597 	/* remove zone_options */
598 	zone_options_delete(opt, zone);
599 
600 	/* see if we need to compact: it is going to halve the zonelist */
601 	if(opt->zonefree_number > opt->zone_options->count) {
602 		zone_list_compact(opt);
603 	} else {
604 		if(fflush(opt->zonelist) != 0) {
605 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
606 		}
607 	}
608 }
609 /* postorder delete of zonelist free space tree */
610 static void
611 delbucket(region_type* region, struct zonelist_bucket* b)
612 {
613 	struct zonelist_free* e, *f;
614 	if(!b || (rbnode_type*)b==RBTREE_NULL)
615 		return;
616 	delbucket(region, (struct zonelist_bucket*)b->node.left);
617 	delbucket(region, (struct zonelist_bucket*)b->node.right);
618 	e = b->list;
619 	while(e) {
620 		f = e->next;
621 		region_recycle(region, e, sizeof(*e));
622 		e = f;
623 	}
624 	region_recycle(region, b, sizeof(*b));
625 }
626 
627 /* compact zonelist file */
628 void
629 zone_list_compact(struct nsd_options* opt)
630 {
631 	char outname[1024];
632 	FILE* out;
633 	struct zone_options* zone;
634 	off_t off;
635 	int r;
636 	snprintf(outname, sizeof(outname), "%s~", opt->zonelistfile);
637 	/* useful, when : count-of-free > count-of-used */
638 	/* write zonelist to zonelist~ */
639 	out = fopen(outname, "w+");
640 	if(!out) {
641 		log_msg(LOG_ERR, "could not open %s: %s", outname, strerror(errno));
642 		return;
643 	}
644 	r = fprintf(out, ZONELIST_HEADER);
645 	if(r == -1) {
646 		log_msg(LOG_ERR, "write %s failed: %s", outname,
647 			strerror(errno));
648 		fclose(out);
649 		return;
650 	} else if(r != strlen(ZONELIST_HEADER)) {
651 		log_msg(LOG_ERR, "write %s was partial: disk full",
652 			outname);
653 		fclose(out);
654 		return;
655 	}
656 	off = ftello(out);
657 	if(off == -1) {
658 		log_msg(LOG_ERR, "ftello(%s): %s", outname, strerror(errno));
659 		fclose(out);
660 		return;
661 	}
662 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
663 		if(zone->part_of_config)
664 			continue;
665 		r = fprintf(out, "add %s %s\n", zone->name,
666 			zone->pattern->pname);
667 		if(r < 0) {
668 			log_msg(LOG_ERR, "write %s failed: %s", outname,
669 				strerror(errno));
670 			fclose(out);
671 			return;
672 		} else if(r != zone->linesize) {
673 			log_msg(LOG_ERR, "write %s was partial: disk full",
674 				outname);
675 			fclose(out);
676 			return;
677 		}
678 	}
679 	if(fflush(out) != 0) {
680 		log_msg(LOG_ERR, "fflush %s: %s", outname, strerror(errno));
681 	}
682 
683 	/* rename zonelist~ onto zonelist */
684 	if(rename(outname, opt->zonelistfile) == -1) {
685 		log_msg(LOG_ERR, "rename(%s to %s) failed: %s",
686 			outname, opt->zonelistfile, strerror(errno));
687 		fclose(out);
688 		return;
689 	}
690 	fclose(opt->zonelist);
691 	/* set offsets */
692 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
693 		if(zone->part_of_config)
694 			continue;
695 		zone->off = off;
696 		off += zone->linesize;
697 	}
698 	/* empty the free tree */
699 	delbucket(opt->region, (struct zonelist_bucket*)opt->zonefree->root);
700 	opt->zonefree->root = RBTREE_NULL;
701 	opt->zonefree->count = 0;
702 	opt->zonefree_number = 0;
703 	/* finish */
704 	opt->zonelist = out;
705 	opt->zonelist_off = off;
706 }
707 
708 /* close zonelist file */
709 void
710 zone_list_close(struct nsd_options* opt)
711 {
712 	if(opt->zonelist) {
713 		fclose(opt->zonelist);
714 		opt->zonelist = NULL;
715 	}
716 }
717 
718 static void
719 c_error_va_list_pos(int showpos, const char* fmt, va_list args)
720 {
721 	char* at = NULL;
722 	cfg_parser->errors++;
723 	if(showpos && c_text && c_text[0]!=0) {
724 		at = c_text;
725 	}
726 	if(cfg_parser->err) {
727 		char m[MAXSYSLOGMSGLEN];
728 		snprintf(m, sizeof(m), "%s:%d: ", cfg_parser->filename,
729 			cfg_parser->line);
730 		(*cfg_parser->err)(cfg_parser->err_arg, m);
731 		if(at) {
732 			snprintf(m, sizeof(m), "at '%s': ", at);
733 			(*cfg_parser->err)(cfg_parser->err_arg, m);
734 		}
735 		(*cfg_parser->err)(cfg_parser->err_arg, "error: ");
736 		vsnprintf(m, sizeof(m), fmt, args);
737 		(*cfg_parser->err)(cfg_parser->err_arg, m);
738 		(*cfg_parser->err)(cfg_parser->err_arg, "\n");
739 		return;
740 	}
741         fprintf(stderr, "%s:%d: ", cfg_parser->filename, cfg_parser->line);
742 	if(at) fprintf(stderr, "at '%s': ", at);
743 	fprintf(stderr, "error: ");
744 	vfprintf(stderr, fmt, args);
745 	fprintf(stderr, "\n");
746 }
747 
748 void
749 c_error(const char *fmt, ...)
750 {
751 	va_list ap;
752 	int showpos = 0;
753 
754 	if (strcmp(fmt, "syntax error") == 0 || strcmp(fmt, "parse error") == 0) {
755 		showpos = 1;
756 	}
757 
758 	va_start(ap, fmt);
759 	c_error_va_list_pos(showpos, fmt, ap);
760 	va_end(ap);
761 }
762 
763 int
764 c_wrap(void)
765 {
766 	return 1;
767 }
768 
769 struct zone_options*
770 zone_options_create(region_type* region)
771 {
772 	struct zone_options* zone;
773 	zone = (struct zone_options*)region_alloc(region, sizeof(
774 		struct zone_options));
775 	zone->node = *RBTREE_NULL;
776 	zone->name = 0;
777 	zone->pattern = 0;
778 	zone->part_of_config = 0;
779 	return zone;
780 }
781 
782 /* true is booleans are the same truth value */
783 #define booleq(x,y) ( ((x) && (y)) || (!(x) && !(y)) )
784 
785 /* true is min_expire_time_expr has either an equal known value
786  * or none of these known values but booleanally equal
787  */
788 #define expire_expr_eq(x,y) (  (  (x) == REFRESHPLUSRETRYPLUS1 \
789                                && (y) == REFRESHPLUSRETRYPLUS1 ) \
790                             || (  (x) != REFRESHPLUSRETRYPLUS1 \
791                                && (y) != REFRESHPLUSRETRYPLUS1 \
792                                && booleq((x), (y))))
793 
794 
795 int
796 acl_equal(struct acl_options* p, struct acl_options* q)
797 {
798 	if(!booleq(p->use_axfr_only, q->use_axfr_only)) return 0;
799 	if(!booleq(p->allow_udp, q->allow_udp)) return 0;
800 	if(strcmp(p->ip_address_spec, q->ip_address_spec)!=0) return 0;
801 	/* the ip6, port, addr, mask, type: are derived from the ip_address_spec */
802 	if(!booleq(p->nokey, q->nokey)) return 0;
803 	if(!booleq(p->blocked, q->blocked)) return 0;
804 	if(p->key_name && q->key_name) {
805 		if(strcmp(p->key_name, q->key_name)!=0) return 0;
806 	} else if(p->key_name && !q->key_name) return 0;
807 	else if(!p->key_name && q->key_name) return 0;
808 	/* key_options is derived from key_name */
809 	return 1;
810 }
811 
812 int
813 acl_list_equal(struct acl_options* p, struct acl_options* q)
814 {
815 	/* must be same and in same order */
816 	while(p && q) {
817 		if(!acl_equal(p, q))
818 			return 0;
819 		p = p->next;
820 		q = q->next;
821 	}
822 	if(!p && !q) return 1;
823 	/* different lengths */
824 	return 0;
825 }
826 
827 struct pattern_options*
828 pattern_options_create(region_type* region)
829 {
830 	struct pattern_options* p;
831 	p = (struct pattern_options*)region_alloc(region, sizeof(
832 		struct pattern_options));
833 	p->node = *RBTREE_NULL;
834 	p->pname = 0;
835 	p->zonefile = 0;
836 	p->zonestats = 0;
837 	p->allow_notify = 0;
838 	p->request_xfr = 0;
839 	p->size_limit_xfr = 0;
840 	p->notify = 0;
841 	p->provide_xfr = 0;
842 	p->allow_query = 0;
843 	p->outgoing_interface = 0;
844 	p->notify_retry = 5;
845 	p->notify_retry_is_default = 1;
846 	p->allow_axfr_fallback = 1;
847 	p->allow_axfr_fallback_is_default = 1;
848 	p->implicit = 0;
849 	p->xfrd_flags = 0;
850 	p->max_refresh_time = 2419200;	/* 4 weeks */
851 	p->max_refresh_time_is_default = 1;
852 	p->min_refresh_time = 0;
853 	p->min_refresh_time_is_default = 1;
854 	p->max_retry_time = 1209600;	/* 2 weeks */
855 	p->max_retry_time_is_default = 1;
856 	p->min_retry_time = 0;
857 	p->min_retry_time_is_default = 1;
858 	p->min_expire_time = 0;
859 	p->min_expire_time_expr = EXPIRE_TIME_IS_DEFAULT;
860 #ifdef RATELIMIT
861 	p->rrl_whitelist = 0;
862 #endif
863 	p->multi_master_check = 0;
864 	return p;
865 }
866 
867 static void
868 acl_delete(region_type* region, struct acl_options* acl)
869 {
870 	if(acl->ip_address_spec)
871 		region_recycle(region, (void*)acl->ip_address_spec,
872 			strlen(acl->ip_address_spec)+1);
873 	if(acl->key_name)
874 		region_recycle(region, (void*)acl->key_name,
875 			strlen(acl->key_name)+1);
876 	/* key_options is a convenience pointer, not owned by the acl */
877 	region_recycle(region, acl, sizeof(*acl));
878 }
879 
880 static void
881 acl_list_delete(region_type* region, struct acl_options* list)
882 {
883 	struct acl_options* n;
884 	while(list) {
885 		n = list->next;
886 		acl_delete(region, list);
887 		list = n;
888 	}
889 }
890 
891 void
892 pattern_options_remove(struct nsd_options* opt, const char* name)
893 {
894 	struct pattern_options* p = (struct pattern_options*)rbtree_delete(
895 		opt->patterns, name);
896 	/* delete p and its contents */
897 	if (!p)
898 		return;
899 	if(p->pname)
900 		region_recycle(opt->region, (void*)p->pname,
901 			strlen(p->pname)+1);
902 	if(p->zonefile)
903 		region_recycle(opt->region, (void*)p->zonefile,
904 			strlen(p->zonefile)+1);
905 	if(p->zonestats)
906 		region_recycle(opt->region, (void*)p->zonestats,
907 			strlen(p->zonestats)+1);
908 	acl_list_delete(opt->region, p->allow_notify);
909 	acl_list_delete(opt->region, p->request_xfr);
910 	acl_list_delete(opt->region, p->notify);
911 	acl_list_delete(opt->region, p->provide_xfr);
912 	acl_list_delete(opt->region, p->allow_query);
913 	acl_list_delete(opt->region, p->outgoing_interface);
914 
915 	region_recycle(opt->region, p, sizeof(struct pattern_options));
916 }
917 
918 static struct acl_options*
919 copy_acl(region_type* region, struct acl_options* a)
920 {
921 	struct acl_options* b;
922 	if(!a) return NULL;
923 	b = (struct acl_options*)region_alloc(region, sizeof(*b));
924 	/* copy the whole lot */
925 	*b = *a;
926 	/* fix the pointers */
927 	if(a->ip_address_spec)
928 		b->ip_address_spec = region_strdup(region, a->ip_address_spec);
929 	if(a->key_name)
930 		b->key_name = region_strdup(region, a->key_name);
931 	b->next = NULL;
932 	b->key_options = NULL;
933 	return b;
934 }
935 
936 static struct acl_options*
937 copy_acl_list(struct nsd_options* opt, struct acl_options* a)
938 {
939 	struct acl_options* b, *blast = NULL, *blist = NULL;
940 	while(a) {
941 		b = copy_acl(opt->region, a);
942 		/* fixup key_options */
943 		if(b->key_name)
944 			b->key_options = key_options_find(opt, b->key_name);
945 		else	b->key_options = NULL;
946 
947 		/* link as last into list */
948 		b->next = NULL;
949 		if(!blist) blist = b;
950 		else blast->next = b;
951 		blast = b;
952 
953 		a = a->next;
954 	}
955 	return blist;
956 }
957 
958 static void
959 copy_changed_acl(struct nsd_options* opt, struct acl_options** orig,
960 	struct acl_options* anew)
961 {
962 	if(!acl_list_equal(*orig, anew)) {
963 		acl_list_delete(opt->region, *orig);
964 		*orig = copy_acl_list(opt, anew);
965 	}
966 }
967 
968 static void
969 copy_pat_fixed(region_type* region, struct pattern_options* orig,
970 	struct pattern_options* p)
971 {
972 	orig->allow_axfr_fallback = p->allow_axfr_fallback;
973 	orig->allow_axfr_fallback_is_default =
974 		p->allow_axfr_fallback_is_default;
975 	orig->notify_retry = p->notify_retry;
976 	orig->notify_retry_is_default = p->notify_retry_is_default;
977 	orig->implicit = p->implicit;
978 	if(p->zonefile)
979 		orig->zonefile = region_strdup(region, p->zonefile);
980 	else orig->zonefile = NULL;
981 	if(p->zonestats)
982 		orig->zonestats = region_strdup(region, p->zonestats);
983 	else orig->zonestats = NULL;
984 	orig->max_refresh_time = p->max_refresh_time;
985 	orig->max_refresh_time_is_default = p->max_refresh_time_is_default;
986 	orig->min_refresh_time = p->min_refresh_time;
987 	orig->min_refresh_time_is_default = p->min_refresh_time_is_default;
988 	orig->max_retry_time = p->max_retry_time;
989 	orig->max_retry_time_is_default = p->max_retry_time_is_default;
990 	orig->min_retry_time = p->min_retry_time;
991 	orig->min_retry_time_is_default = p->min_retry_time_is_default;
992 	orig->min_expire_time = p->min_expire_time;
993 	orig->min_expire_time_expr = p->min_expire_time_expr;
994 #ifdef RATELIMIT
995 	orig->rrl_whitelist = p->rrl_whitelist;
996 #endif
997 	orig->multi_master_check = p->multi_master_check;
998 }
999 
1000 void
1001 pattern_options_add_modify(struct nsd_options* opt, struct pattern_options* p)
1002 {
1003 	struct pattern_options* orig = pattern_options_find(opt, p->pname);
1004 	if(!orig) {
1005 		/* needs to be copied to opt region */
1006 		orig = pattern_options_create(opt->region);
1007 		orig->pname = region_strdup(opt->region, p->pname);
1008 		copy_pat_fixed(opt->region, orig, p);
1009 		orig->allow_notify = copy_acl_list(opt, p->allow_notify);
1010 		orig->request_xfr = copy_acl_list(opt, p->request_xfr);
1011 		orig->notify = copy_acl_list(opt, p->notify);
1012 		orig->provide_xfr = copy_acl_list(opt, p->provide_xfr);
1013 		orig->allow_query = copy_acl_list(opt, p->allow_query);
1014 		orig->outgoing_interface = copy_acl_list(opt,
1015 			p->outgoing_interface);
1016 		nsd_options_insert_pattern(opt, orig);
1017 	} else {
1018 		/* modify in place so pointers stay valid (and copy
1019 		   into region). Do not touch unchanged acls. */
1020 		if(orig->zonefile)
1021 			region_recycle(opt->region, (char*)orig->zonefile,
1022 				strlen(orig->zonefile)+1);
1023 		if(orig->zonestats)
1024 			region_recycle(opt->region, (char*)orig->zonestats,
1025 				strlen(orig->zonestats)+1);
1026 		copy_pat_fixed(opt->region, orig, p);
1027 		copy_changed_acl(opt, &orig->allow_notify, p->allow_notify);
1028 		copy_changed_acl(opt, &orig->request_xfr, p->request_xfr);
1029 		copy_changed_acl(opt, &orig->notify, p->notify);
1030 		copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr);
1031 		copy_changed_acl(opt, &orig->allow_query, p->allow_query);
1032 		copy_changed_acl(opt, &orig->outgoing_interface,
1033 			p->outgoing_interface);
1034 	}
1035 }
1036 
1037 struct pattern_options*
1038 pattern_options_find(struct nsd_options* opt, const char* name)
1039 {
1040 	return (struct pattern_options*)rbtree_search(opt->patterns, name);
1041 }
1042 
1043 int
1044 pattern_options_equal(struct pattern_options* p, struct pattern_options* q)
1045 {
1046 	if(strcmp(p->pname, q->pname) != 0) return 0;
1047 	if(!p->zonefile && q->zonefile) return 0;
1048 	else if(p->zonefile && !q->zonefile) return 0;
1049 	else if(p->zonefile && q->zonefile) {
1050 		if(strcmp(p->zonefile, q->zonefile) != 0) return 0;
1051 	}
1052 	if(!p->zonestats && q->zonestats) return 0;
1053 	else if(p->zonestats && !q->zonestats) return 0;
1054 	else if(p->zonestats && q->zonestats) {
1055 		if(strcmp(p->zonestats, q->zonestats) != 0) return 0;
1056 	}
1057 	if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0;
1058 	if(!booleq(p->allow_axfr_fallback_is_default,
1059 		q->allow_axfr_fallback_is_default)) return 0;
1060 	if(p->notify_retry != q->notify_retry) return 0;
1061 	if(!booleq(p->notify_retry_is_default,
1062 		q->notify_retry_is_default)) return 0;
1063 	if(!booleq(p->implicit, q->implicit)) return 0;
1064 	if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0;
1065 	if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0;
1066 	if(!acl_list_equal(p->notify, q->notify)) return 0;
1067 	if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0;
1068 	if(!acl_list_equal(p->allow_query, q->allow_query)) return 0;
1069 	if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface))
1070 		return 0;
1071 	if(p->max_refresh_time != q->max_refresh_time) return 0;
1072 	if(!booleq(p->max_refresh_time_is_default,
1073 		q->max_refresh_time_is_default)) return 0;
1074 	if(p->min_refresh_time != q->min_refresh_time) return 0;
1075 	if(!booleq(p->min_refresh_time_is_default,
1076 		q->min_refresh_time_is_default)) return 0;
1077 	if(p->max_retry_time != q->max_retry_time) return 0;
1078 	if(!booleq(p->max_retry_time_is_default,
1079 		q->max_retry_time_is_default)) return 0;
1080 	if(p->min_retry_time != q->min_retry_time) return 0;
1081 	if(!booleq(p->min_retry_time_is_default,
1082 		q->min_retry_time_is_default)) return 0;
1083 	if(p->min_expire_time != q->min_expire_time) return 0;
1084 	if(!expire_expr_eq(p->min_expire_time_expr,
1085 		q->min_expire_time_expr)) return 0;
1086 #ifdef RATELIMIT
1087 	if(p->rrl_whitelist != q->rrl_whitelist) return 0;
1088 #endif
1089 	if(!booleq(p->multi_master_check,q->multi_master_check)) return 0;
1090 	if(p->size_limit_xfr != q->size_limit_xfr) return 0;
1091 	return 1;
1092 }
1093 
1094 static void
1095 marshal_u8(struct buffer* b, uint8_t v)
1096 {
1097 	buffer_reserve(b, 1);
1098 	buffer_write_u8(b, v);
1099 }
1100 
1101 static uint8_t
1102 unmarshal_u8(struct buffer* b)
1103 {
1104 	return buffer_read_u8(b);
1105 }
1106 
1107 static void
1108 marshal_u64(struct buffer* b, uint64_t v)
1109 {
1110 	buffer_reserve(b, 8);
1111 	buffer_write_u64(b, v);
1112 }
1113 
1114 static uint64_t
1115 unmarshal_u64(struct buffer* b)
1116 {
1117 	return buffer_read_u64(b);
1118 }
1119 
1120 #ifdef RATELIMIT
1121 static void
1122 marshal_u16(struct buffer* b, uint16_t v)
1123 {
1124 	buffer_reserve(b, 2);
1125 	buffer_write_u16(b, v);
1126 }
1127 #endif
1128 
1129 #ifdef RATELIMIT
1130 static uint16_t
1131 unmarshal_u16(struct buffer* b)
1132 {
1133 	return buffer_read_u16(b);
1134 }
1135 #endif
1136 
1137 static void
1138 marshal_u32(struct buffer* b, uint32_t v)
1139 {
1140 	buffer_reserve(b, 4);
1141 	buffer_write_u32(b, v);
1142 }
1143 
1144 static uint32_t
1145 unmarshal_u32(struct buffer* b)
1146 {
1147 	return buffer_read_u32(b);
1148 }
1149 
1150 static void
1151 marshal_str(struct buffer* b, const char* s)
1152 {
1153 	if(!s) marshal_u8(b, 0);
1154 	else {
1155 		size_t len = strlen(s);
1156 		marshal_u8(b, 1);
1157 		buffer_reserve(b, len+1);
1158 		buffer_write(b, s, len+1);
1159 	}
1160 }
1161 
1162 static char*
1163 unmarshal_str(region_type* r, struct buffer* b)
1164 {
1165 	uint8_t nonnull = unmarshal_u8(b);
1166 	if(nonnull) {
1167 		char* result = region_strdup(r, (char*)buffer_current(b));
1168 		size_t len = strlen((char*)buffer_current(b));
1169 		buffer_skip(b, len+1);
1170 		return result;
1171 	} else return NULL;
1172 }
1173 
1174 static void
1175 marshal_acl(struct buffer* b, struct acl_options* acl)
1176 {
1177 	buffer_reserve(b, sizeof(*acl));
1178 	buffer_write(b, acl, sizeof(*acl));
1179 	marshal_str(b, acl->ip_address_spec);
1180 	marshal_str(b, acl->key_name);
1181 }
1182 
1183 static struct acl_options*
1184 unmarshal_acl(region_type* r, struct buffer* b)
1185 {
1186 	struct acl_options* acl = (struct acl_options*)region_alloc(r,
1187 		sizeof(*acl));
1188 	buffer_read(b, acl, sizeof(*acl));
1189 	acl->next = NULL;
1190 	acl->key_options = NULL;
1191 	acl->ip_address_spec = unmarshal_str(r, b);
1192 	acl->key_name = unmarshal_str(r, b);
1193 	return acl;
1194 }
1195 
1196 static void
1197 marshal_acl_list(struct buffer* b, struct acl_options* list)
1198 {
1199 	while(list) {
1200 		marshal_u8(b, 1); /* is there a next one marker */
1201 		marshal_acl(b, list);
1202 		list = list->next;
1203 	}
1204 	marshal_u8(b, 0); /* end of list marker */
1205 }
1206 
1207 static struct acl_options*
1208 unmarshal_acl_list(region_type* r, struct buffer* b)
1209 {
1210 	struct acl_options* a, *last=NULL, *list=NULL;
1211 	while(unmarshal_u8(b)) {
1212 		a = unmarshal_acl(r, b);
1213 		/* link in */
1214 		a->next = NULL;
1215 		if(!list) list = a;
1216 		else last->next = a;
1217 		last = a;
1218 	}
1219 	return list;
1220 }
1221 
1222 void
1223 pattern_options_marshal(struct buffer* b, struct pattern_options* p)
1224 {
1225 	marshal_str(b, p->pname);
1226 	marshal_str(b, p->zonefile);
1227 	marshal_str(b, p->zonestats);
1228 #ifdef RATELIMIT
1229 	marshal_u16(b, p->rrl_whitelist);
1230 #endif
1231 	marshal_u8(b, p->allow_axfr_fallback);
1232 	marshal_u8(b, p->allow_axfr_fallback_is_default);
1233 	marshal_u8(b, p->notify_retry);
1234 	marshal_u8(b, p->notify_retry_is_default);
1235 	marshal_u8(b, p->implicit);
1236 	marshal_u64(b, p->size_limit_xfr);
1237 	marshal_acl_list(b, p->allow_notify);
1238 	marshal_acl_list(b, p->request_xfr);
1239 	marshal_acl_list(b, p->notify);
1240 	marshal_acl_list(b, p->provide_xfr);
1241 	marshal_acl_list(b, p->allow_query);
1242 	marshal_acl_list(b, p->outgoing_interface);
1243 	marshal_u32(b, p->max_refresh_time);
1244 	marshal_u8(b, p->max_refresh_time_is_default);
1245 	marshal_u32(b, p->min_refresh_time);
1246 	marshal_u8(b, p->min_refresh_time_is_default);
1247 	marshal_u32(b, p->max_retry_time);
1248 	marshal_u8(b, p->max_retry_time_is_default);
1249 	marshal_u32(b, p->min_retry_time);
1250 	marshal_u8(b, p->min_retry_time_is_default);
1251 	marshal_u32(b, p->min_expire_time);
1252 	marshal_u8(b, p->min_expire_time_expr);
1253 	marshal_u8(b, p->multi_master_check);
1254 }
1255 
1256 struct pattern_options*
1257 pattern_options_unmarshal(region_type* r, struct buffer* b)
1258 {
1259 	struct pattern_options* p = pattern_options_create(r);
1260 	p->pname = unmarshal_str(r, b);
1261 	p->zonefile = unmarshal_str(r, b);
1262 	p->zonestats = unmarshal_str(r, b);
1263 #ifdef RATELIMIT
1264 	p->rrl_whitelist = unmarshal_u16(b);
1265 #endif
1266 	p->allow_axfr_fallback = unmarshal_u8(b);
1267 	p->allow_axfr_fallback_is_default = unmarshal_u8(b);
1268 	p->notify_retry = unmarshal_u8(b);
1269 	p->notify_retry_is_default = unmarshal_u8(b);
1270 	p->implicit = unmarshal_u8(b);
1271 	p->size_limit_xfr = unmarshal_u64(b);
1272 	p->allow_notify = unmarshal_acl_list(r, b);
1273 	p->request_xfr = unmarshal_acl_list(r, b);
1274 	p->notify = unmarshal_acl_list(r, b);
1275 	p->provide_xfr = unmarshal_acl_list(r, b);
1276 	p->allow_query = unmarshal_acl_list(r, b);
1277 	p->outgoing_interface = unmarshal_acl_list(r, b);
1278 	p->max_refresh_time = unmarshal_u32(b);
1279 	p->max_refresh_time_is_default = unmarshal_u8(b);
1280 	p->min_refresh_time = unmarshal_u32(b);
1281 	p->min_refresh_time_is_default = unmarshal_u8(b);
1282 	p->max_retry_time = unmarshal_u32(b);
1283 	p->max_retry_time_is_default = unmarshal_u8(b);
1284 	p->min_retry_time = unmarshal_u32(b);
1285 	p->min_retry_time_is_default = unmarshal_u8(b);
1286 	p->min_expire_time = unmarshal_u32(b);
1287 	p->min_expire_time_expr = unmarshal_u8(b);
1288 	p->multi_master_check = unmarshal_u8(b);
1289 	return p;
1290 }
1291 
1292 struct key_options*
1293 key_options_create(region_type* region)
1294 {
1295 	struct key_options* key;
1296 	key = (struct key_options*)region_alloc_zero(region,
1297 		sizeof(struct key_options));
1298 	return key;
1299 }
1300 
1301 void
1302 key_options_insert(struct nsd_options* opt, struct key_options* key)
1303 {
1304 	if(!key->name) return;
1305 	key->node.key = key->name;
1306 	(void)rbtree_insert(opt->keys, &key->node);
1307 }
1308 
1309 struct key_options*
1310 key_options_find(struct nsd_options* opt, const char* name)
1311 {
1312 	return (struct key_options*)rbtree_search(opt->keys, name);
1313 }
1314 
1315 /** remove tsig_key contents */
1316 void
1317 key_options_desetup(region_type* region, struct key_options* key)
1318 {
1319 	/* keep tsig_key pointer so that existing references keep valid */
1320 	if(!key->tsig_key)
1321 		return;
1322 	/* name stays the same */
1323 	if(key->tsig_key->data) {
1324 		/* wipe secret! */
1325 		memset(key->tsig_key->data, 0xdd, key->tsig_key->size);
1326 		region_recycle(region, key->tsig_key->data,
1327 			key->tsig_key->size);
1328 		key->tsig_key->data = NULL;
1329 		key->tsig_key->size = 0;
1330 	}
1331 }
1332 
1333 /** add tsig_key contents */
1334 void
1335 key_options_setup(region_type* region, struct key_options* key)
1336 {
1337 	uint8_t data[16384]; /* 16KB */
1338 	int size;
1339 	if(!key->tsig_key) {
1340 		/* create it */
1341 		key->tsig_key = (tsig_key_type *) region_alloc(region,
1342 			sizeof(tsig_key_type));
1343 		/* create name */
1344 		key->tsig_key->name = dname_parse(region, key->name);
1345 		if(!key->tsig_key->name) {
1346 			log_msg(LOG_ERR, "Failed to parse tsig key name %s",
1347 				key->name);
1348 			/* key and base64 were checked during syntax parse */
1349 			exit(1);
1350 		}
1351 		key->tsig_key->size = 0;
1352 		key->tsig_key->data = NULL;
1353 	}
1354 	size = __b64_pton(key->secret, data, sizeof(data));
1355 	if(size == -1) {
1356 		log_msg(LOG_ERR, "Failed to parse tsig key data %s",
1357 			key->name);
1358 		/* key and base64 were checked during syntax parse */
1359 		exit(1);
1360 	}
1361 	key->tsig_key->size = size;
1362 	key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size);
1363 }
1364 
1365 void
1366 key_options_remove(struct nsd_options* opt, const char* name)
1367 {
1368 	struct key_options* k = key_options_find(opt, name);
1369 	if(!k) return;
1370 	(void)rbtree_delete(opt->keys, name);
1371 	if(k->name)
1372 		region_recycle(opt->region, k->name, strlen(k->name)+1);
1373 	if(k->algorithm)
1374 		region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1);
1375 	if(k->secret) {
1376 		memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */
1377 		region_recycle(opt->region, k->secret, strlen(k->secret)+1);
1378 	}
1379 	if(k->tsig_key) {
1380 		tsig_del_key(k->tsig_key);
1381 		if(k->tsig_key->name)
1382 			region_recycle(opt->region, (void*)k->tsig_key->name,
1383 				dname_total_size(k->tsig_key->name));
1384 		key_options_desetup(opt->region, k);
1385 		region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type));
1386 	}
1387 	region_recycle(opt->region, k, sizeof(struct key_options));
1388 }
1389 
1390 int
1391 key_options_equal(struct key_options* p, struct key_options* q)
1392 {
1393 	return strcmp(p->name, q->name)==0 && strcmp(p->algorithm,
1394 		q->algorithm)==0 && strcmp(p->secret, q->secret)==0;
1395 }
1396 
1397 void
1398 key_options_add_modify(struct nsd_options* opt, struct key_options* key)
1399 {
1400 	struct key_options* orig = key_options_find(opt, key->name);
1401 	if(!orig) {
1402 		/* needs to be copied to opt region */
1403 		orig = key_options_create(opt->region);
1404 		orig->name = region_strdup(opt->region, key->name);
1405 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1406 		orig->secret = region_strdup(opt->region, key->secret);
1407 		key_options_setup(opt->region, orig);
1408 		tsig_add_key(orig->tsig_key);
1409 		key_options_insert(opt, orig);
1410 	} else {
1411 		/* modify entries in existing key, and copy to opt region */
1412 		key_options_desetup(opt->region, orig);
1413 		region_recycle(opt->region, orig->algorithm,
1414 			strlen(orig->algorithm)+1);
1415 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1416 		region_recycle(opt->region, orig->secret,
1417 			strlen(orig->secret)+1);
1418 		orig->secret = region_strdup(opt->region, key->secret);
1419 		key_options_setup(opt->region, orig);
1420 	}
1421 }
1422 
1423 int
1424 acl_check_incoming(struct acl_options* acl, struct query* q,
1425 	struct acl_options** reason)
1426 {
1427 	/* check each acl element.
1428 	   if 1 blocked element matches - return -1.
1429 	   if any element matches - return number.
1430 	   else return -1. */
1431 	int found_match = -1;
1432 	int number = 0;
1433 	struct acl_options* match = 0;
1434 
1435 	if(reason)
1436 		*reason = NULL;
1437 
1438 	while(acl)
1439 	{
1440 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s",
1441 			acl->ip_address_spec, acl->nokey?"NOKEY":
1442 			(acl->blocked?"BLOCKED":acl->key_name)));
1443 		if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) {
1444 			if(!match)
1445 			{
1446 				match = acl; /* remember first match */
1447 				found_match=number;
1448 			}
1449 			if(acl->blocked) {
1450 				if(reason)
1451 					*reason = acl;
1452 				return -1;
1453 			}
1454 		}
1455 		number++;
1456 		acl = acl->next;
1457 	}
1458 
1459 	if(reason)
1460 		*reason = match;
1461 	return found_match;
1462 }
1463 
1464 #ifdef INET6
1465 int
1466 acl_addr_matches_ipv6host(struct acl_options* acl, struct sockaddr_storage* addr_storage, unsigned int port)
1467 {
1468 	struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage;
1469 	if(acl->port != 0 && acl->port != port)
1470 		return 0;
1471 	switch(acl->rangetype) {
1472 	case acl_range_mask:
1473 	case acl_range_subnet:
1474 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1475 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1476 			return 0;
1477 		break;
1478 	case acl_range_minmax:
1479 		if(!acl_addr_match_range_v6((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1480 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1481 			return 0;
1482 		break;
1483 	case acl_range_single:
1484 	default:
1485 		if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
1486 			sizeof(struct in6_addr)) != 0)
1487 			return 0;
1488 		break;
1489 	}
1490 	return 1;
1491 }
1492 #endif
1493 
1494 int
1495 acl_addr_matches_ipv4host(struct acl_options* acl, struct sockaddr_in* addr, unsigned int port)
1496 {
1497 	if(acl->port != 0 && acl->port != port)
1498 		return 0;
1499 	switch(acl->rangetype) {
1500 	case acl_range_mask:
1501 	case acl_range_subnet:
1502 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1503 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1504 			return 0;
1505 		break;
1506 	case acl_range_minmax:
1507 		if(!acl_addr_match_range_v4((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1508 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1509 			return 0;
1510 		break;
1511 	case acl_range_single:
1512 	default:
1513 		if(memcmp(&addr->sin_addr, &acl->addr.addr,
1514 			sizeof(struct in_addr)) != 0)
1515 			return 0;
1516 		break;
1517 	}
1518 	return 1;
1519 }
1520 
1521 int
1522 acl_addr_matches_host(struct acl_options* acl, struct acl_options* host)
1523 {
1524 	if(acl->is_ipv6)
1525 	{
1526 #ifdef INET6
1527 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr;
1528 		if(!host->is_ipv6) return 0;
1529 		return acl_addr_matches_ipv6host(acl, addr, host->port);
1530 #else
1531 		return 0; /* no inet6, no match */
1532 #endif
1533 	}
1534 	else
1535 	{
1536 		struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr;
1537 		if(host->is_ipv6) return 0;
1538 		return acl_addr_matches_ipv4host(acl, addr, host->port);
1539 	}
1540 	/* ENOTREACH */
1541 	return 0;
1542 }
1543 
1544 int
1545 acl_addr_matches(struct acl_options* acl, struct query* q)
1546 {
1547 	if(acl->is_ipv6)
1548 	{
1549 #ifdef INET6
1550 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr;
1551 		if(addr->ss_family != AF_INET6)
1552 			return 0;
1553 		return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port));
1554 #else
1555 		return 0; /* no inet6, no match */
1556 #endif
1557 	}
1558 	else
1559 	{
1560 		struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr;
1561 		if(addr->sin_family != AF_INET)
1562 			return 0;
1563 		return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port));
1564 	}
1565 	/* ENOTREACH */
1566 	return 0;
1567 }
1568 
1569 int
1570 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz)
1571 {
1572 	size_t i;
1573 #ifndef NDEBUG
1574 	assert(sz % 4 == 0);
1575 #endif
1576 	sz /= 4;
1577 	for(i=0; i<sz; ++i)
1578 	{
1579 		if(((*a++)&*mask) != ((*b++)&*mask))
1580 			return 0;
1581 		++mask;
1582 	}
1583 	return 1;
1584 }
1585 
1586 int
1587 acl_addr_match_range_v4(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
1588 {
1589 	assert(sz == 4); (void)sz;
1590 	/* check treats x as one huge number */
1591 
1592 	/* if outside bounds, we are done */
1593 	if(*minval > *x)
1594 		return 0;
1595 	if(*maxval < *x)
1596 		return 0;
1597 
1598 	return 1;
1599 }
1600 
1601 #ifdef INET6
1602 int
1603 acl_addr_match_range_v6(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
1604 {
1605 	size_t i;
1606 	uint8_t checkmin = 1, checkmax = 1;
1607 #ifndef NDEBUG
1608 	assert(sz % 4 == 0);
1609 #endif
1610 	/* check treats x as one huge number */
1611 	sz /= 4;
1612 	for(i=0; i<sz; ++i)
1613 	{
1614 		/* if outside bounds, we are done */
1615 		if(checkmin)
1616 			if(minval[i] > x[i])
1617 				return 0;
1618 		if(checkmax)
1619 			if(maxval[i] < x[i])
1620 				return 0;
1621 		/* if x is equal to a bound, that bound needs further checks */
1622 		if(checkmin && minval[i]!=x[i])
1623 			checkmin = 0;
1624 		if(checkmax && maxval[i]!=x[i])
1625 			checkmax = 0;
1626 		if(!checkmin && !checkmax)
1627 			return 1; /* will always match */
1628 	}
1629 	return 1;
1630 }
1631 #endif /* INET6 */
1632 
1633 int
1634 acl_key_matches(struct acl_options* acl, struct query* q)
1635 {
1636 	if(acl->blocked)
1637 		return 1;
1638 	if(acl->nokey) {
1639 		if(q->tsig.status == TSIG_NOT_PRESENT)
1640 			return 1;
1641 		return 0;
1642 	}
1643 	/* check name of tsig key */
1644 	if(q->tsig.status != TSIG_OK) {
1645 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG"));
1646 		return 0; /* query has no TSIG */
1647 	}
1648 	if(q->tsig.error_code != TSIG_ERROR_NOERROR) {
1649 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error"));
1650 		return 0; /* some tsig error */
1651 	}
1652 	if(!acl->key_options->tsig_key) {
1653 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config"));
1654 		return 0; /* key not properly configured */
1655 	}
1656 	if(dname_compare(q->tsig.key_name,
1657 		acl->key_options->tsig_key->name) != 0) {
1658 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name"));
1659 		return 0; /* wrong key name */
1660 	}
1661 	if(tsig_strlowercmp(q->tsig.algorithm->short_name,
1662 		acl->key_options->algorithm) != 0 && (
1663 		strncmp("hmac-", q->tsig.algorithm->short_name, 5) != 0 ||
1664 		tsig_strlowercmp(q->tsig.algorithm->short_name+5,
1665 		acl->key_options->algorithm) != 0) ) {
1666 		DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm"));
1667 		return 0; /* no such algo */
1668 	}
1669 	return 1;
1670 }
1671 
1672 int
1673 acl_same_host(struct acl_options* a, struct acl_options* b)
1674 {
1675 	if(a->is_ipv6 && !b->is_ipv6)
1676 		return 0;
1677 	if(!a->is_ipv6 && b->is_ipv6)
1678 		return 0;
1679 	if(a->port != b->port)
1680 		return 0;
1681 	if(a->rangetype != b->rangetype)
1682 		return 0;
1683 	if(!a->is_ipv6) {
1684 		if(memcmp(&a->addr.addr, &b->addr.addr,
1685 		   sizeof(struct in_addr)) != 0)
1686 			return 0;
1687 		if(a->rangetype != acl_range_single &&
1688 		   memcmp(&a->range_mask.addr, &b->range_mask.addr,
1689 		   sizeof(struct in_addr)) != 0)
1690 			return 0;
1691 	} else {
1692 #ifdef INET6
1693 		if(memcmp(&a->addr.addr6, &b->addr.addr6,
1694 		   sizeof(struct in6_addr)) != 0)
1695 			return 0;
1696 		if(a->rangetype != acl_range_single &&
1697 		   memcmp(&a->range_mask.addr6, &b->range_mask.addr6,
1698 		   sizeof(struct in6_addr)) != 0)
1699 			return 0;
1700 #else
1701 		return 0;
1702 #endif
1703 	}
1704 	return 1;
1705 }
1706 
1707 #if defined(HAVE_SSL)
1708 void
1709 key_options_tsig_add(struct nsd_options* opt)
1710 {
1711 	struct key_options* optkey;
1712 	RBTREE_FOR(optkey, struct key_options*, opt->keys) {
1713 		key_options_setup(opt->region, optkey);
1714 		tsig_add_key(optkey->tsig_key);
1715 	}
1716 }
1717 #endif
1718 
1719 int
1720 zone_is_slave(struct zone_options* opt)
1721 {
1722 	return opt && opt->pattern && opt->pattern->request_xfr != 0;
1723 }
1724 
1725 /* get a character in string (or replacement char if not long enough) */
1726 static const char*
1727 get_char(const char* str, size_t i)
1728 {
1729 	static char res[2];
1730 	if(i >= strlen(str))
1731 		return ".";
1732 	res[0] = str[i];
1733 	res[1] = 0;
1734 	return res;
1735 }
1736 /* get end label of the zone name (or .) */
1737 static const char*
1738 get_end_label(struct zone_options* zone, int i)
1739 {
1740 	const dname_type* d = (const dname_type*)zone->node.key;
1741 	if(i >= d->label_count) {
1742 		return ".";
1743 	}
1744 	return wirelabel2str(dname_label(d, i));
1745 }
1746 /* replace occurrences of one with two */
1747 void
1748 replace_str(char* str, size_t len, const char* one, const char* two)
1749 {
1750 	char* pos;
1751 	char* at = str;
1752 	while( (pos=strstr(at, one)) ) {
1753 		if(strlen(str)+strlen(two)-strlen(one) >= len)
1754 			return; /* no more space to replace */
1755 		/* stuff before pos is fine */
1756 		/* move the stuff after pos to make space for two, add
1757 		 * one to length of remainder to also copy the 0 byte end */
1758 		memmove(pos+strlen(two), pos+strlen(one),
1759 			strlen(pos+strlen(one))+1);
1760 		/* copy in two */
1761 		memmove(pos, two, strlen(two));
1762 		/* at is end of the newly inserted two (avoids recursion if
1763 		 * two contains one) */
1764 		at = pos+strlen(two);
1765 	}
1766 }
1767 
1768 const char*
1769 config_cook_string(struct zone_options* zone, const char* input)
1770 {
1771 	static char f[1024];
1772 	/* if not a template, return as-is */
1773 	if(!strchr(input, '%')) {
1774 		return input;
1775 	}
1776 	strlcpy(f, input, sizeof(f));
1777 	if(strstr(f, "%1"))
1778 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
1779 	if(strstr(f, "%2"))
1780 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
1781 	if(strstr(f, "%3"))
1782 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
1783 	if(strstr(f, "%z"))
1784 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
1785 	if(strstr(f, "%y"))
1786 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
1787 	if(strstr(f, "%x"))
1788 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
1789 	if(strstr(f, "%s"))
1790 		replace_str(f, sizeof(f), "%s", zone->name);
1791 	return f;
1792 }
1793 
1794 const char*
1795 config_make_zonefile(struct zone_options* zone, struct nsd* nsd)
1796 {
1797 	static char f[1024];
1798 	/* if not a template, return as-is */
1799 	if(!strchr(zone->pattern->zonefile, '%')) {
1800 		if (nsd->chrootdir && nsd->chrootdir[0] &&
1801 			zone->pattern->zonefile &&
1802 			zone->pattern->zonefile[0] == '/' &&
1803 			strncmp(zone->pattern->zonefile, nsd->chrootdir,
1804 			strlen(nsd->chrootdir)) == 0)
1805 			/* -1 because chrootdir ends in trailing slash */
1806 			return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1;
1807 		return zone->pattern->zonefile;
1808 	}
1809 	strlcpy(f, zone->pattern->zonefile, sizeof(f));
1810 	if(strstr(f, "%1"))
1811 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
1812 	if(strstr(f, "%2"))
1813 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
1814 	if(strstr(f, "%3"))
1815 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
1816 	if(strstr(f, "%z"))
1817 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
1818 	if(strstr(f, "%y"))
1819 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
1820 	if(strstr(f, "%x"))
1821 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
1822 	if(strstr(f, "%s"))
1823 		replace_str(f, sizeof(f), "%s", zone->name);
1824 	if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' &&
1825 		strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0)
1826 		/* -1 because chrootdir ends in trailing slash */
1827 		return f + strlen(nsd->chrootdir) - 1;
1828 	return f;
1829 }
1830 
1831 struct zone_options*
1832 zone_options_find(struct nsd_options* opt, const struct dname* apex)
1833 {
1834 	return (struct zone_options*) rbtree_search(opt->zone_options, apex);
1835 }
1836 
1837 struct acl_options*
1838 acl_find_num(struct acl_options* acl, int num)
1839 {
1840 	int count = num;
1841 	if(num < 0)
1842 		return 0;
1843 	while(acl && count > 0) {
1844 		acl = acl->next;
1845 		count--;
1846 	}
1847 	if(count == 0)
1848 		return acl;
1849 	return 0;
1850 }
1851 
1852 /* true if ipv6 address, false if ipv4 */
1853 int
1854 parse_acl_is_ipv6(const char* p)
1855 {
1856 	/* see if addr is ipv6 or ipv4 -- by : and . */
1857 	while(*p) {
1858 		if(*p == '.') return 0;
1859 		if(*p == ':') return 1;
1860 		++p;
1861 	}
1862 	return 0;
1863 }
1864 
1865 /* returns range type. mask is the 2nd part of the range */
1866 int
1867 parse_acl_range_type(char* ip, char** mask)
1868 {
1869 	char *p;
1870 	if((p=strchr(ip, '&'))!=0) {
1871 		*p = 0;
1872 		*mask = p+1;
1873 		return acl_range_mask;
1874 	}
1875 	if((p=strchr(ip, '/'))!=0) {
1876 		*p = 0;
1877 		*mask = p+1;
1878 		return acl_range_subnet;
1879 	}
1880 	if((p=strchr(ip, '-'))!=0) {
1881 		*p = 0;
1882 		*mask = p+1;
1883 		return acl_range_minmax;
1884 	}
1885 	*mask = 0;
1886 	return acl_range_single;
1887 }
1888 
1889 /* parses subnet mask, fills 0 mask as well */
1890 void
1891 parse_acl_range_subnet(char* p, void* addr, int maxbits)
1892 {
1893 	int subnet_bits = atoi(p);
1894 	uint8_t* addr_bytes = (uint8_t*)addr;
1895 	if(subnet_bits == 0 && strcmp(p, "0")!=0) {
1896 		c_error("bad subnet range '%s'", p);
1897 		return;
1898 	}
1899 	if(subnet_bits < 0 || subnet_bits > maxbits) {
1900 		c_error("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits);
1901 		return;
1902 	}
1903 	/* fill addr with n bits of 1s (struct has been zeroed) */
1904 	while(subnet_bits >= 8) {
1905 		*addr_bytes++ = 0xff;
1906 		subnet_bits -= 8;
1907 	}
1908 	if(subnet_bits > 0) {
1909 		uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1910 		*addr_bytes = shifts[subnet_bits];
1911 	}
1912 }
1913 
1914 struct acl_options*
1915 parse_acl_info(region_type* region, char* ip, const char* key)
1916 {
1917 	char* p;
1918 	struct acl_options* acl = (struct acl_options*)region_alloc(region,
1919 		sizeof(struct acl_options));
1920 	acl->next = 0;
1921 	/* ip */
1922 	acl->ip_address_spec = region_strdup(region, ip);
1923 	acl->use_axfr_only = 0;
1924 	acl->allow_udp = 0;
1925 	acl->ixfr_disabled = 0;
1926 	acl->bad_xfr_count = 0;
1927 	acl->key_options = 0;
1928 	acl->is_ipv6 = 0;
1929 	acl->port = 0;
1930 	memset(&acl->addr, 0, sizeof(union acl_addr_storage));
1931 	memset(&acl->range_mask, 0, sizeof(union acl_addr_storage));
1932 	if((p=strrchr(ip, '@'))!=0) {
1933 		if(atoi(p+1) == 0) c_error("expected port number after '@'");
1934 		else acl->port = atoi(p+1);
1935 		*p=0;
1936 	}
1937 	acl->rangetype = parse_acl_range_type(ip, &p);
1938 	if(parse_acl_is_ipv6(ip)) {
1939 		acl->is_ipv6 = 1;
1940 #ifdef INET6
1941 		if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
1942 			c_error("Bad ip6 address '%s'", ip);
1943 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
1944 			assert(p);
1945 			if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
1946 				c_error("Bad ip6 address mask '%s'", p);
1947 		}
1948 		if(acl->rangetype==acl_range_subnet) {
1949 			assert(p);
1950 			parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
1951 		}
1952 #else
1953 		c_error("encountered IPv6 address '%s'.", ip);
1954 #endif /* INET6 */
1955 	} else {
1956 		acl->is_ipv6 = 0;
1957 		if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
1958 			c_error("Bad ip4 address '%s'", ip);
1959 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
1960 			assert(p);
1961 			if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
1962 				c_error("Bad ip4 address mask '%s'", p);
1963 		}
1964 		if(acl->rangetype==acl_range_subnet) {
1965 			assert(p);
1966 			parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
1967 		}
1968 	}
1969 
1970 	/* key */
1971 	if(strcmp(key, "NOKEY")==0) {
1972 		acl->nokey = 1;
1973 		acl->blocked = 0;
1974 		acl->key_name = 0;
1975 	} else if(strcmp(key, "BLOCKED")==0) {
1976 		acl->nokey = 0;
1977 		acl->blocked = 1;
1978 		acl->key_name = 0;
1979 	} else {
1980 		acl->nokey = 0;
1981 		acl->blocked = 0;
1982 		acl->key_name = region_strdup(region, key);
1983 	}
1984 	return acl;
1985 }
1986 
1987 /* copy acl list at end of parser start, update current */
1988 static
1989 void copy_and_append_acls(struct acl_options** start, struct acl_options* list)
1990 {
1991 	struct acl_options *tail = NULL;
1992 
1993 	assert(start != NULL);
1994 
1995 	tail = *start;
1996 	if(tail) {
1997 		while(tail->next) {
1998 			tail = tail->next;
1999 		}
2000 	}
2001 
2002 	while(list) {
2003 		struct acl_options* acl = copy_acl(cfg_parser->opt->region,
2004 			list);
2005 		acl->next = NULL;
2006 		if(tail) {
2007 			tail->next = acl;
2008 		} else {
2009 			*start = acl;
2010 		}
2011 		tail = acl;
2012 		list = list->next;
2013 	}
2014 }
2015 
2016 void
2017 config_apply_pattern(struct pattern_options *dest, const char* name)
2018 {
2019 	/* find the pattern */
2020 	struct pattern_options* pat = pattern_options_find(cfg_parser->opt,
2021 		name);
2022 	if(!pat) {
2023 		c_error("could not find pattern %s", name);
2024 		return;
2025 	}
2026 
2027 	/* apply settings */
2028 	if(pat->zonefile)
2029 		dest->zonefile = region_strdup(cfg_parser->opt->region,
2030 			pat->zonefile);
2031 	if(pat->zonestats)
2032 		dest->zonestats = region_strdup(cfg_parser->opt->region,
2033 			pat->zonestats);
2034 	if(!pat->allow_axfr_fallback_is_default) {
2035 		dest->allow_axfr_fallback = pat->allow_axfr_fallback;
2036 		dest->allow_axfr_fallback_is_default = 0;
2037 	}
2038 	if(!pat->notify_retry_is_default) {
2039 		dest->notify_retry = pat->notify_retry;
2040 		dest->notify_retry_is_default = 0;
2041 	}
2042 	if(!pat->max_refresh_time_is_default) {
2043 		dest->max_refresh_time = pat->max_refresh_time;
2044 		dest->max_refresh_time_is_default = 0;
2045 	}
2046 	if(!pat->min_refresh_time_is_default) {
2047 		dest->min_refresh_time = pat->min_refresh_time;
2048 		dest->min_refresh_time_is_default = 0;
2049 	}
2050 	if(!pat->max_retry_time_is_default) {
2051 		dest->max_retry_time = pat->max_retry_time;
2052 		dest->max_retry_time_is_default = 0;
2053 	}
2054 	if(!pat->min_retry_time_is_default) {
2055 		dest->min_retry_time = pat->min_retry_time;
2056 		dest->min_retry_time_is_default = 0;
2057 	}
2058 	if(!expire_time_is_default(pat->min_expire_time_expr)) {
2059 		dest->min_expire_time = pat->min_expire_time;
2060 		dest->min_expire_time_expr = pat->min_expire_time_expr;
2061 	}
2062 	dest->size_limit_xfr = pat->size_limit_xfr;
2063 #ifdef RATELIMIT
2064 	dest->rrl_whitelist |= pat->rrl_whitelist;
2065 #endif
2066 	/* append acl items */
2067 	copy_and_append_acls(&dest->allow_notify, pat->allow_notify);
2068 	copy_and_append_acls(&dest->request_xfr, pat->request_xfr);
2069 	copy_and_append_acls(&dest->notify, pat->notify);
2070 	copy_and_append_acls(&dest->provide_xfr, pat->provide_xfr);
2071 	copy_and_append_acls(&dest->allow_query, pat->allow_query);
2072 	copy_and_append_acls(&dest->outgoing_interface, pat->outgoing_interface);
2073 	if(pat->multi_master_check)
2074 		dest->multi_master_check = pat->multi_master_check;
2075 }
2076 
2077 void
2078 nsd_options_destroy(struct nsd_options* opt)
2079 {
2080 	region_destroy(opt->region);
2081 #ifdef MEMCLEAN /* OS collects memory pages */
2082 	c_lex_destroy();
2083 #endif
2084 }
2085 
2086 unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt)
2087 {
2088 #ifdef USE_ZONE_STATS
2089 	const char* statname;
2090 	struct zonestatname* n;
2091 	rbnode_type* res;
2092 	/* try to find the instantiated zonestat name */
2093 	if(!zopt->pattern->zonestats || zopt->pattern->zonestats[0]==0)
2094 		return 0; /* no zone stats */
2095 	statname = config_cook_string(zopt, zopt->pattern->zonestats);
2096 	res = rbtree_search(opt->zonestatnames, statname);
2097 	if(res)
2098 		return ((struct zonestatname*)res)->id;
2099 	/* create it */
2100 	n = (struct zonestatname*)region_alloc_zero(opt->region, sizeof(*n));
2101 	n->node.key = region_strdup(opt->region, statname);
2102 	if(!n->node.key) {
2103 		log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
2104 		exit(1);
2105 	}
2106 	n->id = (unsigned)(opt->zonestatnames->count);
2107 	rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
2108 	return n->id;
2109 #else /* USE_ZONE_STATS */
2110 	(void)opt; (void)zopt;
2111 	return 0;
2112 #endif /* USE_ZONE_STATS */
2113 }
2114 
2115 /** check if config turns on IP-address interface with certificates or a
2116  * named pipe without certificates. */
2117 int
2118 options_remote_is_address(struct nsd_options* cfg)
2119 {
2120 	if(!cfg->control_enable) return 0;
2121 	if(!cfg->control_interface) return 1;
2122 	if(!cfg->control_interface->address) return 1;
2123 	if(cfg->control_interface->address[0] == 0) return 1;
2124 	return (cfg->control_interface->address[0] != '/');
2125 }
2126 
2127 #ifdef HAVE_GETIFADDRS
2128 static void
2129 resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, size_t *ip_addresses_size)
2130 {
2131 	struct ifaddrs *ifa;
2132 	size_t last_ip_addresses_size = *ip_addresses_size;
2133 
2134 	for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
2135 		sa_family_t family;
2136 		const char* atsign;
2137 #ifdef INET6      /* |   address ip    | % |  ifa name  | @ |  port  | nul */
2138 		char addr_buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1 + 16 + 1];
2139 #else
2140 		char addr_buf[INET_ADDRSTRLEN + 1 + 16 + 1];
2141 #endif
2142 
2143 		if((atsign=strrchr(search_ifa, '@')) != NULL) {
2144 			if(strlen(ifa->ifa_name) != (size_t)(atsign-search_ifa)
2145 			   || strncmp(ifa->ifa_name, search_ifa,
2146 			   atsign-search_ifa) != 0)
2147 				continue;
2148 		} else {
2149 			if(strcmp(ifa->ifa_name, search_ifa) != 0)
2150 				continue;
2151 			atsign = "";
2152 		}
2153 
2154 		if(ifa->ifa_addr == NULL)
2155 			continue;
2156 
2157 		family = ifa->ifa_addr->sa_family;
2158 		if(family == AF_INET) {
2159 			char a4[INET_ADDRSTRLEN + 1];
2160 			struct sockaddr_in *in4 = (struct sockaddr_in *)
2161 				ifa->ifa_addr;
2162 			if(!inet_ntop(family, &in4->sin_addr, a4, sizeof(a4)))
2163 				error("inet_ntop");
2164 			snprintf(addr_buf, sizeof(addr_buf), "%s%s",
2165 				a4, atsign);
2166 		}
2167 #ifdef INET6
2168 		else if(family == AF_INET6) {
2169 			struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)
2170 				ifa->ifa_addr;
2171 			char a6[INET6_ADDRSTRLEN + 1];
2172 			char if_index_name[IF_NAMESIZE + 1];
2173 			if_index_name[0] = 0;
2174 			if(!inet_ntop(family, &in6->sin6_addr, a6, sizeof(a6)))
2175 				error("inet_ntop");
2176 			if_indextoname(in6->sin6_scope_id,
2177 				(char *)if_index_name);
2178 			if (strlen(if_index_name) != 0) {
2179 				snprintf(addr_buf, sizeof(addr_buf),
2180 					"%s%%%s%s", a6, if_index_name, atsign);
2181 			} else {
2182 				snprintf(addr_buf, sizeof(addr_buf), "%s%s",
2183 					a6, atsign);
2184 			}
2185 		}
2186 #endif
2187 		else {
2188 			continue;
2189 		}
2190 		VERBOSITY(4, (LOG_INFO, "interface %s has address %s",
2191 			search_ifa, addr_buf));
2192 
2193 		*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
2194 		(*ip_addresses)[*ip_addresses_size] = xstrdup(addr_buf);
2195 		(*ip_addresses_size)++;
2196 	}
2197 
2198 	if (*ip_addresses_size == last_ip_addresses_size) {
2199 		*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
2200 		(*ip_addresses)[*ip_addresses_size] = xstrdup(search_ifa);
2201 		(*ip_addresses_size)++;
2202 	}
2203 }
2204 
2205 static void
2206 resolve_interface_names_for_ref(struct ip_address_option** ip_addresses_ref,
2207 		struct ifaddrs *addrs, region_type* region)
2208 {
2209 	struct ip_address_option *ip_addr;
2210 	struct ip_address_option *last = NULL;
2211 	struct ip_address_option *first = NULL;
2212 
2213 	/* replace the list of ip_adresses with a new list where the
2214 	 * interface names are replaced with their ip-address strings
2215 	 * from getifaddrs.  An interface can have several addresses. */
2216 	for(ip_addr = *ip_addresses_ref; ip_addr; ip_addr = ip_addr->next) {
2217 		char **ip_addresses = NULL;
2218 		size_t ip_addresses_size = 0, i;
2219 		resolve_ifa_name(addrs, ip_addr->address, &ip_addresses,
2220 			&ip_addresses_size);
2221 
2222 		for (i = 0; i < ip_addresses_size; i++) {
2223 			struct ip_address_option *current;
2224 			/* this copies the range_option, dev, and fib from
2225 			 * the original ip_address option to the new ones
2226 			 * with the addresses spelled out by resolve_ifa_name*/
2227 			current = region_alloc_init(region, ip_addr,
2228 				sizeof(*ip_addr));
2229 			current->address = region_strdup(region,
2230 				ip_addresses[i]);
2231 			current->next = NULL;
2232 			free(ip_addresses[i]);
2233 
2234 			if(first == NULL) {
2235 				first = current;
2236 			} else {
2237 				last->next = current;
2238 			}
2239 			last = current;
2240 		}
2241 		free(ip_addresses);
2242 	}
2243 	*ip_addresses_ref = first;
2244 
2245 }
2246 #endif /* HAVE_GETIFADDRS */
2247 
2248 void
2249 resolve_interface_names(struct nsd_options* options)
2250 {
2251 #ifdef HAVE_GETIFADDRS
2252 	struct ifaddrs *addrs;
2253 
2254 	if(getifaddrs(&addrs) == -1)
2255 		  error("failed to list interfaces");
2256 
2257 	resolve_interface_names_for_ref(&options->ip_addresses,
2258 			addrs, options->region);
2259 	resolve_interface_names_for_ref(&options->control_interface,
2260 			addrs, options->region);
2261 
2262 	freeifaddrs(addrs);
2263 #else
2264 	(void)options;
2265 #endif /* HAVE_GETIFADDRS */
2266 }
2267