1/*
2 * zonec.c -- zone compiler.
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10#include "config.h"
11
12#include <assert.h>
13#include <fcntl.h>
14#include <ctype.h>
15#include <errno.h>
16#include <limits.h>
17#include <stdio.h>
18#include <string.h>
19#ifdef HAVE_STRINGS_H
20#include <strings.h>
21#endif
22#include <unistd.h>
23#include <stdlib.h>
24#include <time.h>
25#ifdef HAVE_SYS_STAT_H
26#include <sys/stat.h>
27#endif
28
29#include <netinet/in.h>
30
31#ifdef HAVE_NETDB_H
32#include <netdb.h>
33#endif
34
35#include "zonec.h"
36
37#include "dname.h"
38#include "dns.h"
39#include "namedb.h"
40#include "rdata.h"
41#include "region-allocator.h"
42#include "util.h"
43#include "zparser.h"
44#include "options.h"
45#include "nsec3.h"
46
47#define ILNP_MAXDIGITS 4
48#define ILNP_NUMGROUPS 4
49#define SVCB_MAX_COMMA_SEPARATED_VALUES 1000
50
51
52const dname_type *error_dname;
53domain_type *error_domain;
54
55static time_t startzonec = 0;
56static long int totalrrs = 0;
57
58extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
59extern uint16_t nsec_highest_rcode;
60
61
62/*
63 * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first
64 * element.  Return a pointer to the allocation.
65 */
66static uint16_t *
67alloc_rdata(region_type *region, size_t size)
68{
69	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
70	*result = size;
71	return result;
72}
73
74uint16_t *
75alloc_rdata_init(region_type *region, const void *data, size_t size)
76{
77	uint16_t *result = region_alloc(region, sizeof(uint16_t) + size);
78	*result = size;
79	memcpy(result + 1, data, size);
80	return result;
81}
82
83/*
84 * These are parser function for generic zone file stuff.
85 */
86uint16_t *
87zparser_conv_hex(region_type *region, const char *hex, size_t len)
88{
89	/* convert a hex value to wireformat */
90	uint16_t *r = NULL;
91	uint8_t *t;
92	int i;
93
94	if(len == 1 && hex[0] == '0') {
95		/* single 0 represents empty buffer */
96		return alloc_rdata(region, 0);
97	}
98	if (len % 2 != 0) {
99		zc_error_prev_line("number of hex digits must be a multiple of 2");
100	} else if (len > MAX_RDLENGTH * 2) {
101		zc_error_prev_line("hex data exceeds maximum rdata length (%d)",
102				   MAX_RDLENGTH);
103	} else {
104		/* the length part */
105		r = alloc_rdata(region, len/2);
106		t = (uint8_t *)(r + 1);
107
108		/* Now process octet by octet... */
109		while (*hex) {
110			*t = 0;
111			for (i = 16; i >= 1; i -= 15) {
112				if (isxdigit((unsigned char)*hex)) {
113					*t += hexdigit_to_int(*hex) * i;
114				} else {
115					zc_error_prev_line(
116						"illegal hex character '%c'",
117						(int) *hex);
118					return NULL;
119				}
120				++hex;
121			}
122			++t;
123		}
124	}
125	return r;
126}
127
128/* convert hex, precede by a 1-byte length */
129uint16_t *
130zparser_conv_hex_length(region_type *region, const char *hex, size_t len)
131{
132	uint16_t *r = NULL;
133	uint8_t *t;
134	int i;
135	if (len % 2 != 0) {
136		zc_error_prev_line("number of hex digits must be a multiple of 2");
137	} else if (len > 255 * 2) {
138		zc_error_prev_line("hex data exceeds 255 bytes");
139	} else {
140		uint8_t *l;
141
142		/* the length part */
143		r = alloc_rdata(region, len/2+1);
144		t = (uint8_t *)(r + 1);
145
146		l = t++;
147		*l = '\0';
148
149		/* Now process octet by octet... */
150		while (*hex) {
151			*t = 0;
152			for (i = 16; i >= 1; i -= 15) {
153				if (isxdigit((unsigned char)*hex)) {
154					*t += hexdigit_to_int(*hex) * i;
155				} else {
156					zc_error_prev_line(
157						"illegal hex character '%c'",
158						(int) *hex);
159					return NULL;
160				}
161				++hex;
162			}
163			++t;
164			++*l;
165		}
166	}
167	return r;
168}
169
170uint16_t *
171zparser_conv_time(region_type *region, const char *time)
172{
173	/* convert a time YYHM to wireformat */
174	uint16_t *r = NULL;
175	struct tm tm;
176
177	/* Try to scan the time... */
178	if (!strptime(time, "%Y%m%d%H%M%S", &tm)) {
179		zc_error_prev_line("date and time is expected");
180	} else {
181		uint32_t l = htonl(mktime_from_utc(&tm));
182		r = alloc_rdata_init(region, &l, sizeof(l));
183	}
184	return r;
185}
186
187uint16_t *
188zparser_conv_services(region_type *region, const char *protostr,
189		      char *servicestr)
190{
191	/*
192	 * Convert a protocol and a list of service port numbers
193	 * (separated by spaces) in the rdata to wireformat
194	 */
195	uint16_t *r = NULL;
196	uint8_t *p;
197	uint8_t bitmap[65536/8];
198	char sep[] = " ";
199	char *word;
200	int max_port = -8;
201	/* convert a protocol in the rdata to wireformat */
202	struct protoent *proto;
203
204	memset(bitmap, 0, sizeof(bitmap));
205
206	proto = getprotobyname(protostr);
207	if (!proto) {
208		proto = getprotobynumber(atoi(protostr));
209	}
210	if (!proto) {
211		zc_error_prev_line("unknown protocol '%s'", protostr);
212		return NULL;
213	}
214
215	for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) {
216		struct servent *service;
217		int port;
218
219		service = getservbyname(word, proto->p_name);
220		if (service) {
221			/* Note: ntohs not ntohl!  Strange but true.  */
222			port = ntohs((uint16_t) service->s_port);
223		} else {
224			char *end;
225			port = strtol(word, &end, 10);
226			if (*end != '\0') {
227				zc_error_prev_line("unknown service '%s' for protocol '%s'",
228						   word, protostr);
229				continue;
230			}
231		}
232
233		if (port < 0 || port > 65535) {
234			zc_error_prev_line("bad port number %d", port);
235		} else {
236			set_bit(bitmap, port);
237			if (port > max_port)
238				max_port = port;
239		}
240	}
241
242	r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1);
243	p = (uint8_t *) (r + 1);
244	*p = proto->p_proto;
245	memcpy(p + 1, bitmap, *r-1);
246
247	return r;
248}
249
250uint16_t *
251zparser_conv_serial(region_type *region, const char *serialstr)
252{
253	uint16_t *r = NULL;
254	uint32_t serial;
255	const char *t;
256
257	serial = strtoserial(serialstr, &t);
258	if (*t != '\0') {
259		zc_error_prev_line("serial is expected or serial too big");
260	} else {
261		serial = htonl(serial);
262		r = alloc_rdata_init(region, &serial, sizeof(serial));
263	}
264	return r;
265}
266
267uint16_t *
268zparser_conv_period(region_type *region, const char *periodstr)
269{
270	/* convert a time period (think TTL's) to wireformat) */
271	uint16_t *r = NULL;
272	uint32_t period;
273	const char *end;
274
275	/* Allocate required space... */
276	period = strtottl(periodstr, &end);
277	if (*end != '\0') {
278		zc_error_prev_line("time period is expected");
279	} else {
280		period = htonl(period);
281		r = alloc_rdata_init(region, &period, sizeof(period));
282	}
283	return r;
284}
285
286uint16_t *
287zparser_conv_short(region_type *region, const char *text)
288{
289	uint16_t *r = NULL;
290	uint16_t value;
291	char *end;
292
293	value = htons((uint16_t) strtol(text, &end, 10));
294	if (*end != '\0') {
295		zc_error_prev_line("integer value is expected");
296	} else {
297		r = alloc_rdata_init(region, &value, sizeof(value));
298	}
299	return r;
300}
301
302uint16_t *
303zparser_conv_byte(region_type *region, const char *text)
304{
305	uint16_t *r = NULL;
306	uint8_t value;
307	char *end;
308
309	value = (uint8_t) strtol(text, &end, 10);
310	if (*end != '\0') {
311		zc_error_prev_line("integer value is expected");
312	} else {
313		r = alloc_rdata_init(region, &value, sizeof(value));
314	}
315	return r;
316}
317
318uint16_t *
319zparser_conv_algorithm(region_type *region, const char *text)
320{
321	const lookup_table_type *alg;
322	uint8_t id;
323
324	alg = lookup_by_name(dns_algorithms, text);
325	if (alg) {
326		id = (uint8_t) alg->id;
327	} else {
328		char *end;
329		id = (uint8_t) strtol(text, &end, 10);
330		if (*end != '\0') {
331			zc_error_prev_line("algorithm is expected");
332			return NULL;
333		}
334	}
335
336	return alloc_rdata_init(region, &id, sizeof(id));
337}
338
339uint16_t *
340zparser_conv_certificate_type(region_type *region, const char *text)
341{
342	/* convert an algorithm string to integer */
343	const lookup_table_type *type;
344	uint16_t id;
345
346	type = lookup_by_name(dns_certificate_types, text);
347	if (type) {
348		id = htons((uint16_t) type->id);
349	} else {
350		char *end;
351		id = htons((uint16_t) strtol(text, &end, 10));
352		if (*end != '\0') {
353			zc_error_prev_line("certificate type is expected");
354			return NULL;
355		}
356	}
357
358	return alloc_rdata_init(region, &id, sizeof(id));
359}
360
361uint16_t *
362zparser_conv_a(region_type *region, const char *text)
363{
364	in_addr_t address;
365	uint16_t *r = NULL;
366
367	if (inet_pton(AF_INET, text, &address) != 1) {
368		zc_error_prev_line("invalid IPv4 address '%s'", text);
369	} else {
370		r = alloc_rdata_init(region, &address, sizeof(address));
371	}
372	return r;
373}
374
375uint16_t *
376zparser_conv_aaaa(region_type *region, const char *text)
377{
378	uint8_t address[IP6ADDRLEN];
379	uint16_t *r = NULL;
380
381	if (inet_pton(AF_INET6, text, address) != 1) {
382		zc_error_prev_line("invalid IPv6 address '%s'", text);
383	} else {
384		r = alloc_rdata_init(region, address, sizeof(address));
385	}
386	return r;
387}
388
389
390uint16_t *
391zparser_conv_ilnp64(region_type *region, const char *text)
392{
393	uint16_t *r = NULL;
394	int ngroups, num;
395	unsigned long hex;
396	const char *ch;
397	char digits[ILNP_MAXDIGITS+1];
398	unsigned int ui[ILNP_NUMGROUPS];
399	uint16_t a[ILNP_NUMGROUPS];
400
401	ngroups = 1; /* Always at least one group */
402	num = 0;
403	for (ch = text; *ch != '\0'; ch++) {
404		if (*ch == ':') {
405			if (num <= 0) {
406				zc_error_prev_line("ilnp64: empty group of "
407					"digits is not allowed");
408				return NULL;
409			}
410			digits[num] = '\0';
411			hex = (unsigned long) strtol(digits, NULL, 16);
412			num = 0;
413			ui[ngroups - 1] = hex;
414			if (ngroups >= ILNP_NUMGROUPS) {
415				zc_error_prev_line("ilnp64: more than %d groups "
416					"of digits", ILNP_NUMGROUPS);
417				return NULL;
418			}
419			ngroups++;
420		} else {
421			/* Our grammar is stricter than the one accepted by
422			 * strtol. */
423			if (!isxdigit((unsigned char)*ch)) {
424				zc_error_prev_line("ilnp64: invalid "
425					"(non-hexadecimal) character %c", *ch);
426				return NULL;
427			}
428			if (num >= ILNP_MAXDIGITS) {
429				zc_error_prev_line("ilnp64: more than %d digits "
430					"in a group", ILNP_MAXDIGITS);
431				return NULL;
432			}
433			digits[num++] = *ch;
434		}
435	}
436	if (num <= 0) {
437		zc_error_prev_line("ilnp64: empty group of digits is not "
438			"allowed");
439		return NULL;
440	}
441	digits[num] = '\0';
442	hex = (unsigned long) strtol(digits, NULL, 16);
443	ui[ngroups - 1] = hex;
444	if (ngroups < 4) {
445		zc_error_prev_line("ilnp64: less than %d groups of digits",
446			ILNP_NUMGROUPS);
447		return NULL;
448	}
449
450	a[0] = htons(ui[0]);
451	a[1] = htons(ui[1]);
452	a[2] = htons(ui[2]);
453	a[3] = htons(ui[3]);
454	r = alloc_rdata_init(region, a, sizeof(a));
455	return r;
456}
457
458static uint16_t *
459zparser_conv_eui48(region_type *region, const char *text)
460{
461	uint8_t nums[6];
462	uint16_t *r = NULL;
463	unsigned int a, b, c, d, e, f;
464	int l;
465
466	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n",
467		&a, &b, &c, &d, &e, &f, &l) != 6 ||
468		l != (int)strlen(text)){
469		zc_error_prev_line("eui48: invalid rr");
470		return NULL;
471	}
472	nums[0] = (uint8_t)a;
473	nums[1] = (uint8_t)b;
474	nums[2] = (uint8_t)c;
475	nums[3] = (uint8_t)d;
476	nums[4] = (uint8_t)e;
477	nums[5] = (uint8_t)f;
478	r = alloc_rdata_init(region, nums, sizeof(nums));
479	return r;
480}
481
482static uint16_t *
483zparser_conv_eui64(region_type *region, const char *text)
484{
485	uint8_t nums[8];
486	uint16_t *r = NULL;
487	unsigned int a, b, c, d, e, f, g, h;
488	int l;
489	if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
490		&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
491		l != (int)strlen(text)) {
492		zc_error_prev_line("eui64: invalid rr");
493		return NULL;
494	}
495	nums[0] = (uint8_t)a;
496	nums[1] = (uint8_t)b;
497	nums[2] = (uint8_t)c;
498	nums[3] = (uint8_t)d;
499	nums[4] = (uint8_t)e;
500	nums[5] = (uint8_t)f;
501	nums[6] = (uint8_t)g;
502	nums[7] = (uint8_t)h;
503	r = alloc_rdata_init(region, nums, sizeof(nums));
504	return r;
505}
506
507uint16_t *
508zparser_conv_eui(region_type *region, const char *text, size_t len)
509{
510	uint16_t *r = NULL;
511	int nnum, num;
512	const char* ch;
513
514	nnum = len/8;
515	num = 1;
516	for (ch = text; *ch != '\0'; ch++) {
517		if (*ch == '-') {
518			num++;
519		} else if (!isxdigit((unsigned char)*ch)) {
520			zc_error_prev_line("eui%u: invalid (non-hexadecimal) "
521				"character %c", (unsigned) len, *ch);
522			return NULL;
523		}
524	}
525	if (num != nnum) {
526		zc_error_prev_line("eui%u: wrong number of hex numbers",
527			(unsigned) len);
528		return NULL;
529	}
530
531	switch (len) {
532		case 48:
533			r = zparser_conv_eui48(region, text);
534			break;
535		case 64:
536			r = zparser_conv_eui64(region, text);
537		break;
538		default:
539			zc_error_prev_line("eui%u: invalid length",
540				(unsigned) len);
541			return NULL;
542			break;
543	}
544	return r;
545}
546
547uint16_t *
548zparser_conv_text(region_type *region, const char *text, size_t len)
549{
550	uint16_t *r = NULL;
551	uint8_t *p;
552
553	if (len > 255) {
554		zc_error_prev_line("text string is longer than 255 characters,"
555				   " try splitting it into multiple parts");
556		len = 255;
557	}
558	r = alloc_rdata(region, len + 1);
559	p = (uint8_t *) (r + 1);
560	*p = len;
561	memcpy(p + 1, text, len);
562	return r;
563}
564
565/* for CAA Value [RFC 6844] */
566uint16_t *
567zparser_conv_long_text(region_type *region, const char *text, size_t len)
568{
569	uint16_t *r = NULL;
570	if (len > MAX_RDLENGTH) {
571		zc_error_prev_line("text string is longer than max rdlen");
572		return NULL;
573	}
574	r = alloc_rdata_init(region, text, len);
575	return r;
576}
577
578/* for CAA Tag [RFC 6844] */
579uint16_t *
580zparser_conv_tag(region_type *region, const char *text, size_t len)
581{
582	uint16_t *r = NULL;
583	uint8_t *p;
584	const char* ptr;
585
586	if (len < 1) {
587		zc_error_prev_line("invalid tag: zero length");
588		return NULL;
589	}
590	if (len > 15) {
591		zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)",
592			text, (unsigned) len);
593		return NULL;
594	}
595	for (ptr = text; *ptr; ptr++) {
596		if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) {
597			zc_error_prev_line("invalid tag %s: contains invalid char %c",
598				text, *ptr);
599			return NULL;
600		}
601	}
602	r = alloc_rdata(region, len + 1);
603	p = (uint8_t *) (r + 1);
604	*p = len;
605	memmove(p + 1, text, len);
606	return r;
607}
608
609uint16_t *
610zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len)
611{
612	uint16_t* r = NULL;
613	uint8_t* p = NULL;
614	r = alloc_rdata(region, len);
615	p = (uint8_t *) (r + 1);
616	memcpy(p, name, len);
617
618	return r;
619}
620
621uint16_t *
622zparser_conv_b32(region_type *region, const char *b32)
623{
624	uint8_t buffer[B64BUFSIZE];
625	uint16_t *r = NULL;
626	int i;
627
628	if(strcmp(b32, "-") == 0) {
629		return alloc_rdata_init(region, "", 1);
630	}
631	i = b32_pton(b32, buffer+1, B64BUFSIZE-1);
632	if (i == -1 || i > 255) {
633		zc_error_prev_line("invalid base32 data");
634	} else {
635		buffer[0] = i; /* store length byte */
636		r = alloc_rdata_init(region, buffer, i+1);
637	}
638	return r;
639}
640
641uint16_t *
642zparser_conv_b64(region_type *region, const char *b64)
643{
644	uint8_t buffer[B64BUFSIZE];
645	uint16_t *r = NULL;
646	int i;
647
648	if(strcmp(b64, "0") == 0) {
649		/* single 0 represents empty buffer */
650		return alloc_rdata(region, 0);
651	}
652	i = __b64_pton(b64, buffer, B64BUFSIZE);
653	if (i == -1) {
654		zc_error_prev_line("invalid base64 data");
655	} else {
656		r = alloc_rdata_init(region, buffer, i);
657	}
658	return r;
659}
660
661uint16_t *
662zparser_conv_rrtype(region_type *region, const char *text)
663{
664	uint16_t *r = NULL;
665	uint16_t type = rrtype_from_string(text);
666
667	if (type == 0) {
668		zc_error_prev_line("unrecognized RR type '%s'", text);
669	} else {
670		type = htons(type);
671		r = alloc_rdata_init(region, &type, sizeof(type));
672	}
673	return r;
674}
675
676uint16_t *
677zparser_conv_nxt(region_type *region, uint8_t nxtbits[])
678{
679	/* nxtbits[] consists of 16 bytes with some zero's in it
680	 * copy every byte with zero to r and write the length in
681	 * the first byte
682	 */
683	uint16_t i;
684	uint16_t last = 0;
685
686	for (i = 0; i < 16; i++) {
687		if (nxtbits[i] != 0)
688			last = i + 1;
689	}
690
691	return alloc_rdata_init(region, nxtbits, last);
692}
693
694
695/* we potentially have 256 windows, each one is numbered. empty ones
696 * should be discarded
697 */
698uint16_t *
699zparser_conv_nsec(region_type *region,
700		  uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE])
701{
702	/* nsecbits contains up to 64K of bits which represent the
703	 * types available for a name. Walk the bits according to
704	 * nsec++ draft from jakob
705	 */
706	uint16_t *r;
707	uint8_t *ptr;
708	size_t i,j;
709	uint16_t window_count = 0;
710	uint16_t total_size = 0;
711	uint16_t window_max = 0;
712
713	/* The used windows.  */
714	int used[NSEC_WINDOW_COUNT];
715	/* The last byte used in each the window.  */
716	int size[NSEC_WINDOW_COUNT];
717
718	window_max = 1 + (nsec_highest_rcode / 256);
719
720	/* used[i] is the i-th window included in the nsec
721	 * size[used[0]] is the size of window 0
722	 */
723
724	/* walk through the 256 windows */
725	for (i = 0; i < window_max; ++i) {
726		int empty_window = 1;
727		/* check each of the 32 bytes */
728		for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) {
729			if (nsecbits[i][j] != 0) {
730				size[i] = j + 1;
731				empty_window = 0;
732			}
733		}
734		if (!empty_window) {
735			used[window_count] = i;
736			window_count++;
737		}
738	}
739
740	for (i = 0; i < window_count; ++i) {
741		total_size += sizeof(uint16_t) + size[used[i]];
742	}
743
744	r = alloc_rdata(region, total_size);
745	ptr = (uint8_t *) (r + 1);
746
747	/* now walk used and copy it */
748	for (i = 0; i < window_count; ++i) {
749		ptr[0] = used[i];
750		ptr[1] = size[used[i]];
751		memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]);
752		ptr += size[used[i]] + 2;
753	}
754
755	return r;
756}
757
758static uint16_t
759svcbparam_lookup_key(const char *key, size_t key_len)
760{
761	char buf[64];
762	char *endptr;
763	unsigned long int key_value;
764
765	if (key_len >= 4  && key_len <= 8 && !strncmp(key, "key", 3)) {
766		memcpy(buf, key + 3, key_len - 3);
767		buf[key_len - 3] = 0;
768		key_value = strtoul(buf, &endptr, 10);
769		if (endptr > buf	/* digits seen */
770		&& *endptr == 0		/* no non-digit chars after digits */
771		&&  key_value <= 65535)	/* no overflow */
772			return key_value;
773
774	} else switch (key_len) {
775	case sizeof("mandatory")-1:
776		if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
777			return SVCB_KEY_MANDATORY;
778		if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
779			return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
780		break;
781
782	case sizeof("alpn")-1:
783		if (!strncmp(key, "alpn", sizeof("alpn")-1))
784			return SVCB_KEY_ALPN;
785		if (!strncmp(key, "port", sizeof("port")-1))
786			return SVCB_KEY_PORT;
787		break;
788
789	case sizeof("no-default-alpn")-1:
790		if (!strncmp( key  , "no-default-alpn"
791		            , sizeof("no-default-alpn")-1))
792			return SVCB_KEY_NO_DEFAULT_ALPN;
793		break;
794
795	case sizeof("ipv4hint")-1:
796		if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1))
797			return SVCB_KEY_IPV4HINT;
798		if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1))
799			return SVCB_KEY_IPV6HINT;
800		break;
801	case sizeof("dohpath")-1:
802		if (!strncmp(key, "dohpath", sizeof("dohpath")-1))
803			return SVCB_KEY_DOHPATH;
804		break;
805	case sizeof("ech")-1:
806		if (!strncmp(key, "ech", sizeof("ech")-1))
807			return SVCB_KEY_ECH;
808		break;
809	default:
810		break;
811	}
812	if (key_len > sizeof(buf) - 1)
813		zc_error_prev_line("Unknown SvcParamKey");
814	else {
815		memcpy(buf, key, key_len);
816		buf[key_len] = 0;
817		zc_error_prev_line("Unknown SvcParamKey: %s", buf);
818	}
819	/* Although the returned value might be used by the caller,
820	 * the parser has erred, so the zone will not be loaded.
821	 */
822	return -1;
823}
824
825static uint16_t *
826zparser_conv_svcbparam_port_value(region_type *region, const char *val)
827{
828	unsigned long int port;
829	char *endptr;
830	uint16_t *r;
831
832	port = strtoul(val, &endptr, 10);
833	if (endptr > val	/* digits seen */
834	&& *endptr == 0		/* no non-digit chars after digits */
835	&&  port <= 65535) {	/* no overflow */
836
837		r = alloc_rdata(region, 3 * sizeof(uint16_t));
838		r[1] = htons(SVCB_KEY_PORT);
839		r[2] = htons(sizeof(uint16_t));
840		r[3] = htons(port);
841		return r;
842	}
843	zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val);
844	return NULL;
845}
846
847static uint16_t *
848zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val)
849{
850	uint16_t *r;
851	int count;
852	char ip_str[INET_ADDRSTRLEN+1];
853	char *next_ip_str;
854	uint32_t *ip_wire_dst;
855	size_t i;
856
857	for (i = 0, count = 1; val[i]; i++) {
858		if (val[i] == ',')
859			count += 1;
860		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
861			zc_error_prev_line("Too many IPV4 addresses in ipv4hint");
862			return NULL;
863		}
864	}
865
866	/* count == number of comma's in val + 1, so the actual number of IPv4
867	 * addresses in val
868	 */
869	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN * count);
870	r[1] = htons(SVCB_KEY_IPV4HINT);
871	r[2] = htons(IP4ADDRLEN * count);
872	ip_wire_dst = (void *)&r[3];
873
874	while (count) {
875		if (!(next_ip_str = strchr(val, ','))) {
876			if (inet_pton(AF_INET, val, ip_wire_dst) != 1)
877				break;
878
879			assert(count == 1);
880
881		} else if (next_ip_str - val >= (int)sizeof(ip_str))
882			break;
883
884		else {
885			memcpy(ip_str, val, next_ip_str - val);
886			ip_str[next_ip_str - val] = 0;
887			if (inet_pton(AF_INET, ip_str, ip_wire_dst) != 1) {
888				val = ip_str; /* to use in error reporting below */
889				break;
890			}
891
892			val = next_ip_str + 1;
893		}
894		ip_wire_dst++;
895		count--;
896	}
897	if (count)
898		zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val);
899
900	return r;
901}
902
903static uint16_t *
904zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val)
905{
906	uint16_t *r;
907	int i, count;
908	char ip6_str[INET6_ADDRSTRLEN+1];
909	char *next_ip6_str;
910	uint8_t *ipv6_wire_dst;
911
912	for (i = 0, count = 1; val[i]; i++) {
913		if (val[i] == ',')
914			count += 1;
915		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
916			zc_error_prev_line("Too many IPV6 addresses in ipv6hint");
917			return NULL;
918		}
919	}
920
921	/* count == number of comma's in val + 1
922	 * so actually the number of IPv6 addresses in val
923	 */
924	r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN * count);
925	r[1] = htons(SVCB_KEY_IPV6HINT);
926	r[2] = htons(IP6ADDRLEN * count);
927	ipv6_wire_dst = (void *)&r[3];
928
929	while (count) {
930		if (!(next_ip6_str = strchr(val, ','))) {
931			if ((inet_pton(AF_INET6, val, ipv6_wire_dst) != 1))
932				break;
933
934			assert(count == 1);
935
936		} else if (next_ip6_str - val >= (int)sizeof(ip6_str))
937			break;
938
939		else {
940			memcpy(ip6_str, val, next_ip6_str - val);
941			ip6_str[next_ip6_str - val] = 0;
942			if (inet_pton(AF_INET6, ip6_str, ipv6_wire_dst) != 1) {
943				val = ip6_str; /* for error reporting below */
944				break;
945			}
946
947			val = next_ip6_str + 1; /* skip the comma */
948		}
949		ipv6_wire_dst += IP6ADDRLEN;
950		count--;
951	}
952	if (count)
953		zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val);
954
955	return r;
956}
957
958static int
959network_uint16_cmp(const void *a, const void *b)
960{
961	return ((int)read_uint16(a)) - ((int)read_uint16(b));
962}
963
964static uint16_t *
965zparser_conv_svcbparam_mandatory_value(region_type *region,
966		const char *val, size_t val_len)
967{
968	uint16_t *r;
969	size_t i, count;
970	char* next_key;
971	uint16_t* key_dst;
972
973	for (i = 0, count = 1; val[i]; i++) {
974		if (val[i] == ',')
975			count += 1;
976		if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
977			zc_error_prev_line("Too many keys in mandatory");
978			return NULL;
979		}
980	}
981
982	r = alloc_rdata(region, (2 + count) * sizeof(uint16_t));
983	r[1] = htons(SVCB_KEY_MANDATORY);
984	r[2] = htons(sizeof(uint16_t) * count);
985	key_dst = (void *)&r[3];
986
987	for(;;) {
988		if (!(next_key = strchr(val, ','))) {
989			*key_dst = htons(svcbparam_lookup_key(val, val_len));
990			break;
991		} else {
992			*key_dst = htons(svcbparam_lookup_key(val, next_key - val));
993		}
994
995		val_len -= next_key - val + 1;
996		val = next_key + 1; /* skip the comma */
997		key_dst += 1;
998	}
999
1000	/* In draft-ietf-dnsop-svcb-https-04 Section 7:
1001	 *
1002	 *     In wire format, the keys are represented by their numeric
1003	 *     values in network byte order, concatenated in ascending order.
1004	 */
1005	qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp);
1006
1007	return r;
1008}
1009
1010static uint16_t *
1011zparser_conv_svcbparam_ech_value(region_type *region, const char *b64)
1012{
1013	uint8_t buffer[B64BUFSIZE];
1014	uint16_t *r = NULL;
1015	int wire_len;
1016
1017	if(strcmp(b64, "0") == 0) {
1018		/* single 0 represents empty buffer */
1019		return alloc_rdata(region, 0);
1020	}
1021	wire_len = __b64_pton(b64, buffer, B64BUFSIZE);
1022	if (wire_len == -1) {
1023		zc_error_prev_line("invalid base64 data in ech");
1024	} else {
1025		r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len);
1026		r[1] = htons(SVCB_KEY_ECH);
1027		r[2] = htons(wire_len);
1028		memcpy(&r[3], buffer, wire_len);
1029	}
1030
1031	return r;
1032}
1033
1034static const char* parse_alpn_next_unescaped_comma(const char *val)
1035{
1036	while (*val) {
1037		/* Only return when the comma is not escaped*/
1038		if (*val == '\\'){
1039			++val;
1040			if (!*val)
1041				break;
1042		} else if (*val == ',')
1043				return val;
1044
1045		val++;
1046	}
1047	return NULL;
1048}
1049
1050static size_t
1051parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len)
1052{
1053	uint8_t *orig_dst = dst;
1054
1055	while (len) {
1056		if (*src == '\\') {
1057			src++;
1058			len--;
1059			if (!len)
1060				break;
1061		}
1062		*dst++ = *src++;
1063		len--;
1064	}
1065	return (size_t)(dst - orig_dst);
1066}
1067
1068static uint16_t *
1069zparser_conv_svcbparam_alpn_value(region_type *region,
1070		const char *val, size_t val_len)
1071{
1072	uint8_t     unescaped_dst[65536];
1073	uint8_t    *dst = unescaped_dst;
1074	const char *next_str;
1075	size_t      str_len;
1076	size_t      dst_len;
1077	uint16_t   *r = NULL;
1078
1079	if (val_len > sizeof(unescaped_dst)) {
1080		zc_error_prev_line("invalid alpn");
1081		return r;
1082	}
1083	while (val_len) {
1084		size_t dst_len;
1085
1086		str_len = (next_str = parse_alpn_next_unescaped_comma(val))
1087		        ? (size_t)(next_str - val) : val_len;
1088
1089		if (str_len > 255) {
1090			zc_error_prev_line("alpn strings need to be"
1091					   " smaller than 255 chars");
1092			return r;
1093		}
1094		dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len);
1095		*dst++ = dst_len;
1096		 dst  += dst_len;
1097
1098		if (!next_str)
1099			break;
1100
1101		/* skip the comma for the next iteration */
1102		val_len -= next_str - val + 1;
1103		val = next_str + 1;
1104	}
1105	dst_len = dst - unescaped_dst;
1106	r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len);
1107	r[1] = htons(SVCB_KEY_ALPN);
1108	r[2] = htons(dst_len);
1109	memcpy(&r[3], unescaped_dst, dst_len);
1110	return r;
1111}
1112
1113static uint16_t *
1114zparser_conv_svcbparam_key_value(region_type *region,
1115    const char *key, size_t key_len, const char *val, size_t val_len)
1116{
1117	uint16_t svcparamkey = svcbparam_lookup_key(key, key_len);
1118	uint16_t *r;
1119
1120	switch (svcparamkey) {
1121	case SVCB_KEY_PORT:
1122		return zparser_conv_svcbparam_port_value(region, val);
1123	case SVCB_KEY_IPV4HINT:
1124		return zparser_conv_svcbparam_ipv4hint_value(region, val);
1125	case SVCB_KEY_IPV6HINT:
1126		return zparser_conv_svcbparam_ipv6hint_value(region, val);
1127	case SVCB_KEY_MANDATORY:
1128		return zparser_conv_svcbparam_mandatory_value(region, val, val_len);
1129	case SVCB_KEY_NO_DEFAULT_ALPN:
1130		if(zone_is_slave(parser->current_zone->opts))
1131			zc_warning_prev_line("no-default-alpn should not have a value");
1132		else
1133			zc_error_prev_line("no-default-alpn should not have a value");
1134		break;
1135	case SVCB_KEY_ECH:
1136		return zparser_conv_svcbparam_ech_value(region, val);
1137	case SVCB_KEY_ALPN:
1138		return zparser_conv_svcbparam_alpn_value(region, val, val_len);
1139	case SVCB_KEY_DOHPATH:
1140		/* fallthrough */
1141	default:
1142		break;
1143	}
1144	r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len);
1145	r[1] = htons(svcparamkey);
1146	r[2] = htons(val_len);
1147	memcpy(r + 3, val, val_len);
1148	return r;
1149}
1150
1151uint16_t *
1152zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len
1153                                          , const char *val, size_t val_len)
1154{
1155	const char *eq;
1156	uint16_t *r;
1157	uint16_t svcparamkey;
1158
1159	/* Form <key>="<value>" (or at least with quoted value) */
1160	if (val && val_len) {
1161		/* Does key end with '=' */
1162		if (key_len && key[key_len - 1] == '=')
1163			return zparser_conv_svcbparam_key_value(
1164			    region, key, key_len - 1, val, val_len);
1165
1166		zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\""
1167		                  , key, val);
1168	}
1169	assert(val == NULL);
1170	if ((eq = memchr(key, '=', key_len))) {
1171		size_t new_key_len = eq - key;
1172
1173		if (key_len - new_key_len - 1 > 0)
1174			return zparser_conv_svcbparam_key_value(region,
1175			    key, new_key_len, eq+1, key_len - new_key_len - 1);
1176		key_len = new_key_len;
1177	}
1178	/* Some SvcParamKeys require values */
1179	svcparamkey = svcbparam_lookup_key(key, key_len);
1180	switch (svcparamkey) {
1181		case SVCB_KEY_MANDATORY:
1182		case SVCB_KEY_ALPN:
1183		case SVCB_KEY_PORT:
1184		case SVCB_KEY_IPV4HINT:
1185		case SVCB_KEY_IPV6HINT:
1186		case SVCB_KEY_DOHPATH:
1187			if(zone_is_slave(parser->current_zone->opts))
1188				zc_warning_prev_line("value expected for SvcParam: %s", key);
1189			else
1190				zc_error_prev_line("value expected for SvcParam: %s", key);
1191			break;
1192		default:
1193			break;
1194	}
1195	/* SvcParam is only a SvcParamKey */
1196	r = alloc_rdata(region, 2 * sizeof(uint16_t));
1197	r[1] = htons(svcparamkey);
1198	r[2] = 0;
1199	return r;
1200}
1201
1202/* Parse an int terminated in the specified range. */
1203static int
1204parse_int(const char *str,
1205	  char **end,
1206	  int *result,
1207	  const char *name,
1208	  int min,
1209	  int max)
1210{
1211	*result = (int) strtol(str, end, 10);
1212	if (*result < min || *result > max) {
1213		zc_error_prev_line("%s must be within the range [%d .. %d]",
1214				   name,
1215				   min,
1216				   max);
1217		return 0;
1218	} else {
1219		return 1;
1220	}
1221}
1222
1223/* RFC1876 conversion routines */
1224static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1225				1000000,10000000,100000000,1000000000};
1226
1227/*
1228 * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
1229 * Sets the given pointer to the last used character.
1230 *
1231 */
1232static uint8_t
1233precsize_aton (char *cp, char **endptr)
1234{
1235	unsigned int mval = 0, cmval = 0;
1236	uint8_t retval = 0;
1237	int exponent;
1238	int mantissa;
1239
1240	while (isdigit((unsigned char)*cp))
1241		mval = mval * 10 + hexdigit_to_int(*cp++);
1242
1243	if (*cp == '.') {	/* centimeters */
1244		cp++;
1245		if (isdigit((unsigned char)*cp)) {
1246			cmval = hexdigit_to_int(*cp++) * 10;
1247			if (isdigit((unsigned char)*cp)) {
1248				cmval += hexdigit_to_int(*cp++);
1249			}
1250		}
1251	}
1252
1253	if(mval >= poweroften[7]) {
1254		assert(poweroften[7] != 0);
1255		/* integer overflow possible for *100 */
1256		mantissa = mval / poweroften[7];
1257		exponent = 9; /* max */
1258	}
1259	else {
1260		cmval = (mval * 100) + cmval;
1261
1262		for (exponent = 0; exponent < 9; exponent++)
1263			if (cmval < poweroften[exponent+1])
1264				break;
1265
1266		assert(poweroften[exponent] != 0);
1267		mantissa = cmval / poweroften[exponent];
1268	}
1269	if (mantissa > 9)
1270		mantissa = 9;
1271
1272	retval = (mantissa << 4) | exponent;
1273
1274	if (*cp == 'm') cp++;
1275
1276	*endptr = cp;
1277
1278	return (retval);
1279}
1280
1281/*
1282 * Parses a specific part of rdata.
1283 *
1284 * Returns:
1285 *
1286 *	number of elements parsed
1287 *	zero on error
1288 *
1289 */
1290uint16_t *
1291zparser_conv_loc(region_type *region, char *str)
1292{
1293	uint16_t *r;
1294	uint32_t *p;
1295	int i;
1296	int deg, min, secs;	/* Secs is stored times 1000.  */
1297	uint32_t lat = 0, lon = 0, alt = 0;
1298	/* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
1299	uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
1300	char *start;
1301	double d;
1302
1303	for(;;) {
1304		deg = min = secs = 0;
1305
1306		/* Degrees */
1307		if (*str == '\0') {
1308			zc_error_prev_line("unexpected end of LOC data");
1309			return NULL;
1310		}
1311
1312		if (!parse_int(str, &str, &deg, "degrees", 0, 180))
1313			return NULL;
1314		if (!isspace((unsigned char)*str)) {
1315			zc_error_prev_line("space expected after degrees");
1316			return NULL;
1317		}
1318		++str;
1319
1320		/* Minutes? */
1321		if (isdigit((unsigned char)*str)) {
1322			if (!parse_int(str, &str, &min, "minutes", 0, 60))
1323				return NULL;
1324			if (!isspace((unsigned char)*str)) {
1325				zc_error_prev_line("space expected after minutes");
1326				return NULL;
1327			}
1328			++str;
1329		}
1330
1331		/* Seconds? */
1332		if (isdigit((unsigned char)*str)) {
1333			start = str;
1334			if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
1335				return NULL;
1336			}
1337
1338			if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
1339				return NULL;
1340			}
1341
1342			if (!isspace((unsigned char)*str)) {
1343				zc_error_prev_line("space expected after seconds");
1344				return NULL;
1345			}
1346			/* No need for precision specifiers, it's a double */
1347			if (sscanf(start, "%lf", &d) != 1) {
1348				zc_error_prev_line("error parsing seconds");
1349			}
1350
1351			if (d < 0.0 || d > 60.0) {
1352				zc_error_prev_line("seconds not in range 0.0 .. 60.0");
1353			}
1354
1355			secs = (int) (d * 1000.0 + 0.5);
1356			++str;
1357		}
1358
1359		switch(*str) {
1360		case 'N':
1361		case 'n':
1362			lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1363			break;
1364		case 'E':
1365		case 'e':
1366			lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
1367			break;
1368		case 'S':
1369		case 's':
1370			lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1371			break;
1372		case 'W':
1373		case 'w':
1374			lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
1375			break;
1376		default:
1377			zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
1378			return NULL;
1379		}
1380		++str;
1381
1382		if (lat != 0 && lon != 0)
1383			break;
1384
1385		if (!isspace((unsigned char)*str)) {
1386			zc_error_prev_line("space expected after latitude/longitude");
1387			return NULL;
1388		}
1389		++str;
1390	}
1391
1392	/* Altitude */
1393	if (*str == '\0') {
1394		zc_error_prev_line("unexpected end of LOC data");
1395		return NULL;
1396	}
1397
1398	if (!isspace((unsigned char)*str)) {
1399		zc_error_prev_line("space expected before altitude");
1400		return NULL;
1401	}
1402	++str;
1403
1404	start = str;
1405
1406	/* Sign */
1407	if (*str == '+' || *str == '-') {
1408		++str;
1409	}
1410
1411	/* Meters of altitude... */
1412	if(strtol(str, &str, 10) == LONG_MAX) {
1413		zc_error_prev_line("altitude too large, number overflow");
1414		return NULL;
1415	}
1416	switch(*str) {
1417	case ' ':
1418	case '\0':
1419	case 'm':
1420		break;
1421	case '.':
1422		if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
1423			return NULL;
1424		}
1425		if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
1426			zc_error_prev_line("altitude fraction must be a number");
1427			return NULL;
1428		}
1429		break;
1430	default:
1431		zc_error_prev_line("altitude must be expressed in meters");
1432		return NULL;
1433	}
1434	if (!isspace((unsigned char)*str) && *str != '\0')
1435		++str;
1436
1437	if (sscanf(start, "%lf", &d) != 1) {
1438		zc_error_prev_line("error parsing altitude");
1439	}
1440
1441	alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
1442
1443	if (!isspace((unsigned char)*str) && *str != '\0') {
1444		zc_error_prev_line("unexpected character after altitude");
1445		return NULL;
1446	}
1447
1448	/* Now parse size, horizontal precision and vertical precision if any */
1449	for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
1450		vszhpvp[i] = precsize_aton(str + 1, &str);
1451
1452		if (!isspace((unsigned char)*str) && *str != '\0') {
1453			zc_error_prev_line("invalid size or precision");
1454			return NULL;
1455		}
1456	}
1457
1458	/* Allocate required space... */
1459	r = alloc_rdata(region, 16);
1460	p = (uint32_t *) (r + 1);
1461
1462	memmove(p, vszhpvp, 4);
1463	write_uint32(p + 1, lat);
1464	write_uint32(p + 2, lon);
1465	write_uint32(p + 3, alt);
1466
1467	return r;
1468}
1469
1470/*
1471 * Convert an APL RR RDATA element.
1472 */
1473uint16_t *
1474zparser_conv_apl_rdata(region_type *region, char *str)
1475{
1476	int negated = 0;
1477	uint16_t address_family;
1478	uint8_t prefix;
1479	uint8_t maximum_prefix;
1480	uint8_t length;
1481	uint8_t address[IP6ADDRLEN];
1482	char *colon = strchr(str, ':');
1483	char *slash = strchr(str, '/');
1484	int af;
1485	int rc;
1486	uint16_t rdlength;
1487	uint16_t *r;
1488	uint8_t *t;
1489	char *end;
1490	long p;
1491
1492	if (!colon) {
1493		zc_error("address family separator is missing");
1494		return NULL;
1495	}
1496	if (!slash) {
1497		zc_error("prefix separator is missing");
1498		return NULL;
1499	}
1500
1501	*colon = '\0';
1502	*slash = '\0';
1503
1504	if (*str == '!') {
1505		negated = 1;
1506		++str;
1507	}
1508
1509	if (strcmp(str, "1") == 0) {
1510		address_family = htons(1);
1511		af = AF_INET;
1512		length = sizeof(in_addr_t);
1513		maximum_prefix = length * 8;
1514	} else if (strcmp(str, "2") == 0) {
1515		address_family = htons(2);
1516		af = AF_INET6;
1517		length = IP6ADDRLEN;
1518		maximum_prefix = length * 8;
1519	} else {
1520		zc_error("invalid address family '%s'", str);
1521		return NULL;
1522	}
1523
1524	rc = inet_pton(af, colon + 1, address);
1525	if (rc == 0) {
1526		zc_error("invalid address '%s'", colon + 1);
1527		return NULL;
1528	} else if (rc == -1) {
1529		zc_error("inet_pton failed: %s", strerror(errno));
1530		return NULL;
1531	}
1532
1533	/* Strip trailing zero octets.	*/
1534	while (length > 0 && address[length - 1] == 0)
1535		--length;
1536
1537
1538	p = strtol(slash + 1, &end, 10);
1539	if (p < 0 || p > maximum_prefix) {
1540		zc_error("prefix not in the range 0 .. %d", maximum_prefix);
1541		return NULL;
1542	} else if (*end != '\0') {
1543		zc_error("invalid prefix '%s'", slash + 1);
1544		return NULL;
1545	}
1546	prefix = (uint8_t) p;
1547
1548	rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
1549		    + length);
1550	r = alloc_rdata(region, rdlength);
1551	t = (uint8_t *) (r + 1);
1552
1553	memcpy(t, &address_family, sizeof(address_family));
1554	t += sizeof(address_family);
1555	memcpy(t, &prefix, sizeof(prefix));
1556	t += sizeof(prefix);
1557	memcpy(t, &length, sizeof(length));
1558	if (negated) {
1559		*t |= APL_NEGATION_MASK;
1560	}
1561	t += sizeof(length);
1562	memcpy(t, address, length);
1563
1564	return r;
1565}
1566
1567/*
1568 * Below some function that also convert but not to wireformat
1569 * but to "normal" (int,long,char) types
1570 */
1571
1572uint32_t
1573zparser_ttl2int(const char *ttlstr, int* error)
1574{
1575	/* convert a ttl value to a integer
1576	 * return the ttl in a int
1577	 * -1 on error
1578	 */
1579
1580	uint32_t ttl;
1581	const char *t;
1582
1583	ttl = strtottl(ttlstr, &t);
1584	if (*t != 0) {
1585		zc_error_prev_line("invalid TTL value: %s",ttlstr);
1586		*error = 1;
1587	}
1588
1589	return ttl;
1590}
1591
1592
1593void
1594zadd_rdata_wireformat(uint16_t *data)
1595{
1596	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1597		zc_error_prev_line("too many rdata elements");
1598	} else {
1599		parser->current_rr.rdatas[parser->current_rr.rdata_count].data
1600			= data;
1601		++parser->current_rr.rdata_count;
1602	}
1603}
1604
1605/**
1606 * Used for TXT RR's to grow with undefined number of strings.
1607 */
1608void
1609zadd_rdata_txt_wireformat(uint16_t *data, int first)
1610{
1611	rdata_atom_type *rd;
1612	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1613		zc_error_prev_line("too many rdata txt elements");
1614		return;
1615	}
1616
1617	/* First STR in str_seq, allocate 65K in first unused rdata
1618	 * else find last used rdata */
1619	if (first) {
1620		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
1621		if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
1622			sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
1623			zc_error_prev_line("Could not allocate memory for TXT RR");
1624			return;
1625		}
1626		parser->current_rr.rdata_count++;
1627		rd->data[0] = 0;
1628	}
1629	else
1630		rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1631
1632	if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
1633		zc_error_prev_line("too large rdata element");
1634		return;
1635	}
1636
1637	memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
1638	rd->data[0] += data[0];
1639}
1640
1641/**
1642 * Clean up after last call of zadd_rdata_txt_wireformat
1643 */
1644void
1645zadd_rdata_txt_clean_wireformat()
1646{
1647	uint16_t *tmp_data;
1648	rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
1649	if(!rd || !rd->data)
1650		return; /* previous syntax failure */
1651	if ((tmp_data = (uint16_t *) region_alloc(parser->region,
1652		((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
1653		memcpy(tmp_data, rd->data, rd->data[0] + 2);
1654		/* rd->data of u16+65535 freed when rr_region is freed */
1655		rd->data = tmp_data;
1656	}
1657	else {
1658		/* We could not get memory in non-volatile region */
1659		zc_error_prev_line("could not allocate memory for rdata");
1660		return;
1661	}
1662}
1663
1664static int
1665svcparam_key_cmp(const void *a, const void *b)
1666{
1667	return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a)))
1668	     - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b)));
1669}
1670
1671void
1672zadd_rdata_svcb_check_wireformat()
1673{
1674	size_t i;
1675	uint8_t paramkeys[65536];
1676	int prev_key = - 1;
1677	int key = 0;
1678	size_t size;
1679	uint16_t *mandatory_values;
1680
1681	if (parser->current_rr.rdata_count <= 2) {
1682		if (!parser->error_occurred)
1683			zc_error_prev_line("invalid SVCB or HTTPS rdata");
1684		return;
1685	} else for (i = 2; i < parser->current_rr.rdata_count; i++) {
1686		if (parser->current_rr.rdatas[i].data == NULL
1687		||  rdata_atom_data(parser->current_rr.rdatas[i]) == NULL
1688		||  rdata_atom_size(parser->current_rr.rdatas[i]) < 4) {
1689			if (!parser->error_occurred)
1690				zc_error_prev_line("invalid SVCB or HTTPS rdata");
1691			return;
1692		}
1693	}
1694	/* After this point, all rdatas do have data larger than 4 bytes.
1695	 * So we may assume a uint16_t SVCB key followed by uint16_t length
1696	 * in each rdata in the remainder of this function.
1697	 */
1698	memset(paramkeys, 0, sizeof(paramkeys));
1699	/*
1700	 * In draft-ietf-dnsop-svcb-https-04 Section 7:
1701	 * In wire format, the keys are represented by their numeric values in
1702	 * network byte order, concatenated in ascending order.
1703	 *
1704	 * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is
1705	 * safe because we checked.
1706	 *
1707	 */
1708	qsort( (void *)&parser->current_rr.rdatas[2]
1709	     , parser->current_rr.rdata_count - 2
1710	     , sizeof(rdata_atom_type)
1711	     , svcparam_key_cmp
1712	     );
1713
1714	for (i = 2; i < parser->current_rr.rdata_count; i++) {
1715		assert(parser->current_rr.rdatas[i].data);
1716		assert(rdata_atom_data(parser->current_rr.rdatas[i]));
1717		assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t));
1718
1719		key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i]));
1720
1721		/* In draft-ietf-dnsop-svcb-https-04 Section 7:
1722		 *
1723		 *     Keys (...) MUST NOT appear more than once.
1724		 *
1725		 * If they key has already been seen, we have a duplicate
1726		 */
1727		if (!paramkeys[key])
1728			/* keep track of keys that are present */
1729			paramkeys[key] = 1;
1730
1731		else if (key < SVCPARAMKEY_COUNT) {
1732			if(zone_is_slave(parser->current_zone->opts))
1733				zc_warning_prev_line(
1734					"Duplicate key found: %s",
1735					svcparamkey_strs[key]);
1736			else {
1737				zc_error_prev_line(
1738					"Duplicate key found: %s",
1739					svcparamkey_strs[key]);
1740			}
1741		} else if(zone_is_slave(parser->current_zone->opts))
1742			zc_warning_prev_line(
1743					"Duplicate key found: key%d", key);
1744		else
1745			zc_error_prev_line(
1746					"Duplicate key found: key%d", key);
1747	}
1748	/* Checks when a mandatory key is present */
1749	if (!paramkeys[SVCB_KEY_MANDATORY])
1750		return;
1751
1752	size = rdata_atom_size(parser->current_rr.rdatas[2]);
1753	assert(size >= 4);
1754	mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]);
1755	mandatory_values += 2; /* skip the key type and length */
1756
1757	if (size % 2)
1758		zc_error_prev_line("mandatory rdata must be a multiple of shorts");
1759
1760	else for (i = 0; i < (size - 4)/2; i++) {
1761		key = ntohs(mandatory_values[i]);
1762
1763		if (paramkeys[key])
1764			; /* pass */
1765
1766		else if (key < SVCPARAMKEY_COUNT) {
1767			if(zone_is_slave(parser->current_zone->opts))
1768				zc_warning_prev_line("mandatory SvcParamKey: %s is missing "
1769						     "the record", svcparamkey_strs[key]);
1770			else
1771				zc_error_prev_line("mandatory SvcParamKey: %s is missing "
1772						   "the record", svcparamkey_strs[key]);
1773		} else {
1774			if(zone_is_slave(parser->current_zone->opts))
1775				zc_warning_prev_line("mandatory SvcParamKey: key%d is missing "
1776						     "the record", key);
1777			else
1778				zc_error_prev_line("mandatory SvcParamKey: key%d is missing "
1779						   "the record", key);
1780		}
1781
1782		/* In draft-ietf-dnsop-svcb-https-04 Section 8
1783		 * automatically mandatory MUST NOT appear in its own value-list
1784		 */
1785		if (key == SVCB_KEY_MANDATORY) {
1786			if(zone_is_slave(parser->current_zone->opts))
1787				zc_warning_prev_line("mandatory MUST not be included"
1788						     " as mandatory parameter");
1789			else
1790				zc_error_prev_line("mandatory MUST not be included"
1791						   " as mandatory parameter");
1792		}
1793		if (key == prev_key) {
1794			if(zone_is_slave(parser->current_zone->opts))
1795				zc_warning_prev_line("Keys inSvcParam mandatory "
1796				                   "MUST NOT appear more than once.");
1797			else
1798				zc_error_prev_line("Keys in SvcParam mandatory "
1799				                   "MUST NOT appear more than once.");
1800		}
1801		prev_key = key;
1802	}
1803}
1804
1805void
1806zadd_rdata_domain(domain_type *domain)
1807{
1808	if (parser->current_rr.rdata_count >= MAXRDATALEN) {
1809		zc_error_prev_line("too many rdata elements");
1810	} else {
1811		parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
1812			= domain;
1813		domain->usage ++; /* new reference to domain */
1814		++parser->current_rr.rdata_count;
1815	}
1816}
1817
1818void
1819parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
1820{
1821	buffer_type packet;
1822	uint16_t size;
1823	ssize_t rdata_count;
1824	ssize_t i;
1825	rdata_atom_type *rdatas;
1826
1827	if (wireformat) {
1828		size = *wireformat;
1829	} else {
1830		return;
1831	}
1832
1833	buffer_create_from(&packet, wireformat + 1, *wireformat);
1834	rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
1835						      parser->db->domains,
1836						      type,
1837						      size,
1838						      &packet,
1839						      &rdatas);
1840	if (rdata_count == -1) {
1841		zc_error_prev_line("bad unknown RDATA");
1842		return;
1843	}
1844
1845	for (i = 0; i < rdata_count; ++i) {
1846		if (rdata_atom_is_domain(type, i)) {
1847			zadd_rdata_domain(rdatas[i].domain);
1848		} else {
1849			zadd_rdata_wireformat(rdatas[i].data);
1850		}
1851	}
1852	region_recycle(parser->region, rdatas,
1853		rdata_count*sizeof(rdata_atom_type));
1854}
1855
1856
1857/*
1858 * Compares two rdata arrays.
1859 *
1860 * Returns:
1861 *
1862 *	zero if they are equal
1863 *	non-zero if not
1864 *
1865 */
1866static int
1867zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
1868{
1869	int i = 0;
1870
1871	assert(a);
1872	assert(b);
1873
1874	/* One is shorter than another */
1875	if (a->rdata_count != b->rdata_count)
1876		return 1;
1877
1878	/* Compare element by element */
1879	for (i = 0; i < a->rdata_count; ++i) {
1880		if (rdata_atom_is_domain(type, i)) {
1881			if (rdata_atom_domain(a->rdatas[i])
1882			    != rdata_atom_domain(b->rdatas[i]))
1883			{
1884				return 1;
1885			}
1886		} else if(rdata_atom_is_literal_domain(type, i)) {
1887			if (rdata_atom_size(a->rdatas[i])
1888			    != rdata_atom_size(b->rdatas[i]))
1889				return 1;
1890			if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
1891				   rdata_atom_data(b->rdatas[i]),
1892				   rdata_atom_size(a->rdatas[i])))
1893				return 1;
1894		} else {
1895			if (rdata_atom_size(a->rdatas[i])
1896			    != rdata_atom_size(b->rdatas[i]))
1897			{
1898				return 1;
1899			}
1900			if (memcmp(rdata_atom_data(a->rdatas[i]),
1901				   rdata_atom_data(b->rdatas[i]),
1902				   rdata_atom_size(a->rdatas[i])) != 0)
1903			{
1904				return 1;
1905			}
1906		}
1907	}
1908
1909	/* Otherwise they are equal */
1910	return 0;
1911}
1912
1913/*
1914 *
1915 * Opens a zone file.
1916 *
1917 * Returns:
1918 *
1919 *	- pointer to the parser structure
1920 *	- NULL on error and errno set
1921 *
1922 */
1923static int
1924zone_open(const char *filename, uint32_t ttl, uint16_t klass,
1925	  const dname_type *origin)
1926{
1927	/* Open the zone file... */
1928	if (strcmp(filename, "-") == 0) {
1929		yyin = stdin;
1930		filename = "<stdin>";
1931		warn_if_directory("zonefile from stdin", yyin, filename);
1932	} else {
1933		if (!(yyin = fopen(filename, "r"))) {
1934			return 0;
1935		}
1936		warn_if_directory("zonefile", yyin, filename);
1937	}
1938
1939	zparser_init(filename, ttl, klass, origin);
1940
1941	return 1;
1942}
1943
1944
1945void
1946set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
1947	    uint16_t index)
1948{
1949	/*
1950	 * The bits are counted from left to right, so bit #0 is the
1951	 * left most bit.
1952	 */
1953	uint8_t window = index / 256;
1954	uint8_t bit = index % 256;
1955
1956	bits[window][bit / 8] |= (1 << (7 - bit % 8));
1957}
1958
1959
1960static int
1961has_soa(domain_type* domain)
1962{
1963	rrset_type* p = NULL;
1964	if(!domain) return 0;
1965	for(p = domain->rrsets; p; p = p->next)
1966		if(rrset_rrtype(p) == TYPE_SOA)
1967			return 1;
1968	return 0;
1969}
1970
1971int
1972process_rr(void)
1973{
1974	zone_type *zone = parser->current_zone;
1975	rr_type *rr = &parser->current_rr;
1976	rrset_type *rrset;
1977	size_t max_rdlength;
1978	int i;
1979	rrtype_descriptor_type *descriptor
1980		= rrtype_descriptor_by_type(rr->type);
1981
1982	/* We only support IN class */
1983	if (rr->klass != CLASS_IN) {
1984		if(zone_is_slave(zone->opts))
1985			zc_warning_prev_line("only class IN is supported");
1986		else
1987			zc_error_prev_line("only class IN is supported");
1988		return 0;
1989	}
1990
1991	/* Make sure the maximum RDLENGTH does not exceed 65535 bytes.	*/
1992	max_rdlength = rdata_maximum_wireformat_size(
1993		descriptor, rr->rdata_count, rr->rdatas);
1994
1995	if (max_rdlength > MAX_RDLENGTH) {
1996		zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
1997		return 0;
1998	}
1999
2000	/* We cannot print invalid owner names,
2001	 * so error on that before it is used in printing other errors.
2002	 */
2003	if (rr->owner == error_domain
2004	||  domain_dname(rr->owner) == error_dname) {
2005		zc_error_prev_line("invalid owner name");
2006		return 0;
2007	}
2008
2009	/* we have the zone already */
2010	assert(zone);
2011	if (rr->type == TYPE_SOA) {
2012		if (rr->owner != zone->apex) {
2013			char s[MAXDOMAINLEN*5];
2014			snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2015			zc_error_prev_line(
2016				"SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
2017			return 0;
2018		}
2019		if(has_soa(rr->owner)) {
2020			if(zone_is_slave(zone->opts))
2021				zc_warning_prev_line("this SOA record was already encountered");
2022			else
2023				zc_error_prev_line("this SOA record was already encountered");
2024			return 0;
2025		}
2026		rr->owner->is_apex = 1;
2027	}
2028
2029	if (!domain_is_subdomain(rr->owner, zone->apex))
2030	{
2031		char s[MAXDOMAINLEN*5];
2032		snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
2033		if(zone_is_slave(zone->opts))
2034			zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2035		else
2036			zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
2037		return 0;
2038	}
2039
2040	/* Do we have this type of rrset already? */
2041	rrset = domain_find_rrset(rr->owner, zone, rr->type);
2042	if (!rrset) {
2043		rrset = (rrset_type *) region_alloc(parser->region,
2044						    sizeof(rrset_type));
2045		rrset->zone = zone;
2046		rrset->rr_count = 1;
2047		rrset->rrs = (rr_type *) region_alloc(parser->region,
2048						      sizeof(rr_type));
2049		rrset->rrs[0] = *rr;
2050
2051		/* Add it */
2052		domain_add_rrset(rr->owner, rrset);
2053	} else {
2054		rr_type* o;
2055		if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
2056			zc_warning_prev_line(
2057				"%s TTL %u does not match the TTL %u of the %s RRset",
2058				domain_to_string(rr->owner), (unsigned)rr->ttl,
2059				(unsigned)rrset->rrs[0].ttl,
2060				rrtype_to_string(rr->type));
2061		}
2062
2063		/* Search for possible duplicates... */
2064		for (i = 0; i < rrset->rr_count; i++) {
2065			if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
2066				break;
2067			}
2068		}
2069
2070		/* Discard the duplicates... */
2071		if (i < rrset->rr_count) {
2072			/* add rdatas to recycle bin. */
2073			size_t i;
2074			for (i = 0; i < rr->rdata_count; i++) {
2075				if(!rdata_atom_is_domain(rr->type, i))
2076					region_recycle(parser->region, rr->rdatas[i].data,
2077						rdata_atom_size(rr->rdatas[i])
2078						+ sizeof(uint16_t));
2079			}
2080			region_recycle(parser->region, rr->rdatas,
2081				sizeof(rdata_atom_type)*rr->rdata_count);
2082			return 0;
2083		}
2084		if(rrset->rr_count == 65535) {
2085			zc_error_prev_line("too many RRs for domain RRset");
2086			return 0;
2087		}
2088
2089		/* Add it... */
2090		o = rrset->rrs;
2091		rrset->rrs = (rr_type *) region_alloc_array(parser->region,
2092			(rrset->rr_count + 1), sizeof(rr_type));
2093		memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
2094		region_recycle(parser->region, o,
2095			(rrset->rr_count) * sizeof(rr_type));
2096		rrset->rrs[rrset->rr_count] = *rr;
2097		++rrset->rr_count;
2098	}
2099
2100	if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
2101		if(zone_is_slave(zone->opts))
2102			zc_warning_prev_line("multiple DNAMEs at the same name");
2103		else
2104			zc_error_prev_line("multiple DNAMEs at the same name");
2105	}
2106	if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
2107		if(zone_is_slave(zone->opts))
2108			zc_warning_prev_line("multiple CNAMEs at the same name");
2109		else
2110			zc_error_prev_line("multiple CNAMEs at the same name");
2111	}
2112	if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
2113	 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
2114		if(zone_is_slave(zone->opts))
2115			zc_warning_prev_line("DNAME and CNAME at the same name");
2116		else
2117			zc_error_prev_line("DNAME and CNAME at the same name");
2118	}
2119	if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
2120		domain_find_non_cname_rrset(rr->owner, zone)) {
2121		if(zone_is_slave(zone->opts))
2122			zc_warning_prev_line("CNAME and other data at the same name");
2123		else
2124			zc_error_prev_line("CNAME and other data at the same name");
2125	}
2126
2127	/* Check we have SOA */
2128	if(rr->owner == zone->apex)
2129		apex_rrset_checks(parser->db, rrset, rr->owner);
2130
2131	if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
2132		struct stat buf;
2133		startzonec = time(NULL);
2134		buf.st_size = 0;
2135		fstat(fileno(yyin), &buf);
2136		if(buf.st_size == 0) buf.st_size = 1;
2137		VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
2138			parser->current_zone->opts->name,
2139			(int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
2140	}
2141	++totalrrs;
2142	return 1;
2143}
2144
2145/*
2146 * Find rrset type for any zone
2147 */
2148static rrset_type*
2149domain_find_rrset_any(domain_type *domain, uint16_t type)
2150{
2151	rrset_type *result = domain->rrsets;
2152	while (result) {
2153		if (rrset_rrtype(result) == type) {
2154			return result;
2155		}
2156		result = result->next;
2157	}
2158	return NULL;
2159}
2160
2161/*
2162 * Check for DNAME type. Nothing is allowed below it
2163 */
2164static void
2165check_dname(zone_type* zone)
2166{
2167	domain_type* domain;
2168	for(domain = zone->apex; domain && domain_is_subdomain(domain,
2169		zone->apex); domain=domain_next(domain))
2170	{
2171		if(domain->is_existing) {
2172			/* there may not be DNAMEs above it */
2173			domain_type* parent = domain->parent;
2174#ifdef NSEC3
2175			if(domain_has_only_NSEC3(domain, NULL))
2176				continue;
2177#endif
2178			while(parent) {
2179				if(domain_find_rrset_any(parent, TYPE_DNAME)) {
2180					zc_error("While checking node %s,",
2181						domain_to_string(domain));
2182					zc_error("DNAME at %s has data below it. "
2183						"This is not allowed (rfc 2672).",
2184						domain_to_string(parent));
2185					return;
2186				}
2187				parent = parent->parent;
2188			}
2189		}
2190	}
2191}
2192
2193/*
2194 * Reads the specified zone into the memory
2195 * nsd_options can be NULL if no config file is passed.
2196 */
2197unsigned int
2198zonec_read(const char* name, const char* zonefile, zone_type* zone)
2199{
2200	const dname_type *dname;
2201
2202	totalrrs = 0;
2203	startzonec = time(NULL);
2204	parser->errors = 0;
2205
2206	dname = dname_parse(parser->rr_region, name);
2207	if (!dname) {
2208		zc_error("incorrect zone name '%s'", name);
2209		return 1;
2210	}
2211
2212	/* Open the zone file */
2213	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
2214		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
2215		return 1;
2216	}
2217	parser->current_zone = zone;
2218
2219	/* Parse and process all RRs.  */
2220	yyparse();
2221
2222	/* remove origin if it was unused */
2223	if(parser->origin != error_domain)
2224		domain_table_deldomain(parser->db, parser->origin);
2225	/* rr_region has been emptied by now */
2226	dname = dname_parse(parser->rr_region, name);
2227
2228	/* check if zone file contained a correct SOA record */
2229	if (!parser->current_zone) {
2230		zc_error("zone configured as '%s' has no content.", name);
2231	} else if(!parser->current_zone->soa_rrset ||
2232		parser->current_zone->soa_rrset->rr_count == 0) {
2233		zc_error("zone configured as '%s' has no SOA record.", name);
2234	} else if(dname_compare(domain_dname(
2235		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
2236		zc_error("zone configured as '%s', but SOA has owner '%s'.",
2237			name, domain_to_string(
2238			parser->current_zone->soa_rrset->rrs[0].owner));
2239	}
2240	region_free_all(parser->rr_region);
2241
2242	parser_flush();
2243	fclose(yyin);
2244	if(!zone_is_slave(zone->opts))
2245		check_dname(zone);
2246
2247	parser->filename = NULL;
2248	return parser->errors;
2249}
2250
2251
2252/*
2253 * setup parse
2254 */
2255void
2256zonec_setup_parser(namedb_type* db)
2257{
2258	region_type* rr_region = region_create(xalloc, free);
2259	parser = zparser_create(db->region, rr_region, db);
2260	assert(parser);
2261	/* Unique pointers used to mark errors.	 */
2262	error_dname = (dname_type *) region_alloc(db->region, 1);
2263	error_domain = (domain_type *) region_alloc(db->region, 1);
2264	/* Open the network database */
2265	setprotoent(1);
2266	setservent(1);
2267}
2268
2269/** desetup parse */
2270void
2271zonec_desetup_parser(void)
2272{
2273	if(parser) {
2274		endservent();
2275		endprotoent();
2276		region_destroy(parser->rr_region);
2277		/* removed when parser->region(=db->region) is destroyed:
2278		 * region_recycle(parser->region, (void*)error_dname, 1);
2279		 * region_recycle(parser->region, (void*)error_domain, 1); */
2280		/* clear memory for exit, but this is not portable to
2281		 * other versions of lex. yylex_destroy(); */
2282#ifdef MEMCLEAN /* OS collects memory pages */
2283		yylex_destroy();
2284#endif
2285	}
2286}
2287
2288static domain_table_type* orig_domains = NULL;
2289static region_type* orig_region = NULL;
2290static region_type* orig_dbregion = NULL;
2291
2292/** setup for string parse */
2293void
2294zonec_setup_string_parser(region_type* region, domain_table_type* domains)
2295{
2296	assert(parser); /* global parser must be setup */
2297	orig_domains = parser->db->domains;
2298	orig_region = parser->region;
2299	orig_dbregion = parser->db->region;
2300	parser->region = region;
2301	parser->db->region = region;
2302	parser->db->domains = domains;
2303	zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
2304}
2305
2306/** desetup string parse */
2307void
2308zonec_desetup_string_parser(void)
2309{
2310	parser->region = orig_region;
2311	parser->db->domains = orig_domains;
2312	parser->db->region = orig_dbregion;
2313}
2314
2315/** parse a string into temporary storage */
2316int
2317zonec_parse_string(region_type* region, domain_table_type* domains,
2318	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
2319{
2320	int errors;
2321	zonec_setup_string_parser(region, domains);
2322	parser->current_zone = zone;
2323	parser->errors = 0;
2324	totalrrs = 0;
2325	startzonec = time(NULL)+100000; /* disable */
2326	parser_push_stringbuf(str);
2327	yyparse();
2328	parser_pop_stringbuf();
2329	errors = parser->errors;
2330	*num_rrs = totalrrs;
2331	if(*num_rrs == 0)
2332		*parsed = NULL;
2333	else	*parsed = parser->prev_dname;
2334	/* remove origin if it was not used during the parse */
2335	if(parser->origin != error_domain)
2336		domain_table_deldomain(parser->db, parser->origin);
2337	region_free_all(parser->rr_region);
2338	zonec_desetup_string_parser();
2339	parser_flush();
2340	return errors;
2341}
2342
2343/** check SSHFP type for failures and emit warnings */
2344void check_sshfp(void)
2345{
2346	uint8_t hash;
2347	uint16_t size;
2348	if(parser->current_rr.rdata_count < 3)
2349		return; /* cannot check it, too few rdata elements */
2350	if(!parser->current_rr.rdatas[0].data ||
2351		!parser->current_rr.rdatas[1].data ||
2352		!parser->current_rr.rdatas[2].data ||
2353		!parser->current_rr.owner)
2354		return; /* cannot check, NULLs (due to earlier errors) */
2355	if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
2356		return; /* wrong size of the hash type rdata element */
2357	hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
2358	size = rdata_atom_size(parser->current_rr.rdatas[2]);
2359	if(hash == 1 && size != 20) {
2360		zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
2361			"wrong length, %d bytes, should be 20",
2362			domain_to_string(parser->current_rr.owner),
2363			(int)size);
2364	} else if(hash == 2 && size != 32) {
2365		zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
2366			"wrong length, %d bytes, should be 32",
2367			domain_to_string(parser->current_rr.owner),
2368			(int)size);
2369	}
2370}
2371
2372void
2373apex_rrset_checks(namedb_type* db, rrset_type* rrset, domain_type* domain)
2374{
2375	uint32_t soa_minimum;
2376	unsigned i;
2377	zone_type* zone = rrset->zone;
2378	assert(domain == zone->apex);
2379	(void)domain;
2380	if (rrset_rrtype(rrset) == TYPE_SOA) {
2381		zone->soa_rrset = rrset;
2382
2383		/* BUG #103 add another soa with a tweaked ttl */
2384		if(zone->soa_nx_rrset == 0) {
2385			zone->soa_nx_rrset = region_alloc(db->region,
2386				sizeof(rrset_type));
2387			zone->soa_nx_rrset->rr_count = 1;
2388			zone->soa_nx_rrset->next = 0;
2389			zone->soa_nx_rrset->zone = zone;
2390			zone->soa_nx_rrset->rrs = region_alloc(db->region,
2391				sizeof(rr_type));
2392		}
2393		memcpy(zone->soa_nx_rrset->rrs, rrset->rrs, sizeof(rr_type));
2394
2395		/* check the ttl and MINIMUM value and set accordingly */
2396		memcpy(&soa_minimum, rdata_atom_data(rrset->rrs->rdatas[6]),
2397				rdata_atom_size(rrset->rrs->rdatas[6]));
2398		if (rrset->rrs->ttl > ntohl(soa_minimum)) {
2399			zone->soa_nx_rrset->rrs[0].ttl = ntohl(soa_minimum);
2400		}
2401	} else if (rrset_rrtype(rrset) == TYPE_NS) {
2402		zone->ns_rrset = rrset;
2403	} else if (rrset_rrtype(rrset) == TYPE_RRSIG) {
2404		for (i = 0; i < rrset->rr_count; ++i) {
2405			if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY){
2406				zone->is_secure = 1;
2407				break;
2408			}
2409		}
2410	}
2411}
2412