From cf42a019b3e3a8e1be0d2a07ea6c595f9763454d Mon Sep 17 00:00:00 2001 From: Lubos Slovak <lubos.slovak@nic.cz> Date: Wed, 4 Sep 2013 18:50:20 +0200 Subject: [PATCH] Always incrementing SOA on zone resign. Added some more ugly hacks to properly use SOAs from the two changesets. refs #4 --- src/knot/server/zones.c | 56 +++++++++++++++++++------------- src/libknot/updates/changesets.c | 6 ++++ src/libknot/updates/changesets.h | 4 +++ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 3e9ba1fb0..366faeca4 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -1075,10 +1075,16 @@ static void zones_free_merged_changesets(knot_changesets_t *diff_chs, knot_changesets_free(&sec_chs); knot_changesets_free(&diff_chs); } else { + /* Ending SOA from the merged changeset was used in + * zone (same as in DNSSEC changeset). It thus must not + * be freed. + */ + knot_changesets_get_last(diff_chs)->soa_to = NULL; knot_changesets_free(&diff_chs); - // the "SOA to" from the second changeset is not used, - // thus must be freed + /* the "SOA from" from the second changeset is not used, + * thus must be freed + */ knot_rrset_deep_free_no_sig( &(knot_changesets_get_last(sec_chs)->soa_from), 1, 1); @@ -1106,24 +1112,28 @@ static int zones_merge_and_store_changesets(knot_zone_t *zone, return zones_store_changesets_to_disk(zone, sec_chs); } - /* - * Merge changesets (only one in each 'changesets_t' structure), - * use serial from diff (it's user supplied). + knot_changeset_t *diff_ch = knot_changesets_get_last(diff_chs); + knot_changeset_t *sec_ch = knot_changesets_get_last(sec_chs); + + /* SOAs in 'sec_chs' shouldn't be the same. */ + assert(sec_ch->serial_from != sec_ch->serial_to); + + /* But beginning SOA of second changeset should be equal to ending SOA + * of the first changeset. */ - int ret = knot_changeset_merge(knot_changesets_get_last(diff_chs), - knot_changesets_get_last(sec_chs)); + assert(diff_ch->serial_to == sec_ch->serial_from); + + int ret = knot_changeset_merge(diff_ch, sec_ch); if (ret != KNOT_EOK) { return ret; } - /* SOAs in 'sec_chs' should be the same. */ - assert(knot_changesets_get_last(sec_chs)->serial_from == - knot_changesets_get_last(sec_chs)->serial_to); - /* And they should be the same as the 'to' from 'diff_chs'. */ - assert(knot_changesets_get_last(diff_chs)->serial_to == - knot_changesets_get_last(sec_chs)->serial_to); - /* First SOA should not be set. */ - assert(sec_chs->first_soa == NULL); + /* Now the ending serial of first changeset (the merged one) should be + * equal to the ending serial of second changeset. Also the SOAs should + * be the same. + */ + assert(diff_ch->serial_to == sec_ch->serial_to); + assert(diff_ch->soa_to == sec_ch->soa_to); /* Store *ALL* changes to disk. (and only apply 'sec_chs', but not here. */ ret = zones_store_changesets_to_disk(zone, diff_chs); @@ -1421,13 +1431,13 @@ static int zones_insert_zone(conf_zone_t *z, knot_zone_t **dst, return KNOT_ENOMEM; } - /* Sign the zone. Do not incr. serial if diff did that. */ - knot_update_serial_t soa_up = - zones_changesets_empty(diff_chs) ? - KNOT_SOA_SERIAL_INC : KNOT_SOA_SERIAL_KEEP; + /* Increment serial even if diff did that. This way + * it's always possible to flush the changes to zonefile + * and it's also more correct (change in the zone = + * serial increment). + */ + knot_update_serial_t soa_up = KNOT_SOA_SERIAL_INC; - dbg_zones(stderr, "Signing zone, serial policy: %d\n", - soa_up); int ret = knot_dnssec_zone_sign(zone, sec_ch, soa_up); if (ret != KNOT_EOK) { knot_changesets_free(&diff_chs); @@ -1438,9 +1448,9 @@ static int zones_insert_zone(conf_zone_t *z, knot_zone_t **dst, } /* Merge changesets created by diff and sign. */ - int ret = zones_merge_and_store_changesets(zone, - diff_chs, + int ret = zones_merge_and_store_changesets(zone, diff_chs, sec_chs); + if (ret != KNOT_EOK) { knot_changesets_free(&diff_chs); knot_changesets_free(&sec_chs); diff --git a/src/libknot/updates/changesets.c b/src/libknot/updates/changesets.c index d2c5f8481..81781f75d 100644 --- a/src/libknot/updates/changesets.c +++ b/src/libknot/updates/changesets.c @@ -293,6 +293,12 @@ int knot_changeset_merge(knot_changeset_t *ch1, knot_changeset_t *ch2) add_tail_list(&ch1->add, &ch2->add); add_tail_list(&ch1->remove, &ch2->remove); + // Use soa_to and serial from the second changeset + // soa_to from the first changeset is redundant, delete it + knot_rrset_deep_free(&ch1->soa_to, 1, 1); + ch1->soa_to = ch2->soa_to; + ch1->serial_to = ch2->serial_to; + return KNOT_EOK; } diff --git a/src/libknot/updates/changesets.h b/src/libknot/updates/changesets.h index b19a09ffb..dc09cc6dc 100644 --- a/src/libknot/updates/changesets.h +++ b/src/libknot/updates/changesets.h @@ -282,6 +282,10 @@ int knot_changes_add_node(knot_changes_t *ch, knot_node_t *kn_node, * \param ch1 Changeset to merge into * \param ch2 Changeset to merge * + * Beginning SOA is used from the first changeset, ending SOA from the second. + * Ending SOA from first changeset is deleted. SOAs in the second changeset are + * left untouched. + * * \retval KNOT_EOK on success. * \retval Error code on failure. */ -- GitLab