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