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