Commit 53bf2fe0 authored by Lubos Slovak's avatar Lubos Slovak

Preparation to use new DDNS processing - part 2.

refs #2184 @40m
parent 24e1025e
......@@ -2103,7 +2103,7 @@ static int zones_process_update_auth(knot_zone_t *zone,
char *r_str = xfr_remote_str(addr, keytag);
const char *zone_name = ((zonedata_t*)knot_zone_data(zone))->conf->name;
char *msg = sprintf_alloc("UPDATE of '%s' from %s:",
zone_name, r_str ? r_str : "'unknown'");
zone_name, r_str ? r_str : "'unknown'");
free(r_str);
free(keytag);
log_zone_info("%s Started.\n", msg);
......@@ -2138,9 +2138,9 @@ static int zones_process_update_auth(knot_zone_t *zone,
// knot_zone_contents_t *new_contents = NULL;
// ret = knot_ns_process_update2(knot_packet_query(resp),
// knot_zone_contents(zone),
// knot_zone_get_contents(zone),
// &new_contents,
// &chgsets->sets[0], rcode);
// chgsets, rcode);
// if (ret != KNOT_EOK) {
// log_zone_error("%s %s\n", msg, knot_strerror(ret));
// knot_free_changesets(&chgsets);
......@@ -2148,40 +2148,44 @@ static int zones_process_update_auth(knot_zone_t *zone,
// return ret;
// }
// /* Store changesets, (TODO: but do not commit???). */
// /* 2) Store changesets, (TODO: but do not commit???). */
// ret = zones_store_changesets_to_disk(zone, chgsets);
// if (ret != KNOT_EOK) {
// log_zone_error("%s %s\n", msg, knot_strerror(ret));
// xfrin_rollback_update(zone->contents, &new_contents,
// &chgsets->changes);
// knot_free_changesets(&chgsets);
// free(msg);
// return ret;
// }
// /* Switch zone contents. */
// /* 3) Switch zone contents. */
// knot_zone_retain(zone); /* Retain pointer for safe RCU unlock. */
// rcu_read_unlock(); /* Unlock for switch. */
// ret = xfrin_switch_zone(zone, new_contents, type);
// ret = xfrin_switch_zone(zone, new_contents, XFR_TYPE_UPDATE);
// rcu_read_lock(); /* Relock */
// knot_zone_release(zone);/* Release held pointer. */
// if (ret != KNOT_EOK) {
// log_zone_error("%s Failed to replace current zone - %s\n",
// msgpref, knot_strerror(ret));
// log_zone_error("%s: Failed to replace current zone - %s\n",
// msg, knot_strerror(ret));
// // Cleanup old and new contents
// xfrin_rollback_update(zone->contents, &new_contents,
// &chs->changes);
// &chgsets->changes);
// /* Free changesets, but not the data. */
// knot_free_changesets(&chs);
// knot_free_changesets(&chgsets);
// return KNOT_ERROR;
// }
// xfrin_cleanup_successful_update(&chs->changes);
// /* 4) Cleanup. */
// xfrin_cleanup_successful_update(&chgsets->changes);
// /* Free changesets, but not the data. */
// knot_free_changesets(&chs);
// knot_free_changesets(&chgsets);
// assert(ret == KNOT_EOK);
// log_zone_info("%s Finished.\n", msgpref);
// log_zone_info("%s: Finished.\n", msg);
// free(msg);
// msg = NULL;
......
......@@ -4281,18 +4281,63 @@ int knot_ns_process_update(const knot_packet_t *query,
/*----------------------------------------------------------------------------*/
/*
* This function should:
* 1) Create zone shallow copy.
* 2) Create 'changes' structure and store it to 'changeset'.
* 3) Call knot_ddns_process_update2().
* 4 a) If something went bad, call xfrin_rollback_update() and return an error.
* b) If everything went OK, return.
* 1) Create zone shallow copy and the changes structure.
* 2) Call knot_ddns_process_update2().
* - If something went bad, call xfrin_rollback_update() and return an error.
* - If everything went OK, continue.
* 3) Finalize the updated zone.
*
* NOTE: Mostly copied from xfrin_apply_changesets(). Should be refactored in
* order to get rid of duplicate code.
*/
int knot_ns_process_update2(const knot_packet_t *query,
const knot_zone_contents_t *zone,
knot_zone_contents_t *new_zone,
knot_changeset_t *changeset, knot_rcode_t *rcode)
knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents,
knot_changesets_t *chgs, knot_rcode_t *rcode)
{
/*! \todo Implement. */
if (query == NULL || old_contents == NULL || chgs == NULL ||
chgs->sets == NULL || new_contents == NULL || rcode == NULL) {
return KNOT_EINVAL;
}
dbg_ns("Applying UPDATE to zone...\n");
/* 1) Create zone shallow copy. */
dbg_ns_verb("Creating shallow copy of the zone...\n");
knot_zone_contents_t *contents_copy = NULL;
knot_changes_t *changes = NULL;
int ret = xfrin_prepare_zone_copy(old_contents, &contents_copy,
&changes);
if (ret != KNOT_EOK) {
dbg_ns("Failed to prepare zone copy: %s\n",
knot_strerror(ret));
return ret;
}
/* 2) Apply the UPDATE and create changesets. */
dbg_ns_verb("Applying the UPDATE and creating changeset...\n");
ret = knot_ddns_process_update2(contents_copy, query, &chgs->sets[0],
changes, rcode);
if (ret != KNOT_EOK) {
dbg_ns("Failed to apply UPDATE to the zone copy: %\n",
knot_strerror(ret));
xfrin_rollback_update(old_contents, &contents_copy, &changes);
return ret;
}
dbg_ns_verb("Finalizing updated zone...\n");
ret = xfrin_finalize_updated_zone(contents_copy, changes, old_contents);
if (ret != KNOT_EOK) {
dbg_ns("Failed to finalize updated zone: %s\n",
knot_strerror(ret));
xfrin_rollback_update(old_contents, &contents_copy, &changes);
return ret;
}
chgs->changes = changes;
*new_contents = contents_copy;
return KNOT_ERROR;
}
......
......@@ -352,6 +352,11 @@ int knot_ns_process_update(const knot_packet_t *query,
const knot_zone_contents_t *zone,
knot_changeset_t *changeset, knot_rcode_t *rcode);
int knot_ns_process_update2(const knot_packet_t *query,
knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents,
knot_changesets_t *chgs, knot_rcode_t *rcode);
int knot_ns_create_forward_query(const knot_packet_t *query,
uint8_t *query_wire, size_t *size);
......
......@@ -3173,22 +3173,15 @@ static int xfrin_check_contents_copy(knot_zone_contents_t *old_contents)
/*----------------------------------------------------------------------------*/
int xfrin_apply_changesets(knot_zone_t *zone,
knot_changesets_t *chsets,
knot_zone_contents_t **new_contents)
int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents,
knot_changes_t **changes)
{
if (zone == NULL || chsets == NULL || chsets->count == 0
|| new_contents == NULL) {
if (old_contents == NULL || new_contents == NULL || changes == NULL) {
return KNOT_EINVAL;
}
knot_zone_contents_t *old_contents = knot_zone_get_contents(zone);
if (!old_contents) {
dbg_xfrin("Cannot apply changesets to empty zone.\n");
return KNOT_EINVAL;
}
dbg_xfrin("Applying changesets to zone...\n");
dbg_xfrin("Preparing zone copy...\n");
/*
* Ensure that the zone generation is set to 0.
......@@ -3220,15 +3213,15 @@ int xfrin_apply_changesets(knot_zone_t *zone,
return ret;
}
knot_changes_t *changes = (knot_changes_t *)malloc(
knot_changes_t *chgs = (knot_changes_t *)malloc(
sizeof(knot_changes_t));
if (changes == NULL) {
if (chgs == NULL) {
dbg_xfrin("Failed to allocate structure for changes!\n");
xfrin_rollback_update(old_contents, &contents_copy, &changes);
xfrin_rollback_update(old_contents, &contents_copy, &chgs);
return KNOT_ENOMEM;
}
memset(changes, 0, sizeof(knot_changes_t));
memset(chgs, 0, sizeof(knot_changes_t));
/*!
* \todo Check if all nodes have their copy.
......@@ -3236,7 +3229,7 @@ int xfrin_apply_changesets(knot_zone_t *zone,
ret = xfrin_check_contents_copy(old_contents);
if (ret != KNOT_EOK) {
dbg_xfrin("Contents copy check failed!\n");
xfrin_rollback_update(old_contents, &contents_copy, &changes);
xfrin_rollback_update(old_contents, &contents_copy, &chgs);
return ret;
}
......@@ -3249,30 +3242,23 @@ int xfrin_apply_changesets(knot_zone_t *zone,
dbg_xfrin("Switching ptrs pointing to old nodes to the new nodes.\n");
ret = xfrin_switch_nodes(contents_copy);
assert(knot_zone_contents_apex(contents_copy) != NULL);
*new_contents = contents_copy;
*changes = chgs;
return KNOT_EOK;
}
/*
* Apply the changesets.
*/
dbg_xfrin("Applying changesets.\n");
dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n",
old_contents->apex, contents_copy->apex);
for (int i = 0; i < chsets->count; ++i) {
if ((ret = xfrin_apply_changeset(contents_copy, changes,
&chsets->sets[i]))
!= KNOT_EOK) {
xfrin_rollback_update(old_contents,
&contents_copy, &changes);
dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret));
return ret;
}
}
assert(knot_zone_contents_apex(contents_copy) != NULL);
/*!
* \todo Test failure of IXFR.
*/
/*----------------------------------------------------------------------------*/
int xfrin_finalize_updated_zone(knot_zone_contents_t *contents_copy,
knot_changes_t *changes,
knot_zone_contents_t *old_contents)
{
if (contents_copy == NULL || changes == NULL || old_contents == NULL) {
return KNOT_EINVAL;
}
/*
* Finalize the new zone contents:
* - delete empty nodes
......@@ -3285,7 +3271,7 @@ int xfrin_apply_changesets(knot_zone_t *zone,
* Select and remove empty nodes from zone trees. Do not free them right
* away as they may be referenced by some domain names.
*/
ret = xfrin_remove_empty_nodes(contents_copy, changes);
int ret = xfrin_remove_empty_nodes(contents_copy, changes);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to remove empty nodes: %s\n",
knot_strerror(ret));
......@@ -3312,6 +3298,71 @@ int xfrin_apply_changesets(knot_zone_t *zone,
xfrin_rollback_update(old_contents, &contents_copy, &changes);
return ret;
}
return KNOT_EOK;
}
/*----------------------------------------------------------------------------*/
int xfrin_apply_changesets(knot_zone_t *zone,
knot_changesets_t *chsets,
knot_zone_contents_t **new_contents)
{
if (zone == NULL || chsets == NULL || chsets->count == 0
|| new_contents == NULL) {
return KNOT_EINVAL;
}
knot_zone_contents_t *old_contents = knot_zone_get_contents(zone);
if (!old_contents) {
dbg_xfrin("Cannot apply changesets to empty zone.\n");
return KNOT_EINVAL;
}
dbg_xfrin("Applying changesets to zone...\n");
dbg_xfrin_verb("Creating shallow copy of the zone...\n");
knot_zone_contents_t *contents_copy = NULL;
knot_changes_t *changes = NULL;
int ret = xfrin_prepare_zone_copy(old_contents, &contents_copy,
&changes);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to prepare zone copy: %s\n",
knot_strerror(ret));
return ret;
}
/*
* Apply the changesets.
*/
dbg_xfrin("Applying changesets.\n");
dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n",
old_contents->apex, contents_copy->apex);
for (int i = 0; i < chsets->count; ++i) {
if ((ret = xfrin_apply_changeset(contents_copy, changes,
&chsets->sets[i]))
!= KNOT_EOK) {
xfrin_rollback_update(old_contents,
&contents_copy, &changes);
dbg_xfrin("Failed to apply changesets to zone: "
"%s\n", knot_strerror(ret));
return ret;
}
}
assert(knot_zone_contents_apex(contents_copy) != NULL);
/*!
* \todo Test failure of IXFR.
*/
dbg_xfrin_verb("Finalizing updated zone...\n");
ret = xfrin_finalize_updated_zone(contents_copy, changes, old_contents);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to finalize updated zone: %s\n",
knot_strerror(ret));
xfrin_rollback_update(old_contents, &contents_copy, &changes);
return ret;
}
chsets->changes = changes;
*new_contents = contents_copy;
......
......@@ -185,6 +185,14 @@ int xfrin_apply_changesets(knot_zone_t *zone,
knot_changesets_t *chsets,
knot_zone_contents_t **new_contents);
int xfrin_prepare_zone_copy(knot_zone_contents_t *old_contents,
knot_zone_contents_t **new_contents,
knot_changes_t **changes);
int xfrin_finalize_updated_zone(knot_zone_contents_t *contents_copy,
knot_changes_t *changes,
knot_zone_contents_t *old_contents);
int xfrin_switch_zone(knot_zone_t *zone,
knot_zone_contents_t *new_contents,
int deep_free);
......
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