Commit 84a70033 authored by Daniel Salzman's avatar Daniel Salzman

Merge branch 'changeset_merge_cancelout' into 'master'

Changeset merge cancelout

See merge request !816
parents 15696fe6 e07750ba
......@@ -43,6 +43,12 @@ static int sign_init(const zone_contents_t *zone, zone_sign_flags_t flags,
return r;
}
// perform nsec3resalt if pending
if (reschedule->allow_nsec3resalt) {
r = knot_dnssec_nsec3resalt(ctx, &reschedule->allow_nsec3resalt, &reschedule->next_nsec3resalt);
}
// perform key rollover if needed
if (reschedule->allow_rollover) {
......
......@@ -34,9 +34,11 @@ typedef enum zone_sign_flags zone_sign_flags_t;
typedef struct {
knot_time_t next_sign;
knot_time_t next_rollover;
knot_time_t next_nsec3resalt;
bool keys_changed;
bool plan_ds_query;
bool allow_rollover; // this one is set by the caller
bool allow_nsec3resalt; // this one is set by the caller and modified by the salter
} zone_sign_reschedule_t;
/*!
......
......@@ -49,9 +49,14 @@ void event_dnssec_reschedule(conf_t *conf, zone_t *zone,
zone->timers.next_parent_ds_q = now;
}
if (refresh->allow_nsec3resalt) {
zone->timers.last_resalt = time(NULL);
}
zone_events_schedule_at(zone,
ZONE_EVENT_DNSSEC, (time_t)refresh_at,
ZONE_EVENT_PARENT_DS_Q, refresh->plan_ds_query ? now : ignore,
ZONE_EVENT_NSEC3RESALT, refresh->next_nsec3resalt ? refresh->next_nsec3resalt : ignore,
ZONE_EVENT_NOTIFY, zone_changed ? now : ignore,
ZONE_EVENT_FLUSH, zone_changed && conf_int(&val) == 0 ? now : ignore
);
......@@ -75,6 +80,10 @@ int event_dnssec(conf_t *conf, zone_t *zone)
sign_flags = 0;
}
if (zone_events_get_time(zone, ZONE_EVENT_NSEC3RESALT) <= time(NULL)) {
resch.allow_nsec3resalt = true;
}
zone_update_t up;
int ret = zone_update_init(&up, zone, UPDATE_INCREMENTAL);
if (ret != KNOT_EOK) {
......
......@@ -1180,7 +1180,7 @@ static int merge_itercb(iteration_ctx_t *ctx)
int ret = vals_to_changeset(ctx->val, ctx->chunk_count, ctx->txn->j->zone, &ch);
if (ret == KNOT_EOK) {
ret = changeset_merge(mch, ch);
ret = changeset_merge(mch, ch, 0);
changeset_free(ch);
}
return ret;
......
......@@ -143,8 +143,14 @@ static knot_rrset_t get_next_rr(changeset_iter_t *ch_it, trie_it_t *t_it)
return node_rrset_at(ch_it->node, ch_it->node_pos++);
}
static void check_redundancy(zone_contents_t *counterpart, const knot_rrset_t *rr)
// removes from counterpart what is in rr.
// fixed_rr is an output parameter, holding a copy of rr without what has been removed from counterpart
static void check_redundancy(zone_contents_t *counterpart, const knot_rrset_t *rr, knot_rrset_t **fixed_rr)
{
if (fixed_rr != NULL) {
*fixed_rr = knot_rrset_copy(rr, NULL);
}
zone_node_t *node = zone_contents_find_node_for_rr(counterpart, rr);
if (node == NULL) {
return;
......@@ -156,6 +162,14 @@ static void check_redundancy(zone_contents_t *counterpart, const knot_rrset_t *r
// Subtract the data from node's RRSet.
knot_rdataset_t *rrs = node_rdataset(node, rr->type);
if (fixed_rr != NULL && *fixed_rr != NULL) {
int ret = knot_rdataset_subtract(&(*fixed_rr)->rrs, rrs, true, NULL);
if (ret != KNOT_EOK) {
return;
}
}
int ret = knot_rdataset_subtract(rrs, &rr->rrs, true, NULL);
if (ret != KNOT_EOK) {
return;
......@@ -266,6 +280,8 @@ int changeset_add_addition(changeset_t *ch, const knot_rrset_t *rrset, changeset
return handle_soa(&ch->soa_to, rrset);
}
knot_rrset_t *rrset_cancelout = NULL;
/* Check if there's any removal and remove that, then add this
* addition anyway. Required to change TTLs. */
if (flags & CHANGESET_CHECK) {
......@@ -275,14 +291,17 @@ int changeset_add_addition(changeset_t *ch, const knot_rrset_t *rrset, changeset
return KNOT_ENOMEM;
}
check_redundancy(ch->remove, rrset);
check_redundancy(ch->remove, rrset,
((flags & CHANGESET_CHECK_CANCELOUT) ? &rrset_cancelout : NULL));
}
int ret = add_rr_to_contents(ch->add, rrset);
const knot_rrset_t *to_add = (rrset_cancelout == NULL ? rrset : rrset_cancelout);
int ret = knot_rrset_empty(to_add) ? KNOT_EOK : add_rr_to_contents(ch->add, to_add);
if (flags & CHANGESET_CHECK) {
knot_rrset_free((knot_rrset_t **)&rrset, NULL);
}
knot_rrset_free(&rrset_cancelout, NULL);
return ret;
}
......@@ -298,6 +317,8 @@ int changeset_add_removal(changeset_t *ch, const knot_rrset_t *rrset, changeset_
return handle_soa(&ch->soa_from, rrset);
}
knot_rrset_t *rrset_cancelout = NULL;
/* Check if there's any addition and remove that, then add this
* removal anyway. */
if (flags & CHANGESET_CHECK) {
......@@ -307,15 +328,19 @@ int changeset_add_removal(changeset_t *ch, const knot_rrset_t *rrset, changeset_
return KNOT_ENOMEM;
}
check_redundancy(ch->add, rrset);
check_redundancy(ch->add, rrset,
((flags & CHANGESET_CHECK_CANCELOUT) ? &rrset_cancelout : NULL));
}
int ret = add_rr_to_contents(ch->remove, rrset);
const knot_rrset_t *to_remove = (rrset_cancelout == NULL ? rrset : rrset_cancelout);
int ret = knot_rrset_empty(to_remove) ? KNOT_EOK : add_rr_to_contents(ch->remove, to_remove);
if (flags & CHANGESET_CHECK) {
knot_rrset_free((knot_rrset_t **)&rrset, NULL);
}
knot_rrset_free(&rrset_cancelout, NULL);
// we don't care of TTLs at removals anyway (updates/apply.c/can_remove()/compare_ttls)
// in practice, this happens at merging changesets
return (ret == KNOT_ETTL ? KNOT_EOK : ret);
......@@ -351,14 +376,14 @@ int changeset_remove_removal(changeset_t *ch, const knot_rrset_t *rrset)
return zone_contents_remove_rr(ch->remove, rrset, &n);
}
int changeset_merge(changeset_t *ch1, const changeset_t *ch2)
int changeset_merge(changeset_t *ch1, const changeset_t *ch2, int flags)
{
changeset_iter_t itt;
changeset_iter_rem(&itt, ch2);
knot_rrset_t rrset = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rrset)) {
int ret = changeset_add_removal(ch1, &rrset, CHANGESET_CHECK);
int ret = changeset_add_removal(ch1, &rrset, CHANGESET_CHECK | flags);
if (ret != KNOT_EOK) {
changeset_iter_clear(&itt);
return ret;
......@@ -371,7 +396,7 @@ int changeset_merge(changeset_t *ch1, const changeset_t *ch2)
rrset = changeset_iter_next(&itt);
while (!knot_rrset_empty(&rrset)) {
int ret = changeset_add_addition(ch1, &rrset, CHANGESET_CHECK);
int ret = changeset_add_addition(ch1, &rrset, CHANGESET_CHECK | flags);
if (ret != KNOT_EOK) {
changeset_iter_clear(&itt);
return ret;
......
......@@ -24,6 +24,7 @@
typedef enum {
CHANGESET_NONE = 0,
CHANGESET_CHECK = 1 << 0, /*! Perform redundancy check on additions/removals */
CHANGESET_CHECK_CANCELOUT = 1 << 1, /*! Do the complete cancelout on addition/removal/merge (depends on CHANGESET_CHECK */
} changeset_flag_t;
/*! \brief One zone change, from 'soa_from' to 'soa_to'. */
......@@ -130,10 +131,11 @@ int changeset_remove_removal(changeset_t *ch, const knot_rrset_t *rrset);
*
* \param ch1 Merge into this changeset.
* \param ch2 Merge this changeset.
* \param flags Flags how to handle rendundancies.
*
* \return KNOT_E*
*/
int changeset_merge(changeset_t *ch1, const changeset_t *ch2);
int changeset_merge(changeset_t *ch1, const changeset_t *ch2, int flags);
/*!
* \brief Remove from changeset those rdata which won't be added/removed from zone.
......
......@@ -448,7 +448,7 @@ int zone_update_apply_changeset(zone_update_t *update, const changeset_t *change
{
int ret = KNOT_EOK;
if (update->flags & UPDATE_INCREMENTAL) {
ret = changeset_merge(&update->change, changes);
ret = changeset_merge(&update->change, changes, CHANGESET_CHECK_CANCELOUT);
}
if (ret == KNOT_EOK) {
ret = apply_changeset_directly(&update->a_ctx, changes);
......
......@@ -569,6 +569,10 @@ class Server(object):
for line in log:
if pattern in line:
return True
with open(self.ferr) as log:
for line in log:
if pattern in line:
return True
return False
def zone_wait(self, zone, serial=None, equal=False, greater=True):
......
......@@ -143,7 +143,7 @@ int main(int argc, char *argv[])
assert(ret == KNOT_EOK);
// Test merge.
ret = changeset_merge(ch, ch2);
ret = changeset_merge(ch, ch2, 0);
ok(ret == KNOT_EOK && changeset_size(ch) == 5, "changeset: merge");
// Test preapply fix.
......
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