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