Commit b82dd3ea authored by Dominik Taborsky's avatar Dominik Taborsky

zone_update: cleanup, renaming, details

parent 72373bc0
......@@ -44,18 +44,18 @@ static int rem_from_node(zone_node_t *node, const zone_node_t *rem_node,
knot_mm_t *mm)
{
for (uint16_t i = 0; i < rem_node->rrset_count; ++i) {
// Remove each found RR from 'node'.
/* Remove each found RR from 'node'. */
knot_rrset_t rem_rrset = node_rrset_at(rem_node, i);
knot_rdataset_t *to_change = node_rdataset(node, rem_rrset.type);
if (to_change) {
// Remove data from synthesized node
/* Remove data from synthesized node */
int ret = knot_rdataset_subtract(to_change,
&rem_rrset.rrs,
mm);
if (ret != KNOT_EOK) {
return ret;
}
// Remove whole rdataset if empty
/* Remove whole rdataset if empty */
if (to_change->rr_count == 0) {
node_remove_rdataset(node, rem_rrset.type);
}
......@@ -68,7 +68,7 @@ static int rem_from_node(zone_node_t *node, const zone_node_t *rem_node,
static int apply_changes_to_node(zone_node_t *synth_node, const zone_node_t *add_node,
const zone_node_t *rem_node, knot_mm_t *mm)
{
// Add changes to node
/* Add changes to node */
if (!node_empty(add_node)) {
int ret = add_to_node(synth_node, add_node, mm);
if (ret != KNOT_EOK) {
......@@ -76,7 +76,7 @@ static int apply_changes_to_node(zone_node_t *synth_node, const zone_node_t *add
}
}
// Remove changes from node
/* Remove changes from node */
if (!node_empty(rem_node)) {
int ret = rem_from_node(synth_node, rem_node, mm);
if (ret != KNOT_EOK) {
......@@ -90,7 +90,7 @@ static int apply_changes_to_node(zone_node_t *synth_node, const zone_node_t *add
static int deep_copy_node_data(zone_node_t *node_copy, const zone_node_t *node,
knot_mm_t *mm)
{
// Clear space for RRs
/* Clear space for RRs */
node_copy->rrs = NULL;
node_copy->rrset_count = 0;
......@@ -107,13 +107,17 @@ static int deep_copy_node_data(zone_node_t *node_copy, const zone_node_t *node,
static zone_node_t *node_deep_copy(const zone_node_t *node, knot_mm_t *mm)
{
// Shallow copy old node
if (node == NULL) {
return NULL;
}
/* Shallow copy old node */
zone_node_t *synth_node = node_shallow_copy(node, mm);
if (synth_node == NULL) {
return NULL;
}
// Deep copy data inside node copy.
/* Deep copy data inside node copy. */
int ret = deep_copy_node_data(synth_node, node, mm);
if (ret != KNOT_EOK) {
node_free(&synth_node, mm);
......@@ -134,7 +138,7 @@ static int init_incremental(zone_update_t *update, zone_t *zone)
return ret;
}
// Copy base SOA RR.
/* Copy base SOA RR. */
update->change.soa_from =
node_create_rrset(update->zone->contents->apex, KNOT_RRTYPE_SOA);
if (update->change.soa_from == NULL) {
......@@ -154,7 +158,7 @@ static int init_full(zone_update_t *update, zone_t *zone)
return KNOT_EOK;
}
const zone_node_t *get_synth_node(zone_update_t *update, const knot_dname_t *dname)
static const zone_node_t *get_synth_node(zone_update_t *update, const knot_dname_t *dname)
{
const zone_node_t *old_node =
zone_contents_find_node(update->zone->contents, dname);
......@@ -165,28 +169,28 @@ const zone_node_t *get_synth_node(zone_update_t *update, const knot_dname_t *dna
const bool have_change = !node_empty(add_node) || !node_empty(rem_node);
if (!have_change) {
// Nothing to apply
/* Nothing to apply */
return old_node;
}
if (!old_node) {
if (old_node == NULL) {
if (add_node && node_empty(rem_node)) {
// Just addition
/* Just addition */
return add_node;
} else {
// Addition and deletion
/* Addition and deletion */
old_node = add_node;
add_node = NULL;
}
}
// We have to apply changes to node.
/* We have to apply changes to node. */
zone_node_t *synth_node = node_deep_copy(old_node, &update->mm);
if (synth_node == NULL) {
return NULL;
}
// Apply changes to node.
/* Apply changes to node. */
int ret = apply_changes_to_node(synth_node, add_node, rem_node,
&update->mm);
if (ret != KNOT_EOK) {
......@@ -238,6 +242,10 @@ const zone_node_t *zone_update_get_node(zone_update_t *update, const knot_dname_
const zone_node_t *zone_update_get_apex(zone_update_t *update)
{
if (update == NULL) {
return NULL;
}
return zone_update_get_node(update, update->zone->name);
}
......@@ -253,6 +261,10 @@ uint32_t zone_update_current_serial(zone_update_t *update)
const knot_rdataset_t *zone_update_from(zone_update_t *update)
{
if (update == NULL) {
return NULL;
}
if (update->flags & UPDATE_INCREMENTAL) {
const zone_node_t *apex = update->zone->contents->apex;
return node_rdataset(apex, KNOT_RRTYPE_SOA);
......@@ -263,7 +275,9 @@ const knot_rdataset_t *zone_update_from(zone_update_t *update)
const knot_rdataset_t *zone_update_to(zone_update_t *update)
{
assert(update);
if (update == NULL) {
return NULL;
}
if (update->flags & UPDATE_FULL) {
const zone_node_t *apex = update->new_cont->apex;
......@@ -280,7 +294,7 @@ const knot_rdataset_t *zone_update_to(zone_update_t *update)
void zone_update_clear(zone_update_t *update)
{
if (update) {
if (update != NULL) {
if (update->flags & UPDATE_INCREMENTAL) {
/* Revert any changes on error, do nothing on success. */
update_rollback(&update->a_ctx);
......@@ -295,6 +309,10 @@ void zone_update_clear(zone_update_t *update)
int zone_update_add(zone_update_t *update, const knot_rrset_t *rrset)
{
if (update == NULL) {
return KNOT_EINVAL;
}
if (update->flags & UPDATE_INCREMENTAL) {
return changeset_add_rrset(&update->change, rrset, CHANGESET_CHECK);
} else if (update->flags & UPDATE_FULL) {
......@@ -307,6 +325,10 @@ int zone_update_add(zone_update_t *update, const knot_rrset_t *rrset)
int zone_update_remove(zone_update_t *update, const knot_rrset_t *rrset)
{
if (update == NULL) {
return KNOT_EINVAL;
}
if (update->flags & UPDATE_INCREMENTAL) {
return changeset_rem_rrset(&update->change, rrset, CHANGESET_CHECK);
} else if (update->flags & UPDATE_FULL) {
......@@ -321,6 +343,8 @@ static bool apex_rr_changed(const zone_node_t *old_apex,
const zone_node_t *new_apex,
uint16_t type)
{
assert(old_apex);
assert(new_apex);
knot_rrset_t old_rr = node_rrset(old_apex, type);
knot_rrset_t new_rr = node_rrset(new_apex, type);
......@@ -329,23 +353,27 @@ static bool apex_rr_changed(const zone_node_t *old_apex,
static bool apex_dnssec_changed(zone_update_t *update)
{
assert(update->zone->contents);
const zone_node_t *new_apex = zone_update_get_apex(update);
const zone_node_t *old_apex = update->zone->contents->apex;
return !changeset_empty(&update->change) &&
(apex_rr_changed(new_apex, old_apex, KNOT_RRTYPE_DNSKEY) ||
apex_rr_changed(new_apex, old_apex, KNOT_RRTYPE_NSEC3PARAM));
if (update->zone->contents != NULL) {
const zone_node_t *old_apex = update->zone->contents->apex;
return !changeset_empty(&update->change) &&
(apex_rr_changed(new_apex, old_apex, KNOT_RRTYPE_DNSKEY) ||
apex_rr_changed(new_apex, old_apex, KNOT_RRTYPE_NSEC3PARAM));
} else if (new_apex != NULL) {
return true;
}
return false;
}
static int sign_update(zone_update_t *update,
zone_contents_t *new_contents)
{
assert(update != NULL);
assert(update);
assert(new_contents);
/*
* Check if the UPDATE changed DNSKEYs or NSEC3PARAM.
* If so, we have to sign the whole zone.
*/
/* Check if the UPDATE changed DNSKEYs or NSEC3PARAM.
* If so, we have to sign the whole zone. */
int ret = KNOT_EOK;
uint32_t refresh_at = 0;
changeset_t sec_ch;
......@@ -361,7 +389,7 @@ static int sign_update(zone_update_t *update,
ZONE_SIGN_KEEP_SOA_SERIAL,
&refresh_at);
} else {
// Sign the created changeset
/* Sign the created changeset */
ret = knot_dnssec_sign_changeset(new_contents, &update->change,
&sec_ch, &refresh_at);
}
......@@ -370,7 +398,7 @@ static int sign_update(zone_update_t *update,
return ret;
}
// Apply DNSSEC changeset
/* Apply DNSSEC changeset */
ret = apply_changeset_directly(&update->a_ctx, new_contents, &sec_ch);
if (ret != KNOT_EOK) {
changeset_clear(&sec_ch);
......@@ -378,7 +406,7 @@ static int sign_update(zone_update_t *update,
}
if (!full_sign) {
// Merge changesets
/* Merge changesets */
ret = changeset_merge(&update->change, &sec_ch);
if (ret != KNOT_EOK) {
update_rollback(&update->a_ctx);
......@@ -387,16 +415,14 @@ static int sign_update(zone_update_t *update,
}
}
// Plan next zone resign.
/* Plan next zone resign. */
const time_t resign_time = zone_events_get_time(update->zone, ZONE_EVENT_DNSSEC);
if (refresh_at < resign_time) {
zone_events_schedule_at(update->zone, ZONE_EVENT_DNSSEC, refresh_at);
}
/*
* We are not calling update_cleanup, as the rollback data are merged
* into the main changeset and will get cleaned up with that.
*/
/* We are not calling update_cleanup, as the rollback data are merged
* into the main changeset and will get cleaned up with that. */
changeset_clear(&sec_ch);
return KNOT_EOK;
......@@ -428,6 +454,7 @@ static int set_new_soa(zone_update_t *update, unsigned serial_policy)
static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents_t **contents_out)
{
assert(update);
assert(contents_out);
if (changeset_empty(&update->change)) {
changeset_clear(&update->change);
......@@ -436,7 +463,7 @@ static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents
int ret = KNOT_EOK;
if (zone_update_to(update) == NULL) {
// No SOA in the update, create one according to the current policy
/* No SOA in the update, create one according to the current policy */
conf_val_t val = conf_zone_get(conf, C_SERIAL_POLICY, update->zone->name);
ret = set_new_soa(update, conf_opt(&val));
if (ret != KNOT_EOK) {
......@@ -444,7 +471,7 @@ static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents
}
}
// Apply changes.
/* Apply changes. */
zone_contents_t *new_contents = NULL;
ret = apply_changeset(&update->a_ctx, update->zone, &update->change, &new_contents);
if (ret != KNOT_EOK) {
......@@ -455,9 +482,9 @@ static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents
assert(new_contents);
conf_val_t val = conf_zone_get(conf, C_DNSSEC_SIGNING, update->zone->name);
bool dnssec_enable = update->flags & UPDATE_SIGN && conf_bool(&val);
bool dnssec_enable = (update->flags & UPDATE_SIGN) && conf_bool(&val);
// Sign the update.
/* Sign the update. */
if (dnssec_enable) {
ret = sign_update(update, new_contents);
if (ret != KNOT_EOK) {
......@@ -468,7 +495,7 @@ static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents
}
}
// Write changes to journal if all went well. (DNSSEC merged)
/* Write changes to journal if all went well. (DNSSEC merged) */
ret = zone_change_store(conf, update->zone, &update->change);
if (ret != KNOT_EOK) {
update_rollback(&update->a_ctx);
......@@ -483,18 +510,24 @@ static int commit_incremental(conf_t *conf, zone_update_t *update, zone_contents
static int commit_full(conf_t *conf, zone_update_t *update, zone_contents_t **contents_out)
{
int ret = KNOT_EOK;
//!\todo: perform some semantic checks, like if the zone has SOA
// - actually, do we really want to?
assert(update);
assert(contents_out);
/* Check if we have SOA. We might consider adding full semantic check here.
* But if we wanted full sem-check I'd consider being it controlled by a flag
* - to enable/disable it on demand. */
if (!node_rrtype_exists(update->new_cont->apex, KNOT_RRTYPE_SOA)) {
return KNOT_ESEMCHECK;
}
zone_contents_adjust_full(update->new_cont);
conf_val_t val = conf_zone_get(conf, C_DNSSEC_SIGNING, update->zone->name);
bool dnssec_enable = update->flags & UPDATE_SIGN && conf_bool(&val);
bool dnssec_enable = (update->flags & UPDATE_SIGN) && conf_bool(&val);
// Sign the update.
/* Sign the update. */
if (dnssec_enable) {
ret = sign_update(update, update->new_cont);
int ret = sign_update(update, update->new_cont);
if (ret != KNOT_EOK) {
update_rollback(&update->a_ctx);
return ret;
......@@ -508,7 +541,7 @@ static int commit_full(conf_t *conf, zone_update_t *update, zone_contents_t **co
int zone_update_commit(conf_t *conf, zone_update_t *update)
{
if (!conf || !update) {
if (conf == NULL || update == NULL) {
return KNOT_EINVAL;
}
......@@ -527,7 +560,7 @@ int zone_update_commit(conf_t *conf, zone_update_t *update)
}
/* If there is anything to change */
if (new_contents) {
if (new_contents != NULL) {
/* Switch zone contents. */
zone_contents_t *old_contents = zone_switch_contents(update->zone, new_contents);
......@@ -548,35 +581,35 @@ int zone_update_commit(conf_t *conf, zone_update_t *update)
static void select_next_node(zone_update_iter_t *it)
{
int compare = 0;
if (it->t_node) {
if (it->add_node) {
if (it->base_node != NULL) {
if (it->add_node != NULL) {
/* Both original and new node exists. Choose the 'smaller' node to return. */
compare = knot_dname_cmp(it->t_node->owner, it->add_node->owner);
compare = knot_dname_cmp(it->base_node->owner, it->add_node->owner);
if (compare <= 0) {
// Return the original node.
it->next_n = it->t_node;
it->t_node = NULL;
/* Return the original node. */
it->next_node = it->base_node;
it->base_node = NULL;
if (compare == 0) {
it->add_node = NULL;
}
} else {
// Return the new node.
it->next_n = it->add_node;
/* Return the new node. */
it->next_node = it->add_node;
it->add_node = NULL;
}
} else {
// Return the original node.
it->next_n = it->t_node;
it->t_node = NULL;
/* Return the original node. */
it->next_node = it->base_node;
it->base_node = NULL;
}
} else {
if (it->add_node) {
// Return the new node.
it->next_n = it->add_node;
if (it->add_node != NULL) {
/* Return the new node. */
it->next_node = it->add_node;
it->add_node = NULL;
} else {
// Iteration done.
it->next_n = NULL;
/* Iteration done. */
it->next_node = NULL;
}
}
}
......@@ -599,13 +632,13 @@ static int iter_init_tree_iters(zone_update_iter_t *it, zone_update_t *update,
/* Begin iteration. We can safely assume _contents is a valid pointer. */
tree = nsec3 ? _contents->nsec3_nodes : _contents->nodes;
hattrie_build_index(tree);
it->t_it = hattrie_iter_begin(nsec3 ? _contents->nsec3_nodes : _contents->nodes, true);
if (it->t_it == NULL) {
it->base_it = hattrie_iter_begin(nsec3 ? _contents->nsec3_nodes : _contents->nodes, true);
if (it->base_it == NULL) {
return KNOT_ENOMEM;
}
/* Set changeset iterator. */
if (update->flags & UPDATE_INCREMENTAL && !changeset_empty(&update->change)) {
if ((update->flags & UPDATE_INCREMENTAL) && !changeset_empty(&update->change)) {
tree = nsec3 ? update->change.add->nsec3_nodes :
update->change.add->nodes;
if (tree == NULL) {
......@@ -614,14 +647,14 @@ static int iter_init_tree_iters(zone_update_iter_t *it, zone_update_t *update,
hattrie_build_index(tree);
it->add_it = hattrie_iter_begin(tree, true);
if (it->add_it == NULL) {
hattrie_iter_free(it->t_it);
hattrie_iter_free(it->base_it);
return KNOT_ENOMEM;
}
}
} else {
it->add_it = NULL;
}
return KNOT_EOK;
}
......@@ -641,19 +674,19 @@ static int iter_get_added_node(zone_update_iter_t *it)
static int iter_get_synth_node(zone_update_iter_t *it)
{
hattrie_iter_next(it->t_it);
if (hattrie_iter_finished(it->t_it)) {
hattrie_iter_free(it->t_it);
it->t_it = NULL;
hattrie_iter_next(it->base_it);
if (hattrie_iter_finished(it->base_it)) {
hattrie_iter_free(it->base_it);
it->base_it = NULL;
return KNOT_ENOENT;
}
const zone_node_t *n = (zone_node_t *)(*hattrie_iter_val(it->t_it));
const zone_node_t *n = (zone_node_t *)(*hattrie_iter_val(it->base_it));
if (it->update->flags & UPDATE_FULL) {
it->t_node = n;
it->base_node = n;
} else {
it->t_node = zone_update_get_node(it->update, n->owner);
if (it->t_node == NULL) {
it->base_node = zone_update_get_node(it->update, n->owner);
if (it->base_node == NULL) {
return KNOT_ENOMEM;
}
}
......@@ -672,16 +705,16 @@ static int iter_init(zone_update_iter_t *it, zone_update_t *update, const bool n
return ret;
}
if (it->add_it) {
if (it->add_it != NULL) {
it->add_node = (zone_node_t *)(*hattrie_iter_val(it->add_it));
assert(it->add_node);
}
if (it->t_it) {
it->t_node = (zone_node_t *)(*hattrie_iter_val(it->t_it));
assert(it->t_node);
if (it->base_it != NULL) {
it->base_node = (zone_node_t *)(*hattrie_iter_val(it->base_it));
assert(it->base_node);
if (it->update->flags & UPDATE_INCREMENTAL) {
it->t_node = zone_update_get_node(it->update, it->t_node->owner);
if (it->t_node == NULL) {
it->base_node = zone_update_get_node(it->update, it->base_node->owner);
if (it->base_node == NULL) {
return KNOT_ENOMEM;
}
}
......@@ -693,20 +726,28 @@ static int iter_init(zone_update_iter_t *it, zone_update_t *update, const bool n
int zone_update_iter(zone_update_iter_t *it, zone_update_t *update)
{
if (it == NULL || update == NULL) {
return KNOT_EINVAL;
}
return iter_init(it, update, false);
}
int zone_update_iter_nsec3(zone_update_iter_t *it, zone_update_t *update)
{
if (it == NULL || update == NULL) {
return KNOT_EINVAL;
}
if (update->flags & UPDATE_FULL) {
if (update->new_cont->nsec3_nodes == NULL) {
// No NSEC3 tree.
/* No NSEC3 tree. */
return KNOT_ENOENT;
}
} else {
if (update->change.add->nsec3_nodes == NULL &&
update->change.remove->nsec3_nodes == NULL) {
// No NSEC3 changes.
/* No NSEC3 changes. */
return KNOT_ENOENT;
}
}
......@@ -720,29 +761,29 @@ int zone_update_iter_next(zone_update_iter_t *it)
return KNOT_EINVAL;
}
// Get nodes from both iterators if needed.
if (it->t_it && it->t_node == NULL) {
/* Get nodes from both iterators if needed. */
if (it->base_it != NULL && it->base_node == NULL) {
int ret = iter_get_synth_node(it);
if (ret != KNOT_EOK && ret != KNOT_ENOENT) {
return ret;
}
}
if (it->add_it && it->add_node == NULL) {
if (it->add_it != NULL && it->add_node == NULL) {
int ret = iter_get_added_node(it);
if (ret != KNOT_EOK && ret != KNOT_ENOENT) {
return ret;
}
}
select_next_node(it);
return KNOT_EOK;
}
const zone_node_t *zone_update_iter_val(zone_update_iter_t *it)
{
if (it) {
return it->next_n;
if (it != NULL) {
return it->next_node;
} else {
return NULL;
}
......@@ -750,16 +791,26 @@ const zone_node_t *zone_update_iter_val(zone_update_iter_t *it)
int zone_update_iter_finish(zone_update_iter_t *it)
{
hattrie_iter_free(it->t_it);
if (it == NULL) {
return KNOT_EINVAL;
}
hattrie_iter_free(it->base_it);
return KNOT_EOK;
}
bool zone_update_no_change(zone_update_t *update)
{
if (update == NULL) {
return true;
}
if (update->flags & UPDATE_INCREMENTAL) {
return changeset_empty(&update->change);
} else {
return false; //!\todo: there's no zone_contents_empty() function, do we need it?
/* This branch does not make much sense and FULL update will most likely
* be a change every time anyway, just return false. */
return false;
}
}
......@@ -43,11 +43,11 @@ typedef struct {
typedef struct {
zone_update_t *update; /*!< The update we're iterating over. */
hattrie_iter_t *t_it; /*!< Iterator for the original zone in the case of INCREMENTAL update or the new zone in case of FULL update. */
hattrie_iter_t *base_it; /*!< Iterator for the original zone in the case of INCREMENTAL update or the new zone in case of FULL update. */
hattrie_iter_t *add_it; /*!< Iterator for the added nodes in the changeset. Available in the INCREMENTAL update only. */
const zone_node_t *t_node; /*!< The original node (INCREMENTAL update) or new node (FULL update). */
const zone_node_t *base_node; /*!< The original node (INCREMENTAL update) or new node (FULL update). */
const zone_node_t *add_node; /*!< The additions to that node (INCREMENTAL update only). */
const zone_node_t *next_n; /*!< The smaller of t_node and ch_node (INCREMENTAL update) or next new node (FULL update). */
const zone_node_t *next_node; /*!< The smaller of t_node and ch_node (INCREMENTAL update) or next new node (FULL update). */
bool nsec3; /*!< Set when we're using the NSEC3 node tree. */
} zone_update_iter_t;
......
......@@ -566,7 +566,6 @@ static int remove_rr(zone_contents_t *z, const knot_rrset_t *rr,
return KNOT_EOUTOFZONE;
}
int ret = KNOT_EOK;
zone_node_t *node;
if (*n == NULL) {
node = nsec3 ? get_nsec3_node(z, rr->owner) : get_node(z, rr->owner);
......@@ -579,7 +578,7 @@ static int remove_rr(zone_contents_t *z, const knot_rrset_t *rr,
knot_rdataset_t *node_rrs = node_rdataset(node, rr->type);
// Subtract changeset RRS from node RRS.
ret = knot_rdataset_subtract(node_rrs, &rr->rrs, NULL);
int ret = knot_rdataset_subtract(node_rrs, &rr->rrs, NULL);
if (ret != KNOT_EOK) {
return ret;
}
......
......@@ -217,9 +217,7 @@ int main(int argc, char *argv[])
plan_lazy();
/* Load test configuration. */
const char *conf_str = "server:\n identity: bogus.ns\n version: 0.11\n nsid: \n"
"zone:\n - domain: test.\n zonefile-sync: -1\n"
" storage: /tmp\n";
const char *conf_str = "zone:\n - domain: test.\n storage: /tmp\n";
int ret = test_conf(conf_str, NULL);
if (ret != KNOT_EOK) {
return ret;
......
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