"Fossies" - the Fresh Open Source Software Archive

Member "knot-2.8.3/src/knot/zone/zone-load.c" (16 Jul 2019, 4477 Bytes) of package /linux/misc/dns/knot-2.8.3.tar.xz:


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 "zone-load.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.8.1_vs_2.8.2.

    1 /*  Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
    2 
    3     This program is free software: you can redistribute it and/or modify
    4     it under the terms of the GNU General Public License as published by
    5     the Free Software Foundation, either version 3 of the License, or
    6     (at your option) any later version.
    7 
    8     This program is distributed in the hope that it will be useful,
    9     but WITHOUT ANY WARRANTY; without even the implied warranty of
   10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11     GNU General Public License for more details.
   12 
   13     You should have received a copy of the GNU General Public License
   14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
   15 */
   16 
   17 #include "knot/common/log.h"
   18 #include "knot/journal/journal_metadata.h"
   19 #include "knot/journal/journal_read.h"
   20 #include "knot/zone/zone-diff.h"
   21 #include "knot/zone/zone-load.h"
   22 #include "knot/zone/zonefile.h"
   23 #include "knot/dnssec/key-events.h"
   24 #include "knot/dnssec/zone-events.h"
   25 #include "knot/updates/apply.h"
   26 #include "libknot/libknot.h"
   27 
   28 int zone_load_contents(conf_t *conf, const knot_dname_t *zone_name,
   29                        zone_contents_t **contents, bool fail_on_warning)
   30 {
   31     if (conf == NULL || zone_name == NULL || contents == NULL) {
   32         return KNOT_EINVAL;
   33     }
   34 
   35     char *zonefile = conf_zonefile(conf, zone_name);
   36     conf_val_t val = conf_zone_get(conf, C_SEM_CHECKS, zone_name);
   37 
   38     zloader_t zl;
   39     int ret = zonefile_open(&zl, zonefile, zone_name, conf_bool(&val), time(NULL));
   40     free(zonefile);
   41     if (ret != KNOT_EOK) {
   42         return ret;
   43     }
   44 
   45     sem_handler_t handler = {
   46         .cb = err_handler_logger
   47     };
   48 
   49     zl.err_handler = &handler;
   50     zl.creator->master = !zone_load_can_bootstrap(conf, zone_name);
   51 
   52     *contents = zonefile_load(&zl);
   53     zonefile_close(&zl);
   54     if (*contents == NULL) {
   55         return KNOT_ERROR;
   56     }
   57     if (handler.warning && fail_on_warning) {
   58         return KNOT_ESEMCHECK;
   59     }
   60 
   61     return KNOT_EOK;
   62 }
   63 
   64 static int apply_one_cb(bool remove, const knot_rrset_t *rr, void *ctx)
   65 {
   66     return remove ? apply_remove_rr(ctx, rr) : apply_add_rr(ctx, rr);
   67 }
   68 
   69 int zone_load_journal(conf_t *conf, zone_t *zone, zone_contents_t *contents)
   70 {
   71     if (conf == NULL || zone == NULL || contents == NULL) {
   72         return KNOT_EINVAL;
   73     }
   74 
   75     // Check if journal is used (later in zone_changes_load() and zone is not empty.
   76     if (zone_contents_is_empty(contents)) {
   77         return KNOT_EOK;
   78     }
   79     uint32_t serial = zone_contents_serial(contents);
   80 
   81     journal_read_t *read = NULL;
   82     int ret = journal_read_begin(zone_journal(zone), false, serial, &read);
   83     switch (ret) {
   84     case KNOT_EOK:
   85         break;
   86     case KNOT_ENOENT:
   87         return KNOT_EOK;
   88     default:
   89         return ret;
   90     }
   91 
   92     apply_ctx_t a_ctx = { 0 };
   93     ret = apply_init_ctx(&a_ctx, contents, 0);
   94     if (ret != KNOT_EOK) {
   95         journal_read_end(read);
   96         return ret;
   97     }
   98 
   99     ret = journal_read_rrsets(read, apply_one_cb, &a_ctx);
  100     if (ret == KNOT_EOK) {
  101         log_zone_info(zone->name, "changes from journal applied %u -> %u",
  102                       serial, zone_contents_serial(contents));
  103     } else {
  104         log_zone_error(zone->name, "failed to apply journal changes %u -> %u (%s)",
  105                        serial, zone_contents_serial(contents),
  106                        knot_strerror(ret));
  107     }
  108 
  109     update_cleanup(&a_ctx);
  110 
  111     return ret;
  112 }
  113 
  114 int zone_load_from_journal(conf_t *conf, zone_t *zone, zone_contents_t **contents)
  115 {
  116     if (conf == NULL || zone == NULL || contents == NULL) {
  117         return KNOT_EINVAL;
  118     }
  119 
  120     journal_read_t *read = NULL;
  121     int ret = journal_read_begin(zone_journal(zone), true, 0, &read);
  122     if (ret != KNOT_EOK) {
  123         return ret;
  124     }
  125 
  126     changeset_t zone_in_j;
  127     apply_ctx_t a_ctx = { 0 };
  128     ret = journal_read_changeset(read, &zone_in_j) ? KNOT_EOK : KNOT_ENOENT;
  129     if (ret == KNOT_EOK) {
  130         ret = changeset_to_contents(&zone_in_j, contents);
  131     }
  132     if (ret == KNOT_EOK) {
  133         ret = apply_init_ctx(&a_ctx, *contents, 0);
  134     }
  135     if (ret != KNOT_EOK) {
  136         journal_read_end(read);
  137         return ret;
  138     }
  139 
  140     ret = journal_read_rrsets(read, apply_one_cb, &a_ctx);
  141     if (ret == KNOT_EOK) {
  142         log_zone_info(zone->name, "zone loaded from journal, serial %u",
  143                       zone_contents_serial(*contents));
  144     } else {
  145         log_zone_error(zone->name, "failed to load zone from journal (%s)",
  146                        knot_strerror(ret));
  147     }
  148     update_cleanup(&a_ctx);
  149 
  150     return ret;
  151 }
  152 
  153 bool zone_load_can_bootstrap(conf_t *conf, const knot_dname_t *zone_name)
  154 {
  155     if (conf == NULL || zone_name == NULL) {
  156         return false;
  157     }
  158 
  159     conf_val_t val = conf_zone_get(conf, C_MASTER, zone_name);
  160     size_t count = conf_val_count(&val);
  161 
  162     return count > 0;
  163 }