"Fossies" - the Fresh Open Source Software Archive

Member "nsd-4.3.7/difffile.c" (22 Jul 2021, 65669 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 "difffile.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  * difffile.c - DIFF file handling source code. Read and write diff files.
    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 #include <assert.h>
   12 #include <string.h>
   13 #include <unistd.h>
   14 #include <stdlib.h>
   15 #include <errno.h>
   16 #include "difffile.h"
   17 #include "xfrd-disk.h"
   18 #include "util.h"
   19 #include "packet.h"
   20 #include "rdata.h"
   21 #include "udb.h"
   22 #include "udbzone.h"
   23 #include "nsec3.h"
   24 #include "nsd.h"
   25 #include "rrl.h"
   26 
   27 static int
   28 write_64(FILE *out, uint64_t val)
   29 {
   30     return write_data(out, &val, sizeof(val));
   31 }
   32 
   33 static int
   34 write_32(FILE *out, uint32_t val)
   35 {
   36     val = htonl(val);
   37     return write_data(out, &val, sizeof(val));
   38 }
   39 
   40 static int
   41 write_8(FILE *out, uint8_t val)
   42 {
   43     return write_data(out, &val, sizeof(val));
   44 }
   45 
   46 static int
   47 write_str(FILE *out, const char* str)
   48 {
   49     uint32_t len = strlen(str);
   50     if(!write_32(out, len))
   51         return 0;
   52     return write_data(out, str, len);
   53 }
   54 
   55 void
   56 diff_write_packet(const char* zone, const char* pat, uint32_t old_serial,
   57     uint32_t new_serial, uint32_t seq_nr, uint8_t* data, size_t len,
   58     struct nsd* nsd, uint64_t filenumber)
   59 {
   60     FILE* df = xfrd_open_xfrfile(nsd, filenumber, seq_nr?"a":"w");
   61     if(!df) {
   62         log_msg(LOG_ERR, "could not open transfer %s file %lld: %s",
   63             zone, (long long)filenumber, strerror(errno));
   64         return;
   65     }
   66 
   67     /* if first part, first write the header */
   68     if(seq_nr == 0) {
   69         struct timeval tv;
   70         if (gettimeofday(&tv, NULL) != 0) {
   71             log_msg(LOG_ERR, "could not get timestamp for %s: %s",
   72                 zone, strerror(errno));
   73         }
   74         if(!write_32(df, DIFF_PART_XFRF) ||
   75             !write_8(df, 0) /* notcommitted(yet) */ ||
   76             !write_32(df, 0) /* numberofparts when done */ ||
   77             !write_64(df, (uint64_t) tv.tv_sec) ||
   78             !write_32(df, (uint32_t) tv.tv_usec) ||
   79             !write_32(df, old_serial) ||
   80             !write_32(df, new_serial) ||
   81             !write_64(df, (uint64_t) tv.tv_sec) ||
   82             !write_32(df, (uint32_t) tv.tv_usec) ||
   83             !write_str(df, zone) ||
   84             !write_str(df, pat)) {
   85             log_msg(LOG_ERR, "could not write transfer %s file %lld: %s",
   86                 zone, (long long)filenumber, strerror(errno));
   87             fclose(df);
   88             return;
   89         }
   90     }
   91 
   92     if(!write_32(df, DIFF_PART_XXFR) ||
   93         !write_32(df, len) ||
   94         !write_data(df, data, len) ||
   95         !write_32(df, len))
   96     {
   97         log_msg(LOG_ERR, "could not write transfer %s file %lld: %s",
   98             zone, (long long)filenumber, strerror(errno));
   99     }
  100     fclose(df);
  101 }
  102 
  103 void
  104 diff_write_commit(const char* zone, uint32_t old_serial, uint32_t new_serial,
  105     uint32_t num_parts, uint8_t commit, const char* log_str,
  106     struct nsd* nsd, uint64_t filenumber)
  107 {
  108     struct timeval tv;
  109     FILE* df;
  110 
  111     if (gettimeofday(&tv, NULL) != 0) {
  112         log_msg(LOG_ERR, "could not set timestamp for %s: %s",
  113             zone, strerror(errno));
  114     }
  115 
  116     /* overwrite the first part of the file with 'committed = 1', 
  117      * as well as the end_time and number of parts.
  118      * also write old_serial and new_serial, so that a bad file mixup
  119      * will result in unusable serial numbers. */
  120 
  121     df = xfrd_open_xfrfile(nsd, filenumber, "r+");
  122     if(!df) {
  123         log_msg(LOG_ERR, "could not open transfer %s file %lld: %s",
  124             zone, (long long)filenumber, strerror(errno));
  125         return;
  126     }
  127     if(!write_32(df, DIFF_PART_XFRF) ||
  128         !write_8(df, commit) /* committed */ ||
  129         !write_32(df, num_parts) ||
  130         !write_64(df, (uint64_t) tv.tv_sec) ||
  131         !write_32(df, (uint32_t) tv.tv_usec) ||
  132         !write_32(df, old_serial) ||
  133         !write_32(df, new_serial))
  134     {
  135         log_msg(LOG_ERR, "could not write transfer %s file %lld: %s",
  136             zone, (long long)filenumber, strerror(errno));
  137         fclose(df);
  138         return;
  139     }
  140 
  141     /* append the log_str to the end of the file */
  142     if(fseek(df, 0, SEEK_END) == -1) {
  143         log_msg(LOG_ERR, "could not fseek transfer %s file %lld: %s",
  144             zone, (long long)filenumber, strerror(errno));
  145         fclose(df);
  146         return;
  147     }
  148     if(!write_str(df, log_str)) {
  149         log_msg(LOG_ERR, "could not write transfer %s file %lld: %s",
  150             zone, (long long)filenumber, strerror(errno));
  151         fclose(df);
  152         return;
  153 
  154     }
  155     fflush(df);
  156     fclose(df);
  157 }
  158 
  159 int
  160 diff_read_64(FILE *in, uint64_t* result)
  161 {
  162     if (fread(result, sizeof(*result), 1, in) == 1) {
  163         return 1;
  164     } else {
  165         return 0;
  166     }
  167 }
  168 
  169 int
  170 diff_read_32(FILE *in, uint32_t* result)
  171 {
  172     if (fread(result, sizeof(*result), 1, in) == 1) {
  173         *result = ntohl(*result);
  174         return 1;
  175     } else {
  176         return 0;
  177     }
  178 }
  179 
  180 int
  181 diff_read_8(FILE *in, uint8_t* result)
  182 {
  183         if (fread(result, sizeof(*result), 1, in) == 1) {
  184                 return 1;
  185         } else {
  186                 return 0;
  187         }
  188 }
  189 
  190 int
  191 diff_read_str(FILE* in, char* buf, size_t len)
  192 {
  193     uint32_t disklen;
  194     if(!diff_read_32(in, &disklen))
  195         return 0;
  196     if(disklen >= len)
  197         return 0;
  198     if(fread(buf, disklen, 1, in) != 1)
  199         return 0;
  200     buf[disklen] = 0;
  201     return 1;
  202 }
  203 
  204 static void
  205 add_rdata_to_recyclebin(namedb_type* db, rr_type* rr)
  206 {
  207     /* add rdatas to recycle bin. */
  208     size_t i;
  209     for(i=0; i<rr->rdata_count; i++)
  210     {
  211         if(!rdata_atom_is_domain(rr->type, i))
  212             region_recycle(db->region, rr->rdatas[i].data,
  213                 rdata_atom_size(rr->rdatas[i])
  214                 + sizeof(uint16_t));
  215     }
  216     region_recycle(db->region, rr->rdatas,
  217         sizeof(rdata_atom_type)*rr->rdata_count);
  218 }
  219 
  220 /* this routine determines if below a domain there exist names with
  221  * data (is_existing) or no names below the domain have data.
  222  */
  223 static int
  224 has_data_below(domain_type* top)
  225 {
  226     domain_type* d = top;
  227     assert(d != NULL);
  228     /* in the canonical ordering subdomains are after this name */
  229     d = domain_next(d);
  230     while(d != NULL && domain_is_subdomain(d, top)) {
  231         if(d->is_existing)
  232             return 1;
  233         d = domain_next(d);
  234     }
  235     return 0;
  236 }
  237 
  238 /** check if domain with 0 rrsets has become empty (nonexist) */
  239 static domain_type*
  240 rrset_zero_nonexist_check(domain_type* domain, domain_type* ce)
  241 {
  242     /* is the node now an empty node (completely deleted) */
  243     if(domain->rrsets == 0) {
  244         /* if there is no data below it, it becomes non existing.
  245            also empty nonterminals above it become nonexisting */
  246         /* check for data below this node. */
  247         if(!has_data_below(domain)) {
  248             /* nonexist this domain and all parent empty nonterminals */
  249             domain_type* p = domain;
  250             while(p != NULL && p->rrsets == 0) {
  251                 if(p == ce || has_data_below(p))
  252                     return p;
  253                 p->is_existing = 0;
  254                 /* fixup wildcard child of parent */
  255                 if(p->parent &&
  256                     p->parent->wildcard_child_closest_match == p)
  257                     p->parent->wildcard_child_closest_match = domain_previous_existing_child(p);
  258                 p = p->parent;
  259             }
  260         }
  261     }
  262     return NULL;
  263 }
  264 
  265 /** remove rrset.  Adjusts zone params.  Does not remove domain */
  266 static void
  267 rrset_delete(namedb_type* db, domain_type* domain, rrset_type* rrset)
  268 {
  269     int i;
  270     /* find previous */
  271     rrset_type** pp = &domain->rrsets;
  272     while(*pp && *pp != rrset) {
  273         pp = &( (*pp)->next );
  274     }
  275     if(!*pp) {
  276         /* rrset does not exist for domain */
  277         return;
  278     }
  279     *pp = rrset->next;
  280 
  281     DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete rrset of %s type %s",
  282         domain_to_string(domain),
  283         rrtype_to_string(rrset_rrtype(rrset))));
  284 
  285     /* is this a SOA rrset ? */
  286     if(rrset->zone->soa_rrset == rrset) {
  287         rrset->zone->soa_rrset = 0;
  288     }
  289     if(rrset->zone->ns_rrset == rrset) {
  290         rrset->zone->ns_rrset = 0;
  291     }
  292     if(domain == rrset->zone->apex && rrset_rrtype(rrset) == TYPE_RRSIG) {
  293         for (i = 0; i < rrset->rr_count; ++i) {
  294             if(rr_rrsig_type_covered(&rrset->rrs[i])==TYPE_DNSKEY) {
  295                 rrset->zone->is_secure = 0;
  296                 break;
  297             }
  298         }
  299     }
  300     /* recycle the memory space of the rrset */
  301     for (i = 0; i < rrset->rr_count; ++i)
  302         add_rdata_to_recyclebin(db, &rrset->rrs[i]);
  303     region_recycle(db->region, rrset->rrs,
  304         sizeof(rr_type) * rrset->rr_count);
  305     rrset->rr_count = 0;
  306     region_recycle(db->region, rrset, sizeof(rrset_type));
  307 }
  308 
  309 static int
  310 rdatas_equal(rdata_atom_type *a, rdata_atom_type *b, int num, uint16_t type,
  311     int* rdnum, char** reason)
  312 {
  313     int k, start, end;
  314     start = 0;
  315     end = num;
  316     /**
  317      * SOA RDATA comparisons in XFR are more lenient,
  318      * only serial rdata is checked.
  319      **/
  320     if (type == TYPE_SOA) {
  321         start = 2;
  322         end = 3;
  323     }
  324     for(k = start; k < end; k++)
  325     {
  326         if(rdata_atom_is_domain(type, k)) {
  327             if(dname_compare(domain_dname(a[k].domain),
  328                 domain_dname(b[k].domain))!=0) {
  329                 *rdnum = k;
  330                 *reason = "dname data";
  331                 return 0;
  332             }
  333         } else if(rdata_atom_is_literal_domain(type, k)) {
  334             /* literal dname, but compare case insensitive */
  335             if(a[k].data[0] != b[k].data[0]) {
  336                 *rdnum = k;
  337                 *reason = "literal dname len";
  338                 return 0; /* uncompressed len must be equal*/
  339             }
  340             if(!dname_equal_nocase((uint8_t*)(a[k].data+1),
  341                 (uint8_t*)(b[k].data+1), a[k].data[0])) {
  342                 *rdnum = k;
  343                 *reason = "literal dname data";
  344                 return 0;
  345             }
  346         } else {
  347             /* check length */
  348             if(a[k].data[0] != b[k].data[0]) {
  349                 *rdnum = k;
  350                 *reason = "rdata len";
  351                 return 0;
  352             }
  353             /* check data */
  354             if(memcmp(a[k].data+1, b[k].data+1, a[k].data[0])!=0) {
  355                 *rdnum = k;
  356                 *reason = "rdata data";
  357                 return 0;
  358             }
  359         }
  360     }
  361     return 1;
  362 }
  363 
  364 static void
  365 debug_find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass,
  366     rdata_atom_type *rdatas, ssize_t rdata_num)
  367 {
  368     int i, rd;
  369     char* reason = "";
  370 
  371     for(i=0; i < rrset->rr_count; ++i) {
  372         if (rrset->rrs[i].type != type) {
  373             log_msg(LOG_WARNING, "diff: RR <%s, %s> does not match "
  374                 "RR num %d type %s",
  375                 dname_to_string(domain_dname(rrset->rrs[i].owner),0),
  376                 rrtype_to_string(type), i,
  377                 rrtype_to_string(rrset->rrs[i].type));
  378         }
  379         if (rrset->rrs[i].klass != klass) {
  380             log_msg(LOG_WARNING, "diff: RR <%s, %s> class %d "
  381                 "does not match RR num %d class %d",
  382                 dname_to_string(domain_dname(rrset->rrs[i].owner),0),
  383                 rrtype_to_string(type),
  384                 klass, i,
  385                 rrset->rrs[i].klass);
  386         }
  387         if (rrset->rrs[i].rdata_count != rdata_num) {
  388             log_msg(LOG_WARNING, "diff: RR <%s, %s> rdlen %u "
  389                 "does not match RR num %d rdlen %d",
  390                 dname_to_string(domain_dname(rrset->rrs[i].owner),0),
  391                 rrtype_to_string(type),
  392                 (unsigned) rdata_num, i,
  393                 (unsigned) rrset->rrs[i].rdata_count);
  394         }
  395         if (!rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type,
  396             &rd, &reason)) {
  397             log_msg(LOG_WARNING, "diff: RR <%s, %s> rdata element "
  398                 "%d differs from RR num %d rdata (%s)",
  399                 dname_to_string(domain_dname(rrset->rrs[i].owner),0),
  400                 rrtype_to_string(type),
  401                 rd, i, reason);
  402         }
  403     }
  404 }
  405 
  406 static int
  407 find_rr_num(rrset_type* rrset, uint16_t type, uint16_t klass,
  408     rdata_atom_type *rdatas, ssize_t rdata_num, int add)
  409 {
  410     int i, rd;
  411     char* reason;
  412 
  413     for(i=0; i < rrset->rr_count; ++i) {
  414         if(rrset->rrs[i].type == type &&
  415            rrset->rrs[i].klass == klass &&
  416            rrset->rrs[i].rdata_count == rdata_num &&
  417            rdatas_equal(rdatas, rrset->rrs[i].rdatas, rdata_num, type,
  418             &rd, &reason))
  419         {
  420             return i;
  421         }
  422     }
  423         /* this is odd. Log why rr cannot be found. */
  424     if (!add) {
  425         debug_find_rr_num(rrset, type, klass, rdatas, rdata_num);
  426     }
  427     return -1;
  428 }
  429 
  430 #ifdef NSEC3
  431 /* see if nsec3 deletion triggers need action */
  432 static void
  433 nsec3_delete_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone,
  434     udb_ptr* udbz)
  435 {
  436     /* the RR has not actually been deleted yet, so we can inspect it */
  437     if(!zone->nsec3_param)
  438         return;
  439     /* see if the domain was an NSEC3-domain in the chain, but no longer */
  440     if(rr->type == TYPE_NSEC3 && rr->owner->nsec3 &&
  441         rr->owner->nsec3->nsec3_node.key &&
  442         nsec3_rr_uses_params(rr, zone) &&
  443         nsec3_in_chain_count(rr->owner, zone) <= 1) {
  444         domain_type* prev = nsec3_chain_find_prev(zone, rr->owner);
  445         /* remove from prehash because no longer an NSEC3 domain */
  446         if(domain_is_prehash(db->domains, rr->owner))
  447             prehash_del(db->domains, rr->owner);
  448         /* fixup the last in the zone */
  449         if(rr->owner == zone->nsec3_last)
  450             zone->nsec3_last = prev;
  451         /* unlink from the nsec3tree */
  452         zone_del_domain_in_hash_tree(zone->nsec3tree,
  453             &rr->owner->nsec3->nsec3_node);
  454         /* add previous NSEC3 to the prehash list */
  455         if(prev && prev != rr->owner)
  456             prehash_add(db->domains, prev);
  457         else    nsec3_clear_precompile(db, zone);
  458         /* this domain becomes ordinary data domain: done later */
  459     }
  460     /* see if the rr was NSEC3PARAM that we were using */
  461     else if(rr->type == TYPE_NSEC3PARAM && rr == zone->nsec3_param) {
  462         /* clear trees, wipe hashes, wipe precompile */
  463         nsec3_clear_precompile(db, zone);
  464         /* pick up new nsec3param (from udb, or avoid deleted rr) */
  465         nsec3_find_zone_param(db, zone, udbz, rr, 0);
  466         /* if no more NSEC3, done */
  467         if(!zone->nsec3_param)
  468             return;
  469         nsec3_precompile_newparam(db, zone);
  470     }
  471 }
  472 
  473 /* see if nsec3 prehash can be removed with new rrset content */
  474 static void
  475 nsec3_rrsets_changed_remove_prehash(domain_type* domain, zone_type* zone)
  476 {
  477     /* deletion of rrset already done, we can check if conditions apply */
  478     /* see if the domain is no longer precompiled */
  479     /* it has a hash_node, but no longer fulfills conditions */
  480     if(nsec3_domain_part_of_zone(domain, zone) && domain->nsec3 &&
  481         domain->nsec3->hash_wc &&
  482         domain->nsec3->hash_wc->hash.node.key &&
  483         !nsec3_condition_hash(domain, zone)) {
  484         /* remove precompile */
  485         domain->nsec3->nsec3_cover = NULL;
  486         domain->nsec3->nsec3_wcard_child_cover = NULL;
  487         domain->nsec3->nsec3_is_exact = 0;
  488         /* remove it from the hash tree */
  489         zone_del_domain_in_hash_tree(zone->hashtree,
  490             &domain->nsec3->hash_wc->hash.node);
  491         zone_del_domain_in_hash_tree(zone->wchashtree,
  492             &domain->nsec3->hash_wc->wc.node);
  493     }
  494     if(domain != zone->apex && domain->nsec3 &&
  495         domain->nsec3->ds_parent_hash &&
  496         domain->nsec3->ds_parent_hash->node.key &&
  497         (!domain->parent || nsec3_domain_part_of_zone(domain->parent, zone)) &&
  498         !nsec3_condition_dshash(domain, zone)) {
  499         /* remove precompile */
  500         domain->nsec3->nsec3_ds_parent_cover = NULL;
  501         domain->nsec3->nsec3_ds_parent_is_exact = 0;
  502         /* remove it from the hash tree */
  503         zone_del_domain_in_hash_tree(zone->dshashtree,
  504             &domain->nsec3->ds_parent_hash->node);
  505     }
  506 }
  507 
  508 /* see if domain needs to get precompiled info */
  509 static void
  510 nsec3_rrsets_changed_add_prehash(namedb_type* db, domain_type* domain,
  511     zone_type* zone)
  512 {
  513     if(!zone->nsec3_param)
  514         return;
  515     if((!domain->nsec3 || !domain->nsec3->hash_wc
  516                        || !domain->nsec3->hash_wc->hash.node.key)
  517         && nsec3_condition_hash(domain, zone)) {
  518         region_type* tmpregion = region_create(xalloc, free);
  519         nsec3_precompile_domain(db, domain, zone, tmpregion);
  520         region_destroy(tmpregion);
  521     }
  522     if((!domain->nsec3 || !domain->nsec3->ds_parent_hash
  523                        || !domain->nsec3->ds_parent_hash->node.key)
  524         && nsec3_condition_dshash(domain, zone)) {
  525         nsec3_precompile_domain_ds(db, domain, zone);
  526     }
  527 }
  528 
  529 /* see if nsec3 rrset-deletion triggers need action */
  530 static void
  531 nsec3_delete_rrset_trigger(namedb_type* db, domain_type* domain,
  532     zone_type* zone, uint16_t type)
  533 {
  534     if(!zone->nsec3_param)
  535         return;
  536     nsec3_rrsets_changed_remove_prehash(domain, zone);
  537     /* for type nsec3, or a delegation, the domain may have become a
  538      * 'normal' domain with its remaining data now */
  539     if(type == TYPE_NSEC3 || type == TYPE_NS || type == TYPE_DS)
  540         nsec3_rrsets_changed_add_prehash(db, domain, zone);
  541     /* for type DNAME or a delegation, obscured data may be revealed */
  542     if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) {
  543         /* walk over subdomains and check them each */
  544         domain_type *d;
  545         for(d=domain_next(domain); d && domain_is_subdomain(d, domain);
  546             d=domain_next(d)) {
  547             nsec3_rrsets_changed_add_prehash(db, d, zone);
  548         }
  549     }
  550 }
  551 
  552 /* see if nsec3 addition triggers need action */
  553 static void
  554 nsec3_add_rr_trigger(namedb_type* db, rr_type* rr, zone_type* zone,
  555     udb_ptr* udbz)
  556 {
  557     /* the RR has been added in full, also to UDB (and thus NSEC3PARAM 
  558      * in the udb has been adjusted) */
  559     if(zone->nsec3_param && rr->type == TYPE_NSEC3 &&
  560         (!rr->owner->nsec3 || !rr->owner->nsec3->nsec3_node.key)
  561         && nsec3_rr_uses_params(rr, zone)) {
  562         if(!zone->nsec3_last) {
  563             /* all nsec3s have previously been deleted, but
  564              * we have nsec3 parameters, set it up again from
  565              * being cleared. */
  566             nsec3_precompile_newparam(db, zone);
  567         }
  568         /* added NSEC3 into the chain */
  569         nsec3_precompile_nsec3rr(db, rr->owner, zone);
  570         /* the domain has become an NSEC3-domain, if it was precompiled
  571          * previously, remove that, neatly done in routine above */
  572         nsec3_rrsets_changed_remove_prehash(rr->owner, zone);
  573         /* set this NSEC3 to prehash */
  574         prehash_add(db->domains, rr->owner);
  575     } else if(!zone->nsec3_param && rr->type == TYPE_NSEC3PARAM) {
  576         /* see if this means NSEC3 chain can be used */
  577         nsec3_find_zone_param(db, zone, udbz, NULL, 0);
  578         if(!zone->nsec3_param)
  579             return;
  580         nsec3_zone_trees_create(db->region, zone);
  581         nsec3_precompile_newparam(db, zone);
  582     }
  583 }
  584 
  585 /* see if nsec3 rrset-addition triggers need action */
  586 static void
  587 nsec3_add_rrset_trigger(namedb_type* db, domain_type* domain, zone_type* zone,
  588     uint16_t type)
  589 {
  590     /* the rrset has been added so we can inspect it */
  591     if(!zone->nsec3_param)
  592         return;
  593     /* because the rrset is added we can check conditions easily.
  594      * check if domain needs to become precompiled now */
  595     nsec3_rrsets_changed_add_prehash(db, domain, zone);
  596     /* if a delegation, it changes from normal name to unhashed referral */
  597     if(type == TYPE_NS || type == TYPE_DS) {
  598         nsec3_rrsets_changed_remove_prehash(domain, zone);
  599     }
  600     /* if delegation or DNAME added, then some RRs may get obscured */
  601     if(type == TYPE_NS || type == TYPE_DS || type == TYPE_DNAME) {
  602         /* walk over subdomains and check them each */
  603         domain_type *d;
  604         for(d=domain_next(domain); d && domain_is_subdomain(d, domain);
  605             d=domain_next(d)) {
  606             nsec3_rrsets_changed_remove_prehash(d, zone);
  607         }
  608     }
  609 }
  610 #endif /* NSEC3 */
  611 
  612 /* fixup usage lower for domain names in the rdata */
  613 static void
  614 rr_lower_usage(namedb_type* db, rr_type* rr)
  615 {
  616     unsigned i;
  617     for(i=0; i<rr->rdata_count; i++) {
  618         if(rdata_atom_is_domain(rr->type, i)) {
  619             assert(rdata_atom_domain(rr->rdatas[i])->usage > 0);
  620             rdata_atom_domain(rr->rdatas[i])->usage --;
  621             if(rdata_atom_domain(rr->rdatas[i])->usage == 0)
  622                 domain_table_deldomain(db,
  623                     rdata_atom_domain(rr->rdatas[i]));
  624         }
  625     }
  626 }
  627 
  628 static void
  629 rrset_lower_usage(namedb_type* db, rrset_type* rrset)
  630 {
  631     unsigned i;
  632     for(i=0; i<rrset->rr_count; i++)
  633         rr_lower_usage(db, &rrset->rrs[i]);
  634 }
  635 
  636 int
  637 delete_RR(namedb_type* db, const dname_type* dname,
  638     uint16_t type, uint16_t klass,
  639     buffer_type* packet, size_t rdatalen, zone_type *zone,
  640     region_type* temp_region, udb_ptr* udbz, int* softfail)
  641 {
  642     domain_type *domain;
  643     rrset_type *rrset;
  644     domain = domain_table_find(db->domains, dname);
  645     if(!domain) {
  646         log_msg(LOG_WARNING, "diff: domain %s does not exist",
  647             dname_to_string(dname,0));
  648         buffer_skip(packet, rdatalen);
  649         *softfail = 1;
  650         return 1; /* not fatal error */
  651     }
  652     rrset = domain_find_rrset(domain, zone, type);
  653     if(!rrset) {
  654         log_msg(LOG_WARNING, "diff: rrset %s does not exist",
  655             dname_to_string(dname,0));
  656         buffer_skip(packet, rdatalen);
  657         *softfail = 1;
  658         return 1; /* not fatal error */
  659     } else {
  660         /* find the RR in the rrset */
  661         domain_table_type *temptable;
  662         rdata_atom_type *rdatas;
  663         ssize_t rdata_num;
  664         int rrnum;
  665         temptable = domain_table_create(temp_region);
  666         /* This will ensure that the dnames in rdata are
  667          * normalized, conform RFC 4035, section 6.2
  668          */
  669         rdata_num = rdata_wireformat_to_rdata_atoms(
  670             temp_region, temptable, type, rdatalen, packet, &rdatas);
  671         if(rdata_num == -1) {
  672             log_msg(LOG_ERR, "diff: bad rdata for %s",
  673                 dname_to_string(dname,0));
  674             return 0;
  675         }
  676         rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 0);
  677         if(rrnum == -1 && type == TYPE_SOA && domain == zone->apex
  678             && rrset->rr_count != 0)
  679             rrnum = 0; /* replace existing SOA if no match */
  680         if(rrnum == -1) {
  681             log_msg(LOG_WARNING, "diff: RR <%s, %s> does not exist",
  682                 dname_to_string(dname,0), rrtype_to_string(type));
  683             *softfail = 1;
  684             return 1; /* not fatal error */
  685         }
  686         /* delete the normalized RR from the udb */
  687         if(db->udb)
  688             udb_del_rr(db->udb, udbz, &rrset->rrs[rrnum]);
  689 #ifdef NSEC3
  690         /* process triggers for RR deletions */
  691         nsec3_delete_rr_trigger(db, &rrset->rrs[rrnum], zone, udbz);
  692 #endif
  693         /* lower usage (possibly deleting other domains, and thus
  694          * invalidating the current RR's domain pointers) */
  695         rr_lower_usage(db, &rrset->rrs[rrnum]);
  696         if(rrset->rr_count == 1) {
  697             /* delete entire rrset */
  698             rrset_delete(db, domain, rrset);
  699             /* check if domain is now nonexisting (or parents) */
  700             rrset_zero_nonexist_check(domain, NULL);
  701 #ifdef NSEC3
  702             /* cleanup nsec3 */
  703             nsec3_delete_rrset_trigger(db, domain, zone, type);
  704 #endif
  705             /* see if the domain can be deleted (and inspect parents) */
  706             domain_table_deldomain(db, domain);
  707         } else {
  708             /* swap out the bad RR and decrease the count */
  709             rr_type* rrs_orig = rrset->rrs;
  710             add_rdata_to_recyclebin(db, &rrset->rrs[rrnum]);
  711             if(rrnum < rrset->rr_count-1)
  712                 rrset->rrs[rrnum] = rrset->rrs[rrset->rr_count-1];
  713             memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
  714             /* realloc the rrs array one smaller */
  715             rrset->rrs = region_alloc_array_init(db->region, rrs_orig,
  716                 (rrset->rr_count-1), sizeof(rr_type));
  717             if(!rrset->rrs) {
  718                 log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
  719                 exit(1);
  720             }
  721             region_recycle(db->region, rrs_orig,
  722                 sizeof(rr_type) * rrset->rr_count);
  723 #ifdef NSEC3
  724             if(type == TYPE_NSEC3PARAM && zone->nsec3_param) {
  725                 /* fixup nsec3_param pointer to same RR */
  726                 assert(zone->nsec3_param >= rrs_orig &&
  727                     zone->nsec3_param <=
  728                     rrs_orig+rrset->rr_count);
  729                 /* last moved to rrnum, others at same index*/
  730                 if(zone->nsec3_param == &rrs_orig[
  731                     rrset->rr_count-1])
  732                     zone->nsec3_param = &rrset->rrs[rrnum];
  733                 else
  734                     zone->nsec3_param =
  735                         (void*)zone->nsec3_param
  736                         -(void*)rrs_orig +
  737                         (void*)rrset->rrs;
  738             }
  739 #endif /* NSEC3 */
  740             rrset->rr_count --;
  741 #ifdef NSEC3
  742             /* for type nsec3, the domain may have become a
  743              * 'normal' domain with its remaining data now */
  744             if(type == TYPE_NSEC3)
  745                 nsec3_rrsets_changed_add_prehash(db, domain,
  746                     zone);
  747 #endif /* NSEC3 */
  748         }
  749     }
  750     return 1;
  751 }
  752 
  753 int
  754 add_RR(namedb_type* db, const dname_type* dname,
  755     uint16_t type, uint16_t klass, uint32_t ttl,
  756     buffer_type* packet, size_t rdatalen, zone_type *zone, udb_ptr* udbz,
  757     int* softfail)
  758 {
  759     domain_type* domain;
  760     rrset_type* rrset;
  761     rdata_atom_type *rdatas;
  762     rr_type *rrs_old;
  763     ssize_t rdata_num;
  764     int rrnum;
  765 #ifdef NSEC3
  766     int rrset_added = 0;
  767 #endif
  768     domain = domain_table_find(db->domains, dname);
  769     if(!domain) {
  770         /* create the domain */
  771         domain = domain_table_insert(db->domains, dname);
  772     }
  773     rrset = domain_find_rrset(domain, zone, type);
  774     if(!rrset) {
  775         /* create the rrset */
  776         rrset = region_alloc(db->region, sizeof(rrset_type));
  777         if(!rrset) {
  778             log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
  779             exit(1);
  780         }
  781         rrset->zone = zone;
  782         rrset->rrs = 0;
  783         rrset->rr_count = 0;
  784         domain_add_rrset(domain, rrset);
  785 #ifdef NSEC3
  786         rrset_added = 1;
  787 #endif
  788     }
  789 
  790     /* dnames in rdata are normalized, conform RFC 4035,
  791      * Section 6.2
  792      */
  793     rdata_num = rdata_wireformat_to_rdata_atoms(
  794         db->region, db->domains, type, rdatalen, packet, &rdatas);
  795     if(rdata_num == -1) {
  796         log_msg(LOG_ERR, "diff: bad rdata for %s",
  797             dname_to_string(dname,0));
  798         return 0;
  799     }
  800     rrnum = find_rr_num(rrset, type, klass, rdatas, rdata_num, 1);
  801     if(rrnum != -1) {
  802         DEBUG(DEBUG_XFRD, 2, (LOG_ERR, "diff: RR <%s, %s> already exists",
  803             dname_to_string(dname,0), rrtype_to_string(type)));
  804         /* ignore already existing RR: lenient accepting of messages */
  805         *softfail = 1;
  806         return 1;
  807     }
  808     if(rrset->rr_count == 65535) {
  809         log_msg(LOG_ERR, "diff: too many RRs at %s",
  810             dname_to_string(dname,0));
  811         return 0;
  812     }
  813 
  814     /* re-alloc the rrs and add the new */
  815     rrs_old = rrset->rrs;
  816     rrset->rrs = region_alloc_array(db->region,
  817         (rrset->rr_count+1), sizeof(rr_type));
  818     if(!rrset->rrs) {
  819         log_msg(LOG_ERR, "out of memory, %s:%d", __FILE__, __LINE__);
  820         exit(1);
  821     }
  822     if(rrs_old)
  823         memcpy(rrset->rrs, rrs_old, rrset->rr_count * sizeof(rr_type));
  824     region_recycle(db->region, rrs_old, sizeof(rr_type) * rrset->rr_count);
  825     rrset->rr_count ++;
  826 
  827     rrset->rrs[rrset->rr_count - 1].owner = domain;
  828     rrset->rrs[rrset->rr_count - 1].rdatas = rdatas;
  829     rrset->rrs[rrset->rr_count - 1].ttl = ttl;
  830     rrset->rrs[rrset->rr_count - 1].type = type;
  831     rrset->rrs[rrset->rr_count - 1].klass = klass;
  832     rrset->rrs[rrset->rr_count - 1].rdata_count = rdata_num;
  833 
  834     /* see if it is a SOA */
  835     if(domain == zone->apex) {
  836         apex_rrset_checks(db, rrset, domain);
  837 #ifdef NSEC3
  838         if(type == TYPE_NSEC3PARAM && zone->nsec3_param) {
  839             /* the pointer just changed, fix it up to point
  840              * to the same record */
  841             assert(zone->nsec3_param >= rrs_old &&
  842                 zone->nsec3_param < rrs_old+rrset->rr_count);
  843             /* in this order to make sure no overflow/underflow*/
  844             zone->nsec3_param = (void*)zone->nsec3_param - 
  845                 (void*)rrs_old + (void*)rrset->rrs;
  846         }
  847 #endif /* NSEC3 */
  848     }
  849 
  850     /* write the just-normalized RR to the udb */
  851     if(db->udb) {
  852         if(!udb_write_rr(db->udb, udbz, &rrset->rrs[rrset->rr_count - 1])) {
  853             log_msg(LOG_ERR, "could not add RR to nsd.db, disk-space?");
  854             return 0;
  855         }
  856     }
  857 #ifdef NSEC3
  858     if(rrset_added) {
  859         domain_type* p = domain->parent;
  860         nsec3_add_rrset_trigger(db, domain, zone, type);
  861         /* go up and process (possibly created) empty nonterminals, 
  862          * until we hit the apex or root */
  863         while(p && p->rrsets == NULL && !p->is_apex) {
  864             nsec3_rrsets_changed_add_prehash(db, p, zone);
  865             p = p->parent;
  866         }
  867     }
  868     nsec3_add_rr_trigger(db, &rrset->rrs[rrset->rr_count - 1], zone, udbz);
  869 #endif /* NSEC3 */
  870     return 1;
  871 }
  872 
  873 static zone_type*
  874 find_or_create_zone(namedb_type* db, const dname_type* zone_name,
  875     struct nsd_options* opt, const char* zstr, const char* patname)
  876 {
  877     zone_type* zone;
  878     struct zone_options* zopt;
  879     zone = namedb_find_zone(db, zone_name);
  880     if(zone) {
  881         return zone;
  882     }
  883     zopt = zone_options_find(opt, zone_name);
  884     if(!zopt) {
  885         /* if _implicit_ then insert as _part_of_config */
  886         if(strncmp(patname, PATTERN_IMPLICIT_MARKER,
  887             strlen(PATTERN_IMPLICIT_MARKER)) == 0) {
  888             zopt = zone_options_create(opt->region);
  889             if(!zopt) return 0;
  890             zopt->part_of_config = 1;
  891             zopt->name = region_strdup(opt->region, zstr);
  892             zopt->pattern = pattern_options_find(opt, patname);
  893             if(!zopt->name || !zopt->pattern) return 0;
  894             if(!nsd_options_insert_zone(opt, zopt)) {
  895                 log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' "
  896                     "pattern %s", zstr, patname);
  897             }
  898         } else {
  899             /* create zone : presumably already added to zonelist
  900              * by xfrd, who wrote the AXFR or IXFR to disk, so we only
  901              * need to add it to our config.
  902              * This process does not need linesize and offset zonelist */
  903             zopt = zone_list_zone_insert(opt, zstr, patname, 0, 0);
  904             if(!zopt)
  905                 return 0;
  906         }
  907     }
  908     zone = namedb_zone_create(db, zone_name, zopt);
  909     return zone;
  910 }
  911 
  912 void
  913 delete_zone_rrs(namedb_type* db, zone_type* zone)
  914 {
  915     rrset_type *rrset;
  916     domain_type *domain = zone->apex, *next;
  917     int nonexist_check = 0;
  918     /* go through entire tree below the zone apex (incl subzones) */
  919     while(domain && domain_is_subdomain(domain, zone->apex))
  920     {
  921         DEBUG(DEBUG_XFRD,2, (LOG_INFO, "delete zone visit %s",
  922             domain_to_string(domain)));
  923         /* delete all rrsets of the zone */
  924         while((rrset = domain_find_any_rrset(domain, zone))) {
  925             /* lower usage can delete other domains */
  926             rrset_lower_usage(db, rrset);
  927             /* rrset del does not delete our domain(yet) */
  928             rrset_delete(db, domain, rrset);
  929             /* no rrset_zero_nonexist_check, do that later */
  930             if(domain->rrsets == 0)
  931                 nonexist_check = 1;
  932         }
  933         /* the delete upcoming could delete parents, but nothing next
  934          * or after the domain so store next ptr */
  935         next = domain_next(domain);
  936         /* see if the domain can be deleted (and inspect parents) */
  937         domain_table_deldomain(db, domain);
  938         domain = next;
  939     }
  940 
  941     /* check if data deletions have created nonexisting domain entries,
  942      * but after deleting domains so the checks are faster */
  943     if(nonexist_check) {
  944         domain_type* ce = NULL; /* for speeding up has_data_below */
  945         DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: zero rrset check"));
  946         domain = zone->apex;
  947         while(domain && domain_is_subdomain(domain, zone->apex))
  948         {
  949             /* the interesting domains should be existing==1
  950              * and rrsets==0, speeding up out processing of
  951              * sub-zones, since we only spuriously check empty
  952              * nonterminals */
  953             if(domain->is_existing)
  954                 ce = rrset_zero_nonexist_check(domain, ce);
  955             domain = domain_next(domain);
  956         }
  957     }
  958 
  959     DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "axfrdel: recyclebin holds %lu bytes",
  960         (unsigned long) region_get_recycle_size(db->region)));
  961 #ifndef NDEBUG
  962     if(nsd_debug_level >= 2)
  963         region_log_stats(db->region);
  964 #endif
  965 
  966     assert(zone->soa_rrset == 0);
  967     /* keep zone->soa_nx_rrset alloced: it is reused */
  968     assert(zone->ns_rrset == 0);
  969     assert(zone->is_secure == 0);
  970 }
  971 
  972 /* return value 0: syntaxerror,badIXFR, 1:OK, 2:done_and_skip_it */
  973 static int
  974 apply_ixfr(namedb_type* db, FILE *in, const char* zone, uint32_t serialno,
  975     struct nsd_options* opt, uint32_t seq_nr, uint32_t seq_total,
  976     int* is_axfr, int* delete_mode, int* rr_count,
  977     udb_ptr* udbz, struct zone** zone_res, const char* patname, int* bytes,
  978     int* softfail)
  979 {
  980     uint32_t msglen, checklen, pkttype;
  981     int qcount, ancount, counter;
  982     buffer_type* packet;
  983     region_type* region;
  984     int i;
  985     uint16_t rrlen;
  986     const dname_type *dname_zone, *dname;
  987     zone_type* zone_db;
  988 
  989     /* note that errors could not really happen due to format of the
  990      * packet since xfrd has checked all dnames and RRs before commit,
  991      * this is why the errors are fatal (exit process), it must be
  992      * something internal or a bad disk or something. */
  993 
  994     /* read ixfr packet RRs and apply to in memory db */
  995     if(!diff_read_32(in, &pkttype) || pkttype != DIFF_PART_XXFR) {
  996         log_msg(LOG_ERR, "could not read type or wrong type");
  997         return 0;
  998     }
  999 
 1000     if(!diff_read_32(in, &msglen)) {
 1001         log_msg(LOG_ERR, "could not read len");
 1002         return 0;
 1003     }
 1004 
 1005     if(msglen < QHEADERSZ) {
 1006         log_msg(LOG_ERR, "msg too short");
 1007         return 0;
 1008     }
 1009 
 1010     region = region_create(xalloc, free);
 1011     if(!region) {
 1012         log_msg(LOG_ERR, "out of memory");
 1013         return 0;
 1014     }
 1015     packet = buffer_create(region, QIOBUFSZ);
 1016     if(msglen > QIOBUFSZ) {
 1017         log_msg(LOG_ERR, "msg too long");
 1018         region_destroy(region);
 1019         return 0;
 1020     }
 1021     buffer_clear(packet);
 1022     if(fread(buffer_begin(packet), msglen, 1, in) != 1) {
 1023         log_msg(LOG_ERR, "short fread: %s", strerror(errno));
 1024         region_destroy(region);
 1025         return 0;
 1026     }
 1027     buffer_set_limit(packet, msglen);
 1028 
 1029     /* see if check on data fails: checks that we are not reading
 1030      * random garbage */
 1031     if(!diff_read_32(in, &checklen) || checklen != msglen) {
 1032         log_msg(LOG_ERR, "transfer part has incorrect checkvalue");
 1033         return 0;
 1034     }
 1035     *bytes += msglen;
 1036 
 1037     dname_zone = dname_parse(region, zone);
 1038     zone_db = find_or_create_zone(db, dname_zone, opt, zone, patname);
 1039     if(!zone_db) {
 1040         log_msg(LOG_ERR, "could not create zone %s %s", zone, patname);
 1041         region_destroy(region);
 1042         return 0;
 1043     }
 1044     *zone_res = zone_db;
 1045 
 1046     /* only answer section is really used, question, additional and
 1047        authority section RRs are skipped */
 1048     qcount = QDCOUNT(packet);
 1049     ancount = ANCOUNT(packet);
 1050     buffer_skip(packet, QHEADERSZ);
 1051     /* qcount should be 0 or 1 really, ancount limited by 64k packet */
 1052     if(qcount > 64 || ancount > 65530) {
 1053         log_msg(LOG_ERR, "RR count impossibly high");
 1054         region_destroy(region);
 1055         return 0;
 1056     }
 1057 
 1058     /* skip queries */
 1059     for(i=0; i<qcount; ++i)
 1060         if(!packet_skip_rr(packet, 1)) {
 1061             log_msg(LOG_ERR, "bad RR in question section");
 1062             region_destroy(region);
 1063             return 0;
 1064         }
 1065 
 1066     DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: started packet for zone %s",
 1067             dname_to_string(dname_zone, 0)));
 1068     /* first RR: check if SOA and correct zone & serialno */
 1069     if(*rr_count == 0) {
 1070         DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s parse first RR",
 1071             dname_to_string(dname_zone, 0)));
 1072         dname = dname_make_from_packet(region, packet, 1, 1);
 1073         if(!dname) {
 1074             log_msg(LOG_ERR, "could not parse dname");
 1075             region_destroy(region);
 1076             return 0;
 1077         }
 1078         if(dname_compare(dname_zone, dname) != 0) {
 1079             log_msg(LOG_ERR, "SOA dname %s not equal to zone",
 1080                 dname_to_string(dname,0));
 1081             log_msg(LOG_ERR, "zone dname is %s",
 1082                 dname_to_string(dname_zone,0));
 1083             region_destroy(region);
 1084             return 0;
 1085         }
 1086         if(!buffer_available(packet, 10)) {
 1087             log_msg(LOG_ERR, "bad SOA RR");
 1088             region_destroy(region);
 1089             return 0;
 1090         }
 1091         if(buffer_read_u16(packet) != TYPE_SOA ||
 1092             buffer_read_u16(packet) != CLASS_IN) {
 1093             log_msg(LOG_ERR, "first RR not SOA IN");
 1094             region_destroy(region);
 1095             return 0;
 1096         }
 1097         buffer_skip(packet, sizeof(uint32_t)); /* ttl */
 1098         if(!buffer_available(packet, buffer_read_u16(packet)) ||
 1099             !packet_skip_dname(packet) /* skip prim_ns */ ||
 1100             !packet_skip_dname(packet) /* skip email */) {
 1101             log_msg(LOG_ERR, "bad SOA RR");
 1102             region_destroy(region);
 1103             return 0;
 1104         }
 1105         if(buffer_read_u32(packet) != serialno) {
 1106             buffer_skip(packet, -4);
 1107             log_msg(LOG_ERR, "SOA serial %u different from commit %u",
 1108                 (unsigned)buffer_read_u32(packet), (unsigned)serialno);
 1109             region_destroy(region);
 1110             return 0;
 1111         }
 1112         buffer_skip(packet, sizeof(uint32_t)*4);
 1113         counter = 1;
 1114         *rr_count = 1;
 1115         *is_axfr = 0;
 1116         *delete_mode = 0;
 1117         DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s start count %d, ax %d, delmode %d",
 1118             dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode));
 1119     }
 1120     else  counter = 0;
 1121 
 1122     for(; counter < ancount; ++counter,++(*rr_count))
 1123     {
 1124         uint16_t type, klass;
 1125         uint32_t ttl;
 1126 
 1127         if(!(dname=dname_make_from_packet(region, packet, 1,1))) {
 1128             log_msg(LOG_ERR, "bad xfr RR dname %d", *rr_count);
 1129             region_destroy(region);
 1130             return 0;
 1131         }
 1132         if(!buffer_available(packet, 10)) {
 1133             log_msg(LOG_ERR, "bad xfr RR format %d", *rr_count);
 1134             region_destroy(region);
 1135             return 0;
 1136         }
 1137         type = buffer_read_u16(packet);
 1138         klass = buffer_read_u16(packet);
 1139         ttl = buffer_read_u32(packet);
 1140         rrlen = buffer_read_u16(packet);
 1141         if(!buffer_available(packet, rrlen)) {
 1142             log_msg(LOG_ERR, "bad xfr RR rdata %d, len %d have %d",
 1143                 *rr_count, rrlen, (int)buffer_remaining(packet));
 1144             region_destroy(region);
 1145             return 0;
 1146         }
 1147         DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s parsed count %d, ax %d, delmode %d",
 1148             dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode));
 1149 
 1150         if(*rr_count == 1 && type != TYPE_SOA) {
 1151             /* second RR: if not SOA: this is an AXFR; delete all zone contents */
 1152 #ifdef NSEC3
 1153             nsec3_clear_precompile(db, zone_db);
 1154             zone_db->nsec3_param = NULL;
 1155 #endif
 1156             delete_zone_rrs(db, zone_db);
 1157             if(db->udb)
 1158                 udb_zone_clear(db->udb, udbz);
 1159             /* add everything else (incl end SOA) */
 1160             *delete_mode = 0;
 1161             *is_axfr = 1;
 1162             DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s sawAXFR count %d, ax %d, delmode %d",
 1163                 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode));
 1164         }
 1165         if(*rr_count == 1 && type == TYPE_SOA) {
 1166             /* if the serial no of the SOA equals the serialno, then AXFR */
 1167             size_t bufpos = buffer_position(packet);
 1168             uint32_t thisserial;
 1169             if(!packet_skip_dname(packet) ||
 1170                 !packet_skip_dname(packet) ||
 1171                 buffer_remaining(packet) < sizeof(uint32_t)*5)
 1172             {
 1173                 log_msg(LOG_ERR, "bad xfr SOA RR formerr.");
 1174                 region_destroy(region);
 1175                 return 0;
 1176             }
 1177             thisserial = buffer_read_u32(packet);
 1178             if(thisserial == serialno) {
 1179                 /* AXFR */
 1180 #ifdef NSEC3
 1181                 nsec3_clear_precompile(db, zone_db);
 1182                 zone_db->nsec3_param = NULL;
 1183 #endif
 1184                 delete_zone_rrs(db, zone_db);
 1185                 if(db->udb)
 1186                     udb_zone_clear(db->udb, udbz);
 1187                 *delete_mode = 0;
 1188                 *is_axfr = 1;
 1189             }
 1190             /* must have stuff in memory for a successful IXFR,
 1191              * the serial number of the SOA has been checked
 1192              * previously (by check_for_bad_serial) if it exists */
 1193             if(!*is_axfr && !domain_find_rrset(zone_db->apex,
 1194                 zone_db, TYPE_SOA)) {
 1195                 log_msg(LOG_ERR, "%s SOA serial %u is not "
 1196                     "in memory, skip IXFR", zone, serialno);
 1197                 region_destroy(region);
 1198                 /* break out and stop the IXFR, ignore it */
 1199                 return 2;
 1200             }
 1201             buffer_set_position(packet, bufpos);
 1202         }
 1203         if(type == TYPE_SOA && !*is_axfr) {
 1204             /* switch from delete-part to add-part and back again,
 1205                just before soa - so it gets deleted and added too */
 1206             /* this means we switch to delete mode for the final SOA */
 1207             *delete_mode = !*delete_mode;
 1208             DEBUG(DEBUG_XFRD,2, (LOG_INFO, "diff: %s IXFRswapdel count %d, ax %d, delmode %d",
 1209                 dname_to_string(dname_zone, 0), *rr_count, *is_axfr, *delete_mode));
 1210         }
 1211         if(type == TYPE_TSIG || type == TYPE_OPT) {
 1212             /* ignore pseudo RRs */
 1213             buffer_skip(packet, rrlen);
 1214             continue;
 1215         }
 1216 
 1217         DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfr %s RR dname is %s type %s",
 1218             *delete_mode?"del":"add",
 1219             dname_to_string(dname,0), rrtype_to_string(type)));
 1220         if(*delete_mode) {
 1221             /* delete this rr */
 1222             if(!*is_axfr && type == TYPE_SOA && counter==ancount-1
 1223                 && seq_nr == seq_total-1) {
 1224                 continue; /* do not delete final SOA RR for IXFR */
 1225             }
 1226             if(!delete_RR(db, dname, type, klass, packet,
 1227                 rrlen, zone_db, region, udbz, softfail)) {
 1228                 region_destroy(region);
 1229                 return 0;
 1230             }
 1231         }
 1232         else
 1233         {
 1234             /* add this rr */
 1235             if(!add_RR(db, dname, type, klass, ttl, packet,
 1236                 rrlen, zone_db, udbz, softfail)) {
 1237                 region_destroy(region);
 1238                 return 0;
 1239             }
 1240         }
 1241     }
 1242     region_destroy(region);
 1243     return 1;
 1244 }
 1245 
 1246 static int
 1247 check_for_bad_serial(namedb_type* db, const char* zone_str, uint32_t old_serial)
 1248 {
 1249     /* see if serial OK with in-memory serial */
 1250     domain_type* domain;
 1251     region_type* region = region_create(xalloc, free);
 1252     const dname_type* zone_name = dname_parse(region, zone_str);
 1253     zone_type* zone = 0;
 1254     domain = domain_table_find(db->domains, zone_name);
 1255     if(domain)
 1256         zone = domain_find_zone(db, domain);
 1257     if(zone && zone->apex == domain && zone->soa_rrset && old_serial)
 1258     {
 1259         uint32_t memserial;
 1260         memcpy(&memserial, rdata_atom_data(zone->soa_rrset->rrs[0].rdatas[2]),
 1261             sizeof(uint32_t));
 1262         if(old_serial != ntohl(memserial)) {
 1263             region_destroy(region);
 1264             return 1;
 1265         }
 1266     }
 1267     region_destroy(region);
 1268     return 0;
 1269 }
 1270 
 1271 static int
 1272 apply_ixfr_for_zone(nsd_type* nsd, zone_type* zonedb, FILE* in,
 1273     struct nsd_options* opt, udb_base* taskudb, udb_ptr* last_task,
 1274     uint32_t xfrfilenr)
 1275 {
 1276     char zone_buf[3072];
 1277     char log_buf[5120];
 1278     char patname_buf[2048];
 1279 
 1280     uint32_t old_serial, new_serial, num_parts, type;
 1281     uint64_t time_end_0, time_start_0;
 1282     uint32_t time_end_1, time_start_1;
 1283     uint8_t committed;
 1284     uint32_t i;
 1285     int num_bytes = 0;
 1286     assert(zonedb);
 1287 
 1288     /* read zone name and serial */
 1289     if(!diff_read_32(in, &type)) {
 1290         log_msg(LOG_ERR, "diff file too short");
 1291         return 0;
 1292     }
 1293     if(type != DIFF_PART_XFRF) {
 1294         log_msg(LOG_ERR, "xfr file has wrong format");
 1295         return 0;
 1296 
 1297     }
 1298     /* committed and num_parts are first because they need to be
 1299      * updated once the rest is written.  The log buf is not certain
 1300      * until its done, so at end of file.  The patname is in case a
 1301      * new zone is created, we know what the options-pattern is */
 1302     if(!diff_read_8(in, &committed) ||
 1303         !diff_read_32(in, &num_parts) ||
 1304         !diff_read_64(in, &time_end_0) ||
 1305         !diff_read_32(in, &time_end_1) ||
 1306         !diff_read_32(in, &old_serial) ||
 1307         !diff_read_32(in, &new_serial) ||
 1308         !diff_read_64(in, &time_start_0) ||
 1309         !diff_read_32(in, &time_start_1) ||
 1310         !diff_read_str(in, zone_buf, sizeof(zone_buf)) ||
 1311         !diff_read_str(in, patname_buf, sizeof(patname_buf))) {
 1312         log_msg(LOG_ERR, "diff file bad commit part");
 1313         return 0;
 1314     }
 1315 
 1316     /* has been read in completely */
 1317     if(strcmp(zone_buf, domain_to_string(zonedb->apex)) != 0) {
 1318         log_msg(LOG_ERR, "file %s does not match task %s",
 1319             zone_buf, domain_to_string(zonedb->apex));
 1320         return 0;
 1321     }
 1322     if(!committed) {
 1323         log_msg(LOG_ERR, "diff file %s was not committed", zone_buf);
 1324         return 0;
 1325     }
 1326     if(num_parts == 0) {
 1327         log_msg(LOG_ERR, "diff file %s was not completed", zone_buf);
 1328         return 0;
 1329     }
 1330     if(check_for_bad_serial(nsd->db, zone_buf, old_serial)) {
 1331         DEBUG(DEBUG_XFRD,1, (LOG_ERR,
 1332             "skipping diff file commit with bad serial"));
 1333         return 1;
 1334     }
 1335 
 1336     if(committed)
 1337     {
 1338         int is_axfr=0, delete_mode=0, rr_count=0, softfail=0;
 1339         const dname_type* apex = domain_dname_const(zonedb->apex);
 1340         udb_ptr z;
 1341 
 1342         DEBUG(DEBUG_XFRD,1, (LOG_INFO, "processing xfr: %s", zone_buf));
 1343         memset(&z, 0, sizeof(z)); /* if udb==NULL, have &z defined */
 1344         if(nsd->db->udb) {
 1345             if(udb_base_get_userflags(nsd->db->udb) != 0) {
 1346                 log_msg(LOG_ERR, "database corrupted, cannot update");
 1347                 xfrd_unlink_xfrfile(nsd, xfrfilenr);
 1348                 exit(1);
 1349             }
 1350             /* all parts were checked by xfrd before commit */
 1351             if(!udb_zone_search(nsd->db->udb, &z, dname_name(apex),
 1352                 apex->name_size)) {
 1353                 /* create it */
 1354                 if(!udb_zone_create(nsd->db->udb, &z, dname_name(apex),
 1355                     apex->name_size)) {
 1356                     /* out of disk space perhaps */
 1357                     log_msg(LOG_ERR, "could not udb_create_zone "
 1358                         "%s, disk space full?", zone_buf);
 1359                     return 0;
 1360                 }
 1361             }
 1362             /* set the udb dirty until we are finished applying changes */
 1363             udb_base_set_userflags(nsd->db->udb, 1);
 1364         }
 1365         /* read and apply all of the parts */
 1366         for(i=0; i<num_parts; i++) {
 1367             int ret;
 1368             DEBUG(DEBUG_XFRD,2, (LOG_INFO, "processing xfr: apply part %d", (int)i));
 1369             ret = apply_ixfr(nsd->db, in, zone_buf, new_serial, opt,
 1370                 i, num_parts, &is_axfr, &delete_mode,
 1371                 &rr_count, (nsd->db->udb?&z:NULL), &zonedb,
 1372                 patname_buf, &num_bytes, &softfail);
 1373             assert(zonedb);
 1374             if(ret == 0) {
 1375                 log_msg(LOG_ERR, "bad ixfr packet part %d in diff file for %s", (int)i, zone_buf);
 1376                 xfrd_unlink_xfrfile(nsd, xfrfilenr);
 1377                 /* the udb is still dirty, it is bad */
 1378                 exit(1);
 1379             } else if(ret == 2) {
 1380                 break;
 1381             }
 1382         }
 1383         if(nsd->db->udb)
 1384             udb_base_set_userflags(nsd->db->udb, 0);
 1385         /* read the final log_str: but do not fail on it */
 1386         if(!diff_read_str(in, log_buf, sizeof(log_buf))) {
 1387             log_msg(LOG_ERR, "could not read log for transfer %s",
 1388                 zone_buf);
 1389             snprintf(log_buf, sizeof(log_buf), "error reading log");
 1390         }
 1391 #ifdef NSEC3
 1392         if(zonedb) prehash_zone(nsd->db, zonedb);
 1393 #endif /* NSEC3 */
 1394         zonedb->is_changed = 1;
 1395         if(nsd->db->udb) {
 1396             assert(z.base);
 1397             ZONE(&z)->is_changed = 1;
 1398             ZONE(&z)->mtime = time_end_0;
 1399             ZONE(&z)->mtime_nsec = time_end_1*1000;
 1400             udb_zone_set_log_str(nsd->db->udb, &z, log_buf);
 1401             udb_zone_set_file_str(nsd->db->udb, &z, NULL);
 1402             udb_ptr_unlink(&z, nsd->db->udb);
 1403         } else {
 1404             zonedb->mtime.tv_sec = time_end_0;
 1405             zonedb->mtime.tv_nsec = time_end_1*1000;
 1406             if(zonedb->logstr)
 1407                 region_recycle(nsd->db->region, zonedb->logstr,
 1408                     strlen(zonedb->logstr)+1);
 1409             zonedb->logstr = region_strdup(nsd->db->region, log_buf);
 1410             if(zonedb->filename)
 1411                 region_recycle(nsd->db->region, zonedb->filename,
 1412                     strlen(zonedb->filename)+1);
 1413             zonedb->filename = NULL;
 1414         }
 1415         if(softfail && taskudb && !is_axfr) {
 1416             log_msg(LOG_ERR, "Failed to apply IXFR cleanly "
 1417                 "(deletes nonexistent RRs, adds existing RRs). "
 1418                 "Zone %s contents is different from master, "
 1419                 "starting AXFR. Transfer %s", zone_buf, log_buf);
 1420             /* add/del failures in IXFR, get an AXFR */
 1421             task_new_soainfo(taskudb, last_task, zonedb, 1);
 1422         } else {
 1423             if(taskudb)
 1424                 task_new_soainfo(taskudb, last_task, zonedb, 0);
 1425         }
 1426 
 1427         if(1 <= verbosity) {
 1428             double elapsed = (double)(time_end_0 - time_start_0)+
 1429                 (double)((double)time_end_1
 1430                 -(double)time_start_1) / 1000000.0;
 1431             VERBOSITY(1, (LOG_INFO, "zone %s %s of %d bytes in %g seconds",
 1432                 zone_buf, log_buf, num_bytes, elapsed));
 1433         }
 1434     }
 1435     else {
 1436         DEBUG(DEBUG_XFRD,1, (LOG_INFO, "skipping xfr: %s", log_buf));
 1437     }
 1438     return 1;
 1439 }
 1440 
 1441 struct udb_base* task_file_create(const char* file)
 1442 {
 1443         return udb_base_create_new(file, &namedb_walkfunc, NULL);
 1444 }
 1445 
 1446 static int
 1447 task_create_new_elem(struct udb_base* udb, udb_ptr* last, udb_ptr* e,
 1448     size_t sz, const dname_type* zname)
 1449 {
 1450     if(!udb_ptr_alloc_space(e, udb, udb_chunk_type_task, sz)) {
 1451         return 0;
 1452     }
 1453     if(udb_ptr_is_null(last)) {
 1454         udb_base_set_userdata(udb, e->data);
 1455     } else {
 1456         udb_rptr_set_ptr(&TASKLIST(last)->next, udb, e);
 1457     }
 1458     udb_ptr_set_ptr(last, udb, e);
 1459 
 1460     /* fill in tasklist item */
 1461     udb_rel_ptr_init(&TASKLIST(e)->next);
 1462     TASKLIST(e)->size = sz;
 1463     TASKLIST(e)->oldserial = 0;
 1464     TASKLIST(e)->newserial = 0;
 1465     TASKLIST(e)->yesno = 0;
 1466 
 1467     if(zname) {
 1468         memmove(TASKLIST(e)->zname, zname, dname_total_size(zname));
 1469     }
 1470     return 1;
 1471 }
 1472 
 1473 void task_new_soainfo(struct udb_base* udb, udb_ptr* last, struct zone* z,
 1474     int gone)
 1475 {
 1476     /* calculate size */
 1477     udb_ptr e;
 1478     size_t sz;
 1479     const dname_type* apex, *ns, *em;
 1480     if(!z || !z->apex || !domain_dname(z->apex))
 1481         return; /* safety check */
 1482 
 1483     DEBUG(DEBUG_IPC,1, (LOG_INFO, "nsd: add soa info for zone %s",
 1484         domain_to_string(z->apex)));
 1485     apex = domain_dname(z->apex);
 1486     sz = sizeof(struct task_list_d) + dname_total_size(apex);
 1487     if(z->soa_rrset && !gone) {
 1488         ns = domain_dname(rdata_atom_domain(
 1489             z->soa_rrset->rrs[0].rdatas[0]));
 1490         em = domain_dname(rdata_atom_domain(
 1491             z->soa_rrset->rrs[0].rdatas[1]));
 1492         sz += sizeof(uint32_t)*6 + sizeof(uint8_t)*2
 1493             + ns->name_size + em->name_size;
 1494     } else {
 1495         ns = 0;
 1496         em = 0;
 1497     }
 1498 
 1499     /* create new task_list item */
 1500     if(!task_create_new_elem(udb, last, &e, sz, apex)) {
 1501         log_msg(LOG_ERR, "tasklist: out of space, cannot add SOAINFO");
 1502         return;
 1503     }
 1504     TASKLIST(&e)->task_type = task_soa_info;
 1505 
 1506     if(z->soa_rrset && !gone) {
 1507         uint32_t ttl = htonl(z->soa_rrset->rrs[0].ttl);
 1508         uint8_t* p = (uint8_t*)TASKLIST(&e)->zname;
 1509         p += dname_total_size(apex);
 1510         memmove(p, &ttl, sizeof(uint32_t));
 1511         p += sizeof(uint32_t);
 1512         memmove(p, &ns->name_size, sizeof(uint8_t));
 1513         p += sizeof(uint8_t);
 1514         memmove(p, dname_name(ns), ns->name_size);
 1515         p += ns->name_size;
 1516         memmove(p, &em->name_size, sizeof(uint8_t));
 1517         p += sizeof(uint8_t);
 1518         memmove(p, dname_name(em), em->name_size);
 1519         p += em->name_size;
 1520         memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[2]),
 1521             sizeof(uint32_t));
 1522         p += sizeof(uint32_t);
 1523         memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[3]),
 1524             sizeof(uint32_t));
 1525         p += sizeof(uint32_t);
 1526         memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[4]),
 1527             sizeof(uint32_t));
 1528         p += sizeof(uint32_t);
 1529         memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[5]),
 1530             sizeof(uint32_t));
 1531         p += sizeof(uint32_t);
 1532         memmove(p, rdata_atom_data(z->soa_rrset->rrs[0].rdatas[6]),
 1533             sizeof(uint32_t));
 1534     }
 1535     udb_ptr_unlink(&e, udb);
 1536 }
 1537 
 1538 void task_process_sync(struct udb_base* taskudb)
 1539 {
 1540     /* need to sync before other process uses the mmap? */
 1541     DEBUG(DEBUG_IPC,1, (LOG_INFO, "task procsync %s size %d",
 1542         taskudb->fname, (int)taskudb->base_size));
 1543     (void)taskudb;
 1544 }
 1545 
 1546 void task_remap(struct udb_base* taskudb)
 1547 {
 1548     DEBUG(DEBUG_IPC,1, (LOG_INFO, "task remap %s size %d",
 1549         taskudb->fname, (int)taskudb->glob_data->fsize));
 1550     udb_base_remap_process(taskudb);
 1551 }
 1552 
 1553 void task_clear(struct udb_base* taskudb)
 1554 {
 1555     udb_ptr t, n;
 1556     udb_ptr_new(&t, taskudb, udb_base_get_userdata(taskudb));
 1557     udb_base_set_userdata(taskudb, 0);
 1558     udb_ptr_init(&n, taskudb);
 1559     while(!udb_ptr_is_null(&t)) {
 1560         udb_ptr_set_rptr(&n, taskudb, &TASKLIST(&t)->next);
 1561         udb_rptr_zero(&TASKLIST(&t)->next, taskudb);
 1562         udb_ptr_free_space(&t, taskudb, TASKLIST(&t)->size);
 1563         udb_ptr_set_ptr(&t, taskudb, &n);
 1564     }
 1565     udb_ptr_unlink(&t, taskudb);
 1566     udb_ptr_unlink(&n, taskudb);
 1567 }
 1568 
 1569 void task_new_expire(struct udb_base* udb, udb_ptr* last,
 1570     const struct dname* z, int expired)
 1571 {
 1572     udb_ptr e;
 1573     if(!z) return;
 1574     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add expire info for zone %s",
 1575         dname_to_string(z,NULL)));
 1576     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+
 1577         dname_total_size(z), z)) {
 1578         log_msg(LOG_ERR, "tasklist: out of space, cannot add expire");
 1579         return;
 1580     }
 1581     TASKLIST(&e)->task_type = task_expire;
 1582     TASKLIST(&e)->yesno = expired;
 1583     udb_ptr_unlink(&e, udb);
 1584 }
 1585 
 1586 void task_new_check_zonefiles(udb_base* udb, udb_ptr* last,
 1587     const dname_type* zone)
 1588 {
 1589     udb_ptr e;
 1590     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task checkzonefiles"));
 1591     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) +
 1592         (zone?dname_total_size(zone):0), zone)) {
 1593         log_msg(LOG_ERR, "tasklist: out of space, cannot add check_zones");
 1594         return;
 1595     }
 1596     TASKLIST(&e)->task_type = task_check_zonefiles;
 1597     TASKLIST(&e)->yesno = (zone!=NULL);
 1598     udb_ptr_unlink(&e, udb);
 1599 }
 1600 
 1601 void task_new_write_zonefiles(udb_base* udb, udb_ptr* last,
 1602     const dname_type* zone)
 1603 {
 1604     udb_ptr e;
 1605     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task writezonefiles"));
 1606     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d) +
 1607         (zone?dname_total_size(zone):0), zone)) {
 1608         log_msg(LOG_ERR, "tasklist: out of space, cannot add writezones");
 1609         return;
 1610     }
 1611     TASKLIST(&e)->task_type = task_write_zonefiles;
 1612     TASKLIST(&e)->yesno = (zone!=NULL);
 1613     udb_ptr_unlink(&e, udb);
 1614 }
 1615 
 1616 void task_new_set_verbosity(udb_base* udb, udb_ptr* last, int v)
 1617 {
 1618     udb_ptr e;
 1619     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task set_verbosity"));
 1620     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d),
 1621         NULL)) {
 1622         log_msg(LOG_ERR, "tasklist: out of space, cannot add set_v");
 1623         return;
 1624     }
 1625     TASKLIST(&e)->task_type = task_set_verbosity;
 1626     TASKLIST(&e)->yesno = v;
 1627     udb_ptr_unlink(&e, udb);
 1628 }
 1629 
 1630 #ifdef BIND8_STATS
 1631 void* task_new_stat_info(udb_base* udb, udb_ptr* last, struct nsdst* stat,
 1632     size_t child_count)
 1633 {
 1634     void* p;
 1635     udb_ptr e;
 1636     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task stat_info"));
 1637     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+
 1638         sizeof(*stat) + sizeof(stc_type)*child_count, NULL)) {
 1639         log_msg(LOG_ERR, "tasklist: out of space, cannot add stati");
 1640         return NULL;
 1641     }
 1642     TASKLIST(&e)->task_type = task_stat_info;
 1643     p = TASKLIST(&e)->zname;
 1644     memcpy(p, stat, sizeof(*stat));
 1645     udb_ptr_unlink(&e, udb);
 1646     return (char*)p + sizeof(*stat);
 1647 }
 1648 #endif /* BIND8_STATS */
 1649 
 1650 void
 1651 task_new_add_zone(udb_base* udb, udb_ptr* last, const char* zone,
 1652     const char* pattern, unsigned zonestatid)
 1653 {
 1654     size_t zlen = strlen(zone);
 1655     size_t plen = strlen(pattern);
 1656     void *p;
 1657     udb_ptr e;
 1658     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addzone %s %s", zone, pattern));
 1659     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)+
 1660         zlen + 1 + plen + 1, NULL)) {
 1661         log_msg(LOG_ERR, "tasklist: out of space, cannot add addz");
 1662         return;
 1663     }
 1664     TASKLIST(&e)->task_type = task_add_zone;
 1665     TASKLIST(&e)->yesno = zonestatid;
 1666     p = TASKLIST(&e)->zname;
 1667     memcpy(p, zone, zlen+1);
 1668     memmove((char*)p+zlen+1, pattern, plen+1);
 1669     udb_ptr_unlink(&e, udb);
 1670 }
 1671 
 1672 void
 1673 task_new_del_zone(udb_base* udb, udb_ptr* last, const dname_type* dname)
 1674 {
 1675     udb_ptr e;
 1676     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delzone %s", dname_to_string(dname, 0)));
 1677     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1678         +dname_total_size(dname), dname)) {
 1679         log_msg(LOG_ERR, "tasklist: out of space, cannot add delz");
 1680         return;
 1681     }
 1682     TASKLIST(&e)->task_type = task_del_zone;
 1683     udb_ptr_unlink(&e, udb);
 1684 }
 1685 
 1686 void task_new_add_key(udb_base* udb, udb_ptr* last, struct key_options* key)
 1687 {
 1688     char* p;
 1689     udb_ptr e;
 1690     assert(key->name && key->algorithm && key->secret);
 1691     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addkey"));
 1692     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1693         +strlen(key->name)+1+strlen(key->algorithm)+1+
 1694         strlen(key->secret)+1, NULL)) {
 1695         log_msg(LOG_ERR, "tasklist: out of space, cannot add addk");
 1696         return;
 1697     }
 1698     TASKLIST(&e)->task_type = task_add_key;
 1699     p = (char*)TASKLIST(&e)->zname;
 1700     memmove(p, key->name, strlen(key->name)+1);
 1701     p+=strlen(key->name)+1;
 1702     memmove(p, key->algorithm, strlen(key->algorithm)+1);
 1703     p+=strlen(key->algorithm)+1;
 1704     memmove(p, key->secret, strlen(key->secret)+1);
 1705     udb_ptr_unlink(&e, udb);
 1706 }
 1707 
 1708 void task_new_del_key(udb_base* udb, udb_ptr* last, const char* name)
 1709 {
 1710     char* p;
 1711     udb_ptr e;
 1712     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delkey"));
 1713     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1714         +strlen(name)+1, NULL)) {
 1715         log_msg(LOG_ERR, "tasklist: out of space, cannot add delk");
 1716         return;
 1717     }
 1718     TASKLIST(&e)->task_type = task_del_key;
 1719     p = (char*)TASKLIST(&e)->zname;
 1720     memmove(p, name, strlen(name)+1);
 1721     udb_ptr_unlink(&e, udb);
 1722 }
 1723 
 1724 void task_new_add_cookie_secret(udb_base* udb, udb_ptr* last,
 1725                                  const char* secret) {
 1726     udb_ptr e;
 1727     char* p;
 1728     size_t const secret_size = strlen(secret) + 1;
 1729 
 1730     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task add_cookie_secret"));
 1731 
 1732     if(!task_create_new_elem(udb, last, &e,
 1733                              sizeof(struct task_list_d) + secret_size, NULL)) {
 1734         log_msg(LOG_ERR, "tasklist: out of space, cannot add add_cookie_secret");
 1735         return;
 1736     }
 1737     TASKLIST(&e)->task_type = task_add_cookie_secret;
 1738     p = (char*)TASKLIST(&e)->zname;
 1739     memmove(p, secret, secret_size);
 1740     udb_ptr_unlink(&e, udb);
 1741 }
 1742 
 1743 void task_new_drop_cookie_secret(udb_base* udb, udb_ptr* last) {
 1744     udb_ptr e;
 1745     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task drop_cookie_secret"));
 1746     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) {
 1747         log_msg(LOG_ERR, "tasklist: out of space, cannot add drop_cookie_secret");
 1748         return;
 1749     }
 1750     TASKLIST(&e)->task_type = task_drop_cookie_secret;
 1751     udb_ptr_unlink(&e, udb);
 1752 }
 1753 
 1754 void task_new_activate_cookie_secret(udb_base* udb, udb_ptr* last) {
 1755     udb_ptr e;
 1756     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add task activate_cookie_secret"));
 1757     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d), NULL)) {
 1758         log_msg(LOG_ERR, "tasklist: out of space, cannot add activate_cookie_secret");
 1759         return;
 1760     }
 1761     TASKLIST(&e)->task_type = task_activate_cookie_secret;
 1762     udb_ptr_unlink(&e, udb);
 1763 }
 1764 
 1765 void task_new_add_pattern(udb_base* udb, udb_ptr* last,
 1766     struct pattern_options* p)
 1767 {
 1768     region_type* temp;
 1769     buffer_type* buffer;
 1770     udb_ptr e;
 1771     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task addpattern %s", p->pname));
 1772     temp = region_create(xalloc, free);
 1773     buffer = buffer_create(temp, 4096);
 1774     pattern_options_marshal(buffer, p);
 1775     buffer_flip(buffer);
 1776     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1777         + buffer_limit(buffer), NULL)) {
 1778         log_msg(LOG_ERR, "tasklist: out of space, cannot add addp");
 1779         region_destroy(temp);
 1780         return;
 1781     }
 1782     TASKLIST(&e)->task_type = task_add_pattern;
 1783     TASKLIST(&e)->yesno = buffer_limit(buffer);
 1784     memmove(TASKLIST(&e)->zname, buffer_begin(buffer),
 1785         buffer_limit(buffer));
 1786     udb_ptr_unlink(&e, udb);
 1787     region_destroy(temp);
 1788 }
 1789 
 1790 void task_new_del_pattern(udb_base* udb, udb_ptr* last, const char* name)
 1791 {
 1792     char* p;
 1793     udb_ptr e;
 1794     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task delpattern %s", name));
 1795     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1796         +strlen(name)+1, NULL)) {
 1797         log_msg(LOG_ERR, "tasklist: out of space, cannot add delp");
 1798         return;
 1799     }
 1800     TASKLIST(&e)->task_type = task_del_pattern;
 1801     p = (char*)TASKLIST(&e)->zname;
 1802     memmove(p, name, strlen(name)+1);
 1803     udb_ptr_unlink(&e, udb);
 1804 }
 1805 
 1806 void task_new_opt_change(udb_base* udb, udb_ptr* last, struct nsd_options* opt)
 1807 {
 1808     udb_ptr e;
 1809     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task opt_change"));
 1810     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d),
 1811         NULL)) {
 1812         log_msg(LOG_ERR, "tasklist: out of space, cannot add o_c");
 1813         return;
 1814     }
 1815     TASKLIST(&e)->task_type = task_opt_change;
 1816 #ifdef RATELIMIT
 1817     TASKLIST(&e)->oldserial = opt->rrl_ratelimit;
 1818     TASKLIST(&e)->newserial = opt->rrl_whitelist_ratelimit;
 1819     TASKLIST(&e)->yesno = (uint64_t) opt->rrl_slip;
 1820 #else
 1821     (void)opt;
 1822 #endif
 1823     udb_ptr_unlink(&e, udb);
 1824 }
 1825 
 1826 void task_new_zonestat_inc(udb_base* udb, udb_ptr* last, unsigned sz)
 1827 {
 1828     udb_ptr e;
 1829     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task zonestat_inc"));
 1830     if(sz == 0)
 1831         return; /* no need to decrease to 0 */
 1832     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d),
 1833         NULL)) {
 1834         log_msg(LOG_ERR, "tasklist: out of space, cannot add z_i");
 1835         return;
 1836     }
 1837     TASKLIST(&e)->task_type = task_zonestat_inc;
 1838     TASKLIST(&e)->oldserial = (uint32_t)sz;
 1839     udb_ptr_unlink(&e, udb);
 1840 }
 1841 
 1842 int
 1843 task_new_apply_xfr(udb_base* udb, udb_ptr* last, const dname_type* dname,
 1844     uint32_t old_serial, uint32_t new_serial, uint64_t filenumber)
 1845 {
 1846     udb_ptr e;
 1847     DEBUG(DEBUG_IPC,1, (LOG_INFO, "add task apply_xfr"));
 1848     if(!task_create_new_elem(udb, last, &e, sizeof(struct task_list_d)
 1849         +dname_total_size(dname), dname)) {
 1850         log_msg(LOG_ERR, "tasklist: out of space, cannot add applyxfr");
 1851         return 0;
 1852     }
 1853     TASKLIST(&e)->oldserial = old_serial;
 1854     TASKLIST(&e)->newserial = new_serial;
 1855     TASKLIST(&e)->yesno = filenumber;
 1856     TASKLIST(&e)->task_type = task_apply_xfr;
 1857     udb_ptr_unlink(&e, udb);
 1858     return 1;
 1859 }
 1860 
 1861 void
 1862 task_process_expire(namedb_type* db, struct task_list_d* task)
 1863 {
 1864     uint8_t ok;
 1865     zone_type* z = namedb_find_zone(db, task->zname);
 1866     assert(task->task_type == task_expire);
 1867     if(!z) {
 1868         DEBUG(DEBUG_IPC, 1, (LOG_WARNING, "zone %s %s but not in zonetree",
 1869             dname_to_string(task->zname, NULL),
 1870             task->yesno?"expired":"unexpired"));
 1871         return;
 1872     }
 1873     DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: expire task zone %s %s",
 1874         dname_to_string(task->zname,0),
 1875         task->yesno?"expired":"unexpired"));
 1876     /* find zone, set expire flag */
 1877     ok = !task->yesno;
 1878     /* only update zone->is_ok if needed to minimize copy-on-write
 1879      * of memory pages shared after fork() */
 1880     if(ok && !z->is_ok)
 1881         z->is_ok = 1;
 1882     else if(!ok && z->is_ok)
 1883         z->is_ok = 0;
 1884 }
 1885 
 1886 static void
 1887 task_process_set_verbosity(struct task_list_d* task)
 1888 {
 1889     DEBUG(DEBUG_IPC,1, (LOG_INFO, "verbosity task %d", (int)task->yesno));
 1890     verbosity = task->yesno;
 1891 }
 1892 
 1893 static void
 1894 task_process_checkzones(struct nsd* nsd, udb_base* udb, udb_ptr* last_task,
 1895     struct task_list_d* task)
 1896 {
 1897     /* on SIGHUP check if zone-text-files changed and if so,
 1898      * reread.  When from xfrd-reload, no need to fstat the files */
 1899     if(task->yesno) {
 1900         struct zone_options* zo = zone_options_find(nsd->options,
 1901             task->zname);
 1902         if(zo)
 1903             namedb_check_zonefile(nsd, udb, last_task, zo);
 1904     } else {
 1905         /* check all zones */
 1906         namedb_check_zonefiles(nsd, nsd->options, udb, last_task);
 1907     }
 1908 }
 1909 
 1910 static void
 1911 task_process_writezones(struct nsd* nsd, struct task_list_d* task)
 1912 {
 1913     if(task->yesno) {
 1914         struct zone_options* zo = zone_options_find(nsd->options,
 1915             task->zname);
 1916         if(zo)
 1917             namedb_write_zonefile(nsd, zo);
 1918     } else {
 1919         namedb_write_zonefiles(nsd, nsd->options);
 1920     }
 1921 }
 1922 
 1923 static void
 1924 task_process_add_zone(struct nsd* nsd, udb_base* udb, udb_ptr* last_task,
 1925     struct task_list_d* task)
 1926 {
 1927     zone_type* z;
 1928     const dname_type* zdname;
 1929     const char* zname = (const char*)task->zname;
 1930     const char* pname = zname + strlen(zname)+1;
 1931     DEBUG(DEBUG_IPC,1, (LOG_INFO, "addzone task %s %s", zname, pname));
 1932     zdname = dname_parse(nsd->db->region, zname);
 1933     if(!zdname) {
 1934         log_msg(LOG_ERR, "can not parse zone name %s", zname);
 1935         return;
 1936     }
 1937     /* create zone */
 1938     z = find_or_create_zone(nsd->db, zdname, nsd->options, zname, pname);
 1939     if(!z) {
 1940         region_recycle(nsd->db->region, (void*)zdname,
 1941             dname_total_size(zdname));
 1942         log_msg(LOG_ERR, "can not add zone %s %s", zname, pname);
 1943         return;
 1944     }
 1945     z->zonestatid = (unsigned)task->yesno;
 1946     /* if zone is empty, attempt to read the zonefile from disk (if any) */
 1947     if(!z->soa_rrset && z->opts->pattern->zonefile) {
 1948         namedb_read_zonefile(nsd, z, udb, last_task);
 1949     }
 1950 }
 1951 
 1952 static void
 1953 task_process_del_zone(struct nsd* nsd, struct task_list_d* task)
 1954 {
 1955     zone_type* zone;
 1956     struct zone_options* zopt;
 1957     DEBUG(DEBUG_IPC,1, (LOG_INFO, "delzone task %s", dname_to_string(
 1958         task->zname, NULL)));
 1959     zone = namedb_find_zone(nsd->db, task->zname);
 1960     if(!zone)
 1961         return;
 1962 
 1963 #ifdef NSEC3
 1964     nsec3_clear_precompile(nsd->db, zone);
 1965     zone->nsec3_param = NULL;
 1966 #endif
 1967     delete_zone_rrs(nsd->db, zone);
 1968     if(nsd->db->udb) {
 1969         udb_ptr udbz;
 1970         if(udb_zone_search(nsd->db->udb, &udbz, dname_name(task->zname),
 1971             task->zname->name_size)) {
 1972             udb_zone_delete(nsd->db->udb, &udbz);
 1973             udb_ptr_unlink(&udbz, nsd->db->udb);
 1974         }
 1975     }
 1976 
 1977     /* remove from zonetree, apex, soa */
 1978     zopt = zone->opts;
 1979     namedb_zone_delete(nsd->db, zone);
 1980     /* remove from options (zone_list already edited by xfrd) */
 1981     zone_options_delete(nsd->options, zopt);
 1982 }
 1983 
 1984 static void
 1985 task_process_add_key(struct nsd* nsd, struct task_list_d* task)
 1986 {
 1987     struct key_options key;
 1988     key.name = (char*)task->zname;
 1989     DEBUG(DEBUG_IPC,1, (LOG_INFO, "addkey task %s", key.name));
 1990     key.algorithm = key.name + strlen(key.name)+1;
 1991     key.secret = key.algorithm + strlen(key.algorithm)+1;
 1992     key_options_add_modify(nsd->options, &key);
 1993     memset(key.secret, 0xdd, strlen(key.secret)); /* wipe secret */
 1994 }
 1995 
 1996 static void
 1997 task_process_del_key(struct nsd* nsd, struct task_list_d* task)
 1998 {
 1999     char* name = (char*)task->zname;
 2000     DEBUG(DEBUG_IPC,1, (LOG_INFO, "delkey task %s", name));
 2001     /* this is reload and nothing is using the TSIG key right now */
 2002     key_options_remove(nsd->options, name);
 2003 }
 2004 
 2005 static void
 2006 task_process_add_cookie_secret(struct nsd* nsd, struct task_list_d* task) {
 2007     uint8_t secret_tmp[NSD_COOKIE_SECRET_SIZE];
 2008     ssize_t decoded_len;
 2009     char* secret = (char*)task->zname;
 2010 
 2011     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "add_cookie_secret task %s", secret));
 2012 
 2013     if( strlen(secret) != 32 ) {
 2014         log_msg(LOG_ERR, "invalid cookie secret: %s", secret);
 2015         explicit_bzero(secret, strlen(secret));
 2016         return;
 2017     }
 2018 
 2019     decoded_len = hex_pton(secret, secret_tmp, NSD_COOKIE_SECRET_SIZE);
 2020     if( decoded_len != 16 ) {
 2021         explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE);
 2022         log_msg(LOG_ERR, "unable to parse cookie secret: %s", secret);
 2023         explicit_bzero(secret, strlen(secret));
 2024         return;
 2025     }
 2026     explicit_bzero(secret, strlen(secret));
 2027     add_cookie_secret(nsd, secret_tmp);
 2028     explicit_bzero(secret_tmp, NSD_COOKIE_SECRET_SIZE);
 2029 }
 2030 
 2031 static void
 2032 task_process_drop_cookie_secret(struct nsd* nsd, struct task_list_d* task)
 2033 {
 2034     (void)task;
 2035     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "drop_cookie_secret task"));
 2036     if( nsd->cookie_count <= 1 ) {
 2037         log_msg(LOG_ERR, "can not drop the only active cookie secret");
 2038         return;
 2039     }
 2040     drop_cookie_secret(nsd);
 2041 }
 2042 
 2043 static void
 2044 task_process_activate_cookie_secret(struct nsd* nsd, struct task_list_d* task)
 2045 {
 2046     (void)task;
 2047     DEBUG(DEBUG_IPC, 1, (LOG_INFO, "activate_cookie_secret task"));
 2048     if( nsd->cookie_count <= 1 ) {
 2049         log_msg(LOG_ERR, "can not activate the only active cookie secret");
 2050         return;
 2051     }
 2052     activate_cookie_secret(nsd);
 2053 }
 2054 
 2055 static void
 2056 task_process_add_pattern(struct nsd* nsd, struct task_list_d* task)
 2057 {
 2058     region_type* temp = region_create(xalloc, free);
 2059     buffer_type buffer;
 2060     struct pattern_options *pat;
 2061     buffer_create_from(&buffer, task->zname, task->yesno);
 2062     pat = pattern_options_unmarshal(temp, &buffer);
 2063     DEBUG(DEBUG_IPC,1, (LOG_INFO, "addpattern task %s", pat->pname));
 2064     pattern_options_add_modify(nsd->options, pat);
 2065     region_destroy(temp);
 2066 }
 2067 
 2068 static void
 2069 task_process_del_pattern(struct nsd* nsd, struct task_list_d* task)
 2070 {
 2071     char* name = (char*)task->zname;
 2072     DEBUG(DEBUG_IPC,1, (LOG_INFO, "delpattern task %s", name));
 2073     pattern_options_remove(nsd->options, name);
 2074 }
 2075 
 2076 static void
 2077 task_process_opt_change(struct nsd* nsd, struct task_list_d* task)
 2078 {
 2079     DEBUG(DEBUG_IPC,1, (LOG_INFO, "optchange task"));
 2080 #ifdef RATELIMIT
 2081     nsd->options->rrl_ratelimit = task->oldserial;
 2082     nsd->options->rrl_whitelist_ratelimit = task->newserial;
 2083     nsd->options->rrl_slip = task->yesno;
 2084     rrl_set_limit(nsd->options->rrl_ratelimit, nsd->options->rrl_whitelist_ratelimit,
 2085         nsd->options->rrl_slip);
 2086 #else
 2087     (void)nsd; (void)task;
 2088 #endif
 2089 }
 2090 
 2091 #ifdef USE_ZONE_STATS
 2092 static void
 2093 task_process_zonestat_inc(struct nsd* nsd, udb_base* udb, udb_ptr *last_task,
 2094     struct task_list_d* task)
 2095 {
 2096     DEBUG(DEBUG_IPC,1, (LOG_INFO, "zonestat_inc task %u", (unsigned)task->oldserial));
 2097     nsd->zonestatdesired = (unsigned)task->oldserial;
 2098     /* send echo to xfrd to increment on its end */
 2099     task_new_zonestat_inc(udb, last_task, nsd->zonestatdesired);
 2100 }
 2101 #endif
 2102 
 2103 static void
 2104 task_process_apply_xfr(struct nsd* nsd, udb_base* udb, udb_ptr *last_task,
 2105     udb_ptr* task)
 2106 {
 2107     /* we have to use an udb_ptr task here, because the apply_xfr procedure
 2108      * appends soa_info which may remap and change the pointer. */
 2109     zone_type* zone;
 2110     FILE* df;
 2111     DEBUG(DEBUG_IPC,1, (LOG_INFO, "applyxfr task %s", dname_to_string(
 2112         TASKLIST(task)->zname, NULL)));
 2113     zone = namedb_find_zone(nsd->db, TASKLIST(task)->zname);
 2114     if(!zone) {
 2115         /* assume the zone has been deleted and a zone transfer was
 2116          * still waiting to be processed */
 2117         xfrd_unlink_xfrfile(nsd, TASKLIST(task)->yesno);
 2118         return;
 2119     }
 2120     /* apply the XFR */
 2121     /* oldserial, newserial, yesno is filenumber */
 2122     df = xfrd_open_xfrfile(nsd, TASKLIST(task)->yesno, "r");
 2123     if(!df) {
 2124         /* could not open file to update */
 2125         /* there is no reply to xfrd failed-update,
 2126          * because xfrd has a scan for apply-failures. */
 2127         xfrd_unlink_xfrfile(nsd, TASKLIST(task)->yesno);
 2128         return;
 2129     }
 2130     /* read and apply zone transfer */
 2131     if(!apply_ixfr_for_zone(nsd, zone, df, nsd->options, udb,
 2132         last_task, TASKLIST(task)->yesno)) {
 2133         /* there is no reply to xfrd failed-update,
 2134          * because xfrd has a scan for apply-failures. */
 2135     }
 2136 
 2137     fclose(df);
 2138     xfrd_unlink_xfrfile(nsd, TASKLIST(task)->yesno);
 2139 }
 2140 
 2141 
 2142 void task_process_in_reload(struct nsd* nsd, udb_base* udb, udb_ptr *last_task,
 2143         udb_ptr* task)
 2144 {
 2145     switch(TASKLIST(task)->task_type) {
 2146     case task_expire:
 2147         task_process_expire(nsd->db, TASKLIST(task));
 2148         break;
 2149     case task_check_zonefiles:
 2150         task_process_checkzones(nsd, udb, last_task, TASKLIST(task));
 2151         break;
 2152     case task_write_zonefiles:
 2153         task_process_writezones(nsd, TASKLIST(task));
 2154         break;
 2155     case task_set_verbosity:
 2156         task_process_set_verbosity(TASKLIST(task));
 2157         break;
 2158     case task_add_zone:
 2159         task_process_add_zone(nsd, udb, last_task, TASKLIST(task));
 2160         break;
 2161     case task_del_zone:
 2162         task_process_del_zone(nsd, TASKLIST(task));
 2163         break;
 2164     case task_add_key:
 2165         task_process_add_key(nsd, TASKLIST(task));
 2166         break;
 2167     case task_del_key:
 2168         task_process_del_key(nsd, TASKLIST(task));
 2169         break;
 2170     case task_add_pattern:
 2171         task_process_add_pattern(nsd, TASKLIST(task));
 2172         break;
 2173     case task_del_pattern:
 2174         task_process_del_pattern(nsd, TASKLIST(task));
 2175         break;
 2176     case task_opt_change:
 2177         task_process_opt_change(nsd, TASKLIST(task));
 2178         break;
 2179 #ifdef USE_ZONE_STATS
 2180     case task_zonestat_inc:
 2181         task_process_zonestat_inc(nsd, udb, last_task, TASKLIST(task));
 2182         break;
 2183 #endif
 2184     case task_apply_xfr:
 2185         task_process_apply_xfr(nsd, udb, last_task, task);
 2186         break;
 2187     case task_add_cookie_secret:
 2188         task_process_add_cookie_secret(nsd, TASKLIST(task));
 2189         break;
 2190     case task_drop_cookie_secret:
 2191         task_process_drop_cookie_secret(nsd, TASKLIST(task));
 2192         break;
 2193     case task_activate_cookie_secret:
 2194         task_process_activate_cookie_secret(nsd, TASKLIST(task));
 2195         break;
 2196     default:
 2197         log_msg(LOG_WARNING, "unhandled task in reload type %d",
 2198             (int)TASKLIST(task)->task_type);
 2199         break;
 2200     }
 2201     udb_ptr_free_space(task, udb, TASKLIST(task)->size);
 2202 }