Commit 86dc84f4 authored by Jan Kadlec's avatar Jan Kadlec

changeset: Compilable with trie changesets.

parent 35adb004
......@@ -118,12 +118,11 @@ static bool get_zone_soa_min_ttl(const zone_contents_t *zone,
* This function is constructed as a callback for the knot_changeset_apply() f
* function.
*/
static int mark_nsec3(knot_rrset_t *rrset, void *data)
static int mark_nsec3(knot_rrset_t *rrset, zone_tree_t *nsec3s)
{
assert(rrset != NULL);
assert(data != NULL);
assert(nsec3s != NULL);
zone_tree_t *nsec3s = (zone_tree_t *)data;
zone_node_t *node = NULL;
int ret;
......@@ -155,10 +154,24 @@ static int mark_removed_nsec3(changeset_t *out_ch,
if (zone_tree_is_empty(zone->nsec3_nodes)) {
return KNOT_EOK;
}
int ret = changeset_apply(out_ch, CHANGESET_REMOVE,
mark_nsec3, (void *)zone->nsec3_nodes);
return ret;
changeset_iter_t *itt = changeset_iter_rem(out_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
while (!knot_rrset_empty(&rr)) {
int ret = mark_nsec3(&rr, zone->nsec3_nodes);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
return KNOT_EOK;
}
/* - public API ------------------------------------------------------------ */
......
......@@ -615,7 +615,7 @@ static int zone_tree_sign(zone_tree_t *tree,
/*- private API - signing of NSEC(3) in changeset ----------------------------*/
/*!
* \brief Struct to carry data for 'add_rrsigs_for_nsec' callback function.
* \brief Struct to carry data for changeset signing callback functions.
*/
typedef struct {
const zone_contents_t *zone;
......@@ -625,37 +625,6 @@ typedef struct {
hattrie_t *signed_tree;
} changeset_signing_data_t;
/*!
* \brief Sign NSEC nodes in changeset (callback function).
*
* \param node Node to be signed, silently skipped if not NSEC/NSEC3.
* \param data Callback data, changeset_signing_data_t.
*/
static int add_rrsigs_for_nsec(knot_rrset_t *rrset, void *data)
{
if (rrset == NULL) {
return KNOT_EINVAL;
}
assert(data);
int result = KNOT_EOK;
changeset_signing_data_t *nsec_data = (changeset_signing_data_t *)data;
if (rrset->type == KNOT_RRTYPE_NSEC ||
rrset->type == KNOT_RRTYPE_NSEC3
) {
result = add_missing_rrsigs(rrset, NULL, nsec_data->zone_keys,
nsec_data->policy,
nsec_data->changeset);
}
if (result != KNOT_EOK) {
dbg_dnssec_detail("add_rrsigs_for_nsec() for NSEC failed\n");
}
return result;
}
/*- private API - DNSKEY handling --------------------------------------------*/
......@@ -1157,9 +1126,8 @@ static int rr_already_signed(const knot_rrset_t *rrset, hattrie_t *t,
*
* \return Error code, KNOT_EOK if successful.
*/
static int sign_changeset_wrap(knot_rrset_t *chg_rrset, void *data)
static int sign_changeset_wrap(knot_rrset_t *chg_rrset, changeset_signing_data_t *args)
{
changeset_signing_data_t *args = (changeset_signing_data_t *)data;
// Find RR's node in zone, find out if we need to sign this RR
const zone_node_t *node =
zone_contents_find_node(args->zone, chg_rrset->owner);
......@@ -1426,21 +1394,43 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
}
// Sign all RRs that are new in changeset
int ret = changeset_apply((changeset_t *)in_ch,
CHANGESET_ADD,
sign_changeset_wrap, &args);
changeset_iter_t *itt = changeset_iter_add(in_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
while (!knot_rrset_empty(&rr)) {
int ret = sign_changeset_wrap(&rr, &args);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
itt = changeset_iter_rem(in_ch, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
// Sign all RRs that are removed in changeset
if (ret == KNOT_EOK) {
ret = changeset_apply((changeset_t *)in_ch,
CHANGESET_REMOVE,
sign_changeset_wrap, &args);
#warning too much copypasta
rr = changeset_iter_next(itt);
while (!knot_rrset_empty(&rr)) {
int ret = sign_changeset_wrap(&rr, &args);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
knot_zone_clear_sorted_changes(args.signed_tree);
hattrie_free(args.signed_tree);
return ret;
return KNOT_EOK;
}
/*!
......@@ -1454,13 +1444,27 @@ int knot_zone_sign_nsecs_in_changeset(const knot_zone_keys_t *zone_keys,
assert(policy);
assert(changeset);
changeset_signing_data_t data = {.zone = NULL,
.zone_keys = zone_keys,
.policy = policy,
.changeset = changeset };
return changeset_apply(changeset, CHANGESET_ADD,
add_rrsigs_for_nsec, &data);
changeset_iter_t *itt = changeset_iter_add(changeset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
while (!knot_rrset_empty(&rr)) {
if (rr.type == KNOT_RRTYPE_NSEC ||
rr.type == KNOT_RRTYPE_NSEC3) {
int ret = add_missing_rrsigs(&rr, NULL, zone_keys,
policy, changeset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
return KNOT_EOK;
}
/*!
......
......@@ -198,22 +198,29 @@ static int remove_rr(zone_node_t *node, const knot_rrset_t *rr,
/*! \brief Removes all RRs from changeset from zone contents. */
static int apply_remove(zone_contents_t *contents, changeset_t *chset)
{
ptrnode_t *n;
WALK_LIST(n, chset->remove) {
const knot_rrset_t *rr = (knot_rrset_t *)n->d;
changeset_iter_t *itt = changeset_iter_rem(chset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
while (!knot_rrset_empty(&rr)) {
// Find node for this owner
zone_node_t *node = zone_contents_find_node_for_rr(contents, rr);
if (!can_remove(node, rr)) {
zone_node_t *node = zone_contents_find_node_for_rr(contents, &rr);
if (!can_remove(node, &rr)) {
// Nothing to remove from, skip.
continue;
}
int ret = remove_rr(node, rr, chset);
int ret = remove_rr(node, &rr, chset);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
return KNOT_EOK;
}
......@@ -267,22 +274,29 @@ static int add_rr(zone_node_t *node, const knot_rrset_t *rr,
static int apply_add(zone_contents_t *contents, changeset_t *chset,
bool master)
{
ptrnode_t *n;
WALK_LIST(n, chset->add) {
knot_rrset_t *rr = (knot_rrset_t *)n->d;
changeset_iter_t *itt = changeset_iter_add(chset, false);
if (itt == NULL) {
return KNOT_ENOMEM;
}
knot_rrset_t rr = changeset_iter_next(itt);
while(!knot_rrset_empty(&rr)) {
// Get or create node with this owner
zone_node_t *node = zone_contents_get_node_for_rr(contents, rr);
zone_node_t *node = zone_contents_get_node_for_rr(contents, &rr);
if (node == NULL) {
changeset_iter_free(itt, NULL);
return KNOT_ENOMEM;
}
int ret = add_rr(node, rr, chset, master);
int ret = add_rr(node, &rr, chset, master);
if (ret != KNOT_EOK) {
changeset_iter_free(itt, NULL);
return ret;
}
rr = changeset_iter_next(itt);
}
changeset_iter_free(itt, NULL);
return KNOT_EOK;
}
......
......@@ -78,14 +78,14 @@ bool changeset_empty(const changeset_t *ch)
size_t changeset_size(const changeset_t *ch)
{
if (!ch || changeset_empty(ch)) {
if (changeset_empty(ch)) {
return 0;
}
return hattrie_weight(ch->add->nodes) == 0 +
hattrie_weight(ch->add->nsec3_nodes) == 0 +
hattrie_weight(ch->remove->nodes) == 0 +
hattrie_weight(ch->remove->nsec3_nodes) == 0;
return hattrie_weight(ch->add->nodes) +
hattrie_weight(ch->add->nsec3_nodes) +
hattrie_weight(ch->remove->nodes) +
hattrie_weight(ch->remove->nsec3_nodes);
}
int changeset_merge(changeset_t *ch1, changeset_t *ch2)
......
......@@ -231,7 +231,7 @@ static int process_prereq(const knot_rrset_t *rrset, uint16_t qclass,
/*!< \brief Checks whether RR was already removed. */
static bool removed_rr(zone_contents_t *z, const knot_rrset_t *rr)
{
const zone_node_t *n = zone_contents_find_node(z, rr->owner);
const zone_node_t *n = zone_contents_find_node_for_rr(z, rr);
if (n == NULL) {
return false;
}
......@@ -260,7 +260,7 @@ static bool name_added(const changeset_t *changeset, const knot_dname_t *d)
/*!< \brief Removes RR from list, full equality check. */
static void remove_rr_from_list(zone_contents_t *z, const knot_rrset_t *rr)
{
zone_node_t *n = zone_contents_get_node(z, rr->owner);
zone_node_t *n = zone_contents_find_node_for_rr(z, rr);
if (n == NULL) {
return;
}
......@@ -270,16 +270,16 @@ static void remove_rr_from_list(zone_contents_t *z, const knot_rrset_t *rr)
return;
}
knot_rdataset_subtract(rrs, rr, NULL);
knot_rdataset_subtract(rrs, &rr->rrs, NULL);
if (rrs->rr_count == 0) {
node_remove_rdataset(n, rr->type);
}
}
/*!< \brief Removes RR from list, owner and type check. */
static void remove_header_from_list(list_t *l, const knot_rrset_t *rr)
static void remove_header_from_list(zone_contents_t *z, const knot_rrset_t *rr)
{
zone_node_t *n = zone_contents_find_node(z, d);
zone_node_t *n = zone_contents_find_node_for_rr(z, rr);
if (n == NULL) {
return;
}
......@@ -324,15 +324,10 @@ static inline bool is_node_removal(const knot_rrset_t *rr)
}
/*!< \brief Returns true if last addition of certain types is to be replaced. */
static bool should_replace(const knot_rrset_t *chg_rrset,
const knot_rrset_t *rrset)
static bool should_replace(const knot_rrset_t *rrset)
{
if (rrset->type != KNOT_RRTYPE_CNAME &&
rrset->type != KNOT_RRTYPE_NSEC3PARAM) {
return false;
} else {
return chg_rrset->type == rrset->type;
}
return rrset->type == KNOT_RRTYPE_CNAME ||
rrset->type == KNOT_RRTYPE_NSEC3PARAM;
}
/*!< \brief Returns true if node will be empty after update application. */
......@@ -359,7 +354,7 @@ static bool node_empty(const zone_node_t *node, knot_dname_t *owner,
if (ret != KNOT_EOK) {
return false;
}
if (!removed_rr(changeset, &node_rr)) {
if (!removed_rr(changeset->remove, &node_rr)) {
// One of the RRs from node was not removed.
knot_rdataset_clear(&node_rr.rrs, NULL);
return false;
......@@ -408,7 +403,7 @@ static bool adding_to_cname(const knot_dname_t *owner,
return false;
}
if (removed_rr(changeset, &cname)) {
if (removed_rr(changeset->remove, &cname)) {
// Node did contain CNAME, but it was removed in this update.
return false;
}
......@@ -435,22 +430,26 @@ static bool skip_soa(const knot_rrset_t *rr, int64_t sn)
static bool skip_record_addition(changeset_t *changeset,
knot_rrset_t *rr)
{
ptrnode_t *n;
WALK_LIST(n, changeset->add) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
if (should_replace(rr, rrset)) {
// Replacing singleton RR.
knot_rrset_free(&rrset, NULL);
n->d = rr;
return true;
} else if (knot_rrset_equal(rr, rrset, KNOT_RRSET_COMPARE_WHOLE)) {
// Freeing duplication.
knot_rrset_free(&rr, NULL);
return true;
}
if (!should_replace(rr)) {
return false;
}
zone_node_t *n = zone_contents_find_node_for_rr(changeset->add, rr);
if (n == NULL) {
return false;
}
return false;
knot_rdataset_t *rrs = node_rdataset(n, rr->type);
if (rrs == NULL) {
return false;
}
// Replace singleton RR.
knot_rdataset_clear(rrs, NULL);
node_remove_rdataset(n, rr->type);
node_add_rrset(n, rr);
return true;
}
/*!< \brief Adds RR into add section of changeset if it is deemed worthy. */
......@@ -476,22 +475,6 @@ static int add_rr_to_chgset(const knot_rrset_t *rr, changeset_t *changeset,
return changeset_add_rrset(changeset, rr_copy);
}
/*!< \brief Checks whether record should be removed (duplicate check). */
static bool skip_record_removal(changeset_t *changeset, knot_rrset_t *rr)
{
ptrnode_t *n;
WALK_LIST(n, changeset->remove) {
knot_rrset_t *rrset = (knot_rrset_t *)n->d;
if (knot_rrset_equal(rr, rrset, KNOT_RRSET_COMPARE_WHOLE)) {
// Removing the same RR, drop.
knot_rrset_free(&rr, NULL);
return true;
}
}
return false;
}
/*!< \brief Adds RR into remove section of changeset if it is deemed worthy. */
static int rem_rr_to_chgset(const knot_rrset_t *rr, changeset_t *changeset,
int *apex_ns_rem)
......@@ -503,10 +486,6 @@ static int rem_rr_to_chgset(const knot_rrset_t *rr, changeset_t *changeset,
rr_copy->rclass = KNOT_CLASS_IN;
if (skip_record_removal(changeset, rr_copy)) {
return KNOT_EOK;
}
if (apex_ns_rem) {
// Decrease post update apex NS count.
(*apex_ns_rem)++;
......@@ -569,7 +548,7 @@ static int process_add_cname(const zone_node_t *node,
}
}
/*!< \brief Processes CNAME addition (ignore when not removed, or non-apex) */
/*!< \brief Processes NSEC3PARAM addition (ignore when not removed, or non-apex) */
static int process_add_nsec3param(const zone_node_t *node,
const knot_rrset_t *rr,
changeset_t *changeset)
......@@ -583,7 +562,7 @@ static int process_add_nsec3param(const zone_node_t *node,
return KNOT_EDENIED;
}
knot_rrset_t param = node_rrset(node, KNOT_RRTYPE_NSEC3PARAM);
if (knot_rrset_empty(&param) || removed_rr(changeset, &param)) {
if (knot_rrset_empty(&param) || removed_rr(changeset->remove, &param)) {
return add_rr_to_chgset(rr, changeset, NULL);
}
......@@ -644,7 +623,7 @@ static int process_add_normal(const zone_node_t *node,
if (node && node_contains_rr(node, rr)) {
// Adding existing RR, remove removal from changeset if it's there.
remove_rr_from_list(&changeset->remove, rr);
remove_rr_from_list(changeset->remove, rr);
// And ignore.
return KNOT_EOK;
}
......@@ -696,7 +675,7 @@ static int process_rem_rr(const knot_rrset_t *rr,
}
// Remove possible previously added RR
remove_rr_from_list(&changeset->add, rr);
remove_rr_from_list(changeset->add, rr);
if (node == NULL) {
// Removing from node that did not exists before update
return KNOT_EOK;
......@@ -746,7 +725,7 @@ static int process_rem_rrset(const knot_rrset_t *rrset,
}
// Remove all previously added RRs with this owner and type from chgset
remove_header_from_list(&changeset->add, rrset);
remove_header_from_list(changeset->add, rrset);
if (node == NULL) {
return KNOT_EOK;
}
......@@ -765,7 +744,7 @@ static int process_rem_node(const knot_rrset_t *rr,
const zone_node_t *node, changeset_t *changeset)
{
// Remove all previously added records with given owner from changeset
remove_owner_from_list(&changeset->add, rr->owner);
remove_owner_from_list(changeset->add, rr->owner);
if (node == NULL) {
return KNOT_EOK;
......
......@@ -240,7 +240,7 @@ static int event_reload(zone_t *zone)
/* Store zonefile serial and apply changes from the journal. */
zone->zonefile_serial = zone_contents_serial(contents);
int result = zone_load_journal(contents, zone_config);
int result = zone_load_journal(zone);
if (result != KNOT_EOK) {
goto fail;
}
......@@ -505,7 +505,7 @@ static int event_dnssec(zone_t *zone)
assert(zone);
changeset_t ch;
changeset_init(&ch, NULL);
changeset_init(&ch, zone->name, NULL);
int ret = KNOT_ERROR;
char *zname = knot_dname_to_str(zone->name);
......
......@@ -81,20 +81,21 @@ int zone_load_check(zone_contents_t *contents, conf_zone_t *zone_config)
/*!
* \brief Apply changesets to zone from journal.
*/
int zone_load_journal(zone_contents_t *contents, conf_zone_t *zone_config)
int zone_load_journal(zone_t *zone)
{
/* Check if journal is used and zone is not empty. */
if (!journal_exists(zone_config->ixfr_db) || zone_contents_is_empty(contents)) {
if (!journal_exists(zone->conf->ixfr_db) ||
zone_contents_is_empty(zone->contents)) {
return KNOT_EOK;
}
/* Fetch SOA serial. */
uint32_t serial = zone_contents_serial(contents);
uint32_t serial = zone_contents_serial(zone->contents);
/*! \todo Check what should be the upper bound. */
list_t chgs;
init_list(&chgs);
int ret = journal_load_changesets(zone_config->ixfr_db, &chgs, serial, serial - 1);
int ret = journal_load_changesets(zone, &chgs, serial, serial - 1);
if ((ret != KNOT_EOK && ret != KNOT_ERANGE) || EMPTY_LIST(chgs)) {
changesets_free(&chgs, NULL);
/* Absence of records is not an error. */
......@@ -106,10 +107,10 @@ int zone_load_journal(zone_contents_t *contents, conf_zone_t *zone_config)
}
/* Apply changesets. */
ret = apply_changesets_directly(contents, &chgs);
ret = apply_changesets_directly(zone->contents, &chgs);
log_zone_info("Zone '%s' serial %u -> %u: %s\n",
zone_config->name,
serial, zone_contents_serial(contents),
zone->conf->name,
serial, zone_contents_serial(zone->contents),
knot_strerror(ret));
changesets_free(&chgs, NULL);
......@@ -129,7 +130,7 @@ int zone_load_post(zone_contents_t *contents, zone_t *zone, uint32_t *dnssec_ref
if (conf->dnssec_enable) {
assert(conf->build_diffs);
changeset_t ch;
changeset_init(&ch, NULL);
changeset_init(&ch, zone->name, NULL);
ret = knot_dnssec_zone_sign(contents, conf, &ch, KNOT_SOA_SERIAL_UPDATE,
dnssec_refresh);
if (ret != KNOT_EOK) {
......@@ -140,7 +141,7 @@ int zone_load_post(zone_contents_t *contents, zone_t *zone, uint32_t *dnssec_ref
/* Apply DNSSEC changes. */
list_t apply;
init_list(&apply);
add_head(&apply, &ch);
add_head(&apply, &ch.n);
ret = zone_change_commit(contents, &apply);
changeset_clear(&ch, NULL);
if (ret != KNOT_EOK) {
......@@ -151,7 +152,7 @@ int zone_load_post(zone_contents_t *contents, zone_t *zone, uint32_t *dnssec_ref
/* Calculate IXFR from differences (if configured). */
const bool contents_changed = zone->contents && (contents != zone->contents);
changeset_t diff_change;
changeset_init(&diff_change, NULL);
changeset_init(&diff_change, zone->name, NULL);
if (contents_changed && conf->build_diffs) {
ret = zone_contents_create_diff(zone->contents, contents, &diff_change);
if (ret == KNOT_ENODIFF) {
......
......@@ -45,7 +45,7 @@ int zone_load_check(zone_contents_t *contents, conf_zone_t *zone_config);
* \param zone_config
* \return KNOT_EOK or an error
*/
int zone_load_journal(zone_contents_t *contents, conf_zone_t *zone_config);
int zone_load_journal(zone_t *zone);
/*!
* \brief Zone loading post-actions (zone resign, calculation of delta)
......
......@@ -273,7 +273,7 @@ bool knot_rdataset_member(const knot_rdataset_t *rrs, const knot_rdata_t *rr, bo
return true;
}
if (cmp > 0) {
// 'Bigger' RR present, no need to continue.
// 'Greater' RR present, no need to continue.
return false;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment