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