diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 9802a64532ca6ab3991eaaccafa405314f93a755..1812a21213b76ac867d5530137caf5640c0ac5c0 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -1967,18 +1967,19 @@ static int diff_after_load(zone_t *zone, zone_t *old_zone, assert(!zones_changesets_empty(*diff_chs)); /* Apply DNSSEC changeset to the new zone. */ ret = xfrin_apply_changesets_directly(zone->contents, *diff_chs); - if (ret == KNOT_EOK) { - ret = xfrin_finalize_updated_zone( - zone->contents, true); - } - if (ret != KNOT_EOK) { log_zone_error("DNSSEC: Zone %s - Signing failed while " "modifying zone (%s).\n", zone->conf->name, knot_strerror(ret)); + /* HACK ALERT! + * Since we've applied the changesets directly + * to the zone, we have to clean *old* data, + * if something went wrong, not new data as + * we would do normally. Not doing so would + * cause double frees. New zone API will fix this. + */ + xfrin_cleanup_successful_update(*diff_chs); knot_changesets_free(diff_chs); - /* No need to do rollback, the whole new zone will be - * discarded. */ return ret; } @@ -2054,9 +2055,10 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone, old_zone->contents != zone->contents); ret = xfrin_apply_changesets_directly(zone->contents, diff_chs); - if (ret == KNOT_EOK) { - ret = xfrin_finalize_updated_zone( - zone->contents, true); + if (ret != KNOT_EOK) { + /* HACK ALERT! see previous call of + * 'apply_changesets_directly' for explanation. */ + xfrin_cleanup_successful_update(diff_chs); } } else { assert(old_zone != NULL); @@ -2064,6 +2066,10 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone, ret = xfrin_apply_changesets(zone, diff_chs, &new_contents); + if (ret != KNOT_EOK) { + // Do a regular rollback, since we did a copy. + xfrin_rollback_update(diff_chs, &new_contents); + } } if (ret != KNOT_EOK) { @@ -2071,8 +2077,6 @@ static int store_chgsets_after_load(zone_t *old_zone, zone_t *zone, "modifying zone (%s).\n", zone->conf->name, knot_strerror(ret)); zones_store_changesets_rollback(transaction); - /* No zone rollback needed, the whole new zone will be - * discarded. */ return ret; } diff --git a/src/knot/updates/xfr-in.c b/src/knot/updates/xfr-in.c index 2829a3d67ff67825c0a0f07a6f8479b776ef8f50..bd8058ed97c32aa3ce8b4ddd1c8c14d908475e2f 100644 --- a/src/knot/updates/xfr-in.c +++ b/src/knot/updates/xfr-in.c @@ -1152,7 +1152,7 @@ int xfrin_apply_changesets_directly(knot_zone_contents_t *contents, } } - return KNOT_EOK; + return xfrin_finalize_updated_zone(contents, true); } /*----------------------------------------------------------------------------*/ @@ -1180,15 +1180,6 @@ int xfrin_apply_changesets_dnssec_ddns(zone_t *zone, return ret; } - const bool handle_nsec3 = true; - ret = xfrin_finalize_updated_zone(z_new, handle_nsec3); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to finalize updated zone: %s\n", - knot_strerror(ret)); - xfrin_rollback_update(sec_chsets, &z_new); - return ret; - } - return ret; }