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