"Fossies" - the Fresh Open Source Software Archive

Member "nsd-4.3.7/zonec.c" (22 Jul 2021, 56684 Bytes) of package /linux/misc/dns/nsd-4.3.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zonec.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.3.6_vs_4.3.7.

    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 
   52 const dname_type *error_dname;
   53 domain_type *error_domain;
   54 
   55 static time_t startzonec = 0;
   56 static long int totalrrs = 0;
   57 
   58 extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE];
   59 extern 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  */
   66 static uint16_t *
   67 alloc_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 
   74 uint16_t *
   75 alloc_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  */
   86 uint16_t *
   87 zparser_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 */
  129 uint16_t *
  130 zparser_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 
  170 uint16_t *
  171 zparser_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 
  187 uint16_t *
  188 zparser_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 
  250 uint16_t *
  251 zparser_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 
  267 uint16_t *
  268 zparser_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 
  286 uint16_t *
  287 zparser_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 
  302 uint16_t *
  303 zparser_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 
  318 uint16_t *
  319 zparser_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 
  339 uint16_t *
  340 zparser_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 
  361 uint16_t *
  362 zparser_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 
  375 uint16_t *
  376 zparser_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 
  390 uint16_t *
  391 zparser_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 
  458 static uint16_t *
  459 zparser_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 
  482 static uint16_t *
  483 zparser_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 
  507 uint16_t *
  508 zparser_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 
  547 uint16_t *
  548 zparser_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] */
  566 uint16_t *
  567 zparser_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] */
  579 uint16_t *
  580 zparser_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 
  609 uint16_t *
  610 zparser_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 
  621 uint16_t *
  622 zparser_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 
  641 uint16_t *
  642 zparser_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 
  661 uint16_t *
  662 zparser_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 
  676 uint16_t *
  677 zparser_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  */
  698 uint16_t *
  699 zparser_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 
  758 static uint16_t
  759 svcbparam_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("ech")-1:
  802         if (!strncmp(key, "ech", sizeof("ech")-1))
  803             return SVCB_KEY_ECH;
  804         break;
  805     default:
  806         break;
  807     }
  808     if (key_len > sizeof(buf) - 1)
  809         zc_error_prev_line("Unknown SvcParamKey");
  810     else {
  811         memcpy(buf, key, key_len);
  812         buf[key_len] = 0;
  813         zc_error_prev_line("Unknown SvcParamKey: %s", buf);
  814     }
  815     /* Although the returned value might be used by the caller,
  816      * the parser has erred, so the zone will not be loaded.
  817      */
  818     return -1;
  819 }
  820 
  821 static uint16_t *
  822 zparser_conv_svcbparam_port_value(region_type *region, const char *val)
  823 {
  824     unsigned long int port;
  825     char *endptr;
  826     uint16_t *r;
  827 
  828     port = strtoul(val, &endptr, 10);
  829     if (endptr > val    /* digits seen */
  830     && *endptr == 0     /* no non-digit chars after digits */
  831     &&  port <= 65535) {    /* no overflow */
  832 
  833         r = alloc_rdata(region, 3 * sizeof(uint16_t));
  834         r[1] = htons(SVCB_KEY_PORT);
  835         r[2] = htons(sizeof(uint16_t));
  836         r[3] = htons(port);
  837         return r;
  838     }
  839     zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val);
  840     return NULL;
  841 }
  842 
  843 static uint16_t *
  844 zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val)
  845 {
  846     uint16_t *r;
  847     int count;
  848     char ip_str[INET_ADDRSTRLEN+1];
  849     char *next_ip_str;
  850     uint32_t *ip_wire_dst;
  851     size_t i;
  852 
  853     for (i = 0, count = 1; val[i]; i++) {
  854         if (val[i] == ',')
  855             count += 1;
  856         if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
  857             zc_error_prev_line("Too many IPV4 addresses in ipv4hint");
  858             return NULL;
  859         }
  860     }
  861 
  862     /* count == number of comma's in val + 1, so the actual number of IPv4
  863      * addresses in val
  864      */
  865     r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN * count);
  866     r[1] = htons(SVCB_KEY_IPV4HINT);
  867     r[2] = htons(IP4ADDRLEN * count);
  868     ip_wire_dst = (void *)&r[3];
  869 
  870     while (count) {
  871         if (!(next_ip_str = strchr(val, ','))) {
  872             if (inet_pton(AF_INET, val, ip_wire_dst) != 1)
  873                 break;
  874 
  875             assert(count == 1);
  876 
  877         } else if (next_ip_str - val >= (int)sizeof(ip_str))
  878             break;
  879 
  880         else {
  881             memcpy(ip_str, val, next_ip_str - val);
  882             ip_str[next_ip_str - val] = 0;
  883             if (inet_pton(AF_INET, ip_str, ip_wire_dst) != 1) {
  884                 val = ip_str; /* to use in error reporting below */
  885                 break;
  886             }
  887 
  888             val = next_ip_str + 1;
  889         }
  890         ip_wire_dst++;
  891         count--;
  892     }
  893     if (count)
  894         zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val);
  895 
  896     return r;
  897 }
  898 
  899 static uint16_t *
  900 zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val)
  901 {
  902     uint16_t *r;
  903     int i, count;
  904     char ip6_str[INET6_ADDRSTRLEN+1];
  905     char *next_ip6_str;
  906     uint8_t *ipv6_wire_dst;
  907 
  908     for (i = 0, count = 1; val[i]; i++) {
  909         if (val[i] == ',')
  910             count += 1;
  911         if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
  912             zc_error_prev_line("Too many IPV6 addresses in ipv6hint");
  913             return NULL;
  914         }
  915     }
  916 
  917     /* count == number of comma's in val + 1 
  918      * so actually the number of IPv6 addresses in val
  919      */
  920     r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN * count);
  921     r[1] = htons(SVCB_KEY_IPV6HINT);
  922     r[2] = htons(IP6ADDRLEN * count);
  923     ipv6_wire_dst = (void *)&r[3];
  924 
  925     while (count) {
  926         if (!(next_ip6_str = strchr(val, ','))) {
  927             if ((inet_pton(AF_INET6, val, ipv6_wire_dst) != 1))
  928                 break;
  929 
  930             assert(count == 1);
  931 
  932         } else if (next_ip6_str - val >= (int)sizeof(ip6_str))
  933             break;
  934 
  935         else {
  936             memcpy(ip6_str, val, next_ip6_str - val);
  937             ip6_str[next_ip6_str - val] = 0;
  938             if (inet_pton(AF_INET6, ip6_str, ipv6_wire_dst) != 1) {
  939                 val = ip6_str; /* for error reporting below */
  940                 break;
  941             }
  942 
  943             val = next_ip6_str + 1; /* skip the comma */
  944         }
  945         ipv6_wire_dst += IP6ADDRLEN;
  946         count--;
  947     }
  948     if (count)
  949         zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val);
  950 
  951     return r;
  952 }
  953 
  954 static int
  955 network_uint16_cmp(const void *a, const void *b)
  956 {
  957     return ((int)read_uint16(a)) - ((int)read_uint16(b));
  958 }
  959 
  960 static uint16_t *
  961 zparser_conv_svcbparam_mandatory_value(region_type *region,
  962         const char *val, size_t val_len)
  963 {
  964     uint16_t *r;
  965     size_t i, count;
  966     char* next_key;
  967     uint16_t* key_dst;
  968 
  969     for (i = 0, count = 1; val[i]; i++) {
  970         if (val[i] == ',')
  971             count += 1;
  972         if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) {
  973             zc_error_prev_line("Too many keys in mandatory");
  974             return NULL;
  975         }
  976     }
  977 
  978     r = alloc_rdata(region, (2 + count) * sizeof(uint16_t));
  979     r[1] = htons(SVCB_KEY_MANDATORY);
  980     r[2] = htons(sizeof(uint16_t) * count);
  981     key_dst = (void *)&r[3];
  982 
  983     for(;;) {
  984         if (!(next_key = strchr(val, ','))) {
  985             *key_dst = htons(svcbparam_lookup_key(val, val_len));
  986             break;  
  987         } else {
  988             *key_dst = htons(svcbparam_lookup_key(val, next_key - val));
  989         }
  990 
  991         val_len -= next_key - val + 1;
  992         val = next_key + 1; /* skip the comma */
  993         key_dst += 1;
  994     }
  995 
  996     /* In draft-ietf-dnsop-svcb-https-04 Section 7:
  997      *
  998      *     In wire format, the keys are represented by their numeric
  999      *     values in network byte order, concatenated in ascending order.
 1000      */
 1001     qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp);
 1002 
 1003     return r;
 1004 }
 1005 
 1006 static uint16_t *
 1007 zparser_conv_svcbparam_ech_value(region_type *region, const char *b64)
 1008 {
 1009     uint8_t buffer[B64BUFSIZE];
 1010     uint16_t *r = NULL;
 1011     int wire_len;
 1012 
 1013     if(strcmp(b64, "0") == 0) {
 1014         /* single 0 represents empty buffer */
 1015         return alloc_rdata(region, 0);
 1016     }
 1017     wire_len = b64_pton(b64, buffer, B64BUFSIZE);
 1018     if (wire_len == -1) {
 1019         zc_error_prev_line("invalid base64 data in ech");
 1020     } else {
 1021         r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len);
 1022         r[1] = htons(SVCB_KEY_ECH);
 1023         r[2] = htons(wire_len);
 1024         memcpy(&r[3], buffer, wire_len);
 1025     }
 1026 
 1027     return r;
 1028 }
 1029 
 1030 static const char* parse_alpn_next_unescaped_comma(const char *val)
 1031 {
 1032     while (*val) {
 1033         /* Only return when the comma is not escaped*/
 1034         if (*val == '\\'){
 1035             ++val;
 1036             if (!*val)
 1037                 break;
 1038         } else if (*val == ',')
 1039                 return val;
 1040 
 1041         val++;
 1042     }
 1043     return NULL;
 1044 }
 1045 
 1046 static size_t
 1047 parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len)
 1048 {
 1049     uint8_t *orig_dst = dst;
 1050 
 1051     while (len) {
 1052         if (*src == '\\') {
 1053             src++;
 1054             len--;
 1055             if (!len)
 1056                 break;
 1057         }
 1058         *dst++ = *src++;
 1059         len--;
 1060     }
 1061     return (size_t)(dst - orig_dst);
 1062 }
 1063 
 1064 static uint16_t *
 1065 zparser_conv_svcbparam_alpn_value(region_type *region,
 1066         const char *val, size_t val_len)
 1067 {
 1068     uint8_t     unescaped_dst[65536];
 1069     uint8_t    *dst = unescaped_dst;
 1070     const char *next_str;
 1071     size_t      str_len;
 1072     size_t      dst_len;
 1073     uint16_t   *r = NULL;
 1074 
 1075     if (val_len > sizeof(unescaped_dst)) {
 1076         zc_error_prev_line("invalid alpn");
 1077         return r;
 1078     }
 1079     while (val_len) {
 1080         size_t dst_len;
 1081 
 1082         str_len = (next_str = parse_alpn_next_unescaped_comma(val))
 1083                 ? (size_t)(next_str - val) : val_len;
 1084 
 1085         if (str_len > 255) {
 1086             zc_error_prev_line("alpn strings need to be"
 1087                        " smaller than 255 chars");
 1088             return r;
 1089         }
 1090         dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len);
 1091         *dst++ = dst_len;
 1092          dst  += dst_len;
 1093 
 1094         if (!next_str)
 1095             break;
 1096 
 1097         /* skip the comma for the next iteration */
 1098         val_len -= next_str - val + 1;
 1099         val = next_str + 1;
 1100     }
 1101     dst_len = dst - unescaped_dst;
 1102     r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len);
 1103     r[1] = htons(SVCB_KEY_ALPN);
 1104     r[2] = htons(dst_len);
 1105     memcpy(&r[3], unescaped_dst, dst_len);
 1106     return r;
 1107 }
 1108 
 1109 static uint16_t *
 1110 zparser_conv_svcbparam_key_value(region_type *region,
 1111     const char *key, size_t key_len, const char *val, size_t val_len)
 1112 {
 1113     uint16_t svcparamkey = svcbparam_lookup_key(key, key_len);
 1114     uint16_t *r;
 1115 
 1116     switch (svcparamkey) {
 1117     case SVCB_KEY_PORT:
 1118         return zparser_conv_svcbparam_port_value(region, val);
 1119     case SVCB_KEY_IPV4HINT:
 1120         return zparser_conv_svcbparam_ipv4hint_value(region, val);
 1121     case SVCB_KEY_IPV6HINT:
 1122         return zparser_conv_svcbparam_ipv6hint_value(region, val);
 1123     case SVCB_KEY_MANDATORY:
 1124         return zparser_conv_svcbparam_mandatory_value(region, val, val_len);
 1125     case SVCB_KEY_NO_DEFAULT_ALPN:
 1126         if(zone_is_slave(parser->current_zone->opts))
 1127             zc_warning_prev_line("no-default-alpn should not have a value");
 1128         else
 1129             zc_error_prev_line("no-default-alpn should not have a value");
 1130         break;
 1131     case SVCB_KEY_ECH:
 1132         return zparser_conv_svcbparam_ech_value(region, val);
 1133     case SVCB_KEY_ALPN:
 1134         return zparser_conv_svcbparam_alpn_value(region, val, val_len);
 1135     default:
 1136         break;
 1137     }
 1138     r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len);
 1139     r[1] = htons(svcparamkey);
 1140     r[2] = htons(val_len);
 1141     memcpy(r + 3, val, val_len);
 1142     return r;
 1143 }
 1144 
 1145 uint16_t *
 1146 zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len
 1147                                           , const char *val, size_t val_len)
 1148 {
 1149     const char *eq;
 1150     uint16_t *r;
 1151     uint16_t svcparamkey;
 1152 
 1153     /* Form <key>="<value>" (or at least with quoted value) */
 1154     if (val && val_len) {
 1155         /* Does key end with '=' */
 1156         if (key_len && key[key_len - 1] == '=')
 1157             return zparser_conv_svcbparam_key_value(
 1158                 region, key, key_len - 1, val, val_len);
 1159 
 1160         zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\""
 1161                           , key, val);
 1162     }
 1163     assert(val == NULL);
 1164     if ((eq = memchr(key, '=', key_len))) {
 1165         size_t new_key_len = eq - key;
 1166 
 1167         if (key_len - new_key_len - 1 > 0)
 1168             return zparser_conv_svcbparam_key_value(region,
 1169                 key, new_key_len, eq+1, key_len - new_key_len - 1);
 1170         key_len = new_key_len;
 1171     }
 1172     /* Some SvcParamKeys require values */
 1173     svcparamkey = svcbparam_lookup_key(key, key_len);
 1174     switch (svcparamkey) {
 1175         case SVCB_KEY_MANDATORY:
 1176         case SVCB_KEY_ALPN:
 1177         case SVCB_KEY_PORT:
 1178         case SVCB_KEY_IPV4HINT:
 1179         case SVCB_KEY_IPV6HINT:
 1180             if(zone_is_slave(parser->current_zone->opts))
 1181                 zc_warning_prev_line("value expected for SvcParam: %s", key);
 1182             else
 1183                 zc_error_prev_line("value expected for SvcParam: %s", key);
 1184             break;
 1185         default:
 1186             break;
 1187     }
 1188     /* SvcParam is only a SvcParamKey */
 1189     r = alloc_rdata(region, 2 * sizeof(uint16_t));
 1190     r[1] = htons(svcparamkey);
 1191     r[2] = 0;
 1192     return r;
 1193 }
 1194 
 1195 /* Parse an int terminated in the specified range. */
 1196 static int
 1197 parse_int(const char *str,
 1198       char **end,
 1199       int *result,
 1200       const char *name,
 1201       int min,
 1202       int max)
 1203 {
 1204     *result = (int) strtol(str, end, 10);
 1205     if (*result < min || *result > max) {
 1206         zc_error_prev_line("%s must be within the range [%d .. %d]",
 1207                    name,
 1208                    min,
 1209                    max);
 1210         return 0;
 1211     } else {
 1212         return 1;
 1213     }
 1214 }
 1215 
 1216 /* RFC1876 conversion routines */
 1217 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
 1218                 1000000,10000000,100000000,1000000000};
 1219 
 1220 /*
 1221  * Converts ascii size/precision X * 10**Y(cm) to 0xXY.
 1222  * Sets the given pointer to the last used character.
 1223  *
 1224  */
 1225 static uint8_t
 1226 precsize_aton (char *cp, char **endptr)
 1227 {
 1228     unsigned int mval = 0, cmval = 0;
 1229     uint8_t retval = 0;
 1230     int exponent;
 1231     int mantissa;
 1232 
 1233     while (isdigit((unsigned char)*cp))
 1234         mval = mval * 10 + hexdigit_to_int(*cp++);
 1235 
 1236     if (*cp == '.') {   /* centimeters */
 1237         cp++;
 1238         if (isdigit((unsigned char)*cp)) {
 1239             cmval = hexdigit_to_int(*cp++) * 10;
 1240             if (isdigit((unsigned char)*cp)) {
 1241                 cmval += hexdigit_to_int(*cp++);
 1242             }
 1243         }
 1244     }
 1245 
 1246     if(mval >= poweroften[7]) {
 1247         assert(poweroften[7] != 0);
 1248         /* integer overflow possible for *100 */
 1249         mantissa = mval / poweroften[7];
 1250         exponent = 9; /* max */
 1251     }
 1252     else {
 1253         cmval = (mval * 100) + cmval;
 1254 
 1255         for (exponent = 0; exponent < 9; exponent++)
 1256             if (cmval < poweroften[exponent+1])
 1257                 break;
 1258 
 1259         assert(poweroften[exponent] != 0);
 1260         mantissa = cmval / poweroften[exponent];
 1261     }
 1262     if (mantissa > 9)
 1263         mantissa = 9;
 1264 
 1265     retval = (mantissa << 4) | exponent;
 1266 
 1267     if (*cp == 'm') cp++;
 1268 
 1269     *endptr = cp;
 1270 
 1271     return (retval);
 1272 }
 1273 
 1274 /*
 1275  * Parses a specific part of rdata.
 1276  *
 1277  * Returns:
 1278  *
 1279  *  number of elements parsed
 1280  *  zero on error
 1281  *
 1282  */
 1283 uint16_t *
 1284 zparser_conv_loc(region_type *region, char *str)
 1285 {
 1286     uint16_t *r;
 1287     uint32_t *p;
 1288     int i;
 1289     int deg, min, secs; /* Secs is stored times 1000.  */
 1290     uint32_t lat = 0, lon = 0, alt = 0;
 1291     /* encoded defaults: version=0 sz=1m hp=10000m vp=10m */
 1292     uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13};
 1293     char *start;
 1294     double d;
 1295 
 1296     for(;;) {
 1297         deg = min = secs = 0;
 1298 
 1299         /* Degrees */
 1300         if (*str == '\0') {
 1301             zc_error_prev_line("unexpected end of LOC data");
 1302             return NULL;
 1303         }
 1304 
 1305         if (!parse_int(str, &str, &deg, "degrees", 0, 180))
 1306             return NULL;
 1307         if (!isspace((unsigned char)*str)) {
 1308             zc_error_prev_line("space expected after degrees");
 1309             return NULL;
 1310         }
 1311         ++str;
 1312 
 1313         /* Minutes? */
 1314         if (isdigit((unsigned char)*str)) {
 1315             if (!parse_int(str, &str, &min, "minutes", 0, 60))
 1316                 return NULL;
 1317             if (!isspace((unsigned char)*str)) {
 1318                 zc_error_prev_line("space expected after minutes");
 1319                 return NULL;
 1320             }
 1321             ++str;
 1322         }
 1323 
 1324         /* Seconds? */
 1325         if (isdigit((unsigned char)*str)) {
 1326             start = str;
 1327             if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
 1328                 return NULL;
 1329             }
 1330 
 1331             if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) {
 1332                 return NULL;
 1333             }
 1334 
 1335             if (!isspace((unsigned char)*str)) {
 1336                 zc_error_prev_line("space expected after seconds");
 1337                 return NULL;
 1338             }
 1339             /* No need for precision specifiers, it's a double */
 1340             if (sscanf(start, "%lf", &d) != 1) {
 1341                 zc_error_prev_line("error parsing seconds");
 1342             }
 1343 
 1344             if (d < 0.0 || d > 60.0) {
 1345                 zc_error_prev_line("seconds not in range 0.0 .. 60.0");
 1346             }
 1347 
 1348             secs = (int) (d * 1000.0 + 0.5);
 1349             ++str;
 1350         }
 1351 
 1352         switch(*str) {
 1353         case 'N':
 1354         case 'n':
 1355             lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
 1356             break;
 1357         case 'E':
 1358         case 'e':
 1359             lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs);
 1360             break;
 1361         case 'S':
 1362         case 's':
 1363             lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
 1364             break;
 1365         case 'W':
 1366         case 'w':
 1367             lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs);
 1368             break;
 1369         default:
 1370             zc_error_prev_line("invalid latitude/longtitude: '%c'", *str);
 1371             return NULL;
 1372         }
 1373         ++str;
 1374 
 1375         if (lat != 0 && lon != 0)
 1376             break;
 1377 
 1378         if (!isspace((unsigned char)*str)) {
 1379             zc_error_prev_line("space expected after latitude/longitude");
 1380             return NULL;
 1381         }
 1382         ++str;
 1383     }
 1384 
 1385     /* Altitude */
 1386     if (*str == '\0') {
 1387         zc_error_prev_line("unexpected end of LOC data");
 1388         return NULL;
 1389     }
 1390 
 1391     if (!isspace((unsigned char)*str)) {
 1392         zc_error_prev_line("space expected before altitude");
 1393         return NULL;
 1394     }
 1395     ++str;
 1396 
 1397     start = str;
 1398 
 1399     /* Sign */
 1400     if (*str == '+' || *str == '-') {
 1401         ++str;
 1402     }
 1403 
 1404     /* Meters of altitude... */
 1405     if(strtol(str, &str, 10) == LONG_MAX) {
 1406         zc_error_prev_line("altitude too large, number overflow");
 1407         return NULL;
 1408     }
 1409     switch(*str) {
 1410     case ' ':
 1411     case '\0':
 1412     case 'm':
 1413         break;
 1414     case '.':
 1415         if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
 1416             return NULL;
 1417         }
 1418         if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
 1419             zc_error_prev_line("altitude fraction must be a number");
 1420             return NULL;
 1421         }
 1422         break;
 1423     default:
 1424         zc_error_prev_line("altitude must be expressed in meters");
 1425         return NULL;
 1426     }
 1427     if (!isspace((unsigned char)*str) && *str != '\0')
 1428         ++str;
 1429 
 1430     if (sscanf(start, "%lf", &d) != 1) {
 1431         zc_error_prev_line("error parsing altitude");
 1432     }
 1433 
 1434     alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
 1435 
 1436     if (!isspace((unsigned char)*str) && *str != '\0') {
 1437         zc_error_prev_line("unexpected character after altitude");
 1438         return NULL;
 1439     }
 1440 
 1441     /* Now parse size, horizontal precision and vertical precision if any */
 1442     for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
 1443         vszhpvp[i] = precsize_aton(str + 1, &str);
 1444 
 1445         if (!isspace((unsigned char)*str) && *str != '\0') {
 1446             zc_error_prev_line("invalid size or precision");
 1447             return NULL;
 1448         }
 1449     }
 1450 
 1451     /* Allocate required space... */
 1452     r = alloc_rdata(region, 16);
 1453     p = (uint32_t *) (r + 1);
 1454 
 1455     memmove(p, vszhpvp, 4);
 1456     write_uint32(p + 1, lat);
 1457     write_uint32(p + 2, lon);
 1458     write_uint32(p + 3, alt);
 1459 
 1460     return r;
 1461 }
 1462 
 1463 /*
 1464  * Convert an APL RR RDATA element.
 1465  */
 1466 uint16_t *
 1467 zparser_conv_apl_rdata(region_type *region, char *str)
 1468 {
 1469     int negated = 0;
 1470     uint16_t address_family;
 1471     uint8_t prefix;
 1472     uint8_t maximum_prefix;
 1473     uint8_t length;
 1474     uint8_t address[IP6ADDRLEN];
 1475     char *colon = strchr(str, ':');
 1476     char *slash = strchr(str, '/');
 1477     int af;
 1478     int rc;
 1479     uint16_t rdlength;
 1480     uint16_t *r;
 1481     uint8_t *t;
 1482     char *end;
 1483     long p;
 1484 
 1485     if (!colon) {
 1486         zc_error("address family separator is missing");
 1487         return NULL;
 1488     }
 1489     if (!slash) {
 1490         zc_error("prefix separator is missing");
 1491         return NULL;
 1492     }
 1493 
 1494     *colon = '\0';
 1495     *slash = '\0';
 1496 
 1497     if (*str == '!') {
 1498         negated = 1;
 1499         ++str;
 1500     }
 1501 
 1502     if (strcmp(str, "1") == 0) {
 1503         address_family = htons(1);
 1504         af = AF_INET;
 1505         length = sizeof(in_addr_t);
 1506         maximum_prefix = length * 8;
 1507     } else if (strcmp(str, "2") == 0) {
 1508         address_family = htons(2);
 1509         af = AF_INET6;
 1510         length = IP6ADDRLEN;
 1511         maximum_prefix = length * 8;
 1512     } else {
 1513         zc_error("invalid address family '%s'", str);
 1514         return NULL;
 1515     }
 1516 
 1517     rc = inet_pton(af, colon + 1, address);
 1518     if (rc == 0) {
 1519         zc_error("invalid address '%s'", colon + 1);
 1520         return NULL;
 1521     } else if (rc == -1) {
 1522         zc_error("inet_pton failed: %s", strerror(errno));
 1523         return NULL;
 1524     }
 1525 
 1526     /* Strip trailing zero octets.  */
 1527     while (length > 0 && address[length - 1] == 0)
 1528         --length;
 1529 
 1530 
 1531     p = strtol(slash + 1, &end, 10);
 1532     if (p < 0 || p > maximum_prefix) {
 1533         zc_error("prefix not in the range 0 .. %d", maximum_prefix);
 1534         return NULL;
 1535     } else if (*end != '\0') {
 1536         zc_error("invalid prefix '%s'", slash + 1);
 1537         return NULL;
 1538     }
 1539     prefix = (uint8_t) p;
 1540 
 1541     rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length)
 1542             + length);
 1543     r = alloc_rdata(region, rdlength);
 1544     t = (uint8_t *) (r + 1);
 1545 
 1546     memcpy(t, &address_family, sizeof(address_family));
 1547     t += sizeof(address_family);
 1548     memcpy(t, &prefix, sizeof(prefix));
 1549     t += sizeof(prefix);
 1550     memcpy(t, &length, sizeof(length));
 1551     if (negated) {
 1552         *t |= APL_NEGATION_MASK;
 1553     }
 1554     t += sizeof(length);
 1555     memcpy(t, address, length);
 1556 
 1557     return r;
 1558 }
 1559 
 1560 /*
 1561  * Below some function that also convert but not to wireformat
 1562  * but to "normal" (int,long,char) types
 1563  */
 1564 
 1565 uint32_t
 1566 zparser_ttl2int(const char *ttlstr, int* error)
 1567 {
 1568     /* convert a ttl value to a integer
 1569      * return the ttl in a int
 1570      * -1 on error
 1571      */
 1572 
 1573     uint32_t ttl;
 1574     const char *t;
 1575 
 1576     ttl = strtottl(ttlstr, &t);
 1577     if (*t != 0) {
 1578         zc_error_prev_line("invalid TTL value: %s",ttlstr);
 1579         *error = 1;
 1580     }
 1581 
 1582     return ttl;
 1583 }
 1584 
 1585 
 1586 void
 1587 zadd_rdata_wireformat(uint16_t *data)
 1588 {
 1589     if (parser->current_rr.rdata_count >= MAXRDATALEN) {
 1590         zc_error_prev_line("too many rdata elements");
 1591     } else {
 1592         parser->current_rr.rdatas[parser->current_rr.rdata_count].data
 1593             = data;
 1594         ++parser->current_rr.rdata_count;
 1595     }
 1596 }
 1597 
 1598 /**
 1599  * Used for TXT RR's to grow with undefined number of strings.
 1600  */
 1601 void
 1602 zadd_rdata_txt_wireformat(uint16_t *data, int first)
 1603 {
 1604     rdata_atom_type *rd;
 1605     if (parser->current_rr.rdata_count >= MAXRDATALEN) {
 1606         zc_error_prev_line("too many rdata txt elements");
 1607         return;
 1608     }
 1609     
 1610     /* First STR in str_seq, allocate 65K in first unused rdata
 1611      * else find last used rdata */
 1612     if (first) {
 1613         rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count];
 1614         if ((rd->data = (uint16_t *) region_alloc(parser->rr_region,
 1615             sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) {
 1616             zc_error_prev_line("Could not allocate memory for TXT RR");
 1617             return;
 1618         }
 1619         parser->current_rr.rdata_count++;
 1620         rd->data[0] = 0;
 1621     }
 1622     else
 1623         rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
 1624     
 1625     if ((size_t)rd->data[0] + (size_t)data[0] > 65535) {
 1626         zc_error_prev_line("too large rdata element");
 1627         return;
 1628     }
 1629     
 1630     memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]);
 1631     rd->data[0] += data[0];
 1632 }
 1633 
 1634 /**
 1635  * Clean up after last call of zadd_rdata_txt_wireformat
 1636  */
 1637 void
 1638 zadd_rdata_txt_clean_wireformat()
 1639 {
 1640     uint16_t *tmp_data;
 1641     rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1];
 1642     if(!rd || !rd->data)
 1643         return; /* previous syntax failure */
 1644     if ((tmp_data = (uint16_t *) region_alloc(parser->region, 
 1645         ((size_t)rd->data[0]) + ((size_t)2))) != NULL) {
 1646         memcpy(tmp_data, rd->data, rd->data[0] + 2);
 1647         /* rd->data of u16+65535 freed when rr_region is freed */
 1648         rd->data = tmp_data;
 1649     }
 1650     else {
 1651         /* We could not get memory in non-volatile region */
 1652         zc_error_prev_line("could not allocate memory for rdata");
 1653         return;
 1654     }
 1655 }
 1656 
 1657 static int
 1658 svcparam_key_cmp(const void *a, const void *b)
 1659 {
 1660     return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a)))
 1661          - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b)));
 1662 }
 1663 
 1664 void
 1665 zadd_rdata_svcb_check_wireformat()
 1666 {
 1667     size_t i;
 1668     uint8_t paramkeys[65536];
 1669     int prev_key = - 1;
 1670     int key = 0;
 1671     size_t size;
 1672     uint16_t *mandatory_values;
 1673 
 1674     if (parser->current_rr.rdata_count <= 2) {
 1675         if (!parser->error_occurred)
 1676             zc_error_prev_line("invalid SVCB or HTTPS rdata");
 1677         return;
 1678     } else for (i = 2; i < parser->current_rr.rdata_count; i++) {
 1679         if (parser->current_rr.rdatas[i].data == NULL
 1680         ||  rdata_atom_data(parser->current_rr.rdatas[i]) == NULL
 1681         ||  rdata_atom_size(parser->current_rr.rdatas[i]) < 4) {
 1682             if (!parser->error_occurred)
 1683                 zc_error_prev_line("invalid SVCB or HTTPS rdata");
 1684             return;
 1685         }
 1686     }
 1687     /* After this point, all rdatas do have data larger than 4 bytes.
 1688      * So we may assume a uint16_t SVCB key followed by uint16_t length
 1689      * in each rdata in the remainder of this function.
 1690      */
 1691     memset(paramkeys, 0, sizeof(paramkeys));
 1692     /* 
 1693      * In draft-ietf-dnsop-svcb-https-04 Section 7:
 1694      * In wire format, the keys are represented by their numeric values in
 1695      * network byte order, concatenated in ascending order.
 1696      *
 1697      * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is
 1698      * safe because we checked.
 1699      *
 1700      */
 1701     qsort( (void *)&parser->current_rr.rdatas[2]
 1702          , parser->current_rr.rdata_count - 2
 1703          , sizeof(rdata_atom_type)
 1704          , svcparam_key_cmp
 1705          );
 1706 
 1707     for (i = 2; i < parser->current_rr.rdata_count; i++) {
 1708         assert(parser->current_rr.rdatas[i].data);
 1709         assert(rdata_atom_data(parser->current_rr.rdatas[i]));
 1710         assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t));
 1711          
 1712         key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i]));
 1713 
 1714         /* In draft-ietf-dnsop-svcb-https-04 Section 7:
 1715          *
 1716          *     Keys (...) MUST NOT appear more than once.
 1717          * 
 1718          * If they key has already been seen, we have a duplicate
 1719          */
 1720         if (!paramkeys[key])
 1721             /* keep track of keys that are present */
 1722             paramkeys[key] = 1;
 1723 
 1724         else if (key < SVCPARAMKEY_COUNT) {
 1725             if(zone_is_slave(parser->current_zone->opts))
 1726                 zc_warning_prev_line(
 1727                     "Duplicate key found: %s",
 1728                     svcparamkey_strs[key]);
 1729             else {
 1730                 zc_error_prev_line(
 1731                     "Duplicate key found: %s",
 1732                     svcparamkey_strs[key]);
 1733             }
 1734         } else if(zone_is_slave(parser->current_zone->opts))
 1735             zc_warning_prev_line(
 1736                     "Duplicate key found: key%d", key);
 1737         else
 1738             zc_error_prev_line(
 1739                     "Duplicate key found: key%d", key);
 1740     }
 1741     /* Checks when a mandatory key is present */
 1742     if (!paramkeys[SVCB_KEY_MANDATORY])
 1743         return;
 1744 
 1745     size = rdata_atom_size(parser->current_rr.rdatas[2]);
 1746     assert(size >= 4);
 1747     mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]);
 1748     mandatory_values += 2; /* skip the key type and length */
 1749 
 1750     if (size % 2)
 1751         zc_error_prev_line("mandatory rdata must be a multiple of shorts");
 1752         
 1753     else for (i = 0; i < (size - 4)/2; i++) {
 1754         key = ntohs(mandatory_values[i]);
 1755 
 1756         if (paramkeys[key])
 1757             ; /* pass */
 1758 
 1759         else if (key < SVCPARAMKEY_COUNT) {
 1760             if(zone_is_slave(parser->current_zone->opts))
 1761                 zc_warning_prev_line("mandatory SvcParamKey: %s is missing "
 1762                              "the record", svcparamkey_strs[key]);
 1763             else
 1764                 zc_error_prev_line("mandatory SvcParamKey: %s is missing "
 1765                            "the record", svcparamkey_strs[key]);
 1766         } else {
 1767             if(zone_is_slave(parser->current_zone->opts))
 1768                 zc_warning_prev_line("mandatory SvcParamKey: key%d is missing "
 1769                              "the record", key);
 1770             else
 1771                 zc_error_prev_line("mandatory SvcParamKey: key%d is missing "
 1772                            "the record", key);
 1773         }
 1774 
 1775         /* In draft-ietf-dnsop-svcb-https-04 Section 8
 1776          * automatically mandatory MUST NOT appear in its own value-list
 1777          */
 1778         if (key == SVCB_KEY_MANDATORY) {
 1779             if(zone_is_slave(parser->current_zone->opts))
 1780                 zc_warning_prev_line("mandatory MUST not be included"
 1781                              " as mandatory parameter");
 1782             else
 1783                 zc_error_prev_line("mandatory MUST not be included"
 1784                            " as mandatory parameter");
 1785         }
 1786         if (key == prev_key) {
 1787             if(zone_is_slave(parser->current_zone->opts))
 1788                 zc_warning_prev_line("Keys inSvcParam mandatory "
 1789                                    "MUST NOT appear more than once.");
 1790             else
 1791                 zc_error_prev_line("Keys in SvcParam mandatory "
 1792                                    "MUST NOT appear more than once.");
 1793         }
 1794         prev_key = key;
 1795     }
 1796 }
 1797 
 1798 void
 1799 zadd_rdata_domain(domain_type *domain)
 1800 {
 1801     if (parser->current_rr.rdata_count >= MAXRDATALEN) {
 1802         zc_error_prev_line("too many rdata elements");
 1803     } else {
 1804         parser->current_rr.rdatas[parser->current_rr.rdata_count].domain
 1805             = domain;
 1806         domain->usage ++; /* new reference to domain */
 1807         ++parser->current_rr.rdata_count;
 1808     }
 1809 }
 1810 
 1811 void
 1812 parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
 1813 {
 1814     buffer_type packet;
 1815     uint16_t size;
 1816     ssize_t rdata_count;
 1817     ssize_t i;
 1818     rdata_atom_type *rdatas;
 1819 
 1820     if (wireformat) {
 1821         size = *wireformat;
 1822     } else {
 1823         return;
 1824     }
 1825 
 1826     buffer_create_from(&packet, wireformat + 1, *wireformat);
 1827     rdata_count = rdata_wireformat_to_rdata_atoms(parser->region,
 1828                               parser->db->domains,
 1829                               type,
 1830                               size,
 1831                               &packet,
 1832                               &rdatas);
 1833     if (rdata_count == -1) {
 1834         zc_error_prev_line("bad unknown RDATA");
 1835         return;
 1836     }
 1837 
 1838     for (i = 0; i < rdata_count; ++i) {
 1839         if (rdata_atom_is_domain(type, i)) {
 1840             zadd_rdata_domain(rdatas[i].domain);
 1841         } else {
 1842             zadd_rdata_wireformat(rdatas[i].data);
 1843         }
 1844     }
 1845     region_recycle(parser->region, rdatas,
 1846         rdata_count*sizeof(rdata_atom_type));
 1847 }
 1848 
 1849 
 1850 /*
 1851  * Compares two rdata arrays.
 1852  *
 1853  * Returns:
 1854  *
 1855  *  zero if they are equal
 1856  *  non-zero if not
 1857  *
 1858  */
 1859 static int
 1860 zrdatacmp(uint16_t type, rr_type *a, rr_type *b)
 1861 {
 1862     int i = 0;
 1863 
 1864     assert(a);
 1865     assert(b);
 1866 
 1867     /* One is shorter than another */
 1868     if (a->rdata_count != b->rdata_count)
 1869         return 1;
 1870 
 1871     /* Compare element by element */
 1872     for (i = 0; i < a->rdata_count; ++i) {
 1873         if (rdata_atom_is_domain(type, i)) {
 1874             if (rdata_atom_domain(a->rdatas[i])
 1875                 != rdata_atom_domain(b->rdatas[i]))
 1876             {
 1877                 return 1;
 1878             }
 1879         } else if(rdata_atom_is_literal_domain(type, i)) {
 1880             if (rdata_atom_size(a->rdatas[i])
 1881                 != rdata_atom_size(b->rdatas[i]))
 1882                 return 1;
 1883             if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]),
 1884                    rdata_atom_data(b->rdatas[i]),
 1885                    rdata_atom_size(a->rdatas[i])))
 1886                 return 1;
 1887         } else {
 1888             if (rdata_atom_size(a->rdatas[i])
 1889                 != rdata_atom_size(b->rdatas[i]))
 1890             {
 1891                 return 1;
 1892             }
 1893             if (memcmp(rdata_atom_data(a->rdatas[i]),
 1894                    rdata_atom_data(b->rdatas[i]),
 1895                    rdata_atom_size(a->rdatas[i])) != 0)
 1896             {
 1897                 return 1;
 1898             }
 1899         }
 1900     }
 1901 
 1902     /* Otherwise they are equal */
 1903     return 0;
 1904 }
 1905 
 1906 /*
 1907  *
 1908  * Opens a zone file.
 1909  *
 1910  * Returns:
 1911  *
 1912  *  - pointer to the parser structure
 1913  *  - NULL on error and errno set
 1914  *
 1915  */
 1916 static int
 1917 zone_open(const char *filename, uint32_t ttl, uint16_t klass,
 1918       const dname_type *origin)
 1919 {
 1920     /* Open the zone file... */
 1921     if (strcmp(filename, "-") == 0) {
 1922         yyin = stdin;
 1923         filename = "<stdin>";
 1924         warn_if_directory("zonefile from stdin", yyin, filename);
 1925     } else {
 1926         if (!(yyin = fopen(filename, "r"))) {
 1927             return 0;
 1928         }
 1929         warn_if_directory("zonefile", yyin, filename);
 1930     }
 1931 
 1932     zparser_init(filename, ttl, klass, origin);
 1933 
 1934     return 1;
 1935 }
 1936 
 1937 
 1938 void
 1939 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
 1940         uint16_t index)
 1941 {
 1942     /*
 1943      * The bits are counted from left to right, so bit #0 is the
 1944      * left most bit.
 1945      */
 1946     uint8_t window = index / 256;
 1947     uint8_t bit = index % 256;
 1948 
 1949     bits[window][bit / 8] |= (1 << (7 - bit % 8));
 1950 }
 1951 
 1952 
 1953 static int
 1954 has_soa(domain_type* domain)
 1955 {
 1956     rrset_type* p = NULL;
 1957     if(!domain) return 0;
 1958     for(p = domain->rrsets; p; p = p->next)
 1959         if(rrset_rrtype(p) == TYPE_SOA)
 1960             return 1;
 1961     return 0;
 1962 }
 1963 
 1964 int
 1965 process_rr(void)
 1966 {
 1967     zone_type *zone = parser->current_zone;
 1968     rr_type *rr = &parser->current_rr;
 1969     rrset_type *rrset;
 1970     size_t max_rdlength;
 1971     int i;
 1972     rrtype_descriptor_type *descriptor
 1973         = rrtype_descriptor_by_type(rr->type);
 1974 
 1975     /* We only support IN class */
 1976     if (rr->klass != CLASS_IN) {
 1977         if(zone_is_slave(zone->opts))
 1978             zc_warning_prev_line("only class IN is supported");
 1979         else
 1980             zc_error_prev_line("only class IN is supported");
 1981         return 0;
 1982     }
 1983 
 1984     /* Make sure the maximum RDLENGTH does not exceed 65535 bytes.  */
 1985     max_rdlength = rdata_maximum_wireformat_size(
 1986         descriptor, rr->rdata_count, rr->rdatas);
 1987 
 1988     if (max_rdlength > MAX_RDLENGTH) {
 1989         zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH);
 1990         return 0;
 1991     }
 1992 
 1993     /* We cannot print invalid owner names,
 1994      * so error on that before it is used in printing other errors.
 1995      */
 1996     if (rr->owner == error_domain
 1997     ||  domain_dname(rr->owner) == error_dname) {
 1998         zc_error_prev_line("invalid owner name");
 1999         return 0;
 2000     }
 2001 
 2002     /* we have the zone already */
 2003     assert(zone);
 2004     if (rr->type == TYPE_SOA) {
 2005         if (rr->owner != zone->apex) {
 2006             char s[MAXDOMAINLEN*5];
 2007             snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
 2008             zc_error_prev_line(
 2009                 "SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s);
 2010             return 0;
 2011         }
 2012         if(has_soa(rr->owner)) {
 2013             if(zone_is_slave(zone->opts))
 2014                 zc_warning_prev_line("this SOA record was already encountered");
 2015             else
 2016                 zc_error_prev_line("this SOA record was already encountered");
 2017             return 0;
 2018         }
 2019         rr->owner->is_apex = 1;
 2020     }
 2021 
 2022     if (!domain_is_subdomain(rr->owner, zone->apex))
 2023     {
 2024         char s[MAXDOMAINLEN*5];
 2025         snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex));
 2026         if(zone_is_slave(zone->opts))
 2027             zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
 2028         else
 2029             zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s);
 2030         return 0;
 2031     }
 2032 
 2033     /* Do we have this type of rrset already? */
 2034     rrset = domain_find_rrset(rr->owner, zone, rr->type);
 2035     if (!rrset) {
 2036         rrset = (rrset_type *) region_alloc(parser->region,
 2037                             sizeof(rrset_type));
 2038         rrset->zone = zone;
 2039         rrset->rr_count = 1;
 2040         rrset->rrs = (rr_type *) region_alloc(parser->region,
 2041                               sizeof(rr_type));
 2042         rrset->rrs[0] = *rr;
 2043 
 2044         /* Add it */
 2045         domain_add_rrset(rr->owner, rrset);
 2046     } else {
 2047         rr_type* o;
 2048         if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) {
 2049             zc_warning_prev_line(
 2050                 "%s TTL %u does not match the TTL %u of the %s RRset",
 2051                 domain_to_string(rr->owner), (unsigned)rr->ttl,
 2052                 (unsigned)rrset->rrs[0].ttl,
 2053                 rrtype_to_string(rr->type));
 2054         }
 2055 
 2056         /* Search for possible duplicates... */
 2057         for (i = 0; i < rrset->rr_count; i++) {
 2058             if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) {
 2059                 break;
 2060             }
 2061         }
 2062 
 2063         /* Discard the duplicates... */
 2064         if (i < rrset->rr_count) {
 2065             /* add rdatas to recycle bin. */
 2066             size_t i;
 2067             for (i = 0; i < rr->rdata_count; i++) {
 2068                 if(!rdata_atom_is_domain(rr->type, i))
 2069                     region_recycle(parser->region, rr->rdatas[i].data,
 2070                         rdata_atom_size(rr->rdatas[i])
 2071                         + sizeof(uint16_t));
 2072             }
 2073             region_recycle(parser->region, rr->rdatas,
 2074                 sizeof(rdata_atom_type)*rr->rdata_count);
 2075             return 0;
 2076         }
 2077         if(rrset->rr_count == 65535) {
 2078             zc_error_prev_line("too many RRs for domain RRset");
 2079             return 0;
 2080         }
 2081 
 2082         /* Add it... */
 2083         o = rrset->rrs;
 2084         rrset->rrs = (rr_type *) region_alloc_array(parser->region,
 2085             (rrset->rr_count + 1), sizeof(rr_type));
 2086         memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type));
 2087         region_recycle(parser->region, o,
 2088             (rrset->rr_count) * sizeof(rr_type));
 2089         rrset->rrs[rrset->rr_count] = *rr;
 2090         ++rrset->rr_count;
 2091     }
 2092 
 2093     if(rr->type == TYPE_DNAME && rrset->rr_count > 1) {
 2094         if(zone_is_slave(zone->opts))
 2095             zc_warning_prev_line("multiple DNAMEs at the same name");
 2096         else
 2097             zc_error_prev_line("multiple DNAMEs at the same name");
 2098     }
 2099     if(rr->type == TYPE_CNAME && rrset->rr_count > 1) {
 2100         if(zone_is_slave(zone->opts))
 2101             zc_warning_prev_line("multiple CNAMEs at the same name");
 2102         else
 2103             zc_error_prev_line("multiple CNAMEs at the same name");
 2104     }
 2105     if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME))
 2106      ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) {
 2107         if(zone_is_slave(zone->opts))
 2108             zc_warning_prev_line("DNAME and CNAME at the same name");
 2109         else
 2110             zc_error_prev_line("DNAME and CNAME at the same name");
 2111     }
 2112     if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) &&
 2113         domain_find_non_cname_rrset(rr->owner, zone)) {
 2114         if(zone_is_slave(zone->opts))
 2115             zc_warning_prev_line("CNAME and other data at the same name");
 2116         else
 2117             zc_error_prev_line("CNAME and other data at the same name");
 2118     }
 2119 
 2120     /* Check we have SOA */
 2121     if(rr->owner == zone->apex)
 2122         apex_rrset_checks(parser->db, rrset, rr->owner);
 2123 
 2124     if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) {
 2125         struct stat buf;
 2126         startzonec = time(NULL);
 2127         buf.st_size = 0;
 2128         fstat(fileno(yyin), &buf);
 2129         if(buf.st_size == 0) buf.st_size = 1;
 2130         VERBOSITY(1, (LOG_INFO, "parse %s %d %%",
 2131             parser->current_zone->opts->name,
 2132             (int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size)));
 2133     }
 2134     ++totalrrs;
 2135     return 1;
 2136 }
 2137 
 2138 /*
 2139  * Find rrset type for any zone
 2140  */
 2141 static rrset_type*
 2142 domain_find_rrset_any(domain_type *domain, uint16_t type)
 2143 {
 2144     rrset_type *result = domain->rrsets;
 2145     while (result) {
 2146         if (rrset_rrtype(result) == type) {
 2147             return result;
 2148         }
 2149         result = result->next;
 2150     }
 2151     return NULL;
 2152 }
 2153 
 2154 /*
 2155  * Check for DNAME type. Nothing is allowed below it
 2156  */
 2157 static void
 2158 check_dname(zone_type* zone)
 2159 {
 2160     domain_type* domain;
 2161     for(domain = zone->apex; domain && domain_is_subdomain(domain,
 2162         zone->apex); domain=domain_next(domain))
 2163     {
 2164         if(domain->is_existing) {
 2165             /* there may not be DNAMEs above it */
 2166             domain_type* parent = domain->parent;
 2167 #ifdef NSEC3
 2168             if(domain_has_only_NSEC3(domain, NULL))
 2169                 continue;
 2170 #endif
 2171             while(parent) {
 2172                 if(domain_find_rrset_any(parent, TYPE_DNAME)) {
 2173                     zc_error("While checking node %s,",
 2174                         domain_to_string(domain));
 2175                     zc_error("DNAME at %s has data below it. "
 2176                         "This is not allowed (rfc 2672).",
 2177                         domain_to_string(parent));
 2178                     return;
 2179                 }
 2180                 parent = parent->parent;
 2181             }
 2182         }
 2183     }
 2184 }
 2185 
 2186 /*
 2187  * Reads the specified zone into the memory
 2188  * nsd_options can be NULL if no config file is passed.
 2189  */
 2190 unsigned int
 2191 zonec_read(const char* name, const char* zonefile, zone_type* zone)
 2192 {
 2193     const dname_type *dname;
 2194 
 2195     totalrrs = 0;
 2196     startzonec = time(NULL);
 2197     parser->errors = 0;
 2198 
 2199     dname = dname_parse(parser->rr_region, name);
 2200     if (!dname) {
 2201         zc_error("incorrect zone name '%s'", name);
 2202         return 1;
 2203     }
 2204 
 2205 #ifndef ROOT_SERVER
 2206     /* Is it a root zone? Are we a root server then? Idiot proof. */
 2207     if (dname->label_count == 1) {
 2208         zc_error("not configured as a root server");
 2209         return 1;
 2210     }
 2211 #endif
 2212 
 2213     /* Open the zone file */
 2214     if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
 2215         zc_error("cannot open '%s': %s", zonefile, strerror(errno));
 2216         return 1;
 2217     }
 2218     parser->current_zone = zone;
 2219 
 2220     /* Parse and process all RRs.  */
 2221     yyparse();
 2222 
 2223     /* remove origin if it was unused */
 2224     if(parser->origin != error_domain)
 2225         domain_table_deldomain(parser->db, parser->origin);
 2226     /* rr_region has been emptied by now */
 2227     dname = dname_parse(parser->rr_region, name);
 2228 
 2229     /* check if zone file contained a correct SOA record */
 2230     if (!parser->current_zone) {
 2231         zc_error("zone configured as '%s' has no content.", name);
 2232     } else if(!parser->current_zone->soa_rrset ||
 2233         parser->current_zone->soa_rrset->rr_count == 0) {
 2234         zc_error("zone configured as '%s' has no SOA record.", name);
 2235     } else if(dname_compare(domain_dname(
 2236         parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
 2237         zc_error("zone configured as '%s', but SOA has owner '%s'.",
 2238             name, domain_to_string(
 2239             parser->current_zone->soa_rrset->rrs[0].owner));
 2240     }
 2241     region_free_all(parser->rr_region);
 2242 
 2243     parser_flush();
 2244     fclose(yyin);
 2245     if(!zone_is_slave(zone->opts))
 2246         check_dname(zone);
 2247 
 2248     parser->filename = NULL;
 2249     return parser->errors;
 2250 }
 2251 
 2252 
 2253 /*
 2254  * setup parse
 2255  */
 2256 void
 2257 zonec_setup_parser(namedb_type* db)
 2258 {
 2259     region_type* rr_region = region_create(xalloc, free);
 2260     parser = zparser_create(db->region, rr_region, db);
 2261     assert(parser);
 2262     /* Unique pointers used to mark errors.  */
 2263     error_dname = (dname_type *) region_alloc(db->region, 1);
 2264     error_domain = (domain_type *) region_alloc(db->region, 1);
 2265     /* Open the network database */
 2266     setprotoent(1);
 2267     setservent(1);
 2268 }
 2269 
 2270 /** desetup parse */
 2271 void
 2272 zonec_desetup_parser(void)
 2273 {
 2274     if(parser) {
 2275         endservent();
 2276         endprotoent();
 2277         region_destroy(parser->rr_region);
 2278         /* removed when parser->region(=db->region) is destroyed:
 2279          * region_recycle(parser->region, (void*)error_dname, 1);
 2280          * region_recycle(parser->region, (void*)error_domain, 1); */
 2281         /* clear memory for exit, but this is not portable to
 2282          * other versions of lex. yylex_destroy(); */
 2283 #ifdef MEMCLEAN /* OS collects memory pages */
 2284         yylex_destroy();
 2285 #endif
 2286     }
 2287 }
 2288 
 2289 static domain_table_type* orig_domains = NULL;
 2290 static region_type* orig_region = NULL;
 2291 static region_type* orig_dbregion = NULL;
 2292 
 2293 /** setup for string parse */
 2294 void
 2295 zonec_setup_string_parser(region_type* region, domain_table_type* domains)
 2296 {
 2297     assert(parser); /* global parser must be setup */
 2298     orig_domains = parser->db->domains;
 2299     orig_region = parser->region;
 2300     orig_dbregion = parser->db->region;
 2301     parser->region = region;
 2302     parser->db->region = region;
 2303     parser->db->domains = domains;
 2304     zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root));
 2305 }
 2306 
 2307 /** desetup string parse */
 2308 void
 2309 zonec_desetup_string_parser(void)
 2310 {
 2311     parser->region = orig_region;
 2312     parser->db->domains = orig_domains;
 2313     parser->db->region = orig_dbregion;
 2314 }
 2315 
 2316 /** parse a string into temporary storage */
 2317 int
 2318 zonec_parse_string(region_type* region, domain_table_type* domains,
 2319     zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
 2320 {
 2321     int errors;
 2322     zonec_setup_string_parser(region, domains);
 2323     parser->current_zone = zone;
 2324     parser->errors = 0;
 2325     totalrrs = 0;
 2326     startzonec = time(NULL)+100000; /* disable */
 2327     parser_push_stringbuf(str);
 2328     yyparse();
 2329     parser_pop_stringbuf();
 2330     errors = parser->errors;
 2331     *num_rrs = totalrrs;
 2332     if(*num_rrs == 0)
 2333         *parsed = NULL;
 2334     else    *parsed = parser->prev_dname;
 2335     /* remove origin if it was not used during the parse */
 2336     if(parser->origin != error_domain)
 2337         domain_table_deldomain(parser->db, parser->origin);
 2338     region_free_all(parser->rr_region);
 2339     zonec_desetup_string_parser();
 2340     parser_flush();
 2341     return errors;
 2342 }
 2343 
 2344 /** check SSHFP type for failures and emit warnings */
 2345 void check_sshfp(void)
 2346 {
 2347     uint8_t hash;
 2348     uint16_t size;
 2349     if(parser->current_rr.rdata_count < 3)
 2350         return; /* cannot check it, too few rdata elements */
 2351     if(!parser->current_rr.rdatas[0].data ||
 2352         !parser->current_rr.rdatas[1].data ||
 2353         !parser->current_rr.rdatas[2].data ||
 2354         !parser->current_rr.owner)
 2355         return; /* cannot check, NULLs (due to earlier errors) */
 2356     if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1)
 2357         return; /* wrong size of the hash type rdata element */
 2358     hash = rdata_atom_data(parser->current_rr.rdatas[1])[0];
 2359     size = rdata_atom_size(parser->current_rr.rdatas[2]);
 2360     if(hash == 1 && size != 20) {
 2361         zc_warning_prev_line("SSHFP %s of type SHA1 has hash of "
 2362             "wrong length, %d bytes, should be 20",
 2363             domain_to_string(parser->current_rr.owner),
 2364             (int)size);
 2365     } else if(hash == 2 && size != 32) {
 2366         zc_warning_prev_line("SSHFP %s of type SHA256 has hash of "
 2367             "wrong length, %d bytes, should be 32",
 2368             domain_to_string(parser->current_rr.owner),
 2369             (int)size);
 2370     }
 2371 }