]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
load: ignore dnssec-related records if load difference and signing enabled
authorLibor Peltan <libor.peltan@nic.cz>
Fri, 22 Jun 2018 15:03:56 +0000 (17:03 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Sat, 28 Jul 2018 22:14:44 +0000 (00:14 +0200)
The difference ignores RRSIGs, NSECs, and NSEC3s. This is motivated by users
willing to have zonefile w/o DNSSEC, but signed zone.

If the final update consists only from changed SOA serial and RRSIG-SOA, clear it.
This happens after automatic serial icrement, we avoid increment on simple reload.

src/knot/events/handlers/load.c
src/knot/updates/changesets.c
src/knot/updates/changesets.h
src/knot/updates/zone-update.c
src/knot/updates/zone-update.h
src/knot/zone/zone-diff.c
src/knot/zone/zone-diff.h

index b02b1cd5338b0d10137744ace07d5122dd5d1b74..f47d5c74034560dd406655e43741e0ca2ffc96fd 100644 (file)
@@ -119,6 +119,7 @@ int event_load(conf_t *conf, zone_t *zone)
                        ret = zone_load_journal(conf, zone, zf_conts);
                        if (ret != KNOT_EOK) {
                                zone_contents_deep_free(zf_conts);
+                               zf_conts = NULL;
                                log_zone_warning(zone->name, "failed to load journal (%s)",
                                                 knot_strerror(ret));
                        }
@@ -138,6 +139,8 @@ int event_load(conf_t *conf, zone_t *zone)
        val = conf_zone_get(conf, C_DNSSEC_SIGNING, zone->name);
        bool dnssec_enable = conf_bool(&val), zu_from_zf_conts = false;
        zone_update_t up = { 0 };
+       bool ignore_dnssec = ((zf_from == ZONEFILE_LOAD_DIFF || zf_from == ZONEFILE_LOAD_DIFSE)
+                             && dnssec_enable);
 
        // Create zone_update structure according to current state.
        if (old_contents_exist) {
@@ -153,7 +156,9 @@ int event_load(conf_t *conf, zone_t *zone)
                        zu_from_zf_conts = true;
                } else {
                        // compute ZF diff and if success, apply it
-                       ret = zone_update_from_differences(&up, zone, zone->contents, zf_conts, UPDATE_INCREMENTAL);
+                       ret = zone_update_from_differences(&up, zone, zone->contents, zf_conts, UPDATE_INCREMENTAL, ignore_dnssec);
+                       zone_contents_deep_free(zf_conts);
+                       zf_conts = NULL;
                }
        } else {
                if (journal_conts != NULL && zf_from != ZONEFILE_LOAD_WHOLE) {
@@ -162,16 +167,18 @@ int event_load(conf_t *conf, zone_t *zone)
                                ret = zone_update_from_contents(&up, zone, journal_conts, UPDATE_INCREMENTAL);
                        } else {
                                // load zone-in-journal, compute ZF diff and if success, apply it
-                               ret = zone_update_from_differences(&up, zone, journal_conts, zf_conts, UPDATE_INCREMENTAL);
+                               ret = zone_update_from_differences(&up, zone, journal_conts, zf_conts, UPDATE_INCREMENTAL, ignore_dnssec);
+                               zone_contents_deep_free(zf_conts);
+                               zf_conts = NULL;
                                if (ret == KNOT_ESEMCHECK || ret == KNOT_ERANGE) {
                                        log_zone_warning(zone->name,
                                                         "zone file changed with SOA serial %s, "
                                                         "ignoring zone file and loading from journal",
                                                         (ret == KNOT_ESEMCHECK ? "unupdated" : "decreased"));
-                                       zone_contents_deep_free(zf_conts);
                                        ret = zone_update_from_contents(&up, zone, journal_conts, UPDATE_INCREMENTAL);
                                } else {
                                        zone_contents_deep_free(journal_conts);
+                                       journal_conts = NULL;
                                }
                        }
                } else {
@@ -212,17 +219,6 @@ int event_load(conf_t *conf, zone_t *zone)
        zf_conts = NULL;
        journal_conts = NULL;
 
-       // If the change is only automatically incremented SOA serial, make it no change.
-       if (zf_from == ZONEFILE_LOAD_DIFSE && (up.flags & UPDATE_INCREMENTAL) &&
-           changeset_differs_just_serial(&up.change)) {
-               uint32_t orig_ser = knot_soa_serial(&up.change.soa_from->rrs);
-               ret = changeset_remove_addition(&up.change, up.change.soa_to);
-               zone_contents_set_soa_serial(up.new_cont, orig_ser);
-               if (ret != KNOT_EOK) {
-                       goto cleanup;
-               }
-       }
-
        // Sign zone using DNSSEC if configured.
        zone_sign_reschedule_t dnssec_refresh = { .allow_rollover = true, .allow_nsec3resalt = true, };
        if (dnssec_enable) {
@@ -239,6 +235,24 @@ int event_load(conf_t *conf, zone_t *zone)
                }
        }
 
+       // If the change is only automatically incremented SOA serial, make it no change.
+       if (zf_from == ZONEFILE_LOAD_DIFSE && (up.flags & UPDATE_INCREMENTAL) &&
+           changeset_differs_just_serial(&up.change)) {
+               changeset_t *cpy = changeset_clone(&up.change);
+               if (cpy == NULL) {
+                       ret = KNOT_ENOMEM;
+                       goto cleanup;
+               }
+               ret = zone_update_apply_changeset_reverse(&up, cpy);
+               changeset_free(cpy);
+               if (ret == KNOT_EOK) {
+                       ret = changeset_remove_addition(&up.change, up.change.soa_to);
+               }
+               if (ret != KNOT_EOK) {
+                       goto cleanup;
+               }
+       }
+
        // Commit zone_update back to zone (including journal update, rcu,...).
        ret = zone_update_commit(conf, &up);
        zone_update_clear(&up);
index b19e69fdca6cba3bf8ad0a286330612959d4ab87..393521485a894ba3f0a0356cee92bb27f67fcbba 100644 (file)
@@ -537,17 +537,26 @@ bool changeset_differs_just_serial(const changeset_t *ch)
                return false;
        }
 
-       if (!zone_contents_is_empty(ch->remove) || !zone_contents_is_empty(ch->add)) {
-               return false;
-       }
-
        knot_rrset_t *soa_to_cpy = knot_rrset_copy(ch->soa_to, NULL);
-       knot_soa_serial_set(&soa_to_cpy->rrs, knot_soa_serial(&ch->soa_from->rrs));
+       knot_soa_serial_set(soa_to_cpy->rrs.rdata, knot_soa_serial(ch->soa_from->rrs.rdata));
 
-       bool res = knot_rrset_equal(ch->soa_from, soa_to_cpy, KNOT_RRSET_COMPARE_WHOLE);
+       bool ret = knot_rrset_equal(ch->soa_from, soa_to_cpy, KNOT_RRSET_COMPARE_WHOLE);
        knot_rrset_free(soa_to_cpy, NULL);
 
-       return res;
+       changeset_iter_t itt;
+       changeset_iter_all(&itt, ch);
+
+       knot_rrset_t rrset = changeset_iter_next(&itt);
+       while (!knot_rrset_empty(&rrset) && ret) {
+               if (rrset.type != KNOT_RRTYPE_RRSIG || rrset.rrs.count != 1 ||
+                   knot_rrsig_type_covered(rrset.rrs.rdata) != KNOT_RRTYPE_SOA) {
+                       ret = false;
+               }
+               rrset = changeset_iter_next(&itt);
+       }
+       changeset_iter_clear(&itt);
+
+       return ret;
 }
 
 int changeset_to_contents(changeset_t *ch, zone_contents_t **out)
@@ -648,6 +657,49 @@ void changeset_clear(changeset_t *ch)
        free(ch->data);
 }
 
+changeset_t *changeset_clone(const changeset_t *ch)
+{
+       if (ch == NULL) {
+               return NULL;
+       }
+
+       changeset_t *res = changeset_new(ch->soa_from->owner);
+       if (res == NULL) {
+               return NULL;
+       }
+
+       res->soa_from = knot_rrset_copy(ch->soa_from, NULL);
+       res->soa_to = knot_rrset_copy(ch->soa_to, NULL);
+
+       int ret = KNOT_EOK;
+       changeset_iter_t itt;
+
+       changeset_iter_rem(&itt, ch);
+       knot_rrset_t rr = changeset_iter_next(&itt);
+       while (!knot_rrset_empty(&rr) && ret == KNOT_EOK) {
+               ret = changeset_add_removal(res, &rr, 0);
+               rr = changeset_iter_next(&itt);
+       }
+       changeset_iter_clear(&itt);
+
+       changeset_iter_add(&itt, ch);
+       rr = changeset_iter_next(&itt);
+       while (!knot_rrset_empty(&rr) && ret == KNOT_EOK) {
+               ret = changeset_add_addition(res, &rr, 0);
+               rr = changeset_iter_next(&itt);
+       }
+       changeset_iter_clear(&itt);
+
+       if ((ch->soa_from != NULL && res->soa_from == NULL) ||
+           (ch->soa_to != NULL && res->soa_to == NULL) ||
+           ret != KNOT_EOK) {
+               changeset_free(res);
+               return NULL;
+       }
+
+       return res;
+}
+
 void changeset_free(changeset_t *ch)
 {
        changeset_clear(ch);
index 4aa345b332a75089bd2331862ac95b3bb1f3776c..8002712666b057c4cb78774516cfe5aac967485f 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -161,10 +161,13 @@ int changeset_cancelout(changeset_t *ch);
 /*!
  * \brief Check the changes and SOA, ignoring possibly updated SOA serial.
  *
+ * \note Also tolerates changed RRSIG of SOA.
+ *
  * \param ch  Changeset in question.
  *
- * \return false if the changeset changes other records than SOA, or some SOA field other than serial changed
- *         true otherwise
+ * \retval false  If the changeset changes other records than SOA, or some SOA field
+ *                other than serial changed.
+ * \retval true   Otherwise.
  */
 bool changeset_differs_just_serial(const changeset_t *ch);
 
@@ -215,6 +218,15 @@ void changesets_free(list_t *chgs);
  */
 void changeset_clear(changeset_t *ch);
 
+/*!
+ * \brief Copy changeset to newly allocated space, all rrsigs are copied.
+ *
+ * \param ch  Changeset to be copied.
+ *
+ * \return a copy, or NULL if error.
+ */
+changeset_t *changeset_clone(const changeset_t *ch);
+
 /*!
  * \brief Frees single changeset.
  *
index 478436b4147179887f5dbbb092af9f2a0ca1519e..3b6d2a0ad84fabadf0ec7dd901f1afbb671fac41 100644 (file)
@@ -26,9 +26,9 @@
 
 #include <urcu.h>
 
-static int init_incremental(zone_update_t *update, zone_t *zone)
+static int init_incremental(zone_update_t *update, zone_t *zone, zone_contents_t *old_contents)
 {
-       if (zone->contents == NULL) {
+       if (old_contents == NULL) {
                return KNOT_EINVAL;
        }
 
@@ -39,7 +39,7 @@ static int init_incremental(zone_update_t *update, zone_t *zone)
 
        update->new_cont_deep_copy = false;
 
-       ret = apply_prepare_zone_copy(zone->contents, &update->new_cont);
+       ret = apply_prepare_zone_copy(old_contents, &update->new_cont);
        if (ret != KNOT_EOK) {
                changeset_clear(&update->change);
                return ret;
@@ -50,7 +50,7 @@ static int init_incremental(zone_update_t *update, zone_t *zone)
 
        /* Copy base SOA RR. */
        update->change.soa_from =
-               node_create_rrset(zone->contents->apex, KNOT_RRTYPE_SOA);
+               node_create_rrset(old_contents->apex, KNOT_RRTYPE_SOA);
        if (update->change.soa_from == NULL) {
                zone_contents_free(update->new_cont);
                changeset_clear(&update->change);
@@ -96,11 +96,10 @@ static int replace_soa(zone_contents_t *contents, const knot_rrset_t *rr)
        return ret;
 }
 
-/* ------------------------------- API -------------------------------------- */
-
-int zone_update_init(zone_update_t *update, zone_t *zone, zone_update_flags_t flags)
+int init_base(zone_update_t *update, zone_t *zone, zone_contents_t *old_contents,
+              zone_update_flags_t flags)
 {
-       if (update == NULL || zone == NULL) {
+       if (update == NULL || zone == NULL || (old_contents == NULL && (flags & UPDATE_INCREMENTAL))) {
                return KNOT_EINVAL;
        }
 
@@ -117,7 +116,7 @@ int zone_update_init(zone_update_t *update, zone_t *zone, zone_update_flags_t fl
 
        int ret = KNOT_EINVAL;
        if (flags & UPDATE_INCREMENTAL) {
-               ret = init_incremental(update, zone);
+               ret = init_incremental(update, zone, old_contents);
        } else if (flags & UPDATE_FULL) {
                ret = init_full(update, zone);
        }
@@ -128,45 +127,49 @@ int zone_update_init(zone_update_t *update, zone_t *zone, zone_update_flags_t fl
        return ret;
 }
 
+/* ------------------------------- API -------------------------------------- */
+
+int zone_update_init(zone_update_t *update, zone_t *zone, zone_update_flags_t flags)
+{
+       return init_base(update, zone, zone->contents, flags);
+}
+
 int zone_update_from_differences(zone_update_t *update, zone_t *zone, zone_contents_t *old_cont,
-                                 zone_contents_t *new_cont, zone_update_flags_t flags)
+                                zone_contents_t *new_cont, zone_update_flags_t flags, bool ignore_dnssec)
 {
        if (update == NULL || zone == NULL || new_cont == NULL ||
            !(flags & UPDATE_INCREMENTAL) || (flags & UPDATE_FULL)) {
                return KNOT_EINVAL;
        }
 
-       memset(update, 0, sizeof(*update));
-       update->zone = zone;
-
-       mm_ctx_mempool(&update->mm, MM_DEFAULT_BLKSIZE);
-       update->flags = flags;
-
-       update->new_cont = new_cont;
-       update->new_cont_deep_copy = true;
+       changeset_t diff;
+       int ret = changeset_init(&diff, zone->name);
+       if (ret != KNOT_EOK) {
+               return ret;
+       }
 
-       update->a_ctx = calloc(1, sizeof(*update->a_ctx));
-       if (update->a_ctx == NULL) {
-               return KNOT_ENOMEM;
+       ret = zone_contents_diff(old_cont, new_cont, &diff, ignore_dnssec);
+       if (ret != KNOT_EOK && ret != KNOT_ENODIFF && ret != KNOT_ESEMCHECK) {
+               changeset_clear(&diff);
+               return ret;
        }
 
-       int ret = changeset_init(&update->change, zone->name);
+       ret = init_base(update, zone, old_cont, flags);
        if (ret != KNOT_EOK) {
-               free(update->a_ctx);
+               changeset_clear(&diff);
                return ret;
        }
 
-       ret = zone_contents_diff(old_cont, new_cont, &update->change);
-       if (ret != KNOT_EOK && ret != KNOT_ENODIFF && ret != KNOT_ESEMCHECK) {
-               free(update->a_ctx);
-               changeset_clear(&update->change);
+       bool diff_semcheck = (ret == KNOT_ESEMCHECK);
+
+       ret = zone_update_apply_changeset(update, &diff);
+       changeset_clear(&diff);
+       if (ret != KNOT_EOK) {
+               zone_update_clear(update);
                return ret;
        }
 
-       uint32_t apply_flags = update->flags & UPDATE_STRICT ? APPLY_STRICT : 0;
-       apply_init_ctx(update->a_ctx, update->new_cont, apply_flags);
-
-       if (ret == KNOT_ESEMCHECK) {
+       if (diff_semcheck) {
                ret = zone_update_increment_soa(update, conf());
                if (ret != KNOT_EOK) {
                        zone_update_clear(update);
@@ -522,6 +525,16 @@ int zone_update_apply_changeset_fix(zone_update_t *update, changeset_t *changes)
        return ret;
 }
 
+int zone_update_apply_changeset_reverse(zone_update_t *update, const changeset_t *changes)
+{
+       changeset_t reverse;
+       reverse.remove = changes->add;
+       reverse.add = changes->remove;
+       reverse.soa_from = changes->soa_to;
+       reverse.soa_to = changes->soa_from;
+       return zone_update_apply_changeset(update, &reverse);
+}
+
 static int set_new_soa(zone_update_t *update, unsigned serial_policy)
 {
        assert(update);
index bc9a279a16af0b78789bb224fda7212ce792fe60..2a0094dba36602ecff9466a3680b4fd06a1d1a78 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ int zone_update_init(zone_update_t *update, zone_t *zone, zone_update_flags_t fl
  * \return KNOT_E*
  */
 int zone_update_from_differences(zone_update_t *update, zone_t *zone, zone_contents_t *old_cont,
-                                 zone_contents_t *new_cont, zone_update_flags_t flags);
+                                 zone_contents_t *new_cont, zone_update_flags_t flags, bool ignore_dnssec);
 
 /*!
  * \brief Inits a zone update based on new zone contents.
@@ -228,6 +228,16 @@ int zone_update_apply_changeset(zone_update_t *update, const changeset_t *change
  */
 int zone_update_apply_changeset_fix(zone_update_t *update, changeset_t *changes);
 
+/*!
+ * \brief Applies the changeset in reverse, rsets from REM section are added and from ADD section removed.
+ *
+ * \param update   Zone update.
+ * \param changes  Changes to be un-done.
+ *
+ * \return KNOT_E*
+ */
+int zone_update_apply_changeset_reverse(zone_update_t *update, const changeset_t *changes);
+
 /*!
  * \brief Increment SOA serial (according to cofigured policy) in the update.
  *
index 7cf642fec179df9a411c06b2f4aaa35552e7b5e8..245a19459ebac1b369dc3b4987382f8db8b807cd 100644 (file)
 struct zone_diff_param {
        zone_tree_t *nodes;
        changeset_t *changeset;
+       bool ignore_dnssec;
 };
 
+static bool rrset_is_dnssec(const knot_rrset_t *rrset)
+{
+       switch (rrset->type) {
+       case KNOT_RRTYPE_RRSIG:
+       case KNOT_RRTYPE_NSEC:
+       case KNOT_RRTYPE_NSEC3:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static int load_soas(const zone_contents_t *zone1, const zone_contents_t *zone2,
                      changeset_t *changeset)
 {
@@ -75,11 +88,16 @@ static int load_soas(const zone_contents_t *zone1, const zone_contents_t *zone2,
        return KNOT_EOK;
 }
 
-static int add_node(const zone_node_t *node, changeset_t *changeset)
+static int add_node(const zone_node_t *node, changeset_t *changeset, bool ignore_dnssec)
 {
        /* Add all rrsets from node. */
        for (unsigned i = 0; i < node->rrset_count; i++) {
                knot_rrset_t rrset = node_rrset_at(node, i);
+
+               if (ignore_dnssec && rrset_is_dnssec(&rrset)) {
+                       continue;
+               }
+
                int ret = changeset_add_addition(changeset, &rrset, 0);
                if (ret != KNOT_EOK) {
                        return ret;
@@ -89,11 +107,16 @@ static int add_node(const zone_node_t *node, changeset_t *changeset)
        return KNOT_EOK;
 }
 
-static int remove_node(const zone_node_t *node, changeset_t *changeset)
+static int remove_node(const zone_node_t *node, changeset_t *changeset, bool ignore_dnssec)
 {
        /* Remove all the RRSets of the node. */
        for (unsigned i = 0; i < node->rrset_count; i++) {
                knot_rrset_t rrset = node_rrset_at(node, i);
+
+               if (ignore_dnssec && rrset_is_dnssec(&rrset)) {
+                       continue;
+               }
+
                int ret = changeset_add_removal(changeset, &rrset, 0);
                if (ret != KNOT_EOK) {
                        return ret;
@@ -204,7 +227,7 @@ static int knot_zone_diff_node(zone_node_t **node_ptr, void *data)
         */
        zone_node_t *node_in_second_tree = zone_tree_get(param->nodes, node->owner);
        if (node_in_second_tree == NULL) {
-               return remove_node(node, param->changeset);
+               return remove_node(node, param->changeset, param->ignore_dnssec);
        }
 
        assert(node_in_second_tree != node);
@@ -215,7 +238,7 @@ static int knot_zone_diff_node(zone_node_t **node_ptr, void *data)
                 * If there are no RRs in the first tree, all of the RRs
                 * in the second tree will have to be inserted to ADD section.
                 */
-               return add_node(node_in_second_tree, param->changeset);
+               return add_node(node_in_second_tree, param->changeset, param->ignore_dnssec);
        }
 
        for (unsigned i = 0; i < node->rrset_count; i++) {
@@ -227,6 +250,10 @@ static int knot_zone_diff_node(zone_node_t **node_ptr, void *data)
                        continue;
                }
 
+               if (param->ignore_dnssec && rrset_is_dnssec(&rrset)) {
+                       continue;
+               }
+
                knot_rrset_t rrset_from_second_node =
                        node_rrset(node_in_second_tree, rrset.type);
                if (knot_rrset_empty(&rrset_from_second_node)) {
@@ -255,6 +282,10 @@ static int knot_zone_diff_node(zone_node_t **node_ptr, void *data)
                        continue;
                }
 
+               if (param->ignore_dnssec && rrset_is_dnssec(&rrset)) {
+                       continue;
+               }
+
                knot_rrset_t rrset_from_first_node = node_rrset(node, rrset.type);
                if (knot_rrset_empty(&rrset_from_first_node)) {
                        /* RRSet has been added. Make a copy and add. */
@@ -291,19 +322,20 @@ static int add_new_nodes(zone_node_t **node_ptr, void *data)
        zone_node_t *new_node = zone_tree_get(param->nodes, node->owner);
        if (new_node == NULL) {
                assert(node);
-               return add_node(node, param->changeset);
+               return add_node(node, param->changeset, param->ignore_dnssec);
        }
 
        return KNOT_EOK;
 }
 
 static int load_trees(zone_tree_t *nodes1, zone_tree_t *nodes2,
-                      changeset_t *changeset)
+                     changeset_t *changeset, bool ignore_dnssec)
 {
        assert(changeset);
 
        struct zone_diff_param param = {
-               .changeset = changeset
+               .changeset = changeset,
+               .ignore_dnssec = ignore_dnssec,
        };
 
        // Traverse one tree, compare every node, each RRSet with its rdata.
@@ -319,7 +351,7 @@ static int load_trees(zone_tree_t *nodes1, zone_tree_t *nodes2,
 }
 
 int zone_contents_diff(const zone_contents_t *zone1, const zone_contents_t *zone2,
-                       changeset_t *changeset)
+                      changeset_t *changeset, bool ignore_dnssec)
 {
        if (zone1 == NULL || zone2 == NULL || changeset == NULL) {
                return KNOT_EINVAL;
@@ -330,12 +362,12 @@ int zone_contents_diff(const zone_contents_t *zone1, const zone_contents_t *zone
                return ret_soa;
        }
 
-       int ret = load_trees(zone1->nodes, zone2->nodes, changeset);
+       int ret = load_trees(zone1->nodes, zone2->nodes, changeset, ignore_dnssec);
        if (ret != KNOT_EOK) {
                return ret;
        }
 
-       ret = load_trees(zone1->nsec3_nodes, zone2->nsec3_nodes, changeset);
+       ret = load_trees(zone1->nsec3_nodes, zone2->nsec3_nodes, changeset, ignore_dnssec);
        if (ret != KNOT_EOK) {
                return ret;
        }
@@ -353,5 +385,5 @@ int zone_tree_add_diff(zone_tree_t *t1, zone_tree_t *t2, changeset_t *changeset)
                return KNOT_EINVAL;
        }
 
-       return load_trees(t1, t2, changeset);
+       return load_trees(t1, t2, changeset, false);
 }
index b5fef50f01a2a1a758a56b67d86cba9dc8f8b41e..5f467aabd370efd96ce73b0dc92ba61cec1259f9 100644 (file)
@@ -1,4 +1,4 @@
-/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
  * \brief Create diff between two zone trees.
  * */
 int zone_contents_diff(const zone_contents_t *zone1, const zone_contents_t *zone2,
-                       changeset_t *changeset);
+                       changeset_t *changeset, bool ignore_dnssec);
 
 /*!
  * \brief Add diff between two zone trees into the changeset.