diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c index 66377cff445c7131c21d39d373416605fdb28fdf..3ca6f2850f7866f133e852e152c437103f9ec340 100644 --- a/src/libknot/nameserver/name-server.c +++ b/src/libknot/nameserver/name-server.c @@ -4374,7 +4374,8 @@ int knot_ns_process_update2(const knot_packet_t *query, dbg_ns("Failed to apply UPDATE to the zone copy or no update" " made: %s\n", (ret < 0) ? knot_strerror(ret) : "No change made."); - xfrin_rollback_update(old_contents, &contents_copy, &changes); + xfrin_rollback_update(old_contents, &contents_copy, changes); + knot_changes_free(&changes); return ret; } @@ -4383,7 +4384,8 @@ int knot_ns_process_update2(const knot_packet_t *query, if (ret != KNOT_EOK) { dbg_ns("Failed to finalize updated zone: %s\n", knot_strerror(ret)); - xfrin_rollback_update(old_contents, &contents_copy, &changes); + xfrin_rollback_update(old_contents, &contents_copy, changes); + knot_changes_free(&changes); *rcode = (ret == KNOT_EMALF) ? KNOT_RCODE_FORMERR : KNOT_RCODE_SERVFAIL; return ret; diff --git a/src/libknot/updates/changesets.h b/src/libknot/updates/changesets.h index 144ae55a3cc88eb6886f2b9ea9d1d94665b233f9..da4f87cd2dde18b0ff9b913e0c0ebdbd92b69e0b 100644 --- a/src/libknot/updates/changesets.h +++ b/src/libknot/updates/changesets.h @@ -112,6 +112,11 @@ typedef enum { KNOT_CHANGESET_REMOVE } knot_changeset_part_t; +typedef enum { + KNOT_CHANGES_OLD, + KNOT_CHANGES_NEW +} knot_changes_part_t; + /*----------------------------------------------------------------------------*/ int knot_changesets_init(knot_changesets_t **changesets, @@ -145,20 +150,11 @@ int knot_changeset_is_empty(const knot_changeset_t *changeset); void knot_free_changesets(knot_changesets_t **changesets); -int knot_changes_rrsets_reserve(knot_rrset_t ***rrsets, - int *count, int *allocated, int to_add); - -int knot_changes_nodes_reserve(knot_node_t ***nodes, - int *count, int *allocated); - -int knot_changes_rdata_reserve(knot_rrset_t ***rdatas, - int count, int *allocated, int to_add); - -void knot_changes_add_rdata(knot_rrset_t **rdatas, int *count, - knot_rrset_t *rrset); +int knot_changes_add_rr(knot_changes_t *ch, knot_rrset_t *rrset, + knot_changes_part_t part); -int knot_changes_add_rrsets(const knot_rrset_t **from, size_t count, - knot_rrset_t **to, int proc_sigs); +int knot_changes_add_rrset(knot_changes_t *ch, knot_rrset_t *rrset, + knot_changes_part_t part); #endif /* _KNOT_CHANGESETS_H_ */ diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c index 86dc9d521d1ec85bf038bc0109e804ed9fcab972..1d58bf34fba98dde3aafc43bd07a813bd3fc22cb 100644 --- a/src/libknot/updates/xfr-in.c +++ b/src/libknot/updates/xfr-in.c @@ -1274,45 +1274,30 @@ int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy, return KNOT_ENOMEM; } - // add the RRSet to the list of new RRSets - // create place also for RRSIGs + // add the RRSet to the list of new RRSets, RRSIG as well if (save_new) { - changes->new_rrsets[changes->new_rrsets_count++] = *copy; - - dbg_xfrin_detail("Adding RDATA from the RRSet copy to new RDATA list." - "\n"); - knot_changes_add_rdata(changes->new_rdata, - &changes->new_rdata_count, - *copy); - + knot_changes_add_rrset(changes, *copy, KNOT_CHANGES_NEW); if ((*copy)->rrsigs != NULL) { assert(old->rrsigs != NULL); - changes->new_rrsets[changes->new_rrsets_count++] = - (*copy)->rrsigs; - - dbg_xfrin_detail("Adding RDATA from RRSIG of the RRSet copy to " - "new RDATA list.\n"); - knot_changes_add_rdata(changes->new_rdata, - &changes->new_rdata_count, - (*copy)->rrsigs); + ret = knot_changes_add_rrset(changes, (*copy)->rrsigs, + KNOT_CHANGES_NEW); + if (ret != KNOT_EOK) { + return ret; + } } } - changes->old_rrsets[changes->old_rrsets_count++] = old; - - dbg_xfrin_detail("Adding RDATA from old RRSet to old RDATA list.\n"); - knot_changes_add_rdata(changes->old_rdata, &changes->old_rdata_count, - old); - - if ((*copy)->rrsigs != NULL) { - assert(old->rrsigs != NULL); - changes->old_rrsets[changes->old_rrsets_count++] = old->rrsigs; + ret = knot_changes_add_rrset(changes, old, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } - dbg_xfrin_detail("Adding RDATA from RRSIG of the old RRSet to " - "old RDATA list.\n"); - knot_changes_add_rdata(changes->old_rdata, - &changes->old_rdata_count, - old->rrsigs); + if (old->rrsigs != NULL) { + ret = knot_changes_add_rrset(changes, old->rrsigs, + KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } } return KNOT_EOK; @@ -1456,8 +1441,10 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes, assert(rr_removed); // connect the RDATA to the list of old RDATA - knot_changes_add_rdata(changes->old_rdata, &changes->old_rdata_count, - rr_removed); + ret = knot_changes_add_rrset(changes, rr_removed, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } // if the RRSet is empty, remove from node and add to old RRSets // check if there is no RRSIGs; if there are, leave the RRSet @@ -1467,21 +1454,23 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes, knot_rrset_set_rrsigs(*rrset, NULL); // add RRSet to the list of old RRSets - changes->old_rrsets[changes->old_rrsets_count++] = rrsigs; - - // saving old RDATA is not necessary as there is none + ret = knot_changes_add_rrset(changes, rrsigs, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } // now check if the RRSet is not totally empty if (knot_rrset_rdata_rr_count(*rrset) == 0) { assert(knot_rrset_rrsigs(*rrset) == NULL); - // remove the whole RRSet from the node knot_rrset_t *tmp = knot_node_remove_rrset(node, knot_rrset_type(*rrset)); assert(tmp == *rrset); - - changes->old_rrsets[changes->old_rrsets_count++] = - *rrset; + int ret = knot_changes_add_rrset(changes, *rrset, + KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } } } @@ -1576,8 +1565,10 @@ dbg_xfrin_exec_detail( } if (rr_remove->rdata_count != 0) { - knot_changes_add_rdata(changes->old_rdata, - &changes->old_rdata_count, rr_remove); + ret = knot_changes_add_rrset(changes, rr_remove, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } } else { /* Discard empty RRSet. */ knot_rrset_free(&rr_remove); @@ -1600,7 +1591,10 @@ dbg_xfrin_exec_detail( // add the removed RRSet to list of old RRSets assert(tmp == *rrset); - changes->old_rrsets[changes->old_rrsets_count++] = *rrset; + ret = knot_changes_add_rrset(changes, *rrset, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } } return KNOT_EOK; @@ -1612,7 +1606,6 @@ static int xfrin_apply_remove_all_rrsets(knot_changes_t *changes, knot_node_t *node, uint16_t type, uint32_t chflags) { - int ret = KNOT_EOK; knot_rrset_t **rrsets = NULL; unsigned rrsets_count = 0; int is_apex = knot_node_rrset(node, KNOT_RRTYPE_SOA) != NULL; @@ -1694,12 +1687,11 @@ dbg_xfrin_exec_verb( continue; } - changes->old_rrsets[changes->old_rrsets_count++] = rrsets[i]; - - /* Remove old RDATA. */ - knot_changes_add_rdata(changes->old_rdata, - &changes->old_rdata_count, - rrsets[i]); + int ret = knot_changes_add_rrset(changes, rrsets[i], + KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } } free(rrsets); @@ -1760,13 +1752,10 @@ int xfrin_replace_rrset_in_node(knot_node_t *node, // save also the RDATA, because RDATA are not deleted with the RRSet // save the new RRSet to the new RRSet, so that it is deleted if the // apply fails - changes->old_rrsets[changes->old_rrsets_count++] = rrset_old; - - dbg_xfrin_verb("Adding RDATA from old RRSet to the list of old RDATA." - "\n"); - knot_changes_add_rdata(changes->old_rdata, &changes->old_rdata_count, - rrset_old); - + int ret = knot_changes_add_rrset(changes, rrset_old, KNOT_CHANGES_OLD); + if (ret != KNOT_EOK) { + return ret; + } // store RRSIGs from the old RRSet to the new knot_rrset_set_rrsigs(rrset_new, knot_rrset_get_rrsigs(rrset_old)); @@ -1781,12 +1770,10 @@ int xfrin_replace_rrset_in_node(knot_node_t *node, } assert(ret == 0); - changes->new_rrsets[changes->new_rrsets_count++] = rrset_new; - - dbg_xfrin_verb("Adding RDATA from new RRSet to the list of new RDATA." - "\n"); - knot_changes_add_rdata(changes->new_rdata, &changes->new_rdata_count, - rrset_new); + ret = knot_changes_add_rrset(changes, rrset_new, KNOT_CHANGES_NEW); + if (ret != KNOT_EOK) { + return ret; + } return KNOT_EOK; } @@ -2096,7 +2083,10 @@ dbg_xfrin_exec_verb( return KNOT_ERROR; } - changes->new_rrsets[changes->new_rrsets_count++] = *rrset; + ret = knot_changes_add_rrset(changes, *rrset, KNOT_CHANGES_NEW); + if (ret != KNOT_EOK) { + return ret; + } } dbg_xfrin_exec_detail( @@ -2321,37 +2311,17 @@ static void xfrin_cleanup_failed_update(knot_zone_contents_t *old_contents, void xfrin_rollback_update(knot_zone_contents_t *old_contents, knot_zone_contents_t **new_contents, - knot_changes_t **changes) + knot_changes_t *changes) { - assert(changes != NULL); + if (changes == NULL) { + return; + } dbg_xfrin("Rolling back changeset application.\n"); - - if (*changes != NULL) { - // discard new RRSets - for (int i = 0; i < (*changes)->new_rrsets_count; ++i) { - //knot_rrset_deep_free(&changes->new_rrsets[i], 0, 1, 1); - if ((*changes)->new_rrsets[i]->rdata_count == 0) { - knot_rrset_free(&(*changes)->new_rrsets[i]); - } - } - - for (int i = 0; i < (*changes)->new_rdata_count; ++i) { - dbg_xfrin_detail("Freeing %d. RDATA: %p\n", i, - (*changes)->new_rdata[i]); - knot_rrset_deep_free_no_sig(&(*changes)->new_rdata[i], 1, 1); - } - - // free allocated arrays of nodes and rrsets - free((*changes)->new_rrsets); - free((*changes)->new_rdata); - free((*changes)->old_nodes); - free((*changes)->old_nsec3); - free((*changes)->old_rrsets); - free((*changes)->old_rdata); - - free(*changes); - *changes = NULL; + knot_rr_node_t *rr_node = NULL; + WALK_LIST(rr_node, changes->new_rrsets) { + knot_rrset_t *rrset = rr_node->rr; + knot_rrset_deep_free_no_sig(&rrset, 1, 1); } xfrin_cleanup_failed_update(old_contents, new_contents); @@ -2562,13 +2532,6 @@ dbg_xfrin_exec_detail( int count = 1;//knot_rrset_rdata_rr_count(chset->add[i]); // connect the RDATA to the list of new RDATA - int res = knot_changes_rdata_reserve( - &changes->new_rdata, - changes->new_rdata_count, - &changes->new_rdata_allocated, count); - if (res != KNOT_EOK) { - return res; - } knot_changes_add_rdata(changes->new_rdata, &changes->new_rdata_count, diff --git a/src/libknot/updates/xfr-in.h b/src/libknot/updates/xfr-in.h index 54a22c554d6b20d2bbb473354739e68eb06c999c..7763a2d72177cc504c8f80acc4f2d7f791d06a6d 100644 --- a/src/libknot/updates/xfr-in.h +++ b/src/libknot/updates/xfr-in.h @@ -200,7 +200,7 @@ void xfrin_cleanup_successful_update(knot_changes_t **changes); void xfrin_rollback_update(knot_zone_contents_t *old_contents, knot_zone_contents_t **new_contents, - knot_changes_t **changes); + knot_changes_t *changes); int xfrin_copy_rrset(knot_node_t *node, uint16_t type, knot_rrset_t **rrset, knot_changes_t *changes,